diff --git a/DEPS b/DEPS index 4f793440..de97104 100644 --- a/DEPS +++ b/DEPS
@@ -145,11 +145,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'bdb0919dcc6a700b41492c53ecf06b40983d13d7', + 'skia_revision': '87cef069cab4d8a4742d35a1bb1fb31644213045', # 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': '2ec7afe6ff115f5cb7859b81aff29b0775198495', + 'v8_revision': 'f94fe17b50a5c62280c5ea7bfee8caa9f091203e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -157,15 +157,15 @@ # 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': '99f494e42246bda28a1de4f97ca212b0d7172998', + 'angle_revision': '415bb0cdb057f60f684b3c01731a4f0e93e3630d', # 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': '060fcf7771596edc080198a881568dd80a9e5dcd', + 'swiftshader_revision': '3aec8a3be749e60fd8c093f046dae929ced23650', # 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': 'c9edc556eae15379bd56a91829d12f088f7739bc', + 'pdfium_revision': 'e392886b66c382a1573abb355cdcf6847aaacc70', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -196,7 +196,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. - 'freetype_revision': 'ad3443c93121c59181fc4b46c5179d0d00bfcc4e', + 'freetype_revision': '734d60f63cfa27f9b337ddbb80adb9edd60475bf', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling HarfBuzz # and whatever else without interference from each other. @@ -208,7 +208,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': 'c802efc06a4085b351ec3e4874a12ffa1faa4355', + 'catapult_revision': 'cad35e22dcad126c6a20663ded101565e6326d82', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -284,7 +284,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. - 'quiche_revision': 'a0c8f5aa07e68b2fea7862c169d262c6331f04b2', + 'quiche_revision': 'b71a08181bcb67b75f9b4f44fa92237816ade534', # 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. @@ -809,7 +809,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '385c64442a09fbdbbec481cdb7012c4c54603da3', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '6454258063cd52c8667a82668a537cb52de4a161', 'condition': 'checkout_linux', }, @@ -834,7 +834,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '36756e4590417a41f3a9054527219294f02fead1', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'aa2db565b32b0993a834348932c69424993e3f06', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -1207,7 +1207,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '600679a1c326094227e2493a2fbfd778d8f2b48b', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'cb5dd5c30dd6b780ab4b012147f915c934c131a4', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1375,7 +1375,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'abaae129d9a0c6e1e092067e0b105475df43352e', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '61b15905b0145bf339fc785a1d8913a631dbac7b', + Var('webrtc_git') + '/src.git' + '@' + '1e49ab2d40eba7a3a15d00db998f3f5a6703a167', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1416,7 +1416,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@fc9e4928e7c0543eb6d94c0cd6f7a50b4b86c984', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@43dbb476f6af5174d90e971d3a3d812385af9e7b', 'condition': 'checkout_src_internal', },
diff --git a/WATCHLISTS b/WATCHLISTS index fcc1e20..970136e 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -1670,8 +1670,9 @@ 'content/browser/tab_contents/|'\ 'chrome/browser/ui/tab_contents/', }, - 'tab_ui': { - 'filepath': 'chrome/android/features/tab_ui/' + 'tab_ui_and_start_surface': { + 'filepath': 'chrome/android/features/tab_ui/'\ + 'chrome/android/features/start_surface/', }, 'tbmv2_metrics': { 'filepath': 'third_party/catapult/tracing/tracing/metrics' @@ -2322,8 +2323,7 @@ 'fuchsia': ['sergeyu@chromium.org', 'wez@chromium.org'], 'fuzzing': ['fuzzing@chromium.org'], 'gamepad': ['mattreynolds+watch@chromium.org'], - 'gcm': ['peter@chromium.org', - 'zea+watch@chromium.org'], + 'gcm': ['peter@chromium.org'], 'generic_sensor': ['juncai+watch@chromium.org', 'mattreynolds+watch@chromium.org', 'raphael.kubo.da.costa@intel.com', @@ -2581,10 +2581,11 @@ 'tab_contents': ['ajwong+watch@chromium.org', 'avi@chromium.org', 'creis+watch@chromium.org'], - 'tab_ui': ['meiliang@chromium.org', - 'yuezhanggg@chromium.org', - 'wychen@chromium.org', - 'yusufo@chromium.org'], + 'tab_ui_and_start_surface': ['meiliang@chromium.org', + 'yuezhanggg@chromium.org', + 'wychen@chromium.org', + 'yusufo@chromium.org', + 'gogerald@chromium.org'], 'tbmv2_metrics': ['speed-metrics-reviews@chromium.org'], 'tcmalloc': ['dmikurube@chromium.org'], 'telemetry': ['telemetry-reviews@chromium.org'],
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn index 757530f..fad37d5 100644 --- a/android_webview/BUILD.gn +++ b/android_webview/BUILD.gn
@@ -579,8 +579,6 @@ "browser/js_java_interaction/js_java_configurator_host.h", "browser/memory_metrics_logger.cc", "browser/memory_metrics_logger.h", - "browser/net/aw_http_user_agent_settings.cc", - "browser/net/aw_http_user_agent_settings.h", "browser/network_service/android_stream_reader_url_loader.cc", "browser/network_service/android_stream_reader_url_loader.h", "browser/network_service/aw_network_change_notifier.cc",
diff --git a/android_webview/browser/aw_browser_context_unittest.cc b/android_webview/browser/aw_browser_context_unittest.cc index ee9f0338..7192aa86 100644 --- a/android_webview/browser/aw_browser_context_unittest.cc +++ b/android_webview/browser/aw_browser_context_unittest.cc
@@ -5,12 +5,10 @@ #include "android_webview/browser/aw_browser_context.h" #include "android_webview/browser/aw_browser_process.h" #include "android_webview/browser/aw_feature_list_creator.h" -#include "base/test/scoped_feature_list.h" #include "content/public/browser/browser_context.h" #include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_content_client_initializer.h" #include "mojo/core/embedder/embedder.h" -#include "services/network/public/cpp/features.h" #include "testing/gtest/include/gtest/gtest.h" namespace android_webview { @@ -19,7 +17,6 @@ protected: void SetUp() override { mojo::core::Init(); - feature_list_.InitAndEnableFeature(network::features::kNetworkService); test_content_client_initializer_ = new content::TestContentClientInitializer(); @@ -30,7 +27,6 @@ void TearDown() override { delete test_content_client_initializer_; } - base::test::ScopedFeatureList feature_list_; // Create the TestBrowserThreads. content::TestBrowserThreadBundle thread_bundle_; content::TestContentClientInitializer* test_content_client_initializer_;
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc index 35adb95..44ad27b 100644 --- a/android_webview/browser/aw_content_browser_client.cc +++ b/android_webview/browser/aw_content_browser_client.cc
@@ -95,7 +95,6 @@ #include "net/ssl/ssl_cert_request_info.h" #include "net/ssl/ssl_info.h" #include "services/network/network_service.h" -#include "services/network/public/cpp/features.h" #include "services/network/public/cpp/resource_request.h" #include "services/network/public/mojom/cookie_manager.mojom-forward.h" #include "services/service_manager/public/cpp/binder_registry.h" @@ -949,7 +948,6 @@ mojo::PendingReceiver<network::mojom::URLLoaderFactory>* factory_receiver, network::mojom::TrustedURLLoaderHeaderClientPtrInfo* header_client, bool* bypass_redirect_checks) { - DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService)); DCHECK_CURRENTLY_ON(BrowserThread::UI); auto proxied_receiver = std::move(*factory_receiver); @@ -968,7 +966,6 @@ void AwContentBrowserClient::WillCreateURLLoaderFactoryForAppCacheSubresource( int render_process_id, mojo::PendingRemote<network::mojom::URLLoaderFactory>* pending_factory) { - DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService)); DCHECK_CURRENTLY_ON(BrowserThread::UI); auto pending_proxy = std::move(*pending_factory);
diff --git a/android_webview/browser/aw_content_browser_client_unittest.cc b/android_webview/browser/aw_content_browser_client_unittest.cc index 3f6349d..925a6260 100644 --- a/android_webview/browser/aw_content_browser_client_unittest.cc +++ b/android_webview/browser/aw_content_browser_client_unittest.cc
@@ -5,10 +5,8 @@ #include "android_webview/browser/aw_content_browser_client.h" #include "android_webview/browser/aw_feature_list_creator.h" -#include "base/test/scoped_feature_list.h" #include "base/test/scoped_task_environment.h" #include "mojo/core/embedder/embedder.h" -#include "services/network/public/cpp/features.h" #include "testing/gtest/include/gtest/gtest.h" namespace android_webview { @@ -17,11 +15,9 @@ protected: void SetUp() override { mojo::core::Init(); - feature_list_.InitAndEnableFeature(network::features::kNetworkService); } base::test::ScopedTaskEnvironment scoped_task_environment_; - base::test::ScopedFeatureList feature_list_; }; TEST_F(AwContentBrowserClientTest, DisableCreatingThreadPool) {
diff --git a/android_webview/browser/net/aw_http_user_agent_settings.cc b/android_webview/browser/net/aw_http_user_agent_settings.cc deleted file mode 100644 index aab7de8..0000000 --- a/android_webview/browser/net/aw_http_user_agent_settings.cc +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright (c) 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "android_webview/browser/net/aw_http_user_agent_settings.h" - -#include "android_webview/browser/aw_content_browser_client.h" -#include "android_webview/common/aw_content_client.h" -#include "content/public/browser/browser_thread.h" -#include "net/http/http_util.h" - -namespace android_webview { - -AwHttpUserAgentSettings::AwHttpUserAgentSettings() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); -} - -AwHttpUserAgentSettings::~AwHttpUserAgentSettings() { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); -} - -std::string AwHttpUserAgentSettings::GetAcceptLanguage() const { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - std::string new_aw_accept_language = - AwContentBrowserClient::GetAcceptLangsImpl(); - if (new_aw_accept_language != last_aw_accept_language_) { - new_aw_accept_language = - net::HttpUtil::ExpandLanguageList(new_aw_accept_language); - last_http_accept_language_ = - net::HttpUtil::GenerateAcceptLanguageHeader(new_aw_accept_language); - last_aw_accept_language_ = new_aw_accept_language; - } - return last_http_accept_language_; -} - -std::string AwHttpUserAgentSettings::GetUserAgent() const { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - return android_webview::GetUserAgent(); -} - -} // namespace android_webview
diff --git a/android_webview/browser/net/aw_http_user_agent_settings.h b/android_webview/browser/net/aw_http_user_agent_settings.h deleted file mode 100644 index 50c3a25..0000000 --- a/android_webview/browser/net/aw_http_user_agent_settings.h +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright (c) 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ANDROID_WEBVIEW_BROWSER_NET_AW_HTTP_USER_AGENT_SETTINGS_H_ -#define ANDROID_WEBVIEW_BROWSER_NET_AW_HTTP_USER_AGENT_SETTINGS_H_ - -#include <string> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "net/base/http_user_agent_settings.h" - -namespace android_webview { - -// An implementation of |HttpUserAgentSettings| that provides HTTP header -// Accept-Language value that tracks aw accept language. -class AwHttpUserAgentSettings : public net::HttpUserAgentSettings { - public: - // Must be called on the UI thread. - AwHttpUserAgentSettings(); - // Must be called on the IO thread. - ~AwHttpUserAgentSettings() override; - - // net::HttpUserAgentSettings implementation - std::string GetAcceptLanguage() const override; - std::string GetUserAgent() const override; - - private: - // Avoid re-processing by caching the last value from the locale and the - // last result of processing via net::HttpUtil::GenerateAccept*Header(). - mutable std::string last_aw_accept_language_; - mutable std::string last_http_accept_language_; - - DISALLOW_COPY_AND_ASSIGN(AwHttpUserAgentSettings); -}; - -} // namespace android_webview - -#endif // ANDROID_WEBVIEW_BROWSER_NET_AW_HTTP_USER_AGENT_SETTINGS_H_ -
diff --git a/android_webview/browser/network_service/README.md b/android_webview/browser/network_service/README.md index 5833ee7..d797fadc 100644 --- a/android_webview/browser/network_service/README.md +++ b/android_webview/browser/network_service/README.md
@@ -1,25 +1,23 @@ # Android WebView Network Service This folder contains Android WebView's code for interacting with the Network -Service (including code shared with the legacy code path, while that path is -still supported). For details on the Network Service in general, see +Service. For details on the Network Service in general, see [`//services/network/`](/services/network/README.md). +*** note +**Note:** M77 is the last milestone to support the legacy (non-Network-Service) +code path. +*** + ## In-process Android WebView aims to run with the Network Service in-process (`features::kNetworkServiceInProcess`). For details, see -https://crbug.com/882650. +https://crbug.com/882650. This feature is enabled by default, so there's no need +to locally enable it. ## Testing with the Network Service Please see [general testing -instructions](/android_webview/docs/test-instructions.md). Until the feature is -on-by-default, you can enable the Network Service in tests like so: - -```shell -$ autoninja -C out/Default webview_instrumentation_test_apk -$ out/Default/bin/run_webview_instrumentation_test_apk \ - --enable-features="NetworkService,NetworkServiceInProcess" \ - -f <some test filter> # See general instructions for test filtering -``` +instructions](/android_webview/docs/test-instructions.md). There is no need to +modify flags because the Network Service is always enabled.
diff --git a/android_webview/browser/network_service/android_stream_reader_url_loader_unittest.cc b/android_webview/browser/network_service/android_stream_reader_url_loader_unittest.cc index cdd9a59d..f4e1245c 100644 --- a/android_webview/browser/network_service/android_stream_reader_url_loader_unittest.cc +++ b/android_webview/browser/network_service/android_stream_reader_url_loader_unittest.cc
@@ -6,13 +6,11 @@ #include "android_webview/browser/input_stream.h" #include "base/run_loop.h" -#include "base/test/scoped_feature_list.h" #include "base/test/scoped_task_environment.h" #include "content/public/common/resource_type.h" #include "mojo/core/embedder/embedder.h" #include "net/http/http_request_headers.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" -#include "services/network/public/cpp/features.h" #include "services/network/test/test_url_loader_client.h" #include "testing/gtest/include/gtest/gtest.h" @@ -161,7 +159,6 @@ void SetUp() override { mojo::core::Init(); - feature_list_.InitAndEnableFeature(network::features::kNetworkService); } network::ResourceRequest CreateRequest(const GURL& url) { @@ -236,7 +233,6 @@ return std::string(buffer.data(), buffer.size()); } - base::test::ScopedFeatureList feature_list_; base::test::ScopedTaskEnvironment scoped_task_environment_; DISALLOW_COPY_AND_ASSIGN(AndroidStreamReaderURLLoaderTest);
diff --git a/android_webview/common/aw_content_client.cc b/android_webview/common/aw_content_client.cc index 6691237..33e9757 100644 --- a/android_webview/common/aw_content_client.cc +++ b/android_webview/common/aw_content_client.cc
@@ -51,10 +51,6 @@ resource_id); } -bool AwContentClient::IsDataResourceGzipped(int resource_id) { - return ui::ResourceBundle::GetSharedInstance().IsGzipped(resource_id); -} - bool AwContentClient::CanSendWhileSwappedOut(const IPC::Message* message) { // For legacy API support we perform a few browser -> renderer synchronous IPC // messages that block the browser. However, the synchronous IPC replies might
diff --git a/android_webview/common/aw_content_client.h b/android_webview/common/aw_content_client.h index 88ccc80..05fbf9f2 100644 --- a/android_webview/common/aw_content_client.h +++ b/android_webview/common/aw_content_client.h
@@ -23,7 +23,6 @@ base::StringPiece GetDataResource(int resource_id, ui::ScaleFactor scale_factor) override; base::RefCountedMemory* GetDataResourceBytes(int resource_id) override; - bool IsDataResourceGzipped(int resource_id) override; bool CanSendWhileSwappedOut(const IPC::Message* message) override; void SetGpuInfo(const gpu::GPUInfo& gpu_info) override; bool UsingSynchronousCompositing() override;
diff --git a/android_webview/docs/commandline-flags.md b/android_webview/docs/commandline-flags.md index deea817b..a325aac 100644 --- a/android_webview/docs/commandline-flags.md +++ b/android_webview/docs/commandline-flags.md
@@ -90,7 +90,6 @@ Some interesting flags and Features: * `--show-composited-layer-borders` - * `--enable-features=NetworkService,NetworkServiceInProcess` * `--webview-log-js-console-messages` WebView also defines its own flags and Features:
diff --git a/android_webview/docs/net-debugging.md b/android_webview/docs/net-debugging.md index b0f906f..70543146 100644 --- a/android_webview/docs/net-debugging.md +++ b/android_webview/docs/net-debugging.md
@@ -18,14 +18,14 @@ ```shell # Optional: set any flags of your choosing before running the script -$ build/android/adb_system_webview_command_line --enable-features=NetworkService,NetworkServiceInProcess +$ build/android/adb_system_webview_command_line --enable-features=MyFeature,MyOtherFeature Wrote command line file. Current flags (in webview-command-line): - 005d1ac915b0c7d6 (bullhead-userdebug 6.0 MDB08M 2353240 dev-keys): --enable-features=NetworkService,NetworkServiceInProcess + 005d1ac915b0c7d6 (bullhead-userdebug 6.0 MDB08M 2353240 dev-keys): --enable-features=MyFeature,MyOtherFeature # Replace "<app package name>" with your app's package name (ex. the # WebView Shell is "org.chromium.webview_shell") $ android_webview/tools/record_netlog.py --package="<app package name>" -Running with flags ['--enable-features=NetworkService,NetworkServiceInProcess', '--log-net-log=netlog.json'] +Running with flags ['--enable-features=MyFeature,MyOtherFeature', '--log-net-log=netlog.json'] Netlog will start recording as soon as app starts up. Press ctrl-C to stop recording. ^C Pulling netlog to "netlog.json" @@ -34,10 +34,6 @@ Then import the JSON file into [the NetLog viewer](https://chromium.googlesource.com/catapult/+/master/netlog_viewer/). -For more details, see the implementation in -[AwUrlRequestContextGetter](/android_webview/browser/net/aw_url_request_context_getter.cc). -For support in the network service code path, see http://crbug.com/902039. - ### Manual steps 1. Figure out the app's data directory
diff --git a/android_webview/docs/test-instructions.md b/android_webview/docs/test-instructions.md index 03fb770..70b1e12 100644 --- a/android_webview/docs/test-instructions.md +++ b/android_webview/docs/test-instructions.md
@@ -108,7 +108,7 @@ ```sh $ out/Default/bin/run_webview_instrumentation_test_apk \ # Any test runner # Desired Features; see commandline-flags.md for more information - --enable-features="NetworkService,NetworkServiceInProcess" \ + --enable-features="MyFeature,MyOtherFeature" \ -f=AwContentsTest#testClearCacheInQuickSuccession ```
diff --git a/ash/accessibility/accessibility_delegate.h b/ash/accessibility/accessibility_delegate.h index c59d0e6..8da4682 100644 --- a/ash/accessibility/accessibility_delegate.h +++ b/ash/accessibility/accessibility_delegate.h
@@ -6,8 +6,6 @@ #define ASH_ACCESSIBILITY_ACCESSIBILITY_DELEGATE_H_ #include "ash/ash_export.h" -#include "base/time/time.h" -#include "ui/accessibility/ax_enums.mojom.h" namespace ash {
diff --git a/ash/accessibility/touch_exploration_controller.h b/ash/accessibility/touch_exploration_controller.h index 31846ad1..0a3f553 100644 --- a/ash/accessibility/touch_exploration_controller.h +++ b/ash/accessibility/touch_exploration_controller.h
@@ -14,7 +14,7 @@ #include "base/memory/weak_ptr.h" #include "base/timer/timer.h" #include "base/values.h" -#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_enums.mojom-forward.h" #include "ui/events/event.h" #include "ui/events/event_rewriter.h" #include "ui/events/gesture_detection/gesture_detector.h"
diff --git a/ash/accessibility/touch_exploration_controller_unittest.cc b/ash/accessibility/touch_exploration_controller_unittest.cc index ed0094f..e5ba19b 100644 --- a/ash/accessibility/touch_exploration_controller_unittest.cc +++ b/ash/accessibility/touch_exploration_controller_unittest.cc
@@ -14,6 +14,7 @@ #include "base/stl_util.h" #include "base/test/simple_test_tick_clock.h" #include "base/time/time.h" +#include "ui/accessibility/ax_enums.mojom.h" #include "ui/aura/client/cursor_client.h" #include "ui/aura/test/aura_test_base.h" #include "ui/aura/test/test_cursor_client.h"
diff --git a/ash/app_list/views/app_list_view.cc b/ash/app_list/views/app_list_view.cc index 0c2af42..3b372667 100644 --- a/ash/app_list/views/app_list_view.cc +++ b/ash/app_list/views/app_list_view.cc
@@ -160,12 +160,16 @@ // RenderHostWindow in order to handle events in context of app list. class AppListEventTargeter : public aura::WindowTargeter { public: - AppListEventTargeter() = default; + explicit AppListEventTargeter(AppListViewDelegate* delegate) + : delegate_(delegate) {} ~AppListEventTargeter() override = default; // aura::WindowTargeter: bool SubtreeShouldBeExploredForEvent(aura::Window* window, const ui::LocatedEvent& event) override { + if (delegate_ && !delegate_->CanProcessEventsOnApplistViews()) + return false; + if (window->GetProperty(kExcludeWindowFromEventHandling)) { // Allow routing to sub-windows for ET_MOUSE_MOVED event which is used by // accessibility to enter the mode of exploration of WebView contents. @@ -184,6 +188,8 @@ } private: + AppListViewDelegate* delegate_; // Weak. Owned by AppListService. + DISALLOW_COPY_AND_ASSIGN(AppListEventTargeter); }; @@ -582,7 +588,7 @@ widget->Init(std::move(params)); DCHECK_EQ(widget, GetWidget()); widget->GetNativeWindow()->SetEventTargeter( - std::make_unique<AppListEventTargeter>()); + std::make_unique<AppListEventTargeter>(delegate_)); // Enable arrow key in FocusManager. Arrow left/right and up/down triggers // the same focus movement as tab/shift+tab. @@ -705,13 +711,6 @@ return "AppListView"; } -bool AppListView::CanProcessEventsWithinSubtree() const { - if (!delegate_->CanProcessEventsOnApplistViews()) - return false; - - return views::View::CanProcessEventsWithinSubtree(); -} - bool AppListView::AcceleratorPressed(const ui::Accelerator& accelerator) { switch (accelerator.key_code()) { case ui::VKEY_ESCAPE:
diff --git a/ash/app_list/views/app_list_view.h b/ash/app_list/views/app_list_view.h index e1071e7..19dec37 100644 --- a/ash/app_list/views/app_list_view.h +++ b/ash/app_list/views/app_list_view.h
@@ -172,7 +172,6 @@ // views::View: void OnPaint(gfx::Canvas* canvas) override; const char* GetClassName() const override; - bool CanProcessEventsWithinSubtree() const override; bool AcceleratorPressed(const ui::Accelerator& accelerator) override; void Layout() override;
diff --git a/ash/app_list/views/assistant/assistant_page_view.cc b/ash/app_list/views/assistant/assistant_page_view.cc index d86ffba..83a5a0f3 100644 --- a/ash/app_list/views/assistant/assistant_page_view.cc +++ b/ash/app_list/views/assistant/assistant_page_view.cc
@@ -238,8 +238,10 @@ return; } - const bool prefer_voice = assistant_view_delegate_->IsTabletMode() || - assistant_view_delegate_->IsLaunchWithMicOpen(); + const bool prefer_voice = + assistant_view_delegate_->IsTabletMode() || + assistant_view_delegate_->GetState()->launch_with_mic_open().value_or( + false); if (!ash::assistant::util::IsVoiceEntryPoint(entry_point.value(), prefer_voice)) { NotifyAccessibilityEvent(ax::mojom::Event::kAlert, true);
diff --git a/ash/app_list/views/page_switcher.cc b/ash/app_list/views/page_switcher.cc index 00f3c785..c53dab0 100644 --- a/ash/app_list/views/page_switcher.cc +++ b/ash/app_list/views/page_switcher.cc
@@ -14,6 +14,7 @@ #include "base/macros.h" #include "base/metrics/histogram_macros.h" #include "third_party/skia/include/core/SkPath.h" +#include "ui/accessibility/ax_enums.mojom.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/animation/throb_animation.h" #include "ui/gfx/canvas.h"
diff --git a/ash/app_list/views/search_box_view.cc b/ash/app_list/views/search_box_view.cc index 30f1b5ab..911b7933 100644 --- a/ash/app_list/views/search_box_view.cc +++ b/ash/app_list/views/search_box_view.cc
@@ -223,13 +223,6 @@ return "SearchBoxView"; } -bool SearchBoxView::CanProcessEventsWithinSubtree() const { - if (!view_delegate_->CanProcessEventsOnApplistViews()) - return false; - - return views::View::CanProcessEventsWithinSubtree(); -} - // static int SearchBoxView::GetFocusRingSpacing() { return kSearchBoxFocusRingWidth + kSearchBoxFocusRingPadding;
diff --git a/ash/app_list/views/search_box_view.h b/ash/app_list/views/search_box_view.h index 17143f7..5ccddb0 100644 --- a/ash/app_list/views/search_box_view.h +++ b/ash/app_list/views/search_box_view.h
@@ -65,7 +65,6 @@ void GetAccessibleNodeData(ui::AXNodeData* node_data) override; void OnPaintBackground(gfx::Canvas* canvas) override; const char* GetClassName() const override; - bool CanProcessEventsWithinSubtree() const override; // Overridden from views::ButtonListener: void ButtonPressed(views::Button* sender, const ui::Event& event) override;
diff --git a/ash/app_list/views/search_result_actions_view.cc b/ash/app_list/views/search_result_actions_view.cc index e482547..1637a637 100644 --- a/ash/app_list/views/search_result_actions_view.cc +++ b/ash/app_list/views/search_result_actions_view.cc
@@ -13,6 +13,7 @@ #include "ash/app_list/views/search_result_view.h" #include "ash/public/cpp/app_list/app_list_config.h" #include "base/numerics/ranges.h" +#include "ui/accessibility/ax_enums.mojom.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/canvas.h" #include "ui/gfx/color_palette.h"
diff --git a/ash/app_list/views/search_result_base_view.cc b/ash/app_list/views/search_result_base_view.cc index 5bd86eb..617cf868 100644 --- a/ash/app_list/views/search_result_base_view.cc +++ b/ash/app_list/views/search_result_base_view.cc
@@ -8,6 +8,7 @@ #include "ash/app_list/views/search_result_actions_view.h" #include "ash/public/cpp/app_list/app_list_features.h" #include "base/strings/utf_string_conversions.h" +#include "ui/accessibility/ax_enums.mojom.h" namespace app_list {
diff --git a/ash/assistant/assistant_controller.cc b/ash/assistant/assistant_controller.cc index 6debb90..98039a01 100644 --- a/ash/assistant/assistant_controller.cc +++ b/ash/assistant/assistant_controller.cc
@@ -119,8 +119,8 @@ } void AssistantController::StartSpeakerIdEnrollmentFlow() { - if (prefs_controller()->prefs()->GetInteger( - chromeos::assistant::prefs::kAssistantConsentStatus) == + if (state()->consent_status().value_or( + chromeos::assistant::prefs::ConsentStatus::kUnknown) == chromeos::assistant::prefs::ConsentStatus::kActivityControlAccepted) { // If activity control has been accepted, launch the enrollment flow. setup_controller()->StartOnboarding(false /* relaunch */,
diff --git a/ash/assistant/assistant_controller.h b/ash/assistant/assistant_controller.h index b89c910..c4c501b 100644 --- a/ash/assistant/assistant_controller.h +++ b/ash/assistant/assistant_controller.h
@@ -115,6 +115,8 @@ void GetNavigableContentsFactory( mojo::PendingReceiver<content::mojom::NavigableContentsFactory> receiver); + AssistantStateBase* state() { return &assistant_prefs_controller_; } + AssistantAlarmTimerController* alarm_timer_controller() { return &assistant_alarm_timer_controller_; } @@ -131,10 +133,6 @@ return &assistant_notification_controller_; } - AssistantPrefsController* prefs_controller() { - return &assistant_prefs_controller_; - } - AssistantScreenContextController* screen_context_controller() { return &assistant_screen_context_controller_; }
diff --git a/ash/assistant/assistant_interaction_controller.cc b/ash/assistant/assistant_interaction_controller.cc index fb3d12f..d3856e81 100644 --- a/ash/assistant/assistant_interaction_controller.cc +++ b/ash/assistant/assistant_interaction_controller.cc
@@ -701,8 +701,7 @@ assistant_controller_->ui_controller()->model()->visibility()); const bool launch_with_mic_open = - assistant_controller_->prefs_controller()->prefs()->GetBoolean( - chromeos::assistant::prefs::kAssistantLaunchWithMicOpen); + assistant_controller_->state()->launch_with_mic_open().value_or(false); const bool prefer_voice = launch_with_mic_open || IsTabletMode(); // We don't explicitly start a new voice interaction if the entry point
diff --git a/ash/assistant/assistant_notification_controller.cc b/ash/assistant/assistant_notification_controller.cc index 572d6433..2025715 100644 --- a/ash/assistant/assistant_notification_controller.cc +++ b/ash/assistant/assistant_notification_controller.cc
@@ -205,8 +205,7 @@ void AssistantNotificationController::OnNotificationAdded( const AssistantNotification* notification) { // Do not show system notifications if the setting is disabled. - if (!assistant_controller_->prefs_controller()->prefs()->GetBoolean( - chromeos::assistant::prefs::kAssistantNotificationEnabled)) { + if (!assistant_controller_->state()->notification_enabled().value_or(true)) { return; } @@ -221,8 +220,7 @@ void AssistantNotificationController::OnNotificationUpdated( const AssistantNotification* notification) { // Do not show system notifications if the setting is disabled. - if (!assistant_controller_->prefs_controller()->prefs()->GetBoolean( - chromeos::assistant::prefs::kAssistantNotificationEnabled)) { + if (!assistant_controller_->state()->notification_enabled().value_or(true)) { return; }
diff --git a/ash/assistant/assistant_prefs_controller.cc b/ash/assistant/assistant_prefs_controller.cc index 4fc95b5..7a17d4b 100644 --- a/ash/assistant/assistant_prefs_controller.cc +++ b/ash/assistant/assistant_prefs_controller.cc
@@ -6,6 +6,8 @@ #include "ash/session/session_controller_impl.h" #include "ash/shell.h" +#include "ash/system/update/update_notification_controller.h" +#include "chromeos/services/assistant/public/cpp/assistant_prefs.h" #include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_registry_simple.h" @@ -16,67 +18,92 @@ AssistantPrefsController::~AssistantPrefsController() = default; -void AssistantPrefsController::AddObserver(AssistantPrefsObserver* observer) { - InitObserver(observer); - observers_.AddObserver(observer); +void AssistantPrefsController::InitializeObserver( + AssistantStateObserver* observer) { + if (consent_status_.has_value()) + observer->OnAssistantConsentStatusChanged(consent_status_.value()); } -void AssistantPrefsController::RemoveObserver( - AssistantPrefsObserver* observer) { - observers_.RemoveObserver(observer); -} - -void AssistantPrefsController::InitObserver(AssistantPrefsObserver* observer) { - PrefService* primary_user_prefs = - Shell::Get()->session_controller()->GetPrimaryUserPrefService(); - PrefService* active_prefs = - Shell::Get()->session_controller()->GetActivePrefService(); - - if (primary_user_prefs && primary_user_prefs == active_prefs) { - observer->OnAssistantConsentStatusUpdated(active_prefs->GetInteger( - chromeos::assistant::prefs::kAssistantConsentStatus)); - } -} - -PrefService* AssistantPrefsController::prefs() { - PrefService* primary_user_prefs = - Shell::Get()->session_controller()->GetPrimaryUserPrefService(); - PrefService* active_prefs = - Shell::Get()->session_controller()->GetActivePrefService(); - - DCHECK_EQ(primary_user_prefs, active_prefs); - return primary_user_prefs; +void AssistantPrefsController::UpdateState() { + UpdateConsentStatus(); + UpdateHotwordAlwaysOn(); + UpdateLaunchWithMicOpen(); + UpdateNotificationEnabled(); } void AssistantPrefsController::OnActiveUserPrefServiceChanged( PrefService* pref_service) { pref_change_registrar_.reset(); - // If primary user is active, register pref change listeners. + // Skip for non-primary user prefs. PrefService* primary_user_prefs = Shell::Get()->session_controller()->GetPrimaryUserPrefService(); - if (primary_user_prefs && primary_user_prefs == pref_service) { - for (auto& observer : observers_) - InitObserver(&observer); + if (!primary_user_prefs || primary_user_prefs != pref_service) + return; - pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>(); - pref_change_registrar_->Init(pref_service); + // Register preference changes. + pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>(); + pref_change_registrar_->Init(pref_service); + pref_change_registrar_->Add( + chromeos::assistant::prefs::kAssistantConsentStatus, + base::BindRepeating(&AssistantPrefsController::UpdateConsentStatus, + base::Unretained(this))); + pref_change_registrar_->Add( + chromeos::assistant::prefs::kAssistantHotwordAlwaysOn, + base::BindRepeating(&AssistantPrefsController::UpdateHotwordAlwaysOn, + base::Unretained(this))); + pref_change_registrar_->Add( + chromeos::assistant::prefs::kAssistantLaunchWithMicOpen, + base::BindRepeating(&AssistantPrefsController::UpdateLaunchWithMicOpen, + base::Unretained(this))); + pref_change_registrar_->Add( + chromeos::assistant::prefs::kAssistantNotificationEnabled, + base::BindRepeating(&AssistantPrefsController::UpdateNotificationEnabled, + base::Unretained(this))); - pref_change_registrar_->Add( - chromeos::assistant::prefs::kAssistantConsentStatus, - base::BindRepeating(&AssistantPrefsController::NotifyConsentStatus, - base::Unretained(this))); - } + UpdateState(); } -void AssistantPrefsController::NotifyConsentStatus() { - for (auto& observer : observers_) { - observer.OnAssistantConsentStatusUpdated( - Shell::Get() - ->session_controller() - ->GetPrimaryUserPrefService() - ->GetInteger(chromeos::assistant::prefs::kAssistantConsentStatus)); +void AssistantPrefsController::UpdateConsentStatus() { + auto consent_status = pref_change_registrar_->prefs()->GetInteger( + chromeos::assistant::prefs::kAssistantConsentStatus); + if (consent_status_.has_value() && + consent_status_.value() == consent_status) { + return; } + consent_status_ = consent_status; + for (auto& observer : observers_) + observer.OnAssistantConsentStatusChanged(consent_status_.value()); +} + +void AssistantPrefsController::UpdateHotwordAlwaysOn() { + auto hotword_always_on = pref_change_registrar_->prefs()->GetBoolean( + chromeos::assistant::prefs::kAssistantHotwordAlwaysOn); + if (hotword_always_on_.has_value() && + hotword_always_on_.value() == hotword_always_on) { + return; + } + hotword_always_on_ = hotword_always_on; +} + +void AssistantPrefsController::UpdateLaunchWithMicOpen() { + auto launch_with_mic_open = pref_change_registrar_->prefs()->GetBoolean( + chromeos::assistant::prefs::kAssistantLaunchWithMicOpen); + if (launch_with_mic_open_.has_value() && + launch_with_mic_open_.value() == launch_with_mic_open) { + return; + } + launch_with_mic_open_ = launch_with_mic_open; +} + +void AssistantPrefsController::UpdateNotificationEnabled() { + auto notification_enabled = pref_change_registrar_->prefs()->GetBoolean( + chromeos::assistant::prefs::kAssistantNotificationEnabled); + if (notification_enabled_.has_value() && + notification_enabled_.value() == notification_enabled) { + return; + } + notification_enabled_ = notification_enabled; } } // namespace ash
diff --git a/ash/assistant/assistant_prefs_controller.h b/ash/assistant/assistant_prefs_controller.h index 55a0c73..a487db3 100644 --- a/ash/assistant/assistant_prefs_controller.h +++ b/ash/assistant/assistant_prefs_controller.h
@@ -6,6 +6,7 @@ #define ASH_ASSISTANT_ASSISTANT_PREFS_CONTROLLER_H_ #include "ash/ash_export.h" +#include "ash/public/cpp/assistant/assistant_state_base.h" #include "ash/session/session_observer.h" #include "base/macros.h" #include "chromeos/services/assistant/public/cpp/assistant_prefs.h" @@ -14,43 +15,36 @@ namespace ash { -// A checked observer which receives Assistant prefs change. -class ASH_EXPORT AssistantPrefsObserver : public base::CheckedObserver { - public: - AssistantPrefsObserver() = default; - ~AssistantPrefsObserver() override = default; - - virtual void OnAssistantConsentStatusUpdated(int consent_status) {} - - private: - DISALLOW_COPY_AND_ASSIGN(AssistantPrefsObserver); -}; - -class ASH_EXPORT AssistantPrefsController : public SessionObserver { +// Provide access of Assistant related preferences to clients in ash. +class ASH_EXPORT AssistantPrefsController : public SessionObserver, + public AssistantStateBase { public: AssistantPrefsController(); ~AssistantPrefsController() override; - void AddObserver(AssistantPrefsObserver* observer); - void RemoveObserver(AssistantPrefsObserver* observer); - void InitObserver(AssistantPrefsObserver* observer); - - PrefService* prefs(); + // AssistantStateBase: + void InitializeObserver(AssistantStateObserver* observer) override; private: + // Update pref cache and notify observers when primary user prefs becomes + // active. + void UpdateState(); + // SessionObserver: void OnActiveUserPrefServiceChanged(PrefService* pref_service) override; - // Called when the consent status is obtained from the pref service. - void NotifyConsentStatus(); + // Called when the related preferences are obtained from the pref service. + void UpdateConsentStatus(); + void UpdateHotwordAlwaysOn(); + void UpdateLaunchWithMicOpen(); + void UpdateNotificationEnabled(); + // TODO(b/138679823): Move related logics into AssistantStateBase. // Observes user profile prefs for the Assistant. std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_; ScopedSessionObserver session_observer_; - base::ObserverList<AssistantPrefsObserver> observers_; - DISALLOW_COPY_AND_ASSIGN(AssistantPrefsController); };
diff --git a/ash/assistant/assistant_prefs_controller_unittest.cc b/ash/assistant/assistant_prefs_controller_unittest.cc index cbd373d..54146d57 100644 --- a/ash/assistant/assistant_prefs_controller_unittest.cc +++ b/ash/assistant/assistant_prefs_controller_unittest.cc
@@ -7,6 +7,7 @@ #include <memory> #include "ash/assistant/assistant_controller.h" +#include "ash/session/session_controller_impl.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "base/macros.h" @@ -16,13 +17,13 @@ namespace ash { -class TestAssistantPrefsObserver : public AssistantPrefsObserver { +class TestAssistantPrefsObserver : public AssistantStateObserver { public: TestAssistantPrefsObserver() = default; ~TestAssistantPrefsObserver() override = default; // AssistantPrefsObserver: - void OnAssistantConsentStatusUpdated(int consent_status) override { + void OnAssistantConsentStatusChanged(int consent_status) override { consent_status_ = consent_status; } @@ -46,7 +47,7 @@ AshTestBase::SetUp(); - prefs_ = Shell::Get()->assistant_controller()->prefs_controller()->prefs(); + prefs_ = Shell::Get()->session_controller()->GetPrimaryUserPrefService(); DCHECK(prefs_); observer_ = std::make_unique<TestAssistantPrefsObserver>(); @@ -72,15 +73,13 @@ // The observer class should get an instant notification about the current // pref value. - Shell::Get()->assistant_controller()->prefs_controller()->AddObserver( - observer()); + Shell::Get()->assistant_controller()->state()->AddObserver(observer()); EXPECT_EQ(chromeos::assistant::prefs::ConsentStatus::kActivityControlAccepted, observer()->consent_status()); } TEST_F(AssistantPrefsControllerTest, NotifyConsentStatus) { - Shell::Get()->assistant_controller()->prefs_controller()->AddObserver( - observer()); + Shell::Get()->assistant_controller()->state()->AddObserver(observer()); prefs()->SetInteger(chromeos::assistant::prefs::kAssistantConsentStatus, chromeos::assistant::prefs::ConsentStatus::kUnauthorized);
diff --git a/ash/assistant/assistant_setup_controller.cc b/ash/assistant/assistant_setup_controller.cc index 80e5a85..375ee34 100644 --- a/ash/assistant/assistant_setup_controller.cc +++ b/ash/assistant/assistant_setup_controller.cc
@@ -58,8 +58,8 @@ } void AssistantSetupController::OnOptInButtonPressed() { - if (assistant_controller_->prefs_controller()->prefs()->GetInteger( - chromeos::assistant::prefs::kAssistantConsentStatus) == + if (assistant_controller_->state()->consent_status().value_or( + chromeos::assistant::prefs::ConsentStatus::kUnknown) == chromeos::assistant::prefs::ConsentStatus::kUnauthorized) { assistant_controller_->OpenUrl(assistant::util::CreateLocalizedGURL( kGSuiteAdministratorInstructionsUrl));
diff --git a/ash/assistant/assistant_view_delegate_impl.cc b/ash/assistant/assistant_view_delegate_impl.cc index 3cfdd3b75..9c38e6b 100644 --- a/ash/assistant/assistant_view_delegate_impl.cc +++ b/ash/assistant/assistant_view_delegate_impl.cc
@@ -81,6 +81,16 @@ observer); } +void AssistantViewDelegateImpl::AddStateObserver( + AssistantStateObserver* observer) { + assistant_controller_->state()->AddObserver(observer); +} + +void AssistantViewDelegateImpl::RemoveStateObserver( + AssistantStateObserver* observer) { + assistant_controller_->state()->RemoveObserver(observer); +} + void AssistantViewDelegateImpl::AddUiModelObserver( AssistantUiModelObserver* observer) { assistant_controller_->ui_controller()->AddModelObserver(observer); @@ -91,16 +101,6 @@ assistant_controller_->ui_controller()->RemoveModelObserver(observer); } -void AssistantViewDelegateImpl::AddAssistantPrefsObserver( - AssistantPrefsObserver* observer) { - assistant_controller_->prefs_controller()->AddObserver(observer); -} - -void AssistantViewDelegateImpl::RemoveAssistantPrefsObserver( - AssistantPrefsObserver* observer) { - assistant_controller_->prefs_controller()->RemoveObserver(observer); -} - CaptionBarDelegate* AssistantViewDelegateImpl::GetCaptionBarDelegate() { return assistant_controller_->ui_controller(); } @@ -111,9 +111,8 @@ assistant_controller_->DownloadImage(url, std::move(callback)); } -int AssistantViewDelegateImpl::GetConsentStatus() const { - return assistant_controller_->prefs_controller()->prefs()->GetInteger( - chromeos::assistant::prefs::kAssistantConsentStatus); +AssistantStateBase* AssistantViewDelegateImpl::GetState() const { + return assistant_controller_->state(); } ::wm::CursorManager* AssistantViewDelegateImpl::GetCursorManager() { @@ -129,11 +128,6 @@ return Shell::Get()->GetRootWindowForNewWindows(); } -bool AssistantViewDelegateImpl::IsLaunchWithMicOpen() const { - return assistant_controller_->prefs_controller()->prefs()->GetBoolean( - chromeos::assistant::prefs::kAssistantLaunchWithMicOpen); -} - bool AssistantViewDelegateImpl::IsTabletMode() const { return Shell::Get()->tablet_mode_controller()->InTabletMode(); }
diff --git a/ash/assistant/assistant_view_delegate_impl.h b/ash/assistant/assistant_view_delegate_impl.h index e7db110..7b43659 100644 --- a/ash/assistant/assistant_view_delegate_impl.h +++ b/ash/assistant/assistant_view_delegate_impl.h
@@ -39,21 +39,20 @@ AssistantNotificationModelObserver* observer) override; void RemoveNotificationModelObserver( AssistantNotificationModelObserver* observer) override; + void AddStateObserver(AssistantStateObserver* observer) override; + void RemoveStateObserver(AssistantStateObserver* observer) override; void AddUiModelObserver(AssistantUiModelObserver* observer) override; void RemoveUiModelObserver(AssistantUiModelObserver* observer) override; - void AddAssistantPrefsObserver(AssistantPrefsObserver* observer) override; - void RemoveAssistantPrefsObserver(AssistantPrefsObserver* observer) override; CaptionBarDelegate* GetCaptionBarDelegate() override; void DownloadImage( const GURL& url, AssistantImageDownloader::DownloadCallback callback) override; - int GetConsentStatus() const override; + AssistantStateBase* GetState() const override; ::wm::CursorManager* GetCursorManager() override; void GetNavigableContentsFactoryForView( mojo::PendingReceiver<content::mojom::NavigableContentsFactory> receiver) override; aura::Window* GetRootWindowForNewWindows() override; - bool IsLaunchWithMicOpen() const override; bool IsTabletMode() const override; void OnDialogPlateButtonPressed(AssistantButtonId id) override; void OnDialogPlateContentsCommitted(const std::string& text) override;
diff --git a/ash/assistant/ui/assistant_view_delegate.h b/ash/assistant/ui/assistant_view_delegate.h index ab3155e..4a59cd24 100644 --- a/ash/assistant/ui/assistant_view_delegate.h +++ b/ash/assistant/ui/assistant_view_delegate.h
@@ -113,11 +113,9 @@ virtual void AddUiModelObserver(AssistantUiModelObserver* observer) = 0; virtual void RemoveUiModelObserver(AssistantUiModelObserver* observer) = 0; - // Adds/removes the Assistant prefs observer associated with the view - // delegate. - virtual void AddAssistantPrefsObserver(AssistantPrefsObserver* observer) = 0; - virtual void RemoveAssistantPrefsObserver( - AssistantPrefsObserver* observer) = 0; + // Adds/removes the state observer associated with the view delegate. + virtual void AddStateObserver(AssistantStateObserver* observer) = 0; + virtual void RemoveStateObserver(AssistantStateObserver* observer) = 0; // Gets the caption bar delegate associated with the view delegate. virtual CaptionBarDelegate* GetCaptionBarDelegate() = 0; @@ -129,8 +127,7 @@ const GURL& url, AssistantImageDownloader::DownloadCallback callback) = 0; - // Returns the status of the user's consent. - virtual int GetConsentStatus() const = 0; + virtual AssistantStateBase* GetState() const = 0; // Returns the cursor_manager. virtual ::wm::CursorManager* GetCursorManager() = 0; @@ -144,9 +141,6 @@ // Returns the root window that newly created windows should be added to. virtual aura::Window* GetRootWindowForNewWindows() = 0; - // Returns true if user prefers to start with voice interaction. - virtual bool IsLaunchWithMicOpen() const = 0; - // Returns true if in tablet mode. virtual bool IsTabletMode() const = 0;
diff --git a/ash/assistant/ui/main_stage/assistant_footer_view.cc b/ash/assistant/ui/main_stage/assistant_footer_view.cc index e0d3d5f..1406a30 100644 --- a/ash/assistant/ui/main_stage/assistant_footer_view.cc +++ b/ash/assistant/ui/main_stage/assistant_footer_view.cc
@@ -45,11 +45,11 @@ &AssistantFooterView::OnAnimationEnded, base::Unretained(this)))) { InitLayout(); - delegate_->AddAssistantPrefsObserver(this); + delegate_->AddStateObserver(this); } AssistantFooterView::~AssistantFooterView() { - delegate_->RemoveAssistantPrefsObserver(this); + delegate_->RemoveStateObserver(this); } const char* AssistantFooterView::GetClassName() const { @@ -69,7 +69,8 @@ // Initial view state is based on user consent state. const bool consent_given = - delegate_->GetConsentStatus() == + delegate_->GetState()->consent_status().value_or( + chromeos::assistant::prefs::ConsentStatus::kUnknown) == chromeos::assistant::prefs::ConsentStatus::kActivityControlAccepted; // Suggestion container. @@ -97,7 +98,7 @@ AddChildView(opt_in_view_); } -void AssistantFooterView::OnAssistantConsentStatusUpdated(int consent_status) { +void AssistantFooterView::OnAssistantConsentStatusChanged(int consent_status) { using assistant::util::CreateLayerAnimationSequence; using assistant::util::CreateOpacityElement; using assistant::util::StartLayerAnimationSequence; @@ -152,7 +153,8 @@ bool AssistantFooterView::OnAnimationEnded( const ui::CallbackLayerAnimationObserver& observer) { const bool consent_given = - delegate_->GetConsentStatus() == + delegate_->GetState()->consent_status().value_or( + chromeos::assistant::prefs::ConsentStatus::kUnknown) == chromeos::assistant::prefs::ConsentStatus::kActivityControlAccepted; // Only the view relevant to our consent state should process events.
diff --git a/ash/assistant/ui/main_stage/assistant_footer_view.h b/ash/assistant/ui/main_stage/assistant_footer_view.h index 33274fc..8a71075f 100644 --- a/ash/assistant/ui/main_stage/assistant_footer_view.h +++ b/ash/assistant/ui/main_stage/assistant_footer_view.h
@@ -25,7 +25,7 @@ class COMPONENT_EXPORT(ASSISTANT_UI) AssistantFooterView : public views::View, - public AssistantPrefsObserver { + public AssistantStateObserver { public: explicit AssistantFooterView(AssistantViewDelegate* delegate); ~AssistantFooterView() override; @@ -35,8 +35,8 @@ gfx::Size CalculatePreferredSize() const override; int GetHeightForWidth(int width) const override; - // AssistantPrefsObserver: - void OnAssistantConsentStatusUpdated(int consent_status) override; + // AssistantStateObserver: + void OnAssistantConsentStatusChanged(int consent_status) override; private: void InitLayout();
diff --git a/ash/assistant/ui/main_stage/assistant_opt_in_view.cc b/ash/assistant/ui/main_stage/assistant_opt_in_view.cc index 858c5ab..418460c 100644 --- a/ash/assistant/ui/main_stage/assistant_opt_in_view.cc +++ b/ash/assistant/ui/main_stage/assistant_opt_in_view.cc
@@ -90,11 +90,11 @@ AssistantOptInView::AssistantOptInView(AssistantViewDelegate* delegate) : delegate_(delegate) { InitLayout(); - delegate_->AddAssistantPrefsObserver(this); + delegate_->AddStateObserver(this); } AssistantOptInView::~AssistantOptInView() { - delegate_->RemoveAssistantPrefsObserver(this); + delegate_->RemoveStateObserver(this); } const char* AssistantOptInView::GetClassName() const { @@ -114,7 +114,7 @@ delegate_->OnOptInButtonPressed(); } -void AssistantOptInView::OnAssistantConsentStatusUpdated(int consent_status) { +void AssistantOptInView::OnAssistantConsentStatusChanged(int consent_status) { UpdateLabel(consent_status); } @@ -152,7 +152,8 @@ container_->AddChildView(label_); container_->SetFocusForPlatform(); - UpdateLabel(delegate_->GetConsentStatus()); + UpdateLabel(delegate_->GetState()->consent_status().value_or( + chromeos::assistant::prefs::ConsentStatus::kUnknown)); } void AssistantOptInView::UpdateLabel(int consent_status) {
diff --git a/ash/assistant/ui/main_stage/assistant_opt_in_view.h b/ash/assistant/ui/main_stage/assistant_opt_in_view.h index 1f60521..a516a529 100644 --- a/ash/assistant/ui/main_stage/assistant_opt_in_view.h +++ b/ash/assistant/ui/main_stage/assistant_opt_in_view.h
@@ -23,7 +23,7 @@ class COMPONENT_EXPORT(ASSISTANT_UI) AssistantOptInView : public views::View, public views::ButtonListener, - public AssistantPrefsObserver { + public AssistantStateObserver { public: explicit AssistantOptInView(AssistantViewDelegate* delegate_); ~AssistantOptInView() override; @@ -36,8 +36,8 @@ // views::ButtonListener: void ButtonPressed(views::Button* sender, const ui::Event& event) override; - // AssistantPrefsObserver: - void OnAssistantConsentStatusUpdated(int consent_status) override; + // AssistantStateObserver: + void OnAssistantConsentStatusChanged(int consent_status) override; private: void InitLayout();
diff --git a/ash/login/ui/lock_contents_view.cc b/ash/login/ui/lock_contents_view.cc index 0ed5fedf..87b16b7 100644 --- a/ash/login/ui/lock_contents_view.cc +++ b/ash/login/ui/lock_contents_view.cc
@@ -1232,8 +1232,7 @@ bool LockContentsView::AreMediaControlsEnabled() const { return screen_type_ == LockScreen::ScreenType::kLock && !expanded_view_->GetVisible() && - Shell::Get()->media_controller()->AreLockScreenMediaKeysEnabled() && - base::FeatureList::IsEnabled(features::kLockScreenMediaControls); + Shell::Get()->media_controller()->AreLockScreenMediaKeysEnabled(); } void LockContentsView::HideMediaControlsLayout() {
diff --git a/ash/login/ui/lock_contents_view_unittest.cc b/ash/login/ui/lock_contents_view_unittest.cc index c91dfc0..520f30d 100644 --- a/ash/login/ui/lock_contents_view_unittest.cc +++ b/ash/login/ui/lock_contents_view_unittest.cc
@@ -2414,8 +2414,7 @@ TEST_F(LockContentsViewUnitTest, LockScreenMediaControlsShownIfMediaPlaying) { // Enable media controls. base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatures( - {features::kLockScreenMediaKeys, features::kLockScreenMediaControls}, {}); + feature_list.InitAndEnableFeature(features::kLockScreenMediaControls); // Build lock screen with 1 user. auto* contents = new LockContentsView( @@ -2438,8 +2437,7 @@ TEST_F(LockContentsViewUnitTest, LockScreenMediaControlsHiddenAfterDelay) { // Enable media controls. base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatures( - {features::kLockScreenMediaKeys, features::kLockScreenMediaControls}, {}); + feature_list.InitAndEnableFeature(features::kLockScreenMediaControls); // Build lock screen with 1 user. auto* contents = new LockContentsView( @@ -2479,8 +2477,7 @@ MediaControlsHiddenIfScreenLockedWhileMediaPaused) { // Enable media controls. base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatures( - {features::kLockScreenMediaKeys, features::kLockScreenMediaControls}, {}); + feature_list.InitAndEnableFeature(features::kLockScreenMediaControls); // Build lock screen with 1 user. auto* contents = new LockContentsView( @@ -2503,8 +2500,7 @@ TEST_F(LockContentsViewUnitTest, KeepMediaControlsShownWithinDelay) { // Enable media controls. base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatures( - {features::kLockScreenMediaKeys, features::kLockScreenMediaControls}, {}); + feature_list.InitAndEnableFeature(features::kLockScreenMediaControls); // Build lock screen with 1 user. auto* contents = new LockContentsView( @@ -2535,8 +2531,7 @@ TEST_F(LockContentsViewUnitTest, LockScreenMediaControlsHiddenNoMedia) { // Enable media controls. base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatures( - {features::kLockScreenMediaKeys, features::kLockScreenMediaControls}, {}); + feature_list.InitAndEnableFeature(features::kLockScreenMediaControls); // Build lock screen with 1 user. auto* contents = new LockContentsView( @@ -2557,8 +2552,7 @@ TEST_F(LockContentsViewUnitTest, ShowMediaControlsIfPausedAndAlreadyShowing) { // Enable media controls. base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatures( - {features::kLockScreenMediaKeys, features::kLockScreenMediaControls}, {}); + feature_list.InitAndEnableFeature(features::kLockScreenMediaControls); // Build lock screen with 1 user. auto* contents = new LockContentsView( @@ -2587,13 +2581,12 @@ LockScreenMediaControlsHiddenIfPreferenceDisabled) { // Enable media controls. base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatures( - {features::kLockScreenMediaKeys, features::kLockScreenMediaControls}, {}); + feature_list.InitAndEnableFeature(features::kLockScreenMediaControls); - // Disable user preference for media keys. + // Disable user preference for media controls. PrefService* prefs = Shell::Get()->session_controller()->GetLastActiveUserPrefService(); - prefs->SetBoolean(prefs::kLockScreenMediaKeysEnabled, false); + prefs->SetBoolean(prefs::kLockScreenMediaControlsEnabled, false); // Build lock screen with 1 user. auto* contents = new LockContentsView( @@ -2616,8 +2609,7 @@ TEST_F(LockContentsViewUnitTest, MediaControlsHiddenOnLoginScreen) { // Enable media controls. base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatures( - {features::kLockScreenMediaKeys, features::kLockScreenMediaControls}, {}); + feature_list.InitAndEnableFeature(features::kLockScreenMediaControls); // Build login screen with 1 user. auto* contents = new LockContentsView(
diff --git a/ash/login/ui/lock_screen_media_controls_view_unittest.cc b/ash/login/ui/lock_screen_media_controls_view_unittest.cc index 6e69a9b..0ab4a4f 100644 --- a/ash/login/ui/lock_screen_media_controls_view_unittest.cc +++ b/ash/login/ui/lock_screen_media_controls_view_unittest.cc
@@ -83,9 +83,7 @@ void SetUp() override { // Enable media controls. - feature_list.InitWithFeatures( - {features::kLockScreenMediaKeys, features::kLockScreenMediaControls}, - {}); + feature_list.InitAndEnableFeature(features::kLockScreenMediaControls); LoginTestBase::SetUp();
diff --git a/ash/login/ui/login_base_bubble_view.cc b/ash/login/ui/login_base_bubble_view.cc index 81261a8..8c331f7 100644 --- a/ash/login/ui/login_base_bubble_view.cc +++ b/ash/login/ui/login_base_bubble_view.cc
@@ -10,6 +10,7 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/shell.h" #include "base/scoped_observer.h" +#include "ui/accessibility/ax_enums.mojom.h" #include "ui/aura/client/focus_change_observer.h" #include "ui/aura/client/focus_client.h" #include "ui/compositor/layer_animator.h"
diff --git a/ash/media/media_controller_impl.cc b/ash/media/media_controller_impl.cc index 789a4ad..e0662f15 100644 --- a/ash/media/media_controller_impl.cc +++ b/ash/media/media_controller_impl.cc
@@ -46,7 +46,7 @@ // static void MediaControllerImpl::RegisterProfilePrefs(PrefRegistrySimple* registry) { - registry->RegisterBooleanPref(prefs::kLockScreenMediaKeysEnabled, true, + registry->RegisterBooleanPref(prefs::kLockScreenMediaControlsEnabled, true, PrefRegistry::PUBLIC); } @@ -55,8 +55,8 @@ Shell::Get()->session_controller()->GetPrimaryUserPrefService(); DCHECK(prefs); - return base::FeatureList::IsEnabled(features::kLockScreenMediaKeys) && - prefs->GetBoolean(prefs::kLockScreenMediaKeysEnabled) && + return base::FeatureList::IsEnabled(features::kLockScreenMediaControls) && + prefs->GetBoolean(prefs::kLockScreenMediaControlsEnabled) && !media_controls_dismissed_; }
diff --git a/ash/media/media_controller_unittest.cc b/ash/media/media_controller_unittest.cc index 76ca79a8..33a2039f 100644 --- a/ash/media/media_controller_unittest.cc +++ b/ash/media/media_controller_unittest.cc
@@ -98,11 +98,11 @@ TEST_F(MediaControllerTest, EnableLockScreenMediaKeys) { base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(features::kLockScreenMediaKeys); + feature_list.InitAndEnableFeature(features::kLockScreenMediaControls); PrefService* prefs = Shell::Get()->session_controller()->GetLastActiveUserPrefService(); - prefs->SetBoolean(prefs::kLockScreenMediaKeysEnabled, true); + prefs->SetBoolean(prefs::kLockScreenMediaControlsEnabled, true); EXPECT_TRUE( Shell::Get()->media_controller()->AreLockScreenMediaKeysEnabled()); @@ -110,16 +110,16 @@ TEST_F(MediaControllerTest, DisableLockScreenMediaKeysIfFeatureDisabled) { base::test::ScopedFeatureList feature_list; - feature_list.InitAndDisableFeature(features::kLockScreenMediaKeys); + feature_list.InitAndDisableFeature(features::kLockScreenMediaControls); PrefService* prefs = Shell::Get()->session_controller()->GetPrimaryUserPrefService(); - prefs->SetBoolean(prefs::kLockScreenMediaKeysEnabled, true); + prefs->SetBoolean(prefs::kLockScreenMediaControlsEnabled, true); EXPECT_FALSE( Shell::Get()->media_controller()->AreLockScreenMediaKeysEnabled()); - prefs->SetBoolean(prefs::kLockScreenMediaKeysEnabled, false); + prefs->SetBoolean(prefs::kLockScreenMediaControlsEnabled, false); EXPECT_FALSE( Shell::Get()->media_controller()->AreLockScreenMediaKeysEnabled()); @@ -127,23 +127,23 @@ TEST_F(MediaControllerTest, DisableLockScreenMediaKeysIfPreferenceDisabled) { base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(features::kLockScreenMediaKeys); + feature_list.InitAndEnableFeature(features::kLockScreenMediaControls); PrefService* prefs = Shell::Get()->session_controller()->GetPrimaryUserPrefService(); - prefs->SetBoolean(prefs::kLockScreenMediaKeysEnabled, false); + prefs->SetBoolean(prefs::kLockScreenMediaControlsEnabled, false); EXPECT_FALSE( Shell::Get()->media_controller()->AreLockScreenMediaKeysEnabled()); } -TEST_F(MediaControllerTest, EnableMediaKeysWhenLockedAndKeysEnabled) { +TEST_F(MediaControllerTest, EnableMediaKeysWhenLockedAndControlsEnabled) { base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(features::kLockScreenMediaKeys); + feature_list.InitAndEnableFeature(features::kLockScreenMediaControls); PrefService* prefs = Shell::Get()->session_controller()->GetPrimaryUserPrefService(); - prefs->SetBoolean(prefs::kLockScreenMediaKeysEnabled, true); + prefs->SetBoolean(prefs::kLockScreenMediaControlsEnabled, true); EXPECT_EQ(0, controller()->suspend_count()); EXPECT_EQ(0, controller()->previous_track_count()); @@ -158,10 +158,10 @@ EXPECT_EQ(1, controller()->next_track_count()); } -TEST_F(MediaControllerTest, DisableMediaKeysWhenLockedAndKeysDisabled) { +TEST_F(MediaControllerTest, DisableMediaKeysWhenLockedAndControlsDisabled) { PrefService* prefs = Shell::Get()->session_controller()->GetPrimaryUserPrefService(); - prefs->SetBoolean(prefs::kLockScreenMediaKeysEnabled, false); + prefs->SetBoolean(prefs::kLockScreenMediaControlsEnabled, false); EXPECT_EQ(0, controller()->suspend_count()); EXPECT_EQ(0, controller()->previous_track_count());
diff --git a/ash/public/cpp/ash_features.cc b/ash/public/cpp/ash_features.cc index 698a7f7d..3b9d9f8 100644 --- a/ash/public/cpp/ash_features.cc +++ b/ash/public/cpp/ash_features.cc
@@ -29,9 +29,6 @@ "LockScreenHideSensitiveNotificationsSupport", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kLockScreenMediaKeys{"LockScreenMediaKeys", - base::FEATURE_DISABLED_BY_DEFAULT}; - const base::Feature kLockScreenMediaControls{"LockScreenMediaControls", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ash/public/cpp/ash_features.h b/ash/public/cpp/ash_features.h index cb74086..2c1b9391 100644 --- a/ash/public/cpp/ash_features.h +++ b/ash/public/cpp/ash_features.h
@@ -37,10 +37,8 @@ ASH_PUBLIC_EXPORT extern const base::Feature kLockScreenHideSensitiveNotificationsSupport; -// Enables user preference to control media keys on the lock screen. -ASH_PUBLIC_EXPORT extern const base::Feature kLockScreenMediaKeys; - -// Enables lock screen media controls UI. +// Enables lock screen media controls UI and use of media keys on the lock +// screen. ASH_PUBLIC_EXPORT extern const base::Feature kLockScreenMediaControls; // Enables hiding of ARC media notifications. If this is enabled, all ARC
diff --git a/ash/public/cpp/ash_pref_names.cc b/ash/public/cpp/ash_pref_names.cc index 4e2777d..be0e204 100644 --- a/ash/public/cpp/ash_pref_names.cc +++ b/ash/public/cpp/ash_pref_names.cc
@@ -459,8 +459,9 @@ const char kAssistantPrivacyInfoDismissedInLauncher[] = "ash.launcher.assistant_privacy_info_dismissed"; -// A boolean pref that indicates whether lock screen media keys are enabled. -const char kLockScreenMediaKeysEnabled[] = "ash.lock_screen_media_keys_enabled"; +// A boolean pref that indicates whether lock screen media controls are enabled. +const char kLockScreenMediaControlsEnabled[] = + "ash.lock_screen_media_controls_enabled"; // NOTE: New prefs should start with the "ash." prefix. Existing prefs moved // into this file should not be renamed, since they may be synced.
diff --git a/ash/public/cpp/ash_pref_names.h b/ash/public/cpp/ash_pref_names.h index 0a837ff..67b1b3f 100644 --- a/ash/public/cpp/ash_pref_names.h +++ b/ash/public/cpp/ash_pref_names.h
@@ -165,7 +165,7 @@ ASH_PUBLIC_EXPORT extern const char kAssistantPrivacyInfoShownInLauncher[]; ASH_PUBLIC_EXPORT extern const char kAssistantPrivacyInfoDismissedInLauncher[]; -ASH_PUBLIC_EXPORT extern const char kLockScreenMediaKeysEnabled[]; +ASH_PUBLIC_EXPORT extern const char kLockScreenMediaControlsEnabled[]; } // namespace prefs
diff --git a/ash/public/cpp/assistant/assistant_state_base.cc b/ash/public/cpp/assistant/assistant_state_base.cc index d60c3d6..96ff462 100644 --- a/ash/public/cpp/assistant/assistant_state_base.cc +++ b/ash/public/cpp/assistant/assistant_state_base.cc
@@ -44,4 +44,13 @@ return result.str(); } +void AssistantStateBase::AddObserver(AssistantStateObserver* observer) { + observers_.AddObserver(observer); + InitializeObserver(observer); +} + +void AssistantStateBase::RemoveObserver(AssistantStateObserver* observer) { + observers_.RemoveObserver(observer); +} + } // namespace ash
diff --git a/ash/public/cpp/assistant/assistant_state_base.h b/ash/public/cpp/assistant/assistant_state_base.h index 37191f5..c3768745 100644 --- a/ash/public/cpp/assistant/assistant_state_base.h +++ b/ash/public/cpp/assistant/assistant_state_base.h
@@ -13,6 +13,18 @@ namespace ash { +// A checked observer which receives Assistant state change. +class ASH_PUBLIC_EXPORT AssistantStateObserver : public base::CheckedObserver { + public: + AssistantStateObserver() = default; + ~AssistantStateObserver() override = default; + + virtual void OnAssistantConsentStatusChanged(int consent_status) {} + + private: + DISALLOW_COPY_AND_ASSIGN(AssistantStateObserver); +}; + // Plain data class that holds Assistant related prefs and states. This is // shared by both the controller that controlls these values and client proxy // that caches these values locally. Please do not use this object directly, @@ -31,6 +43,8 @@ return settings_enabled_; } + const base::Optional<int>& consent_status() const { return consent_status_; } + const base::Optional<bool>& context_enabled() const { return context_enabled_; } @@ -39,6 +53,18 @@ return hotword_enabled_; } + const base::Optional<bool>& hotword_always_on() const { + return hotword_always_on_; + } + + const base::Optional<bool>& launch_with_mic_open() const { + return launch_with_mic_open_; + } + + const base::Optional<bool>& notification_enabled() const { + return notification_enabled_; + } + const base::Optional<mojom::AssistantAllowedState>& allowed_state() const { return allowed_state_; } @@ -55,13 +81,21 @@ std::string ToString() const; + void AddObserver(AssistantStateObserver* observer); + void RemoveObserver(AssistantStateObserver* observer); + virtual void InitializeObserver(AssistantStateObserver* observer) {} + protected: base::Optional<mojom::VoiceInteractionState> voice_interaction_state_; + // TODO(b/138679823): Maybe remove Optional for preference values. // Whether voice interaction is enabled in system settings. nullopt if the // data is not available yet. base::Optional<bool> settings_enabled_; + // The status of the user's consent. nullopt if the data is not available yet. + base::Optional<int> consent_status_; + // Whether screen context is enabled. nullopt if the data is not available // yet. base::Optional<bool> context_enabled_; @@ -69,6 +103,16 @@ // Whether hotword listening is enabled. base::Optional<bool> hotword_enabled_; + // Whether hotword listening is always on/only with power source. nullopt + // if the data is not available yet. + base::Optional<bool> hotword_always_on_; + + // Whether the Assistant should launch with mic open; + base::Optional<bool> launch_with_mic_open_; + + // Whether notification is enabled. + base::Optional<bool> notification_enabled_; + // Whether voice interaction feature is allowed or disallowed for what reason. // nullopt if the data is not available yet. base::Optional<mojom::AssistantAllowedState> allowed_state_; @@ -82,6 +126,8 @@ // available yet. base::Optional<bool> locked_full_screen_enabled_; + base::ObserverList<AssistantStateObserver> observers_; + private: DISALLOW_COPY_AND_ASSIGN(AssistantStateBase); };
diff --git a/ash/public/cpp/voice_interaction_controller.h b/ash/public/cpp/voice_interaction_controller.h index e8c7774..cc7f222 100644 --- a/ash/public/cpp/voice_interaction_controller.h +++ b/ash/public/cpp/voice_interaction_controller.h
@@ -17,6 +17,7 @@ namespace ash { +// TODO(b/138679823): Merge this with AssistantPrefsController. class ASH_PUBLIC_EXPORT VoiceInteractionController : public mojom::VoiceInteractionController, public AssistantStateBase {
diff --git a/ash/shelf/overflow_bubble_view.cc b/ash/shelf/overflow_bubble_view.cc index 82afe04..c97e282 100644 --- a/ash/shelf/overflow_bubble_view.cc +++ b/ash/shelf/overflow_bubble_view.cc
@@ -224,7 +224,14 @@ gfx::Size OverflowBubbleView::OverflowShelfContainerView::CalculatePreferredSize() const { - return shelf_view_->CalculatePreferredSize(); + const int width = + ShelfView::GetSizeOfAppIcons(shelf_view_->last_visible_index() - + shelf_view_->first_visible_index() + 1, + /* with_overflow=*/false); + const int height = ShelfConstants::button_size(); + return shelf_view_->shelf()->IsHorizontalAlignment() + ? gfx::Size(width, height) + : gfx::Size(height, width); } void OverflowBubbleView::OverflowShelfContainerView::ChildPreferredSizeChanged( @@ -525,7 +532,7 @@ ? preferred_size.width() : preferred_size.height(); preferred_length += 2 * kEndPadding; - int scroll_length = + const int scroll_length = shelf_->IsHorizontalAlignment() ? scroll_offset_.x() : scroll_offset_.y(); if (preferred_length <= available_length) {
diff --git a/ash/shelf/shelf.cc b/ash/shelf/shelf.cc index cf09725..91f43ad5 100644 --- a/ash/shelf/shelf.cc +++ b/ash/shelf/shelf.cc
@@ -124,8 +124,8 @@ DCHECK(!shelf_widget_); aura::Window* shelf_container = root->GetChildById(kShellWindowId_ShelfContainer); - shelf_widget_.reset(new ShelfWidget(shelf_container, this)); - shelf_widget_->Initialize(); + shelf_widget_.reset(new ShelfWidget(this)); + shelf_widget_->Initialize(shelf_container); DCHECK(!shelf_layout_manager_); shelf_layout_manager_ = shelf_widget_->shelf_layout_manager();
diff --git a/ash/shelf/shelf_bubble.cc b/ash/shelf/shelf_bubble.cc index 272a96e5..69e1c1ea 100644 --- a/ash/shelf/shelf_bubble.cc +++ b/ash/shelf/shelf_bubble.cc
@@ -5,6 +5,7 @@ #include "ash/shelf/shelf_bubble.h" #include "ash/public/cpp/shell_window_ids.h" +#include "ui/accessibility/ax_enums.mojom.h" #include "ui/aura/window.h" #include "ui/views/bubble/bubble_frame_view.h"
diff --git a/ash/shelf/shelf_view.cc b/ash/shelf/shelf_view.cc index e61d630..01e05948 100644 --- a/ash/shelf/shelf_view.cc +++ b/ash/shelf/shelf_view.cc
@@ -121,27 +121,6 @@ Shell::Get()->tablet_mode_controller()->InTabletMode(); } -// Returns the size occupied by |count| app icons. If |with_overflow| is -// true, returns the size of |count| app icons followed by an overflow -// button. -int GetSizeOfAppIcons(int count, bool with_overflow) { - const int control_size = ShelfConstants::control_size(); - const int button_spacing = ShelfConstants::button_spacing(); - const int overflow_button_margin = ShelfConstants::overflow_button_margin(); - - if (count == 0) - return with_overflow ? control_size + 2 * overflow_button_margin : 0; - - const int app_size = count * ShelfConstants::button_size(); - int overflow_size = 0; - int total_padding = button_spacing * (count - 1); - if (with_overflow) { - overflow_size += control_size; - total_padding += button_spacing + 2 * overflow_button_margin; - } - return app_size + total_padding + overflow_size; -} - // A class to temporarily disable a given bounds animator. class BoundsAnimatorDisabler { public: @@ -361,6 +340,24 @@ model_->RemoveObserver(this); } +int ShelfView::GetSizeOfAppIcons(int count, bool with_overflow) { + const int control_size = ShelfConstants::control_size(); + const int button_spacing = ShelfConstants::button_spacing(); + const int overflow_button_margin = ShelfConstants::overflow_button_margin(); + + if (count == 0) + return with_overflow ? control_size + 2 * overflow_button_margin : 0; + + const int app_size = count * ShelfConstants::button_size(); + int overflow_size = 0; + int total_padding = button_spacing * (count - 1); + if (with_overflow) { + overflow_size += control_size; + total_padding += button_spacing + 2 * overflow_button_margin; + } + return app_size + total_padding + overflow_size; +} + void ShelfView::Init() { separator_ = new views::Separator(); separator_->SetColor(kSeparatorColor);
diff --git a/ash/shelf/shelf_view.h b/ash/shelf/shelf_view.h index cece3da..8bc8cf4 100644 --- a/ash/shelf/shelf_view.h +++ b/ash/shelf/shelf_view.h
@@ -122,6 +122,11 @@ Shelf* shelf() const { return shelf_; } ShelfModel* model() const { return model_; } + // Returns the size occupied by |count| app icons. If |with_overflow| is + // true, returns the size of |count| app icons followed by an overflow + // button. + static int GetSizeOfAppIcons(int count, bool with_overflow); + // Initializes shelf view elements. void Init();
diff --git a/ash/shelf/shelf_widget.cc b/ash/shelf/shelf_widget.cc index 17e6eb7..2f274b5a 100644 --- a/ash/shelf/shelf_widget.cc +++ b/ash/shelf/shelf_widget.cc
@@ -297,7 +297,7 @@ return true; } -ShelfWidget::ShelfWidget(aura::Window* shelf_container, Shelf* shelf) +ShelfWidget::ShelfWidget(Shelf* shelf) : shelf_(shelf), background_animator_(SHELF_BACKGROUND_DEFAULT, shelf_, @@ -305,12 +305,21 @@ shelf_layout_manager_(new ShelfLayoutManager(this, shelf)), delegate_view_(new DelegateView(this)), shelf_view_(new ShelfView(ShelfModel::Get(), shelf_)), - login_shelf_view_( - new LoginShelfView(RootWindowController::ForWindow(shelf_container) - ->lock_screen_action_background_controller())), scoped_session_observer_(this) { - DCHECK(shelf_container); DCHECK(shelf_); +} + +ShelfWidget::~ShelfWidget() { + // Must call Shutdown() before destruction. + DCHECK(!status_area_widget_); +} + +void ShelfWidget::Initialize(aura::Window* shelf_container) { + DCHECK(shelf_container); + + login_shelf_view_ = + new LoginShelfView(RootWindowController::ForWindow(shelf_container) + ->lock_screen_action_background_controller()); views::Widget::InitParams params( views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); @@ -342,14 +351,7 @@ background_animator_.AddObserver(delegate_view_); shelf_->AddObserver(this); -} -ShelfWidget::~ShelfWidget() { - // Must call Shutdown() before destruction. - DCHECK(!status_area_widget_); -} - -void ShelfWidget::Initialize() { // Sets initial session state to make sure the UI is properly shown. OnSessionStateChanged(Shell::Get()->session_controller()->GetSessionState()); GetFocusManager()->set_arrow_key_traversal_enabled_for_widget(true);
diff --git a/ash/shelf/shelf_widget.h b/ash/shelf/shelf_widget.h index db68597..a41c6fd8 100644 --- a/ash/shelf/shelf_widget.h +++ b/ash/shelf/shelf_widget.h
@@ -40,14 +40,14 @@ public ShelfObserver, public SessionObserver { public: - ShelfWidget(aura::Window* shelf_container, Shelf* shelf); + explicit ShelfWidget(Shelf* shelf); ~ShelfWidget() override; // Sets the initial session state and show the UI. Not part of the constructor // because showing the UI triggers the accessibility checks in browser_tests, // which will crash unless the constructor returns, allowing the caller // to store the constructed widget. - void Initialize(); + void Initialize(aura::Window* shelf_container); // Clean up prior to deletion. void Shutdown(); @@ -168,7 +168,7 @@ // View containing the shelf items for Login/Lock/OOBE/Add User screens. // Owned by the views hierarchy. - LoginShelfView* const login_shelf_view_; + LoginShelfView* login_shelf_view_; // Set to true when the widget is activated from another widget. Do not // focus the default element in this case. This should be set when
diff --git a/ash/system/network/network_state_list_detailed_view.cc b/ash/system/network/network_state_list_detailed_view.cc index ad8bb5b..b393caf0 100644 --- a/ash/system/network/network_state_list_detailed_view.cc +++ b/ash/system/network/network_state_list_detailed_view.cc
@@ -21,6 +21,7 @@ #include "chromeos/network/network_connect.h" #include "net/base/ip_address.h" #include "third_party/cros_system_api/dbus/service_constants.h" +#include "ui/accessibility/ax_enums.mojom.h" #include "ui/base/l10n/l10n_util.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" #include "ui/views/controls/button/button.h"
diff --git a/ash/system/toast/toast_overlay.cc b/ash/system/toast/toast_overlay.cc index feff7ef..79bdcbd 100644 --- a/ash/system/toast/toast_overlay.cc +++ b/ash/system/toast/toast_overlay.cc
@@ -15,6 +15,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_task_runner_handle.h" #include "third_party/skia/include/core/SkColor.h" +#include "ui/accessibility/ax_enums.mojom.h" #include "ui/base/l10n/l10n_util.h" #include "ui/display/display_observer.h" #include "ui/gfx/canvas.h"
diff --git a/ash/system/tray/tray_bubble_view.cc b/ash/system/tray/tray_bubble_view.cc index 1606795..3450eba 100644 --- a/ash/system/tray/tray_bubble_view.cc +++ b/ash/system/tray/tray_bubble_view.cc
@@ -12,6 +12,7 @@ #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkPath.h" #include "third_party/skia/include/effects/SkBlurImageFilter.h" +#include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_node_data.h" #include "ui/aura/env.h" #include "ui/aura/window.h"
diff --git a/ash/system/tray/tray_bubble_view.h b/ash/system/tray/tray_bubble_view.h index ca8efd14..15cd5a0 100644 --- a/ash/system/tray/tray_bubble_view.h +++ b/ash/system/tray/tray_bubble_view.h
@@ -11,7 +11,7 @@ #include "ash/public/cpp/shelf_types.h" #include "base/macros.h" #include "base/optional.h" -#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_enums.mojom-forward.h" #include "ui/events/event.h" #include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/rect.h"
diff --git a/ash/system/unified/page_indicator_view.cc b/ash/system/unified/page_indicator_view.cc index 7a68ea70..306546efd 100644 --- a/ash/system/unified/page_indicator_view.cc +++ b/ash/system/unified/page_indicator_view.cc
@@ -16,6 +16,7 @@ #include "base/macros.h" #include "base/metrics/histogram_macros.h" #include "third_party/skia/include/core/SkPath.h" +#include "ui/accessibility/ax_enums.mojom.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/animation/throb_animation.h" #include "ui/gfx/canvas.h"
diff --git a/ash/system/unified/unified_slider_bubble_controller.cc b/ash/system/unified/unified_slider_bubble_controller.cc index dee3470..abd2917 100644 --- a/ash/system/unified/unified_slider_bubble_controller.cc +++ b/ash/system/unified/unified_slider_bubble_controller.cc
@@ -16,6 +16,7 @@ #include "ash/system/unified/unified_system_tray.h" #include "ash/system/unified/unified_system_tray_bubble.h" #include "ash/system/unified/unified_system_tray_view.h" +#include "ui/accessibility/ax_enums.mojom.h" using chromeos::CrasAudioHandler;
diff --git a/ash/system/unified/unified_system_info_view.cc b/ash/system/unified/unified_system_info_view.cc index 8c230c2..4e50093e 100644 --- a/ash/system/unified/unified_system_info_view.cc +++ b/ash/system/unified/unified_system_info_view.cc
@@ -25,6 +25,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" #include "chromeos/strings/grit/chromeos_strings.h" +#include "ui/accessibility/ax_enums.mojom.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/paint_vector_icon.h" #include "ui/views/animation/ink_drop_highlight.h"
diff --git a/ash/wallpaper/wallpaper_view.cc b/ash/wallpaper/wallpaper_view.cc index 13c874b10..d9e7fa53 100644 --- a/ash/wallpaper/wallpaper_view.cc +++ b/ash/wallpaper/wallpaper_view.cc
@@ -10,7 +10,6 @@ #include "ash/shell.h" #include "ash/wallpaper/wallpaper_controller_impl.h" #include "ash/wallpaper/wallpaper_widget_controller.h" -#include "ash/wm/overview/overview_grid_pre_event_handler.h" #include "cc/paint/render_surface_filters.h" #include "ui/aura/window.h" #include "ui/display/display.h" @@ -71,17 +70,11 @@ // WallpaperView, public: WallpaperView::WallpaperView(int blur, float opacity) - : repaint_blur_(blur), - repaint_opacity_(opacity), - overview_grid_pre_event_handler_( - std::make_unique<OverviewGridPreEventHandler>()) { + : repaint_blur_(blur), repaint_opacity_(opacity) { set_context_menu_controller(this); - AddPreTargetHandler(overview_grid_pre_event_handler_.get()); } -WallpaperView::~WallpaperView() { - RemovePreTargetHandler(overview_grid_pre_event_handler_.get()); -} +WallpaperView::~WallpaperView() = default; void WallpaperView::RepaintBlurAndOpacity(int repaint_blur, float repaint_opacity) {
diff --git a/ash/wallpaper/wallpaper_view.h b/ash/wallpaper/wallpaper_view.h index 8610c75..828bf7c 100644 --- a/ash/wallpaper/wallpaper_view.h +++ b/ash/wallpaper/wallpaper_view.h
@@ -14,8 +14,6 @@ namespace ash { -class OverviewGridPreEventHandler; - // The desktop wallpaper view that, in addition to painting the wallpaper, can // also add blur and dimming effects, as well as handle context menu requests. class WallpaperView : public WallpaperBaseView, @@ -60,10 +58,6 @@ // blur/brightness animations be more performant. base::Optional<gfx::ImageSkia> small_image_; - // A event handler that handles taps and closes overview if we are in that - // mode. - std::unique_ptr<OverviewGridPreEventHandler> overview_grid_pre_event_handler_; - DISALLOW_COPY_AND_ASSIGN(WallpaperView); };
diff --git a/ash/wm/overview/caption_container_view.cc b/ash/wm/overview/caption_container_view.cc index c0e39e9..261fe238 100644 --- a/ash/wm/overview/caption_container_view.cc +++ b/ash/wm/overview/caption_container_view.cc
@@ -65,12 +65,6 @@ parent->AddChildView(child); } -gfx::PointF ConvertToScreen(views::View* view, const gfx::Point& location) { - gfx::Point location_copy(location); - views::View::ConvertPointToScreen(view, &location_copy); - return gfx::PointF(location_copy); -} - // Animates |layer| from 0 -> 1 opacity if |visible| and 1 -> 0 opacity // otherwise. The tween type differs for |visible| and if |visible| is true // there is a slight delay before the animation begins. Does not animate if @@ -308,15 +302,14 @@ bool CaptionContainerView::OnMousePressed(const ui::MouseEvent& event) { if (!event_delegate_) return Button::OnMousePressed(event); - event_delegate_->HandlePressEvent(ConvertToScreen(this, event.location()), - /*from_touch_gesture=*/false); + event_delegate_->HandleMouseEvent(event); return true; } bool CaptionContainerView::OnMouseDragged(const ui::MouseEvent& event) { if (!event_delegate_) return Button::OnMouseDragged(event); - event_delegate_->HandleDragEvent(ConvertToScreen(this, event.location())); + event_delegate_->HandleMouseEvent(event); return true; } @@ -325,7 +318,7 @@ Button::OnMouseReleased(event); return; } - event_delegate_->HandleReleaseEvent(ConvertToScreen(this, event.location())); + event_delegate_->HandleMouseEvent(event); } void CaptionContainerView::OnGestureEvent(ui::GestureEvent* event) { @@ -337,34 +330,7 @@ return; } - const gfx::PointF location = event->details().bounding_box_f().CenterPoint(); - switch (event->type()) { - case ui::ET_GESTURE_TAP_DOWN: - event_delegate_->HandlePressEvent(location, /*from_touch_gesture=*/true); - break; - case ui::ET_GESTURE_SCROLL_UPDATE: - event_delegate_->HandleDragEvent(location); - break; - case ui::ET_SCROLL_FLING_START: - event_delegate_->HandleFlingStartEvent(location, - event->details().velocity_x(), - event->details().velocity_y()); - break; - case ui::ET_GESTURE_SCROLL_END: - event_delegate_->HandleReleaseEvent(location); - break; - case ui::ET_GESTURE_LONG_PRESS: - event_delegate_->HandleLongPressEvent(location); - break; - case ui::ET_GESTURE_TAP: - event_delegate_->HandleTapEvent(); - break; - case ui::ET_GESTURE_END: - event_delegate_->HandleGestureEndEvent(); - break; - default: - break; - } + event_delegate_->HandleGestureEvent(event); event->SetHandled(); }
diff --git a/ash/wm/overview/caption_container_view.h b/ash/wm/overview/caption_container_view.h index 89b7b8a..f24579c 100644 --- a/ash/wm/overview/caption_container_view.h +++ b/ash/wm/overview/caption_container_view.h
@@ -43,18 +43,8 @@ class EventDelegate { public: - // TODO(sammiequon): Maybe consolidate into just mouse and gesture events. - virtual void HandlePressEvent(const gfx::PointF& location_in_screen, - bool from_touch_gesture) = 0; - virtual void HandleDragEvent(const gfx::PointF& location_in_screen) = 0; - virtual void HandleReleaseEvent(const gfx::PointF& location_in_screen) = 0; - virtual void HandleFlingStartEvent(const gfx::PointF& location_in_screen, - float velocity_x, - float velocity_y) = 0; - virtual void HandleLongPressEvent( - const gfx::PointF& location_in_screen) = 0; - virtual void HandleTapEvent() = 0; - virtual void HandleGestureEndEvent() = 0; + virtual void HandleMouseEvent(const ui::MouseEvent& event) = 0; + virtual void HandleGestureEvent(ui::GestureEvent* event) = 0; virtual bool ShouldIgnoreGestureEvents() = 0; virtual void OnHighlightedViewActivated() = 0; virtual void OnHighlightedViewClosed() = 0;
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc index 2abaa3a..b70f579 100644 --- a/ash/wm/overview/overview_grid.cc +++ b/ash/wm/overview/overview_grid.cc
@@ -28,6 +28,7 @@ #include "ash/wm/overview/overview_constants.h" #include "ash/wm/overview/overview_controller.h" #include "ash/wm/overview/overview_delegate.h" +#include "ash/wm/overview/overview_grid_pre_event_handler.h" #include "ash/wm/overview/overview_highlight_controller.h" #include "ash/wm/overview/overview_item.h" #include "ash/wm/overview/overview_session.h" @@ -367,6 +368,7 @@ void OverviewGrid::Shutdown() { ScreenRotationAnimator::GetForRootWindow(root_window_)->RemoveObserver(this); + grid_pre_event_handler_.reset(); bool has_non_cover_animating = false; int animate_count = 0; @@ -408,6 +410,8 @@ if (Shell::Get()->tablet_mode_controller()->InTabletMode()) { ScreenRotationAnimator::GetForRootWindow(root_window_)->AddObserver(this); } + + grid_pre_event_handler_ = std::make_unique<OverviewGridPreEventHandler>(this); } void OverviewGrid::PositionWindows(
diff --git a/ash/wm/overview/overview_grid.h b/ash/wm/overview/overview_grid.h index 8195fd8f..cf2e8d1 100644 --- a/ash/wm/overview/overview_grid.h +++ b/ash/wm/overview/overview_grid.h
@@ -29,6 +29,7 @@ class DesksBarView; class FpsCounter; +class OverviewGridPreEventHandler; class OverviewItem; // Represents a grid of windows in the Overview Mode in a particular root @@ -431,6 +432,9 @@ // are visible in tablet overview mode. float scroll_offset_min_ = 0; + // Handles events that are not handled by the OverviewItems. + std::unique_ptr<OverviewGridPreEventHandler> grid_pre_event_handler_; + DISALLOW_COPY_AND_ASSIGN(OverviewGrid); };
diff --git a/ash/wm/overview/overview_grid_pre_event_handler.cc b/ash/wm/overview/overview_grid_pre_event_handler.cc index a4da9e4..b80710f 100644 --- a/ash/wm/overview/overview_grid_pre_event_handler.cc +++ b/ash/wm/overview/overview_grid_pre_event_handler.cc
@@ -3,18 +3,36 @@ // found in the LICENSE file. #include "ash/wm/overview/overview_grid_pre_event_handler.h" + +#include "ash/root_window_controller.h" #include "ash/shell.h" +#include "ash/wallpaper/wallpaper_view.h" +#include "ash/wallpaper/wallpaper_widget_controller.h" #include "ash/wm/overview/overview_controller.h" #include "ash/wm/overview/overview_grid.h" #include "ash/wm/overview/overview_utils.h" -#include "ash/wm/window_util.h" #include "ui/events/event.h" namespace ash { -OverviewGridPreEventHandler::OverviewGridPreEventHandler() = default; +namespace { -OverviewGridPreEventHandler::~OverviewGridPreEventHandler() = default; +WallpaperView* GetWallpaperViewForRoot(const aura::Window* root_window) { + return RootWindowController::ForWindow(root_window) + ->wallpaper_widget_controller() + ->wallpaper_view(); +} + +} // namespace + +OverviewGridPreEventHandler::OverviewGridPreEventHandler(OverviewGrid* grid) + : grid_(grid) { + GetWallpaperViewForRoot(grid_->root_window())->AddPreTargetHandler(this); +} + +OverviewGridPreEventHandler::~OverviewGridPreEventHandler() { + GetWallpaperViewForRoot(grid_->root_window())->RemovePreTargetHandler(this); +} void OverviewGridPreEventHandler::OnMouseEvent(ui::MouseEvent* event) { if (event->type() == ui::ET_MOUSE_RELEASED) @@ -22,8 +40,6 @@ } void OverviewGridPreEventHandler::OnGestureEvent(ui::GestureEvent* event) { - // TODO(sammiequon): Investigate why scrolling on the bottom of the grid exits - // overview. switch (event->type()) { case ui::ET_GESTURE_TAP: HandleClickOrTap(event); @@ -53,23 +69,14 @@ void OverviewGridPreEventHandler::HandleClickOrTap(ui::Event* event) { CHECK_EQ(ui::EP_PRETARGET, event->phase()); - auto* controller = Shell::Get()->overview_controller(); - if (!controller->InOverviewSession()) - return; // Events that happen while app list is sliding out during overview should // be ignored to prevent overview from disappearing out from under the user. if (!IsSlidingOutOverviewFromShelf()) - controller->EndOverview(); + Shell::Get()->overview_controller()->EndOverview(); event->StopPropagation(); } void OverviewGridPreEventHandler::StartDrag(const gfx::Point& location) { - // TODO(sammiequon): Investigate if this can be passed in the constructor. - auto* controller = Shell::Get()->overview_controller(); - if (!controller->InOverviewSession()) - return; - grid_ = controller->overview_session()->GetGridWithRootWindow( - window_util::GetRootWindowAt(location)); grid_->PrepareScrollLimitMin(); }
diff --git a/ash/wm/overview/overview_grid_pre_event_handler.h b/ash/wm/overview/overview_grid_pre_event_handler.h index 789abe5..dda304d8 100644 --- a/ash/wm/overview/overview_grid_pre_event_handler.h +++ b/ash/wm/overview/overview_grid_pre_event_handler.h
@@ -25,7 +25,7 @@ // - Scrolling through tablet overview mode on scrolling. class OverviewGridPreEventHandler : public ui::EventHandler { public: - OverviewGridPreEventHandler(); + explicit OverviewGridPreEventHandler(OverviewGrid* grid); ~OverviewGridPreEventHandler() override; private: @@ -39,8 +39,8 @@ void UpdateDrag(float scroll); // Cached value of the OverviewGrid that handles a series of gesture scroll - // events. - OverviewGrid* grid_ = nullptr; + // events. Guaranteed to be alive during the lifetime of |this|. + OverviewGrid* grid_; DISALLOW_COPY_AND_ASSIGN(OverviewGridPreEventHandler); };
diff --git a/ash/wm/overview/overview_highlight_controller.cc b/ash/wm/overview/overview_highlight_controller.cc index 35605006..c16a133 100644 --- a/ash/wm/overview/overview_highlight_controller.cc +++ b/ash/wm/overview/overview_highlight_controller.cc
@@ -18,6 +18,7 @@ #include "ash/wm/overview/overview_session.h" #include "ash/wm/overview/overview_utils.h" #include "ash/wm/overview/scoped_overview_animation_settings.h" +#include "ui/accessibility/ax_enums.mojom.h" #include "ui/compositor_extra/shadow.h" #include "ui/views/view.h" #include "ui/views/widget/widget.h"
diff --git a/ash/wm/overview/overview_item.cc b/ash/wm/overview/overview_item.cc index 6697e00..56246964 100644 --- a/ash/wm/overview/overview_item.cc +++ b/ash/wm/overview/overview_item.cc
@@ -35,6 +35,7 @@ #include "ash/wm/wm_event.h" #include "base/auto_reset.h" #include "base/metrics/user_metrics.h" +#include "ui/accessibility/ax_enums.mojom.h" #include "ui/base/l10n/l10n_util.h" #include "ui/compositor/layer_animation_sequence.h" #include "ui/compositor/scoped_animation_duration_scale_mode.h" @@ -792,57 +793,52 @@ : OVERVIEW_ANIMATION_RESTORE_WINDOW_ZERO; } -void OverviewItem::HandlePressEvent(const gfx::PointF& location_in_screen, - bool from_touch_gesture) { - // We allow switching finger while dragging, but do not allow dragging two or - // more items. - if (overview_session_->window_drag_controller() && - overview_session_->window_drag_controller()->item()) { - return; +void OverviewItem::HandleMouseEvent(const ui::MouseEvent& event) { + const gfx::PointF screen_location = event.target()->GetScreenLocationF(event); + switch (event.type()) { + case ui::ET_MOUSE_PRESSED: + HandlePressEvent(screen_location, /*from_touch_gesture=*/false); + break; + case ui::ET_MOUSE_RELEASED: + HandleReleaseEvent(screen_location); + break; + case ui::ET_MOUSE_DRAGGED: + HandleDragEvent(screen_location); + break; + default: + NOTREACHED(); + break; } - - StartDrag(); - overview_session_->InitiateDrag(this, location_in_screen, - /*allow_drag_to_close=*/from_touch_gesture); } -void OverviewItem::HandleReleaseEvent(const gfx::PointF& location_in_screen) { - if (!IsDragItem()) - return; - - overview_session_->CompleteDrag(this, location_in_screen); -} - -void OverviewItem::HandleDragEvent(const gfx::PointF& location_in_screen) { - if (!IsDragItem()) - return; - - overview_session_->Drag(this, location_in_screen); -} - -void OverviewItem::HandleLongPressEvent(const gfx::PointF& location_in_screen) { - if (ShouldAllowSplitView() || desks_util::ShouldDesksBarBeCreated()) - overview_session_->StartNormalDragMode(location_in_screen); -} - -void OverviewItem::HandleFlingStartEvent(const gfx::PointF& location_in_screen, - float velocity_x, - float velocity_y) { - overview_session_->Fling(this, location_in_screen, velocity_x, velocity_y); -} - -void OverviewItem::HandleTapEvent() { - if (!IsDragItem()) - return; - - overview_session_->ActivateDraggedWindow(); -} - -void OverviewItem::HandleGestureEndEvent() { - if (!IsDragItem()) - return; - - overview_session_->ResetDraggedWindowGesture(); +void OverviewItem::HandleGestureEvent(ui::GestureEvent* event) { + const gfx::PointF location = event->details().bounding_box_f().CenterPoint(); + switch (event->type()) { + case ui::ET_GESTURE_TAP_DOWN: + HandlePressEvent(location, /*from_touch_gesture=*/true); + break; + case ui::ET_GESTURE_SCROLL_UPDATE: + HandleDragEvent(location); + break; + case ui::ET_SCROLL_FLING_START: + HandleFlingStartEvent(location, event->details().velocity_x(), + event->details().velocity_y()); + break; + case ui::ET_GESTURE_SCROLL_END: + HandleReleaseEvent(location); + break; + case ui::ET_GESTURE_LONG_PRESS: + HandleLongPressEvent(location); + break; + case ui::ET_GESTURE_TAP: + HandleTapEvent(); + break; + case ui::ET_GESTURE_END: + HandleGestureEndEvent(); + break; + default: + break; + } } bool OverviewItem::ShouldIgnoreGestureEvents() { @@ -1053,6 +1049,59 @@ } } +void OverviewItem::HandlePressEvent(const gfx::PointF& location_in_screen, + bool from_touch_gesture) { + // We allow switching finger while dragging, but do not allow dragging two or + // more items. + if (overview_session_->window_drag_controller() && + overview_session_->window_drag_controller()->item()) { + return; + } + + StartDrag(); + overview_session_->InitiateDrag(this, location_in_screen, + /*allow_drag_to_close=*/from_touch_gesture); +} + +void OverviewItem::HandleReleaseEvent(const gfx::PointF& location_in_screen) { + if (!IsDragItem()) + return; + + overview_session_->CompleteDrag(this, location_in_screen); +} + +void OverviewItem::HandleDragEvent(const gfx::PointF& location_in_screen) { + if (!IsDragItem()) + return; + + overview_session_->Drag(this, location_in_screen); +} + +void OverviewItem::HandleLongPressEvent(const gfx::PointF& location_in_screen) { + if (ShouldAllowSplitView() || desks_util::ShouldDesksBarBeCreated()) + overview_session_->StartNormalDragMode(location_in_screen); +} + +void OverviewItem::HandleFlingStartEvent(const gfx::PointF& location_in_screen, + float velocity_x, + float velocity_y) { + overview_session_->Fling(this, location_in_screen, velocity_x, velocity_y); +} + +void OverviewItem::HandleTapEvent() { + if (!IsDragItem()) + return; + + overview_session_->ActivateDraggedWindow(); +} + +void OverviewItem::HandleGestureEndEvent() { + if (!IsDragItem()) + return; + + overview_session_->ResetDraggedWindowGesture(); +} + void OverviewItem::StartDrag() { // |transform_window_| handles hiding shadow and rounded edges mask while // animating, and applies them after animation is complete. Prevent the
diff --git a/ash/wm/overview/overview_item.h b/ash/wm/overview/overview_item.h index cfd352f..1d896021 100644 --- a/ash/wm/overview/overview_item.h +++ b/ash/wm/overview/overview_item.h
@@ -186,16 +186,8 @@ OverviewAnimationType GetExitTransformAnimationType(); // CaptionContainerView::EventDelegate: - void HandlePressEvent(const gfx::PointF& location_in_screen, - bool from_touch_gesture) override; - void HandleReleaseEvent(const gfx::PointF& location_in_screen) override; - void HandleDragEvent(const gfx::PointF& location_in_screen) override; - void HandleLongPressEvent(const gfx::PointF& location_in_screen) override; - void HandleFlingStartEvent(const gfx::PointF& location_in_screen, - float velocity_x, - float velocity_y) override; - void HandleTapEvent() override; - void HandleGestureEndEvent() override; + void HandleMouseEvent(const ui::MouseEvent& event) override; + void HandleGestureEvent(ui::GestureEvent* event) override; bool ShouldIgnoreGestureEvents() override; void OnHighlightedViewActivated() override; void OnHighlightedViewClosed() override; @@ -289,6 +281,20 @@ // it visible while dragging around. void StartDrag(); + // TODO(sammiequon): Current events go from CaptionContainerView to + // OverviewItem to OverviewSession to OverviewWindowDragController. We may be + // able to shorten this pipeline. + void HandlePressEvent(const gfx::PointF& location_in_screen, + bool from_touch_gesture); + void HandleReleaseEvent(const gfx::PointF& location_in_screen); + void HandleDragEvent(const gfx::PointF& location_in_screen); + void HandleLongPressEvent(const gfx::PointF& location_in_screen); + void HandleFlingStartEvent(const gfx::PointF& location_in_screen, + float velocity_x, + float velocity_y); + void HandleTapEvent(); + void HandleGestureEndEvent(); + // Returns the list of windows that we want to slide up or down when swiping // on the shelf in tablet mode. aura::Window::Windows GetWindowsForHomeGesture();
diff --git a/ash/wm/workspace/workspace_layout_manager.cc b/ash/wm/workspace/workspace_layout_manager.cc index fe6e29b..38d15bc 100644 --- a/ash/wm/workspace/workspace_layout_manager.cc +++ b/ash/wm/workspace/workspace_layout_manager.cc
@@ -199,9 +199,18 @@ void WorkspaceLayoutManager::SetChildBounds(aura::Window* child, const gfx::Rect& requested_bounds) { + WindowState* window_state = WindowState::Get(child); SetBoundsWMEvent event(requested_bounds); - WindowState::Get(child)->OnWMEvent(&event); - UpdateShelfVisibility(); + window_state->OnWMEvent(&event); + + // Setting bounds shouldn't trigger UpdateShelfVisibility(), especially for + // PIP because it can cause an unexpected call of updatePipBounds(). So avoid + // calling this for PIP windows for now. + // TODO(takise): Remove UpdateShelfVisibility() completely, which may be + // obsolete now. + if (!window_state->IsPip()) { + UpdateShelfVisibility(); + } } //////////////////////////////////////////////////////////////////////////////
diff --git a/base/version.cc b/base/version.cc index babe268..3ba39d4 100644 --- a/base/version.cc +++ b/base/version.cc
@@ -22,7 +22,7 @@ // when it reaches an invalid item (including the wildcard character). |parsed| // is the resulting integer vector. Function returns true if all numbers were // parsed successfully, false otherwise. -bool ParseVersionNumbers(const std::string& version_str, +bool ParseVersionNumbers(StringPiece version_str, std::vector<uint32_t>* parsed) { std::vector<StringPiece> numbers = SplitStringPiece(version_str, ".", KEEP_WHITESPACE, SPLIT_WANT_ALL); @@ -83,7 +83,7 @@ Version::~Version() = default; -Version::Version(const std::string& version_str) { +Version::Version(StringPiece version_str) { std::vector<uint32_t> parsed; if (!ParseVersionNumbers(version_str, &parsed)) return; @@ -99,16 +99,16 @@ } // static -bool Version::IsValidWildcardString(const std::string& wildcard_string) { - std::string version_string = wildcard_string; +bool Version::IsValidWildcardString(StringPiece wildcard_string) { + StringPiece version_string = wildcard_string; if (EndsWith(version_string, ".*", CompareCase::SENSITIVE)) - version_string.resize(version_string.size() - 2); + version_string = version_string.substr(0, version_string.size() - 2); Version version(version_string); return version.IsValid(); } -int Version::CompareToWildcardString(const std::string& wildcard_string) const { +int Version::CompareToWildcardString(StringPiece wildcard_string) const { DCHECK(IsValid()); DCHECK(Version::IsValidWildcardString(wildcard_string));
diff --git a/base/version.h b/base/version.h index b3a0956..272cbe8 100644 --- a/base/version.h +++ b/base/version.h
@@ -12,6 +12,7 @@ #include <vector> #include "base/base_export.h" +#include "base/strings/string_piece.h" namespace base { @@ -28,7 +29,7 @@ // Initializes from a decimal dotted version number, like "0.1.1". // Each component is limited to a uint16_t. Call IsValid() to learn // the outcome. - explicit Version(const std::string& version_str); + explicit Version(StringPiece version_str); // Initializes from a vector of components, like {1, 2, 3, 4}. Call IsValid() // to learn the outcome. @@ -43,7 +44,7 @@ // string may end with ".*" (e.g. 1.2.*, 1.*). Any other arrangement with "*" // is invalid (e.g. 1.*.3 or 1.2.3*). This functions defaults to standard // Version behavior (IsValid) if no wildcard is present. - static bool IsValidWildcardString(const std::string& wildcard_string); + static bool IsValidWildcardString(StringPiece wildcard_string); // Returns -1, 0, 1 for <, ==, >. int CompareTo(const Version& other) const; @@ -52,7 +53,7 @@ // newer version. This function will default to CompareTo if the string does // not end in wildcard sequence ".*". IsValidWildcard(wildcard_string) must be // true before using this function. - int CompareToWildcardString(const std::string& wildcard_string) const; + int CompareToWildcardString(StringPiece wildcard_string) const; // Return the string representation of this version. const std::string GetString() const;
diff --git a/build/config/chromecast/BUILD.gn b/build/config/chromecast/BUILD.gn index c8b2989..0c3b2cbe 100644 --- a/build/config/chromecast/BUILD.gn +++ b/build/config/chromecast/BUILD.gn
@@ -34,11 +34,15 @@ # This is explicitly disabled in Chrome for security reasons (see comments in # //build/config/gcc/BUILD.gn), but necessary on Chromecast so that OEM's may # override the default libraries shipped in the Cast receiver package. - ldflags = [ - "-Wl,-rpath=/oem_cast_shlib", - "-Wl,-rpath=\$ORIGIN/lib", - "-Wl,-rpath=\$ORIGIN", - ] + if (target_rpath == "") { + ldflags = [ + "-Wl,-rpath=/oem_cast_shlib", + "-Wl,-rpath=\$ORIGIN/lib", + "-Wl,-rpath=\$ORIGIN", + ] + } else { + ldflags = [ "-Wl,-rpath=${target_rpath}" ] + } # Binaries which don't live in the same directory as Chrome component # libraries may still depend on them. Explicitly add the component library
diff --git a/build/config/chromecast_build.gni b/build/config/chromecast_build.gni index e27cccf6..3702acc 100644 --- a/build/config/chromecast_build.gni +++ b/build/config/chromecast_build.gni
@@ -21,6 +21,10 @@ # Set this true for an audio-only Chromecast build. is_cast_audio_only = false + + # If non empty, rpath of executables is set to this. + # If empty, default value is used. + target_rpath = "" } # Note(slan): This arg depends on the value of is_chromecast, and thus must be
diff --git a/build/config/fuchsia/tests.cmx b/build/config/fuchsia/tests.cmx index eeb526d..0419db8 100644 --- a/build/config/fuchsia/tests.cmx +++ b/build/config/fuchsia/tests.cmx
@@ -18,10 +18,9 @@ "fuchsia.logger.Log", "fuchsia.logger.LogSink", "fuchsia.media.Audio", - "fuchsia.media.drm.WidevineContentDecryptionModule", + "fuchsia.media.drm.Widevine", "fuchsia.mediacodec.CodecFactory", "fuchsia.net.NameLookup", - "fuchsia.net.SocketProvider", "fuchsia.netstack.Netstack", "fuchsia.posix.socket.Provider", "fuchsia.process.Launcher",
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index d38b8e70a..d1430ab 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -8905880171568947312 \ No newline at end of file +8905823319988905248 \ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 95ca517..e8d7d924 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -8905880172285496704 \ No newline at end of file +8905833153311204368 \ No newline at end of file
diff --git a/build/toolchain/win/tool_wrapper.py b/build/toolchain/win/tool_wrapper.py index 9260866..1ad3712 100644 --- a/build/toolchain/win/tool_wrapper.py +++ b/build/toolchain/win/tool_wrapper.py
@@ -15,20 +15,37 @@ import shutil import subprocess import stat -import string import sys -# tool_wrapper.py doesn't get invoked through python.bat so the Python bin -# directory doesn't get added to the path. The Python module search logic -# handles this fine and finds win32file.pyd. However the Windows module -# search logic then looks for pywintypes27.dll and other DLLs in the path and -# if it finds versions with a different bitness first then win32file.pyd will -# fail to load with a cryptic error: -# ImportError: DLL load failed: %1 is not a valid Win32 application. -if sys.platform == 'win32': - os.environ['PATH'] = os.path.dirname(sys.executable) + \ - os.pathsep + os.environ['PATH'] - import win32file # pylint: disable=import-error +# Embedded vpython spec to provide `win32file` when this is invoked with +# vpython. +# +# [VPYTHON:BEGIN] +# wheel: < +# name: "infra/python/wheels/pypiwin32/${vpython_platform}" +# version: "version:219" +# > +# [VPYTHON:END] + +try: + # First, try the normal way. This will work for python installations which + # have win32file already, or for vpython invocations of this script. + import win32file +except ImportError: + # Otherwise, do a hack to locate the depot_tools specific version of + # win32file. + # + # tool_wrapper.py doesn't get invoked through python.bat so the Python bin + # directory doesn't get added to the path. The Python module search logic + # handles this fine and finds win32file.pyd. However the Windows module + # search logic then looks for pywintypes27.dll and other DLLs in the path and + # if it finds versions with a different bitness first then win32file.pyd will + # fail to load with a cryptic error: + # ImportError: DLL load failed: %1 is not a valid Win32 application. + if sys.platform == 'win32': + os.environ['PATH'] = os.path.dirname(sys.executable) + \ + os.pathsep + os.environ['PATH'] + import win32file # pylint: disable=import-error BASE_DIR = os.path.dirname(os.path.abspath(__file__))
diff --git a/cc/paint/paint_shader.cc b/cc/paint/paint_shader.cc index ecd9f0a..b68e6130 100644 --- a/cc/paint/paint_shader.cc +++ b/cc/paint/paint_shader.cc
@@ -178,11 +178,16 @@ sk_sp<PaintShader> PaintShader::MakeImage(const PaintImage& image, SkTileMode tx, SkTileMode ty, - const SkMatrix* local_matrix) { + const SkMatrix* local_matrix, + const SkRect* tile_rect) { sk_sp<PaintShader> shader(new PaintShader(Type::kImage)); shader->image_ = image; shader->SetMatrixAndTiling(local_matrix, tx, ty); + if (tile_rect) { + DCHECK(image.IsPaintWorklet()); + shader->tile_ = *tile_rect; + } shader->CreateSkShader(); return shader; @@ -433,7 +438,7 @@ flags_, base::OptionalOrNullptr(local_matrix_)); break; case Type::kImage: - if (image_) { + if (image_ && !image_.IsPaintWorklet()) { cached_shader_ = image_.GetSkImage()->makeShader( tx_, ty_, base::OptionalOrNullptr(local_matrix_)); }
diff --git a/cc/paint/paint_shader.h b/cc/paint/paint_shader.h index 24fda29c..2ce5770 100644 --- a/cc/paint/paint_shader.h +++ b/cc/paint/paint_shader.h
@@ -97,10 +97,12 @@ const SkMatrix* local_matrix = nullptr, SkColor fallback_color = SK_ColorTRANSPARENT); + // |tile_rect| is not null only if the |image| is paint worklet backed. static sk_sp<PaintShader> MakeImage(const PaintImage& image, SkTileMode tx, SkTileMode ty, - const SkMatrix* local_matrix); + const SkMatrix* local_matrix, + const SkRect* tile_rect = nullptr); static sk_sp<PaintShader> MakePaintRecord( sk_sp<PaintRecord> record,
diff --git a/cc/paint/scoped_raster_flags.cc b/cc/paint/scoped_raster_flags.cc index d51b6ab..54fd30f 100644 --- a/cc/paint/scoped_raster_flags.cc +++ b/cc/paint/scoped_raster_flags.cc
@@ -46,6 +46,23 @@ flags()->getShader()->shader_type() != PaintShader::Type::kImage) return; + PaintImage image = flags()->getShader()->paint_image(); + if (image.IsPaintWorklet()) { + ImageProvider::ScopedResult result = + decode_stashing_image_provider_->GetRasterContent(DrawImage(image)); + if (result && result.paint_record()) { + const PaintShader* shader = flags()->getShader(); + SkMatrix local_matrix = shader->GetLocalMatrix(); + auto decoded_shader = PaintShader::MakePaintRecord( + sk_ref_sp<PaintRecord>(result.paint_record()), shader->tile(), + shader->tx(), shader->tx(), &local_matrix); + MutableFlags()->setShader(decoded_shader); + } else { + decode_failed_ = true; + } + return; + } + uint32_t transfer_cache_entry_id = kInvalidImageTransferCacheEntryId; SkFilterQuality raster_quality = flags()->getFilterQuality(); bool transfer_cache_entry_needs_mips = false;
diff --git a/cc/paint/scoped_raster_flags_unittest.cc b/cc/paint/scoped_raster_flags_unittest.cc index 52b407b..2a4ac36c 100644 --- a/cc/paint/scoped_raster_flags_unittest.cc +++ b/cc/paint/scoped_raster_flags_unittest.cc
@@ -7,7 +7,9 @@ #include "base/bind.h" #include "base/callback.h" #include "cc/paint/paint_op_buffer.h" +#include "cc/paint/paint_shader.h" #include "cc/test/skia_common.h" +#include "cc/test/test_paint_worklet_input.h" #include "testing/gtest/include/gtest/gtest.h" namespace cc { @@ -41,8 +43,40 @@ private: int ref_count_ = 0; }; + +class MockPaintWorkletImageProvider : public ImageProvider { + public: + MockPaintWorkletImageProvider() = default; + ~MockPaintWorkletImageProvider() override = default; + + ScopedResult GetRasterContent(const DrawImage& draw_image) override { + auto record = sk_make_sp<PaintOpBuffer>(); + return ScopedResult(std::move(record)); + } +}; } // namespace +TEST(ScopedRasterFlagsTest, DecodePaintWorkletImageShader) { + float width = 100; + float height = 100; + scoped_refptr<TestPaintWorkletInput> input = + base::MakeRefCounted<TestPaintWorkletInput>(gfx::SizeF(width, height)); + auto image = CreatePaintWorkletPaintImage(input); + SkMatrix pattern_matrix; + SkRect tile_rect = SkRect::MakeXYWH(0, 0, width, height); + auto shader = + PaintShader::MakeImage(image, SkTileMode::kRepeat, SkTileMode::kRepeat, + &pattern_matrix, &tile_rect); + PaintFlags flags; + flags.setShader(shader); + + MockPaintWorkletImageProvider provider; + ScopedRasterFlags scoped_flags(&flags, &provider, SkMatrix::I(), 0, 255); + ASSERT_TRUE(scoped_flags.flags()); + EXPECT_TRUE(scoped_flags.flags()->getShader()->shader_type() == + PaintShader::Type::kPaintRecord); +} + TEST(ScopedRasterFlagsTest, KeepsDecodesAlive) { auto record = sk_make_sp<PaintOpBuffer>(); record->push<DrawImageOp>(CreateDiscardablePaintImage(gfx::Size(10, 10)), 0.f,
diff --git a/cc/test/stub_decode_cache.h b/cc/test/stub_decode_cache.h index 7b47e57e..c3bc53c 100644 --- a/cc/test/stub_decode_cache.h +++ b/cc/test/stub_decode_cache.h
@@ -28,6 +28,7 @@ void ClearCache() override {} size_t GetMaximumMemoryLimitBytes() const override; bool UseCacheForDrawImage(const DrawImage& image) const override; + void RecordStats() override {} }; } // namespace cc
diff --git a/cc/tiles/gpu_image_decode_cache.cc b/cc/tiles/gpu_image_decode_cache.cc index d49deb2..8cb5728 100644 --- a/cc/tiles/gpu_image_decode_cache.cc +++ b/cc/tiles/gpu_image_decode_cache.cc
@@ -1233,6 +1233,17 @@ paint_image_entries_.clear(); } +void GpuImageDecodeCache::RecordStats() { + base::AutoLock lock(lock_); + double cache_usage; + if (base::CheckDiv(static_cast<double>(working_set_bytes_), + max_working_set_bytes_).AssignIfValid(&cache_usage)) { + UMA_HISTOGRAM_PERCENTAGE( + "Renderer4.GpuImageDecodeState.CachePeakUsagePercent", + cache_usage * 100); + } +} + void GpuImageDecodeCache::AddToPersistentCache(const DrawImage& draw_image, scoped_refptr<ImageData> data) { lock_.AssertAcquired();
diff --git a/cc/tiles/gpu_image_decode_cache.h b/cc/tiles/gpu_image_decode_cache.h index ecc6b0b8b..4b832070 100644 --- a/cc/tiles/gpu_image_decode_cache.h +++ b/cc/tiles/gpu_image_decode_cache.h
@@ -163,6 +163,7 @@ void ClearCache() override; size_t GetMaximumMemoryLimitBytes() const override; bool UseCacheForDrawImage(const DrawImage& image) const override; + void RecordStats() override; // MemoryDumpProvider overrides. bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
diff --git a/cc/tiles/image_decode_cache.h b/cc/tiles/image_decode_cache.h index 241f577..eff7850e 100644 --- a/cc/tiles/image_decode_cache.h +++ b/cc/tiles/image_decode_cache.h
@@ -143,6 +143,11 @@ // image can directly be used for raster (for instance bitmaps in a software // draw). virtual bool UseCacheForDrawImage(const DrawImage& image) const = 0; + + // Should be called periodically to record statistics about cache use and + // performance. + virtual void RecordStats() = 0; + }; } // namespace cc
diff --git a/cc/tiles/software_image_decode_cache.h b/cc/tiles/software_image_decode_cache.h index 176adee..994194b 100644 --- a/cc/tiles/software_image_decode_cache.h +++ b/cc/tiles/software_image_decode_cache.h
@@ -57,6 +57,7 @@ void ClearCache() override; size_t GetMaximumMemoryLimitBytes() const override; bool UseCacheForDrawImage(const DrawImage& image) const override; + void RecordStats() override {} // Decode the given image and store it in the cache. This is only called by an // image decode task from a worker thread.
diff --git a/cc/tiles/tile_manager.cc b/cc/tiles/tile_manager.cc index 032b487..e6d77b6a 100644 --- a/cc/tiles/tile_manager.cc +++ b/cc/tiles/tile_manager.cc
@@ -873,6 +873,7 @@ all_tiles_that_need_to_be_rasterized_are_scheduled_, "had_enough_memory_to_schedule_tiles_needed_now", had_enough_memory_to_schedule_tiles_needed_now); + image_controller_.cache()->RecordStats(); return work_to_schedule; }
diff --git a/chrome/VERSION b/chrome/VERSION index fe2f221..9097319 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=78 MINOR=0 -BUILD=3876 +BUILD=3877 PATCH=0
diff --git a/chrome/android/features/start_surface/internal/dummy/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinator.java b/chrome/android/features/start_surface/internal/dummy/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinator.java index 9a99a5c96..f6b2e4ff 100644 --- a/chrome/android/features/start_surface/internal/dummy/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinator.java +++ b/chrome/android/features/start_surface/internal/dummy/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinator.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.features.start_surface; +import android.support.annotation.Nullable; +import android.view.View; import android.view.ViewGroup; import org.chromium.chrome.browser.ChromeActivity; @@ -12,8 +14,8 @@ /** The dummy coordinator when feed is not enabled ('src/components/feed/features.gni'). */ class ExploreSurfaceCoordinator { - ExploreSurfaceCoordinator( - ChromeActivity activity, ViewGroup parentView, PropertyModel containerPropertyModel) {} + ExploreSurfaceCoordinator(ChromeActivity activity, ViewGroup parentView, + @Nullable View headerView, PropertyModel containerPropertyModel) {} /** * Gets the {@link FeedSurfaceCreator}.
diff --git a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinator.java b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinator.java index fe5b6a4..0ffb6aa 100644 --- a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinator.java +++ b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinator.java
@@ -5,7 +5,9 @@ package org.chromium.chrome.features.start_surface; import android.app.Activity; +import android.support.annotation.Nullable; import android.view.MotionEvent; +import android.view.View; import android.view.ViewGroup; import com.google.android.libraries.feed.api.client.stream.Stream; @@ -22,6 +24,8 @@ /** The coordinator to control the explore surface. */ class ExploreSurfaceCoordinator implements FeedSurfaceCoordinator.FeedSurfaceDelegate { private final ChromeActivity mActivity; + @Nullable + private final View mHeaderView; private final PropertyModelChangeProcessor mPropertyModelChangeProcessor; private final FeedSurfaceCreator mFeedSurfaceCreator; @@ -39,9 +43,10 @@ FeedSurfaceCoordinator createFeedSurfaceCoordinator(boolean isIncognito); } - ExploreSurfaceCoordinator( - ChromeActivity activity, ViewGroup parentView, PropertyModel containerPropertyModel) { + ExploreSurfaceCoordinator(ChromeActivity activity, ViewGroup parentView, + @Nullable View headerView, PropertyModel containerPropertyModel) { mActivity = activity; + mHeaderView = headerView; mPropertyModelChangeProcessor = PropertyModelChangeProcessor.create( containerPropertyModel, parentView, ExploreSurfaceViewBinder::bind); @@ -86,7 +91,7 @@ : Profile.getLastUsedProfile()), FeedProcessScopeFactory.getFeedLoggingBridge()); return new FeedSurfaceCoordinator( - mActivity, null, null, null, exploreSurfaceActionHandler, isIncognito, this); + mActivity, null, null, mHeaderView, exploreSurfaceActionHandler, isIncognito, this); // TODO(crbug.com/982018): Customize surface background for incognito and dark mode. // TODO(crbug.com/982018): Hide signin promo UI in incognito mode. }
diff --git a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinator.java b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinator.java index d7b2516f..6c9b23b8 100644 --- a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinator.java +++ b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinator.java
@@ -7,6 +7,8 @@ import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.BOTTOM_BAR_HEIGHT; import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.TOP_BAR_HEIGHT; +import android.support.annotation.IntDef; +import android.support.annotation.Nullable; import android.view.ViewGroup; import org.chromium.base.ContextUtils; @@ -20,66 +22,76 @@ import org.chromium.chrome.start_surface.R; import org.chromium.ui.modelutil.PropertyModel; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** * Root coordinator that is responsible for showing start surfaces, like a grid of Tabs, explore * surface and the bottom bar to switch between them. */ public class StartSurfaceCoordinator implements StartSurface { - private final TasksSurface mTasksSurface; + @IntDef({SurfaceMode.NO_START_SURFACE, SurfaceMode.TASKS_ONLY, SurfaceMode.TWO_PANES, + SurfaceMode.SINGLE_PANE}) + @Retention(RetentionPolicy.SOURCE) + @interface SurfaceMode { + int NO_START_SURFACE = 0; + int TASKS_ONLY = 1; + int TWO_PANES = 2; + int SINGLE_PANE = 3; + } + + private final @SurfaceMode int mSurfaceMode; private final StartSurfaceMediator mStartSurfaceMediator; + @Nullable + private TasksSurface mTasksSurface; + @Nullable + private TabSwitcher mTabSwitcher; private BottomBarCoordinator mBottomBarCoordinator; private ExploreSurfaceCoordinator mExploreSurfaceCoordinator; + @Nullable private PropertyModel mPropertyModel; public StartSurfaceCoordinator(ChromeActivity activity) { - mTasksSurface = TabManagementModuleProvider.getDelegate().createTasksSurface(activity); + mSurfaceMode = computeSurfaceMode(); - // Do not enable this feature when the bottom bar is enabled since it will - // overlap the start surface's bottom bar. - if ((ChromeFeatureList - .getFieldTrialParamByFeature(ChromeFeatureList.START_SURFACE_ANDROID, - "start_surface_variation") - .equals("twopanes")) - && !FeatureUtilities.isBottomToolbarEnabled()) { - // Margin the bottom of the Tab grid to save space for the bottom bar. - int bottomBarHeight = - ContextUtils.getApplicationContext().getResources().getDimensionPixelSize( - R.dimen.ss_bottom_bar_height); - mTasksSurface.getTabListDelegate().setBottomControlsHeight(bottomBarHeight); - - mPropertyModel = new PropertyModel(StartSurfaceProperties.ALL_KEYS); - mPropertyModel.set(BOTTOM_BAR_HEIGHT, bottomBarHeight); - int singleToolbarHeight = - activity.getResources().getDimensionPixelSize(R.dimen.toolbar_height_no_shadow); - int toolbarHeight = ReturnToChromeExperimentsUtil.shouldShowOmniboxOnTabSwitcher() - ? singleToolbarHeight - : 0; - mPropertyModel.set(TOP_BAR_HEIGHT, toolbarHeight); - - // Create the bottom bar. - mBottomBarCoordinator = new BottomBarCoordinator( - activity, activity.getCompositorViewHolder(), mPropertyModel); - - // Create the explore surface. - // TODO(crbug.com/982018): This is a hack to hide the top tab switcher toolbar in - // the explore surface. Remove it after deciding on where to put the omnibox. - ViewGroup exploreSurfaceContainer = - (ViewGroup) activity.getCompositorViewHolder().getParent(); - mExploreSurfaceCoordinator = new ExploreSurfaceCoordinator( - activity, exploreSurfaceContainer, mPropertyModel); + if (mSurfaceMode == SurfaceMode.NO_START_SURFACE) { + // Create Tab switcher directly to save one layer in the view hierarchy. + mTabSwitcher = TabManagementModuleProvider.getDelegate().createGridTabSwitcher( + activity, activity.getCompositorViewHolder()); + } else { + mTasksSurface = TabManagementModuleProvider.getDelegate().createTasksSurface( + activity, mSurfaceMode == SurfaceMode.SINGLE_PANE); + createAndSetStartSurface(activity); } - mStartSurfaceMediator = new StartSurfaceMediator(mTasksSurface.getController(), - activity.getTabModelSelector(), mPropertyModel, + StartSurfaceMediator.OverlayVisibilityHandler overlayVisibilityHandler = + new StartSurfaceMediator.OverlayVisibilityHandler() { + @Override + // TODO(crbug.com/982018): Consider moving this to LayoutManager. + public void setContentOverlayVisibility(boolean isVisible) { + if (activity.getTabModelSelector().getCurrentTab() == null) return; + activity.getCompositorViewHolder().setContentOverlayVisibility( + isVisible, true); + } + }; + TabSwitcher.Controller controller = + mTabSwitcher != null ? mTabSwitcher.getController() : mTasksSurface.getController(); + mStartSurfaceMediator = new StartSurfaceMediator(controller, activity.getTabModelSelector(), + overlayVisibilityHandler, mPropertyModel, mExploreSurfaceCoordinator == null ? null - : mExploreSurfaceCoordinator.getFeedSurfaceCreator()); + : mExploreSurfaceCoordinator.getFeedSurfaceCreator(), + mSurfaceMode == SurfaceMode.SINGLE_PANE); } // Implements StartSurface. @Override public void setOnTabSelectingListener(StartSurface.OnTabSelectingListener listener) { - mTasksSurface.setOnTabSelectingListener(listener); + if (mTasksSurface != null) { + mTasksSurface.setOnTabSelectingListener(listener); + } else { + mTabSwitcher.setOnTabSelectingListener(listener); + } } @Override @@ -89,6 +101,75 @@ @Override public TabSwitcher.TabListDelegate getTabListDelegate() { - return mTasksSurface.getTabListDelegate(); + if (mTasksSurface != null) { + return mTasksSurface.getTabListDelegate(); + } + + return mTabSwitcher.getTabListDelegate(); + } + + private @SurfaceMode int computeSurfaceMode() { + String feature = ChromeFeatureList.getFieldTrialParamByFeature( + ChromeFeatureList.START_SURFACE_ANDROID, "start_surface_variation"); + + // Do not enable two panes when the bottom bar is enabled since it will + // overlap the two panes' bottom bar. + if (feature.equals("twopanes") && !FeatureUtilities.isBottomToolbarEnabled()) { + return SurfaceMode.TWO_PANES; + } + + if (feature.equals("single")) return SurfaceMode.SINGLE_PANE; + + // TODO(crbug.com/982018): Add the task only surface variation. + return SurfaceMode.NO_START_SURFACE; + } + + private void createAndSetStartSurface(ChromeActivity activity) { + assert mTasksSurface != null; + + // The tasks surface is added to the explore surface in the single pane mode below. + if (mSurfaceMode != SurfaceMode.SINGLE_PANE) { + activity.getCompositorViewHolder().addView(mTasksSurface.getView()); + } + + // There is nothing else to do for SurfaceMode.TASKS_ONLY for now. + if (mSurfaceMode != SurfaceMode.TWO_PANES && mSurfaceMode != SurfaceMode.SINGLE_PANE) { + return; + } + + mPropertyModel = new PropertyModel(StartSurfaceProperties.ALL_KEYS); + if (mSurfaceMode == SurfaceMode.TWO_PANES) createAndSetBottomBar(activity); + + int toolbarHeight = + activity.getResources().getDimensionPixelSize(R.dimen.toolbar_height_no_shadow); + int topControlsHeight = + ReturnToChromeExperimentsUtil.shouldShowOmniboxOnTabSwitcher() ? toolbarHeight : 0; + + // Do not hide the top tab switcher toolbar on the single pane start surface for now. + if (mSurfaceMode == SurfaceMode.SINGLE_PANE) topControlsHeight += toolbarHeight; + mPropertyModel.set(TOP_BAR_HEIGHT, topControlsHeight); + + // Create the explore surface. + // TODO(crbug.com/982018): This is a hack to hide the top tab switcher toolbar in + // the explore surface. Remove it after deciding on where to put the omnibox. + ViewGroup exploreSurfaceContainer = + (ViewGroup) activity.getCompositorViewHolder().getParent(); + mExploreSurfaceCoordinator = + new ExploreSurfaceCoordinator(activity, exploreSurfaceContainer, + mSurfaceMode == SurfaceMode.SINGLE_PANE ? mTasksSurface.getView() : null, + mPropertyModel); + } + + private void createAndSetBottomBar(ChromeActivity activity) { + // Margin the bottom of the Tab grid to save space for the bottom bar. + int bottomBarHeight = + ContextUtils.getApplicationContext().getResources().getDimensionPixelSize( + R.dimen.ss_bottom_bar_height); + mTasksSurface.getTabListDelegate().setBottomControlsHeight(bottomBarHeight); + mPropertyModel.set(BOTTOM_BAR_HEIGHT, bottomBarHeight); + + // Create the bottom bar. + mBottomBarCoordinator = new BottomBarCoordinator( + activity, activity.getCompositorViewHolder(), mPropertyModel); } }
diff --git a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java index 462d2ec..cbe21e5 100644 --- a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java +++ b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java
@@ -23,19 +23,34 @@ /** The mediator implements the logic to interact with the surfaces and caller. */ class StartSurfaceMediator implements StartSurface.Controller, TabSwitcher.OverviewModeObserver { + /** Interface to control overlay visibility. */ + interface OverlayVisibilityHandler { + /** + * Set the content overlay visibility. + * @param isVisible Whether the content overlay should be visible. + */ + void setContentOverlayVisibility(boolean isVisible); + } + private final ObserverList<StartSurface.OverviewModeObserver> mObservers = new ObserverList<>(); private final TabSwitcher.Controller mController; + private final OverlayVisibilityHandler mOverlayVisibilityHandler; @Nullable private final PropertyModel mPropertyModel; @Nullable private final ExploreSurfaceCoordinator.FeedSurfaceCreator mFeedSurfaceCreator; + private final boolean mOnlyShowExploreSurface; StartSurfaceMediator(TabSwitcher.Controller controller, TabModelSelector tabModelSelector, + OverlayVisibilityHandler overlayVisibilityHandler, @Nullable PropertyModel propertyModel, - @Nullable ExploreSurfaceCoordinator.FeedSurfaceCreator feedSurfaceCreator) { + @Nullable ExploreSurfaceCoordinator.FeedSurfaceCreator feedSurfaceCreator, + boolean onlyShowExploreSurface) { mController = controller; + mOverlayVisibilityHandler = overlayVisibilityHandler; mPropertyModel = propertyModel; mFeedSurfaceCreator = feedSurfaceCreator; + mOnlyShowExploreSurface = onlyShowExploreSurface; if (mPropertyModel != null) { mPropertyModel.set( @@ -96,6 +111,8 @@ // TODO(crbug.com/982018): Animate the bottom bar together with the Tab Grid view. if (mPropertyModel != null) { + if (mOnlyShowExploreSurface) mPropertyModel.set(IS_EXPLORE_SURFACE_VISIBLE, true); + // Make sure FeedSurfaceCoordinator is built before the explore surface is showing by // default. if (mPropertyModel.get(IS_EXPLORE_SURFACE_VISIBLE) @@ -110,7 +127,8 @@ @Override public boolean onBackPressed() { - if (mPropertyModel != null && mPropertyModel.get(IS_EXPLORE_SURFACE_VISIBLE)) { + if (mPropertyModel != null && mPropertyModel.get(IS_EXPLORE_SURFACE_VISIBLE) + && !mOnlyShowExploreSurface) { setExploreSurfaceVisibility(false); return true; } @@ -130,10 +148,12 @@ for (StartSurface.OverviewModeObserver observer : mObservers) { observer.finishedShowing(); } + mOverlayVisibilityHandler.setContentOverlayVisibility(false); } @Override public void startedHiding() { + mOverlayVisibilityHandler.setContentOverlayVisibility(true); if (mPropertyModel != null) { mPropertyModel.set(IS_SHOWING_OVERVIEW, false); destroyFeedSurfaceCoordinator(); @@ -151,7 +171,7 @@ } /** This interface builds the feed surface coordinator when showing if needed. */ - void setExploreSurfaceVisibility(boolean isVisible) { + private void setExploreSurfaceVisibility(boolean isVisible) { if (isVisible == mPropertyModel.get(IS_EXPLORE_SURFACE_VISIBLE)) return; if (isVisible && mPropertyModel.get(FEED_SURFACE_COORDINATOR) == null) { @@ -167,7 +187,7 @@ mPropertyModel.set(BOTTOM_BAR_SELECTED_TAB_POSITION, isVisible ? 1 : 0); } - void updateIncognitoMode(boolean isIncognito) { + private void updateIncognitoMode(boolean isIncognito) { if (isIncognito == mPropertyModel.get(IS_INCOGNITO)) return; mPropertyModel.set(IS_INCOGNITO, isIncognito); @@ -184,7 +204,7 @@ if (wasShown) setExploreSurfaceVisibility(true); } - void destroyFeedSurfaceCoordinator() { + private void destroyFeedSurfaceCoordinator() { FeedSurfaceCoordinator feedSurfaceCoordinator = mPropertyModel.get(FEED_SURFACE_COORDINATOR); if (feedSurfaceCoordinator != null) feedSurfaceCoordinator.destroy();
diff --git a/chrome/android/features/tab_ui/java/res/layout/tasks_surface_layout.xml b/chrome/android/features/tab_ui/java/res/layout/tasks_surface_layout.xml new file mode 100644 index 0000000..9591802 --- /dev/null +++ b/chrome/android/features/tab_ui/java/res/layout/tasks_surface_layout.xml
@@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. --> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + <FrameLayout + android:id="@+id/tab_switcher_container" + android:layout_width="match_parent" + android:layout_height="match_parent"/> +</LinearLayout> \ No newline at end of file
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksSurface.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksSurface.java index 029090d..264b107 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksSurface.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksSurface.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.browser.tasks; +import android.view.View; + import org.chromium.chrome.browser.compositor.layouts.Layout; import org.chromium.chrome.browser.tasks.tab_management.TabSwitcher; @@ -28,4 +30,10 @@ * @return TabListDelegate implementation to access the tab grid. */ TabSwitcher.TabListDelegate getTabListDelegate(); + + /** + * Get the {@link View} of the surface. + * @return The surface view. + */ + View getView(); }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksSurfaceCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksSurfaceCoordinator.java index a8bbdc5..0dc3c0e 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksSurfaceCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/TasksSurfaceCoordinator.java
@@ -4,52 +4,64 @@ package org.chromium.chrome.browser.tasks; +import android.view.LayoutInflater; +import android.view.View; import android.widget.FrameLayout; import android.widget.LinearLayout; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.tasks.tab_management.TabManagementModuleProvider; import org.chromium.chrome.browser.tasks.tab_management.TabSwitcher; +import org.chromium.chrome.tab_ui.R; /** * Coordinator for displaying task-related surfaces (Tab Switcher, MV Tiles, Omnibox, etc.). * Concrete implementation of {@link TasksSurface}. */ public class TasksSurfaceCoordinator implements TasksSurface { - private final TabSwitcher mGridTabSwitcher; + private final TabSwitcher mTabSwitcher; private final LinearLayout mLayout; private final FrameLayout mGridContainerLayout; - public TasksSurfaceCoordinator(ChromeActivity activity) { - mLayout = new LinearLayout(activity); - mLayout.setLayoutParams(new LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)); - mLayout.setOrientation(LinearLayout.VERTICAL); + public TasksSurfaceCoordinator(ChromeActivity activity, boolean isTabCarousel) { + mLayout = (LinearLayout) LayoutInflater.from(activity).inflate( + R.layout.tasks_surface_layout, null); + mGridContainerLayout = (FrameLayout) mLayout.findViewById(R.id.tab_switcher_container); - mGridContainerLayout = new FrameLayout(activity); - mGridContainerLayout.setLayoutParams(new FrameLayout.LayoutParams( - FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)); - - mLayout.addView(mGridContainerLayout); - - activity.getCompositorViewHolder().addView(mLayout); - - mGridTabSwitcher = TabManagementModuleProvider.getDelegate().createGridTabSwitcher( - activity, mGridContainerLayout); + if (isTabCarousel) { + // TODO(crbug.com/982018): Change view according to incognito and dark mode. + // TODO(crbug.com/982018): Add the section title. + mLayout.setLayoutParams( + new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.WRAP_CONTENT)); + mGridContainerLayout.setLayoutParams( + new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.WRAP_CONTENT)); + mTabSwitcher = TabManagementModuleProvider.getDelegate().createCarouselTabSwitcher( + activity, mGridContainerLayout); + } else { + mTabSwitcher = TabManagementModuleProvider.getDelegate().createGridTabSwitcher( + activity, mGridContainerLayout); + } } @Override public void setOnTabSelectingListener(TabSwitcher.OnTabSelectingListener listener) { - mGridTabSwitcher.setOnTabSelectingListener(listener); + mTabSwitcher.setOnTabSelectingListener(listener); } @Override public TabSwitcher.Controller getController() { - return mGridTabSwitcher.getController(); + return mTabSwitcher.getController(); } @Override public TabSwitcher.TabListDelegate getTabListDelegate() { - return mGridTabSwitcher.getTabListDelegate(); + return mTabSwitcher.getTabListDelegate(); + } + + @Override + public View getView() { + return mLayout; } }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java index 30e62f1..ebd94f0 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java
@@ -8,8 +8,8 @@ import android.graphics.Rect; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.view.ViewGroup; -import org.chromium.chrome.browser.compositor.CompositorViewHolder; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabCreatorManager; @@ -34,8 +34,7 @@ TabGridDialogCoordinator(Context context, TabModelSelector tabModelSelector, TabContentManager tabContentManager, TabCreatorManager tabCreatorManager, - CompositorViewHolder compositorViewHolder, - TabSwitcherMediator.ResetHandler resetHandler, + ViewGroup containerView, TabSwitcherMediator.ResetHandler resetHandler, TabListMediator.GridCardOnClickListenerProvider gridCardOnClickListenerProvider, TabGridDialogMediator.AnimationOriginProvider animationOriginProvider) { mContext = context; @@ -48,9 +47,9 @@ mTabListCoordinator = new TabListCoordinator(TabListCoordinator.TabListMode.GRID, context, tabModelSelector, tabContentManager::getTabThumbnailWithCallback, null, false, null, gridCardOnClickListenerProvider, mMediator.getTabGridDialogHandler(), null, null, - compositorViewHolder, null, false, COMPONENT_NAME); + containerView, null, false, COMPONENT_NAME); - mParentLayout = new TabGridDialogParent(context, compositorViewHolder); + mParentLayout = new TabGridDialogParent(context, containerView); } /**
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegate.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegate.java index ca749d7..5c17acb 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegate.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegate.java
@@ -28,9 +28,10 @@ /** * Create the {@link TasksSurface} * @param activity The {@link ChromeActivity} that creates this surface. + * @param isTabCarousel Whether show the Tabs in carousel mode. * @return The {@TasksSurface}. */ - TasksSurface createTasksSurface(ChromeActivity activity); + TasksSurface createTasksSurface(ChromeActivity activity, boolean isTabCarousel); /** * Create the {@link TabSwitcher} to display Tabs in grid.
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java index 22185c9..7f52aaa 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java
@@ -31,8 +31,8 @@ @UsedByReflection("TabManagementModule") public class TabManagementDelegateImpl implements TabManagementDelegate { @Override - public TasksSurface createTasksSurface(ChromeActivity activity) { - return new TasksSurfaceCoordinator(activity); + public TasksSurface createTasksSurface(ChromeActivity activity, boolean isTabCarousel) { + return new TasksSurfaceCoordinator(activity, isTabCarousel); } @Override @@ -44,7 +44,8 @@ } return new TabSwitcherCoordinator(activity, activity.getLifecycleDispatcher(), activity.getTabModelSelector(), activity.getTabContentManager(), - activity.getCompositorViewHolder(), activity.getFullscreenManager(), activity, + activity.getCompositorViewHolder().getDynamicResourceLoader(), + activity.getFullscreenManager(), activity, activity.getMenuOrKeyboardActionController(), activity, containerView, TabListCoordinator.TabListMode.GRID); } @@ -53,7 +54,8 @@ public TabSwitcher createCarouselTabSwitcher(ChromeActivity activity, ViewGroup containerView) { return new TabSwitcherCoordinator(activity, activity.getLifecycleDispatcher(), activity.getTabModelSelector(), activity.getTabContentManager(), - activity.getCompositorViewHolder(), activity.getFullscreenManager(), activity, + activity.getCompositorViewHolder().getDynamicResourceLoader(), + activity.getFullscreenManager(), activity, activity.getMenuOrKeyboardActionController(), activity, containerView, TabListCoordinator.TabListMode.CAROUSEL); }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherCoordinator.java index da68ccc..78b295b 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherCoordinator.java
@@ -15,7 +15,6 @@ import org.chromium.base.VisibleForTesting; import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.browser.MenuOrKeyboardActionController; -import org.chromium.chrome.browser.compositor.CompositorViewHolder; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; @@ -29,6 +28,7 @@ import org.chromium.chrome.tab_ui.R; import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModelChangeProcessor; +import org.chromium.ui.resources.dynamics.DynamicResourceLoader; import java.util.ArrayList; import java.util.List; @@ -69,23 +69,22 @@ public TabSwitcherCoordinator(Context context, ActivityLifecycleDispatcher lifecycleDispatcher, TabModelSelector tabModelSelector, TabContentManager tabContentManager, - CompositorViewHolder compositorViewHolder, ChromeFullscreenManager fullscreenManager, + DynamicResourceLoader dynamicResourceLoader, ChromeFullscreenManager fullscreenManager, TabCreatorManager tabCreatorManager, MenuOrKeyboardActionController menuOrKeyboardActionController, - SnackbarManager.SnackbarManageable snackbarManageable, @Nullable ViewGroup container, + SnackbarManager.SnackbarManageable snackbarManageable, ViewGroup container, @TabListCoordinator.TabListMode int mode) { PropertyModel containerViewModel = new PropertyModel(TabListContainerProperties.ALL_KEYS); mTabSelectionEditorCoordinator = new TabSelectionEditorCoordinator( - context, compositorViewHolder, tabModelSelector, tabContentManager); + context, container, tabModelSelector, tabContentManager); mMediator = new TabSwitcherMediator(this, containerViewModel, tabModelSelector, - fullscreenManager, compositorViewHolder, - mTabSelectionEditorCoordinator.getController()); + fullscreenManager, container, mTabSelectionEditorCoordinator.getController(), mode); if (FeatureUtilities.isTabGroupsAndroidUiImprovementsEnabled()) { mTabGridDialogCoordinator = new TabGridDialogCoordinator(context, tabModelSelector, - tabContentManager, tabCreatorManager, compositorViewHolder, this, mMediator, + tabContentManager, tabCreatorManager, container, this, mMediator, this::getTabGridCardPosition); mUndoGroupSnackbarController = @@ -109,12 +108,10 @@ R.plurals.bottom_tab_grid_title_placeholder, numRelatedTabs, numRelatedTabs); }; - ViewGroup tabListContainerView = container != null ? container : compositorViewHolder; - mTabListCoordinator = - new TabListCoordinator(mode, context, tabModelSelector, mMultiThumbnailCardProvider, - titleProvider, true, mMediator::getCreateGroupButtonOnClickListener, - mMediator, null, null, null, tabListContainerView, - compositorViewHolder.getDynamicResourceLoader(), true, COMPONENT_NAME); + mTabListCoordinator = new TabListCoordinator(mode, context, tabModelSelector, + mMultiThumbnailCardProvider, titleProvider, true, + mMediator::getCreateGroupButtonOnClickListener, mMediator, null, null, null, + container, dynamicResourceLoader, true, COMPONENT_NAME); mContainerViewChangeProcessor = PropertyModelChangeProcessor.create(containerViewModel, mTabListCoordinator.getContainerView(), TabListContainerViewBinder::bind);
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java index 4100938d..b289fba 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java
@@ -17,6 +17,7 @@ import android.graphics.Bitmap; import android.os.Handler; import android.support.annotation.Nullable; +import android.view.ViewGroup; import org.chromium.base.ContextUtils; import org.chromium.base.Log; @@ -25,7 +26,6 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.browser.ChromeFeatureList; -import org.chromium.chrome.browser.compositor.CompositorViewHolder; import org.chromium.chrome.browser.compositor.layouts.LayoutManager; import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager; import org.chromium.chrome.browser.fullscreen.FullscreenManager; @@ -106,7 +106,7 @@ } }; - private final CompositorViewHolder mCompositorViewHolder; + private final ViewGroup mContainerView; private final TabSelectionEditorCoordinator .TabSelectionEditorController mTabSelectionEditorController; private TabSwitcher.OnTabSelectingListener mOnTabSelectingListener; @@ -146,15 +146,16 @@ * grid or carousel. * @param tabModelSelector {@link TabModelSelector} to observer for model and selection changes. * @param fullscreenManager {@link FullscreenManager} to use. - * @param compositorViewHolder {@link CompositorViewHolder} to use. + * @param containerView The container {@link ViewGroup} to use. * @param tabSelectionEditorController The controller that can control the visibility of the * TabSelectionEditor. + * @param mode One of the {@TabListCoordinator.TabListMode}. */ TabSwitcherMediator(ResetHandler resetHandler, PropertyModel containerViewModel, TabModelSelector tabModelSelector, ChromeFullscreenManager fullscreenManager, - CompositorViewHolder compositorViewHolder, - TabSelectionEditorCoordinator - .TabSelectionEditorController tabSelectionEditorController) { + ViewGroup containerView, + TabSelectionEditorCoordinator.TabSelectionEditorController tabSelectionEditorController, + @TabListCoordinator.TabListMode int mode) { mResetHandler = resetHandler; mContainerViewModel = containerViewModel; mTabModelSelector = tabModelSelector; @@ -213,23 +214,27 @@ .getCurrentTabModelFilter() .isIncognito()); mContainerViewModel.set(ANIMATE_VISIBILITY_CHANGES, true); - mContainerViewModel.set(TOP_CONTROLS_HEIGHT, fullscreenManager.getTopControlsHeight()); - mContainerViewModel.set( - BOTTOM_CONTROLS_HEIGHT, fullscreenManager.getBottomControlsHeight()); - int toolbarHeight = - ContextUtils.getApplicationContext().getResources().getDimensionPixelSize( - R.dimen.toolbar_height_no_shadow); - int topPadding = ReturnToChromeExperimentsUtil.shouldShowOmniboxOnTabSwitcher() - ? toolbarHeight - : DEFAULT_TOP_PADDING; - mContainerViewModel.set(TOP_PADDING, topPadding); - int shadowTopMargin = ReturnToChromeExperimentsUtil.shouldShowOmniboxOnTabSwitcher() - ? toolbarHeight * 2 - : toolbarHeight; - mContainerViewModel.set(SHADOW_TOP_MARGIN, shadowTopMargin); + // Container view takes care of padding and margin in carousel mode. + if (mode != TabListCoordinator.TabListMode.CAROUSEL) { + mContainerViewModel.set(TOP_CONTROLS_HEIGHT, fullscreenManager.getTopControlsHeight()); + mContainerViewModel.set( + BOTTOM_CONTROLS_HEIGHT, fullscreenManager.getBottomControlsHeight()); - mCompositorViewHolder = compositorViewHolder; + int toolbarHeight = + ContextUtils.getApplicationContext().getResources().getDimensionPixelSize( + R.dimen.toolbar_height_no_shadow); + int topPadding = ReturnToChromeExperimentsUtil.shouldShowOmniboxOnTabSwitcher() + ? toolbarHeight + : DEFAULT_TOP_PADDING; + mContainerViewModel.set(TOP_PADDING, topPadding); + int shadowTopMargin = ReturnToChromeExperimentsUtil.shouldShowOmniboxOnTabSwitcher() + ? toolbarHeight * 2 + : toolbarHeight; + mContainerViewModel.set(SHADOW_TOP_MARGIN, shadowTopMargin); + } + + mContainerView = containerView; mSoftClearTabListRunnable = mResetHandler::softCleanup; mClearTabListRunnable = () -> mResetHandler.resetWithTabList(null, false); @@ -292,12 +297,6 @@ mContainerViewModel.set(IS_VISIBLE, isVisible); } - private void setContentOverlayVisibility(boolean isVisible) { - Tab currentTab = mTabModelSelector.getCurrentTab(); - if (currentTab == null) return; - mCompositorViewHolder.setContentOverlayVisibility(isVisible, true); - } - /** * Record tab switch related metric for GTS. * @param tab The new selected tab. @@ -420,12 +419,10 @@ for (TabSwitcher.OverviewModeObserver observer : mObservers) { observer.finishedShowing(); } - setContentOverlayVisibility(false); } @Override public void startedHiding(boolean isAnimating) { - setContentOverlayVisibility(true); for (TabSwitcher.OverviewModeObserver observer : mObservers) { observer.startedHiding(); }
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherMediatorUnitTest.java index 1207ba4..a20a7dfc 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherMediatorUnitTest.java
@@ -183,7 +183,8 @@ mModel = new PropertyModel(TabListContainerProperties.ALL_KEYS); mModel.addObserver(mPropertyObserver); mMediator = new TabSwitcherMediator(mResetHandler, mModel, mTabModelSelector, - mFullscreenManager, mCompositorViewHolder, null); + mFullscreenManager, mCompositorViewHolder, null, + TabListCoordinator.TabListMode.GRID); mMediator.addOverviewModeObserver(mOverviewModeObserver); mMediator.setOnTabSelectingListener(mLayout::onTabSelecting); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java index ee81355e..12141d4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
@@ -221,6 +221,7 @@ public static final String DOWNLOAD_HOME_V2 = "DownloadHomeV2"; public static final String DOWNLOAD_LOCATION_SHOW_IMAGE_IN_GALLERY = "DownloadLocationShowImageInGallery"; + public static final String DOWNLOAD_NOTIFICATION_BADGE = "DownloadNotificationBadge"; public static final String DOWNLOAD_PROGRESS_INFOBAR = "DownloadProgressInfoBar"; public static final String DOWNLOAD_RENAME = "DownloadRename"; public static final String DOWNLOADS_FOREGROUND = "DownloadsForeground";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ReorderBookmarkItemsAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ReorderBookmarkItemsAdapter.java index 2fc5d65..a2a212f5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ReorderBookmarkItemsAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ReorderBookmarkItemsAdapter.java
@@ -23,6 +23,7 @@ import org.chromium.chrome.browser.bookmarks.BookmarkManager.ItemsAdapter; import org.chromium.chrome.browser.bookmarks.BookmarkRow.Location; import org.chromium.chrome.browser.signin.PersonalizedSigninPromoView; +import org.chromium.chrome.browser.sync.ProfileSyncService; import org.chromium.chrome.browser.widget.dragreorder.DragReorderableListAdapter; import org.chromium.components.bookmarks.BookmarkId; import org.chromium.components.bookmarks.BookmarkType; @@ -36,7 +37,7 @@ * BaseAdapter for {@link RecyclerView}. It manages bookmarks to list there. */ class ReorderBookmarkItemsAdapter extends DragReorderableListAdapter<BookmarkItem> - implements BookmarkUIObserver, ItemsAdapter { + implements BookmarkUIObserver, ProfileSyncService.SyncStateChangedListener, ItemsAdapter { /** * Specifies the view types that the bookmark delegate screen can contain. */ @@ -63,6 +64,7 @@ private BookmarkPromoHeader mPromoHeaderManager; private String mSearchText; private BookmarkId mCurrentFolder; + private ProfileSyncService mProfileSyncService; // For metrics private int mDragReorderCount; @@ -110,6 +112,8 @@ ReorderBookmarkItemsAdapter(Context context) { super(context); + mProfileSyncService = ProfileSyncService.get(); + mProfileSyncService.addSyncStateChangedListener(this); } /** @@ -229,7 +233,11 @@ mDelegate.getModel().addObserver(mBookmarkModelObserver); Runnable promoHeaderChangeAction = () -> { - updateHeader(true); + // If top level folders are not showing, update the header and notify. + // Otherwise, update header without notifying; we are going to update the bookmarks + // list, in case other top-level folders appeared because of the sync, and then + // redraw. + updateHeader(!topLevelFoldersShowing()); }; mPromoHeaderManager = new BookmarkPromoHeader(mContext, promoHeaderChangeAction); @@ -249,6 +257,7 @@ mDelegate.getSelectionDelegate().removeObserver(this); mDelegate = null; mPromoHeaderManager.destroy(); + mProfileSyncService.removeSyncStateChangedListener(this); } @Override @@ -264,7 +273,7 @@ } enableDrag(); - if (folder.equals(mDelegate.getModel().getRootFolderId())) { + if (topLevelFoldersShowing()) { setBookmarks(mTopLevelFolders); } else { setBookmarks(mDelegate.getModel().getChildIDs(folder, true, true)); @@ -323,10 +332,17 @@ setOrder(mElements); } + // SyncStateChangedListener implementation. + @Override + public void syncStateChanged() { + mTopLevelFolders.clear(); + populateTopLevelFoldersList(); + } + private void recordSessionReorderInfo() { // Record metrics when we are exiting a folder (mCurrentFolder must not be null) // Cannot reorder top level folders or partner bookmarks - if (mCurrentFolder != null && !mCurrentFolder.equals(mDelegate.getModel().getRootFolderId()) + if (mCurrentFolder != null && !topLevelFoldersShowing() && mCurrentFolder.getType() != BookmarkType.PARTNER) { RecordHistogram.recordCount1000Histogram( "BookmarkManager.NumDraggedInSession", mDragReorderCount); @@ -419,8 +435,7 @@ @Override protected void setOrder(List<BookmarkItem> bookmarkItems) { - assert !mCurrentFolder.equals(mDelegate.getModel().getRootFolderId()) - : "Cannot reorder top-level folders!"; + assert !topLevelFoldersShowing() : "Cannot reorder top-level folders!"; assert mCurrentFolder.getType() != BookmarkType.PARTNER : "Cannot reorder partner bookmarks!"; assert mDelegate.getCurrentState() @@ -495,4 +510,18 @@ return Location.MIDDLE; } } + + /** + * @return True iff the currently-open folder is the root folder + * (which is true iff the top-level folders are showing) + */ + private boolean topLevelFoldersShowing() { + return mCurrentFolder.equals(mDelegate.getModel().getRootFolderId()); + } + + @VisibleForTesting + void simulateSignInForTests() { + syncStateChanged(); + onFolderStateSet(mCurrentFolder); + } } \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuCoordinator.java index bf62c0e..b7c722e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuCoordinator.java
@@ -158,8 +158,8 @@ View frame = view.findViewById(R.id.context_menu_frame); // TODO(sinansahin): Refactor ContextMenuDialog as well. final ContextMenuDialog dialog = - new ContextMenuDialog(activity, R.style.Theme_Chromium_DialogWhenLarge, - touchPointXPx, touchPointYPx, mTopContentOffsetPx, frame); + new ContextMenuDialog(activity, R.style.Theme_Chromium_AlertDialog, touchPointXPx, + touchPointYPx, mTopContentOffsetPx, frame); dialog.setContentView(view); return dialog;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationFactory.java index def94d6..65da435 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationFactory.java
@@ -76,10 +76,15 @@ public static Notification buildNotification(Context context, @DownloadNotificationService.DownloadStatus int downloadStatus, DownloadUpdate downloadUpdate, int notificationId) { + String channelId = ChannelDefinitions.ChannelId.DOWNLOADS; + if (LegacyHelpers.isLegacyDownload(downloadUpdate.getContentId()) + && downloadStatus == DownloadNotificationService.DownloadStatus.COMPLETED + && ChromeFeatureList.isEnabled(ChromeFeatureList.DOWNLOAD_NOTIFICATION_BADGE)) { + channelId = ChannelDefinitions.ChannelId.COMPLETED_DOWNLOADS; + } ChromeNotificationBuilder builder = NotificationBuilderFactory - .createChromeNotificationBuilder(true /* preferCompat */, - ChannelDefinitions.ChannelId.DOWNLOADS, + .createChromeNotificationBuilder(true /* preferCompat */, channelId, null /* remoteAppPackageName */, new NotificationMetadata(LegacyHelpers.isLegacyDownload( downloadUpdate.getContentId())
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationManagerProxyImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationManagerProxyImpl.java index b3fe485..aa5ab6310 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationManagerProxyImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationManagerProxyImpl.java
@@ -56,12 +56,6 @@ @Override public void createNotificationChannel(NotificationChannel channel) { assert Build.VERSION.SDK_INT >= Build.VERSION_CODES.O; - // Suppress the notification dot/number that may appear on the browser app launcher. We - // suppress this because showing it may imply that tapping the launch icon will lead - // to some way of dismissing the dot, which is generally not the case. We don't want to - // show a number either because users may have notifications from various websites, so an - // aggregate figure is probably not useful. - channel.setShowBadge(false); mNotificationManager.createNotificationChannel(channel); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/channels/ChannelDefinitions.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/channels/ChannelDefinitions.java index 7ce21b1..23a0e48f0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/channels/ChannelDefinitions.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/channels/ChannelDefinitions.java
@@ -55,7 +55,7 @@ */ @StringDef({ChannelId.BROWSER, ChannelId.DOWNLOADS, ChannelId.INCOGNITO, ChannelId.MEDIA, ChannelId.SCREEN_CAPTURE, ChannelId.CONTENT_SUGGESTIONS, ChannelId.WEBAPP_ACTIONS, - ChannelId.SITES, ChannelId.SHARING, ChannelId.UPDATES}) + ChannelId.SITES, ChannelId.SHARING, ChannelId.UPDATES, ChannelId.COMPLETED_DOWNLOADS}) @Retention(RetentionPolicy.SOURCE) public @interface ChannelId { String BROWSER = "browser"; @@ -70,6 +70,7 @@ String VR = "vr"; String SHARING = "sharing"; String UPDATES = "updates"; + String COMPLETED_DOWNLOADS = "completed_downloads"; } @StringDef({ @@ -168,6 +169,12 @@ new PredefinedChannel(ChannelId.UPDATES, R.string.notification_category_updates, NotificationManager.IMPORTANCE_HIGH, ChannelGroupId.GENERAL)); + map.put(ChannelId.COMPLETED_DOWNLOADS, + new PredefinedChannel(ChannelId.COMPLETED_DOWNLOADS, + R.string.notification_category_completed_downloads, + NotificationManager.IMPORTANCE_LOW, ChannelGroupId.GENERAL, + true /* showNotificationBadges */)); + MAP = Collections.unmodifiableMap(map); STARTUP = Collections.unmodifiableSet(startup); } @@ -262,19 +269,27 @@ private final int mImportance; @ChannelGroupId private final String mGroupId; + private final boolean mShowNotificationBadges; PredefinedChannel(@ChannelId String id, int nameResId, int importance, @ChannelGroupId String groupId) { + this(id, nameResId, importance, groupId, false /* showNotificationBadges */); + } + + PredefinedChannel(@ChannelId String id, int nameResId, int importance, + @ChannelGroupId String groupId, boolean showNotificationBadges) { this.mId = id; this.mNameResId = nameResId; this.mImportance = importance; this.mGroupId = groupId; + this.mShowNotificationBadges = showNotificationBadges; } NotificationChannel toNotificationChannel(Resources resources) { String name = resources.getString(mNameResId); NotificationChannel channel = new NotificationChannel(mId, name, mImportance); channel.setGroup(mGroupId); + channel.setShowBadge(mShowNotificationBadges); return channel; } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabModelObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabModelObserver.java index e0ce5ee..fcf9999 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabModelObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabModelObserver.java
@@ -4,7 +4,6 @@ package org.chromium.chrome.browser.tabmodel; -import org.chromium.base.ThreadUtils; import org.chromium.chrome.browser.tab.Tab; import java.util.List; @@ -51,10 +50,7 @@ }; mTabModelSelector.addObserver(mSelectorObserver); } else { - // Run this asynchronously so it is done after the tasks in the constructor of - // the inherited classes (specifically when used in TabModelSelectoTabObserver) - // are completed. - ThreadUtils.getUiThreadHandler().postAtFrontOfQueue(() -> registerModelObservers()); + registerModelObservers(); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabObserver.java index 8fea3ec..da99e9d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabObserver.java
@@ -6,11 +6,13 @@ import android.util.SparseArray; +import org.chromium.base.ThreadUtils; import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; import org.chromium.content_public.browser.UiThreadTaskTraits; +import java.util.ArrayList; import java.util.List; /** @@ -73,6 +75,7 @@ @Override protected void onRegistrationComplete() { + List<Tab> tabs = new ArrayList<>(); List<TabModel> tabModels = mTabModelSelector.getModels(); for (int i = 0; i < tabModels.size(); i++) { TabModel tabModel = tabModels.get(i); @@ -80,9 +83,18 @@ for (int j = 0; j < comprehensiveTabList.getCount(); j++) { Tab tab = comprehensiveTabList.getTabAt(j); tab.addObserver(TabModelSelectorTabObserver.this); - onTabRegistered(tab); + tabs.add(tab); } } + + // Run |onTabRegistered| asynchronously so it is done after the tasks in the + // constructor of the inherited classes are completed and the relevant local + // variables are ready. + // TODO(jinsukkim): Consifer making this class final, and instroducing an inner + // class that extends EmptyTabObserver + provides onTab[Un]Registered instead. + ThreadUtils.getUiThreadHandler().postAtFrontOfQueue(() -> { + for (Tab tab : tabs) onTabRegistered(tab); + }); } }; }
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index 38a0697..098b9d6 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -334,6 +334,9 @@ <message name="IDS_NOTIFICATION_CATEGORY_UPDATES" desc="Label for update notifications, within a list of notification categories. [CHAR-LIMIT=32]"> Updates </message> + <message name="IDS_NOTIFICATION_CATEGORY_COMPLETED_DOWNLOADS" desc="Label for completed download notifications, within a list of notification categories. [CHAR-LIMIT=32]"> + Completed downloads + </message> <!-- Sign-in, sync and personalization preferences --> <message name="IDS_PREFS_SECTION_ACCOUNT" desc="Title for the group of account-related entries in Settings. [CHAR-LIMIT=32]">
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkReorderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkReorderTest.java index 3aa5bc0d1..5fe3b682 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkReorderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkReorderTest.java
@@ -576,6 +576,34 @@ onView(withText("Move down")).check(doesNotExist()); } + @Test + @MediumTest + public void testTopLevelFolderUpdateAfterSync() throws Exception { + // Set up the test and open the bookmark manager to the Mobile Bookmarks folder. + MockSyncContentResolverDelegate syncDelegate = new MockSyncContentResolverDelegate(); + syncDelegate.setMasterSyncAutomatically(true); + AndroidSyncSettings.overrideForTests(syncDelegate, null); + readPartnerBookmarks(); + openBookmarkManager(); + ReorderBookmarkItemsAdapter adapter = getReorderAdapter(); + + // Open the root folder. + TestThreadUtils.runOnUiThreadBlocking( + () -> mManager.openFolder(mBookmarkModel.getRootFolderId())); + + // Add a bookmark to the Other Bookmarks folder. + TestThreadUtils.runOnUiThreadBlocking(() -> { + mBookmarkModel.addBookmark( + mBookmarkModel.getOtherFolderId(), 0, TEST_TITLE_A, TEST_URL_A); + }); + + // Dismiss promo header and simulate a sign in. + syncDelegate.setMasterSyncAutomatically(false); + TestThreadUtils.runOnUiThreadBlocking(adapter::simulateSignInForTests); + Assert.assertEquals( + "Expected \"Other Bookmarks\" folder to appear!", 2, adapter.getItemCount()); + } + @Override protected void openBookmarkManager() throws InterruptedException { super.openBookmarkManager();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadNotificationServiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadNotificationServiceTest.java index 26eb375..233b368 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadNotificationServiceTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadNotificationServiceTest.java
@@ -45,7 +45,8 @@ */ @RunWith(ParameterizedRunner.class) @UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class) -@Features.DisableFeatures(ChromeFeatureList.DOWNLOAD_OFFLINE_CONTENT_PROVIDER) +@Features.DisableFeatures({ChromeFeatureList.DOWNLOAD_NOTIFICATION_BADGE, + ChromeFeatureList.DOWNLOAD_OFFLINE_CONTENT_PROVIDER}) public class DownloadNotificationServiceTest { private static final ContentId ID1 = LegacyHelpers.buildLegacyContentId(false, UUID.randomUUID().toString());
diff --git a/chrome/android/webapk/shell_apk/current_version/current_version.gni b/chrome/android/webapk/shell_apk/current_version/current_version.gni index dd990c15..079aae7 100644 --- a/chrome/android/webapk/shell_apk/current_version/current_version.gni +++ b/chrome/android/webapk/shell_apk/current_version/current_version.gni
@@ -12,4 +12,4 @@ # //chrome/android/webapk/shell_apk:webapk is changed. This includes # Java files, Android resource files and AndroidManifest.xml. Does not affect # Chrome.apk -current_shell_apk_version = 103 +current_shell_apk_version = 104
diff --git a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/h2o/LaunchTest.java b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/h2o/LaunchTest.java index ddfaf12..5109af82 100644 --- a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/h2o/LaunchTest.java +++ b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/h2o/LaunchTest.java
@@ -37,6 +37,7 @@ import org.chromium.webapk.lib.common.WebApkMetaDataKeys; import org.chromium.webapk.shell_apk.CustomAndroidOsShadowAsyncTask; import org.chromium.webapk.shell_apk.HostBrowserLauncher; +import org.chromium.webapk.shell_apk.HostBrowserUtils; import org.chromium.webapk.shell_apk.WebApkSharedPreferences; import org.chromium.webapk.shell_apk.WebApkUtils; import org.chromium.webapk.test.WebApkTestHelper; @@ -262,8 +263,8 @@ PackageManager.COMPONENT_ENABLED_STATE_DISABLED); changeWebApkActivityEnabledSetting(mPackageManager, H2OMainActivity.class, PackageManager.COMPONENT_ENABLED_STATE_ENABLED); - installBrowser( - BROWSER_PACKAGE_NAME, H2OLauncher.MINIMUM_REQUIRED_CHROMIUM_VERSION_NEW_SPLASH); + installBrowser(BROWSER_PACKAGE_NAME, + HostBrowserUtils.MINIMUM_REQUIRED_CHROMIUM_VERSION_NEW_SPLASH); Intent launchIntent = new Intent(Intent.ACTION_MAIN); launchIntent.setPackage(sWebApkPackageName); @@ -296,6 +297,33 @@ } } + /** + * Test that H2OMainActivity is always used as the entry point when the host browser is + * org.chromium.arc.intent_helper. + */ + @Test + public void testLaunchWithArcIntentHelperHostBrowser() { + Intent launchIntent = new Intent(Intent.ACTION_MAIN); + launchIntent.setPackage(sWebApkPackageName); + + changeWebApkActivityEnabledSetting(mPackageManager, H2OOpaqueMainActivity.class, + PackageManager.COMPONENT_ENABLED_STATE_ENABLED); + changeWebApkActivityEnabledSetting(mPackageManager, H2OMainActivity.class, + PackageManager.COMPONENT_ENABLED_STATE_DISABLED); + installBrowser(HostBrowserUtils.ARC_INTENT_HELPER_BROWSER, + HostBrowserUtils.MINIMUM_REQUIRED_CHROMIUM_VERSION_NEW_SPLASH); + ArrayList<Intent> launchedIntents = runActivityChain(launchIntent, + H2OOpaqueMainActivity.class, HostBrowserUtils.ARC_INTENT_HELPER_BROWSER); + + // The entry point should have been switched to H2OMainActivity. + Assert.assertFalse(isWebApkActivityEnabled(mPackageManager, H2OOpaqueMainActivity.class)); + Assert.assertTrue(isWebApkActivityEnabled(mPackageManager, H2OMainActivity.class)); + + Assert.assertTrue(!launchedIntents.isEmpty()); + assertIntentIsForCustomBrowserLaunch(launchedIntents.get(launchedIntents.size() - 1), + HostBrowserUtils.ARC_INTENT_HELPER_BROWSER, DEFAULT_START_URL); + } + /** Checks the name of the intent's component class name. */ private static void assertIntentComponentClassNameEquals(Class expectedClass, Intent intent) { Assert.assertEquals(expectedClass.getName(), intent.getComponent().getClassName()); @@ -303,7 +331,13 @@ /** Checks that the passed in intent launches the host browser with the given URL. */ private static void assertIntentIsForBrowserLaunch(Intent intent, String expectedStartUrl) { - Assert.assertEquals(BROWSER_PACKAGE_NAME, intent.getPackage()); + assertIntentIsForCustomBrowserLaunch(intent, BROWSER_PACKAGE_NAME, expectedStartUrl); + } + + /** Checks that the passed in intent launches the given host browser with the given URL. */ + private static void assertIntentIsForCustomBrowserLaunch( + Intent intent, String browserPackage, String expectedStartUrl) { + Assert.assertEquals(browserPackage, intent.getPackage()); Assert.assertEquals(HostBrowserLauncher.ACTION_START_WEBAPK, intent.getAction()); Assert.assertEquals(expectedStartUrl, intent.getStringExtra(WebApkConstants.EXTRA_URL)); } @@ -332,7 +366,7 @@ PackageManager.COMPONENT_ENABLED_STATE_DISABLED); installBrowser(BROWSER_PACKAGE_NAME, browserCompatibleWithSplashActivity - ? H2OLauncher.MINIMUM_REQUIRED_CHROMIUM_VERSION_NEW_SPLASH + ? HostBrowserUtils.MINIMUM_REQUIRED_CHROMIUM_VERSION_NEW_SPLASH : BROWSER_H2O_INCOMPATIBLE_VERSION); // Android modifies the intent when the intent is used to launch an activity. Clone the
diff --git a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/h2o/SplashActivityTest.java b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/h2o/SplashActivityTest.java index 72f48a56..0cd5b47 100644 --- a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/h2o/SplashActivityTest.java +++ b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/h2o/SplashActivityTest.java
@@ -36,6 +36,7 @@ import org.chromium.testing.local.LocalRobolectricTestRunner; import org.chromium.webapk.lib.common.WebApkMetaDataKeys; import org.chromium.webapk.shell_apk.CustomAndroidOsShadowAsyncTask; +import org.chromium.webapk.shell_apk.HostBrowserUtils; import org.chromium.webapk.shell_apk.LaunchHostBrowserSelector; import org.chromium.webapk.test.WebApkTestHelper; @@ -97,8 +98,8 @@ WebApkTestHelper.registerWebApkWithMetaData(appContext.getPackageName(), metadata, null); // Install browser. - mShadowPackageManager.addPackage(newPackageInfo( - BROWSER_PACKAGE_NAME, H2OLauncher.MINIMUM_REQUIRED_CHROMIUM_VERSION_NEW_SPLASH)); + mShadowPackageManager.addPackage(newPackageInfo(BROWSER_PACKAGE_NAME, + HostBrowserUtils.MINIMUM_REQUIRED_CHROMIUM_VERSION_NEW_SPLASH)); } /**
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserLauncher.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserLauncher.java index 10691ab..122ab10 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserLauncher.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserLauncher.java
@@ -36,8 +36,7 @@ public static void launch(Activity activity, HostBrowserLauncherParams params) { Log.v(TAG, "WebAPK Launch URL: " + params.getStartUrl()); - if (HostBrowserUtils.shouldLaunchInTab(params.getHostBrowserPackageName(), - params.getHostBrowserMajorChromiumVersion())) { + if (HostBrowserUtils.shouldLaunchInTab(params)) { launchInTab(activity.getApplicationContext(), params); return; }
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserUtils.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserUtils.java index 3e8e3010..51f3c8b5 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserUtils.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserUtils.java
@@ -10,6 +10,7 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.os.Build; import android.text.TextUtils; import org.chromium.webapk.lib.common.WebApkMetaDataKeys; @@ -26,17 +27,22 @@ private static final int MINIMUM_REQUIRED_INTENT_HELPER_VERSION = 2; + // Lowest version of Chromium which supports ShellAPK showing the splash screen. + public static final int MINIMUM_REQUIRED_CHROMIUM_VERSION_NEW_SPLASH = 77; + private static final String VERSION_NAME_DEVELOPER_BUILD = "Developer Build"; private static final String TAG = "cr_HostBrowserUtils"; + public static String ARC_INTENT_HELPER_BROWSER = "org.chromium.arc.intent_helper"; + /** * The package names of the browsers that support WebAPKs. The most preferred one comes first. */ - private static List<String> sBrowsersSupportingWebApk = new ArrayList<String>( - Arrays.asList("com.google.android.apps.chrome", "com.android.chrome", "com.chrome.beta", - "com.chrome.dev", "com.chrome.canary", "org.chromium.chrome", - "org.chromium.chrome.tests", "org.chromium.arc.intent_helper")); + private static List<String> sBrowsersSupportingWebApk = + new ArrayList<String>(Arrays.asList("com.google.android.apps.chrome", + "com.android.chrome", "com.chrome.beta", "com.chrome.dev", "com.chrome.canary", + "org.chromium.chrome", "org.chromium.chrome.tests", ARC_INTENT_HELPER_BROWSER)); /** Caches the package name of the host browser. */ private static String sHostPackage; @@ -136,17 +142,29 @@ } /** Returns whether a WebAPK should be launched as a tab. See crbug.com/772398. */ - public static boolean shouldLaunchInTab( - String hostBrowserPackageName, int hostBrowserChromiumMajorVersion) { + public static boolean shouldLaunchInTab(HostBrowserLauncherParams params) { + String hostBrowserPackageName = params.getHostBrowserPackageName(); + int hostBrowserMajorChromiumVersion = params.getHostBrowserMajorChromiumVersion(); if (!sBrowsersSupportingWebApk.contains(hostBrowserPackageName)) { return true; } - if (TextUtils.equals(hostBrowserPackageName, "org.chromium.arc.intent_helper")) { - return hostBrowserChromiumMajorVersion < MINIMUM_REQUIRED_INTENT_HELPER_VERSION; + if (TextUtils.equals(hostBrowserPackageName, ARC_INTENT_HELPER_BROWSER)) { + return hostBrowserMajorChromiumVersion < MINIMUM_REQUIRED_INTENT_HELPER_VERSION; } - return hostBrowserChromiumMajorVersion < MINIMUM_REQUIRED_CHROME_VERSION; + return hostBrowserMajorChromiumVersion < MINIMUM_REQUIRED_CHROME_VERSION; + } + + /** + * Returns whether intents (android.intent.action.MAIN, android.intent.action.SEND ...) should + * launch {@link SplashActivity} for the given host browser params. + */ + public static boolean shouldIntentLaunchSplashActivity(HostBrowserLauncherParams params) { + return !params.getHostBrowserPackageName().equals(ARC_INTENT_HELPER_BROWSER) + && params.getHostBrowserMajorChromiumVersion() + >= MINIMUM_REQUIRED_CHROMIUM_VERSION_NEW_SPLASH + && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N; } /**
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OLauncher.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OLauncher.java index b7ca981..296e54b 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OLauncher.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OLauncher.java
@@ -10,7 +10,6 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; -import android.os.Build; import android.os.Bundle; import android.util.Log; @@ -21,21 +20,8 @@ /** Contains methods for launching host browser where ShellAPK shows the splash screen. */ public class H2OLauncher { - // Lowest version of Chromium which supports ShellAPK showing the splash screen. - static final int MINIMUM_REQUIRED_CHROMIUM_VERSION_NEW_SPLASH = 77; - private static final String TAG = "cr_H2OLauncher"; - /** - * Returns whether intents (android.intent.action.MAIN, android.intent.action.SEND ...) should - * launch {@link SplashActivity} for the given host browser params. - */ - public static boolean shouldIntentLaunchSplashActivity(HostBrowserLauncherParams params) { - return params.getHostBrowserMajorChromiumVersion() - >= MINIMUM_REQUIRED_CHROMIUM_VERSION_NEW_SPLASH - && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N; - } - /** Returns whether the WebAPK requested a relaunch within the last {@link deltaMs}. */ public static boolean didRequestRelaunchFromHostBrowserWithinLastMs( Context context, long deltaMs) {
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OMainActivity.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OMainActivity.java index 5b2156e..c3cd12c 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OMainActivity.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OMainActivity.java
@@ -10,6 +10,7 @@ import org.chromium.webapk.shell_apk.HostBrowserLauncher; import org.chromium.webapk.shell_apk.HostBrowserLauncherParams; +import org.chromium.webapk.shell_apk.HostBrowserUtils; import org.chromium.webapk.shell_apk.TransparentLauncherActivity; /** @@ -36,7 +37,7 @@ } Context appContext = getApplicationContext(); - if (H2OLauncher.shouldIntentLaunchSplashActivity(params) + if (HostBrowserUtils.shouldIntentLaunchSplashActivity(params) && !H2OLauncher.didRequestRelaunchFromHostBrowserWithinLastMs( appContext, MINIMUM_INTERVAL_BETWEEN_RELAUNCHES_MS)) { // Request the host browser to relaunch the WebAPK. We cannot relaunch ourselves
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OTransparentLauncherActivity.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OTransparentLauncherActivity.java index f842eec..66bd43b1 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OTransparentLauncherActivity.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OTransparentLauncherActivity.java
@@ -9,6 +9,7 @@ import org.chromium.webapk.shell_apk.HostBrowserLauncher; import org.chromium.webapk.shell_apk.HostBrowserLauncherParams; +import org.chromium.webapk.shell_apk.HostBrowserUtils; import org.chromium.webapk.shell_apk.TransparentLauncherActivity; import org.chromium.webapk.shell_apk.WebApkUtils; @@ -25,7 +26,7 @@ WebApkUtils.grantUriPermissionToHostBrowserIfShare(getApplicationContext(), params); - boolean shouldLaunchSplash = H2OLauncher.shouldIntentLaunchSplashActivity(params); + boolean shouldLaunchSplash = HostBrowserUtils.shouldIntentLaunchSplashActivity(params); if (relaunchIfNeeded(params, shouldLaunchSplash)) { return; }
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/SplashActivity.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/SplashActivity.java index 3375a2b..7f68c80 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/SplashActivity.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/SplashActivity.java
@@ -22,6 +22,7 @@ import org.chromium.webapk.lib.common.WebApkMetaDataUtils; import org.chromium.webapk.shell_apk.HostBrowserLauncher; import org.chromium.webapk.shell_apk.HostBrowserLauncherParams; +import org.chromium.webapk.shell_apk.HostBrowserUtils; import org.chromium.webapk.shell_apk.LaunchHostBrowserSelector; import org.chromium.webapk.shell_apk.WebApkUtils; @@ -183,7 +184,7 @@ Context appContext = getApplicationContext(); - if (!H2OLauncher.shouldIntentLaunchSplashActivity(params)) { + if (!HostBrowserUtils.shouldIntentLaunchSplashActivity(params)) { HostBrowserLauncher.launch(this, params); H2OLauncher.changeEnabledComponentsAndKillShellApk(appContext, new ComponentName(appContext, H2OMainActivity.class),
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 413869d..2786e5a 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -1235,13 +1235,13 @@ Battery isn't charging </message> <message name="IDS_WILCO_NOTIFICATION_BATTERY_AUTH_MESSAGE" desc="The message of the notification shown to inform the user that an unauthorized battery is connected to a Chromebook."> - To charge, use a battery by the maker of your Chromebook. + To charge this Chromebook, use a battery from the same brand. </message> <message name="IDS_WILCO_NOTIFICATION_NON_WILCO_CHARGER_TITLE" desc="The title of the notification shown to inform the user that charger is unauthorized and battery will not charge."> Power adapter issue </message> <message name="IDS_WILCO_NOTIFICATION_NON_WILCO_CHARGER_MESSAGE" desc="The message of the notification shown to inform the user that charger is unauthorized and battery will not charge."> - To avoid charging or performance issues, use a USB Type-C power adapter or an adapter by the maker of your Chromebook. + Please use a USB Type-C power adapter or an adapter from the same brand as your Chromebook. </message> <message name="IDS_WILCO_NOTIFICATION_INCOMPATIBLE_DOCK_TITLE" desc="The title of the notification shown to inform the user that attached dock is incompatible."> Not all features on this dock are supported @@ -3266,9 +3266,6 @@ <message name="IDS_ASSISTANT_DONE_BUTTON" desc="Done button for asssitant optin flow."> Done </message> - <message name="IDS_ASSISTANT_HOTWORD_NOTIFICATION_TITLE" desc="Title for assistant hotword enable notification."> - Turn on 'Ok Google' - </message> <message name="IDS_ASSISTANT_ACTIVITY_CONTROL_POPUP_LINK" desc="Link text for activity control details popup."> Learn more </message> @@ -4165,4 +4162,12 @@ <message name="IDS_LOGIN_EXTENSION_UI_DIALOG_TITLE" desc="Dialog title for windows opened from a login screen extension. These windows will be displayed over the login screen."> This authentication service is hosted by <ph name="EXTENSION_NAME">$1<ex>Identity Provider Name</ex></ph> </message> + + <!-- Strings for notifications about features which aren't supported in Crostini --> + <message name="IDS_CROSTINI_UNSUPPORTED_VIRTUAL_KEYBOARD" desc="Text for notification message shown when a user tries to use a virtual keyboard or tablet mode in a Linux app."> + The on-screen keyboard doesn’t work in Linux apps yet + </message> + <message name="IDS_CROSTINI_UNSUPPORTED_IME" desc="Text for notification message shown when a user tries to use an unsupported Input Method Editor (IME) in a Linux app."> + <ph name="IME_NAME">$1<ex>German NEO 2 keyboard</ex></ph> doesn’t work in Linux apps yet + </message> </grit-part>
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index c42fc6a..03f3c74 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -9861,6 +9861,12 @@ Your feedback is important to us. </message> </if> + <message name="IDS_NOTIFICATION_DEFAULT_HELPFUL_BUTTON_TEXT" desc="Text body for the helpful button in notifications sent from notification scheduler."> + Helpful + </message> + <message name="IDS_NOTIFICATION_DEFAULT_UNHELPFUL_BUTTON_TEXT" desc="Text body for the unhelpful button in notifications sent from notification scheduler."> + Not Helpful + </message> </messages> </release> </grit>
diff --git a/chrome/app/media_router_strings.grdp b/chrome/app/media_router_strings.grdp index 6f30cae4..272b84e1 100644 --- a/chrome/app/media_router_strings.grdp +++ b/chrome/app/media_router_strings.grdp
@@ -73,6 +73,9 @@ <message name="IDS_MEDIA_ROUTER_ISSUE_FILE_CAST_ERROR" desc="Title of an issue to show when a selected file cannot be cast, file specified by FILE_NAME."> Unable to cast <ph name="FILE_NAME">$1<ex>my_media.mp3</ex></ph>. </message> + <message name="IDS_MEDIA_ROUTER_ISSUE_TAB_AUDIO_NOT_SUPPORTED" desc="Title of an issue shown when the user is casting a tab, but only its visual content can be cast and not its audio output."> + Casting tab audio is not supported on this device. + </message> <!-- Sink List --> <message name="IDS_MEDIA_ROUTER_STATUS_LOOKING_FOR_DEVICES" desc="Status text temporarily shown while searching for Cast devices but none have been found.">
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 34c3d592..86d9b7eb 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -171,19 +171,25 @@ <message name="IDS_SETTINGS_CAPTIONS" desc="Name of the settings page which displays caption preferences."> Captions </message> - <message name="IDS_SETTINGS_CAPTIONS_TEXT_SIZE" desc="Name of the settings page which displays caption text size preferences."> + <message name="IDS_SETTINGS_CAPTIONS_SETTINGS" desc="Name of settings section of the caption settings page."> + Settings + </message> + <message name="IDS_SETTINGS_CAPTIONS_PREVIEW" desc="Name of preview section of the caption settings page."> + Preview + </message> + <message name="IDS_SETTINGS_CAPTIONS_TEXT_SIZE" desc="Name of the caption text size preference."> Text size </message> - <message name="IDS_SETTINGS_CAPTIONS_TEXT_FONT" desc="Name of the settings page which displays caption text font preferences."> + <message name="IDS_SETTINGS_CAPTIONS_TEXT_FONT" desc="Name of the caption text font preference."> Text font </message> - <message name="IDS_SETTINGS_CAPTIONS_TEXT_COLOR" desc="Name of the settings page which displays caption text color preferences."> + <message name="IDS_SETTINGS_CAPTIONS_TEXT_COLOR" desc="Name of the caption text color preference."> Text color </message> - <message name="IDS_SETTINGS_CAPTIONS_TEXT_OPACITY" desc="Name of the settings page which displays caption text opacity preferences."> + <message name="IDS_SETTINGS_CAPTIONS_TEXT_OPACITY" desc="Name of the caption text opacity preference."> Text opacity </message> - <message name="IDS_SETTINGS_CAPTIONS_BACKGROUND_OPACITY" desc="Name of the settings page which displays caption background opacity preferences."> + <message name="IDS_SETTINGS_CAPTIONS_BACKGROUND_OPACITY" desc="Name of the caption background opacity preference."> Background opacity </message> <message name="IDS_SETTINGS_CAPTIONS_OPACITY_MIN" desc="Value of the minimum captions text opacity setting."> @@ -192,7 +198,7 @@ <message name="IDS_SETTINGS_CAPTIONS_OPACITY_MAX" desc="Value of the maximum captions text opacity setting."> 100 </message> - <message name="IDS_SETTINGS_CAPTIONS_TEXT_SHADOW" desc="Name of the settings page which displays caption text shadow preferences."> + <message name="IDS_SETTINGS_CAPTIONS_TEXT_SHADOW" desc="Name of the caption text shadow preference."> Text shadow </message> <message name="IDS_SETTINGS_CAPTIONS_TEXT_SHADOW_NONE" desc="Name of the None option for the caption text shadow."> @@ -210,7 +216,7 @@ <message name="IDS_SETTINGS_CAPTIONS_TEXT_SHADOW_DROP_SHADOW" desc="Name of the Drop shadow option for the caption text shadow."> Drop shadow </message> - <message name="IDS_SETTINGS_CAPTIONS_BACKGROUND_COLOR" desc="Name of the settings page which displays caption background color preferences."> + <message name="IDS_SETTINGS_CAPTIONS_BACKGROUND_COLOR" desc="Name of the caption background color preference."> Background color </message> <message name="IDS_SETTINGS_CAPTIONS_COLOR_BLACK" desc="Name of the Black color for the caption text or background."> @@ -3824,7 +3830,7 @@ <message name="IDS_SETTINGS_PEOPLE_LOCK_SCREEN_NEW_FINGERPRINT_DEFAULT_NAME" desc="The default name (plus a number for a newly added fingerprint)."> Finger <ph name="NEW_FINGER_NUMBER">$1<ex>1</ex></ph> </message> - <message name="IDS_SETTINGS_PEOPLE_LOCK_SCREEN_MEDIA_KEYS" desc="Label for the checkbox which enables or disables media keys on the lock screen."> + <message name="IDS_SETTINGS_PEOPLE_LOCK_SCREEN_MEDIA_CONTROLS" desc="Label for the checkbox which enables or disables media controls on the lock screen."> Enable Chrome media playback at lock screen </message> <message name="IDS_SETTINGS_ACCOUNT_MANAGER_ADD_ACCOUNT_LABEL" desc="Label of the Add account button in Account Manager.">
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_CAPTIONS.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CAPTIONS.png.sha1 index 4ba1991..ed36b53 100644 --- a/chrome/app/settings_strings_grdp/IDS_SETTINGS_CAPTIONS.png.sha1 +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_CAPTIONS.png.sha1
@@ -1 +1 @@ -3e05aa8562cd7a68d00d313431aca4dfe7effc5e \ No newline at end of file +39f3d045711d6364907ad1e709fa85cfac133726 \ No newline at end of file
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 1e90b149..1f68539 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -2353,15 +2353,6 @@ SINGLE_VALUE_TYPE( ::switches:: kEnableExperimentalAccessibilityChromeVoxLanguageSwitching)}, - {"enable-experimental-accessibility-chromevox-rich-text-indication", - flag_descriptions:: - kExperimentalAccessibilityChromeVoxRichTextIndicationName, - flag_descriptions:: - kExperimentalAccessibilityChromeVoxRichTextIndicationDescription, - kOsCrOS, - SINGLE_VALUE_TYPE( - ::switches:: - kEnableExperimentalAccessibilityChromeVoxRichTextIndication)}, {"enable-experimental-kernel-vm-support", flag_descriptions::kKernelnextVMsName, flag_descriptions::kKernelnextVMsDescription, kOsCrOS, @@ -4311,6 +4302,13 @@ flag_descriptions::kPolicyAtomicGroupsEnabledDescription, kOsAll, FEATURE_VALUE_TYPE(policy::features::kPolicyAtomicGroup)}, + {"enable-autofill-updated-card-unmask-prompt-ui", + flag_descriptions::kEnableAutofillUpdatedCardUnmaskPromptUiName, + flag_descriptions::kEnableAutofillUpdatedCardUnmaskPromptUiDescription, + kOsDesktop, + FEATURE_VALUE_TYPE( + autofill::features::kAutofillUpdatedCardUnmaskPromptUi)}, + // NOTE: Adding a new flag requires adding a corresponding entry to enum // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag // Histograms" in tools/metrics/histograms/README.md (run the
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc index a3d8712..c51ce3c 100644 --- a/chrome/browser/android/chrome_feature_list.cc +++ b/chrome/browser/android/chrome_feature_list.cc
@@ -129,6 +129,7 @@ &kDownloadFileProvider, &kDownloadHomeV2, &kDownloadHomeShowStorageInfo, + &kDownloadNotificationBadge, &kDownloadProgressInfoBar, &kDownloadRename, &kDownloadTabManagementModule, @@ -392,6 +393,9 @@ const base::Feature kDownloadHomeShowStorageInfo{ "DownloadHomeShowStorageInfo", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kDownloadNotificationBadge{ + "DownloadNotificationBadge", base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kDownloadRename{"DownloadRename", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/browser/android/chrome_feature_list.h b/chrome/browser/android/chrome_feature_list.h index 460a7fc69..bad8998 100644 --- a/chrome/browser/android/chrome_feature_list.h +++ b/chrome/browser/android/chrome_feature_list.h
@@ -63,6 +63,7 @@ extern const base::Feature kDownloadHomeV2; extern const base::Feature kDownloadHomeShowStorageInfo; extern const base::Feature kDownloadLocationShowImageInGallery; +extern const base::Feature kDownloadNotificationBadge; extern const base::Feature kDownloadProgressInfoBar; extern const base::Feature kDownloadRename; extern const base::Feature kDownloadTabManagementModule;
diff --git a/chrome/browser/android/vr/mailbox_to_surface_bridge.cc b/chrome/browser/android/vr/mailbox_to_surface_bridge.cc index 6dd3872d..cf991b4 100644 --- a/chrome/browser/android/vr/mailbox_to_surface_bridge.cc +++ b/chrome/browser/android/vr/mailbox_to_surface_bridge.cc
@@ -137,7 +137,7 @@ TRACE_EVENT0("gpu", "MailboxToSurfaceBridge::ConsumeTexture"); gl->WaitSyncTokenCHROMIUM(mailbox.sync_token.GetConstData()); - return gl->CreateAndConsumeTextureCHROMIUM(mailbox.mailbox.name); + return gl->CreateAndTexStorage2DSharedImageCHROMIUM(mailbox.mailbox.name); } } // namespace @@ -321,8 +321,13 @@ needs_resize_ = false; } + DCHECK(mailbox.mailbox.IsSharedImage()); + GLuint sourceTexture = ConsumeTexture(gl_, mailbox); + gl_->BeginSharedImageAccessDirectCHROMIUM( + sourceTexture, GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM); DrawQuad(sourceTexture); + gl_->EndSharedImageAccessDirectCHROMIUM(sourceTexture); gl_->DeleteTextures(1, &sourceTexture); gl_->SwapBuffers(swap_id_++); return true;
diff --git a/chrome/browser/apps/app_service/app_launch_params.cc b/chrome/browser/apps/app_service/app_launch_params.cc index c67cdca..b2c4006 100644 --- a/chrome/browser/apps/app_service/app_launch_params.cc +++ b/chrome/browser/apps/app_service/app_launch_params.cc
@@ -16,8 +16,7 @@ disposition(disposition), command_line(base::CommandLine::NO_PROGRAM), source(source), - display_id(display_id), - opener(nullptr) {} + display_id(display_id) {} AppLaunchParams::AppLaunchParams(const AppLaunchParams& other) = default;
diff --git a/chrome/browser/apps/app_service/app_launch_params.h b/chrome/browser/apps/app_service/app_launch_params.h index 32a17a4..63909198 100644 --- a/chrome/browser/apps/app_service/app_launch_params.h +++ b/chrome/browser/apps/app_service/app_launch_params.h
@@ -18,10 +18,6 @@ class Profile; -namespace content { -class RenderFrameHost; -} - struct AppLaunchParams { AppLaunchParams(Profile* profile, const std::string& app_id, @@ -77,10 +73,6 @@ // set. int64_t display_id; - // The frame that initiated the open. May be null. If set, the new app will - // have |opener| as its window.opener. - content::RenderFrameHost* opener; - // The files the application was launched with. Empty if the application was // not launched with files. std::vector<base::FilePath> launch_files;
diff --git a/chrome/browser/apps/guest_view/extension_view/extension_view_browsertest.cc b/chrome/browser/apps/guest_view/extension_view/extension_view_browsertest.cc deleted file mode 100644 index 8bfb59e..0000000 --- a/chrome/browser/apps/guest_view/extension_view/extension_view_browsertest.cc +++ /dev/null
@@ -1,155 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/strings/stringprintf.h" -#include "chrome/browser/apps/platform_apps/app_browsertest_util.h" -#include "chrome/test/base/ui_test_utils.h" -#include "components/guest_view/browser/guest_view_manager.h" -#include "components/guest_view/browser/guest_view_manager_delegate.h" -#include "components/guest_view/browser/guest_view_manager_factory.h" -#include "components/guest_view/browser/test_guest_view_manager.h" -#include "content/public/common/content_features.h" -#include "content/public/common/content_switches.h" -#include "content/public/test/browser_test_utils.h" -#include "extensions/browser/api/extensions_api_client.h" -#include "extensions/test/extension_test_message_listener.h" -#include "testing/gtest/include/gtest/gtest.h" - -using extensions::ExtensionsAPIClient; -using guest_view::GuestViewManager; -using guest_view::TestGuestViewManager; -using guest_view::TestGuestViewManagerFactory; - -class ExtensionViewTest : public extensions::PlatformAppBrowserTest { - public: - ExtensionViewTest() { - CHECK( - base::FeatureList::IsEnabled(::features::kGuestViewCrossProcessFrames)); - GuestViewManager::set_factory_for_testing(&factory_); - } - - TestGuestViewManager* GetGuestViewManager() { - TestGuestViewManager* manager = static_cast<TestGuestViewManager*>( - TestGuestViewManager::FromBrowserContext(browser()->profile())); - // TestGuestViewManager::WaitForSingleGuestCreated may and will get called - // before a guest is created. - if (!manager) { - manager = static_cast<TestGuestViewManager*>( - GuestViewManager::CreateWithDelegate( - browser()->profile(), - ExtensionsAPIClient::Get()->CreateGuestViewManagerDelegate( - browser()->profile()))); - } - return manager; - } - - void TestHelper(const std::string& test_name, - const std::string& app_location, - const std::string& app_to_embed, - const std::string& second_app_to_embed) { - LoadAndLaunchPlatformApp(app_location.c_str(), "Launched"); - - // Flush any pending events to make sure we start with a clean slate. - content::RunAllPendingInMessageLoop(); - - content::WebContents* embedder_web_contents = - GetFirstAppWindowWebContents(); - if (!embedder_web_contents) { - LOG(ERROR) << "UNABLE TO FIND EMBEDDER WEB CONTENTS."; - return; - } - - ExtensionTestMessageListener done_listener("TEST_PASSED", false); - done_listener.set_failure_message("TEST_FAILED"); - if (!content::ExecuteScript( - embedder_web_contents, - base::StringPrintf("runTest('%s', '%s', '%s')", test_name.c_str(), - app_to_embed.c_str(), - second_app_to_embed.c_str()))) { - LOG(ERROR) << "UNABLE TO START TEST."; - return; - } - ASSERT_TRUE(done_listener.WaitUntilSatisfied()); - } - - private: - TestGuestViewManagerFactory factory_; -}; - -// Tests that <extensionview> can be created and added to the DOM. -IN_PROC_BROWSER_TEST_F(ExtensionViewTest, - TestExtensionViewCreationShouldSucceed) { - TestHelper("testExtensionViewCreationShouldSucceed", - "extension_view/creation", "", ""); -} - -// Tests that verify that <extensionview> does not change extension ID if -// someone tries to change it in JavaScript. -IN_PROC_BROWSER_TEST_F(ExtensionViewTest, ShimExtensionAttribute) { - const extensions::Extension* skeleton_app = - InstallPlatformApp("extension_view/skeleton"); - TestHelper("testExtensionAttribute", "extension_view/extension_attribute", - skeleton_app->id(), ""); -} - -// Tests that verify that <extensionview> does not change src if -// someone tries to change it in JavaScript. -IN_PROC_BROWSER_TEST_F(ExtensionViewTest, ShimSrcAttribute) { - const extensions::Extension* skeleton_app = - InstallPlatformApp("extension_view/skeleton"); - TestHelper("testSrcAttribute", "extension_view/src_attribute", - skeleton_app->id(), ""); -} - -class ExtensionViewLoadApiTest : public ExtensionViewTest { - public: - void TestLoadApiHelper(const std::string& test_name) { - const extensions::Extension* skeleton_app = - InstallPlatformApp("extension_view/skeleton"); - const extensions::Extension* skeleton_app_two = - InstallPlatformApp("extension_view/skeleton_two"); - TestHelper(test_name, "extension_view/load_api", skeleton_app->id(), - skeleton_app_two->id()); - } -}; - -IN_PROC_BROWSER_TEST_F(ExtensionViewLoadApiTest, LoadAPIFunction) { - TestLoadApiHelper("testLoadAPIFunction"); -} - -IN_PROC_BROWSER_TEST_F(ExtensionViewLoadApiTest, LoadAPISameIdAndSrc) { - TestLoadApiHelper("testLoadAPISameIdAndSrc"); -} - -IN_PROC_BROWSER_TEST_F(ExtensionViewLoadApiTest, LoadAPISameIdDifferentSrc) { - TestLoadApiHelper("testLoadAPISameIdDifferentSrc"); -} - -// TODO(crbug.com/810225): Test is flaky. -IN_PROC_BROWSER_TEST_F(ExtensionViewLoadApiTest, - DISABLED_LoadAPILoadOtherExtension) { - TestLoadApiHelper("testLoadAPILoadOtherExtension"); -} - -IN_PROC_BROWSER_TEST_F(ExtensionViewLoadApiTest, LoadAPIInvalidExtension) { - TestLoadApiHelper("testLoadAPIInvalidExtension"); -} - -IN_PROC_BROWSER_TEST_F(ExtensionViewLoadApiTest, LoadAPIAfterInvalidCall) { - TestLoadApiHelper("testLoadAPIAfterInvalidCall"); -} - -IN_PROC_BROWSER_TEST_F(ExtensionViewLoadApiTest, LoadAPINullExtension) { - TestLoadApiHelper("testLoadAPINullExtension"); -} - -IN_PROC_BROWSER_TEST_F(ExtensionViewLoadApiTest, QueuedLoadAPIFunction) { - TestLoadApiHelper("testQueuedLoadAPIFunction"); -} - -// TODO(crbug.com/810225): Test is flaky. -IN_PROC_BROWSER_TEST_F(ExtensionViewLoadApiTest, - DISABLED_QueuedLoadAPILoadOtherExtension) { - TestLoadApiHelper("testQueuedLoadAPILoadOtherExtension"); -}
diff --git a/chrome/browser/availability/availability_prober.h b/chrome/browser/availability/availability_prober.h index d71636db..a211aeb 100644 --- a/chrome/browser/availability/availability_prober.h +++ b/chrome/browser/availability/availability_prober.h
@@ -73,7 +73,6 @@ // enum is mapped to a string value which is then used in histograms and // prefs. enum class ClientName { - // TODO(crbug.com/971918): Use in litepages. kLitepages = 0, kMaxValue = kLitepages,
diff --git a/chrome/browser/banners/app_banner_manager_desktop.cc b/chrome/browser/banners/app_banner_manager_desktop.cc index 9172901..c2e2b71c 100644 --- a/chrome/browser/banners/app_banner_manager_desktop.cc +++ b/chrome/browser/banners/app_banner_manager_desktop.cc
@@ -122,7 +122,7 @@ return web_app::WebAppProvider::Get( Profile::FromBrowserContext(web_contents->GetBrowserContext())) ->registrar() - .IsInstalled(start_url); + .IsLocallyInstalled(start_url); } void AppBannerManagerDesktop::ShowBannerUi(WebappInstallSource install_source) {
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 8ce28ba..c2db887 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -2352,6 +2352,7 @@ "arc/bluetooth/arc_bluetooth_bridge_unittest.cc", "arc/bluetooth/arc_bluetooth_task_queue_unittest.cc", "arc/boot_phase_monitor/arc_boot_phase_monitor_bridge_unittest.cc", + "arc/boot_phase_monitor/arc_instance_throttle_unittest.cc", "arc/enterprise/cert_store/arc_cert_installer_unittest.cc", "arc/enterprise/cert_store/arc_cert_installer_utils_unittest.cc", "arc/extensions/arc_support_message_host_unittest.cc",
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.cc b/chrome/browser/chromeos/accessibility/accessibility_manager.cc index 10fdbe0..8054b60 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager.cc +++ b/chrome/browser/chromeos/accessibility/accessibility_manager.cc
@@ -89,6 +89,7 @@ #include "services/service_manager/public/cpp/connector.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/chromeos/extension_ime_util.h" #include "ui/base/resource/resource_bundle.h" #include "ui/views/widget/widget.h"
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.h b/chrome/browser/chromeos/accessibility/accessibility_manager.h index 132fa90..ce2bb7c 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager.h +++ b/chrome/browser/chromeos/accessibility/accessibility_manager.h
@@ -28,7 +28,7 @@ #include "extensions/browser/event_router.h" #include "extensions/browser/extension_system.h" #include "services/media_session/public/mojom/audio_focus.mojom.h" -#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_enums.mojom-forward.h" #include "ui/base/ime/chromeos/input_method_manager.h" class Browser;
diff --git a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_util.cc b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_util.cc index 43f7de8..2363c70 100644 --- a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_util.cc +++ b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_util.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_util.h" #include "components/arc/mojom/accessibility_helper.mojom.h" +#include "ui/accessibility/ax_enums.mojom.h" namespace arc {
diff --git a/chrome/browser/chromeos/arc/arc_service_launcher.cc b/chrome/browser/chromeos/arc/arc_service_launcher.cc index 05fa4553..7e95bde 100644 --- a/chrome/browser/chromeos/arc/arc_service_launcher.cc +++ b/chrome/browser/chromeos/arc/arc_service_launcher.cc
@@ -20,6 +20,7 @@ #include "chrome/browser/chromeos/arc/auth/arc_auth_service.h" #include "chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge.h" #include "chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h" +#include "chrome/browser/chromeos/arc/boot_phase_monitor/arc_instance_throttle.h" #include "chrome/browser/chromeos/arc/cast_receiver/arc_cast_receiver_service.h" #include "chrome/browser/chromeos/arc/enterprise/arc_enterprise_reporting_service.h" #include "chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_store_bridge.h" @@ -184,6 +185,7 @@ ArcFileSystemWatcherService::GetForBrowserContext(profile); ArcImeService::GetForBrowserContext(profile); ArcInputMethodManagerService::GetForBrowserContext(profile); + ArcInstanceThrottle::GetForBrowserContext(profile); ArcIntentHelperBridge::GetForBrowserContext(profile); ArcKeymasterBridge::GetForBrowserContext(profile); ArcKioskBridge::GetForBrowserContext(profile);
diff --git a/chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.cc b/chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.cc index 5d6b731b..cf22d46 100644 --- a/chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.cc +++ b/chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.cc
@@ -12,21 +12,15 @@ #include "base/metrics/histogram_macros.h" #include "base/one_shot_event.h" #include "chrome/browser/chromeos/arc/arc_util.h" -#include "chrome/browser/chromeos/arc/boot_phase_monitor/arc_instance_throttle.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/sessions/session_restore.h" #include "chrome/browser/ui/ash/multi_user/multi_user_util.h" #include "chromeos/constants/chromeos_switches.h" #include "chromeos/cryptohome/cryptohome_parameters.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/session_manager/session_manager_client.h" -#include "components/arc/arc_browser_context_keyed_service_factory_base.h" #include "components/arc/arc_prefs.h" #include "components/arc/arc_util.h" #include "components/arc/session/arc_bridge_service.h" -#include "extensions/browser/extension_system.h" -#include "extensions/browser/extension_system_provider.h" -#include "extensions/browser/extensions_browser_client.h" namespace arc { namespace { @@ -41,10 +35,6 @@ DefaultDelegateImpl() = default; ~DefaultDelegateImpl() override = default; - void DisableCpuRestriction() override { - SetArcCpuRestriction(false /* do_restrict */); - } - void RecordFirstAppLaunchDelayUMA(base::TimeDelta delta) override { VLOG(2) << "Launching the first app took " << delta.InMillisecondsRoundedUp() << " ms."; @@ -57,33 +47,15 @@ DISALLOW_COPY_AND_ASSIGN(DefaultDelegateImpl); }; -// Singleton factory for ArcBootPhaseMonitorBridge. -class ArcBootPhaseMonitorBridgeFactory - : public internal::ArcBrowserContextKeyedServiceFactoryBase< - ArcBootPhaseMonitorBridge, - ArcBootPhaseMonitorBridgeFactory> { - public: - // Factory name used by ArcBrowserContextKeyedServiceFactoryBase. - static constexpr const char* kName = "ArcBootPhaseMonitorBridgeFactory"; - - static ArcBootPhaseMonitorBridgeFactory* GetInstance() { - return base::Singleton<ArcBootPhaseMonitorBridgeFactory>::get(); - } - - private: - friend base::DefaultSingletonTraits<ArcBootPhaseMonitorBridgeFactory>; - - ArcBootPhaseMonitorBridgeFactory() { - DependsOn(extensions::ExtensionsBrowserClient::Get() - ->GetExtensionSystemFactory()); - } - - ~ArcBootPhaseMonitorBridgeFactory() override = default; -}; - } // namespace // static +ArcBootPhaseMonitorBridgeFactory* +ArcBootPhaseMonitorBridgeFactory::GetInstance() { + return base::Singleton<ArcBootPhaseMonitorBridgeFactory>::get(); +} + +// static ArcBootPhaseMonitorBridge* ArcBootPhaseMonitorBridge::GetForBrowserContext( content::BrowserContext* context) { return ArcBootPhaseMonitorBridgeFactory::GetForBrowserContext(context); @@ -108,8 +80,7 @@ ArcBootPhaseMonitorBridge::ArcBootPhaseMonitorBridge( content::BrowserContext* context, ArcBridgeService* bridge_service) - : context_(context), - arc_bridge_service_(bridge_service), + : arc_bridge_service_(bridge_service), account_id_(multi_user_util::GetAccountIdFromProfile( Profile::FromBrowserContext(context))), // Set the default delegate. Unit tests may use a different one. @@ -119,17 +90,6 @@ auto* arc_session_manager = ArcSessionManager::Get(); DCHECK(arc_session_manager); arc_session_manager->AddObserver(this); - SessionRestore::AddObserver(this); - - auto* profile = Profile::FromBrowserContext(context); - auto* extension_system = extensions::ExtensionSystem::Get(profile); - DCHECK(extension_system); - extension_system->ready().Post( - FROM_HERE, base::BindOnce(&ArcBootPhaseMonitorBridge::OnExtensionsReady, - weak_ptr_factory_.GetWeakPtr())); - - // Initialize |enabled_by_policy_| now. - OnArcPlayStoreEnabledChanged(IsArcPlayStoreEnabledForProfile(profile)); } ArcBootPhaseMonitorBridge::~ArcBootPhaseMonitorBridge() { @@ -138,7 +98,14 @@ auto* arc_session_manager = ArcSessionManager::Get(); DCHECK(arc_session_manager); arc_session_manager->RemoveObserver(this); - SessionRestore::RemoveObserver(this); +} + +void ArcBootPhaseMonitorBridge::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void ArcBootPhaseMonitorBridge::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); } void ArcBootPhaseMonitorBridge::RecordFirstAppLaunchDelayUMAInternal() { @@ -165,102 +132,28 @@ cryptohome::CreateAccountIdentifierFromAccountId(account_id_), base::BindOnce(&OnEmitArcBooted)); - ArcSessionManager* arc_session_manager = ArcSessionManager::Get(); - DCHECK(arc_session_manager); - if (arc_session_manager->is_directly_started()) { - // Unless this is opt-in boot, start monitoring window activation changes to - // prioritize/throttle the container when needed. - throttle_ = std::make_unique<ArcInstanceThrottle>(); - VLOG(2) << "ArcInstanceThrottle created in OnBootCompleted()"; - } - if (!app_launch_time_.is_null() && delegate_) { delegate_->RecordFirstAppLaunchDelayUMA(base::TimeTicks::Now() - app_launch_time_); } -} - -void ArcBootPhaseMonitorBridge::OnArcPlayStoreEnabledChanged(bool enabled) { - auto* profile = Profile::FromBrowserContext(context_); - enabled_by_policy_ = - enabled && IsArcPlayStoreEnabledPreferenceManagedForProfile(profile); - if (enabled_by_policy_) - MaybeDisableCpuRestriction(); -} - -void ArcBootPhaseMonitorBridge::OnArcInitialStart() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - // ARC apps for opt-in finished doing their jobs. Start the throttle. - throttle_ = std::make_unique<ArcInstanceThrottle>(); - VLOG(2) << "ArcInstanceThrottle created in OnArcInitialStart()"; + for (auto& observer : observers_) + observer.OnBootCompleted(); } void ArcBootPhaseMonitorBridge::OnArcSessionStopped(ArcStopReason stop_reason) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - // Remove the throttle so that the window observer won't interfere with the - // container startup when the user opts in to ARC. Reset(); - VLOG(2) << "ArcInstanceThrottle has been removed in OnArcSessionStopped()"; } void ArcBootPhaseMonitorBridge::OnArcSessionRestarting() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - // Remove the throttle so that the window observer won't interfere with the - // container restart. Reset(); - VLOG(2) << "ArcInstanceThrottle has been removed in OnArcSessionRestarting()"; - - // We assume that a crash tends to happen while the user is actively using - // the instance. For that reason, we try to restart the instance without the - // restricted cgroups. - if (delegate_) - delegate_->DisableCpuRestriction(); -} - -void ArcBootPhaseMonitorBridge::OnSessionRestoreFinishedLoadingTabs() { - VLOG(2) << "All tabs have been restored"; - if (throttle_) - return; - // |throttle_| is not available. This means either of the following: - // 1) This is an opt-in boot, and OnArcInitialStart() hasn't been called. - // 2) This is not an opt-in boot, and OnBootCompleted() hasn't been called. - // In both cases, relax the restriction to let the instance fully start. - VLOG(2) << "Allowing the instance to use more CPU resources"; - if (delegate_) - delegate_->DisableCpuRestriction(); -} - -void ArcBootPhaseMonitorBridge::OnExtensionsReady() { - VLOG(2) << "All extensions are loaded"; - extensions_ready_ = true; - MaybeDisableCpuRestriction(); -} - -void ArcBootPhaseMonitorBridge::MaybeDisableCpuRestriction() { - // Unthrottle ARC instance if the instance is being tested, indicated by the - // disable cpu restriction switch. - if (chromeos::switches::IsArcCpuRestrictionDisabled() && delegate_) { - delegate_->DisableCpuRestriction(); - return; - } - - if (throttle_) - return; - if (!extensions_ready_ || !enabled_by_policy_) - return; - - VLOG(1) << "ARC is enabled by policy. " - << "Allowing the instance to use more CPU resources"; - if (delegate_) - delegate_->DisableCpuRestriction(); } void ArcBootPhaseMonitorBridge::Reset() { - throttle_.reset(); app_launch_time_ = base::TimeTicks(); first_app_launch_delay_recorded_ = false; boot_completed_ = false; - enabled_by_policy_ = false; // Do not reset |extensions_ready_| here. That variable is not tied to the // instance.
diff --git a/chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h b/chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h index f23b2f3..ae4de5d4 100644 --- a/chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h +++ b/chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h
@@ -8,12 +8,15 @@ #include <memory> #include "base/macros.h" +#include "base/memory/singleton.h" #include "base/memory/weak_ptr.h" +#include "base/observer_list_types.h" #include "base/threading/thread_checker.h" #include "base/time/time.h" #include "chrome/browser/chromeos/arc/arc_session_manager.h" #include "chrome/browser/sessions/session_restore_observer.h" #include "components/account_id/account_id.h" +#include "components/arc/arc_browser_context_keyed_service_factory_base.h" #include "components/arc/mojom/boot_phase_monitor.mojom.h" #include "components/keyed_service/core/keyed_service.h" @@ -24,25 +27,26 @@ namespace arc { class ArcBridgeService; -class ArcInstanceThrottle; // Receives events regarding ARC boot phase from both ARC and Chrome, and do // either one-time or continuous container priority adjustment / UMA recording // in response. -class ArcBootPhaseMonitorBridge - : public KeyedService, - public mojom::BootPhaseMonitorHost, - public ArcSessionManager::Observer, - public SessionRestoreObserver { +class ArcBootPhaseMonitorBridge : public KeyedService, + public mojom::BootPhaseMonitorHost, + public ArcSessionManager::Observer { public: class Delegate { public: virtual ~Delegate() = default; - - virtual void DisableCpuRestriction() = 0; virtual void RecordFirstAppLaunchDelayUMA(base::TimeDelta delta) = 0; }; + class Observer : public base::CheckedObserver { + public: + ~Observer() override = default; + virtual void OnBootCompleted() = 0; + }; + // Returns singleton instance for the given BrowserContext, // or nullptr if the browser |context| is not allowed to use ARC. static ArcBootPhaseMonitorBridge* GetForBrowserContext( @@ -65,52 +69,37 @@ ArcBridgeService* bridge_service); ~ArcBootPhaseMonitorBridge() override; + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + // mojom::BootPhaseMonitorHost void OnBootCompleted() override; // ArcSessionManager::Observer - void OnArcPlayStoreEnabledChanged(bool enabled) override; - void OnArcInitialStart() override; void OnArcSessionStopped(ArcStopReason stop_reason) override; void OnArcSessionRestarting() override; - // SessionRestoreObserver - void OnSessionRestoreFinishedLoadingTabs() override; - void SetDelegateForTesting(std::unique_ptr<Delegate> delegate); void RecordFirstAppLaunchDelayUMAForTesting() { RecordFirstAppLaunchDelayUMAInternal(); } - void OnExtensionsReadyForTesting() { OnExtensionsReady(); } - - ArcInstanceThrottle* throttle_for_testing() const { return throttle_.get(); } private: void RecordFirstAppLaunchDelayUMAInternal(); void Reset(); - void MaybeDisableCpuRestriction(); - - // Called when ExtensionsServices finishes loading all extensions for the - // profile. - void OnExtensionsReady(); THREAD_CHECKER(thread_checker_); - content::BrowserContext* const context_; ArcBridgeService* const arc_bridge_service_; // Owned by ArcServiceManager. const AccountId account_id_; std::unique_ptr<Delegate> delegate_; - - // Indicates whether all extensions for the profile have been loaded. - bool extensions_ready_ = false; + base::ObserverList<Observer> observers_; // The following variables must be reset every time when the instance stops or // restarts. - std::unique_ptr<ArcInstanceThrottle> throttle_; base::TimeTicks app_launch_time_; bool first_app_launch_delay_recorded_ = false; bool boot_completed_ = false; - bool enabled_by_policy_ = false; // This has to be the last member variable in the class. base::WeakPtrFactory<ArcBootPhaseMonitorBridge> weak_ptr_factory_; @@ -118,6 +107,25 @@ DISALLOW_COPY_AND_ASSIGN(ArcBootPhaseMonitorBridge); }; +// Singleton factory for ArcBootPhaseMonitorBridge. +class ArcBootPhaseMonitorBridgeFactory + : public internal::ArcBrowserContextKeyedServiceFactoryBase< + ArcBootPhaseMonitorBridge, + ArcBootPhaseMonitorBridgeFactory> { + public: + // Factory name used by ArcBrowserContextKeyedServiceFactoryBase. + static constexpr const char* kName = "ArcBootPhaseMonitorBridgeFactory"; + + static ArcBootPhaseMonitorBridgeFactory* GetInstance(); + + private: + friend base::DefaultSingletonTraits<ArcBootPhaseMonitorBridgeFactory>; + + ArcBootPhaseMonitorBridgeFactory() = default; + + ~ArcBootPhaseMonitorBridgeFactory() override = default; +}; + } // namespace arc #endif // CHROME_BROWSER_CHROMEOS_ARC_BOOT_PHASE_MONITOR_ARC_BOOT_PHASE_MONITOR_BRIDGE_H_
diff --git a/chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge_unittest.cc b/chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge_unittest.cc index d88922e5..5610017 100644 --- a/chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge_unittest.cc +++ b/chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge_unittest.cc
@@ -36,7 +36,6 @@ std::make_unique<ArcSessionRunner>( base::BindRepeating(FakeArcSession::Create)))), testing_profile_(std::make_unique<TestingProfile>()), - disable_cpu_restriction_counter_(0), record_uma_counter_(0) { chromeos::SessionManagerClient::InitializeFakeInMemory(); @@ -67,9 +66,6 @@ ArcBootPhaseMonitorBridge* boot_phase_monitor_bridge() const { return boot_phase_monitor_bridge_; } - size_t disable_cpu_restriction_counter() const { - return disable_cpu_restriction_counter_; - } size_t record_uma_counter() const { return record_uma_counter_; } base::TimeDelta last_time_delta() const { return last_time_delta_; } @@ -84,10 +80,6 @@ : test_(test) {} ~TestDelegateImpl() override = default; - // ArcBootPhaseMonitorBridge::Delegate overrides: - void DisableCpuRestriction() override { - ++(test_->disable_cpu_restriction_counter_); - } void RecordFirstAppLaunchDelayUMA(base::TimeDelta delta) override { test_->last_time_delta_ = delta; ++(test_->record_uma_counter_); @@ -111,7 +103,6 @@ std::unique_ptr<TestingProfile> testing_profile_; ArcBootPhaseMonitorBridge* boot_phase_monitor_bridge_; - size_t disable_cpu_restriction_counter_; size_t record_uma_counter_; base::TimeDelta last_time_delta_; @@ -121,59 +112,6 @@ // Tests that ArcBootPhaseMonitorBridge can be constructed and destructed. TEST_F(ArcBootPhaseMonitorBridgeTest, TestConstructDestruct) {} -// Tests that the throttle is created on BootCompleted. -TEST_F(ArcBootPhaseMonitorBridgeTest, TestThrottleCreation) { - // Tell |arc_session_manager_| that this is not opt-in boot. - arc_session_manager()->set_directly_started_for_testing(true); - - // Initially, |throttle_| is null. - EXPECT_EQ(nullptr, boot_phase_monitor_bridge()->throttle_for_testing()); - // OnBootCompleted() creates it. - boot_phase_monitor_bridge()->OnBootCompleted(); - EXPECT_NE(nullptr, boot_phase_monitor_bridge()->throttle_for_testing()); - // ..but it's removed when the session stops. - boot_phase_monitor_bridge()->OnArcSessionStopped(ArcStopReason::SHUTDOWN); - EXPECT_EQ(nullptr, boot_phase_monitor_bridge()->throttle_for_testing()); -} - -// Tests the same but with OnSessionRestarting(). -TEST_F(ArcBootPhaseMonitorBridgeTest, TestThrottleCreation_Restart) { - // Tell |arc_session_manager_| that this is not opt-in boot. - arc_session_manager()->set_directly_started_for_testing(true); - - EXPECT_EQ(nullptr, boot_phase_monitor_bridge()->throttle_for_testing()); - boot_phase_monitor_bridge()->OnBootCompleted(); - EXPECT_NE(nullptr, boot_phase_monitor_bridge()->throttle_for_testing()); - // Call OnArcSessionRestarting() instead, and confirm that |throttle_| is - // gone. - EXPECT_EQ(0U, disable_cpu_restriction_counter()); - boot_phase_monitor_bridge()->OnArcSessionRestarting(); - EXPECT_EQ(nullptr, boot_phase_monitor_bridge()->throttle_for_testing()); - EXPECT_EQ(1U, disable_cpu_restriction_counter()); - // Also make sure that |throttle| is created again once restarting id done. - boot_phase_monitor_bridge()->OnBootCompleted(); - EXPECT_NE(nullptr, boot_phase_monitor_bridge()->throttle_for_testing()); -} - -// Tests that the throttle is created on ArcInitialStart when opting in. -TEST_F(ArcBootPhaseMonitorBridgeTest, TestThrottleCreation_OptIn) { - // Tell |arc_session_manager_| that this *is* opt-in boot. - arc_session_manager()->set_directly_started_for_testing(false); - - // Initially, |throttle_| is null. - EXPECT_EQ(nullptr, boot_phase_monitor_bridge()->throttle_for_testing()); - // OnArcInitialStart(), which is called when the user accepts ToS, creates - // |throttle_|. - boot_phase_monitor_bridge()->OnArcInitialStart(); - EXPECT_NE(nullptr, boot_phase_monitor_bridge()->throttle_for_testing()); - // ..and OnBootCompleted() does not delete it. - boot_phase_monitor_bridge()->OnBootCompleted(); - EXPECT_NE(nullptr, boot_phase_monitor_bridge()->throttle_for_testing()); - // ..but it's removed when the session stops. - boot_phase_monitor_bridge()->OnArcSessionStopped(ArcStopReason::SHUTDOWN); - EXPECT_EQ(nullptr, boot_phase_monitor_bridge()->throttle_for_testing()); -} - // Tests that the UMA recording function is never called unless // RecordFirstAppLaunchDelayUMA is called. TEST_F(ArcBootPhaseMonitorBridgeTest, TestRecordUMA_None) { @@ -240,95 +178,6 @@ boot_phase_monitor_bridge()->RecordFirstAppLaunchDelayUMAForTesting(); EXPECT_EQ(1U, record_uma_counter()); } - -// Tests that CPU restriction is disabled when tab restoration is done. -TEST_F(ArcBootPhaseMonitorBridgeTest, TestOnSessionRestoreFinishedLoadingTabs) { - EXPECT_EQ(0U, disable_cpu_restriction_counter()); - boot_phase_monitor_bridge()->OnSessionRestoreFinishedLoadingTabs(); - EXPECT_EQ(1U, disable_cpu_restriction_counter()); -} - -// Tests that nothing happens if tab restoration is done after ARC boot. -TEST_F(ArcBootPhaseMonitorBridgeTest, - TestOnSessionRestoreFinishedLoadingTabs_BootFirst) { - // Tell |arc_session_manager_| that this is not opt-in boot. - arc_session_manager()->set_directly_started_for_testing(true); - - // However, OnSessionRestoreFinishedLoadingTabs() should be no-op when the - // instance has already fully started. - boot_phase_monitor_bridge()->OnBootCompleted(); - EXPECT_EQ(0U, disable_cpu_restriction_counter()); - boot_phase_monitor_bridge()->OnSessionRestoreFinishedLoadingTabs(); - EXPECT_EQ(0U, disable_cpu_restriction_counter()); -} - -// Tests that OnExtensionsReady() does nothing by default. -TEST_F(ArcBootPhaseMonitorBridgeTest, TestOnExtensionsReady) { - boot_phase_monitor_bridge()->OnExtensionsReadyForTesting(); - EXPECT_EQ(0U, disable_cpu_restriction_counter()); -} - -// Tests that OnExtensionsReady() does nothing when prefs::kArcEnabled is not -// set. -TEST_F(ArcBootPhaseMonitorBridgeTest, TestOnExtensionsReady_ArcNotEnabled) { - boot_phase_monitor_bridge()->OnArcPlayStoreEnabledChanged(false); - boot_phase_monitor_bridge()->OnExtensionsReadyForTesting(); - EXPECT_EQ(0U, disable_cpu_restriction_counter()); -} - -// Tests that OnExtensionsReady() does nothing when prefs::kArcEnabled is not -// managed. -TEST_F(ArcBootPhaseMonitorBridgeTest, - TestOnExtensionsReady_ArcEnabledButUnmanaged) { - GetPrefs()->SetUserPref(prefs::kArcEnabled, - std::make_unique<base::Value>(true)); - boot_phase_monitor_bridge()->OnArcPlayStoreEnabledChanged(true); - boot_phase_monitor_bridge()->OnExtensionsReadyForTesting(); - EXPECT_EQ(0U, disable_cpu_restriction_counter()); -} - -// Tests that OnExtensionsReady() relaxes the CPU restriction when ARC is -// enabled by policy. -TEST_F(ArcBootPhaseMonitorBridgeTest, - TestOnExtensionsReady_ArcEnabledAndManaged) { - GetPrefs()->SetManagedPref(prefs::kArcEnabled, - std::make_unique<base::Value>(true)); - boot_phase_monitor_bridge()->OnArcPlayStoreEnabledChanged(true); - EXPECT_EQ(0U, disable_cpu_restriction_counter()); - boot_phase_monitor_bridge()->OnExtensionsReadyForTesting(); - EXPECT_EQ(1U, disable_cpu_restriction_counter()); -} - -// Does the same but in a reversed event order. -TEST_F(ArcBootPhaseMonitorBridgeTest, - TestOnExtensionsReady_ArcEnabledAndManaged2) { - boot_phase_monitor_bridge()->OnExtensionsReadyForTesting(); - EXPECT_EQ(0U, disable_cpu_restriction_counter()); - GetPrefs()->SetManagedPref(prefs::kArcEnabled, - std::make_unique<base::Value>(true)); - boot_phase_monitor_bridge()->OnArcPlayStoreEnabledChanged(true); - EXPECT_EQ(1U, disable_cpu_restriction_counter()); -} - -// Does the same but after ARC boot is completed. This emulates the -// situation where ARC instance finishes booting before other conditions -// (|extentions_ready_| and |enabled_by_policy_|) are met. -// |disable_cpu_restriction_counter| should stay 0 in this case because -// ArcInstanceThrottle already has the control. -TEST_F(ArcBootPhaseMonitorBridgeTest, - TestOnExtensionsReady_AfterBootCompleted) { - // Tell |arc_session_manager_| that this is not opt-in boot. - arc_session_manager()->set_directly_started_for_testing(true); - - GetPrefs()->SetManagedPref(prefs::kArcEnabled, - std::make_unique<base::Value>(true)); - boot_phase_monitor_bridge()->OnArcPlayStoreEnabledChanged(true); - - boot_phase_monitor_bridge()->OnBootCompleted(); - boot_phase_monitor_bridge()->OnExtensionsReadyForTesting(); - EXPECT_EQ(0U, disable_cpu_restriction_counter()); -} - } // namespace } // namespace arc
diff --git a/chrome/browser/chromeos/arc/boot_phase_monitor/arc_instance_throttle.cc b/chrome/browser/chromeos/arc/boot_phase_monitor/arc_instance_throttle.cc index a37bd37..f842a1f7 100644 --- a/chrome/browser/chromeos/arc/boot_phase_monitor/arc_instance_throttle.cc +++ b/chrome/browser/chromeos/arc/boot_phase_monitor/arc_instance_throttle.cc
@@ -7,9 +7,22 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/shell.h" #include "ash/wm/window_util.h" +#include "base/logging.h" +#include "base/memory/singleton.h" +#include "base/metrics/single_sample_metrics.h" +#include "base/one_shot_event.h" +#include "chrome/browser/chromeos/arc/arc_session_manager.h" +#include "chrome/browser/chromeos/arc/arc_util.h" +#include "chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/sessions/session_restore.h" +#include "components/arc/arc_browser_context_keyed_service_factory_base.h" #include "components/arc/arc_util.h" +#include "components/arc/session/arc_stop_reason.h" +#include "extensions/browser/extension_system.h" +#include "extensions/browser/extension_system_provider.h" +#include "extensions/browser/extensions_browser_client.h" #include "ui/wm/public/activation_client.h" - namespace arc { namespace { @@ -24,23 +37,85 @@ parent->id() == ash::ShellWindowId::kShellWindowId_AppListContainer; } -void ThrottleInstance(const aura::Window* active) { - SetArcCpuRestriction(!IsArcAppWindow(active)); -} +class DefaultDelegateImpl : public ArcInstanceThrottle::Delegate { + public: + DefaultDelegateImpl() = default; + ~DefaultDelegateImpl() override = default; + void SetCpuRestriction(bool restrict) override { + SetArcCpuRestriction(restrict); + } + + private: + DISALLOW_COPY_AND_ASSIGN(DefaultDelegateImpl); +}; + +// Singleton factory for ArcInstanceThrottle. +class ArcInstanceThrottleFactory + : public internal::ArcBrowserContextKeyedServiceFactoryBase< + ArcInstanceThrottle, + ArcInstanceThrottleFactory> { + public: + static constexpr const char* kName = "ArcInstanceThrottleFactory"; + static ArcInstanceThrottleFactory* GetInstance() { + return base::Singleton<ArcInstanceThrottleFactory>::get(); + } + + private: + friend struct base::DefaultSingletonTraits<ArcInstanceThrottleFactory>; + ArcInstanceThrottleFactory() { + DependsOn(extensions::ExtensionsBrowserClient::Get() + ->GetExtensionSystemFactory()); + DependsOn(ArcBootPhaseMonitorBridgeFactory::GetInstance()); + } + ~ArcInstanceThrottleFactory() override = default; +}; } // namespace -ArcInstanceThrottle::ArcInstanceThrottle() { - if (!ash::Shell::HasInstance()) // for unit testing. - return; - ash::Shell::Get()->activation_client()->AddObserver(this); - ThrottleInstance(ash::window_util::GetActiveWindow()); +// static +ArcInstanceThrottle* ArcInstanceThrottle::GetForBrowserContext( + content::BrowserContext* context) { + return ArcInstanceThrottleFactory::GetForBrowserContext(context); } -ArcInstanceThrottle::~ArcInstanceThrottle() { - if (!ash::Shell::HasInstance()) - return; - ash::Shell::Get()->activation_client()->RemoveObserver(this); +// static +ArcInstanceThrottle* ArcInstanceThrottle::GetForBrowserContextForTesting( + content::BrowserContext* context) { + return ArcInstanceThrottleFactory::GetForBrowserContextForTesting(context); +} + +ArcInstanceThrottle::ArcInstanceThrottle(content::BrowserContext* context, + ArcBridgeService* arc_bridge_service) + : context_(context), + delegate_for_testing_(std::make_unique<DefaultDelegateImpl>()), + weak_ptr_factory_(this) { + auto* arc_session_manager = ArcSessionManager::Get(); + DCHECK(arc_session_manager); + arc_session_manager->AddObserver(this); + SessionRestore::AddObserver(this); + auto* boot_phase_monitor = + ArcBootPhaseMonitorBridge::GetForBrowserContext(context_); + if (boot_phase_monitor) // for unit testing. + boot_phase_monitor->AddObserver(this); + + auto* profile = Profile::FromBrowserContext(context); + auto* extension_system = extensions::ExtensionSystem::Get(profile); + DCHECK(extension_system); + extension_system->ready().Post( + FROM_HERE, base::BindOnce(&ArcInstanceThrottle::OnExtensionsReady, + weak_ptr_factory_.GetWeakPtr())); +} + +ArcInstanceThrottle::~ArcInstanceThrottle() {} + +void ArcInstanceThrottle::Shutdown() { + auto* arc_session_manager = ArcSessionManager::Get(); + arc_session_manager->RemoveObserver(this); + SessionRestore::RemoveObserver(this); + auto* boot_phase_monitor = + ArcBootPhaseMonitorBridge::GetForBrowserContext(context_); + if (boot_phase_monitor) // for unit testing. + boot_phase_monitor->RemoveObserver(this); } void ArcInstanceThrottle::OnWindowActivated(ActivationReason reason, @@ -73,8 +148,91 @@ // app was a native one then the instance was throttled anyway. if (IsAppListWindow(lost_active) || IsAppListWindow(gained_active)) return; - - ThrottleInstance(gained_active); + delegate_for_testing_->SetCpuRestriction(!IsArcAppWindow(gained_active)); } +void ArcInstanceThrottle::StartObservingWindowActivations() { + observing_window_activations_ = true; + if (!ash::Shell::HasInstance()) // for unit testing. + return; + ash::Shell::Get()->activation_client()->AddObserver(this); +} + +void ArcInstanceThrottle::StopObservingWindowActivations() { + observing_window_activations_ = false; + delegate_for_testing_->SetCpuRestriction(false); + if (!ash::Shell::HasInstance()) + return; + ash::Shell::Get()->activation_client()->RemoveObserver(this); + VLOG(1) << "ArcInstanceThrottle has stopped observing and " + "delegate_for_testing_->SetCpuRestriction(false)"; +} + +void ArcInstanceThrottle::OnExtensionsReady() { + VLOG(2) << "All extensions are loaded"; + if (!boot_completed_ && !provisioning_finished_) { + VLOG(1) << "Allowing the instance to use more CPU resources"; + delegate_for_testing_->SetCpuRestriction(false); + } +} + +void ArcInstanceThrottle::OnArcStarted() { + VLOG(1) << "ArcInstanceThrottle " + "delegate_for_testing_->SetCpuRestriction(false) in " + "OnArcStarted()"; + delegate_for_testing_->SetCpuRestriction(false); +} + +// Called after provisioning is finished +void ArcInstanceThrottle::OnArcInitialStart() { + provisioning_finished_ = true; + if (observing_window_activations_) + return; + StartObservingWindowActivations(); + VLOG(1) << "ArcInstanceThrottle started observing in OnArcInitialStart()"; +} + +void ArcInstanceThrottle::OnArcSessionStopped(ArcStopReason stop_reason) { + // Stop observing so that the window observer won't interfere with the + // container startup when the user opts in to ARC. Will remove once we have + // locks to cover container stopping/restarting. + if (!observing_window_activations_) + return; + StopObservingWindowActivations(); + VLOG(1) << "ArcInstanceThrottle stopped observing in OnArcSessionStopped()"; +} + +void ArcInstanceThrottle::OnArcSessionRestarting() { + // Stop observing so that the window observer won't interfere with the + // container restart. + if (!observing_window_activations_) + return; + StopObservingWindowActivations(); + VLOG(1) + << "ArcInstanceThrottle stopped observing in OnArcSessionRestarting()"; +} + +void ArcInstanceThrottle::OnArcPlayStoreEnabledChanged(bool enabled) { + if (enabled) + delegate_for_testing_->SetCpuRestriction(false); +} + +void ArcInstanceThrottle::OnSessionRestoreFinishedLoadingTabs() { + VLOG(1) << "All tabs have been restored"; + // If OnArcInitialStart() or OnBootCompleted haven't been called, relax the + // restriction to let the instance fully start. + if (!boot_completed_ && !provisioning_finished_) { + VLOG(1) << "Allowing the instance to use more CPU resources"; + delegate_for_testing_->SetCpuRestriction(false); + } +} + +// Called after boot is completed. +void ArcInstanceThrottle::OnBootCompleted() { + boot_completed_ = true; + if (observing_window_activations_) + return; + StartObservingWindowActivations(); + VLOG(1) << "ArcInstanceThrottle started observing in OnBootCompleted()"; +} } // namespace arc
diff --git a/chrome/browser/chromeos/arc/boot_phase_monitor/arc_instance_throttle.h b/chrome/browser/chromeos/arc/boot_phase_monitor/arc_instance_throttle.h index 7ab5b167..a264c93 100644 --- a/chrome/browser/chromeos/arc/boot_phase_monitor/arc_instance_throttle.h +++ b/chrome/browser/chromeos/arc/boot_phase_monitor/arc_instance_throttle.h
@@ -5,25 +5,91 @@ #ifndef CHROME_BROWSER_CHROMEOS_ARC_BOOT_PHASE_MONITOR_ARC_INSTANCE_THROTTLE_H_ #define CHROME_BROWSER_CHROMEOS_ARC_BOOT_PHASE_MONITOR_ARC_INSTANCE_THROTTLE_H_ +#include <memory> + #include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "chrome/browser/chromeos/arc/arc_session_manager.h" +#include "chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h" +#include "chrome/browser/sessions/session_restore_observer.h" +#include "components/keyed_service/core/keyed_service.h" +#include "content/public/browser/browser_context.h" #include "ui/wm/public/activation_change_observer.h" namespace arc { // A class that watches window activations and prioritizes the ARC instance when // one of ARC windows is activated. The class also unprioritizes the instance -// when non-ARC window such as Chrome is activated. -class ArcInstanceThrottle : public wm::ActivationChangeObserver { +// when non-ARC window such as Chrome is activated. Additionally, the class +// prioritizes/unprioritizes in response to ARC boot events from +// ArcSessionManager. +class ArcInstanceThrottle : public KeyedService, + public wm::ActivationChangeObserver, + public ArcSessionManager::Observer, + public SessionRestoreObserver, + public ArcBootPhaseMonitorBridge::Observer { public: - ArcInstanceThrottle(); + // Delegate for testing + class Delegate { + public: + virtual ~Delegate() = default; + virtual void SetCpuRestriction(bool) = 0; + }; + // Returns singleton instance for the given BrowserContext, or nullptr if the + // browser |context| is not allowed to use ARC. + static ArcInstanceThrottle* GetForBrowserContext( + content::BrowserContext* context); + static ArcInstanceThrottle* GetForBrowserContextForTesting( + content::BrowserContext* context); + + ArcInstanceThrottle(content::BrowserContext* context, + ArcBridgeService* arc_bridge_service); ~ArcInstanceThrottle() override; + // KeyedService override + void Shutdown() override; + + // All of these observers will be refactored into locks. // wm::ActivationChangeObserver overrides: void OnWindowActivated(ActivationReason reason, aura::Window* gained_active, aura::Window* lost_active) override; + // ArcSessionManager::Observer overrides + void OnArcPlayStoreEnabledChanged(bool enabled) override; + void OnArcStarted() override; + void OnArcInitialStart() override; + void OnArcSessionStopped(ArcStopReason stop_reason) override; + void OnArcSessionRestarting() override; + + // SessionRestoreObserver + void OnSessionRestoreFinishedLoadingTabs() override; + + // ArcBootPhaseMonitorBridge::Observer + void OnBootCompleted() override; + + void SetDelegateForTesting(std::unique_ptr<Delegate> delegate) { + delegate_for_testing_ = std::move(delegate); + } + void OnExtensionsReadyForTesting() { OnExtensionsReady(); } + bool observing_window_activations() const { + return observing_window_activations_; + } private: + void StartObservingWindowActivations(); + void StopObservingWindowActivations(); + // Called when ExtensionsServices finishes loading all extensions for the + // profile. + void OnExtensionsReady(); + + content::BrowserContext* context_; + std::unique_ptr<Delegate> delegate_for_testing_; + bool observing_window_activations_ = false; + bool provisioning_finished_ = false; + bool boot_completed_ = false; + + base::WeakPtrFactory<ArcInstanceThrottle> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(ArcInstanceThrottle); };
diff --git a/chrome/browser/chromeos/arc/boot_phase_monitor/arc_instance_throttle_unittest.cc b/chrome/browser/chromeos/arc/boot_phase_monitor/arc_instance_throttle_unittest.cc new file mode 100644 index 0000000..0a450d5 --- /dev/null +++ b/chrome/browser/chromeos/arc/boot_phase_monitor/arc_instance_throttle_unittest.cc
@@ -0,0 +1,193 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/arc/boot_phase_monitor/arc_instance_throttle.h" + +#include <memory> + +#include "ash/public/cpp/app_types.h" +#include "base/bind.h" +#include "base/command_line.h" +#include "base/test/scoped_task_environment.h" +#include "chrome/browser/chromeos/arc/arc_session_manager.h" +#include "chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h" +#include "chrome/test/base/testing_profile.h" +#include "components/arc/arc_prefs.h" +#include "components/arc/arc_service_manager.h" +#include "components/arc/arc_util.h" +#include "components/arc/session/arc_stop_reason.h" +#include "components/arc/test/fake_arc_session.h" +#include "components/keyed_service/core/keyed_service.h" +#include "components/keyed_service/core/keyed_service_factory.h" +#include "components/sync_preferences/testing_pref_service_syncable.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/aura/client/aura_constants.h" +#include "ui/aura/test/test_windows.h" +#include "ui/wm/public/activation_change_observer.h" + +namespace arc { +namespace { + +class ArcInstanceThrottleTest : public testing::Test { + public: + ArcInstanceThrottleTest() + : arc_service_manager_(std::make_unique<ArcServiceManager>()), + arc_session_manager_(std::make_unique<ArcSessionManager>( + std::make_unique<ArcSessionRunner>( + base::BindRepeating(FakeArcSession::Create)))), + testing_profile_(std::make_unique<TestingProfile>()), + disable_cpu_restriction_counter_(0), + enable_cpu_restriction_counter_(0) { + SetArcAvailableCommandLineForTesting( + base::CommandLine::ForCurrentProcess()); + + ArcBootPhaseMonitorBridgeFactory::GetInstance()->SetTestingFactoryAndUse( + testing_profile_.get(), + base::BindRepeating([](content::BrowserContext* context) + -> std::unique_ptr<KeyedService> { + return std::unique_ptr<KeyedService>(); + })); + arc_instance_throttle_ = + ArcInstanceThrottle::GetForBrowserContextForTesting( + testing_profile_.get()); + arc_instance_throttle_->SetDelegateForTesting( + std::make_unique<TestDelegateImpl>(this)); + } + ~ArcInstanceThrottleTest() override { arc_instance_throttle_->Shutdown(); } + + protected: + ArcInstanceThrottle* arc_instance_throttle() const { + return arc_instance_throttle_; + } + + size_t disable_cpu_restriction_counter() const { + return disable_cpu_restriction_counter_; + } + + size_t enable_cpu_restriction_counter() const { + return enable_cpu_restriction_counter_; + } + + sync_preferences::TestingPrefServiceSyncable* GetPrefs() const { + return testing_profile_->GetTestingPrefService(); + } + + private: + class TestDelegateImpl : public ArcInstanceThrottle::Delegate { + public: + explicit TestDelegateImpl(ArcInstanceThrottleTest* test) : test_(test) {} + ~TestDelegateImpl() override = default; + void SetCpuRestriction(bool restrict) override { + if (!restrict) + ++(test_->disable_cpu_restriction_counter_); + else + ++(test_->enable_cpu_restriction_counter_); + } + + private: + ArcInstanceThrottleTest* test_; + DISALLOW_COPY_AND_ASSIGN(TestDelegateImpl); + }; + content::TestBrowserThreadBundle thread_bundle_; + std::unique_ptr<ArcServiceManager> arc_service_manager_; + std::unique_ptr<ArcSessionManager> arc_session_manager_; + std::unique_ptr<TestingProfile> testing_profile_; + ArcInstanceThrottle* arc_instance_throttle_; + size_t disable_cpu_restriction_counter_; + size_t enable_cpu_restriction_counter_; + + DISALLOW_COPY_AND_ASSIGN(ArcInstanceThrottleTest); +}; + +// Tests that ArcInstanceThrottle starts/stop observing windows when it receives +// notification that the container has started/stopped. +TEST_F(ArcInstanceThrottleTest, TestOnBootCompleted) { + arc_instance_throttle()->OnArcStarted(); + EXPECT_FALSE(arc_instance_throttle()->observing_window_activations()); + arc_instance_throttle()->OnArcInitialStart(); + EXPECT_TRUE(arc_instance_throttle()->observing_window_activations()); + arc_instance_throttle()->OnArcSessionStopped(ArcStopReason::SHUTDOWN); + EXPECT_FALSE(arc_instance_throttle()->observing_window_activations()); + arc_instance_throttle()->OnBootCompleted(); + EXPECT_TRUE(arc_instance_throttle()->observing_window_activations()); + arc_instance_throttle()->OnArcSessionRestarting(); + EXPECT_FALSE(arc_instance_throttle()->observing_window_activations()); +} + +// Tests that container is unthrottled on OnArcStarted, +// OnArcPlayStoreEnabledChanged, OnArcSessionStopped, and OnArcSessionRestarting +TEST_F(ArcInstanceThrottleTest, TestOnArcStarted) { + EXPECT_EQ(0U, disable_cpu_restriction_counter()); + arc_instance_throttle()->OnArcStarted(); + EXPECT_EQ(1U, disable_cpu_restriction_counter()); + + arc_instance_throttle()->OnArcPlayStoreEnabledChanged(true); + EXPECT_EQ(2U, disable_cpu_restriction_counter()); + + arc_instance_throttle()->OnArcInitialStart(); + arc_instance_throttle()->OnArcSessionStopped(ArcStopReason::SHUTDOWN); + EXPECT_EQ(3U, disable_cpu_restriction_counter()); + + arc_instance_throttle()->OnBootCompleted(); + arc_instance_throttle()->OnArcSessionRestarting(); + EXPECT_EQ(4U, disable_cpu_restriction_counter()); +} + +// Tests that CPU restriction is disabled when tab restoration is done. +TEST_F(ArcInstanceThrottleTest, TestOnSessionRestoreFinishedLoadingTabs) { + EXPECT_EQ(0U, disable_cpu_restriction_counter()); + arc_instance_throttle()->OnSessionRestoreFinishedLoadingTabs(); + EXPECT_EQ(1U, disable_cpu_restriction_counter()); +} + +// Tests that nothing happens if tab restoration is done after ARC boot. +TEST_F(ArcInstanceThrottleTest, + TestOnSessionRestoreFinishedLoadingTabs_BootFirst) { + // OnSessionRestoreFinishedLoadingTabs() should be no-op when the + // instance has already fully started. + arc_instance_throttle()->OnBootCompleted(); + EXPECT_EQ(0U, disable_cpu_restriction_counter()); + arc_instance_throttle()->OnSessionRestoreFinishedLoadingTabs(); + EXPECT_EQ(0U, disable_cpu_restriction_counter()); +} + +// Tests that OnExtensionsReady() disables throttling iff instance boot is not +// completed yet. +TEST_F(ArcInstanceThrottleTest, TestOnExtensionsReady) { + arc_instance_throttle()->OnExtensionsReadyForTesting(); + EXPECT_EQ(1U, disable_cpu_restriction_counter()); + arc_instance_throttle()->OnBootCompleted(); + arc_instance_throttle()->OnExtensionsReadyForTesting(); + EXPECT_EQ(1U, disable_cpu_restriction_counter()); +} + +// Tests that CPU restriction is disabled when ARC window is in focus, +// and enabled when ARC window is unfocused. +TEST_F(ArcInstanceThrottleTest, TestOnWindowActivated) { + aura::test::TestWindowDelegate dummy_delegate; + aura::Window* arc_window = aura::test::CreateTestWindowWithDelegate( + &dummy_delegate, 1, gfx::Rect(), nullptr); + aura::Window* chrome_window = aura::test::CreateTestWindowWithDelegate( + &dummy_delegate, 2, gfx::Rect(), nullptr); + arc_window->SetProperty(aura::client::kAppType, + static_cast<int>(ash::AppType::ARC_APP)); + chrome_window->SetProperty(aura::client::kAppType, + static_cast<int>(ash::AppType::BROWSER)); + + EXPECT_EQ(0U, disable_cpu_restriction_counter()); + EXPECT_EQ(0U, enable_cpu_restriction_counter()); + arc_instance_throttle()->OnWindowActivated( + ArcInstanceThrottle::ActivationReason::INPUT_EVENT, arc_window, + chrome_window); + EXPECT_EQ(1U, disable_cpu_restriction_counter()); + arc_instance_throttle()->OnWindowActivated( + ArcInstanceThrottle::ActivationReason::INPUT_EVENT, chrome_window, + arc_window); + EXPECT_EQ(1U, disable_cpu_restriction_counter()); + EXPECT_EQ(1U, enable_cpu_restriction_counter()); +} + +} // namespace +} // namespace arc
diff --git a/chrome/browser/chromeos/cryptauth/client_app_metadata_provider_service.cc b/chrome/browser/chromeos/cryptauth/client_app_metadata_provider_service.cc index 58d455b..1648190 100644 --- a/chrome/browser/chromeos/cryptauth/client_app_metadata_provider_service.cc +++ b/chrome/browser/chromeos/cryptauth/client_app_metadata_provider_service.cc
@@ -208,7 +208,7 @@ DCHECK(!instance_id.empty()); instance_id_->GetToken( device_sync:: - kCryptAuthGcmInstanceIdAuthorizedEntity /* authorized_entity */, + kCryptAuthV2EnrollmentAuthorizedEntity /* authorized_entity */, kInstanceIdScope /* scope */, std::map<std::string, std::string>() /* options */, {} /* flags */, base::Bind(&ClientAppMetadataProviderService::OnInstanceIdTokenFetched,
diff --git a/chrome/browser/chromeos/extensions/default_app_order.cc b/chrome/browser/chromeos/extensions/default_app_order.cc index cf54b2d2..d118f17a 100644 --- a/chrome/browser/chromeos/extensions/default_app_order.cc +++ b/chrome/browser/chromeos/extensions/default_app_order.cc
@@ -72,12 +72,13 @@ default_web_apps::kCanvasAppId, extension_misc::kTextEditorAppId, default_web_apps::kYoutubeTVAppId, + default_web_apps::kGoogleNewsAppId, + extensions::kWebStoreAppId, arc::kLightRoom, arc::kInfinitePainter, default_web_apps::kShowtimeAppId, extension_misc::kGooglePlusAppId, extension_misc::kChromeRemoteDesktopAppId, - extensions::kWebStoreAppId, }; // Reads external ordinal json file and returned the parsed value. Returns NULL
diff --git a/chrome/browser/chromeos/extensions/default_web_app_ids.h b/chrome/browser/chromeos/extensions/default_web_app_ids.h index bd27caa..7ee5270 100644 --- a/chrome/browser/chromeos/extensions/default_web_app_ids.h +++ b/chrome/browser/chromeos/extensions/default_web_app_ids.h
@@ -30,6 +30,10 @@ // Generated as web_app::GenerateAppIdFromURL(GURL("chrome://os-settings/")). constexpr char kOsSettingsAppId[] = "odknhmnlageboeamepcngndbggdpaobj"; +// Generated as +// web_app::GenerateAppIdFromURL(GURL("https://news.google.com/?lfhs=2")). +constexpr char kGoogleNewsAppId[] = "kfgapjallbhpciobgmlhlhokknljkgho"; + } // namespace default_web_apps } // namespace chromeos
diff --git a/chrome/browser/chromeos/printing/printers_sync_bridge.cc b/chrome/browser/chromeos/printing/printers_sync_bridge.cc index 0987f91..a7b5a463 100644 --- a/chrome/browser/chromeos/printing/printers_sync_bridge.cc +++ b/chrome/browser/chromeos/printing/printers_sync_bridge.cc
@@ -8,6 +8,7 @@ #include <utility> #include "base/bind.h" +#include "base/metrics/histogram_functions.h" #include "base/stl_util.h" #include "base/task/post_task.h" #include "chrome/browser/chromeos/printing/specifics_translation.h" @@ -41,6 +42,31 @@ return entity_data; } +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class MakeAndModelMigrationState { + kNotMigrated = 0, + kMigrated = 1, + kMaxValue = kMigrated, +}; + +// Computes the make_and_model field for old |specifics| where it is missing. +// Returns true if an update was made. make_and_model is computed from the +// manufacturer and model strings. +bool MigrateMakeAndModel(sync_pb::PrinterSpecifics* specifics) { + if (specifics->has_make_and_model()) { + base::UmaHistogramEnumeration("Printing.CUPS.MigratedMakeAndModel", + MakeAndModelMigrationState::kNotMigrated); + return false; + } + + specifics->set_make_and_model( + chromeos::MakeAndModel(specifics->manufacturer(), specifics->model())); + base::UmaHistogramEnumeration("Printing.CUPS.MigratedMakeAndModel", + MakeAndModelMigrationState::kMigrated); + return true; +} + } // namespace // Delegate class which helps to manage the ModelTypeStore. @@ -188,7 +214,11 @@ // appropriate metadata. for (const auto& entry : all_data_) { const std::string& local_entity_id = entry.first; - if (!base::Contains(sync_entity_ids, local_entity_id)) { + + // TODO(crbug.com/737809): Remove when all data is expected to have been + // migrated. + bool migrated = MigrateMakeAndModel(entry.second.get()); + if (!base::Contains(sync_entity_ids, local_entity_id) || migrated) { // Only local objects which were not updated are uploaded. Objects for // which there was a remote copy are overwritten. change_processor()->Put(local_entity_id,
diff --git a/chrome/browser/chromeos/printing/specifics_translation.cc b/chrome/browser/chromeos/printing/specifics_translation.cc index f0bffc6..640b4b76 100644 --- a/chrome/browser/chromeos/printing/specifics_translation.cc +++ b/chrome/browser/chromeos/printing/specifics_translation.cc
@@ -48,14 +48,6 @@ } } -// Combines |make| and |model| with a space to generate a make and model string. -// If |model| already represents the make and model, the string is just |model|. -// This is to prevent strings of the form '<make> <make> <model>'. -std::string MakeAndModel(base::StringPiece make, base::StringPiece model) { - return model.starts_with(make) ? model.as_string() - : base::JoinString({make, model}, " "); -} - } // namespace std::unique_ptr<Printer> SpecificsToPrinter( @@ -121,4 +113,9 @@ printer.ppd_reference()); } +std::string MakeAndModel(base::StringPiece make, base::StringPiece model) { + return model.starts_with(make) ? model.as_string() + : base::JoinString({make, model}, " "); +} + } // namespace chromeos
diff --git a/chrome/browser/chromeos/printing/specifics_translation.h b/chrome/browser/chromeos/printing/specifics_translation.h index 6f8a129..a19722ac 100644 --- a/chrome/browser/chromeos/printing/specifics_translation.h +++ b/chrome/browser/chromeos/printing/specifics_translation.h
@@ -7,6 +7,7 @@ #include <memory> +#include "base/strings/string_piece.h" #include "components/sync/protocol/printer_specifics.pb.h" namespace chromeos { @@ -31,6 +32,11 @@ void MergePrinterToSpecifics(const Printer& printer, sync_pb::PrinterSpecifics* specifics); +// Combines |make| and |model| with a space to generate a make and model string. +// If |model| already represents the make and model, the string is just |model|. +// This is to prevent strings of the form '<make> <make> <model>'. +std::string MakeAndModel(base::StringPiece make, base::StringPiece model); + } // namespace chromeos #endif // CHROME_BROWSER_CHROMEOS_PRINTING_SPECIFICS_TRANSLATION_H_
diff --git a/chrome/browser/content_index/content_index_browsertest.cc b/chrome/browser/content_index/content_index_browsertest.cc index 447f032..e21ce82 100644 --- a/chrome/browser/content_index/content_index_browsertest.cc +++ b/chrome/browser/content_index/content_index_browsertest.cc
@@ -20,8 +20,10 @@ #include "chrome/test/base/ui_test_utils.h" #include "components/offline_items_collection/core/offline_content_provider.h" #include "components/offline_items_collection/core/offline_item.h" +#include "components/ukm/test_ukm_recorder.h" #include "content/public/common/content_switches.h" #include "net/test/embedded_test_server/embedded_test_server.h" +#include "services/metrics/public/cpp/ukm_builders.h" #include "testing/gmock/include/gmock/gmock.h" #include "third_party/blink/public/common/service_worker/service_worker_status_code.h" #include "third_party/re2/src/re2/re2.h" @@ -267,7 +269,7 @@ EXPECT_TRUE(GetAllItems().empty()); } -IN_PROC_BROWSER_TEST_F(ContentIndexTest, UmaCollected) { +IN_PROC_BROWSER_TEST_F(ContentIndexTest, MetricsCollected) { // Inititally there is no content. { base::HistogramTester histogram_tester; @@ -279,12 +281,20 @@ // Record that two articles were added. { base::HistogramTester histogram_tester; + ukm::TestAutoSetUkmRecorder ukm_recorder; + RunScript("AddContent('my-id-1')"); RunScript("AddContent('my-id-2')"); base::RunLoop() .RunUntilIdle(); // Wait for the provider to get the content. histogram_tester.ExpectBucketCount( "ContentIndex.ContentAdded", blink::mojom::ContentCategory::ARTICLE, 2); + + EXPECT_EQ( + ukm_recorder + .GetEntriesByName(ukm::builders::ContentIndex_Added::kEntryName) + .size(), + 2u); } // Querying the items should record that there are 2 entries available. @@ -298,6 +308,8 @@ // User deletion will dispatch an event. { base::HistogramTester histogram_tester; + ukm::TestAutoSetUkmRecorder ukm_recorder; + provider()->RemoveItem(offline_items().at("my-id-1").id); EXPECT_EQ(RunScript("waitForMessageFromServiceWorker()"), "my-id-1"); base::RunLoop().RunUntilIdle(); @@ -309,11 +321,18 @@ histogram_tester.ExpectBucketCount( "ContentIndex.ContentDeleteEvent.Dispatch", blink::ServiceWorkerStatusCode::kOk, 1); + EXPECT_EQ(ukm_recorder + .GetEntriesByName( + ukm::builders::ContentIndex_DeletedByUser::kEntryName) + .size(), + 1u); } // Opening an article is recorded. { base::HistogramTester histogram_tester; + ukm::TestAutoSetUkmRecorder ukm_recorder; + provider()->OpenItem( offline_items_collection::LaunchLocation::DOWNLOAD_HOME, offline_items().at("my-id-2").id); @@ -326,6 +345,12 @@ histogram_tester.ExpectBucketCount("ContentIndex.ContentOpened", blink::mojom::ContentCategory::ARTICLE, 1); + + EXPECT_EQ( + ukm_recorder + .GetEntriesByName(ukm::builders::ContentIndex_Opened::kEntryName) + .size(), + 1u); } }
diff --git a/chrome/browser/content_index/content_index_metrics.cc b/chrome/browser/content_index/content_index_metrics.cc index 2b004a2..0835064e 100644 --- a/chrome/browser/content_index/content_index_metrics.cc +++ b/chrome/browser/content_index/content_index_metrics.cc
@@ -5,19 +5,70 @@ #include "chrome/browser/content_index/content_index_metrics.h" #include "base/metrics/histogram_functions.h" +#include "chrome/browser/metrics/ukm_background_recorder_service.h" +#include "content/public/browser/web_contents.h" +#include "net/base/network_change_notifier.h" +#include "services/metrics/public/cpp/ukm_builders.h" +#include "services/metrics/public/cpp/ukm_recorder.h" -namespace content_index { +namespace { -void RecordContentAdded(blink::mojom::ContentCategory category) { +void MaybeRecordUkmContentAdded(blink::mojom::ContentCategory category, + base::Optional<ukm::SourceId> source_id) { + if (!source_id) + return; + + ukm::builders::ContentIndex_Added(*source_id) + .SetCategory(static_cast<int>(category)) + .Record(ukm::UkmRecorder::Get()); +} + +void MaybeRecordUkmContentDeletedByUser( + base::Optional<ukm::SourceId> source_id) { + if (!source_id) + return; + + ukm::builders::ContentIndex_DeletedByUser(*source_id) + .SetDeleted(true) + .Record(ukm::UkmRecorder::Get()); +} + +} // namespace + +ContentIndexMetrics::ContentIndexMetrics( + ukm::UkmBackgroundRecorderService* ukm_background_service) + : ukm_background_service_(ukm_background_service) { + DCHECK(ukm_background_service_); +} + +ContentIndexMetrics::~ContentIndexMetrics() = default; + +void ContentIndexMetrics::RecordContentAdded( + const url::Origin& origin, + blink::mojom::ContentCategory category) { base::UmaHistogramEnumeration("ContentIndex.ContentAdded", category); + + ukm_background_service_->GetBackgroundSourceIdIfAllowed( + origin, base::BindOnce(&MaybeRecordUkmContentAdded, category)); } -void RecordContentOpened(blink::mojom::ContentCategory category) { +void ContentIndexMetrics::RecordContentOpened( + content::WebContents* web_contents, + blink::mojom::ContentCategory category) { base::UmaHistogramEnumeration("ContentIndex.ContentOpened", category); + + ukm::builders::ContentIndex_Opened(web_contents->GetLastCommittedSourceId()) + .SetIsOffline(net::NetworkChangeNotifier::IsOffline()) + .Record(ukm::UkmRecorder::Get()); } -void RecordContentIndexEntries(size_t num_entries) { +void ContentIndexMetrics::RecordContentDeletedByUser( + const url::Origin& origin) { + ukm_background_service_->GetBackgroundSourceIdIfAllowed( + origin, base::BindOnce(&MaybeRecordUkmContentDeletedByUser)); +} + +// static +void ContentIndexMetrics::RecordContentIndexEntries(size_t num_entries) { base::UmaHistogramCounts1000("ContentIndex.NumEntriesAvailable", num_entries); } - -} // namespace content_index
diff --git a/chrome/browser/content_index/content_index_metrics.h b/chrome/browser/content_index/content_index_metrics.h index c517ce4..8561b98 100644 --- a/chrome/browser/content_index/content_index_metrics.h +++ b/chrome/browser/content_index/content_index_metrics.h
@@ -5,19 +5,45 @@ #ifndef CHROME_BROWSER_CONTENT_INDEX_CONTENT_INDEX_METRICS_H_ #define CHROME_BROWSER_CONTENT_INDEX_CONTENT_INDEX_METRICS_H_ +#include "base/macros.h" #include "third_party/blink/public/mojom/content_index/content_index.mojom.h" -namespace content_index { +namespace content { +class WebContents; +} // namespace content -// Records the category of the Content Index entry after registration. -void RecordContentAdded(blink::mojom::ContentCategory category); +namespace ukm { +class UkmBackgroundRecorderService; +} // namespace ukm -// Records the category of the Content Index entry when a user opens it. -void RecordContentOpened(blink::mojom::ContentCategory category); +namespace url { +class Origin; +} // namespace url -// Records the number of Content Index entries available when requested. -void RecordContentIndexEntries(size_t num_entries); +class ContentIndexMetrics { + public: + explicit ContentIndexMetrics( + ukm::UkmBackgroundRecorderService* ukm_background_service); + ~ContentIndexMetrics(); -} // namespace content_index + // Records the category of the Content Index entry after registration. + void RecordContentAdded(const url::Origin& origin, + blink::mojom::ContentCategory category); + + // Records the category of the Content Index entry when a user opens it. + void RecordContentOpened(content::WebContents* web_contents, + blink::mojom::ContentCategory category); + + // Records when a Content UIndex entry is deleted by a user. + void RecordContentDeletedByUser(const url::Origin& origin); + + // Records the number of Content Index entries available when requested. + static void RecordContentIndexEntries(size_t num_entries); + + private: + ukm::UkmBackgroundRecorderService* ukm_background_service_; + + DISALLOW_COPY_AND_ASSIGN(ContentIndexMetrics); +}; #endif // CHROME_BROWSER_CONTENT_INDEX_CONTENT_INDEX_METRICS_H_
diff --git a/chrome/browser/content_index/content_index_provider_factory.cc b/chrome/browser/content_index/content_index_provider_factory.cc index 5ca42fc..fd08abd 100644 --- a/chrome/browser/content_index/content_index_provider_factory.cc +++ b/chrome/browser/content_index/content_index_provider_factory.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/content_index/content_index_provider_factory.h" #include "chrome/browser/content_index/content_index_provider_impl.h" +#include "chrome/browser/metrics/ukm_background_recorder_service.h" #include "chrome/browser/offline_items_collection/offline_content_aggregator_factory.h" #include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/profile.h" @@ -27,6 +28,7 @@ "ContentIndexProvider", BrowserContextDependencyManager::GetInstance()) { DependsOn(OfflineContentAggregatorFactory::GetInstance()); + DependsOn(ukm::UkmBackgroundRecorderFactory::GetInstance()); } ContentIndexProviderFactory::~ContentIndexProviderFactory() = default;
diff --git a/chrome/browser/content_index/content_index_provider_impl.cc b/chrome/browser/content_index/content_index_provider_impl.cc index 5b0e5fc..edc58bd5 100644 --- a/chrome/browser/content_index/content_index_provider_impl.cc +++ b/chrome/browser/content_index/content_index_provider_impl.cc
@@ -11,7 +11,7 @@ #include "base/strings/string_split.h" #include "base/task/post_task.h" #include "build/build_config.h" -#include "chrome/browser/content_index/content_index_metrics.h" +#include "chrome/browser/metrics/ukm_background_recorder_service.h" #include "chrome/browser/offline_items_collection/offline_content_aggregator_factory.h" #include "chrome/browser/profiles/profile.h" #include "components/offline_items_collection/core/offline_content_aggregator.h" @@ -129,7 +129,7 @@ void DidGetAllEntriesAcrossStorageParitions( std::unique_ptr<ContentIndexProviderImpl::OfflineItemList> item_list, ContentIndexProviderImpl::MultipleItemCallback callback) { - content_index::RecordContentIndexEntries(item_list->size()); + ContentIndexMetrics::RecordContentIndexEntries(item_list->size()); std::move(callback).Run(*item_list); } @@ -137,8 +137,9 @@ ContentIndexProviderImpl::ContentIndexProviderImpl(Profile* profile) : profile_(profile), - aggregator_(OfflineContentAggregatorFactory::GetForKey( - profile_->GetProfileKey())), + metrics_(ukm::UkmBackgroundRecorderFactory::GetForProfile(profile)), + aggregator_( + OfflineContentAggregatorFactory::GetForKey(profile->GetProfileKey())), weak_ptr_factory_(this) { aggregator_->RegisterProvider(kProviderNamespace, this); } @@ -166,7 +167,8 @@ for (auto& observer : observers_) observer.OnItemsAdded(items); - content_index::RecordContentAdded(entry.description->category); + metrics_.RecordContentAdded(url::Origin::Create(entry.launch_url.GetOrigin()), + entry.description->category); } void ContentIndexProviderImpl::OnContentDeleted( @@ -208,15 +210,21 @@ WindowOpenDisposition::NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_LINK, /* is_renderer_initiated= */ false); - ServiceTabLauncher::GetInstance()->LaunchTab(profile_, params, - base::DoNothing()); + ServiceTabLauncher::GetInstance()->LaunchTab( + profile_, params, + base::BindOnce(&ContentIndexProviderImpl::DidOpenTab, + weak_ptr_factory_.GetWeakPtr(), std::move(*entry))); #else NavigateParams nav_params(profile_, entry->launch_url, ui::PAGE_TRANSITION_LINK); Navigate(&nav_params); + DidOpenTab(std::move(*entry), nav_params.navigated_or_inserted_contents); #endif +} - content_index::RecordContentOpened(entry->description->category); +void ContentIndexProviderImpl::DidOpenTab(content::ContentIndexEntry entry, + content::WebContents* web_contents) { + metrics_.RecordContentOpened(web_contents, entry.description->category); } void ContentIndexProviderImpl::RemoveItem(const ContentId& id) { @@ -228,6 +236,8 @@ if (!storage_partition || !storage_partition->GetContentIndexContext()) return; + metrics_.RecordContentDeletedByUser(components.origin); + storage_partition->GetContentIndexContext()->OnUserDeletedItem( components.service_worker_registration_id, components.origin, components.description_id);
diff --git a/chrome/browser/content_index/content_index_provider_impl.h b/chrome/browser/content_index/content_index_provider_impl.h index 572e98a..aac2b1ab 100644 --- a/chrome/browser/content_index/content_index_provider_impl.h +++ b/chrome/browser/content_index/content_index_provider_impl.h
@@ -11,11 +11,16 @@ #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/optional.h" +#include "chrome/browser/content_index/content_index_metrics.h" #include "components/keyed_service/core/keyed_service.h" #include "components/offline_items_collection/core/offline_content_provider.h" #include "components/offline_items_collection/core/offline_item.h" #include "content/public/browser/content_index_provider.h" +namespace content { +class WebContents; +} // namespace content + namespace offline_items_collection { class OfflineContentAggregator; } // namespace offline_items_collection @@ -68,8 +73,11 @@ VisualsCallback callback, std::vector<SkBitmap> icons); void DidGetEntryToOpen(base::Optional<content::ContentIndexEntry> entry); + void DidOpenTab(content::ContentIndexEntry entry, + content::WebContents* web_contents); Profile* profile_; + ContentIndexMetrics metrics_; offline_items_collection::OfflineContentAggregator* aggregator_; base::ObserverList<Observer>::Unchecked observers_; base::WeakPtrFactory<ContentIndexProviderImpl> weak_ptr_factory_;
diff --git a/chrome/browser/content_index/content_index_provider_unittest.cc b/chrome/browser/content_index/content_index_provider_unittest.cc index a1c5d0e..2057835 100644 --- a/chrome/browser/content_index/content_index_provider_unittest.cc +++ b/chrome/browser/content_index/content_index_provider_unittest.cc
@@ -37,6 +37,8 @@ public OfflineContentProvider::Observer { public: void SetUp() override { + ASSERT_TRUE(profile_.CreateHistoryService(/* delete_file= */ true, + /* no_db= */ false)); provider_ = std::make_unique<ContentIndexProviderImpl>(&profile_); provider_->AddObserver(this); }
diff --git a/chrome/browser/download/download_request_limiter.cc b/chrome/browser/download/download_request_limiter.cc index 77ac016..5d86a0c 100644 --- a/chrome/browser/download/download_request_limiter.cc +++ b/chrome/browser/download/download_request_limiter.cc
@@ -400,8 +400,8 @@ for (auto& callback : callbacks) { // When callback runs, it can cause the WebContents to be destroyed. - base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(std::move(callback), allow)); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(std::move(callback), allow)); } return throttled;
diff --git a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc index 83b28ca..2c6777cd 100644 --- a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc +++ b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
@@ -941,7 +941,8 @@ rule.condition->url_filter = rule_data.url_filter; rule.condition->resource_types = std::vector<std::string>({"main_frame"}); rule.action->type = rule_data.action_type; - rule.action->redirect_url = rule_data.redirect_url; + rule.action->redirect.emplace(); + rule.action->redirect->url = rule_data.redirect_url; rules.push_back(rule); } @@ -1154,7 +1155,8 @@ // Add |kNumExtensions| each redirecting example.com to a different redirect // url. for (size_t i = 1; i <= kNumExtensions; ++i) { - rule.action->redirect_url = redirect_url_for_extension_number(i); + rule.action->redirect.emplace(); + rule.action->redirect->url = redirect_url_for_extension_number(i); ASSERT_NO_FATAL_FAILURE(LoadExtensionWithRules( {rule}, std::to_string(i), {URLPattern::kAllUrlsPattern})); @@ -1197,7 +1199,6 @@ {"def.com", 4, "block", base::nullopt}, {"def.com", 5, "redirect", get_url_for_host("xyz.com")}, {"ghi*", 6, "redirect", get_url_for_host("ghijk.com")}, - {"ijk*", 7, "redirect", "/manifest.json?q=1#fragment"}, }; // Load the extension. @@ -1209,7 +1210,8 @@ rule.priority = kMinValidPriority; rule.condition->resource_types = std::vector<std::string>({"main_frame"}); rule.action->type = rule_data.action_type; - rule.action->redirect_url = rule_data.redirect_url; + rule.action->redirect.emplace(); + rule.action->redirect->url = rule_data.redirect_url; rules.push_back(rule); } ASSERT_NO_FATAL_FAILURE(LoadExtensionWithRules( @@ -1235,13 +1237,7 @@ // Though ghijk.com still matches the redirect rule for |ghi*|, it will // not redirect to itself. {"ghi.com", true, GURL(get_url_for_host("ghijk.com")), 2}, - // ijklm.com -> chrome-extension://<extension_id>/manifest.json. - // Since this redirects to a manifest.json, don't expect the frame with - // script to load. - {"ijklm.com", false, - GURL("chrome-extension://" + last_loaded_extension_id() + - "/manifest.json?q=1#fragment"), - 2}}; + }; for (const auto& test_case : test_cases) { std::string url = get_url_for_host(test_case.hostname); @@ -1298,7 +1294,8 @@ rule.id = id++; rule.priority = j; rule.action->type = std::string("redirect"); - rule.action->redirect_url = redirect_url_for_priority(j); + rule.action->redirect.emplace(); + rule.action->redirect->url = redirect_url_for_priority(j); rule.condition->url_filter = pattern; rule.condition->resource_types = std::vector<std::string>({"main_frame"}); rules.push_back(rule); @@ -1371,7 +1368,8 @@ rule.priority = rule_data.priority; rule.condition->resource_types = std::vector<std::string>({"main_frame"}); rule.action->type = rule_data.action_type; - rule.action->redirect_url = rule_data.redirect_url; + rule.action->redirect.emplace(); + rule.action->redirect->url = rule_data.redirect_url; rules.push_back(rule); } @@ -2280,7 +2278,8 @@ rule.condition->resource_types = std::vector<std::string>({"script"}); rule.priority = kMinValidPriority; rule.action->type = std::string("redirect"); - rule.action->redirect_url = + rule.action->redirect.emplace(); + rule.action->redirect->url = embedded_test_server()->GetURL("b.com", "/subresources/script.js").spec(); std::vector<std::string> host_permissions = {"*://a.com/", "*://b.com/*"}; @@ -2476,7 +2475,8 @@ std::vector<std::string>({"main_frame"}); redirect_rule.priority = kMinValidPriority; redirect_rule.action->type = std::string("redirect"); - redirect_rule.action->redirect_url = dynamic_redirect_url.spec(); + redirect_rule.action->redirect.emplace(); + redirect_rule.action->redirect->url = dynamic_redirect_url.spec(); redirect_rule.id = kMinValidID + 1; ASSERT_NO_FATAL_FAILURE(AddDynamicRules(last_loaded_extension_id(), @@ -2570,6 +2570,72 @@ test_referrer_blocked(false); } +// Tests rules using the Redirect dictionary. +IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest, Redirect) { + TestRule rule1 = CreateGenericRule(); + rule1.condition->resource_types = std::vector<std::string>({"main_frame"}); + rule1.id = kMinValidID; + rule1.condition->url_filter = std::string("ex"); + rule1.action->type = std::string("redirect"); + rule1.priority = kMinValidPriority; + rule1.action->redirect.emplace(); + rule1.action->redirect->url = + embedded_test_server() + ->GetURL("google.com", "/pages_with_script/index.html") + .spec(); + + TestRule rule2 = CreateGenericRule(); + rule2.condition->resource_types = std::vector<std::string>({"main_frame"}); + rule2.id = kMinValidID + 1; + rule2.condition->url_filter = std::string("example.com"); + rule2.action->type = std::string("redirect"); + rule2.priority = kMinValidPriority + 1; + rule2.action->redirect.emplace(); + rule2.action->redirect->extension_path = "/manifest.json?query#fragment"; + + TestRule rule3 = CreateGenericRule(); + rule3.condition->resource_types = std::vector<std::string>({"main_frame"}); + rule3.id = kMinValidID + 2; + rule3.condition->url_filter = std::string("||example.com"); + rule3.action->type = std::string("redirect"); + rule3.priority = kMinValidPriority + 2; + rule3.action->redirect.emplace(); + rule3.action->redirect->transform.emplace(); + auto& transform = rule3.action->redirect->transform; + transform->host = "new.host.com"; + transform->path = "/pages_with_script/page.html"; + transform->query = "?new_query"; + transform->fragment = "#new_fragment"; + + ASSERT_NO_FATAL_FAILURE(LoadExtensionWithRules( + {rule1, rule2, rule3}, "test_extension", {URLPattern::kAllUrlsPattern})); + + struct { + GURL url; + GURL expected_url; + } cases[] = {{embedded_test_server()->GetURL("example.com", + "/pages_with_script/index.html"), + // Because of higher priority, the transform rule is chosen. + embedded_test_server()->GetURL( + "new.host.com", + "/pages_with_script/page.html?new_query#new_fragment")}, + // Because of higher priority, the extensionPath rule is chosen. + {embedded_test_server()->GetURL( + "xyz.com", "/pages_with_script/index.html?example.com"), + GURL("chrome-extension://" + last_loaded_extension_id() + + "/manifest.json?query#fragment")}, + {embedded_test_server()->GetURL("ex.com", + "/pages_with_script/index.html"), + embedded_test_server()->GetURL( + "google.com", "/pages_with_script/index.html")}}; + + for (const auto& test_case : cases) { + SCOPED_TRACE("Testing " + test_case.url.spec()); + ui_test_utils::NavigateToURL(browser(), test_case.url); + EXPECT_EQ(test_case.expected_url, web_contents()->GetLastCommittedURL()); + } +} + // Test fixture to verify that host permissions for the request url and the // request initiator are properly checked when redirecting requests. Loads an // example.com url with four sub-frames named frame_[1..4] from hosts @@ -2594,7 +2660,8 @@ rule.condition->url_filter = std::string("not_a_valid_child_frame.html"); rule.condition->resource_types = std::vector<std::string>({"sub_frame"}); rule.action->type = std::string("redirect"); - rule.action->redirect_url = + rule.action->redirect.emplace(); + rule.action->redirect->url = embedded_test_server()->GetURL("foo.com", "/child_frame.html").spec(); ASSERT_NO_FATAL_FAILURE(
diff --git a/chrome/browser/extensions/api/declarative_net_request/rule_indexing_unittest.cc b/chrome/browser/extensions/api/declarative_net_request/rule_indexing_unittest.cc index eb626a6c..7d33916 100644 --- a/chrome/browser/extensions/api/declarative_net_request/rule_indexing_unittest.cc +++ b/chrome/browser/extensions/api/declarative_net_request/rule_indexing_unittest.cc
@@ -191,7 +191,8 @@ TEST_P(RuleIndexingTest, EmptyRedirectRulePriority) { TestRule rule = CreateGenericRule(); rule.action->type = std::string("redirect"); - rule.action->redirect_url = std::string("https://google.com"); + rule.action->redirect.emplace(); + rule.action->redirect->url = std::string("https://google.com"); AddRule(rule); LoadAndExpectError( ParseInfo(ParseResult::ERROR_EMPTY_REDIRECT_RULE_PRIORITY, *rule.id) @@ -208,7 +209,7 @@ rule.priority = kMinValidPriority; AddRule(rule); - LoadAndExpectError(ParseInfo(ParseResult::ERROR_EMPTY_REDIRECT_URL, *rule.id) + LoadAndExpectError(ParseInfo(ParseResult::ERROR_INVALID_REDIRECT, *rule.id) .GetErrorDescription()); } @@ -223,7 +224,8 @@ TEST_P(RuleIndexingTest, InvalidRedirectRulePriority) { TestRule rule = CreateGenericRule(); rule.action->type = std::string("redirect"); - rule.action->redirect_url = std::string("https://google.com"); + rule.action->redirect.emplace(); + rule.action->redirect->url = std::string("https://google.com"); rule.priority = kMinValidPriority - 1; AddRule(rule); LoadAndExpectError( @@ -271,7 +273,8 @@ TEST_P(RuleIndexingTest, InvalidRedirectURL) { TestRule rule = CreateGenericRule(); rule.action->type = std::string("redirect"); - rule.action->redirect_url = std::string("google"); + rule.action->redirect.emplace(); + rule.action->redirect->url = std::string("google"); rule.priority = kMinValidPriority; AddRule(rule); LoadAndExpectError(
diff --git a/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc b/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc index da54fade..808d1b52 100644 --- a/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc +++ b/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc
@@ -307,7 +307,8 @@ rule.condition->url_filter = std::string("example.com"); rule.priority = kMinValidPriority; rule.action->type = std::string("redirect"); - rule.action->redirect_url = std::string("http://google.com"); + rule.action->redirect.emplace(); + rule.action->redirect->url = std::string("http://google.com"); std::unique_ptr<CompositeMatcher> matcher; ASSERT_NO_FATAL_FAILURE( CreateMatcherForRules({rule}, "test_extension", &matcher, @@ -373,7 +374,8 @@ rule.condition->url_filter = std::string("*"); rule.priority = kMinValidPriority; rule.action->type = std::string("redirect"); - rule.action->redirect_url = std::string("http://google.com"); + rule.action->redirect.emplace(); + rule.action->redirect->url = std::string("http://google.com"); ASSERT_NO_FATAL_FAILURE(CreateMatcherForRules( {rule}, "test extension_2", &matcher, std::vector<std::string>({URLPattern::kAllUrlsPattern}), @@ -589,7 +591,8 @@ rule.priority = kMinValidPriority; rule.condition->url_filter = std::string("example.com"); rule.action->type = std::string("redirect"); - rule.action->redirect_url = std::string("https://foo.com"); + rule.action->redirect.emplace(); + rule.action->redirect->url = std::string("https://foo.com"); std::vector<std::string> host_permissions = {"*://yahoo.com/*", "*://example.com/*"}; ASSERT_NO_FATAL_FAILURE(CreateMatcherForRules(
diff --git a/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc b/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc index 9f27581..d11e197 100644 --- a/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc +++ b/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/macros.h" +#include "base/strings/strcat.h" #include "base/strings/utf_string_conversions.h" #include "base/task/post_task.h" #include "chrome/browser/apps/app_service/app_launch_params.h" @@ -51,16 +52,59 @@ #include "services/data_decoder/public/cpp/safe_json_parser.h" #if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/arc/arc_util.h" #include "chrome/browser/chromeos/login/demo_mode/demo_session.h" -#endif +#include "chrome/browser/ui/app_list/arc/arc_app_utils.h" +#include "components/arc/arc_service_manager.h" +#include "components/arc/arc_util.h" +#include "components/arc/mojom/intent_helper.mojom.h" +#include "components/arc/session/arc_bridge_service.h" +#endif // OS_CHROMEOS namespace { +#if defined(OS_CHROMEOS) +const char kPlayIntentPrefix[] = + "https://play.google.com/store/apps/details?id="; +const char kChromeWebStoreReferrer[] = "&referrer=chrome_web_store"; +#endif // OS_CHROMEOS + +using InstallAndroidAppCallback = + extensions::ManagementAPIDelegate::InstallAndroidAppCallback; +using AndroidAppInstallStatusCallback = + extensions::ManagementAPIDelegate::AndroidAppInstallStatusCallback; using InstallWebAppCallback = extensions::ManagementAPIDelegate::InstallWebAppCallback; using InstallWebAppResult = extensions::ManagementAPIDelegate::InstallWebAppResult; +#if defined(OS_CHROMEOS) +void OnDidCheckForIntentToPlayStore(const std::string& intent, + InstallAndroidAppCallback callback, + bool installable) { + if (!installable) { + std::move(callback).Run(false); + return; + } + + auto* arc_service_manager = arc::ArcServiceManager::Get(); + if (!arc_service_manager) { + std::move(callback).Run(false); + return; + } + + auto* instance = ARC_GET_INSTANCE_FOR_METHOD( + arc_service_manager->arc_bridge_service()->intent_helper(), HandleUrl); + if (!instance) { + std::move(callback).Run(false); + return; + } + + instance->HandleUrl(intent, arc::kPlayStorePackage); + std::move(callback).Run(true); +} +#endif // OS_CHROMEOS + class ManagementSetEnabledFunctionInstallPromptDelegate : public extensions::InstallPromptDelegate { public: @@ -370,7 +414,7 @@ auto* provider = web_app::WebAppProviderBase::GetProviderBase( Profile::FromBrowserContext(context)); DCHECK(provider); - return provider->registrar().IsInstalled(web_app_url); + return provider->registrar().IsLocallyInstalled(web_app_url); } bool ChromeManagementAPIDelegate::CanContextInstallWebApps( @@ -392,6 +436,66 @@ std::move(callback))); } +bool ChromeManagementAPIDelegate::CanContextInstallAndroidApps( + content::BrowserContext* context) const { +#if defined(OS_CHROMEOS) + return arc::IsArcAllowedForProfile(Profile::FromBrowserContext(context)); +#else + return false; +#endif // defined(OS_CHROMEOS) +} + +void ChromeManagementAPIDelegate::CheckAndroidAppInstallStatus( + const std::string& package_name, + AndroidAppInstallStatusCallback callback) const { +#if defined(OS_CHROMEOS) + auto* arc_service_manager = arc::ArcServiceManager::Get(); + if (!arc_service_manager) { + std::move(callback).Run(false); + return; + } + + auto* instance = ARC_GET_INSTANCE_FOR_METHOD( + arc_service_manager->arc_bridge_service()->app(), IsInstallable); + if (!instance) { + std::move(callback).Run(false); + return; + } + + instance->IsInstallable(package_name, std::move(callback)); +#else + std::move(callback).Run(false); +#endif // OS_CHROMEOS +} + +void ChromeManagementAPIDelegate::InstallReplacementAndroidApp( + const std::string& package_name, + InstallAndroidAppCallback callback) const { +#if defined(OS_CHROMEOS) + std::string intent = + base::StrCat({kPlayIntentPrefix, package_name, kChromeWebStoreReferrer}); + + auto* arc_service_manager = arc::ArcServiceManager::Get(); + if (!arc_service_manager) { + std::move(callback).Run(false); + return; + } + + auto* instance = ARC_GET_INSTANCE_FOR_METHOD( + arc_service_manager->arc_bridge_service()->app(), IsInstallable); + if (!instance) { + std::move(callback).Run(false); + return; + } + + instance->IsInstallable( + package_name, base::BindOnce(&OnDidCheckForIntentToPlayStore, intent, + std::move(callback))); +#else + std::move(callback).Run(false); +#endif // defined(OS_CHROMEOS) +} + void ChromeManagementAPIDelegate::EnableExtension( content::BrowserContext* context, const std::string& extension_id) const {
diff --git a/chrome/browser/extensions/api/management/chrome_management_api_delegate.h b/chrome/browser/extensions/api/management/chrome_management_api_delegate.h index 8088380..8358759 100644 --- a/chrome/browser/extensions/api/management/chrome_management_api_delegate.h +++ b/chrome/browser/extensions/api/management/chrome_management_api_delegate.h
@@ -54,6 +54,15 @@ content::BrowserContext* context, const GURL& web_app_url, ManagementAPIDelegate::InstallWebAppCallback callback) const override; + bool CanContextInstallAndroidApps( + content::BrowserContext* context) const override; + void CheckAndroidAppInstallStatus( + const std::string& package_name, + ManagementAPIDelegate::AndroidAppInstallStatusCallback callback) + const override; + void InstallReplacementAndroidApp( + const std::string& package_name, + ManagementAPIDelegate::InstallAndroidAppCallback callback) const override; void EnableExtension(content::BrowserContext* context, const std::string& extension_id) const override; void DisableExtension(
diff --git a/chrome/browser/extensions/api/management/management_apitest.cc b/chrome/browser/extensions/api/management/management_apitest.cc index 807f141..fbe8bb8 100644 --- a/chrome/browser/extensions/api/management/management_apitest.cc +++ b/chrome/browser/extensions/api/management/management_apitest.cc
@@ -282,10 +282,10 @@ auto* provider = web_app::WebAppProviderBase::GetProviderBase(browser()->profile()); - EXPECT_FALSE(provider->registrar().IsInstalled(good_web_app_url)); + EXPECT_FALSE(provider->registrar().IsLocallyInstalled(good_web_app_url)); RunTest(kManifest, kGoodWebAppURL, kBackground, true /* from_webstore */); - EXPECT_TRUE(provider->registrar().IsInstalled(good_web_app_url)); + EXPECT_TRUE(provider->registrar().IsLocallyInstalled(good_web_app_url)); chrome::SetAutoAcceptPWAInstallConfirmationForTesting(false); } @@ -319,10 +319,10 @@ auto* provider = web_app::WebAppProviderBase::GetProviderBase(browser()->profile()); - EXPECT_FALSE(provider->registrar().IsInstalled(good_web_app_url)); + EXPECT_FALSE(provider->registrar().IsLocallyInstalled(good_web_app_url)); RunTest(kAppManifest, kGoodWebAppURL, kBackground, true /* from_webstore */); - EXPECT_TRUE(provider->registrar().IsInstalled(good_web_app_url)); + EXPECT_TRUE(provider->registrar().IsLocallyInstalled(good_web_app_url)); chrome::SetAutoAcceptPWAInstallConfirmationForTesting(false); }
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc index 158b881..f5a5bff 100644 --- a/chrome/browser/extensions/api/settings_private/prefs_util.cc +++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -471,7 +471,7 @@ settings_api::PrefType::PREF_TYPE_BOOLEAN; (*s_whitelist)[prefs::kRestoreLastLockScreenNote] = settings_api::PrefType::PREF_TYPE_BOOLEAN; - (*s_whitelist)[ash::prefs::kLockScreenMediaKeysEnabled] = + (*s_whitelist)[ash::prefs::kLockScreenMediaControlsEnabled] = settings_api::PrefType::PREF_TYPE_BOOLEAN; (*s_whitelist)[::prefs::kSettingsShowBrowserBanner] = settings_api::PrefType::PREF_TYPE_BOOLEAN;
diff --git a/chrome/browser/extensions/chrome_url_request_util.cc b/chrome/browser/extensions/chrome_url_request_util.cc index 7766498..5a492622a 100644 --- a/chrome/browser/extensions/chrome_url_request_util.cc +++ b/chrome/browser/extensions/chrome_url_request_util.cc
@@ -29,7 +29,6 @@ #include "net/http/http_request_headers.h" #include "net/http/http_response_headers.h" #include "net/http/http_response_info.h" -#include "third_party/zlib/google/compression_utils.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/template_expressions.h" @@ -63,30 +62,15 @@ ->GetTemplateReplacementsForExtension(extension_id) : nullptr; - bool is_gzipped = rb.IsGzipped(resource_id); - if (!bytes->size() || (!replacements && !is_gzipped)) { + if (replacements) { + base::StringPiece input(reinterpret_cast<const char*>(bytes->front()), + bytes->size()); + std::string temp_str = ui::ReplaceTemplateExpressions(input, *replacements); + DCHECK(!temp_str.empty()); + return base::RefCountedString::TakeString(&temp_str); + } else { return bytes; } - - base::StringPiece input(reinterpret_cast<const char*>(bytes->front()), - bytes->size()); - - std::string temp_str; - - base::StringPiece source = input; - if (is_gzipped) { - temp_str.resize(compression::GetUncompressedSize(input)); - source = temp_str; - CHECK(compression::GzipUncompress(input, source)); - } - - if (replacements) { - temp_str = ui::ReplaceTemplateExpressions(source, *replacements); - } - - DCHECK(!temp_str.empty()); - - return base::RefCountedString::TakeString(&temp_str); } // Loads an extension resource in a Chrome .pak file. These are used by
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 5e0e1aa..daa0007 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -346,6 +346,11 @@ "expiry_milestone": 82 }, { + "name": "enable-autofill-updated-card-unmask-prompt-ui", + "owners": ["siyua", "payments-autofill-team@google.com"], + "expiry_milestone": 87 + }, + { "name": "enable-force-dark", "owners": [ "gilmanmh@google.com" ], "expiry_milestone": 80 @@ -1113,11 +1118,6 @@ "expiry_milestone": 78 }, { - "name": "enable-experimental-accessibility-chromevox-rich-text-indication", - "owners": [ "akihiroota", "dtseng" ], - "expiry_milestone": 78 - }, - { "name": "enable-experimental-kernel-vm-support", "owners": [ "jflat", "zwisler" ], "expiry_milestone": 78
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index f45583a..81b32eb 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -515,6 +515,12 @@ "If enabled, adds the status of certain experiment variations when making " "calls to Google Payments."; +const char kEnableAutofillUpdatedCardUnmaskPromptUiName[] = + "Enable new card unmask prompt UI"; +const char kEnableAutofillUpdatedCardUnmaskPromptUiDescription[] = + "If enabled, shows the updated card unmask prompt when performing CVC " + "verification."; + const char kEnableDeferAllScriptName[] = "DeferAllScript previews"; const char kEnableDeferAllScriptDescription[] = "Enable deferring synchronous script on slow pages."; @@ -3250,12 +3256,6 @@ "Enable ChromeVox language switching, which changes ChromeVox's " "output language upon detection of new language."; -const char kExperimentalAccessibilityChromeVoxRichTextIndicationName[] = - "Enable experimental ChromeVox rich text indication."; -const char kExperimentalAccessibilityChromeVoxRichTextIndicationDescription[] = - "Enable ChromeVox rich text indication, which automatically notifies the " - "user of text styling."; - const char kExperimentalAccessibilitySwitchAccessName[] = "Experimental feature Switch Access"; const char kExperimentalAccessibilitySwitchAccessDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index c19ffca..e079d7a 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -319,6 +319,9 @@ extern const char kEnableAutofillSendExperimentIdsInPaymentsRPCsName[]; extern const char kEnableAutofillSendExperimentIdsInPaymentsRPCsDescription[]; +extern const char kEnableAutofillUpdatedCardUnmaskPromptUiName[]; +extern const char kEnableAutofillUpdatedCardUnmaskPromptUiDescription[]; + extern const char kEnableDeferAllScriptName[]; extern const char kEnableDeferAllScriptDescription[]; @@ -1943,10 +1946,6 @@ extern const char kExperimentalAccessibilityChromeVoxLanguageSwitchingDescription[]; -extern const char kExperimentalAccessibilityChromeVoxRichTextIndicationName[]; -extern const char - kExperimentalAccessibilityChromeVoxRichTextIndicationDescription[]; - extern const char kExperimentalAccessibilitySwitchAccessName[]; extern const char kExperimentalAccessibilitySwitchAccessDescription[];
diff --git a/chrome/browser/mac/keystone_glue.mm b/chrome/browser/mac/keystone_glue.mm index ba76413..157ba8fd 100644 --- a/chrome/browser/mac/keystone_glue.mm +++ b/chrome/browser/mac/keystone_glue.mm
@@ -85,10 +85,11 @@ DCHECK(sel); scoped_refptr<PerformBridge> op = new PerformBridge(target, sel, arg); - base::PostTaskWithTraits(FROM_HERE, - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, - base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, - base::BindOnce(&PerformBridge::Run, op.get())); + base::PostTask( + FROM_HERE, + {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT, + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + base::BindOnce(&PerformBridge::Run, op.get())); } // Convenience for the no-argument case.
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_manager.cc b/chrome/browser/media/webrtc/webrtc_event_log_manager.cc index 9d04ca7..577b56b 100644 --- a/chrome/browser/media/webrtc/webrtc_event_log_manager.cc +++ b/chrome/browser/media/webrtc/webrtc_event_log_manager.cc
@@ -46,7 +46,7 @@ void EnableWebRtcEventLogging(const WebRtcEventLogPeerConnectionKey& key, int output_period_ms) override { - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce( &PeerConnectionTrackerProxyImpl::EnableWebRtcEventLoggingInternal, @@ -55,7 +55,7 @@ void DisableWebRtcEventLogging( const WebRtcEventLogPeerConnectionKey& key) override { - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce( &PeerConnectionTrackerProxyImpl::DisableWebRtcEventLoggingInternal, @@ -148,8 +148,8 @@ base::OnceCallback<void(Args...)> reply, Args... args) { if (reply) { - base::PostTaskWithTraits(location, {BrowserThread::UI}, - base::BindOnce(std::move(reply), args...)); + base::PostTask(location, {BrowserThread::UI}, + base::BindOnce(std::move(reply), args...)); } } @@ -181,8 +181,9 @@ } WebRtcEventLogManager::WebRtcEventLogManager() - : task_runner_(base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, + : task_runner_(base::CreateSequencedTaskRunner( + {base::ThreadPool(), base::MayBlock(), + base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})), remote_logging_feature_enabled_(IsRemoteLoggingFeatureEnabled()), local_logs_observer_(nullptr), @@ -450,9 +451,9 @@ } if (error) { - base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(std::move(reply), false, - std::string(), std::string(error))); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(std::move(reply), false, std::string(), + std::string(error))); return; } @@ -925,7 +926,7 @@ DCHECK_EQ(result, !log_id.empty()); DCHECK_EQ(!result, !error_message.empty()); - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce(std::move(reply), result, log_id, error_message)); } @@ -962,7 +963,7 @@ local_logs_observer_ = observer; if (reply) { - base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(reply)); + base::PostTask(FROM_HERE, {BrowserThread::UI}, std::move(reply)); } } @@ -974,7 +975,7 @@ remote_logs_observer_ = observer; if (reply) { - base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(reply)); + base::PostTask(FROM_HERE, {BrowserThread::UI}, std::move(reply)); } } @@ -987,7 +988,7 @@ base::OnceClosure reply) { manager->local_logs_manager_.SetClockForTesting(clock); - base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(reply)); + base::PostTask(FROM_HERE, {BrowserThread::UI}, std::move(reply)); }; // |this| is destroyed by ~BrowserProcessImpl(), so base::Unretained(this) @@ -1007,7 +1008,7 @@ base::OnceClosure reply) { manager->pc_tracker_proxy_ = std::move(pc_tracker_proxy); - base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(reply)); + base::PostTask(FROM_HERE, {BrowserThread::UI}, std::move(reply)); }; // |this| is destroyed by ~BrowserProcessImpl(), so base::Unretained(this) @@ -1031,8 +1032,7 @@ remote_logs_manager.SetWebRtcEventLogUploaderFactoryForTesting( std::move(uploader_factory)); - base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, - std::move(reply)); + base::PostTask(FROM_HERE, {BrowserThread::UI}, std::move(reply)); }; // |this| is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_manager_remote.cc b/chrome/browser/media/webrtc/webrtc_event_log_manager_remote.cc index 3fcdc3ed..a69b8d02 100644 --- a/chrome/browser/media/webrtc/webrtc_event_log_manager_remote.cc +++ b/chrome/browser/media/webrtc/webrtc_event_log_manager_remote.cc
@@ -542,8 +542,8 @@ if (!BrowserContextEnabled(browser_context_id)) { LOG(ERROR) << "Unknown |browser_context_id|."; - base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(std::move(reply), history)); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, + base::BindOnce(std::move(reply), history)); return; } @@ -591,8 +591,8 @@ }; std::sort(history.begin(), history.end(), cmp); - base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(std::move(reply), history)); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, + base::BindOnce(std::move(reply), history)); } void WebRtcRemoteEventLogManager::RemovePendingLogsForNotEnabledBrowserContext( @@ -664,17 +664,16 @@ void WebRtcRemoteEventLogManager::UploadConditionsHoldForTesting( base::OnceCallback<void(bool)> callback) { DCHECK(task_runner_->RunsTasksInCurrentSequence()); - base::PostTaskWithTraits( - FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(std::move(callback), UploadConditionsHold())); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, + base::BindOnce(std::move(callback), UploadConditionsHold())); } void WebRtcRemoteEventLogManager::ShutDownForTesting(base::OnceClosure reply) { DCHECK(task_runner_->RunsTasksInCurrentSequence()); weak_ptr_factory_->InvalidateWeakPtrs(); weak_ptr_factory_.reset(); - base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(std::move(reply))); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, + base::BindOnce(std::move(reply))); } bool WebRtcRemoteEventLogManager::AreLogParametersValid(
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_uploader.cc b/chrome/browser/media/webrtc/webrtc_event_log_uploader.cc index 4d3a4bf..d21dd50 100644 --- a/chrome/browser/media/webrtc/webrtc_event_log_uploader.cc +++ b/chrome/browser/media/webrtc/webrtc_event_log_uploader.cc
@@ -279,10 +279,9 @@ // immediately, even though it needs to finish initialization on the UI // thread. network::mojom::URLLoaderFactoryPtr url_loader_factory_ptr; - base::PostTaskWithTraits( - FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(BindURLLoaderFactoryRequest, - mojo::MakeRequest(&url_loader_factory_ptr))); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, + base::BindOnce(BindURLLoaderFactoryRequest, + mojo::MakeRequest(&url_loader_factory_ptr))); url_loader_ = network::SimpleURLLoader::Create( std::move(resource_request), kWebrtcEventLogUploaderTrafficAnnotation);
diff --git a/chrome/browser/net/chrome_mojo_proxy_resolver_factory_browsertest.cc b/chrome/browser/net/chrome_mojo_proxy_resolver_factory_browsertest.cc index 70aec8b..7e857b3 100644 --- a/chrome/browser/net/chrome_mojo_proxy_resolver_factory_browsertest.cc +++ b/chrome/browser/net/chrome_mojo_proxy_resolver_factory_browsertest.cc
@@ -157,9 +157,8 @@ // Wait a little bit and check it's still running. { base::RunLoop run_loop; - base::PostDelayedTaskWithTraits(FROM_HERE, {content::BrowserThread::UI}, - run_loop.QuitClosure(), - kServiceShutdownTimeout); + base::PostDelayedTask(FROM_HERE, {content::BrowserThread::UI}, + run_loop.QuitClosure(), kServiceShutdownTimeout); run_loop.Run(); } @@ -202,9 +201,8 @@ // Wait a little bit and check it's still running. { base::RunLoop run_loop; - base::PostDelayedTaskWithTraits(FROM_HERE, {content::BrowserThread::UI}, - run_loop.QuitClosure(), - kServiceShutdownTimeout); + base::PostDelayedTask(FROM_HERE, {content::BrowserThread::UI}, + run_loop.QuitClosure(), kServiceShutdownTimeout); run_loop.Run(); }
diff --git a/chrome/browser/net/dns_probe_browsertest.cc b/chrome/browser/net/dns_probe_browsertest.cc index 6fc5241..56b5263 100644 --- a/chrome/browser/net/dns_probe_browsertest.cc +++ b/chrome/browser/net/dns_probe_browsertest.cc
@@ -58,10 +58,10 @@ namespace { // Postable function to run a Closure on the UI thread. Since -// base::PostTaskWithTraits returns a bool, it can't directly be posted to +// base::PostTask returns a bool, it can't directly be posted to // another thread. void RunClosureOnUIThread(const base::Closure& closure) { - base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, closure); + base::PostTask(FROM_HERE, {BrowserThread::UI}, closure); } // Wraps DnsProbeService and delays probes until someone calls @@ -419,10 +419,9 @@ browser()->profile()->GetPrefs()->SetBoolean( prefs::kAlternateErrorPagesEnabled, true); - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::IO}, - BindOnce(&DnsProbeBrowserTestIOThreadHelper::SetUpOnIOThread, - Unretained(helper_))); + base::PostTask(FROM_HERE, {BrowserThread::IO}, + BindOnce(&DnsProbeBrowserTestIOThreadHelper::SetUpOnIOThread, + Unretained(helper_))); ASSERT_TRUE(embedded_test_server()->Start()); @@ -434,7 +433,7 @@ } void DnsProbeBrowserTest::TearDownOnMainThread() { - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::IO}, BindOnce( &DnsProbeBrowserTestIOThreadHelper::CleanUpOnIOThreadAndDeleteHelper, @@ -500,7 +499,7 @@ void DnsProbeBrowserTest::SetCorrectionServiceBroken(bool broken) { int net_error = broken ? net::ERR_NAME_NOT_RESOLVED : net::OK; - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::IO}, BindOnce(&DnsProbeBrowserTestIOThreadHelper::SetCorrectionServiceNetError, Unretained(helper_), net_error)); @@ -508,7 +507,7 @@ void DnsProbeBrowserTest::SetCorrectionServiceDelayRequests( bool delay_requests) { - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::IO}, BindOnce( &DnsProbeBrowserTestIOThreadHelper::SetCorrectionServiceDelayRequests, @@ -517,7 +516,7 @@ void DnsProbeBrowserTest::WaitForDelayedRequestDestruction() { base::RunLoop run_loop; - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::IO}, BindOnce( &DnsProbeBrowserTestIOThreadHelper::SetRequestDestructionCallback,
diff --git a/chrome/browser/net/errorpage_browsertest.cc b/chrome/browser/net/errorpage_browsertest.cc index 348db55..cbfa8137 100644 --- a/chrome/browser/net/errorpage_browsertest.cc +++ b/chrome/browser/net/errorpage_browsertest.cc
@@ -331,10 +331,9 @@ EXPECT_EQ(origin, "null"); // Send RequestCreated so that anyone blocking on // WaitForRequests can continue. - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&DNSErrorPageTest::RequestCreated, - base::Unretained(owner))); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(&DNSErrorPageTest::RequestCreated, + base::Unretained(owner))); content::URLLoaderInterceptor::WriteResponse( "chrome/test/data/mock-link-doctor.json", params->client.get());
diff --git a/chrome/browser/net/file_downloader.cc b/chrome/browser/net/file_downloader.cc index cbb75e64..93edaf3 100644 --- a/chrome/browser/net/file_downloader.cc +++ b/chrome/browser/net/file_downloader.cc
@@ -48,8 +48,9 @@ base::Unretained(this))); } else { base::PostTaskAndReplyWithResult( - base::CreateTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, + base::CreateTaskRunner( + {base::ThreadPool(), base::MayBlock(), + base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}) .get(), FROM_HERE, base::Bind(&base::PathExists, local_path_), @@ -75,9 +76,9 @@ } base::PostTaskAndReplyWithResult( - base::CreateTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, - base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}) + base::CreateTaskRunner({base::ThreadPool(), base::MayBlock(), + base::TaskPriority::BEST_EFFORT, + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}) .get(), FROM_HERE, base::Bind(&base::Move, response_path, local_path_), base::Bind(&FileDownloader::OnFileMoveDone,
diff --git a/chrome/browser/net/network_quality_tracker_browsertest.cc b/chrome/browser/net/network_quality_tracker_browsertest.cc index 0a20d6f5d..2b53d797 100644 --- a/chrome/browser/net/network_quality_tracker_browsertest.cc +++ b/chrome/browser/net/network_quality_tracker_browsertest.cc
@@ -124,8 +124,7 @@ void SimulateNetworkQualityChange(net::EffectiveConnectionType type) { if (!content::IsOutOfProcessNetworkService()) { scoped_refptr<base::SequencedTaskRunner> task_runner = - base::CreateSequencedTaskRunnerWithTraits( - {content::BrowserThread::IO}); + base::CreateSequencedTaskRunner({content::BrowserThread::IO}); if (content::IsInProcessNetworkService()) task_runner = content::GetNetworkTaskRunner(); task_runner->PostTask(
diff --git a/chrome/browser/net/nss_context.cc b/chrome/browser/net/nss_context.cc index 18e501c8..67aa6bf 100644 --- a/chrome/browser/net/nss_context.cc +++ b/chrome/browser/net/nss_context.cc
@@ -52,7 +52,7 @@ const base::Callback<void(net::NSSCertDatabase*)>& callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::IO}, base::BindOnce(&GetCertDBOnIOThread, profile->GetResourceContext(), base::ThreadTaskRunnerHandle::Get(), callback));
diff --git a/chrome/browser/net/nss_context_chromeos_browsertest.cc b/chrome/browser/net/nss_context_chromeos_browsertest.cc index df30a0b2..d17dfc9 100644 --- a/chrome/browser/net/nss_context_chromeos_browsertest.cc +++ b/chrome/browser/net/nss_context_chromeos_browsertest.cc
@@ -42,7 +42,7 @@ // Returns true if the database was retrieved successfully. bool DoGetDBTests() { base::RunLoop run_loop; - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {content::BrowserThread::IO}, base::BindOnce(&DBTester::GetDBAndDoTestsOnIOThread, base::Unretained(this), profile_->GetResourceContext(), @@ -54,7 +54,7 @@ // Test retrieving the database again, should be called after DoGetDBTests. void DoGetDBAgainTests() { base::RunLoop run_loop; - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {content::BrowserThread::IO}, base::BindOnce(&DBTester::DoGetDBAgainTestsOnIOThread, base::Unretained(this), profile_->GetResourceContext(), @@ -95,8 +95,7 @@ EXPECT_EQ(db->GetPublicSlot().get(), db->GetPrivateSlot().get()); } - base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI}, - done_callback); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, done_callback); } void DoGetDBAgainTestsOnIOThread(content::ResourceContext* context, @@ -108,8 +107,7 @@ // Should return the same db as before. EXPECT_EQ(db_, db); - base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI}, - done_callback); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, done_callback); } Profile* profile_;
diff --git a/chrome/browser/net/profile_network_context_service.cc b/chrome/browser/net/profile_network_context_service.cc index 97ea0ee..d4150cd 100644 --- a/chrome/browser/net/profile_network_context_service.cc +++ b/chrome/browser/net/profile_network_context_service.cc
@@ -226,9 +226,9 @@ // stable users, which would be after M83 branches. base::FilePath media_cache_path = GetPartitionPath(relative_partition_path) .Append(chrome::kMediaCacheDirname); - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, - {base::TaskPriority::BEST_EFFORT, base::MayBlock(), + {base::ThreadPool(), base::TaskPriority::BEST_EFFORT, base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, base::BindOnce(base::IgnoreResult(&base::DeleteFile), media_cache_path, true /* recursive */));
diff --git a/chrome/browser/notifications/scheduler/internal/BUILD.gn b/chrome/browser/notifications/scheduler/internal/BUILD.gn index bfd2e3a6..0641e7a 100644 --- a/chrome/browser/notifications/scheduler/internal/BUILD.gn +++ b/chrome/browser/notifications/scheduler/internal/BUILD.gn
@@ -58,11 +58,13 @@ # This target should not depend on anything in //chrome/* except the proto library. deps = [ "//base", + "//chrome/app:generated_resources", "//chrome/browser/notifications/proto", "//chrome/browser/notifications/scheduler/public", "//components/keyed_service/core", "//components/leveldb_proto", "//skia", + "//ui/base", "//ui/gfx/codec", ] }
diff --git a/chrome/browser/notifications/scheduler/internal/impression_history_tracker.cc b/chrome/browser/notifications/scheduler/internal/impression_history_tracker.cc index 976641fc..158b5e5 100644 --- a/chrome/browser/notifications/scheduler/internal/impression_history_tracker.cc +++ b/chrome/browser/notifications/scheduler/internal/impression_history_tracker.cc
@@ -61,14 +61,21 @@ weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } -void ImpressionHistoryTrackerImpl::AddImpression(SchedulerClientType type, - const std::string& guid) { +void ImpressionHistoryTrackerImpl::AddImpression( + SchedulerClientType type, + const std::string& guid, + const Impression::ImpressionResultMap& impression_mapping, + const Impression::CustomData& custom_data) { DCHECK(initialized_); auto it = client_states_.find(type); if (it == client_states_.end()) return; - it->second->impressions.emplace_back(Impression(type, guid, clock_->Now())); + Impression impression(type, guid, clock_->Now()); + impression.impression_mapping = impression_mapping; + impression.custom_data = custom_data; + it->second->impressions.emplace_back(std::move(impression)); + impression_map_.emplace(guid, &it->second->impressions.back()); SetNeedsUpdate(type, true /*needs_update*/); MaybeUpdateDb(type); @@ -93,6 +100,12 @@ } } +const Impression* ImpressionHistoryTrackerImpl::GetImpression( + const std::string& guid) const { + auto it = impression_map_.find(guid); + return it == impression_map_.end() ? nullptr : it->second; +} + void ImpressionHistoryTrackerImpl::GetImpressionDetail( SchedulerClientType type, ImpressionDetail::ImpressionDetailCallback callback) {
diff --git a/chrome/browser/notifications/scheduler/internal/impression_history_tracker.h b/chrome/browser/notifications/scheduler/internal/impression_history_tracker.h index 0ea2916..5be695b 100644 --- a/chrome/browser/notifications/scheduler/internal/impression_history_tracker.h +++ b/chrome/browser/notifications/scheduler/internal/impression_history_tracker.h
@@ -48,8 +48,11 @@ virtual void Init(Delegate* delegate, InitCallback callback) = 0; // Add a new impression, called after the notification is shown. - virtual void AddImpression(SchedulerClientType type, - const std::string& guid) = 0; + virtual void AddImpression( + SchedulerClientType type, + const std::string& guid, + const Impression::ImpressionResultMap& impression_map, + const Impression::CustomData& custom_data) = 0; // Analyzes the impression history for all notification clients, and adjusts // the |current_max_daily_show|. @@ -60,6 +63,10 @@ std::map<SchedulerClientType, const ClientState*>* client_states) const = 0; + // Queries impression based on guid, returns nullptr if no impression is + // found. + virtual const Impression* GetImpression(const std::string& guid) const = 0; + // Queries the impression detail of a given |SchedulerClientType|. virtual void GetImpressionDetail( SchedulerClientType type, @@ -88,10 +95,13 @@ // ImpressionHistoryTracker implementation. void Init(Delegate* delegate, InitCallback callback) override; void AddImpression(SchedulerClientType type, - const std::string& guid) override; + const std::string& guid, + const Impression::ImpressionResultMap& impression_mapping, + const Impression::CustomData& custom_data) override; void AnalyzeImpressionHistory() override; void GetClientStates(std::map<SchedulerClientType, const ClientState*>* client_states) const override; + const Impression* GetImpression(const std::string& guid) const override; void GetImpressionDetail( SchedulerClientType type, ImpressionDetail::ImpressionDetailCallback callback) override;
diff --git a/chrome/browser/notifications/scheduler/internal/impression_history_tracker_unittest.cc b/chrome/browser/notifications/scheduler/internal/impression_history_tracker_unittest.cc index 2e44085..b77cbe6 100644 --- a/chrome/browser/notifications/scheduler/internal/impression_history_tracker_unittest.cc +++ b/chrome/browser/notifications/scheduler/internal/impression_history_tracker_unittest.cc
@@ -24,6 +24,7 @@ namespace { const char kGuid1[] = "guid1"; +const char kGuid2[] = "guid2"; const char kButtonId[] = "button_id_1"; const char kTimeStr[] = "04/25/20 01:00:00 AM"; @@ -233,17 +234,37 @@ InitTrackerWithData(test_case); // No-op for unregistered client. - tracker()->AddImpression(SchedulerClientType::kTest2, kGuid1); + tracker()->AddImpression(SchedulerClientType::kTest2, kGuid2, + Impression::ImpressionResultMap(), + Impression::CustomData()); VerifyClientStates(test_case); SetNow(kTimeStr); + Impression::ImpressionResultMap impression_mapping = { + {UserFeedback::kDismiss, ImpressionResult::kNegative}}; + Impression::CustomData custom_data = {{"url", "https://www.example.com"}}; EXPECT_CALL(*store(), Update(_, _, _)); EXPECT_CALL(*delegate(), OnImpressionUpdated()); - tracker()->AddImpression(SchedulerClientType::kTest1, kGuid1); - test_case.expected.back().impressions.emplace_back( - Impression(SchedulerClientType::kTest1, kGuid1, clock()->Now())); + tracker()->AddImpression(SchedulerClientType::kTest1, kGuid1, + impression_mapping, custom_data); + Impression expected_impression(SchedulerClientType::kTest1, kGuid1, + clock()->Now()); + expected_impression.impression_mapping = impression_mapping; + expected_impression.custom_data = custom_data; + test_case.expected.back().impressions.emplace_back(expected_impression); VerifyClientStates(test_case); + EXPECT_EQ(*tracker()->GetImpression(kGuid1), expected_impression); +} + +// Verifies that impression loaded from the database can be retrieved correctly. +TEST_F(ImpressionHistoryTrackerTest, GetImpressionLoadedFromDb) { + TestCase test_case = CreateDefaultTestCase(); + Impression impression(SchedulerClientType::kTest1, kGuid1, clock()->Now()); + test_case.input.front().impressions.emplace_back(impression); + CreateTracker(test_case); + InitTrackerWithData(test_case); + EXPECT_EQ(*tracker()->GetImpression(kGuid1), impression); } // If impression has been deleted, click should have no result.
diff --git a/chrome/browser/notifications/scheduler/internal/impression_types.h b/chrome/browser/notifications/scheduler/internal/impression_types.h index aeba9ab..711885b 100644 --- a/chrome/browser/notifications/scheduler/internal/impression_types.h +++ b/chrome/browser/notifications/scheduler/internal/impression_types.h
@@ -25,6 +25,7 @@ // an impression result, which may affect notification exposure. // 4. The impression is deleted after it expires. struct Impression { + using ImpressionResultMap = std::map<UserFeedback, ImpressionResult>; using CustomData = std::map<std::string, std::string>; Impression(); Impression(SchedulerClientType type, @@ -63,7 +64,7 @@ SchedulerClientType type = SchedulerClientType::kUnknown; // Used to override default impression result. - std::map<UserFeedback, ImpressionResult> impression_mapping; + ImpressionResultMap impression_mapping; // Custom data associated with a notification. Send back to the client when // the user interacts with the notification.
diff --git a/chrome/browser/notifications/scheduler/internal/notification_scheduler.cc b/chrome/browser/notifications/scheduler/internal/notification_scheduler.cc index 6642241..187ff86 100644 --- a/chrome/browser/notifications/scheduler/internal/notification_scheduler.cc +++ b/chrome/browser/notifications/scheduler/internal/notification_scheduler.cc
@@ -221,15 +221,17 @@ void AfterClientUpdateData( std::unique_ptr<NotificationEntry> entry, std::unique_ptr<NotificationData> updated_notification_data) { + // Tracks user impression on the notification to be shown. + context_->impression_tracker()->AddImpression( + entry->type, entry->guid, entry->schedule_params.impression_mapping, + updated_notification_data->custom_data); + // Show the notification in UI. auto system_data = std::make_unique<DisplayAgent::SystemData>(); system_data->type = entry->type; system_data->guid = entry->guid; context_->display_agent()->ShowNotification( std::move(updated_notification_data), std::move(system_data)); - - // Tracks user impression on the notification to be shown. - context_->impression_tracker()->AddImpression(entry->type, entry->guid); } // ImpressionHistoryTracker::Delegate implementation. @@ -283,7 +285,16 @@ if (!client) return; - client->OnUserAction(action_data); + auto client_action_data = action_data; + + // Attach custom data if the impression is not expired. + const auto* impression = + context_->impression_tracker()->GetImpression(action_data.guid); + if (impression) { + client_action_data.custom_data = impression->custom_data; + } + + client->OnUserAction(client_action_data); } std::unique_ptr<NotificationSchedulerContext> context_;
diff --git a/chrome/browser/notifications/scheduler/internal/notification_scheduler_unittest.cc b/chrome/browser/notifications/scheduler/internal/notification_scheduler_unittest.cc index e424a22..85d70e2d 100644 --- a/chrome/browser/notifications/scheduler/internal/notification_scheduler_unittest.cc +++ b/chrome/browser/notifications/scheduler/internal/notification_scheduler_unittest.cc
@@ -291,7 +291,7 @@ DisplayDecider::Results result({kGuid}); EXPECT_CALL(*display_decider(), FindNotificationsToShow(_, _, _, _)) .WillOnce(SetArgPointee<3>(result)); - EXPECT_CALL(*impression_tracker(), AddImpression(_, _)); + EXPECT_CALL(*impression_tracker(), AddImpression(_, _, _, _)); EXPECT_CALL(*client(), BeforeShowNotification(_, _)) .WillOnce(Invoke(
diff --git a/chrome/browser/notifications/scheduler/internal/scheduled_notification_manager.cc b/chrome/browser/notifications/scheduler/internal/scheduled_notification_manager.cc index 5be9fcc..17e7486 100644 --- a/chrome/browser/notifications/scheduler/internal/scheduled_notification_manager.cc +++ b/chrome/browser/notifications/scheduler/internal/scheduled_notification_manager.cc
@@ -21,6 +21,8 @@ #include "chrome/browser/notifications/scheduler/internal/scheduler_utils.h" #include "chrome/browser/notifications/scheduler/public/notification_params.h" #include "chrome/browser/notifications/scheduler/public/notification_scheduler_constant.h" +#include "chrome/grit/generated_resources.h" +#include "ui/base/l10n/l10n_util.h" namespace notifications { namespace { @@ -40,12 +42,16 @@ NotificationStore notification_store, std::unique_ptr<IconStore> icon_store, const std::vector<SchedulerClientType>& clients, - const SchedulerConfig& config) + const SchedulerConfig& config, + EncodeIconsCallback encode_icons_callback, + DecodeIconsCallback decode_icons_callback) : notification_store_(std::move(notification_store)), icon_store_(std::move(icon_store)), clients_(clients.begin(), clients.end()), delegate_(nullptr), - config_(config) {} + config_(config), + encode_icons_callback_(std::move(encode_icons_callback)), + decode_icons_callback_(std::move(decode_icons_callback)) {} private: void Init(Delegate* delegate, InitCallback callback) override { @@ -225,7 +231,8 @@ // in following CLs. if (entry->notification_data.icons.empty()) return; - notifications::ConvertIconToString( + + encode_icons_callback_.Run( std::move(entry->notification_data.icons.front()), base::BindOnce(&ScheduledNotificationManagerImpl::OnIconEncoded, weak_ptr_factory_.GetWeakPtr(), type, std::move(guid))); @@ -281,15 +288,18 @@ // Create two default buttons {Helpful, Unhelpful} for notification. void CreateInhrButtonsPair(std::vector<NotificationData::Button>* buttons) { buttons->clear(); - // TODO(hesen): Fill button text field with GRD string resource. NotificationData::Button helpful_button; helpful_button.type = ActionButtonType::kHelpful; helpful_button.id = notifications::kDefaultHelpfulButtonId; + helpful_button.text = + l10n_util::GetStringUTF16(IDS_NOTIFICATION_DEFAULT_HELPFUL_BUTTON_TEXT); buttons->emplace_back(std::move(helpful_button)); NotificationData::Button unhelpful_button; unhelpful_button.type = ActionButtonType::kUnhelpful; unhelpful_button.id = notifications::kDefaultUnhelpfulButtonId; + unhelpful_button.text = l10n_util::GetStringUTF16( + IDS_NOTIFICATION_DEFAULT_UNHELPFUL_BUTTON_TEXT); buttons->emplace_back(std::move(unhelpful_button)); } @@ -301,6 +311,8 @@ std::map<std::string, std::unique_ptr<NotificationEntry>>> notifications_; const SchedulerConfig& config_; + EncodeIconsCallback encode_icons_callback_; + DecodeIconsCallback decode_icons_callback_; base::WeakPtrFactory<ScheduledNotificationManagerImpl> weak_ptr_factory_{ this}; DISALLOW_COPY_AND_ASSIGN(ScheduledNotificationManagerImpl); @@ -313,9 +325,12 @@ std::unique_ptr<CollectionStore<NotificationEntry>> notification_store, std::unique_ptr<IconStore> icon_store, const std::vector<SchedulerClientType>& clients, - const SchedulerConfig& config) { + const SchedulerConfig& config, + EncodeIconsCallback encode_icons_callback, + DecodeIconsCallback decode_icons_callback) { return std::make_unique<ScheduledNotificationManagerImpl>( - std::move(notification_store), std::move(icon_store), clients, config); + std::move(notification_store), std::move(icon_store), clients, config, + std::move(encode_icons_callback), std::move(decode_icons_callback)); } ScheduledNotificationManager::ScheduledNotificationManager() = default;
diff --git a/chrome/browser/notifications/scheduler/internal/scheduled_notification_manager.h b/chrome/browser/notifications/scheduler/internal/scheduled_notification_manager.h index f228dad..b7cba887 100644 --- a/chrome/browser/notifications/scheduler/internal/scheduled_notification_manager.h +++ b/chrome/browser/notifications/scheduler/internal/scheduled_notification_manager.h
@@ -8,11 +8,13 @@ #include <map> #include <memory> #include <string> +#include <vector> #include "base/callback.h" #include "base/macros.h" #include "chrome/browser/notifications/scheduler/internal/collection_store.h" #include "chrome/browser/notifications/scheduler/public/notification_scheduler_types.h" +#include "third_party/skia/include/core/SkBitmap.h" namespace notifications { @@ -24,9 +26,15 @@ // Class to manage in-memory scheduled notifications loaded from the storage. class ScheduledNotificationManager { public: - using InitCallback = base::OnceCallback<void(bool)>; using Notifications = std::map<SchedulerClientType, std::vector<const NotificationEntry*>>; + using InitCallback = base::OnceCallback<void(bool)>; + using EncodeIconsCallback = + base::RepeatingCallback<void(SkBitmap, + base::OnceCallback<void(std::string)>)>; + using DecodeIconsCallback = + base::RepeatingCallback<void(std::string, + base::OnceCallback<void(SkBitmap)>)>; // Delegate that receives events from the manager. class Delegate { @@ -47,7 +55,9 @@ std::unique_ptr<CollectionStore<NotificationEntry>> notification_store, std::unique_ptr<IconStore> icon_store, const std::vector<SchedulerClientType>& clients, - const SchedulerConfig& config); + const SchedulerConfig& config, + EncodeIconsCallback encode_icons_callback, + DecodeIconsCallback decode_icons_callback); // Initializes the notification store. virtual void Init(Delegate* delegate, InitCallback callback) = 0;
diff --git a/chrome/browser/notifications/scheduler/internal/scheduled_notification_manager_unittest.cc b/chrome/browser/notifications/scheduler/internal/scheduled_notification_manager_unittest.cc index 9da9547..f3cbc9d 100644 --- a/chrome/browser/notifications/scheduler/internal/scheduled_notification_manager_unittest.cc +++ b/chrome/browser/notifications/scheduler/internal/scheduled_notification_manager_unittest.cc
@@ -31,6 +31,16 @@ const char kGuid[] = "test_guid_1234"; const char kTitle[] = "test_title"; +void NoopConvertIconToString(SkBitmap image, + base::OnceCallback<void(std::string)> callback) { + // TODO(hesen): Need to implement and then move a mock class. +} + +void NoopConvertStringToIcon(std::string data, + base::OnceCallback<void(SkBitmap)> callback) { + // TODO(hesen): Need to implement and then move a mock class. +} + NotificationEntry CreateNotificationEntry(SchedulerClientType type) { return NotificationEntry(type, base::GenerateGUID()); } @@ -103,7 +113,8 @@ std::move(notification_store), std::move(icon_store), {SchedulerClientType::kTest1, SchedulerClientType::kTest2, SchedulerClientType::kTest3}, - config_); + config_, base::BindRepeating(&NoopConvertIconToString), + base::BindRepeating(&NoopConvertStringToIcon)); } protected:
diff --git a/chrome/browser/notifications/scheduler/schedule_service_factory_helper.cc b/chrome/browser/notifications/scheduler/schedule_service_factory_helper.cc index 4da3677..07bd38d 100644 --- a/chrome/browser/notifications/scheduler/schedule_service_factory_helper.cc +++ b/chrome/browser/notifications/scheduler/schedule_service_factory_helper.cc
@@ -23,6 +23,7 @@ #include "chrome/browser/notifications/scheduler/internal/notification_store.h" #include "chrome/browser/notifications/scheduler/internal/scheduled_notification_manager.h" #include "chrome/browser/notifications/scheduler/internal/scheduler_config.h" +#include "chrome/browser/notifications/scheduler/internal/scheduler_utils.h" #include "chrome/browser/notifications/scheduler/internal/webui_client.h" #include "chrome/browser/notifications/scheduler/public/display_agent.h" #include "chrome/browser/notifications/scheduler/public/features.h" @@ -87,9 +88,16 @@ notification_store_dir, task_runner); auto notification_store = std::make_unique<NotificationStore>(std::move(notification_db)); + + auto encode_icons_callback = + base::BindRepeating(¬ifications::ConvertIconToString); + auto decode_icons_callback = + base::BindRepeating(¬ifications::ConvertStringToIcon); + auto notification_manager = ScheduledNotificationManager::Create( std::move(notification_store), std::move(icon_store), registered_clients, - *config.get()); + *config.get(), std::move(encode_icons_callback), + std::move(decode_icons_callback)); auto background_task_coordinator = BackgroundTaskCoordinator::Create( std::move(background_task_scheduler), config.get(),
diff --git a/chrome/browser/notifications/scheduler/test/mock_impression_history_tracker.h b/chrome/browser/notifications/scheduler/test/mock_impression_history_tracker.h index 46d3f32..1639112 100644 --- a/chrome/browser/notifications/scheduler/test/mock_impression_history_tracker.h +++ b/chrome/browser/notifications/scheduler/test/mock_impression_history_tracker.h
@@ -20,10 +20,15 @@ ~MockImpressionHistoryTracker() override; MOCK_METHOD2(Init, void(Delegate*, base::OnceCallback<void(bool)>)); - MOCK_METHOD2(AddImpression, void(SchedulerClientType, const std::string&)); + MOCK_METHOD4(AddImpression, + void(SchedulerClientType, + const std::string&, + const Impression::ImpressionResultMap&, + const Impression::CustomData&)); MOCK_METHOD0(AnalyzeImpressionHistory, void()); MOCK_CONST_METHOD1(GetClientStates, void(std::map<SchedulerClientType, const ClientState*>*)); + MOCK_CONST_METHOD1(GetImpression, Impression*(const std::string&)); MOCK_METHOD2(GetImpressionDetail, void(SchedulerClientType, ImpressionDetail::ImpressionDetailCallback));
diff --git a/chrome/browser/notifications/scheduler/test/test_utils.cc b/chrome/browser/notifications/scheduler/test/test_utils.cc index c33b95b..c12399d7 100644 --- a/chrome/browser/notifications/scheduler/test/test_utils.cc +++ b/chrome/browser/notifications/scheduler/test/test_utils.cc
@@ -141,6 +141,11 @@ << " : " << static_cast<int>(mapping.second); } + for (const auto& pair : impression.custom_data) { + stream << " \n custom data, key: " << pair.first + << " value: " << pair.second; + } + log += stream.str(); }
diff --git a/chrome/browser/offline_pages/android/evaluation/offline_page_evaluation_bridge.cc b/chrome/browser/offline_pages/android/evaluation/offline_page_evaluation_bridge.cc index 8c20658..5d5f5e4 100644 --- a/chrome/browser/offline_pages/android/evaluation/offline_page_evaluation_bridge.cc +++ b/chrome/browser/offline_pages/android/evaluation/offline_page_evaluation_bridge.cc
@@ -140,7 +140,7 @@ std::unique_ptr<OfflinerPolicy> policy, std::unique_ptr<Offliner> offliner) { scoped_refptr<base::SequencedTaskRunner> background_task_runner = - base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()}); + base::CreateSequencedTaskRunner({base::MayBlock()}); Profile* profile = Profile::FromBrowserContext(context); base::FilePath queue_store_path = profile->GetPath().Append(kTestRequestQueueDirname);
diff --git a/chrome/browser/offline_pages/android/offline_page_bridge.cc b/chrome/browser/offline_pages/android/offline_page_bridge.cc index f5782564..73ac4870 100644 --- a/chrome/browser/offline_pages/android/offline_page_bridge.cc +++ b/chrome/browser/offline_pages/android/offline_page_bridge.cc
@@ -776,8 +776,9 @@ } ScopedJavaGlobalRef<jobject> j_callback_ref(j_callback_obj); - base::PostTaskWithTraitsAndReplyWithResult( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, + base::PostTaskAndReplyWithResult( + FROM_HERE, + {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT}, base::Bind(&ArchiveValidator::GetSizeAndComputeDigest, file_path), base::Bind(&OfflinePageBridge::GetSizeAndComputeDigestDone, weak_ptr_factory_.GetWeakPtr(), j_callback_ref, url)); @@ -811,8 +812,9 @@ return; } - base::PostTaskWithTraitsAndReplyWithResult( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, + base::PostTaskAndReplyWithResult( + FROM_HERE, + {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT}, base::Bind(&ArchiveValidator::ValidateFile, offline_page->file_path, offline_page->file_size, offline_page->digest), base::Bind(&ValidateFileCallback, launch_location, j_callback_obj,
diff --git a/chrome/browser/offline_pages/android/offline_page_model_factory.cc b/chrome/browser/offline_pages/android/offline_page_model_factory.cc index ee62667..dffc0c0 100644 --- a/chrome/browser/offline_pages/android/offline_page_model_factory.cc +++ b/chrome/browser/offline_pages/android/offline_page_model_factory.cc
@@ -54,7 +54,7 @@ std::unique_ptr<KeyedService> OfflinePageModelFactory::BuildServiceInstanceFor( SimpleFactoryKey* key) const { scoped_refptr<base::SequencedTaskRunner> background_task_runner = - base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()}); + base::CreateSequencedTaskRunner({base::ThreadPool(), base::MayBlock()}); base::FilePath store_path = key->GetPath().Append(chrome::kOfflinePageMetadataDirname);
diff --git a/chrome/browser/offline_pages/android/request_coordinator_factory.cc b/chrome/browser/offline_pages/android/request_coordinator_factory.cc index 10f093bd..ebf0f31 100644 --- a/chrome/browser/offline_pages/android/request_coordinator_factory.cc +++ b/chrome/browser/offline_pages/android/request_coordinator_factory.cc
@@ -95,8 +95,8 @@ context, policy.get(), model, std::move(load_termination_listener))); scoped_refptr<base::SequencedTaskRunner> background_task_runner = - base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT}); + base::CreateSequencedTaskRunner({base::ThreadPool(), base::MayBlock(), + base::TaskPriority::BEST_EFFORT}); Profile* profile = Profile::FromBrowserContext(context); base::FilePath queue_store_path = profile->GetPath().Append(chrome::kOfflinePageRequestQueueDirname);
diff --git a/chrome/browser/offline_pages/offline_page_mhtml_archiver.cc b/chrome/browser/offline_pages/offline_page_mhtml_archiver.cc index d91d9ad..19ec093 100644 --- a/chrome/browser/offline_pages/offline_page_mhtml_archiver.cc +++ b/chrome/browser/offline_pages/offline_page_mhtml_archiver.cc
@@ -31,8 +31,9 @@ namespace { void DeleteFileOnFileThread(const base::FilePath& file_path, const base::Closure& callback) { - base::PostTaskWithTraitsAndReply( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, + base::PostTaskAndReply( + FROM_HERE, + {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT}, base::BindOnce(base::IgnoreResult(&base::DeleteFile), file_path, false /* recursive */), callback); @@ -44,8 +45,9 @@ void ComputeDigestOnFileThread( const base::FilePath& file_path, base::OnceCallback<void(const std::string&)> callback) { - base::PostTaskWithTraitsAndReplyWithResult( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, + base::PostTaskAndReplyWithResult( + FROM_HERE, + {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT}, base::BindOnce(&ArchiveValidator::ComputeDigest, file_path), std::move(callback)); }
diff --git a/chrome/browser/offline_pages/offline_page_request_handler.cc b/chrome/browser/offline_pages/offline_page_request_handler.cc index daf99a96..e409fe0 100644 --- a/chrome/browser/offline_pages/offline_page_request_handler.cc +++ b/chrome/browser/offline_pages/offline_page_request_handler.cc
@@ -524,7 +524,7 @@ delegate_->GetTabIdGetter(), weak_ptr_factory_.GetWeakPtr()); } else { - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {content::BrowserThread::UI}, base::BindOnce(&GetPagesToServeURL, url_, offline_header_, network_state_, delegate_->GetWebContentsGetter(), @@ -565,8 +565,8 @@ return; } - file_task_runner_ = base::CreateTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::USER_VISIBLE, + file_task_runner_ = base::CreateTaskRunner( + {base::ThreadPool(), base::MayBlock(), base::TaskPriority::USER_VISIBLE, base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}); // Start the file validation from the 1st offline page. @@ -632,7 +632,7 @@ delegate_->SetOfflinePageNavigationUIData(true /*is_offline_page*/); - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {content::BrowserThread::UI}, base::BindOnce(&VisitTrustedOfflinePageOnUI, offline_header_, network_state_, delegate_->GetWebContentsGetter(), @@ -994,9 +994,9 @@ // be called before the response is being received. Furthermore, there is // no need to clear the offline bit since the error code should already // indicate that the offline page is not loaded. - base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(&ClearOfflinePageData, - delegate_->GetWebContentsGetter())); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, + base::BindOnce(&ClearOfflinePageData, + delegate_->GetWebContentsGetter())); result = net::ERR_FAILED; }
diff --git a/chrome/browser/offline_pages/offline_page_request_handler_unittest.cc b/chrome/browser/offline_pages/offline_page_request_handler_unittest.cc index 067b590c..6cffebb 100644 --- a/chrome/browser/offline_pages/offline_page_request_handler_unittest.cc +++ b/chrome/browser/offline_pages/offline_page_request_handler_unittest.cc
@@ -594,7 +594,7 @@ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); base::RunLoop run_loop; - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {content::BrowserThread::IO}, base::BindOnce(&OfflinePageRequestHandlerTest::CreateFileWithContentOnIO, base::Unretained(this), content, run_loop.QuitClosure()));
diff --git a/chrome/browser/offline_pages/prefetch/prefetch_service_factory.cc b/chrome/browser/offline_pages/prefetch/prefetch_service_factory.cc index 1c5ed86..de3fc62e 100644 --- a/chrome/browser/offline_pages/prefetch/prefetch_service_factory.cc +++ b/chrome/browser/offline_pages/prefetch/prefetch_service_factory.cc
@@ -83,7 +83,7 @@ // https://crbug.com/944952 // Update is not a priority so make sure it happens after the critical // startup path. - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {content::BrowserThread::UI, base::TaskPriority::BEST_EFFORT}, base::BindOnce(&PrefetchServiceImpl::RefreshGCMToken, @@ -148,7 +148,7 @@ profile_key->GetPrefs()); scoped_refptr<base::SequencedTaskRunner> background_task_runner = - base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()}); + base::CreateSequencedTaskRunner({base::ThreadPool(), base::MayBlock()}); base::FilePath store_path = profile_key->GetPath().Append(chrome::kOfflinePagePrefetchStoreDirname); auto prefetch_store =
diff --git a/chrome/browser/optimization_guide/optimization_guide_hints_manager.cc b/chrome/browser/optimization_guide/optimization_guide_hints_manager.cc index 2c8d7bb..da22be7d 100644 --- a/chrome/browser/optimization_guide/optimization_guide_hints_manager.cc +++ b/chrome/browser/optimization_guide/optimization_guide_hints_manager.cc
@@ -100,7 +100,8 @@ leveldb_proto::ProtoDatabaseProvider* database_provider) : optimization_guide_service_(optimization_guide_service), background_task_runner_(base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT})), + {base::ThreadPool(), base::MayBlock(), + base::TaskPriority::BEST_EFFORT})), pref_service_(pref_service), hint_cache_(std::make_unique<optimization_guide::HintCache>( std::make_unique<optimization_guide::HintCacheStore>(
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index 418793ae..f0859b30 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -363,7 +363,7 @@ int CountPDFProcesses() { int result = -1; base::RunLoop run_loop; - base::PostTaskWithTraitsAndReply( + base::PostTaskAndReply( FROM_HERE, {content::BrowserThread::IO}, base::BindOnce(&PDFExtensionTest::CountPDFProcessesOnIOThread, base::Unretained(this), base::Unretained(&result)),
diff --git a/chrome/browser/performance_manager/graph/page_node_impl_browsertest.cc b/chrome/browser/performance_manager/graph/page_node_impl_browsertest.cc new file mode 100644 index 0000000..748c00b --- /dev/null +++ b/chrome/browser/performance_manager/graph/page_node_impl_browsertest.cc
@@ -0,0 +1,332 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/files/file_util.h" +#include "base/run_loop.h" +#include "base/strings/strcat.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" +#include "base/test/bind_test_util.h" +#include "base/threading/thread_restrictions.h" +#include "chrome/browser/performance_manager/graph/page_node_impl.h" +#include "chrome/browser/performance_manager/performance_manager.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "net/http/http_status_code.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/test/embedded_test_server/http_request.h" +#include "net/test/embedded_test_server/http_response.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace performance_manager { + +namespace { + +// Origin Trial tokens are bound to a specific origin (incl. port), so we need +// to force our test server to run on the same port that the test token has +// been generated for. +const int kServerPort = 54321; + +constexpr char kOriginTrialTestPublicKey[] = + "dRCs+TocuKkocNKa0AtZ4awrt9XKH2SQCI6o4FY6BNA="; + +// Origin Trial Token for PageLifecycleTransitionsOptOut generated with: +// $ tools/origin_trials/generate_token.py \ +// https://127.0.0.1:54321/ \ +// "PageLifecycleTransitionsOptOut" \ +// --expire-timestamp=2000000000 +// (Token will expire ca. ~2033. See content/test/data/origin_trials/basic.html) +constexpr char kOriginTrialPageLifecycleOptOutToken[] = + "Ah4aYo237SBR30bpy6p2AtxDi//nEjBJMvdRVK5XywJHT3h6AZEdfvIejN9BBTn+" + "JXWpxCBU6PcSPQct5BSZAAEAAABoeyJvcmlnaW4iOiAiaHR0cHM6Ly8xMjcuMC4wLjE6NTQzMj" + "EiLCAiZmVhdHVyZSI6ICJQYWdlTGlmZWN5Y2xlVHJhbnNpdGlvbnNPcHRPdXQiLCAiZXhwaXJ5" + "IjogMjAwMDAwMDAwMH0="; + +// Origin Trial Token for PageLifecycleTransitionsOptIn generated with: +// $ tools/origin_trials/generate_token.py \ +// https://127.0.0.1:54321/ \ +// "PageLifecycleTransitionsOptIn" \ +// --expire-timestamp=2000000000 +// (Token will expire ca. ~2033. See content/test/data/origin_trials/basic.html) +constexpr char kOriginTrialPageLifecycleOptInToken[] = + "AhTNLPzOPkxjkQoNWrLvdOBbET3ZX+OCe7k4SnkYHikPsq2aFTTKF2xVwwTZnepfn1heEK7q" + "bJu6yokw9zFjwwAAAABneyJvcmlnaW4iOiAiaHR0cHM6Ly8xMjcuMC4wLjE6NTQzMjEiLCAiZm" + "VhdHVyZSI6ICJQYWdlTGlmZWN5Y2xlVHJhbnNpdGlvbnNPcHRJbiIsICJleHBpcnkiOiAyMDAw" + "MDAwMDAwfQ=="; + +// The path used in the URL of the Page Lifecycle Origin Trial tests. +constexpr char kOriginTrialTestLifecyclePath[] = "lifecycle_origin_trial"; + +// The path used in the URL of the tests that uses 2 iFrames. +constexpr char k2iFramesPath[] = "two_iframe_tests"; + +// The page name used to set the appropriate Origin Trial tokens. +constexpr char kOriginTrialOptInPage[] = "optin.html"; +constexpr char kOriginTrialOptOutPage[] = "optout.html"; +constexpr char kOriginTrialDefaultPage[] = "default.html"; + +// Test pages that use 2 iFrames. +constexpr char kOriginTrialOptInOptOut[] = "optin_optout.html"; +constexpr char kOriginTrialOptOutOptIn[] = "optout_optin.html"; +constexpr char kOriginTrialDefaultOptIn[] = "default_optin.html"; +constexpr char kOriginTrialDefaultOptOut[] = "default_optout.html"; +constexpr char kOriginTrialOptInOptIn[] = "optin_optin.html"; +constexpr char kOriginTrialOptOutOptOut[] = "optout_optout.html"; +constexpr char kOriginTrialDefaultDefault[] = "default_default.html"; + +constexpr char kOriginTrialTestResponseTemplate[] = R"( +<html> +<head> + <title>Page Lifecycle test</title> + META_TAG +</head> +</html> +)"; + +constexpr char kTwoiFrameTestBody[] = R"( +<html> +<base href="https://127.0.0.1:54321/"> +<head> + <title>iFrame Test</title> +</head> +<iframe src="IFRAME_URL_1"></iframe> +<iframe src="IFRAME_URL_2"></iframe> +</html> +)"; + +// Generate a test response for the PageLifecycle Origin Trial tests, based on +// kOriginTrialTestResponseTemplate. +std::string GetPageLifecycleOriginTrialPageContent(const std::string& page) { + std::string token; + std::string contents = kOriginTrialTestResponseTemplate; + + // Get the appropriate Origin Trial token if needed. + if (page.compare(kOriginTrialOptInPage) == 0) { + token = kOriginTrialPageLifecycleOptInToken; + } else if (page.compare(kOriginTrialOptOutPage) == 0) { + token = kOriginTrialPageLifecycleOptOutToken; + } + + std::string meta_tag; + if (token.size()) { + meta_tag.append(base::StrCat( + {R"(<meta http-equiv="origin-trial" content=")", token, R"(">)"})); + } + base::ReplaceFirstSubstringAfterOffset(&contents, 0, "META_TAG", meta_tag); + return contents; +} + +std::string GetPageLifecycleOriginTrialiFramePageContent( + const std::string& page) { + std::string contents = kTwoiFrameTestBody; + std::string url1 = base::StrCat({kOriginTrialTestLifecyclePath, "/"}); + std::string url2 = base::StrCat({kOriginTrialTestLifecyclePath, "/"}); + + std::string page_base_path = base::SplitString( + page, ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY)[0]; + auto parts = base::SplitString(page_base_path, "_", base::KEEP_WHITESPACE, + base::SPLIT_WANT_NONEMPTY); + EXPECT_EQ(2U, parts.size()); + url1 += parts[0] + ".html"; + url2 += parts[1] + ".html"; + + base::ReplaceFirstSubstringAfterOffset(&contents, 0, "IFRAME_URL_1", url1); + base::ReplaceFirstSubstringAfterOffset(&contents, 0, "IFRAME_URL_2", url2); + return contents; +} + +// Request handler for these tests, redirect the query to the appropriate +// handler. Return 404 for all paths not ending in ".html". +std::unique_ptr<net::test_server::HttpResponse> RequestHandler( + const net::test_server::HttpRequest& request) { + std::unique_ptr<net::test_server::BasicHttpResponse> response = + std::make_unique<net::test_server::BasicHttpResponse>(); + std::string url = request.GetURL().path(); + if (!base::EndsWith(url, ".html", base::CompareCase::SENSITIVE)) { + response->set_code(net::HTTP_NOT_FOUND); + return response; + } + + auto url_parts = base::SplitString(url, "/", base::KEEP_WHITESPACE, + base::SPLIT_WANT_NONEMPTY); + // The URL should be composed of 2 parts, the base directory indicates the + // kind of response to serve and the filename is passed to the function that + // generates the response to serve the appropriate content. + EXPECT_EQ(2U, url_parts.size()); + + if (url_parts[0].compare(kOriginTrialTestLifecyclePath) == 0) { + response->set_content(GetPageLifecycleOriginTrialPageContent(url_parts[1])); + } else if (url_parts[0].compare(k2iFramesPath) == 0) { + response->set_content( + GetPageLifecycleOriginTrialiFramePageContent(url_parts[1])); + } + + response->set_content_type("text/html"); + response->set_code(net::HTTP_OK); + return response; +} + +void RunOriginTrialTestOnPMSequence( + const resource_coordinator::mojom::InterventionPolicy expected_policy) { + auto* perf_manager = PerformanceManager::GetInstance(); + ASSERT_TRUE(perf_manager); + base::RunLoop run_loop; + perf_manager->CallOnGraph( + FROM_HERE, + base::BindOnce( + [](base::OnceClosure quit_closure, + const resource_coordinator::mojom::InterventionPolicy + expected_policy, + performance_manager::GraphImpl* graph) { + auto page_nodes = graph->GetAllPageNodeImpls(); + EXPECT_EQ(1U, page_nodes.size()); + auto policy = page_nodes[0]->GetInterventionPolicy( + resource_coordinator::mojom::PolicyControlledIntervention:: + kPageLifecycleTransitions); + EXPECT_EQ(expected_policy, policy); + std::move(quit_closure).Run(); + }, + run_loop.QuitClosure(), expected_policy)); + run_loop.Run(); +} + +} // namespace + +class PageNodeImplBrowserTest : public InProcessBrowserTest { + public: + PageNodeImplBrowserTest() = default; + ~PageNodeImplBrowserTest() override = default; + + void SetUpDefaultCommandLine(base::CommandLine* command_line) override { + InProcessBrowserTest::SetUpDefaultCommandLine(command_line); + command_line->AppendSwitchASCII(switches::kOriginTrialPublicKey, + kOriginTrialTestPublicKey); + } + + void SetUpInProcessBrowserTestFixture() override { + server_ = std::make_unique<net::test_server::EmbeddedTestServer>( + net::test_server::EmbeddedTestServer::TYPE_HTTPS); + server_->RegisterRequestHandler(base::Bind(&RequestHandler)); + EXPECT_TRUE(server_->Start(kServerPort)); + } + + net::test_server::EmbeddedTestServer* server() { return server_.get(); } + + private: + std::unique_ptr<net::test_server::EmbeddedTestServer> server_; + + DISALLOW_COPY_AND_ASSIGN(PageNodeImplBrowserTest); +}; + +IN_PROC_BROWSER_TEST_F(PageNodeImplBrowserTest, PageLifecycleOriginTrialOptIn) { + ui_test_utils::NavigateToURL( + browser(), + server()->GetURL("/" + base::JoinString({kOriginTrialTestLifecyclePath, + kOriginTrialOptInPage}, + "/"))); + RunOriginTrialTestOnPMSequence( + resource_coordinator::mojom::InterventionPolicy::kOptIn); +} + +IN_PROC_BROWSER_TEST_F(PageNodeImplBrowserTest, + PageLifecycleOriginTrialOptOut) { + ui_test_utils::NavigateToURL( + browser(), + server()->GetURL("/" + base::JoinString({kOriginTrialTestLifecyclePath, + kOriginTrialOptOutPage}, + "/"))); + RunOriginTrialTestOnPMSequence( + resource_coordinator::mojom::InterventionPolicy::kOptOut); +} + +IN_PROC_BROWSER_TEST_F(PageNodeImplBrowserTest, + PageLifecycleOriginTrialDefault) { + ui_test_utils::NavigateToURL( + browser(), + server()->GetURL("/" + base::JoinString({kOriginTrialTestLifecyclePath, + kOriginTrialDefaultPage}, + "/"))); + RunOriginTrialTestOnPMSequence( + resource_coordinator::mojom::InterventionPolicy::kDefault); +} + +IN_PROC_BROWSER_TEST_F(PageNodeImplBrowserTest, + PageLifecycleOriginTrialOptInOptOut) { + ui_test_utils::NavigateToURL( + browser(), server()->GetURL( + "/" + base::JoinString( + {k2iFramesPath, kOriginTrialOptInOptOut}, "/"))); + RunOriginTrialTestOnPMSequence( + resource_coordinator::mojom::InterventionPolicy::kOptOut); +} + +IN_PROC_BROWSER_TEST_F(PageNodeImplBrowserTest, + PageLifecycleOriginTrialOptOutOptIn) { + ui_test_utils::NavigateToURL( + browser(), server()->GetURL( + "/" + base::JoinString( + {k2iFramesPath, kOriginTrialOptOutOptIn}, "/"))); + RunOriginTrialTestOnPMSequence( + resource_coordinator::mojom::InterventionPolicy::kOptOut); +} + +IN_PROC_BROWSER_TEST_F(PageNodeImplBrowserTest, + PageLifecycleOriginTrialDefaultOptIn) { + ui_test_utils::NavigateToURL( + browser(), + server()->GetURL( + "/" + + base::JoinString({k2iFramesPath, kOriginTrialDefaultOptIn}, "/"))); + RunOriginTrialTestOnPMSequence( + resource_coordinator::mojom::InterventionPolicy::kOptIn); +} + +IN_PROC_BROWSER_TEST_F(PageNodeImplBrowserTest, + PageLifecycleOriginTrialDefaultOptOut) { + ui_test_utils::NavigateToURL( + browser(), + server()->GetURL( + "/" + + base::JoinString({k2iFramesPath, kOriginTrialDefaultOptOut}, "/"))); + RunOriginTrialTestOnPMSequence( + resource_coordinator::mojom::InterventionPolicy::kOptOut); +} + +IN_PROC_BROWSER_TEST_F(PageNodeImplBrowserTest, + PageLifecycleOriginTrialOptInOptIn) { + ui_test_utils::NavigateToURL( + browser(), server()->GetURL( + "/" + base::JoinString( + {k2iFramesPath, kOriginTrialOptInOptIn}, "/"))); + RunOriginTrialTestOnPMSequence( + resource_coordinator::mojom::InterventionPolicy::kOptIn); +} + +IN_PROC_BROWSER_TEST_F(PageNodeImplBrowserTest, + PageLifecycleOriginTrialOptOutOptOut) { + ui_test_utils::NavigateToURL( + browser(), + server()->GetURL( + "/" + + base::JoinString({k2iFramesPath, kOriginTrialOptOutOptOut}, "/"))); + RunOriginTrialTestOnPMSequence( + resource_coordinator::mojom::InterventionPolicy::kOptOut); +} + +IN_PROC_BROWSER_TEST_F(PageNodeImplBrowserTest, + PageLifecycleOriginTrialDefaultDefault) { + ui_test_utils::NavigateToURL( + browser(), + server()->GetURL( + "/" + + base::JoinString({k2iFramesPath, kOriginTrialDefaultDefault}, "/"))); + RunOriginTrialTestOnPMSequence( + resource_coordinator::mojom::InterventionPolicy::kDefault); +} + +// TODO(sebmarchand): Add more tests, e.g. a test where the main frame and a +// subframe set a different policy. + +} // namespace performance_manager
diff --git a/chrome/browser/performance_manager/graph/system_node_impl.cc b/chrome/browser/performance_manager/graph/system_node_impl.cc index b73f763..4928df0 100644 --- a/chrome/browser/performance_manager/graph/system_node_impl.cc +++ b/chrome/browser/performance_manager/graph/system_node_impl.cc
@@ -18,144 +18,10 @@ namespace performance_manager { -ProcessResourceMeasurement::ProcessResourceMeasurement() = default; -ProcessResourceMeasurementBatch::ProcessResourceMeasurementBatch() = default; -ProcessResourceMeasurementBatch::~ProcessResourceMeasurementBatch() = default; - SystemNodeImpl::SystemNodeImpl(GraphImpl* graph) : TypedNodeBase(graph) {} SystemNodeImpl::~SystemNodeImpl() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); } -void SystemNodeImpl::DistributeMeasurementBatch( - std::unique_ptr<ProcessResourceMeasurementBatch> measurement_batch) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - base::TimeDelta time_since_last_measurement; - if (!last_measurement_end_time_.is_null()) { - // Use the end of the measurement batch as a proxy for when every - // measurement was acquired. For the purpose of estimating CPU usage - // over the duration from last measurement, it'll be near enough. The error - // will average out, and there's an inherent race in knowing when a - // measurement was actually acquired in any case. - time_since_last_measurement = - measurement_batch->batch_ended_time - last_measurement_end_time_; - DCHECK_LE(base::TimeDelta(), time_since_last_measurement); - } - - // TODO(siggi): Need to decide what to do with measurements that span an - // absurd length of time, or which are missing a significant portion of the - // data wanted/required. Maybe there should be a filtering step here, or - // perhaps this should be up to the consumers, who can perhaps better - // assess whether the gaps affect them. This would require propagating more - // information through the graph. Perhaps each page could maintain the - // min/max span for all the data that went into the current estimates. - last_measurement_start_time_ = measurement_batch->batch_started_time; - last_measurement_end_time_ = measurement_batch->batch_ended_time; - - // Keep track of the pages updated with CPU cost for the second pass, - // where their memory usage is updated. - base::flat_set<PageNodeImpl*> pages; - std::vector<ProcessNodeImpl*> found_processes; - for (const auto& measurement : measurement_batch->measurements) { - ProcessNodeImpl* process = graph()->GetProcessNodeByPid(measurement.pid); - if (process) { - base::TimeDelta cumulative_cpu_delta = - measurement.cpu_usage - process->cumulative_cpu_usage(); - DCHECK_LE(base::TimeDelta(), cumulative_cpu_delta); - - // Distribute the CPU delta to the pages that own the frames in this - // process. - const auto& frames = process->frame_nodes(); - if (!frames.empty()) { - // To make sure we don't systemically truncate the remainder of the - // delta, simply subtract the remainder and "hold it back" from the - // measurement. Since our measurement is cumulative, we'll see that - // CPU time again in the next measurement. - cumulative_cpu_delta -= - cumulative_cpu_delta % - base::TimeDelta::FromMicroseconds(frames.size()); - - for (FrameNodeImpl* frame : frames) { - PageNodeImpl* page = frame->page_node(); - if (page) { - page->set_usage_estimate_time(last_measurement_end_time_); - page->set_cumulative_cpu_usage_estimate( - page->cumulative_cpu_usage_estimate() + - cumulative_cpu_delta / frames.size()); - - pages.insert(page); - } - } - } else { - // TODO(siggi): The process has zero frames, maybe this is a newly - // started renderer and if so, this might be a good place to - // estimate the process overhead. Alternatively perhaps the first - // measurement for each process, or a lower bound thereof will - // converge to a decent estimate. - } - - if (process->cumulative_cpu_usage().is_zero() || - time_since_last_measurement.is_zero()) { - // Imitate the behavior of GetPlatformIndependentCPUUsage, which - // yields zero for the initial measurement of each process. - process->SetCPUUsage(0); - } else { - double cpu_usage = 100.0 * cumulative_cpu_delta.InMicrosecondsF() / - time_since_last_measurement.InMicrosecondsF(); - process->SetCPUUsage(cpu_usage); - } - process->set_cumulative_cpu_usage(process->cumulative_cpu_usage() + - cumulative_cpu_delta); - process->set_private_footprint_kb(measurement.private_footprint_kb); - - // Note the found processes. - found_processes.push_back(process); - } - } - - // Grab all the processes to see if there were any we didn't get data for. - std::vector<ProcessNodeImpl*> processes = graph_->GetAllProcessNodeImpls(); - - if (found_processes.size() != processes.size()) { - // We didn't find them all, compute the difference and clear the data for - // the processes we didn't find. - std::sort(processes.begin(), processes.end()); - std::sort(found_processes.begin(), found_processes.end()); - std::vector<ProcessNodeImpl*> not_found_processes; - std::set_difference( - processes.begin(), processes.end(), found_processes.begin(), - found_processes.end(), - std::inserter(not_found_processes, not_found_processes.begin())); - - // Clear processes we didn't get data for. - for (ProcessNodeImpl* process : not_found_processes) { - process->SetCPUUsage(0.0); - process->set_private_footprint_kb(0); - } - } - - // Iterate through the pages involved to distribute the memory to them. - for (PageNodeImpl* page : pages) { - uint64_t private_footprint_kb_sum = 0; - auto frames = GraphImplOperations::GetFrameNodes(page); - for (FrameNodeImpl* frame : frames) { - ProcessNodeImpl* process = frame->process_node(); - if (process) { - private_footprint_kb_sum += - process->private_footprint_kb() / process->frame_nodes().size(); - } - } - - page->set_private_footprint_kb_estimate(private_footprint_kb_sum); - - DCHECK_EQ(last_measurement_end_time_, page->usage_estimate_time()); - } - - for (auto& observer : observers()) - observer.OnProcessCPUUsageReady(this); - for (auto* observer : GetObservers()) - observer->OnProcessCPUUsageReady(this); -} - } // namespace performance_manager
diff --git a/chrome/browser/performance_manager/graph/system_node_impl.h b/chrome/browser/performance_manager/graph/system_node_impl.h index 8bba25d..cc422cc1 100644 --- a/chrome/browser/performance_manager/graph/system_node_impl.h +++ b/chrome/browser/performance_manager/graph/system_node_impl.h
@@ -18,35 +18,6 @@ namespace performance_manager { -// TODO(siggi): In the end game, this should be private implementation detail -// of the performance measurement graph decorator. It's here for now because -// there's still a thread hop to get the measurement results into the graph. -struct ProcessResourceMeasurement { - ProcessResourceMeasurement(); - - // Identifies the process associated with this measurement. - base::ProcessId pid; - - // The cumulative CPU usage accrued to this process from its start. - base::TimeDelta cpu_usage; - - // The private memory footprint of the process. - uint32_t private_footprint_kb = 0; -}; - -struct ProcessResourceMeasurementBatch { - ProcessResourceMeasurementBatch(); - ~ProcessResourceMeasurementBatch(); - - // These times bracket the capture of the entire dump, e.g. each distinct - // measurement is captured somewhere between |batch_started_time| and - // |batch_ended_time|. - base::TimeTicks batch_started_time; - base::TimeTicks batch_ended_time; - - std::vector<ProcessResourceMeasurement> measurements; -}; - class SystemNodeImpl : public PublicNodeImpl<SystemNodeImpl, SystemNode>, public TypedNodeBase<SystemNodeImpl, GraphImplObserver, @@ -58,22 +29,7 @@ explicit SystemNodeImpl(GraphImpl* graph); ~SystemNodeImpl() override; - void DistributeMeasurementBatch( - std::unique_ptr<ProcessResourceMeasurementBatch> measurement_batch); - - // Accessors for the start/end times bracketing when the last performance - // measurement occurred. - base::TimeTicks last_measurement_start_time() const { - return last_measurement_start_time_; - } - base::TimeTicks last_measurement_end_time() const { - return last_measurement_end_time_; - } - private: - base::TimeTicks last_measurement_start_time_; - base::TimeTicks last_measurement_end_time_; - DISALLOW_COPY_AND_ASSIGN(SystemNodeImpl); };
diff --git a/chrome/browser/performance_manager/graph/system_node_impl_unittest.cc b/chrome/browser/performance_manager/graph/system_node_impl_unittest.cc index fbbd4d8a..48b7062d 100644 --- a/chrome/browser/performance_manager/graph/system_node_impl_unittest.cc +++ b/chrome/browser/performance_manager/graph/system_node_impl_unittest.cc
@@ -23,10 +23,6 @@ // Observer used to make sure that signals are dispatched correctly. class SystemObserver : public SystemNodeImpl::ObserverDefaultImpl { public: - void OnProcessCPUUsageReady(const SystemNode* system_node) override { - ++system_event_seen_count_; - } - size_t system_event_seen_count() const { return system_event_seen_count_; } private: @@ -51,28 +47,6 @@ base::SimpleTestTickClock clock_; }; -std::unique_ptr<ProcessResourceMeasurementBatch> CreateMeasurementBatch( - base::TimeTicks start_end_time, - size_t num_processes, - base::TimeDelta additional_cpu_time) { - std::unique_ptr<ProcessResourceMeasurementBatch> batch = - std::make_unique<ProcessResourceMeasurementBatch>(); - batch->batch_started_time = start_end_time; - batch->batch_ended_time = start_end_time; - - for (size_t i = 1; i <= num_processes; ++i) { - ProcessResourceMeasurement measurement; - measurement.pid = i; - measurement.cpu_usage = - base::TimeDelta::FromMicroseconds(i * 10) + additional_cpu_time; - measurement.private_footprint_kb = static_cast<uint32_t>(i * 100); - - batch->measurements.push_back(measurement); - } - - return batch; -} - } // namespace TEST_F(SystemNodeImplTest, SafeDowncast) { @@ -85,89 +59,6 @@ EXPECT_EQ(static_cast<Node*>(node), base->ToNode()); } -TEST_F(SystemNodeImplTest, DistributeMeasurementBatch) { - SystemObserver observer; - MockMultiplePagesWithMultipleProcessesGraph mock_graph(graph()); - graph()->AddSystemNodeObserver(&observer); - - EXPECT_EQ(0u, observer.system_event_seen_count()); - - // Build and dispatch a measurement batch. - base::TimeTicks start_time = base::TimeTicks::Now(); - mock_graph.system->DistributeMeasurementBatch( - CreateMeasurementBatch(start_time, 3, base::TimeDelta())); - - EXPECT_EQ(start_time, mock_graph.system->last_measurement_start_time()); - EXPECT_EQ(start_time, mock_graph.system->last_measurement_end_time()); - - EXPECT_EQ(1u, observer.system_event_seen_count()); - - // The first measurement batch results in a zero CPU usage for the processes. - EXPECT_EQ(0, mock_graph.process->cpu_usage()); - EXPECT_EQ(100u, mock_graph.process->private_footprint_kb()); - EXPECT_EQ(base::TimeDelta::FromMicroseconds(10u), - mock_graph.process->cumulative_cpu_usage()); - - EXPECT_EQ(0, mock_graph.process->cpu_usage()); - EXPECT_EQ(200u, mock_graph.other_process->private_footprint_kb()); - EXPECT_EQ(base::TimeDelta::FromMicroseconds(20u), - mock_graph.other_process->cumulative_cpu_usage()); - - EXPECT_EQ(base::TimeDelta::FromMicroseconds(5), - mock_graph.page->cumulative_cpu_usage_estimate()); - EXPECT_EQ(50u, mock_graph.page->private_footprint_kb_estimate()); - - EXPECT_EQ(base::TimeDelta::FromMicroseconds(25), - mock_graph.other_page->cumulative_cpu_usage_estimate()); - EXPECT_EQ(250u, mock_graph.other_page->private_footprint_kb_estimate()); - - // Dispatch another batch, and verify the CPUUsage is appropriately updated. - mock_graph.system->DistributeMeasurementBatch( - CreateMeasurementBatch(start_time + base::TimeDelta::FromMicroseconds(10), - 3, base::TimeDelta::FromMicroseconds(10))); - EXPECT_EQ(100, mock_graph.process->cpu_usage()); - EXPECT_EQ(base::TimeDelta::FromMicroseconds(20u), - mock_graph.process->cumulative_cpu_usage()); - EXPECT_EQ(100, mock_graph.process->cpu_usage()); - EXPECT_EQ(base::TimeDelta::FromMicroseconds(30u), - mock_graph.other_process->cumulative_cpu_usage()); - - EXPECT_EQ(base::TimeDelta::FromMicroseconds(10), - mock_graph.page->cumulative_cpu_usage_estimate()); - EXPECT_EQ(50u, mock_graph.page->private_footprint_kb_estimate()); - - EXPECT_EQ(base::TimeDelta::FromMicroseconds(40), - mock_graph.other_page->cumulative_cpu_usage_estimate()); - EXPECT_EQ(250u, mock_graph.other_page->private_footprint_kb_estimate()); - - // Now test that a measurement batch that leaves out a process clears the - // properties of that process - except for cumulative CPU, which can only - // go forwards. - mock_graph.system->DistributeMeasurementBatch( - CreateMeasurementBatch(start_time + base::TimeDelta::FromMicroseconds(20), - 1, base::TimeDelta::FromMicroseconds(310))); - - EXPECT_EQ(3000, mock_graph.process->cpu_usage()); - EXPECT_EQ(100u, mock_graph.process->private_footprint_kb()); - EXPECT_EQ(base::TimeDelta::FromMicroseconds(320u), - mock_graph.process->cumulative_cpu_usage()); - - EXPECT_EQ(3000, mock_graph.process->cpu_usage()); - EXPECT_EQ(0u, mock_graph.other_process->private_footprint_kb()); - EXPECT_EQ(base::TimeDelta::FromMicroseconds(30u), - mock_graph.other_process->cumulative_cpu_usage()); - - EXPECT_EQ(base::TimeDelta::FromMicroseconds(160), - mock_graph.page->cumulative_cpu_usage_estimate()); - EXPECT_EQ(50u, mock_graph.page->private_footprint_kb_estimate()); - - EXPECT_EQ(base::TimeDelta::FromMicroseconds(190), - mock_graph.other_page->cumulative_cpu_usage_estimate()); - EXPECT_EQ(50u, mock_graph.other_page->private_footprint_kb_estimate()); - - graph()->RemoveSystemNodeObserver(&observer); -} - namespace { class LenientMockObserver : public SystemNodeImpl::Observer { @@ -177,7 +68,6 @@ MOCK_METHOD1(OnSystemNodeAdded, void(const SystemNode*)); MOCK_METHOD1(OnBeforeSystemNodeRemoved, void(const SystemNode*)); - MOCK_METHOD1(OnProcessCPUUsageReady, void(const SystemNode*)); void SetNotifiedSystemNode(const SystemNode* system_node) { notified_system_node_ = system_node;
diff --git a/chrome/browser/performance_manager/public/graph/system_node.h b/chrome/browser/performance_manager/public/graph/system_node.h index 218f8a2..7558793 100644 --- a/chrome/browser/performance_manager/public/graph/system_node.h +++ b/chrome/browser/performance_manager/public/graph/system_node.h
@@ -41,13 +41,6 @@ // Called before the |system_node| is removed from the graph. virtual void OnBeforeSystemNodeRemoved(const SystemNode* system_node) = 0; - // Events with no property changes. - - // Fired when a batch of consistent process CPU measurements is available on - // the graph. - // TODO(siggi): Deprecate this as the CPU measurement code is reworked. - virtual void OnProcessCPUUsageReady(const SystemNode* system_node) = 0; - private: DISALLOW_COPY_AND_ASSIGN(SystemNodeObserver); }; @@ -63,7 +56,6 @@ // SystemNodeObserver implementation: void OnSystemNodeAdded(const SystemNode* system_node) override {} void OnBeforeSystemNodeRemoved(const SystemNode* system_node) override {} - void OnProcessCPUUsageReady(const SystemNode* system_node) override {} private: DISALLOW_COPY_AND_ASSIGN(ObserverDefaultImpl);
diff --git a/chrome/browser/performance_monitor/metric_evaluator_helper_win.cc b/chrome/browser/performance_monitor/metric_evaluator_helper_win.cc index ad0fe83..7646160 100644 --- a/chrome/browser/performance_monitor/metric_evaluator_helper_win.cc +++ b/chrome/browser/performance_monitor/metric_evaluator_helper_win.cc
@@ -24,8 +24,9 @@ } // namespace MetricEvaluatorsHelperWin::MetricEvaluatorsHelperWin() - : wmi_initialization_sequence_(base::CreateSequencedTaskRunnerWithTraits( - {base::TaskPriority::BEST_EFFORT, base::MayBlock(), + : wmi_initialization_sequence_(base::CreateSequencedTaskRunner( + {base::ThreadPool(), base::TaskPriority::BEST_EFFORT, + base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})), wmi_refresher_(new win::WMIRefresher(), base::OnTaskRunnerDeleter(wmi_initialization_sequence_)),
diff --git a/chrome/browser/performance_monitor/process_monitor.cc b/chrome/browser/performance_monitor/process_monitor.cc index 42df9d4..994722b 100644 --- a/chrome/browser/performance_monitor/process_monitor.cc +++ b/chrome/browser/performance_monitor/process_monitor.cc
@@ -110,7 +110,7 @@ MarkProcessAsAlive(data, current_update_sequence); } - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::IO}, base::BindOnce(&ProcessMonitor::GatherMetricsMapOnIOThread, base::Unretained(this), current_update_sequence)); @@ -167,7 +167,7 @@ browser_process_data.handle = base::GetCurrentProcessHandle(); process_data_list->push_back(browser_process_data); - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce(&ProcessMonitor::MarkProcessesAsAliveOnUIThread, base::Unretained(this), std::move(process_data_list), @@ -181,7 +181,7 @@ for (const ProcessMetricsMetadata& data : *process_data_list) MarkProcessAsAlive(data, current_update_sequence); - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::IO}, base::BindOnce(&ProcessMonitor::UpdateMetricsOnIOThread, base::Unretained(this), current_update_sequence)); @@ -202,9 +202,9 @@ } } - base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&ProcessMonitor::RunTriggersUIThread, - base::Unretained(this))); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(&ProcessMonitor::RunTriggersUIThread, + base::Unretained(this))); } void ProcessMonitor::RunTriggersUIThread() {
diff --git a/chrome/browser/performance_monitor/system_monitor.cc b/chrome/browser/performance_monitor/system_monitor.cc index 2b9b5de1..0d7e77c 100644 --- a/chrome/browser/performance_monitor/system_monitor.cc +++ b/chrome/browser/performance_monitor/system_monitor.cc
@@ -41,8 +41,8 @@ SystemMonitor::SystemMonitor( std::unique_ptr<MetricEvaluatorsHelper> metric_evaluators_helper) - : blocking_task_runner_(base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), + : blocking_task_runner_(base::CreateSequencedTaskRunner( + {base::ThreadPool(), base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})), metric_evaluators_helper_( metric_evaluators_helper.release(),
diff --git a/chrome/browser/plugins/pdf_iframe_navigation_throttle.cc b/chrome/browser/plugins/pdf_iframe_navigation_throttle.cc index b9d1c2d..2c66cd4 100644 --- a/chrome/browser/plugins/pdf_iframe_navigation_throttle.cc +++ b/chrome/browser/plugins/pdf_iframe_navigation_throttle.cc
@@ -174,7 +174,7 @@ PdfWebContentsLifetimeHelper::CreateForWebContents(web_contents); PdfWebContentsLifetimeHelper* helper = PdfWebContentsLifetimeHelper::FromWebContents(web_contents); - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {content::BrowserThread::UI}, base::BindOnce(&PdfWebContentsLifetimeHelper::NavigateIFrameToPlaceholder, helper->GetWeakPtr(), params));
diff --git a/chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.cc b/chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.cc index dea4b42..233f86c0 100644 --- a/chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.cc +++ b/chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.cc
@@ -105,7 +105,7 @@ bool embedded = resource_type_ != static_cast<int>(content::ResourceType::kMainFrame); - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {content::BrowserThread::UI}, base::BindOnce( &extensions::StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent,
diff --git a/chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle_browsertest.cc b/chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle_browsertest.cc index 6a30bdc..1562509 100644 --- a/chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle_browsertest.cc +++ b/chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle_browsertest.cc
@@ -50,7 +50,7 @@ int CountPDFProcesses() { int result = -1; base::RunLoop run_loop; - base::PostTaskWithTraitsAndReply( + base::PostTaskAndReply( FROM_HERE, {content::BrowserThread::IO}, base::BindOnce(&PluginResponseInterceptorURLLoaderThrottleBrowserTest:: CountPDFProcessesOnIOThread,
diff --git a/chrome/browser/policy/browser_dm_token_storage_linux.cc b/chrome/browser/policy/browser_dm_token_storage_linux.cc index 5611dff..394da39 100644 --- a/chrome/browser/policy/browser_dm_token_storage_linux.cc +++ b/chrome/browser/policy/browser_dm_token_storage_linux.cc
@@ -169,8 +169,8 @@ void BrowserDMTokenStorageLinux::SaveDMToken(const std::string& token) { std::string client_id = RetrieveClientId(); - base::PostTaskWithTraitsAndReplyWithResult( - FROM_HERE, {base::MayBlock()}, + base::PostTaskAndReplyWithResult( + FROM_HERE, {base::ThreadPool(), base::MayBlock()}, base::BindOnce(&StoreDMTokenInUserDataDir, token, client_id), base::BindOnce(&BrowserDMTokenStorage::OnDMTokenStored, weak_factory_.GetWeakPtr()));
diff --git a/chrome/browser/policy/browser_dm_token_storage_mac.mm b/chrome/browser/policy/browser_dm_token_storage_mac.mm index 00a19a080..a5bf7aa 100644 --- a/chrome/browser/policy/browser_dm_token_storage_mac.mm +++ b/chrome/browser/policy/browser_dm_token_storage_mac.mm
@@ -233,8 +233,8 @@ void BrowserDMTokenStorageMac::SaveDMToken(const std::string& token) { std::string client_id = RetrieveClientId(); - base::PostTaskWithTraitsAndReplyWithResult( - FROM_HERE, {base::MayBlock()}, + base::PostTaskAndReplyWithResult( + FROM_HERE, {base::ThreadPool(), base::MayBlock()}, base::BindOnce(&StoreDMTokenInDirAppDataDir, token, client_id), base::BindOnce(&BrowserDMTokenStorage::OnDMTokenStored, weak_factory_.GetWeakPtr()));
diff --git a/chrome/browser/policy/browser_dm_token_storage_win.cc b/chrome/browser/policy/browser_dm_token_storage_win.cc index 0e43843..5f74cf3 100644 --- a/chrome/browser/policy/browser_dm_token_storage_win.cc +++ b/chrome/browser/policy/browser_dm_token_storage_win.cc
@@ -213,7 +213,7 @@ BrowserDMTokenStorageWin::BrowserDMTokenStorageWin() : com_sta_task_runner_( - base::CreateCOMSTATaskRunnerWithTraits({base::MayBlock()})), + base::CreateCOMSTATaskRunner({base::ThreadPool(), base::MayBlock()})), weak_factory_(this) {} BrowserDMTokenStorageWin::~BrowserDMTokenStorageWin() {}
diff --git a/chrome/browser/policy/chrome_browser_policy_connector.cc b/chrome/browser/policy/chrome_browser_policy_connector.cc index 7bd4917b..68b637c8 100644 --- a/chrome/browser/policy/chrome_browser_policy_connector.cc +++ b/chrome/browser/policy/chrome_browser_policy_connector.cc
@@ -171,8 +171,8 @@ ChromeBrowserPolicyConnector::CreatePlatformProvider() { #if defined(OS_WIN) std::unique_ptr<AsyncPolicyLoader> loader(PolicyLoaderWin::Create( - base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT}), + base::CreateSequencedTaskRunner({base::ThreadPool(), base::MayBlock(), + base::TaskPriority::BEST_EFFORT}), kRegistryChromePolicyKey)); return std::make_unique<AsyncPolicyProvider>(GetSchemaRegistry(), std::move(loader)); @@ -187,8 +187,8 @@ base::SysUTF8ToCFStringRef(base::mac::BaseBundleID())); #endif auto loader = std::make_unique<PolicyLoaderMac>( - base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT}), + base::CreateSequencedTaskRunner({base::ThreadPool(), base::MayBlock(), + base::TaskPriority::BEST_EFFORT}), policy::PolicyLoaderMac::GetManagedPolicyPath(bundle_id), new MacPreferences(), bundle_id); return std::make_unique<AsyncPolicyProvider>(GetSchemaRegistry(), @@ -197,8 +197,8 @@ base::FilePath config_dir_path; if (base::PathService::Get(chrome::DIR_POLICY_FILES, &config_dir_path)) { std::unique_ptr<AsyncPolicyLoader> loader(new ConfigDirPolicyLoader( - base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT}), + base::CreateSequencedTaskRunner({base::ThreadPool(), base::MayBlock(), + base::TaskPriority::BEST_EFFORT}), config_dir_path, POLICY_SCOPE_MACHINE)); return std::make_unique<AsyncPolicyProvider>(GetSchemaRegistry(), std::move(loader));
diff --git a/chrome/browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc b/chrome/browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc index 092feec..4a082b6c 100644 --- a/chrome/browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc +++ b/chrome/browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc
@@ -388,8 +388,9 @@ MachineLevelUserCloudPolicyStore::Create( dm_token, client_id, user_data_dir, /*cloud_policy_overrides=*/false, - base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT})); + base::CreateSequencedTaskRunner({base::ThreadPool(), + base::MayBlock(), + base::TaskPriority::BEST_EFFORT})); policy_store->AddObserver(&observer); base::FilePath policy_dir =
diff --git a/chrome/browser/policy/e2e_test/tests/__init__.py b/chrome/browser/policy/e2e_test/tests/__init__.py index 4f36ec5d..2fc8628e 100644 --- a/chrome/browser/policy/e2e_test/tests/__init__.py +++ b/chrome/browser/policy/e2e_test/tests/__init__.py
@@ -14,10 +14,8 @@ from password_manager_enabled.password_manager_enabled import * from popups_allowed.popups_allowed import * from restore_on_startup.restore_on_startup import * +from translate_enabled.translate_enabled import * from url_blacklist.url_blacklist import * from url_whitelist.url_whitelist import * from user_data_dir.user_data_dir import * from youtube_restrict.youtube_restrict import * - -# TODO(mbinette): Fix TranslateEnabledTest on LUCI bots. -# from translate_enabled.translate_enabled import *
diff --git a/chrome/browser/policy/e2e_test/tests/translate_enabled/translate_enabled.py b/chrome/browser/policy/e2e_test/tests/translate_enabled/translate_enabled.py index db909cb..270e3bc 100644 --- a/chrome/browser/policy/e2e_test/tests/translate_enabled/translate_enabled.py +++ b/chrome/browser/policy/e2e_test/tests/translate_enabled/translate_enabled.py
@@ -17,13 +17,14 @@ @before_all def setup(self): self.InstallChrome('client2012') - self.InstallWebDriver('client2012') + self.EnableUITest('client2012') def isChromeTranslateEnabled(self, incognito=False): dir = os.path.dirname(os.path.abspath(__file__)) - output = self.RunWebDriverTest( - 'client2012', os.path.join(dir, 'translate_enabled_webdriver_test.py'), - ['--incognito'] if incognito else []) + output = self.RunUITest( + 'client2012', + os.path.join(dir, 'translate_enabled_webdriver_test.py'), + args=['--incognito'] if incognito else []) return "TRUE" in output @test
diff --git a/chrome/browser/policy/e2e_test/tests/translate_enabled/translate_enabled_webdriver_test.py b/chrome/browser/policy/e2e_test/tests/translate_enabled/translate_enabled_webdriver_test.py index a31e780..aec81fd1 100644 --- a/chrome/browser/policy/e2e_test/tests/translate_enabled/translate_enabled_webdriver_test.py +++ b/chrome/browser/policy/e2e_test/tests/translate_enabled/translate_enabled_webdriver_test.py
@@ -5,23 +5,13 @@ import time import test_util from absl import app, flags +from pywinauto.application import Application from selenium import webdriver from selenium.webdriver.chrome.options import Options -# A URL that is in a different language than our Chrome language. It should be -# a site stable enough for us to rely on for our tests, and have a somewhat -# static string we can use to tell if translate worked (see below). +# A URL that is in a different language than our Chrome language. URL = "https://zh.wikipedia.org/wiki/Chromium" -# The magic string to look for on the translated page. -# This string must NOT be on the original page. -MAGIC_STRING_ENGLISH = "Wikipedia, the free encyclopedia" - -# We automatically accept Translate prompts from Chinese (Simpl.) to English. -# Ideally we would detect the Translate prompt and return TRUE/FALSE based on -# that, but webdriver doesn't support this AFAIK. -PREFS = {"translate_whitelists": {"zh-CN": "en"}} - FLAGS = flags.FLAGS flags.DEFINE_bool('incognito', False, @@ -29,15 +19,21 @@ def main(argv): - driver = test_util.create_chrome_webdriver( - incognito=FLAGS.incognito, prefs=PREFS) + driver = test_util.create_chrome_webdriver(incognito=FLAGS.incognito) driver.get(URL) time.sleep(10) - output = driver.find_element_by_css_selector('html').text.encode('utf-8') + app = Application(backend="uia") + app.connect(title_re='.*Chrome|.*Chromium') - if MAGIC_STRING_ENGLISH in output: + translatePopupVisible = False + for desc in app.top_window().descendants(): + if 'Translate this page?' in desc.window_text(): + translatePopupVisible = True + break + + if translatePopupVisible: print "TRUE" else: print "FALSE"
diff --git a/chrome/browser/policy/machine_level_user_cloud_policy_controller.cc b/chrome/browser/policy/machine_level_user_cloud_policy_controller.cc index 04bf80c0..2d87f9d 100644 --- a/chrome/browser/policy/machine_level_user_cloud_policy_controller.cc +++ b/chrome/browser/policy/machine_level_user_cloud_policy_controller.cc
@@ -134,8 +134,9 @@ std::unique_ptr<MachineLevelUserCloudPolicyStore> policy_store = MachineLevelUserCloudPolicyStore::Create( dm_token, client_id, policy_dir, cloud_policy_has_priority, - base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, + base::CreateSequencedTaskRunner( + {base::ThreadPool(), base::MayBlock(), + base::TaskPriority::BEST_EFFORT, // Block shutdown to make sure the policy cache update is always // finished. base::TaskShutdownBehavior::BLOCK_SHUTDOWN}));
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc index 35376ff..fcaa8a8 100644 --- a/chrome/browser/policy/policy_browsertest.cc +++ b/chrome/browser/policy/policy_browsertest.cc
@@ -410,16 +410,16 @@ // Sets up the filter on IO thread such that requests to |host| fail. explicit MakeRequestFail(const std::string& host) : host_(host) { base::RunLoop run_loop; - base::PostTaskWithTraitsAndReply(FROM_HERE, {BrowserThread::IO}, - base::BindOnce(MakeRequestFailOnIO, host_), - run_loop.QuitClosure()); + base::PostTaskAndReply(FROM_HERE, {BrowserThread::IO}, + base::BindOnce(MakeRequestFailOnIO, host_), + run_loop.QuitClosure()); run_loop.Run(); } ~MakeRequestFail() { base::RunLoop run_loop; - base::PostTaskWithTraitsAndReply( - FROM_HERE, {BrowserThread::IO}, - base::BindOnce(UndoMakeRequestFailOnIO, host_), run_loop.QuitClosure()); + base::PostTaskAndReply(FROM_HERE, {BrowserThread::IO}, + base::BindOnce(UndoMakeRequestFailOnIO, host_), + run_loop.QuitClosure()); run_loop.Run(); } @@ -830,7 +830,7 @@ return; } - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::IO}, base::BindOnce( &net::TransportSecurityState::SetShouldRequireCTForTesting, @@ -846,8 +846,8 @@ void OnScreenshotCompleted( ui::ScreenshotResult screenshot_result, const base::FilePath& screenshot_path) override { - base::PostTaskWithTraitsAndReply(FROM_HERE, {BrowserThread::IO}, - base::DoNothing(), std::move(done_)); + base::PostTaskAndReply(FROM_HERE, {BrowserThread::IO}, base::DoNothing(), + std::move(done_)); } ~QuitMessageLoopAfterScreenshot() override {} @@ -4143,10 +4143,9 @@ } void SetUpOnMainThread() override { - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::IO}, - base::BindOnce(RedirectHostsToTestData, kRestoredURLs, - base::size(kRestoredURLs))); + base::PostTask(FROM_HERE, {BrowserThread::IO}, + base::BindOnce(RedirectHostsToTestData, kRestoredURLs, + base::size(kRestoredURLs))); } void ListOfURLs() { @@ -4557,7 +4556,7 @@ ConfigurePolicyMap(&policies, key::kAudioCaptureAllowed, NULL, NULL); UpdateProviderPolicy(policies); - base::PostTaskWithTraitsAndReply( + base::PostTaskAndReply( FROM_HERE, {content::BrowserThread::IO}, base::BindOnce( &MediaCaptureDevicesDispatcher::SetTestAudioCaptureDevices, @@ -4591,7 +4590,7 @@ key::kAudioCaptureAllowedUrls, allow_pattern[i]); UpdateProviderPolicy(policies); - base::PostTaskWithTraitsAndReply( + base::PostTaskAndReply( FROM_HERE, {content::BrowserThread::IO}, base::BindOnce( &MediaCaptureDevicesDispatcher::SetTestAudioCaptureDevices, @@ -4617,7 +4616,7 @@ ConfigurePolicyMap(&policies, key::kVideoCaptureAllowed, NULL, NULL); UpdateProviderPolicy(policies); - base::PostTaskWithTraitsAndReply( + base::PostTaskAndReply( FROM_HERE, {content::BrowserThread::IO}, base::BindOnce( &MediaCaptureDevicesDispatcher::SetTestVideoCaptureDevices, @@ -4651,7 +4650,7 @@ key::kVideoCaptureAllowedUrls, allow_pattern[i]); UpdateProviderPolicy(policies); - base::PostTaskWithTraitsAndReply( + base::PostTaskAndReply( FROM_HERE, {content::BrowserThread::IO}, base::BindOnce( &MediaCaptureDevicesDispatcher::SetTestVideoCaptureDevices, @@ -5547,8 +5546,8 @@ } void ComponentUpdaterPolicyTest::CallAsync(TestCaseAction action) { - base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(action, base::Unretained(this))); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(action, base::Unretained(this))); } void ComponentUpdaterPolicyTest::OnDemandComplete(update_client::Error error) {
diff --git a/chrome/browser/predictors/preconnect_manager.cc b/chrome/browser/predictors/preconnect_manager.cc index cdee4d11..7f42bd7 100644 --- a/chrome/browser/predictors/preconnect_manager.cc +++ b/chrome/browser/predictors/preconnect_manager.cc
@@ -192,7 +192,7 @@ if (!network_context) { // Cannot invoke the callback right away because it would cause the // use-after-free after returning from this function. - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {content::BrowserThread::UI, content::BrowserTaskType::kPreconnect}, base::BindOnce(std::move(callback), false));
diff --git a/chrome/browser/predictors/predictor_database_factory.cc b/chrome/browser/predictors/predictor_database_factory.cc index c65d344..98217a3 100644 --- a/chrome/browser/predictors/predictor_database_factory.cc +++ b/chrome/browser/predictors/predictor_database_factory.cc
@@ -37,8 +37,9 @@ KeyedService* PredictorDatabaseFactory::BuildServiceInstanceFor( content::BrowserContext* profile) const { scoped_refptr<base::SequencedTaskRunner> db_task_runner = - base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, + base::CreateSequencedTaskRunner( + {base::ThreadPool(), base::MayBlock(), + base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}); return new PredictorDatabase(static_cast<Profile*>(profile), std::move(db_task_runner));
diff --git a/chrome/browser/predictors/proxy_lookup_client_impl.cc b/chrome/browser/predictors/proxy_lookup_client_impl.cc index d7dc77e..6ead04c2 100644 --- a/chrome/browser/predictors/proxy_lookup_client_impl.cc +++ b/chrome/browser/predictors/proxy_lookup_client_impl.cc
@@ -26,7 +26,7 @@ network::mojom::ProxyLookupClientPtr proxy_lookup_client_ptr; binding_.Bind( mojo::MakeRequest(&proxy_lookup_client_ptr), - base::CreateSingleThreadTaskRunnerWithTraits( + base::CreateSingleThreadTaskRunner( {content::BrowserThread::UI, content::BrowserTaskType::kPreconnect})); network_context->LookUpProxyForURL(url, std::move(proxy_lookup_client_ptr)); binding_.set_connection_error_handler(
diff --git a/chrome/browser/predictors/resolve_host_client_impl.cc b/chrome/browser/predictors/resolve_host_client_impl.cc index cfcbc25f..7033b3d 100644 --- a/chrome/browser/predictors/resolve_host_client_impl.cc +++ b/chrome/browser/predictors/resolve_host_client_impl.cc
@@ -28,7 +28,7 @@ network::mojom::ResolveHostClientPtr resolve_host_client_ptr; binding_.Bind( mojo::MakeRequest(&resolve_host_client_ptr), - base::CreateSingleThreadTaskRunnerWithTraits( + base::CreateSingleThreadTaskRunner( {content::BrowserThread::UI, content::BrowserTaskType::kPreconnect})); network::mojom::ResolveHostParametersPtr parameters = network::mojom::ResolveHostParameters::New();
diff --git a/chrome/browser/prefs/incognito_mode_prefs.cc b/chrome/browser/prefs/incognito_mode_prefs.cc index 3ad84b96..881d7e69 100644 --- a/chrome/browser/prefs/incognito_mode_prefs.cc +++ b/chrome/browser/prefs/incognito_mode_prefs.cc
@@ -199,8 +199,8 @@ #if defined(OS_WIN) // static void IncognitoModePrefs::InitializePlatformParentalControls() { - base::CreateCOMSTATaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::USER_VISIBLE}) + base::CreateCOMSTATaskRunner( + {base::ThreadPool(), base::MayBlock(), base::TaskPriority::USER_VISIBLE}) ->PostTask(FROM_HERE, base::BindOnce(base::IgnoreResult( &PlatformParentalControlsValue::GetInstance))); }
diff --git a/chrome/browser/previews/previews_content_util.cc b/chrome/browser/previews/previews_content_util.cc index c5826e6..6fc242e0 100644 --- a/chrome/browser/previews/previews_content_util.cc +++ b/chrome/browser/previews/previews_content_util.cc
@@ -108,6 +108,17 @@ IneligibleReason::kInvalidProxyHeaders); } + if (previews::params::LitePageRedirectOnlyTriggerOnSuccessfulProbe()) { + if (!decider->IsServerProbeResultAvailable()) { + ineligible_reasons.push_back( + PreviewsLitePageNavigationThrottle::IneligibleReason:: + kServiceProbeIncomplete); + } else if (!decider->IsServerReachableByProbe()) { + ineligible_reasons.push_back(PreviewsLitePageNavigationThrottle:: + IneligibleReason::kServiceProbeFailed); + } + } + // Record UMA. for (PreviewsLitePageNavigationThrottle::IneligibleReason reason : ineligible_reasons) {
diff --git a/chrome/browser/previews/previews_lite_page_browsertest.cc b/chrome/browser/previews/previews_lite_page_browsertest.cc index 93c03e8c..d43571e81 100644 --- a/chrome/browser/previews/previews_lite_page_browsertest.cc +++ b/chrome/browser/previews/previews_lite_page_browsertest.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include <stdint.h> + #include <map> #include <memory> #include <string> @@ -269,6 +270,7 @@ std::map<std::string, std::string> feature_parameters = { {"previews_host", previews_server_url().spec()}, + {"full_probe_url", previews_server_url().spec()}, {"blacklisted_path_suffixes", ".mp4,.jpg"}, {"trigger_on_localhost", "true"}, {"max_navigation_restart", base::NumberToString(kRedirectLoopCount)}, @@ -320,6 +322,27 @@ net::ReportingPolicy policy; policy.delivery_interval = base::TimeDelta::FromSeconds(0); net::ReportingPolicy::UsePolicyForTesting(policy); + + WaitForServerProbe(); + } + + void WaitForServerProbe() { + DataReductionProxyChromeSettings* drp_settings = + DataReductionProxyChromeSettingsFactory::GetForBrowserContext( + browser()->profile()); + + PreviewsService* previews_service = + PreviewsServiceFactory::GetForProfile(browser()->profile()); + PreviewsLitePageDecider* decider = + previews_service->previews_lite_page_decider(); + + // Wait for a completed probe to the litepages server if needed. + while (drp_settings->IsDataReductionProxyEnabled()) { + if (decider->IsServerProbeResultAvailable()) { + break; + } + base::RunLoop().RunUntilIdle(); + } } void InitializeOptimizationHints() { @@ -422,14 +445,14 @@ EXPECT_EQ(content::PAGE_TYPE_NORMAL, entry->GetPageType()); const GURL virtual_url = entry->GetVirtualURL(); - // The loaded url should be the previews version of the virtual url. - EXPECT_EQ(loaded_url, - PreviewsLitePageNavigationThrottle::GetPreviewsURLForURL( - virtual_url)); + // The loaded url should be the previews version of the virtual url. + EXPECT_EQ( + loaded_url, + PreviewsLitePageNavigationThrottle::GetPreviewsURLForURL(virtual_url)); - EXPECT_FALSE(virtual_url.DomainIs(previews_server_url().host()) && - virtual_url.EffectiveIntPort() == - previews_server_url().EffectiveIntPort()); + EXPECT_FALSE(virtual_url.DomainIs(previews_server_url().host()) && + virtual_url.EffectiveIntPort() == + previews_server_url().EffectiveIntPort()); } void VerifyPreviewNotLoaded() const { @@ -970,7 +993,7 @@ ui_test_utils::NavigateToURL( browser(), PreviewsLitePageNavigationThrottle::GetPreviewsURLForURL( HttpsLitePageURL(kSuccess))); - VerifyPreviewNotLoaded(); + VerifyPreviewNotLoaded(); } { @@ -1237,12 +1260,12 @@ previews::ServerLitePageStatus::kSuccess); ClearDeciderState(); - histogram_tester.ExpectBucketCount( - "Previews.ServerLitePage.ServerResponse", - PreviewsLitePageNavigationThrottle::ServerResponse::kRedirect, 1); - histogram_tester.ExpectBucketCount( - "Previews.ServerLitePage.ServerResponse", - PreviewsLitePageNavigationThrottle::ServerResponse::kOk, 1); + histogram_tester.ExpectBucketCount( + "Previews.ServerLitePage.ServerResponse", + PreviewsLitePageNavigationThrottle::ServerResponse::kRedirect, 1); + histogram_tester.ExpectBucketCount( + "Previews.ServerLitePage.ServerResponse", + PreviewsLitePageNavigationThrottle::ServerResponse::kOk, 1); } } @@ -1257,14 +1280,13 @@ VerifyInfoStatus(&histogram_tester, previews::ServerLitePageStatus::kBypass); ClearDeciderState(); - histogram_tester.ExpectBucketCount( - "Previews.ServerLitePage.ServerResponse", - PreviewsLitePageNavigationThrottle::ServerResponse:: - kPreviewUnavailable, - 1); + histogram_tester.ExpectBucketCount( + "Previews.ServerLitePage.ServerResponse", + PreviewsLitePageNavigationThrottle::ServerResponse::kPreviewUnavailable, + 1); - histogram_tester.ExpectBucketCount( - "Previews.ServerLitePage.HostBlacklistedOnBypass", false, 1); + histogram_tester.ExpectBucketCount( + "Previews.ServerLitePage.HostBlacklistedOnBypass", false, 1); } { @@ -1277,13 +1299,12 @@ VerifyInfoStatus(&histogram_tester, previews::ServerLitePageStatus::kBypass); - histogram_tester.ExpectBucketCount( - "Previews.ServerLitePage.ServerResponse", - PreviewsLitePageNavigationThrottle::ServerResponse:: - kPreviewUnavailable, - 1); - histogram_tester.ExpectBucketCount( - "Previews.ServerLitePage.HostBlacklistedOnBypass", true, 1); + histogram_tester.ExpectBucketCount( + "Previews.ServerLitePage.ServerResponse", + PreviewsLitePageNavigationThrottle::ServerResponse::kPreviewUnavailable, + 1); + histogram_tester.ExpectBucketCount( + "Previews.ServerLitePage.HostBlacklistedOnBypass", true, 1); ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess)); VerifyPreviewNotLoaded(); @@ -1306,9 +1327,9 @@ VerifyInfoStatus(&histogram_tester, previews::ServerLitePageStatus::kFailure); ClearDeciderState(); - histogram_tester.ExpectBucketCount( - "Previews.ServerLitePage.ServerResponse", - PreviewsLitePageNavigationThrottle::ServerResponse::kAuthFailure, 1); + histogram_tester.ExpectBucketCount( + "Previews.ServerLitePage.ServerResponse", + PreviewsLitePageNavigationThrottle::ServerResponse::kAuthFailure, 1); } { @@ -1319,11 +1340,10 @@ VerifyInfoStatus(&histogram_tester, previews::ServerLitePageStatus::kFailure); ClearDeciderState(); - histogram_tester.ExpectBucketCount( - "Previews.ServerLitePage.ServerResponse", - PreviewsLitePageNavigationThrottle::ServerResponse:: - kServiceUnavailable, - 1); + histogram_tester.ExpectBucketCount( + "Previews.ServerLitePage.ServerResponse", + PreviewsLitePageNavigationThrottle::ServerResponse::kServiceUnavailable, + 1); } } @@ -1702,16 +1722,16 @@ // under test, and another one for loading the preview. { - // Verify the preview is not shown on a bad previews server. + // Verify the preview is not shown on a bad previews server because it was + // never triggered due to a failed probe. base::HistogramTester histogram_tester; ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess)); VerifyPreviewNotLoaded(); - VerifyInfoStatus(&histogram_tester, - previews::ServerLitePageStatus::kFailure); - ClearDeciderState(); histogram_tester.ExpectBucketCount( - "Previews.ServerLitePage.ServerResponse", - PreviewsLitePageNavigationThrottle::ServerResponse::kFailed, 1); + "Previews.ServerLitePage.IneligibleReasons", + PreviewsLitePageNavigationThrottle::IneligibleReason:: + kServiceProbeFailed, + 1); } } @@ -1804,6 +1824,8 @@ g_browser_process->network_quality_tracker() ->ReportEffectiveConnectionTypeForTesting( net::EFFECTIVE_CONNECTION_TYPE_2G); + + WaitForServerProbe(); } };
diff --git a/chrome/browser/previews/previews_lite_page_decider.cc b/chrome/browser/previews/previews_lite_page_decider.cc index f9ccd4e..78133d2 100644 --- a/chrome/browser/previews/previews_lite_page_decider.cc +++ b/chrome/browser/previews/previews_lite_page_decider.cc
@@ -86,21 +86,6 @@ DCHECK_GE(kMaxBlacklistEntries, dict->DictSize()); } -void PreconnectToLitePagesServer(content::BrowserContext* browser_context) { - predictors::LoadingPredictor* loading_predictor = - predictors::LoadingPredictorFactory::GetForProfile( - Profile::FromBrowserContext(browser_context)); - - if (!loading_predictor || !loading_predictor->preconnect_manager()) - return; - - url::Origin previews_origin = - url::Origin::Create(previews::params::GetLitePagePreviewsDomainURL()); - loading_predictor->preconnect_manager()->StartPreconnectUrl( - previews::params::GetLitePagePreviewsDomainURL(), true, - net::NetworkIsolationKey(previews_origin, previews_origin)); -} - } // namespace // This WebContentsObserver watches the rest of the current navigation shows a @@ -163,6 +148,8 @@ if (!browser_context) return; + Profile* profile = Profile::FromBrowserContext(browser_context); + DataReductionProxyChromeSettings* drp_settings = DataReductionProxyChromeSettingsFactory::GetForBrowserContext( browser_context); @@ -171,12 +158,7 @@ DCHECK(!browser_context->IsOffTheRecord()); - // TODO(crbug.com/971918): Remove once a more robust prober is setup. - if (drp_settings->IsDataReductionProxyEnabled()) { - PreconnectToLitePagesServer(browser_context); - } - - pref_service_ = Profile::FromBrowserContext(browser_context)->GetPrefs(); + pref_service_ = profile->GetPrefs(); host_bypass_blacklist_ = pref_service_->GetDictionary(kHostBlacklist)->CreateDeepCopy(); @@ -196,6 +178,47 @@ OnSettingsInitialized(); OnProxyRequestHeadersChanged(drp_settings->GetProxyRequestHeaders()); } + + // This section depends on |pref_service_| being set so it must come after + // that. + net::NetworkTrafficAnnotationTag traffic_annotation = + net::DefineNetworkTrafficAnnotation("previews_litepage_prober", R"( + semantics { + sender: "Previews Litepage Prober" + description: + "Requests a small resource to test network connectivity to a " + "Google domain." + trigger: + "Requested when Lite mode and Previews are enabled on startup and " + "on every network change." + data: "None." + destination: GOOGLE_OWNED_SERVICE + } + policy { + cookies_allowed: NO + setting: + "Users can control Lite mode on Android via the settings menu. " + "Lite mode is not available on iOS, and on desktop only for " + "developer testing." + policy_exception_justification: "Not implemented." + })"); + + AvailabilityProber::TimeoutPolicy timeout_policy; + AvailabilityProber::RetryPolicy retry_policy; + retry_policy.backoff = AvailabilityProber::Backoff::kExponential; + retry_policy.base_interval = base::TimeDelta::FromSeconds(30); + retry_policy.use_random_urls = true; + + litepages_service_prober_ = std::make_unique<AvailabilityProber>( + this, profile->GetURLLoaderFactory(), profile->GetPrefs(), + AvailabilityProber::ClientName::kLitepages, + previews::params::LitePageRedirectProbeURL(), + AvailabilityProber::HttpMethod::kHead, net::HttpRequestHeaders(), + retry_policy, timeout_policy, traffic_annotation, + 10 /* max_cache_entries */, + base::TimeDelta::FromHours(24) /* revalidate_cache_after */); + litepages_service_prober_->SendNowIfInactive( + true /* send_only_in_foreground */); } PreviewsLitePageDecider::~PreviewsLitePageDecider() = default; @@ -455,3 +478,32 @@ base::Time expiry = base::Time::FromDoubleT(value->GetDouble()); return expiry > base::Time::Now(); } + +bool PreviewsLitePageDecider::ShouldSendNextProbe() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return data_reduction_proxy::DataReductionProxySettings:: + IsDataSaverEnabledByUser(pref_service_) && + previews::params::ArePreviewsAllowed() && + previews::params::IsLitePageServerPreviewsEnabled(); +} + +bool PreviewsLitePageDecider::IsResponseSuccess( + net::Error net_error, + const network::ResourceResponseHead* head, + std::unique_ptr<std::string> body) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // Any HTTP response is fine, so long as we got it. + return net_error == net::OK && head && head->headers; +} + +bool PreviewsLitePageDecider::IsServerProbeResultAvailable() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return litepages_service_prober_->LastProbeWasSuccessful().has_value(); +} + +bool PreviewsLitePageDecider::IsServerReachableByProbe() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + base::Optional<bool> probe = + litepages_service_prober_->LastProbeWasSuccessful(); + return probe.value_or(false); +}
diff --git a/chrome/browser/previews/previews_lite_page_decider.h b/chrome/browser/previews/previews_lite_page_decider.h index c9c0b18..65e31c0 100644 --- a/chrome/browser/previews/previews_lite_page_decider.h +++ b/chrome/browser/previews/previews_lite_page_decider.h
@@ -16,6 +16,7 @@ #include "base/time/tick_clock.h" #include "base/time/time.h" #include "base/values.h" +#include "chrome/browser/availability/availability_prober.h" #include "chrome/browser/previews/previews_https_notification_infobar_decider.h" #include "chrome/browser/previews/previews_lite_page_navigation_throttle_manager.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h" @@ -40,7 +41,8 @@ // current Profile is not incognito before handing off the real legwork of the // triggering decision to |PreviewsLitePageNavigationThrottle|. class PreviewsLitePageDecider - : public PreviewsLitePageNavigationThrottleManager, + : public AvailabilityProber::Delegate, + public PreviewsLitePageNavigationThrottleManager, public PreviewsHTTPSNotificationInfoBarDecider, public data_reduction_proxy::DataReductionProxySettingsObserver { public: @@ -96,6 +98,8 @@ void BlacklistBypassedHost(const std::string& host, base::TimeDelta duration) override; bool HostBlacklistedFromBypass(const std::string& host) override; + bool IsServerReachableByProbe() override; + bool IsServerProbeResultAvailable() override; // data_reduction_proxy::DataReductionProxySettingsObserver: void OnProxyRequestHeadersChanged( @@ -105,6 +109,12 @@ bool has_drp_headers() const { return drp_headers_valid_; } private: + // AvailabilityProber::Delegate: + bool ShouldSendNextProbe() override; + bool IsResponseSuccess(net::Error net_error, + const network::ResourceResponseHead* head, + std::unique_ptr<std::string> body) override; + // The time after which it is ok to send the server more preview requests. base::Optional<base::TimeTicks> retry_at_; @@ -139,6 +149,10 @@ // what looked like a valid chrome-proxy header. bool drp_headers_valid_; + // Probes the litepages service to establish that it is reachable before + // attempting a preview. + std::unique_ptr<AvailabilityProber> litepages_service_prober_; + SEQUENCE_CHECKER(sequence_checker_); DISALLOW_COPY_AND_ASSIGN(PreviewsLitePageDecider);
diff --git a/chrome/browser/previews/previews_lite_page_navigation_throttle.h b/chrome/browser/previews/previews_lite_page_navigation_throttle.h index 1c5c5e62..112e2c8d 100644 --- a/chrome/browser/previews/previews_lite_page_navigation_throttle.h +++ b/chrome/browser/previews/previews_lite_page_navigation_throttle.h
@@ -13,7 +13,7 @@ namespace content { struct OpenURLParams; class BrowserContext; -} +} // namespace content // If the given URL is a LitePage Preview URL, this returns true but does not // change the |url|. This will set |update_virtual_url_with_url| on @@ -64,7 +64,9 @@ kExceededMaxNavigationRestarts = 9, kPreviewsState_DEPRECATED = 10, kInvalidProxyHeaders = 11, - kMaxValue = kInvalidProxyHeaders, + kServiceProbeIncomplete = 12, + kServiceProbeFailed = 13, + kMaxValue = kServiceProbeFailed, }; // The response type from the previews server. This enum must
diff --git a/chrome/browser/previews/previews_lite_page_navigation_throttle_manager.h b/chrome/browser/previews/previews_lite_page_navigation_throttle_manager.h index 5d79306..6bab32e 100644 --- a/chrome/browser/previews/previews_lite_page_navigation_throttle_manager.h +++ b/chrome/browser/previews/previews_lite_page_navigation_throttle_manager.h
@@ -24,6 +24,16 @@ // unavailable. virtual bool IsServerUnavailable() = 0; + // Returns true if a Preview server probe has completed for the current + // network ID. This is session-agnostic because cached values from previous + // sessions will be used if they exist for the current network ID. + virtual bool IsServerProbeResultAvailable() = 0; + + // Returns true if the Preview server is reachable on the network according to + // a network probe. This will return the result of the most recent probe, + // either from this session or a previous cached session's. + virtual bool IsServerReachableByProbe() = 0; + // Informs the manager that the given URL should be bypassed one time. virtual void AddSingleBypass(std::string url) = 0;
diff --git a/chrome/browser/profile_resetter/profile_resetter.cc b/chrome/browser/profile_resetter/profile_resetter.cc index a8defdb2..1a80299 100644 --- a/chrome/browser/profile_resetter/profile_resetter.cc +++ b/chrome/browser/profile_resetter/profile_resetter.cc
@@ -109,7 +109,7 @@ CHECK_EQ(static_cast<ResettableFlags>(0), pending_reset_flags_); if (!resettable_flags) { - base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI}, callback); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, callback); return; } @@ -160,8 +160,7 @@ pending_reset_flags_ &= ~resettable; if (!pending_reset_flags_) { - base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI}, - callback_); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, callback_); callback_.Reset(); master_settings_.reset(); template_url_service_sub_.reset(); @@ -329,8 +328,8 @@ void ProfileResetter::ResetShortcuts() { #if defined(OS_WIN) - base::CreateCOMSTATaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::USER_VISIBLE}) + base::CreateCOMSTATaskRunner( + {base::ThreadPool(), base::MayBlock(), base::TaskPriority::USER_VISIBLE}) ->PostTaskAndReply(FROM_HERE, base::Bind(&ResetShortcutsOnBlockingThread), base::Bind(&ProfileResetter::MarkAsDone, weak_ptr_factory_.GetWeakPtr(), SHORTCUTS));
diff --git a/chrome/browser/profile_resetter/resettable_settings_snapshot.cc b/chrome/browser/profile_resetter/resettable_settings_snapshot.cc index b08b4130..1e91634a 100644 --- a/chrome/browser/profile_resetter/resettable_settings_snapshot.cc +++ b/chrome/browser/profile_resetter/resettable_settings_snapshot.cc
@@ -137,8 +137,8 @@ cancellation_flag_ = new SharedCancellationFlag; #if defined(OS_WIN) base::PostTaskAndReplyWithResult( - base::CreateCOMSTATaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::USER_VISIBLE}) + base::CreateCOMSTATaskRunner({base::ThreadPool(), base::MayBlock(), + base::TaskPriority::USER_VISIBLE}) .get(), FROM_HERE, base::Bind(&GetChromeLaunchShortcuts, cancellation_flag_), base::Bind(&ResettableSettingsSnapshot::SetShortcutsAndReport,
diff --git a/chrome/browser/push_messaging/budget_database.cc b/chrome/browser/push_messaging/budget_database.cc index 45188db..16abf59 100644 --- a/chrome/browser/push_messaging/budget_database.cc +++ b/chrome/browser/push_messaging/budget_database.cc
@@ -62,8 +62,9 @@ db_ = protodb_provider->GetDB<budget_service::Budget>( leveldb_proto::ProtoDbType::BUDGET_DATABASE, profile->GetPath().Append(FILE_PATH_LITERAL("BudgetDatabase")), - base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, + base::CreateSequencedTaskRunner( + {base::ThreadPool(), base::MayBlock(), + base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})); db_->Init(base::BindOnce(&BudgetDatabase::OnDatabaseInit, weak_ptr_factory_.GetWeakPtr()));
diff --git a/chrome/browser/resources/chromeos/chromevox/chromevox/background/options.js b/chrome/browser/resources/chromeos/chromevox/chromevox/background/options.js index 1edcee39..0cbbb9e 100644 --- a/chrome/browser/resources/chromeos/chromevox/chromevox/background/options.js +++ b/chrome/browser/resources/chromeos/chromevox/chromevox/background/options.js
@@ -108,14 +108,6 @@ } }); - chrome.commandLinePrivate.hasSwitch( - 'enable-experimental-accessibility-chromevox-rich-text-indication', - function(enabled) { - if (!enabled) { - $('richTextIndicationOption').style.display = 'none'; - } - }); - var registerEventStreamFiltersListener = function() { $('toggleEventStreamFilters').addEventListener('click', function(evt) { if ($('eventStreamFilters').hidden) {
diff --git a/chrome/browser/resources/chromeos/login/multidevice_setup_first_run.js b/chrome/browser/resources/chromeos/login/multidevice_setup_first_run.js index 7e9758b..2db9191 100644 --- a/chrome/browser/resources/chromeos/login/multidevice_setup_first_run.js +++ b/chrome/browser/resources/chromeos/login/multidevice_setup_first_run.js
@@ -14,9 +14,9 @@ constructor() { /** * @private {?chromeos.multideviceSetup.mojom. - * PrivilegedHostDeviceSetterProxy} + * PrivilegedHostDeviceSetterRemote} */ - this.proxy_ = null; + this.remote_ = null; } /** @override */ @@ -30,13 +30,13 @@ // required. assert(!opt_authToken); - if (!this.proxy_) { - this.proxy_ = chromeos.multideviceSetup.mojom.PrivilegedHostDeviceSetter - .getProxy(); + if (!this.remote_) { + this.remote_ = chromeos.multideviceSetup.mojom + .PrivilegedHostDeviceSetter.getRemote(); } return /** @type {!Promise<{success: boolean}>} */ ( - this.proxy_.setHostDevice(hostDeviceId)); + this.remote_.setHostDevice(hostDeviceId)); } /** @override */
diff --git a/chrome/browser/resources/chromeos/multidevice_setup/post_oobe_delegate.js b/chrome/browser/resources/chromeos/multidevice_setup/post_oobe_delegate.js index 3d5cecd..c1cf482 100644 --- a/chrome/browser/resources/chromeos/multidevice_setup/post_oobe_delegate.js +++ b/chrome/browser/resources/chromeos/multidevice_setup/post_oobe_delegate.js
@@ -21,7 +21,7 @@ // multidevice_setup.mojom). return /** @type {!Promise<{success: boolean}>} */ ( multidevice_setup.MojoInterfaceProviderImpl.getInstance() - .getMojoServiceProxy() + .getMojoServiceRemote() .setHostDevice(hostDeviceId, opt_authToken)); }
diff --git a/chrome/browser/resources/chromeos/switch_access/navigation_manager.js b/chrome/browser/resources/chromeos/switch_access/navigation_manager.js index c95d3cd..e7a828f 100644 --- a/chrome/browser/resources/chromeos/switch_access/navigation_manager.js +++ b/chrome/browser/resources/chromeos/switch_access/navigation_manager.js
@@ -357,7 +357,7 @@ * @public */ selectionStarted() { - return this.textNavigationManager_.isSelStartIndexSet(); + return this.textNavigationManager_.isSelectionStarted(); } /** @@ -560,6 +560,8 @@ // Rebuild scope stack and set scope for focused node. this.buildScopeStack_(event.target); + this.textNavigationManager_.resetSelStartIndex(); + // Move to focused node. this.node_ = event.target;
diff --git a/chrome/browser/resources/chromeos/switch_access/text_navigation_manager.js b/chrome/browser/resources/chromeos/switch_access/text_navigation_manager.js index 08a191f8..3e78d9a9 100644 --- a/chrome/browser/resources/chromeos/switch_access/text_navigation_manager.js +++ b/chrome/browser/resources/chromeos/switch_access/text_navigation_manager.js
@@ -152,6 +152,13 @@ } /** + * Reset the selectionStartIndex to NO_SELECT_INDEX. + */ + resetSelStartIndex() { + this.selectionStartIndex_ = NO_SELECT_INDEX; + } + + /** * Returns the selection start index. * @return {number} * @public @@ -172,11 +179,11 @@ } /** - * Returns if the selection start index is set. + * Returns if the selection start index is set in the current node. * @return {boolean} * @public */ - isSelStartIndexSet() { + isSelectionStarted() { return this.selectionStartIndex_ !== NO_SELECT_INDEX; }
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_manager.js b/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_manager.js index 556a25e..42b9360a 100644 --- a/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_manager.js +++ b/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_manager.js
@@ -367,15 +367,6 @@ }, 500); }; }()); - - // Center horizontally after any style changes. - const observer = new MutationObserver(function() { - centerElement( - $('message-container'), $('message-container').parentNode.offsetWidth, - null); - }); - observer.observe( - $('message-container'), {attributes: true, attributeFilter: ['style']}); }; /**
diff --git a/chrome/browser/resources/local_ntp/customize.js b/chrome/browser/resources/local_ntp/customize.js index 3ae15417d..ced9b9c6 100644 --- a/chrome/browser/resources/local_ntp/customize.js +++ b/chrome/browser/resources/local_ntp/customize.js
@@ -704,7 +704,8 @@ */ customize.tileOnKeyDownInteraction = function(event) { const tile = event.currentTarget; - if (event.keyCode === customize.KEYCODES.ENTER) { + if (event.keyCode === customize.KEYCODES.ENTER || + event.keyCode === customize.KEYCODES.SPACE) { event.preventDefault(); event.stopPropagation(); if (tile.onClickOverride) { @@ -991,6 +992,9 @@ customize.selectedOptions.background); } + // Remove any existing preview. + customize.richerPicker_unpreviewImage(); + customize.selectedOptions.background = tile; customize.selectedOptions.backgroundData = { id: tile.id, @@ -1995,6 +1999,14 @@ }; const clOption = $(customize.IDS.SHORTCUTS_OPTION_CUSTOM_LINKS); + const mvOption = $(customize.IDS.SHORTCUTS_OPTION_MOST_VISITED); + const hideToggle = $(customize.IDS.SHORTCUTS_HIDE_TOGGLE); + $(customize.IDS.SHORTCUTS_MENU).onkeydown = function(event) { + if (customize.arrowKeys.includes(event.keyCode)) { + clOption.focus(); + } + }; + clOption.onclick = function() { if (customize.selectedOptions.shortcutType !== clOption) { ntpApiHandle.logEvent( @@ -2006,10 +2018,18 @@ if (event.keyCode === customize.KEYCODES.ENTER || event.keyCode === customize.KEYCODES.SPACE) { clOption.click(); + } else if (customize.arrowKeys.includes(event.keyCode)) { + // Handle arrow key navigation. + event.preventDefault(); + event.stopPropagation(); + if (event.keyCode === customize.KEYCODES.RIGHT) { + mvOption.focus(); + } else if (event.keyCode === customize.KEYCODES.DOWN) { + hideToggle.focus(); + } } }; - const mvOption = $(customize.IDS.SHORTCUTS_OPTION_MOST_VISITED); mvOption.onclick = function() { if (customize.selectedOptions.shortcutType !== mvOption) { ntpApiHandle.logEvent( @@ -2021,10 +2041,20 @@ if (event.keyCode === customize.KEYCODES.ENTER || event.keyCode === customize.KEYCODES.SPACE) { mvOption.click(); + } else if (customize.arrowKeys.includes(event.keyCode)) { + // Handle arrow key navigation. + event.preventDefault(); + event.stopPropagation(); + if (event.keyCode === customize.KEYCODES.LEFT) { + clOption.focus(); + } else if ( + event.keyCode === customize.KEYCODES.RIGHT || + event.keyCode === customize.KEYCODES.DOWN) { + hideToggle.focus(); + } } }; - const hideToggle = $(customize.IDS.SHORTCUTS_HIDE_TOGGLE); hideToggle.onchange = function(event) { customize.richerPicker_toggleShortcutHide(hideToggle.checked); ntpApiHandle.logEvent( @@ -2034,6 +2064,14 @@ if (event.keyCode === customize.KEYCODES.ENTER || event.keyCode === customize.KEYCODES.SPACE) { hideToggle.onchange(event); + } else if (customize.arrowKeys.includes(event.keyCode)) { + // Handle arrow key navigation. + event.preventDefault(); + event.stopPropagation(); + if (event.keyCode === customize.KEYCODES.LEFT || + event.keyCode === customize.KEYCODES.UP) { + mvOption.focus(); + } } }; hideToggle.onclick = function(event) { @@ -2281,12 +2319,13 @@ } } else if ( configData.chromeColorsCustomColorPicker && themeInfo.colorDark && - themeInfo.colorLight) { + themeInfo.colorLight && themeInfo.colorPicked) { // Custom color is selected. tile = $(customize.IDS.COLOR_PICKER_TILE); // Update color picker tile colors. - $(customize.IDS.COLOR_PICKER).value = colorArrayToHex(themeInfo.colorDark); + $(customize.IDS.COLOR_PICKER).value = + colorArrayToHex(themeInfo.colorPicked); $(customize.IDS.COLORS_MENU) .style.setProperty( '--custom-color-border', colorArrayToHex(themeInfo.colorDark));
diff --git a/chrome/browser/resources/local_ntp/local_ntp.css b/chrome/browser/resources/local_ntp/local_ntp.css index 1c24cc63..52b1ff3 100644 --- a/chrome/browser/resources/local_ntp/local_ntp.css +++ b/chrome/browser/resources/local_ntp/local_ntp.css
@@ -723,6 +723,7 @@ display: inline-block; height: 384px; left: 0; + margin-top: 80px; vertical-align: top; width: 192px; } @@ -843,7 +844,6 @@ height: 80px; line-height: 80px; padding-inline-end: 24px; - padding-inline-start: 232px; } #menu-title { @@ -889,14 +889,14 @@ #menu-contents { display: inline-block; - height: 384px; + height: 464px; margin-inline-start: 40px; position: relative; width: 568px; } .menu-panel { - height: 100%; + height: 384px; left: 0; /* Pad the content by 5px top/left. This will prevent the focus outline on * tiles from being cut off by overflow-y. */ @@ -906,7 +906,7 @@ padding-inline-start: 5px; padding-top: 5px; position: absolute; - top: 0; + top: 80px; visibility: hidden; width: 100%; }
diff --git a/chrome/browser/resources/local_ntp/local_ntp.html b/chrome/browser/resources/local_ntp/local_ntp.html index fd5607f..126cfef9 100644 --- a/chrome/browser/resources/local_ntp/local_ntp.html +++ b/chrome/browser/resources/local_ntp/local_ntp.html
@@ -170,26 +170,6 @@ </dialog> <dialog id="customization-menu" class="customize-dialog"> - <div id="menu-header"> - <div id="menu-back-circle" tabindex="0" role="button" - aria-label="$i18n{backLabel}" title="$i18n{backLabel}"> - <div id="menu-back"></div> - </div> - <div id="menu-title">$i18n{customizeMenu}</div> - <div id="refresh-daily-wrapper"> - <div id="refresh-toggle-wrapper" title="$i18n{refreshDaily}"> - <label class="switch"> - <input id="refresh-daily-toggle" type="checkbox" - aria-labelledby="refresh-text"></input> - <span class="toggle"> - <div class="knob"></div> - <div class="highlight"></div> - </span> - </label> - </div> - <div id="refresh-text">$i18n{refreshDaily}</div> - </div> - </div> <div id="menu-nav-panel" role="tablist" aria-label="$i18n{customizeMenu}"> <button id="backgrounds-button" class="menu-option" tabindex="0" role="tab" aria-controls="backgrounds-menu backgrounds-image-menu" @@ -225,18 +205,40 @@ </button> </div> <div id="menu-contents"> + <div id="menu-header"> + <div id="menu-back-circle" tabindex="0" role="button" + aria-label="$i18n{backLabel}" title="$i18n{backLabel}"> + <div id="menu-back"></div> + </div> + <div id="menu-title">$i18n{customizeMenu}</div> + <div id="refresh-daily-wrapper"> + <div id="refresh-toggle-wrapper" title="$i18n{refreshDaily}"> + <label class="switch"> + <input id="refresh-daily-toggle" type="checkbox" + aria-labelledby="refresh-text"></input> + <span class="toggle"> + <div class="knob"></div> + <div class="highlight"></div> + </span> + </label> + </div> + <div id="refresh-text">$i18n{refreshDaily}</div> + </div> + </div> <div id="backgrounds-menu" class="menu-panel" tabindex="0" role="tabpanel" aria-label="$i18n{backgroundsOption}"> <div id="backgrounds-upload" class="bg-sel-tile-bg"> <div id="backgrounds-upload-icon" class="bg-sel-tile" tabindex="-1" - aria-label="$i18n{uploadImage}" title="$i18n{uploadImage}"> + role="button" aria-label="$i18n{uploadImage}" + title="$i18n{uploadImage}"> <div id="backgrounds-upload-arrow"></div> <div id="backgrounds-upload-text">$i18n{uploadImage}</div> </div> </div> <div id="backgrounds-default" class="bg-sel-tile-bg"> <div id="backgrounds-default-icon" class="bg-sel-tile" tabindex="-1" - aria-label="$i18n{noBackground}" title="$i18n{noBackground}"> + role="button" aria-label="$i18n{noBackground}" + title="$i18n{noBackground}"> <div class="mini-page"> <div class="mini-header-colorful"></div> <div class="mini-shortcuts"></div> @@ -251,7 +253,7 @@ aria-label="$i18n{shortcutsOption}"> <div id="sh-options"> <div class="sh-option"> - <div id="sh-option-cl" class="sh-option-image" tabindex="0" + <div id="sh-option-cl" class="sh-option-image" tabindex="-1" role="button" aria-pressed="false" aria-labelledby="sh-option-cl-title" title="$i18n{myShortcuts}"> <div class="sh-option-icon"></div> @@ -268,7 +270,7 @@ $i18n{shortcutsCurated} </div> <div class="sh-option"> - <div id="sh-option-mv" class="sh-option-image" tabindex="0" + <div id="sh-option-mv" class="sh-option-image" tabindex="-1" role="button" aria-pressed="false" aria-labelledby="sh-option-mv-title" title="$i18n{mostVisited}"> <div class="sh-option-icon"></div> @@ -293,7 +295,7 @@ </div> <div id="sh-hide-toggle-wrapper" title="$i18n{hideShortcuts}"> <label class="switch"> - <input id="sh-hide-toggle" type="checkbox" + <input id="sh-hide-toggle" type="checkbox" tabindex="-1" aria-labelledby="sh-hide-title"></input> <span class="toggle"> <div class="knob"></div> @@ -319,7 +321,8 @@ </button> </div> <div id="color-picker-container" class="bg-sel-tile-bg" - aria-label="$i18n{colorPickerLabel}" title="$i18n{colorPickerLabel}"> + aria-label="$i18n{colorPickerLabel}" + title="$i18n{colorPickerLabel}"> <div id="color-picker-tile" class="bg-sel-tile" tabindex="-1"> <div id="left-semicircle"></div> <div id="color-picker-icon"></div> @@ -328,8 +331,8 @@ </div> </div> <div id="colors-default" class="bg-sel-tile-bg" - aria-label="$i18n{defaultThemeLabel}" - title="$i18n{defaultThemeLabel}"> + aria-label="$i18n{defaultThemeLabel}" + title="$i18n{defaultThemeLabel}"> <div id="colors-default-icon" class="bg-sel-tile" tabindex="-1"></div> </div> </div>
diff --git a/chrome/browser/resources/omnibox/omnibox_output.js b/chrome/browser/resources/omnibox/omnibox_output.js index ceccc7e..72184d0 100644 --- a/chrome/browser/resources/omnibox/omnibox_output.js +++ b/chrome/browser/resources/omnibox/omnibox_output.js
@@ -727,7 +727,7 @@ */ static renderClassifiedText_(container, string, classes) { clearChildren(container); - OutputAnswerProperty.classify(string + '\n', classes) + OutputAnswerProperty.classify(string, classes) .map( ({string, style}) => OutputJsonProperty.renderJsonWord( string, OutputAnswerProperty.styleToClasses_(style)))
diff --git a/chrome/browser/resources/omnibox/output_results_group.css b/chrome/browser/resources/omnibox/output_results_group.css index 56f5d51..c46e20e 100644 --- a/chrome/browser/resources/omnibox/output_results_group.css +++ b/chrome/browser/resources/omnibox/output_results_group.css
@@ -54,6 +54,7 @@ } .body td { + white-space: pre-wrap; word-break: break-all; } @@ -62,7 +63,7 @@ } .body td.elided:not(:hover) { - white-space: nowrap; + white-space: pre; } .body td:not(:hover) * {
diff --git a/chrome/browser/resources/settings/a11y_page/captions_subpage.html b/chrome/browser/resources/settings/a11y_page/captions_subpage.html index d3d305b9..2e56392 100644 --- a/chrome/browser/resources/settings/a11y_page/captions_subpage.html +++ b/chrome/browser/resources/settings/a11y_page/captions_subpage.html
@@ -7,84 +7,103 @@ <dom-module id="settings-captions"> <template> - <style include="settings-shared"></style> - <div class="settings-box"> - <div class="start settings-box-text">$i18n{captionsTextSize}</div> - <settings-dropdown-menu id="captionsTextSize" - label="$i18n{captionsTextSize}" - pref="{{prefs.accessibility.captions.text_size}}" - menu-options="[[textSizeOptions_]]"> - </settings-dropdown-menu> - </div> - <div class="settings-box"> - <div class="start settings-box-text">$i18n{captionsTextFont}</div> - <settings-dropdown-menu id="captionsTextFont" - label="$i18n{captionsTextFont}" - pref="{{prefs.accessibility.captions.text_font}}" - menu-options="[[textFontOptions_]]"> - </settings-dropdown-menu> - </div> - <div class="settings-box"> - <div class="start settings-box-text">$i18n{captionsTextColor}</div> - <settings-dropdown-menu id="captionsTextColor" - label="$i18n{captionsTextColor}" - pref="{{prefs.accessibility.captions.text_color}}" - menu-options="[[colorOptions_]]"> - </settings-dropdown-menu> - </div> - <div class="settings-box"> - <div class="start settings-box-text">$i18n{captionsTextOpacity}</div> - <settings-slider id="captionsTextOpacity" - ticks="[[textOpacityRange_]]" - label-min="$i18n{captionsOpacityMin}" - label-max="$i18n{captionsOpacityMax}" - pref="{{prefs.accessibility.captions.text_opacity}}"> - </settings-slider> - </div> - <div class="settings-box"> - <div class="start settings-box-text">$i18n{captionsTextShadow}</div> - <settings-dropdown-menu id="captionsTextShadow" - label="$i18n{captionsTextShadow}" - pref="{{prefs.accessibility.captions.text_shadow}}" - menu-options="[[textShadowOptions_]]"> - </settings-dropdown-menu> - </div> - <div class="settings-box"> - <div class="start settings-box-text">$i18n{captionsBackgroundColor}</div> - <settings-dropdown-menu id="captionsBackgroundColor" - label="$i18n{captionsBackgroundColor}" - pref="{{prefs.accessibility.captions.background_color}}" - menu-options="[[colorOptions_]]"> - </settings-dropdown-menu> - </div> - <div class="settings-box"> - <div class="start settings-box-text"> - $i18n{captionsBackgroundOpacity} - </div> - <settings-slider id="captionsBackgroundOpacity" - ticks="[[textOpacityRange_]]" - label-min="$i18n{captionsOpacityMin}" - label-max="$i18n{captionsOpacityMax}" - pref="{{prefs.accessibility.captions.background_opacity}}"> - </settings-slider> + <style include="settings-shared"> + .preview-box { + align-items: center; + border: var(--cr-separator-line); + border-radius: var(--cr-card-border-radius); + display: flex; + height: 112px; + justify-content: center; + margin: var(--cr-section-padding); + text-align: center; + } + </style> + <div class="settings-box first"> + <h2 class="start">$i18n{captionsSettings}</h2> </div> <div class="list-frame"> - <div class="list-item"> - <span style=" - font-size:[[prefs.accessibility.captions.text_size.value]]; - font-family:[[prefs.accessibility.captions.text_font.value]]; - background-color: [[computeBackgroundColor_( - prefs.accessibility.captions.background_opacity.value, - prefs.accessibility.captions.background_color.value)]]; - color: [[computeTextColor_( - prefs.accessibility.captions.text_opacity.value, - prefs.accessibility.captions.text_color.value)]]; - text-shadow: [[prefs.accessibility.captions.text_shadow.value]]; - padding: [[computePadding_( - prefs.accessibility.captions.text_size.value)]]"> - $i18n{quickBrownFox} - </span> + <div class="list-item underbar first"> + <div class="start settings-box-text">$i18n{captionsTextSize}</div> + <settings-dropdown-menu id="captionsTextSize" + label="$i18n{captionsTextSize}" + pref="{{prefs.accessibility.captions.text_size}}" + menu-options="[[textSizeOptions_]]"> + </settings-dropdown-menu> </div> + <div class="list-item underbar"> + <div class="start settings-box-text">$i18n{captionsTextFont}</div> + <settings-dropdown-menu id="captionsTextFont" + label="$i18n{captionsTextFont}" + pref="{{prefs.accessibility.captions.text_font}}" + menu-options="[[textFontOptions_]]"> + </settings-dropdown-menu> + </div> + <div class="list-item underbar"> + <div class="start settings-box-text">$i18n{captionsTextColor}</div> + <settings-dropdown-menu id="captionsTextColor" + label="$i18n{captionsTextColor}" + pref="{{prefs.accessibility.captions.text_color}}" + menu-options="[[colorOptions_]]"> + </settings-dropdown-menu> + </div> + <div class="list-item underbar"> + <div class="start settings-box-text">$i18n{captionsTextOpacity}</div> + <settings-slider id="captionsTextOpacity" + ticks="[[textOpacityRange_]]" + label-min="$i18n{captionsOpacityMin}" + label-max="$i18n{captionsOpacityMax}" + pref="{{prefs.accessibility.captions.text_opacity}}"> + </settings-slider> + </div> + <div class="list-item underbar"> + <div class="start settings-box-text">$i18n{captionsTextShadow}</div> + <settings-dropdown-menu id="captionsTextShadow" + label="$i18n{captionsTextShadow}" + pref="{{prefs.accessibility.captions.text_shadow}}" + menu-options="[[textShadowOptions_]]"> + </settings-dropdown-menu> + </div> + <div class="list-item underbar"> + <div class="start settings-box-text"> + $i18n{captionsBackgroundColor} + </div> + <settings-dropdown-menu id="captionsBackgroundColor" + label="$i18n{captionsBackgroundColor}" + pref="{{prefs.accessibility.captions.background_color}}" + menu-options="[[colorOptions_]]"> + </settings-dropdown-menu> + </div> + <div class="list-item"> + <div class="start settings-box-text"> + $i18n{captionsBackgroundOpacity} + </div> + <settings-slider id="captionsBackgroundOpacity" + ticks="[[textOpacityRange_]]" + label-min="$i18n{captionsOpacityMin}" + label-max="$i18n{captionsOpacityMax}" + pref="{{prefs.accessibility.captions.background_opacity}}"> + </settings-slider> + </div> + </div> + <div class="settings-box continuation"> + <h2 class="start">$i18n{captionsPreview}</h2> + </div> + <div class="preview-box"> + <span style=" + font-size:[[prefs.accessibility.captions.text_size.value]]; + font-family:[[prefs.accessibility.captions.text_font.value]]; + background-color: [[computeBackgroundColor_( + prefs.accessibility.captions.background_opacity.value, + prefs.accessibility.captions.background_color.value)]]; + color: [[computeTextColor_( + prefs.accessibility.captions.text_opacity.value, + prefs.accessibility.captions.text_color.value)]]; + text-shadow: [[prefs.accessibility.captions.text_shadow.value]]; + padding: [[computePadding_( + prefs.accessibility.captions.text_size.value)]]"> + $i18n{quickBrownFox} + </span> </div> </template> <script src="captions_subpage.js"></script>
diff --git a/chrome/browser/resources/settings/people_page/lock_screen.html b/chrome/browser/resources/settings/people_page/lock_screen.html index a2ce568..a16743f6 100644 --- a/chrome/browser/resources/settings/people_page/lock_screen.html +++ b/chrome/browser/resources/settings/people_page/lock_screen.html
@@ -66,10 +66,10 @@ label="$i18n{enableScreenlock}"> </settings-toggle-button> - <settings-toggle-button id="enableLockScreenMediaKeys" - hidden="[[!lockScreenMediaKeysPreferenceEnabled_]]" - pref="{{prefs.ash.lock_screen_media_keys_enabled}}" - label="$i18n{lockScreenMediaKeys}"> + <settings-toggle-button id="enableLockScreenMediaControls" + hidden="[[!lockScreenMediaControlsPreferenceEnabled_]]" + pref="{{prefs.ash.lock_screen_media_controls_enabled}}" + label="$i18n{lockScreenMediaControls}"> </settings-toggle-button> <template is="dom-if" if="[[quickUnlockEnabled_]]">
diff --git a/chrome/browser/resources/settings/people_page/lock_screen.js b/chrome/browser/resources/settings/people_page/lock_screen.js index 6780493..b2f7116ce 100644 --- a/chrome/browser/resources/settings/people_page/lock_screen.js +++ b/chrome/browser/resources/settings/people_page/lock_screen.js
@@ -131,14 +131,14 @@ }, /** - * Whether the lock screen media keys preference is enabled by the + * Whether the lock screen media controls preference is enabled by the * feature flag. * @private */ - lockScreenMediaKeysPreferenceEnabled_: { + lockScreenMediaControlsPreferenceEnabled_: { type: Boolean, value: function() { - return loadTimeData.getBoolean('lockScreenMediaKeysEnabled'); + return loadTimeData.getBoolean('lockScreenMediaControlsEnabled'); }, readOnly: true, },
diff --git a/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html b/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html index a67ac0a..0045f54 100644 --- a/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html +++ b/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html
@@ -1,5 +1,6 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_checkbox/cr_checkbox.html"> <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
diff --git a/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.js b/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.js index ce300e5..146f226 100644 --- a/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.js +++ b/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.js
@@ -166,6 +166,8 @@ this.confirmButtonVisible_ = false; this.closeButtonVisible_ = true; break; + default: + assertNotReached(); } this.fire('credential-management-dialog-ready-for-testing'); },
diff --git a/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.js b/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.js index 69f476c0..813d93e5 100644 --- a/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.js +++ b/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.js
@@ -339,7 +339,7 @@ this.currentPINError_ = this.isValidPIN_(this.currentPIN_); if (this.currentPINError_ != '') { this.focusOn_(this.$.currentPIN); - this.fire('iron-announce', {message: this.currentPINError_}); + this.fire('iron-announce', {text: this.currentPINError_}); this.fire('ui-ready'); // for test synchronization. return; } @@ -348,7 +348,7 @@ this.newPINError_ = this.isValidPIN_(this.newPIN_); if (this.newPINError_ != '') { this.focusOn_(this.$.newPIN); - this.fire('iron-announce', {message: this.newPINError_}); + this.fire('iron-announce', {text: this.newPINError_}); this.fire('ui-ready'); // for test synchronization. return; } @@ -356,7 +356,7 @@ if (this.newPIN_ != this.confirmPIN_) { this.confirmPINError_ = this.i18n('securityKeysPINMismatch'); this.focusOn_(this.$.confirmPIN); - this.fire('iron-announce', {message: this.confirmPINError_}); + this.fire('iron-announce', {text: this.confirmPINError_}); this.fire('ui-ready'); // for test synchronization. return; } @@ -381,7 +381,7 @@ this.currentPINError_ = this.mismatchError_(this.retries_); this.setPINButtonValid_ = true; this.focusOn_(this.$.currentPIN); - this.fire('iron-announce', {message: this.currentPINError_}); + this.fire('iron-announce', {text: this.currentPINError_}); this.fire('ui-ready'); // for test synchronization. } else { // Unknown error.
diff --git a/chrome/browser/search/instant_service.cc b/chrome/browser/search/instant_service.cc index cc369c5..f5f02a0 100644 --- a/chrome/browser/search/instant_service.cc +++ b/chrome/browser/search/instant_service.cc
@@ -746,6 +746,7 @@ theme_provider.GetColor(ThemeProperties::COLOR_FRAME); theme_info_->color_light = theme_provider.GetColor(ThemeProperties::COLOR_NTP_BACKGROUND); + theme_info_->color_picked = theme_service->GetThemeColor(); } }
diff --git a/chrome/browser/service_process/service_process_control.cc b/chrome/browser/service_process/service_process_control.cc index 0cd60d25..fb38c90 100644 --- a/chrome/browser/service_process/service_process_control.cc +++ b/chrome/browser/service_process/service_process_control.cc
@@ -60,8 +60,10 @@ response_task_runner->PostTask( FROM_HERE, base::BindOnce(std::move(response_callback), nullptr)); } else { - base::PostDelayedTaskWithTraits( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, + base::PostDelayedTask( + FROM_HERE, + {base::ThreadPool(), base::MayBlock(), + base::TaskPriority::BEST_EFFORT}, base::BindOnce( &ConnectAsyncWithBackoff, std::move(interface_provider_request), server_name, num_retries_left - 1, retry_delay * 2, @@ -104,8 +106,9 @@ service_manager::mojom::InterfaceProviderPtr remote_interfaces; auto interface_provider_request = mojo::MakeRequest(&remote_interfaces); SetMojoHandle(std::move(remote_interfaces)); - base::PostTaskWithTraits( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, + base::PostTask( + FROM_HERE, + {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT}, base::BindOnce( &ConnectAsyncWithBackoff, std::move(interface_provider_request), GetServiceProcessServerName(), kMaxConnectionAttempts, @@ -299,9 +302,8 @@ // Run timeout task to make sure |histograms_callback| is called. histograms_timeout_callback_.Reset(base::Bind( &ServiceProcessControl::RunHistogramsCallback, base::Unretained(this))); - base::PostDelayedTaskWithTraits(FROM_HERE, {BrowserThread::UI}, - histograms_timeout_callback_.callback(), - timeout); + base::PostDelayedTask(FROM_HERE, {BrowserThread::UI}, + histograms_timeout_callback_.callback(), timeout); histograms_callback_ = histograms_callback; return true; @@ -356,8 +358,8 @@ if (launched_ || (retry_count_ >= kMaxLaunchDetectRetries) || process_.WaitForExitWithTimeout(base::TimeDelta(), &exit_code)) { process_.Close(); - base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&Launcher::Notify, this)); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(&Launcher::Notify, this)); return; } retry_count_++; @@ -379,11 +381,11 @@ process_ = base::LaunchProcess(*cmd_line_, options); if (process_.IsValid()) { saved_pid_ = process_.Pid(); - base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&Launcher::DoDetectLaunched, this)); + base::PostTask(FROM_HERE, {BrowserThread::IO}, + base::BindOnce(&Launcher::DoDetectLaunched, this)); } else { - base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&Launcher::Notify, this)); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(&Launcher::Notify, this)); } } #endif // !OS_MACOSX
diff --git a/chrome/browser/service_process/service_process_control_mac.mm b/chrome/browser/service_process/service_process_control_mac.mm index 9a622761..ed1262ba 100644 --- a/chrome/browser/service_process/service_process_control_mac.mm +++ b/chrome/browser/service_process/service_process_control_mac.mm
@@ -18,6 +18,6 @@ void ServiceProcessControl::Launcher::DoRun() { launched_ = mac::services::SubmitJob( GetServiceProcessJobOptions(cmd_line_.get(), false)); - base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&Launcher::Notify, this)); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(&Launcher::Notify, this)); }
diff --git a/chrome/browser/spellchecker/spellcheck_custom_dictionary.cc b/chrome/browser/spellchecker/spellcheck_custom_dictionary.cc index 31619d7..0decf90b 100644 --- a/chrome/browser/spellchecker/spellcheck_custom_dictionary.cc +++ b/chrome/browser/spellchecker/spellcheck_custom_dictionary.cc
@@ -222,8 +222,8 @@ SpellcheckCustomDictionary::SpellcheckCustomDictionary( const base::FilePath& dictionary_directory_name) - : task_runner_( - base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()})), + : task_runner_(base::CreateSequencedTaskRunner( + {base::ThreadPool(), base::MayBlock()})), custom_dictionary_path_( dictionary_directory_name.Append(chrome::kCustomDictionaryFileName)), is_loaded_(false) {} @@ -452,7 +452,7 @@ fix_invalid_file_.Reset( base::BindOnce(&SpellcheckCustomDictionary::FixInvalidFile, weak_ptr_factory_.GetWeakPtr(), std::move(result))); - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {content::BrowserThread::UI, base::TaskPriority::BEST_EFFORT}, fix_invalid_file_.callback());
diff --git a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc index 901060a..78432896 100644 --- a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc +++ b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
@@ -110,8 +110,8 @@ const std::string& language, content::BrowserContext* browser_context, SpellcheckService* spellcheck_service) - : task_runner_( - base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()})), + : task_runner_(base::CreateSequencedTaskRunner( + {base::ThreadPool(), base::MayBlock()})), language_(language), use_browser_spellchecker_(false), browser_context_(browser_context),
diff --git a/chrome/browser/spellchecker/spelling_request.cc b/chrome/browser/spellchecker/spelling_request.cc index a105477b..66aafc3 100644 --- a/chrome/browser/spellchecker/spelling_request.cc +++ b/chrome/browser/spellchecker/spelling_request.cc
@@ -128,10 +128,9 @@ base::WeakPtr<SpellingRequest> request, const std::vector<SpellCheckResult>& results) { // Local checking can happen on any thread - don't DCHECK thread. - base::PostTaskWithTraits( - FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(&SpellingRequest::OnLocalCheckCompleted, request, - results)); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, + base::BindOnce(&SpellingRequest::OnLocalCheckCompleted, + request, results)); } void SpellingRequest::OnLocalCheckCompleted(
diff --git a/chrome/browser/subresource_filter/chrome_subresource_filter_client.cc b/chrome/browser/subresource_filter/chrome_subresource_filter_client.cc index 573bf11..d9318b07 100644 --- a/chrome/browser/subresource_filter/chrome_subresource_filter_client.cc +++ b/chrome/browser/subresource_filter/chrome_subresource_filter_client.cc
@@ -77,8 +77,7 @@ std::make_unique<subresource_filter:: SubresourceFilterSafeBrowsingActivationThrottle>( navigation_handle, this, - base::CreateSingleThreadTaskRunnerWithTraits( - {content::BrowserThread::IO}), + base::CreateSingleThreadTaskRunner({content::BrowserThread::IO}), safe_browsing_service->database_manager())); }
diff --git a/chrome/browser/supervised_user/experimental/supervised_user_blacklist.cc b/chrome/browser/supervised_user/experimental/supervised_user_blacklist.cc index f9a12b50..ce45b25 100644 --- a/chrome/browser/supervised_user/experimental/supervised_user_blacklist.cc +++ b/chrome/browser/supervised_user/experimental/supervised_user_blacklist.cc
@@ -70,9 +70,9 @@ void SupervisedUserBlacklist::ReadFromFile(const base::FilePath& path, const base::Closure& done_callback) { - base::PostTaskWithTraitsAndReplyWithResult( + base::PostTaskAndReplyWithResult( FROM_HERE, - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, + {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, base::BindOnce(&ReadFromBinaryFileOnFileThread, path), base::BindOnce(&SupervisedUserBlacklist::OnReadFromFileCompleted,
diff --git a/chrome/browser/supervised_user/supervised_user_interstitial.cc b/chrome/browser/supervised_user/supervised_user_interstitial.cc index 8d2fe746..15fb01e 100644 --- a/chrome/browser/supervised_user/supervised_user_interstitial.cc +++ b/chrome/browser/supervised_user/supervised_user_interstitial.cc
@@ -79,9 +79,9 @@ friend class content::WebContentsUserData<TabCloser>; explicit TabCloser(WebContents* web_contents) : web_contents_(web_contents) { - base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&TabCloser::CloseTabImpl, - weak_ptr_factory_.GetWeakPtr())); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(&TabCloser::CloseTabImpl, + weak_ptr_factory_.GetWeakPtr())); } void CloseTabImpl() {
diff --git a/chrome/browser/supervised_user/supervised_user_service.cc b/chrome/browser/supervised_user/supervised_user_service.cc index bbc12e9..40550a8e 100644 --- a/chrome/browser/supervised_user/supervised_user_service.cc +++ b/chrome/browser/supervised_user/supervised_user_service.cc
@@ -576,9 +576,9 @@ const GURL& url) { DCHECK(blacklist_state_ == BlacklistLoadState::NOT_LOADED); blacklist_state_ = BlacklistLoadState::LOAD_STARTED; - base::PostTaskWithTraitsAndReplyWithResult( + base::PostTaskAndReplyWithResult( FROM_HERE, - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, + {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, base::BindOnce(&base::PathExists, path), base::BindOnce(&SupervisedUserService::OnBlacklistFileChecked,
diff --git a/chrome/browser/supervised_user/supervised_user_site_list.cc b/chrome/browser/supervised_user/supervised_user_site_list.cc index b464047..155b8f67 100644 --- a/chrome/browser/supervised_user/supervised_user_site_list.cc +++ b/chrome/browser/supervised_user/supervised_user_site_list.cc
@@ -90,9 +90,9 @@ const base::FilePath& large_icon_path, const base::FilePath& path, const LoadedCallback& callback) { - base::PostTaskWithTraitsAndReplyWithResult( + base::PostTaskAndReplyWithResult( FROM_HERE, - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, + {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, base::BindOnce(&ReadFileOnBlockingThread, path), base::BindOnce(&SupervisedUserSiteList::OnJsonLoaded, id, title,
diff --git a/chrome/browser/supervised_user/supervised_user_url_filter.cc b/chrome/browser/supervised_user/supervised_user_url_filter.cc index 7dba1385..cc80a45 100644 --- a/chrome/browser/supervised_user/supervised_user_url_filter.cc +++ b/chrome/browser/supervised_user/supervised_user_url_filter.cc
@@ -217,8 +217,9 @@ : default_behavior_(ALLOW), contents_(new Contents()), blacklist_(nullptr), - blocking_task_runner_(base::CreateTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, + blocking_task_runner_(base::CreateTaskRunner( + {base::ThreadPool(), base::MayBlock(), + base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})) {} SupervisedUserURLFilter::~SupervisedUserURLFilter() {
diff --git a/chrome/browser/sync/test/integration/printers_helper.cc b/chrome/browser/sync/test/integration/printers_helper.cc index 3d09f898..37135ae 100644 --- a/chrome/browser/sync/test/integration/printers_helper.cc +++ b/chrome/browser/sync/test/integration/printers_helper.cc
@@ -110,6 +110,16 @@ return printer; } +std::unique_ptr<sync_pb::PrinterSpecifics> CreateTestPrinterSpecifics( + int index) { + auto specifics = std::make_unique<sync_pb::PrinterSpecifics>(); + specifics->set_id(PrinterId(index)); + specifics->set_description("Description"); + specifics->set_uri(base::StringPrintf("ipp://192.168.1.%d", index)); + + return specifics; +} + void WaitForPrinterStoreToLoad(content::BrowserContext* context) { GetPrinterStore(context); // Run tasks to allow a ModelTypeStore to be associated with the
diff --git a/chrome/browser/sync/test/integration/printers_helper.h b/chrome/browser/sync/test/integration/printers_helper.h index cdd7a8d..463eebf 100644 --- a/chrome/browser/sync/test/integration/printers_helper.h +++ b/chrome/browser/sync/test/integration/printers_helper.h
@@ -16,11 +16,19 @@ class BrowserContext; } +namespace sync_pb { +class PrinterSpecifics; +} + namespace printers_helper { // Create a test printer. chromeos::Printer CreateTestPrinter(int index); +// Create a test printer, as PrinterSpecifics. +std::unique_ptr<sync_pb::PrinterSpecifics> CreateTestPrinterSpecifics( + int index); + // Add printer to the supplied store. void AddPrinter(chromeos::SyncedPrintersManager* manager, const chromeos::Printer& printer);
diff --git a/chrome/browser/sync/test/integration/two_client_printers_sync_test.cc b/chrome/browser/sync/test/integration/two_client_printers_sync_test.cc index 2ab8b2cc..551a8d7 100644 --- a/chrome/browser/sync/test/integration/two_client_printers_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_printers_sync_test.cc
@@ -6,22 +6,30 @@ #include "base/macros.h" #include "base/run_loop.h" +#include "base/test/metrics/histogram_tester.h" #include "build/build_config.h" +#include "chrome/browser/chromeos/printing/printers_sync_bridge.h" #include "chrome/browser/sync/test/integration/printers_helper.h" #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" #include "chrome/browser/sync/test/integration/sync_test.h" #include "content/public/test/test_utils.h" +#include "testing/gmock/include/gmock/gmock.h" namespace { using printers_helper::AddPrinter; using printers_helper::AllProfilesContainSamePrinters; -using printers_helper::EditPrinterDescription; using printers_helper::CreateTestPrinter; +using printers_helper::CreateTestPrinterSpecifics; +using printers_helper::EditPrinterDescription; using printers_helper::GetPrinterCount; using printers_helper::GetPrinterStore; using printers_helper::PrintersMatchChecker; using printers_helper::RemovePrinter; +using ::testing::EndsWith; +using ::testing::IsEmpty; +using ::testing::Not; +using ::testing::StartsWith; constexpr char kOverwrittenDescription[] = "I should not show up"; constexpr char kLatestDescription[] = "YAY! More recent changes win!"; @@ -213,3 +221,34 @@ EXPECT_EQ(4, GetPrinterCount(0)); EXPECT_TRUE(AllProfilesContainSamePrinters()); } + +IN_PROC_BROWSER_TEST_F(TwoClientPrintersSyncTest, MakeAndModelMigration) { + ASSERT_TRUE(SetupClients()); + base::HistogramTester histograms; + const char kMake[] = "make"; + const char kModel[] = "model"; + + // Initialize sync bridge with test printer. + auto printer = CreateTestPrinterSpecifics(0); + const std::string spec_printer_id = printer->id(); + printer->set_manufacturer(kMake); + printer->set_model(kModel); + auto* bridge = GetPrinterStore(0)->GetSyncBridge(); + bridge->AddPrinter(std::move(printer)); + + // Confirm that the bridge is not migrated. + auto spec_printer = bridge->GetPrinter(spec_printer_id); + ASSERT_TRUE(spec_printer); + ASSERT_THAT(spec_printer->make_and_model(), IsEmpty()); + + ASSERT_TRUE(SetupSync()); + spec_printer = bridge->GetPrinter(spec_printer_id); + ASSERT_TRUE(spec_printer); + + base::StringPiece make_and_model = spec_printer->make_and_model(); + EXPECT_THAT(make_and_model, Not(IsEmpty())); + EXPECT_THAT(make_and_model, StartsWith(kMake)); + EXPECT_THAT(make_and_model, EndsWith(kModel)); + histograms.ExpectBucketCount("Printing.CUPS.MigratedMakeAndModel", + 1 /* kMigrated */, 1); +}
diff --git a/chrome/browser/tracing/chrome_tracing_delegate_browsertest.cc b/chrome/browser/tracing/chrome_tracing_delegate_browsertest.cc index 507d18f..fe25c19 100644 --- a/chrome/browser/tracing/chrome_tracing_delegate_browsertest.cc +++ b/chrome/browser/tracing/chrome_tracing_delegate_browsertest.cc
@@ -104,10 +104,10 @@ done_callback) { receive_count_ += 1; - base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(std::move(done_callback), true)); - base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI}, - on_upload_callback_); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, + base::BindOnce(std::move(done_callback), true)); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, + on_upload_callback_); } void OnStartedFinalizing(bool success) { @@ -115,8 +115,8 @@ last_on_started_finalizing_success_ = success; if (!on_started_finalization_callback_.is_null()) { - base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI}, - on_started_finalization_callback_); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, + on_started_finalization_callback_); } }
diff --git a/chrome/browser/tracing/crash_service_uploader.cc b/chrome/browser/tracing/crash_service_uploader.cc index 55e3412..257f29e 100644 --- a/chrome/browser/tracing/crash_service_uploader.cc +++ b/chrome/browser/tracing/crash_service_uploader.cc
@@ -101,9 +101,8 @@ base::NumberToString(response_code); } - base::PostTaskWithTraits( - FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(std::move(done_callback_), success, feedback)); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, + base::BindOnce(std::move(done_callback_), success, feedback)); simple_url_loader_.reset(); } @@ -116,8 +115,8 @@ if (progress_callback_.is_null()) return; - base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(progress_callback_, current, total)); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, + base::BindOnce(progress_callback_, current, total)); } void TraceCrashServiceUploader::DoUpload( @@ -131,8 +130,8 @@ progress_callback_ = progress_callback; done_callback_ = std::move(done_callback); - base::PostTaskWithTraits( - FROM_HERE, {base::TaskPriority::BEST_EFFORT}, + base::PostTask( + FROM_HERE, {base::ThreadPool(), base::TaskPriority::BEST_EFFORT}, base::BindOnce(&TraceCrashServiceUploader::DoCompressOnBackgroundThread, base::Unretained(this), file_contents, upload_mode, upload_url_, std::move(metadata))); @@ -207,7 +206,7 @@ SetupMultipart(product, version, std::move(metadata), "trace.json.gz", compressed_contents, &post_data); - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {content::BrowserThread::UI}, base::BindOnce(&TraceCrashServiceUploader::CreateAndStartURLLoader, base::Unretained(this), upload_url, post_data)); @@ -216,7 +215,7 @@ void TraceCrashServiceUploader::OnUploadError( const std::string& error_message) { LOG(ERROR) << error_message; - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {content::BrowserThread::UI}, base::BindOnce(std::move(done_callback_), false, error_message)); }
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 58a5497..3dafaaee 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -2445,6 +2445,7 @@ ] configs += [ "//build/config/linux:x11" ] deps += [ + "//components/dbus/menu", "//ui/events/devices", "//ui/events/devices/x11", "//ui/events/platform/x11", @@ -3053,8 +3054,11 @@ "views/tabs/tab_strip_layout.h", "views/tabs/tab_strip_layout_helper.cc", "views/tabs/tab_strip_layout_helper.h", + "views/tabs/tab_strip_layout_types.h", "views/tabs/tab_style_views.cc", "views/tabs/tab_style_views.h", + "views/tabs/tab_width_constraints.cc", + "views/tabs/tab_width_constraints.h", "views/tabs/window_finder.h", "views/task_manager_view.cc", "views/task_manager_view.h", @@ -3848,10 +3852,6 @@ deps += [ "//dbus" ] } - if (use_gio) { - configs += [ "//build/linux:gio_config" ] - } - if (use_nss_certs) { sources += [ "crypto_module_delegate_nss.cc",
diff --git a/chrome/browser/ui/ash/assistant/assistant_setup.cc b/chrome/browser/ui/ash/assistant/assistant_setup.cc index 0c38d539..5395f853 100644 --- a/chrome/browser/ui/ash/assistant/assistant_setup.cc +++ b/chrome/browser/ui/ash/assistant/assistant_setup.cc
@@ -8,80 +8,23 @@ #include <utility> #include "ash/public/cpp/notification_utils.h" -#include "ash/public/cpp/vector_icons/vector_icons.h" #include "base/bind.h" #include "base/bind_helpers.h" -#include "base/metrics/histogram_macros.h" -#include "base/strings/utf_string_conversions.h" #include "base/threading/sequenced_task_runner_handle.h" -#include "chrome/browser/chromeos/login/ui/login_display_host.h" -#include "chrome/browser/notifications/notification_display_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/settings_window_manager_chromeos.h" #include "chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_ui.h" #include "chrome/common/webui_url_constants.h" -#include "chrome/grit/generated_resources.h" #include "chromeos/services/assistant/public/cpp/assistant_prefs.h" #include "chromeos/services/assistant/public/mojom/constants.mojom.h" #include "chromeos/services/assistant/public/proto/settings_ui.pb.h" #include "components/arc/arc_prefs.h" #include "components/prefs/pref_service.h" -#include "components/user_manager/user_manager.h" #include "services/service_manager/public/cpp/connector.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/gfx/paint_vector_icon.h" -#include "ui/message_center/public/cpp/notification.h" -#include "ui/message_center/public/cpp/notification_delegate.h" using chromeos::assistant::ConsentFlowUi; -namespace { - -constexpr char kAssistantDisplaySource[] = "Assistant"; -constexpr char kHotwordNotificationId[] = "assistant/hotword"; -constexpr char kNotifierAssistant[] = "assistant"; - -// Delegate for assistant hotword notification. -class AssistantHotwordNotificationDelegate - : public message_center::NotificationDelegate { - public: - explicit AssistantHotwordNotificationDelegate(Profile* profile) - : profile_(profile) {} - - // message_center::NotificationDelegate: - void Close(bool by_user) override { - if (!by_user) - return; - - HandleHotwordEnableNotificationResult(false /* enable */); - } - - void Click(const base::Optional<int>& button_index, - const base::Optional<base::string16>& reply) override { - HandleHotwordEnableNotificationResult(true /* enable */); - NotificationDisplayService::GetForProfile(profile_)->Close( - NotificationHandler::Type::TRANSIENT, kHotwordNotificationId); - } - - private: - ~AssistantHotwordNotificationDelegate() override = default; - - void HandleHotwordEnableNotificationResult(bool enable) { - if (enable) { - chrome::SettingsWindowManager::GetInstance()->ShowOSSettings( - ProfileManager::GetActiveUserProfile(), chrome::kAssistantSubPage); - } - UMA_HISTOGRAM_BOOLEAN("Assistant.HotwordEnableNotification", enable); - } - - Profile* profile_; - - DISALLOW_COPY_AND_ASSIGN(AssistantHotwordNotificationDelegate); -}; - -} // namespace - AssistantSetup::AssistantSetup(service_manager::Connector* connector) : connector_(connector), weak_factory_(this) { arc::VoiceInteractionControllerClient::Get()->AddObserver(this); @@ -101,47 +44,12 @@ if (state == ash::mojom::VoiceInteractionState::NOT_READY) return; - // Sync activity control state when assistant service started. + // Sync settings state when Assistant service started. if (!settings_manager_) - SyncActivityControlState(); - - // If the OOBE flow is active, no need to show the notification since it is - // included in the flow. - if (user_manager::UserManager::Get()->IsCurrentUserNew() && - chromeos::LoginDisplayHost::default_host()) { - return; - } - - Profile* profile = ProfileManager::GetActiveUserProfile(); - PrefService* prefs = profile->GetPrefs(); - if (!prefs->FindPreference(arc::prefs::kVoiceInteractionHotwordEnabled) - ->IsDefaultValue()) { - return; - } - // TODO(xiaohuic): need better ways to decide when to show the notification. - // Avoid the notification from keep showing up. - prefs->SetBoolean(arc::prefs::kVoiceInteractionHotwordEnabled, false); - - const base::string16 title = - l10n_util::GetStringUTF16(IDS_ASSISTANT_HOTWORD_NOTIFICATION_TITLE); - const base::string16 display_source = - base::UTF8ToUTF16(kAssistantDisplaySource); - - auto notification = ash::CreateSystemNotification( - message_center::NOTIFICATION_TYPE_SIMPLE, kHotwordNotificationId, title, - base::string16(), display_source, GURL(), - message_center::NotifierId(message_center::NotifierType::SYSTEM_COMPONENT, - kNotifierAssistant), - {}, base::MakeRefCounted<AssistantHotwordNotificationDelegate>(profile), - ash::kNotificationAssistantIcon, - message_center::SystemNotificationWarningLevel::NORMAL); - - NotificationDisplayService::GetForProfile(profile)->Display( - NotificationHandler::Type::TRANSIENT, *notification, - /*metadata=*/nullptr); + SyncSettingsState(); } -void AssistantSetup::SyncActivityControlState() { +void AssistantSetup::SyncSettingsState() { // Set up settings mojom. connector_->BindInterface(chromeos::assistant::mojom::kServiceName, mojo::MakeRequest(&settings_manager_)); @@ -152,6 +60,7 @@ consent_flow_ui->set_flow_id( chromeos::assistant::ActivityControlSettingsUiSelector:: ASSISTANT_SUW_ONBOARDING_ON_CHROME_OS); + selector.set_gaia_user_context_ui(true); settings_manager_->GetSettings( selector.SerializeAsString(), base::BindOnce(&AssistantSetup::OnGetSettingsResponse, @@ -163,13 +72,28 @@ if (!settings_ui.ParseFromString(settings)) return; + // Sync domain policy status. + if (settings_ui.has_gaia_user_context_ui()) { + const auto& gaia_user_context_ui = settings_ui.gaia_user_context_ui(); + if (gaia_user_context_ui.assistant_disabled_by_dasher_domain()) { + DVLOG(1) << "Assistant is disabled by domain policy."; + PrefService* prefs = ProfileManager::GetActiveUserProfile()->GetPrefs(); + prefs->SetBoolean(chromeos::assistant::prefs::kAssistantDisabledByPolicy, + true); + prefs->SetBoolean(arc::prefs::kVoiceInteractionEnabled, false); + return; + } + } else { + LOG(ERROR) << "Failed to get gaia user context"; + } + + // Sync activity control status. if (!settings_ui.has_consent_flow_ui()) { LOG(ERROR) << "Failed to get activity control status."; return; } - - auto consent_status = settings_ui.consent_flow_ui().consent_status(); - auto& consent_ui = settings_ui.consent_flow_ui().consent_ui(); + const auto& consent_status = settings_ui.consent_flow_ui().consent_status(); + const auto& consent_ui = settings_ui.consent_flow_ui().consent_ui(); Profile* profile = ProfileManager::GetActiveUserProfile(); PrefService* prefs = profile->GetPrefs(); switch (consent_status) {
diff --git a/chrome/browser/ui/ash/assistant/assistant_setup.h b/chrome/browser/ui/ash/assistant/assistant_setup.h index d620570..2f571a34 100644 --- a/chrome/browser/ui/ash/assistant/assistant_setup.h +++ b/chrome/browser/ui/ash/assistant/assistant_setup.h
@@ -35,7 +35,7 @@ // arc::VoiceInteractionControllerClient::Observer overrides void OnStateChanged(ash::mojom::VoiceInteractionState state) override; - void SyncActivityControlState(); + void SyncSettingsState(); void OnGetSettingsResponse(const std::string& settings); service_manager::Connector* connector_;
diff --git a/chrome/browser/ui/ash/launcher/OWNERS b/chrome/browser/ui/ash/launcher/OWNERS index e90111b8..23593dd 100644 --- a/chrome/browser/ui/ash/launcher/OWNERS +++ b/chrome/browser/ui/ash/launcher/OWNERS
@@ -2,4 +2,4 @@ stevenjb@chromium.org khmel@chromium.org -# COMPONENTS: UI>Shell>Shelf \ No newline at end of file +# COMPONENT: UI>Shell>Shelf \ No newline at end of file
diff --git a/chrome/browser/ui/certificate_dialogs.cc b/chrome/browser/ui/certificate_dialogs.cc index 2f4d0fa0..5c3d6f7c 100644 --- a/chrome/browser/ui/certificate_dialogs.cc +++ b/chrome/browser/ui/certificate_dialogs.cc
@@ -152,8 +152,8 @@ } if (!data.empty()) { - base::PostTaskWithTraits(FROM_HERE, {base::MayBlock()}, - base::BindOnce(&WriterCallback, path, data)); + base::PostTask(FROM_HERE, {base::ThreadPool(), base::MayBlock()}, + base::BindOnce(&WriterCallback, path, data)); } delete this;
diff --git a/chrome/browser/ui/crypto_module_delegate_nss.cc b/chrome/browser/ui/crypto_module_delegate_nss.cc index 88f1aef..1232d04 100644 --- a/chrome/browser/ui/crypto_module_delegate_nss.cc +++ b/chrome/browser/ui/crypto_module_delegate_nss.cc
@@ -31,7 +31,7 @@ DCHECK(!event_.IsSignaled()); event_.Reset(); - if (base::PostTaskWithTraits( + if (base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce(&ChromeNSSCryptoModuleDelegate::ShowDialog, // This method blocks on |event_| until the task
diff --git a/chrome/browser/ui/extensions/application_launch.cc b/chrome/browser/ui/extensions/application_launch.cc index 5dcf424..bcc27e4 100644 --- a/chrome/browser/ui/extensions/application_launch.cc +++ b/chrome/browser/ui/extensions/application_launch.cc
@@ -413,7 +413,6 @@ NavigateParams nav_params(browser, url, transition); nav_params.disposition = disposition; - nav_params.opener = params.opener; Navigate(&nav_params); WebContents* web_contents = nav_params.navigated_or_inserted_contents;
diff --git a/chrome/browser/ui/extensions/hosted_app_browsertest.cc b/chrome/browser/ui/extensions/hosted_app_browsertest.cc index deefdbc..07d7abde 100644 --- a/chrome/browser/ui/extensions/hosted_app_browsertest.cc +++ b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
@@ -1094,7 +1094,7 @@ } // Tests that PWA menus have an uninstall option. -IN_PROC_BROWSER_TEST_P(HostedAppPWAOnlyTest, UninstallMenuOption) { +IN_PROC_BROWSER_TEST_P(SharedPWATest, UninstallMenuOption) { ASSERT_TRUE(https_server()->Start()); ASSERT_TRUE(embedded_test_server()->Start());
diff --git a/chrome/browser/ui/global_error/global_error_browsertest.cc b/chrome/browser/ui/global_error/global_error_browsertest.cc index 783b0c92..49fde3e 100644 --- a/chrome/browser/ui/global_error/global_error_browsertest.cc +++ b/chrome/browser/ui/global_error/global_error_browsertest.cc
@@ -165,8 +165,8 @@ ->OnBlacklistUpdated(); base::RunLoop().RunUntilIdle(); base::RunLoop flush_io; - base::PostTaskWithTraitsAndReply(FROM_HERE, {content::BrowserThread::IO}, - base::DoNothing(), flush_io.QuitClosure()); + base::PostTaskAndReply(FROM_HERE, {content::BrowserThread::IO}, + base::DoNothing(), flush_io.QuitClosure()); flush_io.Run(); // Oh no! This relies on RunUntilIdle() to show the bubble. The bubble is
diff --git a/chrome/browser/ui/hung_plugin_tab_helper.cc b/chrome/browser/ui/hung_plugin_tab_helper.cc index a416e6bb..6acfe4c 100644 --- a/chrome/browser/ui/hung_plugin_tab_helper.cc +++ b/chrome/browser/ui/hung_plugin_tab_helper.cc
@@ -167,8 +167,8 @@ } void HungPluginTabHelper::KillPlugin(int child_id) { - base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO}, - base::BindOnce(&KillPluginOnIOThread, child_id)); + base::PostTask(FROM_HERE, {content::BrowserThread::IO}, + base::BindOnce(&KillPluginOnIOThread, child_id)); } HungPluginTabHelper::HungPluginTabHelper(content::WebContents* contents)
diff --git a/chrome/browser/ui/network_profile_bubble.cc b/chrome/browser/ui/network_profile_bubble.cc index 0174a14..b9b88a3 100644 --- a/chrome/browser/ui/network_profile_bubble.cc +++ b/chrome/browser/ui/network_profile_bubble.cc
@@ -139,8 +139,8 @@ } if (profile_on_network) { RecordUmaEvent(METRIC_PROFILE_ON_NETWORK); - base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(&NotifyNetworkProfileDetected)); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, + base::BindOnce(&NotifyNetworkProfileDetected)); } else { RecordUmaEvent(METRIC_PROFILE_NOT_ON_NETWORK); }
diff --git a/chrome/browser/ui/page_info/page_info.cc b/chrome/browser/ui/page_info/page_info.cc index 138cd34..b0c14e4 100644 --- a/chrome/browser/ui/page_info/page_info.cc +++ b/chrome/browser/ui/page_info/page_info.cc
@@ -204,10 +204,10 @@ if (info.type == CONTENT_SETTINGS_TYPE_AUTOPLAY) return false; - // Only display the Native File System write permission if it's currently - // being used. + // Display the Native File System write permission if the Native File System + // API is currently being used. if (info.type == CONTENT_SETTINGS_TYPE_NATIVE_FILE_SYSTEM_WRITE_GUARD && - web_contents->HasWritableNativeFileSystemHandles()) { + web_contents->HasNativeFileSystemHandles()) { return true; } #endif
diff --git a/chrome/browser/ui/views/frame/DEPS b/chrome/browser/ui/views/frame/DEPS index 39901e3f..8bfaa60 100644 --- a/chrome/browser/ui/views/frame/DEPS +++ b/chrome/browser/ui/views/frame/DEPS
@@ -6,6 +6,9 @@ "browser_frame_ash\.*": [ "+ash", ], + "global_menu_bar_.*x11\.*": [ + "+dbus", + ], "top_controls_slide_controller_chromeos_browsertest.cc": [ "+cc/base/math_util.h", ],
diff --git a/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.cc b/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.cc index f6254b5..d46b3d2e2 100644 --- a/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.cc +++ b/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.cc
@@ -5,17 +5,21 @@ #include "chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h" #include "base/bind.h" -#include "base/debug/leak_annotations.h" +#include "base/bind_helpers.h" #include "base/logging.h" +#include "base/stl_util.h" #include "chrome/browser/ui/views/frame/global_menu_bar_x11.h" -#include "content/public/browser/browser_thread.h" - -using content::BrowserThread; +#include "components/dbus/thread_linux/dbus_thread_linux.h" +#include "dbus/bus.h" +#include "dbus/message.h" +#include "dbus/object_path.h" +#include "dbus/object_proxy.h" namespace { const char kAppMenuRegistrarName[] = "com.canonical.AppMenu.Registrar"; const char kAppMenuRegistrarPath[] = "/com/canonical/AppMenu/Registrar"; +const char kAppMenuRegistrarInterface[] = "com.canonical.AppMenu.Registrar"; } // namespace @@ -24,118 +28,111 @@ return base::Singleton<GlobalMenuBarRegistrarX11>::get(); } -void GlobalMenuBarRegistrarX11::OnWindowMapped(unsigned long xid) { - live_xids_.insert(xid); - - if (registrar_proxy_) - RegisterXID(xid); +void GlobalMenuBarRegistrarX11::OnMenuBarCreated(GlobalMenuBarX11* menu) { + if (base::Contains(menus_, menu)) { + NOTREACHED(); + return; + } + menus_[menu] = kUninitialized; + if (service_has_owner_) + InitializeMenu(menu); } -void GlobalMenuBarRegistrarX11::OnWindowUnmapped(unsigned long xid) { - if (registrar_proxy_) - UnregisterXID(xid); - - live_xids_.erase(xid); +void GlobalMenuBarRegistrarX11::OnMenuBarDestroyed(GlobalMenuBarX11* menu) { + DCHECK(base::Contains(menus_, menu)); + if (menus_[menu] == kRegistered) { + dbus::MethodCall method_call(kAppMenuRegistrarInterface, + "UnregisterWindow"); + dbus::MessageWriter writer(&method_call); + writer.AppendUint32(menu->xid()); + registrar_proxy_->CallMethod(&method_call, + dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::DoNothing()); + } + menus_.erase(menu); } -GlobalMenuBarRegistrarX11::GlobalMenuBarRegistrarX11() - : registrar_proxy_(nullptr) { - // libdbusmenu uses the gio version of dbus; I tried using the code in dbus/, - // but it looks like that's isn't sharing the bus name with the gio version, - // even when |connection_type| is set to SHARED. - g_dbus_proxy_new_for_bus( - G_BUS_TYPE_SESSION, - static_cast<GDBusProxyFlags>( - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | - G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | - G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START), - nullptr, - kAppMenuRegistrarName, - kAppMenuRegistrarPath, - kAppMenuRegistrarName, - nullptr, // TODO: Probalby want a real cancelable. - static_cast<GAsyncReadyCallback>(OnProxyCreatedThunk), - this); +GlobalMenuBarRegistrarX11::GlobalMenuBarRegistrarX11() { + dbus::Bus::Options bus_options; + bus_options.bus_type = dbus::Bus::SESSION; + bus_options.connection_type = dbus::Bus::PRIVATE; + bus_options.dbus_task_runner = dbus_thread_linux::GetTaskRunner(); + bus_ = base::MakeRefCounted<dbus::Bus>(bus_options); + + registrar_proxy_ = bus_->GetObjectProxy( + kAppMenuRegistrarName, dbus::ObjectPath(kAppMenuRegistrarPath)); + + dbus::Bus::GetServiceOwnerCallback callback = + base::BindRepeating(&GlobalMenuBarRegistrarX11::OnNameOwnerChanged, + weak_ptr_factory_.GetWeakPtr()); + bus_->ListenForServiceOwnerChange(kAppMenuRegistrarName, callback); + bus_->GetServiceOwner(kAppMenuRegistrarName, callback); } GlobalMenuBarRegistrarX11::~GlobalMenuBarRegistrarX11() { - if (registrar_proxy_) { - g_signal_handlers_disconnect_by_func( - registrar_proxy_, - reinterpret_cast<void*>(OnNameOwnerChangedThunk), - this); - g_object_unref(registrar_proxy_); - } + DCHECK(menus_.empty()); + bus_->GetDBusTaskRunner()->PostTask( + FROM_HERE, base::BindOnce(&dbus::Bus::ShutdownAndBlock, bus_)); } -void GlobalMenuBarRegistrarX11::RegisterXID(unsigned long xid) { - DCHECK(registrar_proxy_); - std::string path = GlobalMenuBarX11::GetPathForWindow(xid); - - ANNOTATE_SCOPED_MEMORY_LEAK; // http://crbug.com/314087 - // TODO(erg): The mozilla implementation goes to a lot of callback trouble - // just to make sure that they react to make sure there's some sort of - // cancelable object; including making a whole callback just to handle the - // cancelable. - // - // I don't see any reason why we should care if "RegisterWindow" completes or - // not. - g_dbus_proxy_call(registrar_proxy_, - "RegisterWindow", - g_variant_new("(uo)", xid, path.c_str()), - G_DBUS_CALL_FLAGS_NONE, -1, - nullptr, - nullptr, - nullptr); +void GlobalMenuBarRegistrarX11::InitializeMenu(GlobalMenuBarX11* menu) { + DCHECK(base::Contains(menus_, menu)); + DCHECK_EQ(menus_[menu], kUninitialized); + menus_[menu] = kInitializing; + menu->Initialize(base::BindOnce(&GlobalMenuBarRegistrarX11::OnMenuInitialized, + weak_ptr_factory_.GetWeakPtr(), menu)); } -void GlobalMenuBarRegistrarX11::UnregisterXID(unsigned long xid) { - DCHECK(registrar_proxy_); - std::string path = GlobalMenuBarX11::GetPathForWindow(xid); - - ANNOTATE_SCOPED_MEMORY_LEAK; // http://crbug.com/314087 - // TODO(erg): The mozilla implementation goes to a lot of callback trouble - // just to make sure that they react to make sure there's some sort of - // cancelable object; including making a whole callback just to handle the - // cancelable. - // - // I don't see any reason why we should care if "UnregisterWindow" completes - // or not. - g_dbus_proxy_call(registrar_proxy_, - "UnregisterWindow", - g_variant_new("(u)", xid), - G_DBUS_CALL_FLAGS_NONE, -1, - nullptr, - nullptr, - nullptr); +void GlobalMenuBarRegistrarX11::RegisterMenu(GlobalMenuBarX11* menu) { + DCHECK(base::Contains(menus_, menu)); + DCHECK(menus_[menu] == kInitializeSucceeded || menus_[menu] == kRegistered); + menus_[menu] = kRegistered; + dbus::MethodCall method_call(kAppMenuRegistrarInterface, "RegisterWindow"); + dbus::MessageWriter writer(&method_call); + writer.AppendUint32(menu->xid()); + writer.AppendObjectPath(dbus::ObjectPath(menu->GetPath())); + registrar_proxy_->CallMethod( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, base::DoNothing()); } -void GlobalMenuBarRegistrarX11::OnProxyCreated(GObject* source, - GAsyncResult* result) { - GError* error = nullptr; - GDBusProxy* proxy = g_dbus_proxy_new_for_bus_finish(result, &error); - if (error) { - g_error_free(error); - return; - } - - // TODO(erg): Mozilla's implementation has a workaround for GDBus - // cancellation here. However, it's marked as fixed. If there's weird - // problems with cancelation, look at how they fixed their issues. - - registrar_proxy_ = proxy; - - g_signal_connect(registrar_proxy_, "notify::g-name-owner", - G_CALLBACK(OnNameOwnerChangedThunk), this); - - OnNameOwnerChanged(nullptr, nullptr); +void GlobalMenuBarRegistrarX11::OnMenuInitialized(GlobalMenuBarX11* menu, + bool success) { + DCHECK(base::Contains(menus_, menu)); + DCHECK(menus_[menu] == kInitializing); + menus_[menu] = success ? kInitializeSucceeded : kInitializeFailed; + if (success && service_has_owner_) + RegisterMenu(menu); } -void GlobalMenuBarRegistrarX11::OnNameOwnerChanged(GObject* /* ignored */, - GParamSpec* /* ignored */) { - // If the name owner changed, we need to reregister all the live xids with +void GlobalMenuBarRegistrarX11::OnNameOwnerChanged( + const std::string& service_owner) { + service_has_owner_ = !service_owner.empty(); + + // If the name owner changed, we need to reregister all the live menus with // the system. - for (auto it = live_xids_.begin(); it != live_xids_.end(); ++it) { - RegisterXID(*it); + for (const auto& pair : menus_) { + GlobalMenuBarX11* menu = pair.first; + switch (pair.second) { + case kUninitialized: + if (service_has_owner_) + InitializeMenu(menu); + break; + case kInitializing: + // Wait for Initialize() to finish. + break; + case kInitializeFailed: + // Don't try to recover. + break; + case kInitializeSucceeded: + if (service_has_owner_) + RegisterMenu(menu); + break; + case kRegistered: + if (service_has_owner_) + RegisterMenu(menu); + else + menus_[menu] = kInitializeSucceeded; + break; + } } }
diff --git a/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h b/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h index 55c10d7..357b7a1 100644 --- a/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h +++ b/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h
@@ -5,48 +5,78 @@ #ifndef CHROME_BROWSER_UI_VIEWS_FRAME_GLOBAL_MENU_BAR_REGISTRAR_X11_H_ #define CHROME_BROWSER_UI_VIEWS_FRAME_GLOBAL_MENU_BAR_REGISTRAR_X11_H_ -#include <gio/gio.h> - -#include <set> +#include <map> +#include <string> #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/singleton.h" -#include "ui/base/glib/glib_signal.h" +#include "base/memory/weak_ptr.h" -// Advertises our menu bars to Unity. +namespace dbus { +class Bus; +class ObjectProxy; +} // namespace dbus + +class GlobalMenuBarX11; + +// Advertises our menu bars to com.canonical.AppMenu.Registrar. // -// GlobalMenuBarX11 is responsible for managing the DbusmenuServer for each -// XID. We need a separate object to own the dbus channel to -// com.canonical.AppMenu.Registrar and to register/unregister the mapping -// between a XID and the DbusmenuServer instance we are offering. +// GlobalMenuBarRegistrarX11 is responsible for managing the dbus::Bus shared by +// each menu. We need a separate object to own the dbus channel and to +// register/unregister the mapping between a menu and the com.canonical.dbusmenu +// instance we are offering. class GlobalMenuBarRegistrarX11 { public: static GlobalMenuBarRegistrarX11* GetInstance(); - void OnWindowMapped(unsigned long xid); - void OnWindowUnmapped(unsigned long xid); + void OnMenuBarCreated(GlobalMenuBarX11* menu); + void OnMenuBarDestroyed(GlobalMenuBarX11* menu); + + dbus::Bus* bus() { return bus_.get(); } private: friend struct base::DefaultSingletonTraits<GlobalMenuBarRegistrarX11>; + enum MenuState { + // Initialize() hasn't been called. + kUninitialized, + + // Initialize() has been called and we're waiting for an async result. + kInitializing, + + // Initialize() failed, and the window will not be registered. + kInitializeFailed, + + // Initialize() succeeded and we will register the window once the appmenu + // registrar has an owner. + kInitializeSucceeded, + + // Initialize() succeeded and RegisterMenu has been sent. + kRegistered, + }; + GlobalMenuBarRegistrarX11(); ~GlobalMenuBarRegistrarX11(); + void InitializeMenu(GlobalMenuBarX11* menu); + // Sends the actual message. - void RegisterXID(unsigned long xid); - void UnregisterXID(unsigned long xid); + void RegisterMenu(GlobalMenuBarX11* menu); - CHROMEG_CALLBACK_1(GlobalMenuBarRegistrarX11, void, OnProxyCreated, - GObject*, GAsyncResult*); - CHROMEG_CALLBACK_1(GlobalMenuBarRegistrarX11, void, OnNameOwnerChanged, - GObject*, GParamSpec*); + void OnMenuInitialized(GlobalMenuBarX11* menu, bool success); - GDBusProxy* registrar_proxy_; + void OnNameOwnerChanged(const std::string& service_owner); - // Window XIDs which want to be registered, but haven't yet been because - // we're waiting for the proxy to become available. - std::set<unsigned long> live_xids_; + scoped_refptr<dbus::Bus> bus_; + dbus::ObjectProxy* registrar_proxy_; + bool service_has_owner_ = false; + + // Maps menus to flags that indicate if the menu has been successfully + // initialized. + std::map<GlobalMenuBarX11*, MenuState> menus_; + + base::WeakPtrFactory<GlobalMenuBarRegistrarX11> weak_ptr_factory_{this}; DISALLOW_COPY_AND_ASSIGN(GlobalMenuBarRegistrarX11); };
diff --git a/chrome/browser/ui/views/frame/global_menu_bar_x11.cc b/chrome/browser/ui/views/frame/global_menu_bar_x11.cc index 0f0816a..69736824 100644 --- a/chrome/browser/ui/views/frame/global_menu_bar_x11.cc +++ b/chrome/browser/ui/views/frame/global_menu_bar_x11.cc
@@ -8,11 +8,12 @@ #include <glib-object.h> #include <stddef.h> +#include <limits> +#include <memory> #include <utility> #include <vector> #include "base/bind.h" -#include "base/debug/leak_annotations.h" #include "base/logging.h" #include "base/macros.h" #include "base/stl_util.h" @@ -30,7 +31,6 @@ #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_live_tab_context.h" -#include "chrome/browser/ui/views/frame/browser_desktop_window_tree_host_x11.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h" #include "chrome/grit/generated_resources.h" @@ -39,92 +39,22 @@ #include "components/prefs/pref_service.h" #include "components/sessions/core/tab_restore_service.h" #include "components/strings/grit/components_strings.h" +#include "dbus/object_path.h" #include "ui/base/accelerators/menu_label_accelerator_util_linux.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/base/models/menu_model.h" +#include "ui/base/models/menu_separator_types.h" #include "ui/events/keycodes/keyboard_code_conversion_x.h" #include "ui/gfx/text_elider.h" -// libdbusmenu-glib types -typedef struct _DbusmenuMenuitem DbusmenuMenuitem; -typedef DbusmenuMenuitem* (*dbusmenu_menuitem_new_func)(); -typedef bool (*dbusmenu_menuitem_child_add_position_func)( - DbusmenuMenuitem* parent, - DbusmenuMenuitem* child, - unsigned int position); -typedef DbusmenuMenuitem* (*dbusmenu_menuitem_child_append_func)( - DbusmenuMenuitem* parent, - DbusmenuMenuitem* child); -typedef bool (*dbusmenu_menuitem_child_delete_func)( - DbusmenuMenuitem* parent, - DbusmenuMenuitem* child); -typedef GList* (*dbusmenu_menuitem_get_children_func)( - DbusmenuMenuitem* item); -typedef DbusmenuMenuitem* (*dbusmenu_menuitem_property_set_func)( - DbusmenuMenuitem* item, - const char* property, - const char* value); -typedef DbusmenuMenuitem* (*dbusmenu_menuitem_property_set_variant_func)( - DbusmenuMenuitem* item, - const char* property, - GVariant* value); -typedef DbusmenuMenuitem* (*dbusmenu_menuitem_property_set_bool_func)( - DbusmenuMenuitem* item, - const char* property, - bool value); -typedef DbusmenuMenuitem* (*dbusmenu_menuitem_property_set_int_func)( - DbusmenuMenuitem* item, - const char* property, - int value); - -typedef struct _DbusmenuServer DbusmenuServer; -typedef DbusmenuServer* (*dbusmenu_server_new_func)(const char* object); -typedef void (*dbusmenu_server_set_root_func)(DbusmenuServer* self, - DbusmenuMenuitem* root); - // A line in the static menu definitions. struct GlobalMenuBarCommand { - int str_id; int command; - int tag; + int str_id; }; namespace { -// Retrieved functions from libdbusmenu-glib. - -// DbusmenuMenuItem methods: -dbusmenu_menuitem_new_func menuitem_new = nullptr; -dbusmenu_menuitem_get_children_func menuitem_get_children = nullptr; -dbusmenu_menuitem_child_add_position_func menuitem_child_add_position = nullptr; -dbusmenu_menuitem_child_append_func menuitem_child_append = nullptr; -dbusmenu_menuitem_child_delete_func menuitem_child_delete = nullptr; -dbusmenu_menuitem_property_set_func menuitem_property_set = nullptr; -dbusmenu_menuitem_property_set_variant_func menuitem_property_set_variant = - nullptr; -dbusmenu_menuitem_property_set_bool_func menuitem_property_set_bool = nullptr; -dbusmenu_menuitem_property_set_int_func menuitem_property_set_int = nullptr; - -// DbusmenuServer methods: -dbusmenu_server_new_func server_new = nullptr; -dbusmenu_server_set_root_func server_set_root = nullptr; - -// Properties that we set on menu items: -const char kPropertyEnabled[] = "enabled"; -const char kPropertyLabel[] = "label"; -const char kPropertyShortcut[] = "shortcut"; -const char kPropertyType[] = "type"; -const char kPropertyToggleType[] = "toggle-type"; -const char kPropertyToggleState[] = "toggle-state"; -const char kPropertyVisible[] = "visible"; - -const char kTypeCheckmark[] = "checkmark"; -const char kTypeSeparator[] = "separator"; - -// Data set on GObjectgs. -const char kTypeTag[] = "type-tag"; -const char kHistoryItem[] = "history-item"; -const char kProfileId[] = "profile-id"; - // The maximum number of most visited items to display. const unsigned int kMostVisitedCount = 8; @@ -134,166 +64,116 @@ // Menus more than this many chars long will get trimmed. const size_t kMaximumMenuWidthInChars = 50; -// Constants used in menu definitions. -const int MENU_SEPARATOR =-1; -const int MENU_END = -2; -const int MENU_DISABLED_ID = -3; - -// These tag values are used to refer to menu items. -const int TAG_MOST_VISITED = 1; -const int TAG_RECENTLY_CLOSED = 2; -const int TAG_MOST_VISITED_HEADER = 3; -const int TAG_RECENTLY_CLOSED_HEADER = 4; -const int TAG_PROFILES = 5; - -GlobalMenuBarCommand file_menu[] = { - { IDS_NEW_TAB, IDC_NEW_TAB }, - { IDS_NEW_WINDOW, IDC_NEW_WINDOW }, - { IDS_NEW_INCOGNITO_WINDOW, IDC_NEW_INCOGNITO_WINDOW }, - { IDS_REOPEN_CLOSED_TABS_LINUX, IDC_RESTORE_TAB }, - { IDS_OPEN_FILE_LINUX, IDC_OPEN_FILE }, - { IDS_OPEN_LOCATION_LINUX, IDC_FOCUS_LOCATION }, - - { MENU_SEPARATOR, MENU_SEPARATOR }, - - { IDS_CLOSE_WINDOW_LINUX, IDC_CLOSE_WINDOW }, - { IDS_CLOSE_TAB_LINUX, IDC_CLOSE_TAB }, - { IDS_SAVE_PAGE, IDC_SAVE_PAGE }, - - { MENU_SEPARATOR, MENU_SEPARATOR }, - - { IDS_PRINT, IDC_PRINT }, - - { MENU_END, MENU_END } +// Constants used in menu definitions. The first non-Chrome command is at +// IDC_FIRST_BOOKMARK_MENU. +enum ReservedCommandId { + kLastChromeCommand = IDC_FIRST_BOOKMARK_MENU - 1, + kMenuEnd, + kSeparator, + kSubmenu, + kTagRecentlyClosed, + kTagMostVisited, + kTagProfileEdit, + kTagProfileCreate, + kFirstUnreservedCommandId }; -GlobalMenuBarCommand edit_menu[] = { - { IDS_CUT, IDC_CUT }, - { IDS_COPY, IDC_COPY }, - { IDS_PASTE, IDC_PASTE }, +constexpr GlobalMenuBarCommand kFileMenu[] = { + {IDC_NEW_TAB, IDS_NEW_TAB}, + {IDC_NEW_WINDOW, IDS_NEW_WINDOW}, + {IDC_NEW_INCOGNITO_WINDOW, IDS_NEW_INCOGNITO_WINDOW}, + {IDC_RESTORE_TAB, IDS_REOPEN_CLOSED_TABS_LINUX}, + {IDC_OPEN_FILE, IDS_OPEN_FILE_LINUX}, + {IDC_FOCUS_LOCATION, IDS_OPEN_LOCATION_LINUX}, + {kSeparator}, + {IDC_CLOSE_WINDOW, IDS_CLOSE_WINDOW_LINUX}, + {IDC_CLOSE_TAB, IDS_CLOSE_TAB_LINUX}, + {IDC_SAVE_PAGE, IDS_SAVE_PAGE}, + {kSeparator}, + {IDC_PRINT, IDS_PRINT}, + {kMenuEnd}}; - { MENU_SEPARATOR, MENU_SEPARATOR }, +constexpr GlobalMenuBarCommand kEditMenu[] = {{IDC_CUT, IDS_CUT}, + {IDC_COPY, IDS_COPY}, + {IDC_PASTE, IDS_PASTE}, + {kSeparator}, + {IDC_FIND, IDS_FIND}, + {kSeparator}, + {IDC_OPTIONS, IDS_PREFERENCES}, + {kMenuEnd}}; - { IDS_FIND, IDC_FIND }, +constexpr GlobalMenuBarCommand kViewMenu[] = { + {IDC_SHOW_BOOKMARK_BAR, IDS_SHOW_BOOKMARK_BAR}, + {kSeparator}, + {IDC_STOP, IDS_STOP_MENU_LINUX}, + {IDC_RELOAD, IDS_RELOAD_MENU_LINUX}, + {kSeparator}, + {IDC_FULLSCREEN, IDS_FULLSCREEN}, + {IDC_ZOOM_NORMAL, IDS_TEXT_DEFAULT_LINUX}, + {IDC_ZOOM_PLUS, IDS_TEXT_BIGGER_LINUX}, + {IDC_ZOOM_MINUS, IDS_TEXT_SMALLER_LINUX}, + {kMenuEnd}}; - { MENU_SEPARATOR, MENU_SEPARATOR }, +constexpr GlobalMenuBarCommand kHistoryMenu[] = { + {IDC_HOME, IDS_HISTORY_HOME_LINUX}, + {IDC_BACK, IDS_HISTORY_BACK_LINUX}, + {IDC_FORWARD, IDS_HISTORY_FORWARD_LINUX}, + {kSeparator}, + {kTagRecentlyClosed, IDS_HISTORY_CLOSED_LINUX}, + {kSeparator}, + {kTagMostVisited, IDS_HISTORY_VISITED_LINUX}, + {kSeparator}, + {IDC_SHOW_HISTORY, IDS_HISTORY_SHOWFULLHISTORY_LINK}, + {kMenuEnd}}; - { IDS_PREFERENCES, IDC_OPTIONS }, +constexpr GlobalMenuBarCommand kToolsMenu[] = { + {IDC_SHOW_DOWNLOADS, IDS_SHOW_DOWNLOADS}, + {IDC_SHOW_HISTORY, IDS_HISTORY_SHOW_HISTORY}, + {IDC_MANAGE_EXTENSIONS, IDS_SHOW_EXTENSIONS}, + {kSeparator}, + {IDC_TASK_MANAGER, IDS_TASK_MANAGER}, + {IDC_CLEAR_BROWSING_DATA, IDS_CLEAR_BROWSING_DATA}, + {kSeparator}, + {IDC_VIEW_SOURCE, IDS_VIEW_SOURCE}, + {IDC_DEV_TOOLS, IDS_DEV_TOOLS}, + {IDC_DEV_TOOLS_INSPECT, IDS_DEV_TOOLS_ELEMENTS}, + {IDC_DEV_TOOLS_CONSOLE, IDS_DEV_TOOLS_CONSOLE}, + {IDC_DEV_TOOLS_DEVICES, IDS_DEV_TOOLS_DEVICES}, + {kMenuEnd}}; - { MENU_END, MENU_END } -}; +constexpr GlobalMenuBarCommand kProfilesMenu[] = { + {kSeparator}, + {kTagProfileEdit, IDS_PROFILES_MANAGE_BUTTON_LABEL}, + {kTagProfileCreate, IDS_PROFILES_CREATE_BUTTON_LABEL}, + {kMenuEnd}}; -GlobalMenuBarCommand view_menu[] = { - { IDS_SHOW_BOOKMARK_BAR, IDC_SHOW_BOOKMARK_BAR }, - - { MENU_SEPARATOR, MENU_SEPARATOR }, - - { IDS_STOP_MENU_LINUX, IDC_STOP }, - { IDS_RELOAD_MENU_LINUX, IDC_RELOAD }, - - { MENU_SEPARATOR, MENU_SEPARATOR }, - - { IDS_FULLSCREEN, IDC_FULLSCREEN }, - { IDS_TEXT_DEFAULT_LINUX, IDC_ZOOM_NORMAL }, - { IDS_TEXT_BIGGER_LINUX, IDC_ZOOM_PLUS }, - { IDS_TEXT_SMALLER_LINUX, IDC_ZOOM_MINUS }, - - { MENU_END, MENU_END } -}; - -GlobalMenuBarCommand history_menu[] = { - {IDS_HISTORY_HOME_LINUX, IDC_HOME}, - {IDS_HISTORY_BACK_LINUX, IDC_BACK}, - {IDS_HISTORY_FORWARD_LINUX, IDC_FORWARD}, - - {MENU_SEPARATOR, MENU_SEPARATOR}, - - {IDS_HISTORY_CLOSED_LINUX, MENU_DISABLED_ID, TAG_RECENTLY_CLOSED_HEADER}, - - {MENU_SEPARATOR, MENU_SEPARATOR}, - - {IDS_HISTORY_VISITED_LINUX, MENU_DISABLED_ID, TAG_MOST_VISITED_HEADER}, - - {MENU_SEPARATOR, MENU_SEPARATOR}, - - {IDS_HISTORY_SHOWFULLHISTORY_LINK, IDC_SHOW_HISTORY}, - - {MENU_END, MENU_END}}; - -GlobalMenuBarCommand tools_menu[] = { - {IDS_SHOW_DOWNLOADS, IDC_SHOW_DOWNLOADS}, - {IDS_HISTORY_SHOW_HISTORY, IDC_SHOW_HISTORY}, - {IDS_SHOW_EXTENSIONS, IDC_MANAGE_EXTENSIONS}, - - {MENU_SEPARATOR, MENU_SEPARATOR}, - - {IDS_TASK_MANAGER, IDC_TASK_MANAGER}, - {IDS_CLEAR_BROWSING_DATA, IDC_CLEAR_BROWSING_DATA}, - - {MENU_SEPARATOR, MENU_SEPARATOR}, - - {IDS_VIEW_SOURCE, IDC_VIEW_SOURCE}, - {IDS_DEV_TOOLS, IDC_DEV_TOOLS}, - {IDS_DEV_TOOLS_ELEMENTS, IDC_DEV_TOOLS_INSPECT}, - {IDS_DEV_TOOLS_CONSOLE, IDC_DEV_TOOLS_CONSOLE}, - {IDS_DEV_TOOLS_DEVICES, IDC_DEV_TOOLS_DEVICES}, - - {MENU_END, MENU_END}}; - -GlobalMenuBarCommand help_menu[] = { +constexpr GlobalMenuBarCommand kHelpMenu[] = { #if defined(GOOGLE_CHROME_BUILD) - { IDS_FEEDBACK, IDC_FEEDBACK }, + {IDC_FEEDBACK, IDS_FEEDBACK}, #endif - { IDS_HELP_PAGE , IDC_HELP_PAGE_VIA_MENU }, - { MENU_END, MENU_END } -}; + {IDC_HELP_PAGE_VIA_MENU, IDS_HELP_PAGE}, + {kMenuEnd}}; -GlobalMenuBarCommand profiles_menu[] = { - { MENU_SEPARATOR, MENU_SEPARATOR }, - { MENU_END, MENU_END } -}; +void FindMenuItemsForCommandAux( + ui::MenuModel* menu, + int command, + std::vector<std::pair<ui::MenuModel*, int>>* menu_items) { + for (int i = 0; i < menu->GetItemCount(); i++) { + if (menu->GetCommandIdAt(i) == command) + menu_items->push_back({menu, i}); + if (menu->GetTypeAt(i) == ui::SimpleMenuModel::ItemType::TYPE_SUBMENU) { + FindMenuItemsForCommandAux(menu->GetSubmenuModelAt(i), command, + menu_items); + } + } +} -void EnsureMethodsLoaded() { - static bool attempted_load = false; - if (attempted_load) - return; - attempted_load = true; - - void* dbusmenu_lib = dlopen("libdbusmenu-glib.so", RTLD_LAZY); - if (!dbusmenu_lib) - dbusmenu_lib = dlopen("libdbusmenu-glib.so.4", RTLD_LAZY); - if (!dbusmenu_lib) - return; - - // DbusmenuMenuItem methods. - menuitem_new = reinterpret_cast<dbusmenu_menuitem_new_func>( - dlsym(dbusmenu_lib, "dbusmenu_menuitem_new")); - menuitem_child_add_position = - reinterpret_cast<dbusmenu_menuitem_child_add_position_func>( - dlsym(dbusmenu_lib, "dbusmenu_menuitem_child_add_position")); - menuitem_child_append = reinterpret_cast<dbusmenu_menuitem_child_append_func>( - dlsym(dbusmenu_lib, "dbusmenu_menuitem_child_append")); - menuitem_child_delete = reinterpret_cast<dbusmenu_menuitem_child_delete_func>( - dlsym(dbusmenu_lib, "dbusmenu_menuitem_child_delete")); - menuitem_get_children = reinterpret_cast<dbusmenu_menuitem_get_children_func>( - dlsym(dbusmenu_lib, "dbusmenu_menuitem_get_children")); - menuitem_property_set = reinterpret_cast<dbusmenu_menuitem_property_set_func>( - dlsym(dbusmenu_lib, "dbusmenu_menuitem_property_set")); - menuitem_property_set_variant = - reinterpret_cast<dbusmenu_menuitem_property_set_variant_func>( - dlsym(dbusmenu_lib, "dbusmenu_menuitem_property_set_variant")); - menuitem_property_set_bool = - reinterpret_cast<dbusmenu_menuitem_property_set_bool_func>( - dlsym(dbusmenu_lib, "dbusmenu_menuitem_property_set_bool")); - menuitem_property_set_int = - reinterpret_cast<dbusmenu_menuitem_property_set_int_func>( - dlsym(dbusmenu_lib, "dbusmenu_menuitem_property_set_int")); - - // DbusmenuServer methods. - server_new = reinterpret_cast<dbusmenu_server_new_func>( - dlsym(dbusmenu_lib, "dbusmenu_server_new")); - server_set_root = reinterpret_cast<dbusmenu_server_set_root_func>( - dlsym(dbusmenu_lib, "dbusmenu_server_set_root")); +std::vector<std::pair<ui::MenuModel*, int>> FindMenuItemsForCommand( + ui::MenuModel* menu, + int command) { + std::vector<std::pair<ui::MenuModel*, int>> menu_items; + FindMenuItemsForCommandAux(menu, command, &menu_items); + return menu_items; } } // namespace @@ -314,9 +194,9 @@ SessionID session_id; // If the HistoryItem is a window, this will be the vector of tabs. Note - // that this is a list of weak references. The |menu_item_map_| is the owner - // of all items. If it is not a window, then the entry is a single page and - // the vector will be empty. + // that this is a list of weak references. GlobalMenuBarX11::history_items_ + // is the owner of all items. If it is not a window, then the entry is a + // single page and the vector will be empty. std::vector<HistoryItem*> tabs; private: @@ -324,108 +204,58 @@ }; GlobalMenuBarX11::GlobalMenuBarX11(BrowserView* browser_view, - BrowserDesktopWindowTreeHostX11* host) + aura::WindowTreeHost* host) : browser_(browser_view->browser()), profile_(browser_->profile()), browser_view_(browser_view), - host_(host), - server_(nullptr), - root_item_(nullptr), - history_menu_(nullptr), - profiles_menu_(nullptr), - top_sites_(nullptr), + xid_(host->GetAcceleratedWidget()), tab_restore_service_(nullptr), - scoped_observer_(this) { - EnsureMethodsLoaded(); - - if (server_new) - host_->AddObserver(this); + scoped_observer_(this), + last_command_id_(kFirstUnreservedCommandId - 1) { + GlobalMenuBarRegistrarX11::GetInstance()->OnMenuBarCreated(this); } GlobalMenuBarX11::~GlobalMenuBarX11() { - if (server_) { - Disable(); + auto* registrar = GlobalMenuBarRegistrarX11::GetInstance(); + registrar->OnMenuBarDestroyed(this); - if (tab_restore_service_) - tab_restore_service_->RemoveObserver(this); + if (!initialized_) + return; - g_object_unref(server_); - host_->RemoveObserver(this); - } + registrar->bus()->UnregisterExportedObject(dbus::ObjectPath(GetPath())); + + for (int command : observed_commands_) + chrome::RemoveCommandObserver(browser_, command, this); + + pref_change_registrar_.RemoveAll(); + + if (tab_restore_service_) + tab_restore_service_->RemoveObserver(this); + BrowserList::RemoveObserver(this); } -// static -std::string GlobalMenuBarX11::GetPathForWindow(XID xid) { - return base::StringPrintf("/com/canonical/menu/%lX", xid); -} - -DbusmenuMenuitem* GlobalMenuBarX11::BuildSeparator() { - DbusmenuMenuitem* item = menuitem_new(); - menuitem_property_set(item, kPropertyType, kTypeSeparator); - menuitem_property_set_bool(item, kPropertyVisible, true); - return item; -} - -DbusmenuMenuitem* GlobalMenuBarX11::BuildMenuItem( - const std::string& label, - int tag_id) { - DbusmenuMenuitem* item = menuitem_new(); - menuitem_property_set(item, kPropertyLabel, label.c_str()); - menuitem_property_set_bool(item, kPropertyVisible, true); - - if (tag_id) - g_object_set_data(G_OBJECT(item), kTypeTag, GINT_TO_POINTER(tag_id)); - - return item; -} - -void GlobalMenuBarX11::InitServer(XID xid) { - std::string path = GetPathForWindow(xid); - { - ANNOTATE_SCOPED_MEMORY_LEAK; // http://crbug.com/314087 - server_ = server_new(path.c_str()); - } - - root_item_ = menuitem_new(); - menuitem_property_set(root_item_, kPropertyLabel, "Root"); - menuitem_property_set_bool(root_item_, kPropertyVisible, true); +void GlobalMenuBarX11::Initialize(DbusMenu::InitializedCallback callback) { + DCHECK(!initialized_); + initialized_ = true; // First build static menu content. - BuildStaticMenu(root_item_, IDS_FILE_MENU_LINUX, file_menu); - BuildStaticMenu(root_item_, IDS_EDIT_MENU_LINUX, edit_menu); - BuildStaticMenu(root_item_, IDS_VIEW_MENU_LINUX, view_menu); - history_menu_ = BuildStaticMenu( - root_item_, IDS_HISTORY_MENU_LINUX, history_menu); - BuildStaticMenu(root_item_, IDS_TOOLS_MENU_LINUX, tools_menu); - profiles_menu_ = BuildStaticMenu( - root_item_, IDS_PROFILES_OPTIONS_GROUP_NAME, profiles_menu); - BuildStaticMenu(root_item_, IDS_HELP_MENU_LINUX, help_menu); + root_menu_ = std::make_unique<ui::SimpleMenuModel>(this); - // We have to connect to |history_menu_item|'s "activate" signal instead of - // |history_menu|'s "show" signal because we are not supposed to modify the - // menu during "show" - g_signal_connect(history_menu_, "about-to-show", - G_CALLBACK(OnHistoryMenuAboutToShowThunk), this); - - for (CommandIDMenuItemMap::const_iterator it = id_to_menu_item_.begin(); - it != id_to_menu_item_.end(); ++it) { - menuitem_property_set_bool(it->second, kPropertyEnabled, - chrome::IsCommandEnabled(browser_, it->first)); - - ui::Accelerator accelerator; - if (browser_view_->GetAccelerator(it->first, &accelerator)) - RegisterAccelerator(it->second, accelerator); - - chrome::AddCommandObserver(browser_, it->first, this); - } + BuildStaticMenu(IDS_FILE_MENU_LINUX, kFileMenu); + BuildStaticMenu(IDS_EDIT_MENU_LINUX, kEditMenu); + BuildStaticMenu(IDS_VIEW_MENU_LINUX, kViewMenu); + history_menu_ = BuildStaticMenu(IDS_HISTORY_MENU_LINUX, kHistoryMenu); + BuildStaticMenu(IDS_TOOLS_MENU_LINUX, kToolsMenu); + profiles_menu_ = + BuildStaticMenu(IDS_PROFILES_OPTIONS_GROUP_NAME, kProfilesMenu); + BuildStaticMenu(IDS_HELP_MENU_LINUX, kHelpMenu); pref_change_registrar_.Init(browser_->profile()->GetPrefs()); pref_change_registrar_.Add( bookmarks::prefs::kShowBookmarkBar, base::Bind(&GlobalMenuBarX11::OnBookmarkBarVisibilityChanged, base::Unretained(this))); - OnBookmarkBarVisibilityChanged(); top_sites_ = TopSitesFactory::GetForProfile(profile_); if (top_sites_) { @@ -438,116 +268,70 @@ ProfileManager* profile_manager = g_browser_process->profile_manager(); DCHECK(profile_manager); - avatar_menu_.reset(new AvatarMenu( - &profile_manager->GetProfileAttributesStorage(), this, nullptr)); + avatar_menu_ = std::make_unique<AvatarMenu>( + &profile_manager->GetProfileAttributesStorage(), this, nullptr); avatar_menu_->RebuildMenu(); BrowserList::AddObserver(this); RebuildProfilesMenu(); - server_set_root(server_, root_item_); + menu_service_ = std::make_unique<DbusMenu>( + GlobalMenuBarRegistrarX11::GetInstance()->bus()->GetExportedObject( + dbus::ObjectPath(GetPath())), + std::move(callback)); + menu_service_->SetModel(root_menu_.get(), false); } -void GlobalMenuBarX11::Disable() { - for (CommandIDMenuItemMap::const_iterator it = id_to_menu_item_.begin(); - it != id_to_menu_item_.end(); ++it) { - chrome::RemoveCommandObserver(browser_, it->first, this); - } - id_to_menu_item_.clear(); - - pref_change_registrar_.RemoveAll(); +std::string GlobalMenuBarX11::GetPath() const { + return base::StringPrintf("/com/canonical/menu/%lX", xid_); } -DbusmenuMenuitem* GlobalMenuBarX11::BuildStaticMenu( - DbusmenuMenuitem* parent, - int menu_str_id, - GlobalMenuBarCommand* commands) { - DbusmenuMenuitem* top = menuitem_new(); - menuitem_property_set( - top, kPropertyLabel, - ui::RemoveWindowsStyleAccelerators(l10n_util::GetStringUTF8(menu_str_id)) - .c_str()); - menuitem_property_set_bool(top, kPropertyVisible, true); +ui::SimpleMenuModel* GlobalMenuBarX11::BuildStaticMenu( + int string_id, + const GlobalMenuBarCommand* commands) { + toplevel_menus_.push_back(std::make_unique<ui::SimpleMenuModel>(this)); + ui::SimpleMenuModel* menu = toplevel_menus_.back().get(); + for (; commands->command != kMenuEnd; commands++) { + int command_id = commands->command; + if (command_id == kSeparator) { + // Use InsertSeparatorAt() instead of AddSeparator() because the latter + // refuses to add a separator to an empty menu. + int old_item_count = menu->GetItemCount(); + menu->InsertSeparatorAt(old_item_count, + ui::MenuSeparatorType::SPACING_SEPARATOR); - for (int i = 0; commands[i].str_id != MENU_END; ++i) { - DbusmenuMenuitem* menu_item = nullptr; - int command_id = commands[i].command; - if (commands[i].str_id == MENU_SEPARATOR) { - menu_item = BuildSeparator(); - } else { - std::string label = ui::ConvertAcceleratorsFromWindowsStyle( - l10n_util::GetStringUTF8(commands[i].str_id)); - - menu_item = BuildMenuItem(label, commands[i].tag); - - if (command_id == MENU_DISABLED_ID) { - menuitem_property_set_bool(menu_item, kPropertyEnabled, false); - } else { - if (command_id == IDC_SHOW_BOOKMARK_BAR) - menuitem_property_set(menu_item, kPropertyToggleType, kTypeCheckmark); - - id_to_menu_item_.insert(std::make_pair(command_id, menu_item)); - g_object_set_data(G_OBJECT(menu_item), "command-id", - GINT_TO_POINTER(command_id)); - g_signal_connect(menu_item, "item-activated", - G_CALLBACK(OnItemActivatedThunk), this); - } + // Make extra sure the separator got added in case the behavior + // InsertSeparatorAt() changes. + CHECK_EQ(old_item_count + 1, menu->GetItemCount()); + continue; } - menuitem_child_append(top, menu_item); - g_object_unref(menu_item); + int string_id = commands->str_id; + if (command_id == IDC_SHOW_BOOKMARK_BAR) + menu->AddCheckItemWithStringId(command_id, string_id); + else + menu->AddItemWithStringId(command_id, string_id); + if (command_id < kLastChromeCommand) + RegisterCommandObserver(command_id); } - - menuitem_child_append(parent, top); - g_object_unref(top); - return top; + root_menu_->AddSubMenu(kSubmenu, l10n_util::GetStringUTF16(string_id), menu); + return menu; } -void GlobalMenuBarX11::RegisterAccelerator(DbusmenuMenuitem* item, - const ui::Accelerator& accelerator) { - // A translation of libdbusmenu-gtk's menuitem_property_set_shortcut() - // translated from GDK types to ui::Accelerator types. - GVariantBuilder builder; - g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY); - - if (accelerator.IsCtrlDown()) - g_variant_builder_add(&builder, "s", "Control"); - if (accelerator.IsAltDown()) - g_variant_builder_add(&builder, "s", "Alt"); - if (accelerator.IsShiftDown()) - g_variant_builder_add(&builder, "s", "Shift"); - - char* name = XKeysymToString(XKeysymForWindowsKeyCode( - accelerator.key_code(), false)); - if (!name) { - NOTIMPLEMENTED(); - return; - } - g_variant_builder_add(&builder, "s", name); - - GVariant* inside_array = g_variant_builder_end(&builder); - g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY); - g_variant_builder_add_value(&builder, inside_array); - GVariant* outside_array = g_variant_builder_end(&builder); - - menuitem_property_set_variant(item, kPropertyShortcut, outside_array); -} - -GlobalMenuBarX11::HistoryItem* GlobalMenuBarX11::HistoryItemForTab( +std::unique_ptr<GlobalMenuBarX11::HistoryItem> +GlobalMenuBarX11::HistoryItemForTab( const sessions::TabRestoreService::Tab& entry) { const sessions::SerializedNavigationEntry& current_navigation = entry.navigations.at(entry.current_navigation_index); - HistoryItem* item = new HistoryItem(); + auto item = std::make_unique<HistoryItem>(); item->title = current_navigation.title(); item->url = current_navigation.virtual_url(); item->session_id = entry.id; - return item; } -void GlobalMenuBarX11::AddHistoryItemToMenu(HistoryItem* item, - DbusmenuMenuitem* menu, - int tag, +void GlobalMenuBarX11::AddHistoryItemToMenu(std::unique_ptr<HistoryItem> item, + ui::SimpleMenuModel* menu, int index) { base::string16 title = item->title; std::string url_string = item->url.possibly_invalid_spec(); @@ -556,14 +340,9 @@ title = base::UTF8ToUTF16(url_string); gfx::ElideString(title, kMaximumMenuWidthInChars, &title); - DbusmenuMenuitem* menu_item = BuildMenuItem(base::UTF16ToUTF8(title), tag); - g_signal_connect(menu_item, "item-activated", - G_CALLBACK(OnHistoryItemActivatedThunk), this); - - g_object_set_data_full(G_OBJECT(menu_item), kHistoryItem, item, - DeleteHistoryItem); - menuitem_child_add_position(menu, menu_item, index); - g_object_unref(menu_item); + int command_id = NextCommandId(); + menu->InsertItemAt(index, command_id, title); + history_items_[command_id] = std::move(item); } void GlobalMenuBarX11::GetTopSitesData() { @@ -575,138 +354,88 @@ void GlobalMenuBarX11::OnTopSitesReceived( const history::MostVisitedURLList& visited_list) { - ClearMenuSection(history_menu_, TAG_MOST_VISITED); - - int index = GetIndexOfMenuItemWithTag(history_menu_, - TAG_MOST_VISITED_HEADER) + 1; + int index = ClearHistoryMenuSection(kTagMostVisited); for (size_t i = 0; i < visited_list.size() && i < kMostVisitedCount; ++i) { const history::MostVisitedURL& visited = visited_list[i]; if (visited.url.spec().empty()) break; // This is the signal that there are no more real visited sites. - HistoryItem* item = new HistoryItem(); + auto item = std::make_unique<HistoryItem>(); item->title = visited.title; item->url = visited.url; - AddHistoryItemToMenu(item, - history_menu_, - TAG_MOST_VISITED, - index++); + AddHistoryItemToMenu(std::move(item), history_menu_, index++); } + + if (menu_service_) + menu_service_->MenuLayoutUpdated(history_menu_); } void GlobalMenuBarX11::OnBookmarkBarVisibilityChanged() { - auto it = id_to_menu_item_.find(IDC_SHOW_BOOKMARK_BAR); - if (it != id_to_menu_item_.end()) { - PrefService* prefs = browser_->profile()->GetPrefs(); - // Note: Unlike the GTK version, we don't appear to need to do tricks where - // we block activation while setting the toggle. - menuitem_property_set_int( - it->second, - kPropertyToggleState, - prefs->GetBoolean(bookmarks::prefs::kShowBookmarkBar)); - } + menu_service_->MenuItemsPropertiesUpdated( + FindMenuItemsForCommand(root_menu_.get(), IDC_SHOW_BOOKMARK_BAR)); } void GlobalMenuBarX11::RebuildProfilesMenu() { - ClearMenuSection(profiles_menu_, TAG_PROFILES); + while (profiles_menu_->GetTypeAt(0) != ui::MenuModel::TYPE_SEPARATOR) + profiles_menu_->RemoveItemAt(0); + profile_commands_.clear(); // Don't call avatar_menu_->GetActiveProfileIndex() as the as the index might // be incorrect if RebuildProfilesMenu() is called while we deleting the // active profile and closing all its browser windows. - int active_profile_index = -1; - + active_profile_index_ = -1; for (size_t i = 0; i < avatar_menu_->GetNumberOfItems(); ++i) { const AvatarMenu::Item& item = avatar_menu_->GetItemAt(i); base::string16 title = item.name; gfx::ElideString(title, kMaximumMenuWidthInChars, &title); - DbusmenuMenuitem* menu_item = BuildMenuItem( - base::UTF16ToUTF8(title), TAG_PROFILES); - g_object_set_data(G_OBJECT(menu_item), kProfileId, GINT_TO_POINTER(i)); - g_signal_connect(menu_item, "item-activated", - G_CALLBACK(OnProfileItemActivatedThunk), this); - menuitem_property_set(menu_item, kPropertyToggleType, kTypeCheckmark); - menuitem_property_set_int(menu_item, kPropertyToggleState, item.active); - if (item.active) - active_profile_index = i; + active_profile_index_ = i; - menuitem_child_add_position(profiles_menu_, menu_item, i); - g_object_unref(menu_item); + int command = NextCommandId(); + profile_commands_[command] = i; + profiles_menu_->InsertCheckItemAt(i, command, title); } - // There is a separator between the list of profiles and the possible actions. - int index = avatar_menu_->GetNumberOfItems() + 1; - - DbusmenuMenuitem* edit_profile_item = BuildMenuItem( - l10n_util::GetStringUTF8(IDS_PROFILES_MANAGE_BUTTON_LABEL), TAG_PROFILES); - DbusmenuMenuitem* create_profile_item = BuildMenuItem( - l10n_util::GetStringUTF8(IDS_PROFILES_CREATE_BUTTON_LABEL), - TAG_PROFILES); - - // There is no active profile in Guest mode, in which case the action buttons - // should be disabled. - if (active_profile_index >= 0) { - g_object_set_data(G_OBJECT(edit_profile_item), kProfileId, - GINT_TO_POINTER(active_profile_index)); - g_signal_connect(edit_profile_item, "item-activated", - G_CALLBACK(OnEditProfileItemActivatedThunk), this); - g_signal_connect(create_profile_item, "item-activated", - G_CALLBACK(OnCreateProfileItemActivatedThunk), this); - } else { - menuitem_property_set_bool(edit_profile_item, kPropertyEnabled, false); - menuitem_property_set_bool(create_profile_item, kPropertyEnabled, false); - } - - menuitem_child_add_position(profiles_menu_, edit_profile_item, index++); - menuitem_child_add_position(profiles_menu_, create_profile_item, index); - g_object_unref(edit_profile_item); - g_object_unref(create_profile_item); + if (menu_service_) + menu_service_->MenuLayoutUpdated(profiles_menu_); } -int GlobalMenuBarX11::GetIndexOfMenuItemWithTag(DbusmenuMenuitem* menu, - int tag_id) { - GList* childs = menuitem_get_children(menu); - int i = 0; - for (; childs != nullptr; childs = childs->next, i++) { - int tag = - GPOINTER_TO_INT(g_object_get_data(G_OBJECT(childs->data), kTypeTag)); - if (tag == tag_id) - return i; +int GlobalMenuBarX11::ClearHistoryMenuSection(int header_command_id) { + int index = 0; + while (history_menu_->GetCommandIdAt(index++) != header_command_id) { } - - NOTREACHED(); - return -1; + while (history_menu_->GetTypeAt(index) != ui::MenuModel::TYPE_SEPARATOR) { + history_items_.erase(history_menu_->GetCommandIdAt(index)); + history_menu_->RemoveItemAt(index); + } + return index; } -void GlobalMenuBarX11::ClearMenuSection(DbusmenuMenuitem* menu, int tag_id) { - std::vector<DbusmenuMenuitem*> menuitems_to_delete; +void GlobalMenuBarX11::RegisterCommandObserver(int command) { + if (command > kLastChromeCommand) + return; - GList* childs = menuitem_get_children(menu); - for (; childs != nullptr; childs = childs->next) { - DbusmenuMenuitem* current_item = reinterpret_cast<DbusmenuMenuitem*>( - childs->data); - ClearMenuSection(current_item, tag_id); + // Keep track of which commands are already registered to avoid + // registering them twice. + const bool inserted = observed_commands_.insert(command).second; + if (!inserted) + return; - int tag = - GPOINTER_TO_INT(g_object_get_data(G_OBJECT(childs->data), kTypeTag)); - if (tag == tag_id) - menuitems_to_delete.push_back(current_item); - } - - for (std::vector<DbusmenuMenuitem*>::const_iterator it = - menuitems_to_delete.begin(); it != menuitems_to_delete.end(); ++it) { - menuitem_child_delete(menu, *it); - } + chrome::AddCommandObserver(browser_, command, this); } -// static -void GlobalMenuBarX11::DeleteHistoryItem(void* void_item) { - HistoryItem* item = - reinterpret_cast<GlobalMenuBarX11::HistoryItem*>(void_item); - delete item; +int GlobalMenuBarX11::NextCommandId() { + do { + if (last_command_id_ == std::numeric_limits<int>::max()) + last_command_id_ = kFirstUnreservedCommandId; + else + last_command_id_++; + } while (base::Contains(history_items_, last_command_id_) || + base::Contains(profile_commands_, last_command_id_)); + return last_command_id_; } void GlobalMenuBarX11::OnAvatarMenuChanged(AvatarMenu* avatar_menu) { @@ -722,29 +451,23 @@ } void GlobalMenuBarX11::EnabledStateChangedForCommand(int id, bool enabled) { - auto it = id_to_menu_item_.find(id); - if (it != id_to_menu_item_.end()) - menuitem_property_set_bool(it->second, kPropertyEnabled, enabled); + menu_service_->MenuItemsPropertiesUpdated( + FindMenuItemsForCommand(root_menu_.get(), id)); } -void GlobalMenuBarX11::TopSitesLoaded(history::TopSites* top_sites) { -} +void GlobalMenuBarX11::TopSitesLoaded(history::TopSites* top_sites) {} void GlobalMenuBarX11::TopSitesChanged(history::TopSites* top_sites, ChangeReason change_reason) { - GetTopSitesData(); + GetTopSitesData(); } void GlobalMenuBarX11::TabRestoreServiceChanged( sessions::TabRestoreService* service) { const sessions::TabRestoreService::Entries& entries = service->entries(); - ClearMenuSection(history_menu_, TAG_RECENTLY_CLOSED); - - // We'll get the index the "Recently Closed" header. (This can vary depending - // on the number of "Most Visited" items. - int index = GetIndexOfMenuItemWithTag(history_menu_, - TAG_RECENTLY_CLOSED_HEADER) + 1; + int index = ClearHistoryMenuSection(kTagRecentlyClosed); + recently_closed_window_menus_.clear(); unsigned int added_count = 0; for (auto it = entries.begin(); @@ -759,58 +482,41 @@ continue; // Create the item for the parent/window. - HistoryItem* item = new HistoryItem(); + auto item = std::make_unique<HistoryItem>(); item->session_id = entry_win->id; - std::string title = l10n_util::GetPluralStringFUTF8( + base::string16 title = l10n_util::GetPluralStringFUTF16( IDS_RECENTLY_CLOSED_WINDOW, tabs.size()); - DbusmenuMenuitem* parent_item = BuildMenuItem( - title, TAG_RECENTLY_CLOSED); - menuitem_child_add_position(history_menu_, parent_item, index++); - g_object_unref(parent_item); - // The mac version of this code allows the user to click on the parent - // menu item to have the same effect as clicking the restore window - // submenu item. GTK+ helpfully activates a menu item when it shows a - // submenu so toss that feature out. - DbusmenuMenuitem* restore_item = BuildMenuItem( - l10n_util::GetStringUTF8( - IDS_HISTORY_CLOSED_RESTORE_WINDOW_LINUX).c_str(), - TAG_RECENTLY_CLOSED); - g_signal_connect(restore_item, "item-activated", - G_CALLBACK(OnHistoryItemActivatedThunk), this); - g_object_set_data_full(G_OBJECT(restore_item), kHistoryItem, item, - DeleteHistoryItem); - menuitem_child_append(parent_item, restore_item); - g_object_unref(restore_item); - - DbusmenuMenuitem* separator = BuildSeparator(); - menuitem_child_append(parent_item, separator); - g_object_unref(separator); + auto parent_menu = std::make_unique<ui::SimpleMenuModel>(this); + int command = NextCommandId(); + history_menu_->InsertSubMenuAt(index++, command, title, + parent_menu.get()); + parent_menu->AddItemWithStringId(command, + IDS_HISTORY_CLOSED_RESTORE_WINDOW_LINUX); + parent_menu->AddSeparator(ui::MenuSeparatorType::NORMAL_SEPARATOR); // Loop over the window's tabs and add them to the submenu. int subindex = 2; for (const auto& tab : tabs) { - HistoryItem* tab_item = HistoryItemForTab(*tab); - item->tabs.push_back(tab_item); - AddHistoryItemToMenu(tab_item, - parent_item, - TAG_RECENTLY_CLOSED, + std::unique_ptr<HistoryItem> tab_item = HistoryItemForTab(*tab); + item->tabs.push_back(tab_item.get()); + AddHistoryItemToMenu(std::move(tab_item), parent_menu.get(), subindex++); } + history_items_[command] = std::move(item); + recently_closed_window_menus_.push_back(std::move(parent_menu)); ++added_count; } else if (entry->type == sessions::TabRestoreService::TAB) { sessions::TabRestoreService::Tab* tab = static_cast<sessions::TabRestoreService::Tab*>(entry); - HistoryItem* item = HistoryItemForTab(*tab); - AddHistoryItemToMenu(item, - history_menu_, - TAG_RECENTLY_CLOSED, - index++); + AddHistoryItemToMenu(HistoryItemForTab(*tab), history_menu_, index++); ++added_count; } } + + menu_service_->MenuLayoutUpdated(history_menu_); } void GlobalMenuBarX11::TabRestoreServiceDestroyed( @@ -818,75 +524,75 @@ tab_restore_service_ = nullptr; } -void GlobalMenuBarX11::OnWindowMapped(XID xid) { - if (!server_) - InitServer(xid); - - GlobalMenuBarRegistrarX11::GetInstance()->OnWindowMapped(xid); -} - -void GlobalMenuBarX11::OnWindowUnmapped(XID xid) { - GlobalMenuBarRegistrarX11::GetInstance()->OnWindowUnmapped(xid); -} - -void GlobalMenuBarX11::OnItemActivated(DbusmenuMenuitem* item, - unsigned int timestamp) { - int id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(item), "command-id")); - chrome::ExecuteCommand(browser_, id); -} - -void GlobalMenuBarX11::OnHistoryItemActivated(DbusmenuMenuitem* sender, - unsigned int timestamp) { - // Note: We don't have access to the event modifiers used to click the menu - // item since that happens in a different process. - HistoryItem* item = reinterpret_cast<HistoryItem*>( - g_object_get_data(G_OBJECT(sender), kHistoryItem)); - - // If this item can be restored using TabRestoreService, do so. Otherwise, - // just load the URL. - sessions::TabRestoreService* service = - TabRestoreServiceFactory::GetForProfile(profile_); - if (item->session_id.is_valid() && service) { - service->RestoreEntryById(browser_->live_tab_context(), item->session_id, - WindowOpenDisposition::UNKNOWN); - } else { - DCHECK(item->url.is_valid()); - browser_->OpenURL( - content::OpenURLParams(item->url, content::Referrer(), - WindowOpenDisposition::NEW_FOREGROUND_TAB, - ui::PAGE_TRANSITION_AUTO_BOOKMARK, false)); +bool GlobalMenuBarX11::IsCommandIdChecked(int command_id) const { + if (command_id == IDC_SHOW_BOOKMARK_BAR) { + return browser_->profile()->GetPrefs()->GetBoolean( + bookmarks::prefs::kShowBookmarkBar); } + + auto it = profile_commands_.find(command_id); + return it != profile_commands_.end() && it->second == active_profile_index_; } -void GlobalMenuBarX11::OnHistoryMenuAboutToShow(DbusmenuMenuitem* item) { - if (!tab_restore_service_) { - tab_restore_service_ = TabRestoreServiceFactory::GetForProfile(profile_); - if (tab_restore_service_) { - tab_restore_service_->LoadTabsFromLastSession(); - tab_restore_service_->AddObserver(this); +bool GlobalMenuBarX11::IsCommandIdEnabled(int command_id) const { + if (command_id <= kLastChromeCommand) + return chrome::IsCommandEnabled(browser_, command_id); + // There is no active profile in Guest mode, in which case the action + // buttons should be disabled. + if (command_id == kTagProfileEdit || command_id == kTagProfileCreate) + return active_profile_index_ >= 0; + return command_id != kTagRecentlyClosed && command_id != kTagMostVisited; +} - // If LoadTabsFromLastSession doesn't load tabs, it won't call - // TabRestoreServiceChanged(). This ensures that all new windows after - // the first one will have their menus populated correctly. - TabRestoreServiceChanged(tab_restore_service_); +void GlobalMenuBarX11::ExecuteCommand(int command_id, int event_flags) { + if (command_id <= kLastChromeCommand) { + chrome::ExecuteCommand(browser_, command_id); + } else if (command_id == kTagProfileEdit) { + avatar_menu_->EditProfile(active_profile_index_); + } else if (command_id == kTagProfileCreate) { + profiles::CreateAndSwitchToNewProfile(ProfileManager::CreateCallback(), + ProfileMetrics::ADD_NEW_USER_MENU); + } else if (base::Contains(history_items_, command_id)) { + HistoryItem* item = history_items_[command_id].get(); + // If this item can be restored using TabRestoreService, do so. + // Otherwise, just load the URL. + sessions::TabRestoreService* service = + TabRestoreServiceFactory::GetForProfile(profile_); + if (item->session_id.is_valid() && service) { + service->RestoreEntryById(browser_->live_tab_context(), item->session_id, + WindowOpenDisposition::UNKNOWN); + } else { + DCHECK(item->url.is_valid()); + browser_->OpenURL( + content::OpenURLParams(item->url, content::Referrer(), + WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui::PAGE_TRANSITION_AUTO_BOOKMARK, false)); } + } else if (base::Contains(profile_commands_, command_id)) { + avatar_menu_->SwitchToProfile(profile_commands_[command_id], false, + ProfileMetrics::SWITCH_PROFILE_MENU); } } -void GlobalMenuBarX11::OnProfileItemActivated(DbusmenuMenuitem* sender, - unsigned int timestamp) { - int id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(sender), kProfileId)); - avatar_menu_->SwitchToProfile(id, false, ProfileMetrics::SWITCH_PROFILE_MENU); +void GlobalMenuBarX11::OnMenuWillShow(ui::SimpleMenuModel* source) { + if (source != history_menu_ || tab_restore_service_) + return; + + tab_restore_service_ = TabRestoreServiceFactory::GetForProfile(profile_); + if (!tab_restore_service_) + return; + + tab_restore_service_->LoadTabsFromLastSession(); + tab_restore_service_->AddObserver(this); + + // If LoadTabsFromLastSession doesn't load tabs, it won't call + // TabRestoreServiceChanged(). This ensures that all new windows after + // the first one will have their menus populated correctly. + TabRestoreServiceChanged(tab_restore_service_); } -void GlobalMenuBarX11::OnEditProfileItemActivated(DbusmenuMenuitem* sender, - unsigned int timestamp) { - int id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(sender), kProfileId)); - avatar_menu_->EditProfile(id); -} - -void GlobalMenuBarX11::OnCreateProfileItemActivated(DbusmenuMenuitem* sender, - unsigned int timestamp) { - profiles::CreateAndSwitchToNewProfile(ProfileManager::CreateCallback(), - ProfileMetrics::ADD_NEW_USER_MENU); +bool GlobalMenuBarX11::GetAcceleratorForCommandId( + int command_id, + ui::Accelerator* accelerator) const { + return browser_view_->GetAccelerator(command_id, accelerator); }
diff --git a/chrome/browser/ui/views/frame/global_menu_bar_x11.h b/chrome/browser/ui/views/frame/global_menu_bar_x11.h index fdc8bdd..a93ea65 100644 --- a/chrome/browser/ui/views/frame/global_menu_bar_x11.h +++ b/chrome/browser/ui/views/frame/global_menu_bar_x11.h
@@ -9,6 +9,7 @@ #include <string> #include "base/compiler_specific.h" +#include "base/containers/flat_set.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/scoped_observer.h" @@ -16,16 +17,15 @@ #include "chrome/browser/profiles/avatar_menu.h" #include "chrome/browser/profiles/avatar_menu_observer.h" #include "chrome/browser/ui/browser_list_observer.h" +#include "components/dbus/menu/menu.h" #include "components/history/core/browser/history_types.h" #include "components/history/core/browser/top_sites_observer.h" #include "components/prefs/pref_change_registrar.h" #include "components/sessions/core/tab_restore_service.h" #include "components/sessions/core/tab_restore_service_observer.h" -#include "ui/base/glib/glib_signal.h" -#include "ui/views/widget/desktop_aura/desktop_window_tree_host_observer_x11.h" - -typedef struct _DbusmenuMenuitem DbusmenuMenuitem; -typedef struct _DbusmenuServer DbusmenuServer; +#include "ui/aura/window_tree_host.h" +#include "ui/base/models/simple_menu_model.h" +#include "ui/gfx/x/x11_types.h" namespace history { class TopSites; @@ -37,67 +37,45 @@ class Browser; class BrowserView; -class Profile; - -class BrowserDesktopWindowTreeHostX11; struct GlobalMenuBarCommand; +class Profile; // Controls the Mac style menu bar on Unity. // // Unity has an Apple-like menu bar at the top of the screen that changes -// depending on the active window. In the GTK port, we had a hidden GtkMenuBar -// object in each GtkWindow which existed only to be scrapped by the -// libdbusmenu-gtk code. Since we don't have GtkWindows anymore, we need to -// interface directly with the lower level libdbusmenu-glib, which we -// opportunistically dlopen() since not everyone is running Ubuntu. +// depending on the active window. class GlobalMenuBarX11 : public AvatarMenuObserver, public BrowserListObserver, public CommandObserver, public history::TopSitesObserver, public sessions::TabRestoreServiceObserver, - public views::DesktopWindowTreeHostObserverX11 { + public ui::SimpleMenuModel::Delegate { public: - GlobalMenuBarX11(BrowserView* browser_view, - BrowserDesktopWindowTreeHostX11* host); + GlobalMenuBarX11(BrowserView* browser_view, aura::WindowTreeHost* host); ~GlobalMenuBarX11() override; + void Initialize(DbusMenu::InitializedCallback callback); + // Creates the object path for DbusemenuServer which is attached to |xid|. - static std::string GetPathForWindow(unsigned long xid); + std::string GetPath() const; + + XID xid() const { return xid_; } private: struct HistoryItem; - typedef std::map<int, DbusmenuMenuitem*> CommandIDMenuItemMap; - - // Builds a separator. - DbusmenuMenuitem* BuildSeparator(); - - // Creates an individual menu item from a title and command, and subscribes - // to the activation signal. - DbusmenuMenuitem* BuildMenuItem(const std::string& label, int tag_id); - - // Creates a DbusmenuServer, and attaches all the menu items. - void InitServer(unsigned long xid); - - // Stops listening to enable state changed events. - void Disable(); // Creates a whole menu defined with |commands| and titled with the string - // |menu_str_id|. Then appends it to |parent|. - DbusmenuMenuitem* BuildStaticMenu(DbusmenuMenuitem* parent, - int menu_str_id, - GlobalMenuBarCommand* commands); - - // Sets the accelerator for |item|. - void RegisterAccelerator(DbusmenuMenuitem* item, - const ui::Accelerator& accelerator); + // |string_id|. Then appends it to |root_menu_|. + ui::SimpleMenuModel* BuildStaticMenu(int string_id, + const GlobalMenuBarCommand* commands); // Creates a HistoryItem from the data in |entry|. - HistoryItem* HistoryItemForTab(const sessions::TabRestoreService::Tab& entry); + std::unique_ptr<HistoryItem> HistoryItemForTab( + const sessions::TabRestoreService::Tab& entry); // Creates a menu item form |item| and inserts it in |menu| at |index|. - void AddHistoryItemToMenu(HistoryItem* item, - DbusmenuMenuitem* menu, - int tag, + void AddHistoryItemToMenu(std::unique_ptr<HistoryItem> item, + ui::SimpleMenuModel* menu, int index); // Sends a message off to History for data. @@ -111,66 +89,67 @@ void RebuildProfilesMenu(); - // Find the first index of the item in |menu| with the tag |tag_id|. - int GetIndexOfMenuItemWithTag(DbusmenuMenuitem* menu, int tag_id); + // This will remove all menu items in |history_menu_| starting from the item + // with command |header_command_id| up to the item with command + // MENU_SEPARATOR, non-inclusive. Returns the index of the separator. + int ClearHistoryMenuSection(int header_command_id); - // This will remove all menu items in |menu| with |tag| as their tag. This - // clears state about HistoryItems* that we keep to prevent that data from - // going stale. That's why this method recurses into its child menus. - void ClearMenuSection(DbusmenuMenuitem* menu, int tag_id); + // Start listening for enabled state changes for |command|. + void RegisterCommandObserver(int command); - // Deleter function for HistoryItem implementation detail. - static void DeleteHistoryItem(void* void_item); + // Returns a command ID for use in menus. The command will not conflict with + // Chrome commands or reserved commands. + int NextCommandId(); - // Overridden from AvatarMenuObserver: + // AvatarMenuObserver: void OnAvatarMenuChanged(AvatarMenu* avatar_menu) override; - // Overridden from BrowserListObserver: + // BrowserListObserver: void OnBrowserSetLastActive(Browser* browser) override; - // Overridden from CommandObserver: + // CommandObserver: void EnabledStateChangedForCommand(int id, bool enabled) override; - // Overridden from history::TopSitesObserver: + // history::TopSitesObserver: void TopSitesLoaded(history::TopSites* top_sites) override; void TopSitesChanged(history::TopSites* top_sites, ChangeReason change_reason) override; - // Overridden from TabRestoreServiceObserver: + // TabRestoreServiceObserver: void TabRestoreServiceChanged(sessions::TabRestoreService* service) override; void TabRestoreServiceDestroyed( sessions::TabRestoreService* service) override; - // Overridden from views::DesktopWindowTreeHostObserverX11: - void OnWindowMapped(unsigned long xid) override; - void OnWindowUnmapped(unsigned long xid) override; + // ui::SimpleMenuModel::Delegate: + bool IsCommandIdChecked(int command_id) const override; + bool IsCommandIdEnabled(int command_id) const override; + void ExecuteCommand(int command_id, int event_flags) override; + void OnMenuWillShow(ui::SimpleMenuModel* source) override; + bool GetAcceleratorForCommandId(int command_id, + ui::Accelerator* accelerator) const override; - CHROMEG_CALLBACK_1(GlobalMenuBarX11, void, OnItemActivated, DbusmenuMenuitem*, - unsigned int); - CHROMEG_CALLBACK_1(GlobalMenuBarX11, void, OnHistoryItemActivated, - DbusmenuMenuitem*, unsigned int); - CHROMEG_CALLBACK_0(GlobalMenuBarX11, void, OnHistoryMenuAboutToShow, - DbusmenuMenuitem*); - CHROMEG_CALLBACK_1(GlobalMenuBarX11, void, OnProfileItemActivated, - DbusmenuMenuitem*, unsigned int); - CHROMEG_CALLBACK_1(GlobalMenuBarX11, void, OnEditProfileItemActivated, - DbusmenuMenuitem*, unsigned int); - CHROMEG_CALLBACK_1(GlobalMenuBarX11, void, OnCreateProfileItemActivated, - DbusmenuMenuitem*, unsigned int); - + // State for the browser window we're tracking. Browser* const browser_; Profile* profile_; BrowserView* browser_view_; - BrowserDesktopWindowTreeHostX11* host_; + XID xid_; - // Maps command ids to DbusmenuMenuitems so we can modify their - // enabled/checked state in response to state change notifications. - CommandIDMenuItemMap id_to_menu_item_; + // Has Initialize() been called? + bool initialized_ = false; - DbusmenuServer* server_; - DbusmenuMenuitem* root_item_; - DbusmenuMenuitem* history_menu_; - DbusmenuMenuitem* profiles_menu_; + // The DBus menu service. + std::unique_ptr<DbusMenu> menu_service_; + + // Menu models. Menus don't own their children, so we must own them. + // |toplevel_menus_| are children of |root_menu_|. + // |recently_closed_window_menus_| are children of |history_menu_|. + // |history_menu_| and |profiles_menu_| are owned by |toplevel_menus_|. + std::unique_ptr<ui::SimpleMenuModel> root_menu_; + std::vector<std::unique_ptr<ui::SimpleMenuModel>> toplevel_menus_; + std::vector<std::unique_ptr<ui::SimpleMenuModel>> + recently_closed_window_menus_; + ui::SimpleMenuModel* history_menu_ = nullptr; + ui::SimpleMenuModel* profiles_menu_ = nullptr; // Tracks value of the kShowBookmarkBar preference. PrefChangeRegistrar pref_change_registrar_; @@ -183,6 +162,18 @@ ScopedObserver<history::TopSites, history::TopSitesObserver> scoped_observer_; + // Maps from history item command ID to HistoryItem data. + std::map<int, std::unique_ptr<HistoryItem>> history_items_; + + // Maps from profile item command ID to an index into |avatar_menu_|, at the + // time the menu was created. + std::map<int, int> profile_commands_; + int active_profile_index_ = -1; + + base::flat_set<int> observed_commands_; + + int last_command_id_; + // For callbacks may be run after destruction. base::WeakPtrFactory<GlobalMenuBarX11> weak_ptr_factory_{this};
diff --git a/chrome/browser/ui/views/media_router/media_router_views_ui.cc b/chrome/browser/ui/views/media_router/media_router_views_ui.cc index d27a7840..2973adb 100644 --- a/chrome/browser/ui/views/media_router/media_router_views_ui.cc +++ b/chrome/browser/ui/views/media_router/media_router_views_ui.cc
@@ -16,6 +16,7 @@ #include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "base/time/time.h" #include "base/timer/timer.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" @@ -716,6 +717,15 @@ AddIssue(issue_info); } +void MediaRouterViewsUI::SendIssueForTabAudioNotSupported( + const MediaSink::Id& sink_id) { + IssueInfo issue_info( + l10n_util::GetStringUTF8(IDS_MEDIA_ROUTER_ISSUE_TAB_AUDIO_NOT_SUPPORTED), + IssueInfo::Action::DISMISS, IssueInfo::Severity::NOTIFICATION); + issue_info.sink_id = sink_id; + AddIssue(issue_info); +} + IssueManager* MediaRouterViewsUI::GetIssueManager() { return GetMediaRouter()->GetIssueManager(); } @@ -798,7 +808,12 @@ } current_route_request_.reset(); - if (result.result_code() == RouteRequestResult::TIMED_OUT) { + if (result.result_code() == RouteRequestResult::OK && + cast_mode == TAB_MIRROR && !base::TimeTicks::IsHighResolution()) { + // When tab mirroring on a device without a high resolution clock, the audio + // is not mirrored. + SendIssueForTabAudioNotSupported(sink_id); + } else if (result.result_code() == RouteRequestResult::TIMED_OUT) { SendIssueForRouteTimeout(cast_mode, sink_id, presentation_request_source_name); }
diff --git a/chrome/browser/ui/views/media_router/media_router_views_ui.h b/chrome/browser/ui/views/media_router/media_router_views_ui.h index dfc5389b..4b61e03 100644 --- a/chrome/browser/ui/views/media_router/media_router_views_ui.h +++ b/chrome/browser/ui/views/media_router/media_router_views_ui.h
@@ -262,6 +262,10 @@ void SendIssueForUnableToCast(MediaCastMode cast_mode, const MediaSink::Id& sink_id); + // Creates and sends an issue for notifying the user that the tab audio cannot + // be mirrored from their device. + void SendIssueForTabAudioNotSupported(const MediaSink::Id& sink_id); + // Returns the IssueManager associated with |router_|. IssueManager* GetIssueManager();
diff --git a/chrome/browser/ui/views/status_icons/status_icon_linux_dbus.cc b/chrome/browser/ui/views/status_icons/status_icon_linux_dbus.cc index 898887e..52ce18c 100644 --- a/chrome/browser/ui/views/status_icons/status_icon_linux_dbus.cc +++ b/chrome/browser/ui/views/status_icons/status_icon_linux_dbus.cc
@@ -88,14 +88,6 @@ const char kPropertyValueCategory[] = "ApplicationStatus"; const char kPropertyValueStatus[] = "Active"; -scoped_refptr<dbus::Bus> CreateBus() { - dbus::Bus::Options bus_options; - bus_options.bus_type = dbus::Bus::SESSION; - bus_options.connection_type = dbus::Bus::PRIVATE; - bus_options.dbus_task_runner = dbus_thread_linux::GetTaskRunner(); - return base::MakeRefCounted<dbus::Bus>(bus_options); -} - int NextServiceId() { static int status_icon_count = 0; return ++status_icon_count; @@ -141,7 +133,12 @@ } // namespace -StatusIconLinuxDbus::StatusIconLinuxDbus() : bus_(CreateBus()) { +StatusIconLinuxDbus::StatusIconLinuxDbus() { + dbus::Bus::Options bus_options; + bus_options.bus_type = dbus::Bus::SESSION; + bus_options.connection_type = dbus::Bus::PRIVATE; + bus_options.dbus_task_runner = dbus_thread_linux::GetTaskRunner(); + bus_ = base::MakeRefCounted<dbus::Bus>(bus_options); CheckStatusNotifierWatcherHasOwner(); }
diff --git a/chrome/browser/ui/views/tabs/tab_animation.cc b/chrome/browser/ui/views/tabs/tab_animation.cc index f63c149..1a916e6 100644 --- a/chrome/browser/ui/views/tabs/tab_animation.cc +++ b/chrome/browser/ui/views/tabs/tab_animation.cc
@@ -8,6 +8,7 @@ #include <utility> #include "base/numerics/ranges.h" +#include "chrome/browser/ui/views/tabs/tab_width_constraints.h" #include "ui/gfx/animation/tween.h" namespace { @@ -28,6 +29,14 @@ TabAnimation::~TabAnimation() = default; +bool TabAnimation::IsClosing() const { + return target_state_.IsFullyClosed(); +} + +bool TabAnimation::IsClosed() const { + return target_state_.IsFullyClosed() && GetTimeRemaining().is_zero(); +} + void TabAnimation::AnimateTo(TabAnimationState target_state) { initial_state_ = GetCurrentState(); target_state_ = target_state; @@ -54,6 +63,17 @@ std::move(tab_removed_callback_).Run(); } +base::TimeDelta TabAnimation::GetTimeRemaining() const { + return std::max(start_time_ + duration_ - base::TimeTicks::Now(), + kZeroDuration); +} + +TabWidthConstraints TabAnimation::GetCurrentTabWidthConstraints( + const TabLayoutConstants& layout_constants, + const TabSizeInfo& size_info) const { + return TabWidthConstraints(GetCurrentState(), layout_constants, size_info); +} + TabAnimationState TabAnimation::GetCurrentState() const { if (duration_.is_zero()) return target_state_; @@ -66,8 +86,3 @@ return TabAnimationState::Interpolate(interpolation_value, initial_state_, target_state_); } - -base::TimeDelta TabAnimation::GetTimeRemaining() const { - return std::max(start_time_ + duration_ - base::TimeTicks::Now(), - kZeroDuration); -}
diff --git a/chrome/browser/ui/views/tabs/tab_animation.h b/chrome/browser/ui/views/tabs/tab_animation.h index 5178350..45c159d 100644 --- a/chrome/browser/ui/views/tabs/tab_animation.h +++ b/chrome/browser/ui/views/tabs/tab_animation.h
@@ -8,6 +8,9 @@ #include "base/callback.h" #include "base/time/time.h" #include "chrome/browser/ui/views/tabs/tab_animation_state.h" +#include "chrome/browser/ui/views/tabs/tab_strip_layout_types.h" + +class TabWidthConstraints; // Interpolates between TabAnimationStates. Apply the current state to a tab // to animate that tab. @@ -22,11 +25,17 @@ ~TabAnimation(); - // Animates this tab from its current state to |target_state|. + // Returns whether this tab is currently animating closed. + bool IsClosing() const; + + // Returns whether this tab has finished animating closed. + bool IsClosed() const; + + // Animates this tab from its current state to |target_state_|. // If an animation is already running, the duration is reset. void AnimateTo(TabAnimationState target_state); - // Animates this tab from its current state to |target_state|. + // Animates this tab from its current state to |target_state_|. // Keeps the current remaining animation duration. void RetargetTo(TabAnimationState target_state); @@ -36,11 +45,20 @@ // has completed and the tab can be cleaned up. void NotifyCloseCompleted(); - TabAnimationState GetCurrentState() const; TabAnimationState target_state() const { return target_state_; } base::TimeDelta GetTimeRemaining() const; + // Returns the TabWidthConstraints for the current state of the animation. + TabWidthConstraints GetCurrentTabWidthConstraints( + const TabLayoutConstants& layout_constants, + const TabSizeInfo& size_info) const; + private: + friend class TabAnimationTest; + FRIEND_TEST_ALL_PREFIXES(TabAnimationTest, ReplacedAnimationRestartsDuration); + + TabAnimationState GetCurrentState() const; + TabAnimationState initial_state_; TabAnimationState target_state_; base::TimeTicks start_time_;
diff --git a/chrome/browser/ui/views/tabs/tab_animation_state.cc b/chrome/browser/ui/views/tabs/tab_animation_state.cc index 5e4292d..ebcac485 100644 --- a/chrome/browser/ui/views/tabs/tab_animation_state.cc +++ b/chrome/browser/ui/views/tabs/tab_animation_state.cc
@@ -4,7 +4,7 @@ #include "chrome/browser/ui/views/tabs/tab_animation_state.h" -#include "chrome/browser/ui/views/tabs/tab_strip_layout.h" +#include "chrome/browser/ui/views/tabs/tab_strip_layout_types.h" #include "ui/gfx/animation/tween.h" TabAnimationState TabAnimationState::ForIdealTabState(TabOpenness open, @@ -48,39 +48,6 @@ normalized_leading_edge_x_); } -float TabAnimationState::GetMinimumWidth( - const TabLayoutConstants& layout_constants, - const TabSizeInfo& size_info) const { - const float min_width = gfx::Tween::FloatValueBetween( - activeness_, size_info.min_inactive_width, size_info.min_active_width); - return TransformForPinnednessAndOpenness(layout_constants, size_info, - min_width); -} - -float TabAnimationState::GetLayoutCrossoverWidth( - const TabLayoutConstants& layout_constants, - const TabSizeInfo& size_info) const { - return TransformForPinnednessAndOpenness(layout_constants, size_info, - size_info.min_active_width); -} - -float TabAnimationState::GetPreferredWidth( - const TabLayoutConstants& layout_constants, - const TabSizeInfo& size_info) const { - return TransformForPinnednessAndOpenness(layout_constants, size_info, - size_info.standard_width); -} - -float TabAnimationState::TransformForPinnednessAndOpenness( - const TabLayoutConstants& layout_constants, - const TabSizeInfo& size_info, - float width) const { - const float pinned_width = gfx::Tween::FloatValueBetween( - pinnedness_, width, size_info.pinned_tab_width); - return gfx::Tween::FloatValueBetween(openness_, layout_constants.tab_overlap, - pinned_width); -} - int TabAnimationState::GetLeadingEdgeOffset(std::vector<int> tab_widths, int my_index) const { // TODO(949660): Implement this to handle animated tab translations. Sum
diff --git a/chrome/browser/ui/views/tabs/tab_animation_state.h b/chrome/browser/ui/views/tabs/tab_animation_state.h index b3cfea27..e3d315e 100644 --- a/chrome/browser/ui/views/tabs/tab_animation_state.h +++ b/chrome/browser/ui/views/tabs/tab_animation_state.h
@@ -7,9 +7,6 @@ #include <vector> -struct TabLayoutConstants; -struct TabSizeInfo; - // Contains the data necessary to determine the bounds of a tab even while // it's in the middle of animating between states. Immutable (except for // replacement via assignment). @@ -39,33 +36,19 @@ TabAnimationState origin, TabAnimationState target); + float openness() const { return openness_; } + float pinnedness() const { return pinnedness_; } + float activeness() const { return activeness_; } + TabAnimationState WithOpenness(TabOpenness open) const; TabAnimationState WithPinnedness(TabPinnedness pinned) const; TabAnimationState WithActiveness(TabActiveness active) const; - // The smallest width this tab should ever have. - float GetMinimumWidth(const TabLayoutConstants& layout_constants, - const TabSizeInfo& size_info) const; - - // The width this tab should have at the crossover point between the - // tabstrip's two layout domains. Above this width, inactive tabs have the - // same width as active tabs. Below this width, inactive tabs are smaller - // than active tabs. - float GetLayoutCrossoverWidth(const TabLayoutConstants& layout_constants, - const TabSizeInfo& size_info) const; - - // The width this tab would like to have, if space is available. - float GetPreferredWidth(const TabLayoutConstants& layout_constants, - const TabSizeInfo& size_info) const; - int GetLeadingEdgeOffset(std::vector<int> tab_widths, int my_index) const; bool IsFullyClosed() const; private: - friend class TabAnimationTest; - friend class TabStripAnimatorTest; - TabAnimationState(float openness, float pinnedness, float activeness, @@ -75,12 +58,6 @@ activeness_(activeness), normalized_leading_edge_x_(normalized_leading_edge_x) {} - // All widths are affected by pinnedness and activeness in the same way. - float TransformForPinnednessAndOpenness( - const TabLayoutConstants& layout_constants, - const TabSizeInfo& size_info, - float width) const; - // The degree to which the tab is open. 1 if it is, 0 if it is not, and in // between if it's in the process of animating between open and closed. float openness_;
diff --git a/chrome/browser/ui/views/tabs/tab_animation_unittest.cc b/chrome/browser/ui/views/tabs/tab_animation_unittest.cc index 96618e6..a9dcaca7 100644 --- a/chrome/browser/ui/views/tabs/tab_animation_unittest.cc +++ b/chrome/browser/ui/views/tabs/tab_animation_unittest.cc
@@ -23,7 +23,9 @@ TabAnimationTest() : env_(base::test::ScopedTaskEnvironment::TimeSource::MOCK_TIME) {} - float PinnednessOf(TabAnimationState state) { return state.pinnedness_; } + float CurrentPinnedness(const TabAnimation& animation) { + return animation.GetCurrentState().pinnedness(); + } base::test::ScopedTaskEnvironment env_; }; @@ -38,12 +40,10 @@ EXPECT_EQ(kZeroDuration, static_animation.GetTimeRemaining()); EXPECT_EQ(base::TimeDelta::FromMilliseconds(0), static_animation.GetTimeRemaining()); - EXPECT_EQ(PinnednessOf(static_state), - PinnednessOf(static_animation.GetCurrentState())); + EXPECT_EQ(static_state.pinnedness(), CurrentPinnedness(static_animation)); env_.FastForwardBy(TabAnimation::kAnimationDuration); - EXPECT_EQ(PinnednessOf(static_state), - PinnednessOf(static_animation.GetCurrentState())); + EXPECT_EQ(static_state.pinnedness(), CurrentPinnedness(static_animation)); } TEST_F(TabAnimationTest, AnimationAnimates) { @@ -57,21 +57,17 @@ animation.AnimateTo(target_state); EXPECT_LT(kZeroDuration, animation.GetTimeRemaining()); - EXPECT_EQ(PinnednessOf(initial_state), - PinnednessOf(animation.GetCurrentState())); + EXPECT_EQ(initial_state.pinnedness(), CurrentPinnedness(animation)); env_.FastForwardBy(TabAnimation::kAnimationDuration / 2.0); EXPECT_LT(kZeroDuration, animation.GetTimeRemaining()); - EXPECT_LT(PinnednessOf(initial_state), - PinnednessOf(animation.GetCurrentState())); - EXPECT_LT(PinnednessOf(animation.GetCurrentState()), - PinnednessOf(target_state)); + EXPECT_LT(initial_state.pinnedness(), CurrentPinnedness(animation)); + EXPECT_LT(CurrentPinnedness(animation), target_state.pinnedness()); env_.FastForwardBy(TabAnimation::kAnimationDuration / 2.0); - EXPECT_EQ(PinnednessOf(target_state), - PinnednessOf(animation.GetCurrentState())); + EXPECT_EQ(target_state.pinnedness(), CurrentPinnedness(animation)); } TEST_F(TabAnimationTest, CompletedAnimationSnapsToTarget) { @@ -88,8 +84,7 @@ EXPECT_EQ(kZeroDuration, animation.GetTimeRemaining()); EXPECT_EQ(base::TimeDelta::FromMilliseconds(0), animation.GetTimeRemaining()); - EXPECT_EQ(PinnednessOf(target_state), - PinnednessOf(animation.GetCurrentState())); + EXPECT_EQ(target_state.pinnedness(), CurrentPinnedness(animation)); } TEST_F(TabAnimationTest, ReplacedAnimationRestartsDuration) { @@ -106,8 +101,7 @@ TabAnimationState reversal_state = animation.GetCurrentState(); animation.AnimateTo(initial_state); - EXPECT_EQ(PinnednessOf(reversal_state), - PinnednessOf(animation.GetCurrentState())); + EXPECT_EQ(reversal_state.pinnedness(), CurrentPinnedness(animation)); EXPECT_EQ(TabAnimation::kAnimationDuration, animation.GetTimeRemaining()); } @@ -131,8 +125,7 @@ animation.GetTimeRemaining()); env_.FastForwardBy(TabAnimation::kAnimationDuration); - EXPECT_EQ(PinnednessOf(initial_state), - PinnednessOf(animation.GetCurrentState())); + EXPECT_EQ(initial_state.pinnedness(), CurrentPinnedness(animation)); } TEST_F(TabAnimationTest, TestNotifyCloseCompleted) {
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc index d24d8f9..685549b 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.cc +++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -43,8 +43,8 @@ #include "chrome/browser/ui/views/tabs/tab_group_header.h" #include "chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h" #include "chrome/browser/ui/views/tabs/tab_strip_controller.h" -#include "chrome/browser/ui/views/tabs/tab_strip_layout.h" #include "chrome/browser/ui/views/tabs/tab_strip_layout_helper.h" +#include "chrome/browser/ui/views/tabs/tab_strip_layout_types.h" #include "chrome/browser/ui/views/tabs/tab_strip_observer.h" #include "chrome/browser/ui/views/tabs/tab_style_views.h" #include "chrome/browser/ui/views/touch_uma/touch_uma.h"
diff --git a/chrome/browser/ui/views/tabs/tab_strip_layout.cc b/chrome/browser/ui/views/tabs/tab_strip_layout.cc index 967d0b5..984dfba 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_layout.cc +++ b/chrome/browser/ui/views/tabs/tab_strip_layout.cc
@@ -11,7 +11,6 @@ #include "base/logging.h" #include "base/numerics/ranges.h" #include "chrome/browser/ui/tabs/tab_style.h" -#include "chrome/browser/ui/views/tabs/tab_animation_state.h" #include "ui/gfx/animation/tween.h" #include "ui/gfx/geometry/rect.h" @@ -32,48 +31,32 @@ // of space available relative to how much the tabs could use. class TabSizer { public: - TabSizer(const TabLayoutConstants& layout_constants, - LayoutDomain domain, - float space_fraction_available) - : layout_constants_(layout_constants), - domain_(domain), - space_fraction_available_(space_fraction_available) {} + TabSizer(LayoutDomain domain, float space_fraction_available) + : domain_(domain), space_fraction_available_(space_fraction_available) {} - int CalculateTabWidth(const TabLayoutInfo& tab) { + int CalculateTabWidth(const TabWidthConstraints& tab) { switch (domain_) { case LayoutDomain::kInactiveWidthBelowActiveWidth: return std::floor(gfx::Tween::FloatValueBetween( - space_fraction_available_, - tab.animation_state.GetMinimumWidth(layout_constants_, - tab.size_info), - tab.animation_state.GetLayoutCrossoverWidth(layout_constants_, - tab.size_info))); + space_fraction_available_, tab.GetMinimumWidth(), + tab.GetLayoutCrossoverWidth())); case LayoutDomain::kInactiveWidthEqualsActiveWidth: return std::floor(gfx::Tween::FloatValueBetween( - space_fraction_available_, - tab.animation_state.GetLayoutCrossoverWidth(layout_constants_, - tab.size_info), - tab.animation_state.GetPreferredWidth(layout_constants_, - tab.size_info))); + space_fraction_available_, tab.GetLayoutCrossoverWidth(), + tab.GetPreferredWidth())); } } // Returns true iff it's OK for this tab to be one pixel wider than // CalculateTabWidth(|tab|). - bool TabAcceptsExtraSpace(const TabLayoutInfo& tab) { + bool TabAcceptsExtraSpace(const TabWidthConstraints& tab) { if (space_fraction_available_ == 0.0f || space_fraction_available_ == 1.0f) return false; switch (domain_) { case LayoutDomain::kInactiveWidthBelowActiveWidth: - return tab.animation_state.GetMinimumWidth(layout_constants_, - tab.size_info) < - tab.animation_state.GetLayoutCrossoverWidth(layout_constants_, - tab.size_info); + return tab.GetMinimumWidth() < tab.GetLayoutCrossoverWidth(); case LayoutDomain::kInactiveWidthEqualsActiveWidth: - return tab.animation_state.GetLayoutCrossoverWidth(layout_constants_, - tab.size_info) < - tab.animation_state.GetPreferredWidth(layout_constants_, - tab.size_info); + return tab.GetLayoutCrossoverWidth() < tab.GetPreferredWidth(); } } @@ -83,7 +66,6 @@ } private: - const TabLayoutConstants& layout_constants_; const LayoutDomain domain_; // The proportion of space requirements we can fulfill within the layout @@ -95,23 +77,18 @@ // to use relative to how much they want to use. TabSizer CalculateSpaceFractionAvailable( const TabLayoutConstants& layout_constants, - const std::vector<TabLayoutInfo>& tabs, + const std::vector<TabWidthConstraints>& tabs, int width) { float minimum_width = 0; float crossover_width = 0; float preferred_width = 0; - for (const TabLayoutInfo& tab : tabs) { + for (const TabWidthConstraints& tab : tabs) { // Add the tab's width, less the width of its trailing foot (which would // be double counting). - minimum_width += - tab.animation_state.GetMinimumWidth(layout_constants, tab.size_info) - - layout_constants.tab_overlap; - crossover_width += tab.animation_state.GetLayoutCrossoverWidth( - layout_constants, tab.size_info) - - layout_constants.tab_overlap; - preferred_width += - tab.animation_state.GetPreferredWidth(layout_constants, tab.size_info) - - layout_constants.tab_overlap; + minimum_width += tab.GetMinimumWidth() - layout_constants.tab_overlap; + crossover_width += + tab.GetLayoutCrossoverWidth() - layout_constants.tab_overlap; + preferred_width += tab.GetPreferredWidth() - layout_constants.tab_overlap; } // Add back the width of the trailing foot of the last tab. @@ -135,29 +112,29 @@ space_fraction_available = base::ClampToRange(space_fraction_available, 0.0f, 1.0f); - return TabSizer(layout_constants, domain, space_fraction_available); + return TabSizer(domain, space_fraction_available); } // Because TabSizer::CalculateTabWidth() rounds down, the fractional part of tab // widths go unused. Retroactively round up tab widths from left to right to // use up that width. -void AllocateExtraSpace(std::vector<gfx::Rect>& bounds, - const std::vector<TabLayoutInfo>& tabs, +void AllocateExtraSpace(std::vector<gfx::Rect>* bounds, + const std::vector<TabWidthConstraints>& tabs, int width, TabSizer tab_sizer) { // Don't expand tabs if they are already at their preferred width. if (tab_sizer.IsAlreadyPreferredWidth()) return; - const int extra_space = width - bounds.back().right(); + const int extra_space = width - bounds->back().right(); int allocated_extra_space = 0; for (size_t i = 0; i < tabs.size(); i++) { - const TabLayoutInfo& tab = tabs[i]; - bounds[i].set_x(bounds[i].x() + allocated_extra_space); + const TabWidthConstraints& tab = tabs[i]; + bounds->at(i).set_x(bounds->at(i).x() + allocated_extra_space); if (allocated_extra_space < extra_space && tab_sizer.TabAcceptsExtraSpace(tab)) { allocated_extra_space++; - bounds[i].set_width(bounds[i].width() + 1); + bounds->at(i).set_width(bounds->at(i).width() + 1); } } } @@ -166,7 +143,7 @@ std::vector<gfx::Rect> CalculateTabBounds( const TabLayoutConstants& layout_constants, - const std::vector<TabLayoutInfo>& tabs, + const std::vector<TabWidthConstraints>& tabs, int width) { if (tabs.empty()) return std::vector<gfx::Rect>(); @@ -176,21 +153,21 @@ int next_x = 0; std::vector<gfx::Rect> bounds; - for (const TabLayoutInfo& tab : tabs) { + for (const TabWidthConstraints& tab : tabs) { const int tab_width = tab_sizer.CalculateTabWidth(tab); bounds.push_back( gfx::Rect(next_x, 0, tab_width, layout_constants.tab_height)); next_x += tab_width - layout_constants.tab_overlap; } - AllocateExtraSpace(bounds, tabs, width, tab_sizer); + AllocateExtraSpace(&bounds, tabs, width, tab_sizer); return bounds; } std::vector<gfx::Rect> CalculatePinnedTabBounds( const TabLayoutConstants& layout_constants, - const std::vector<TabLayoutInfo>& pinned_tabs) { + const std::vector<TabWidthConstraints>& pinned_tabs) { // Pinned tabs are always the same size regardless of the available width. return CalculateTabBounds(layout_constants, pinned_tabs, 0); }
diff --git a/chrome/browser/ui/views/tabs/tab_strip_layout.h b/chrome/browser/ui/views/tabs/tab_strip_layout.h index 28636cc..cd51ffb 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_layout.h +++ b/chrome/browser/ui/views/tabs/tab_strip_layout.h
@@ -7,53 +7,24 @@ #include <vector> -#include "chrome/browser/ui/views/tabs/tab_animation_state.h" -#include "ui/gfx/geometry/size.h" +#include "chrome/browser/ui/views/tabs/tab_strip_layout_types.h" +#include "chrome/browser/ui/views/tabs/tab_width_constraints.h" namespace gfx { class Rect; } -// Sizing info for individual tabs. -struct TabSizeInfo { - // The width of pinned tabs. - int pinned_tab_width; - - // The min width of active/inactive tabs. - int min_active_width; - int min_inactive_width; - - // The width of a standard tab, which is the largest size active or inactive - // tabs ever have. - int standard_width; -}; - -// Sizing info global to the tabstrip. -struct TabLayoutConstants { - // The height of tabs. - int tab_height; - - // The amount adjacent tabs overlap each other. - int tab_overlap; -}; - -// Animation and sizing information for one tab. -struct TabLayoutInfo { - TabAnimationState animation_state; - TabSizeInfo size_info; -}; - // Calculates and returns the bounds of the tabs. |width| is the available // width to use for tab layout. This never sizes the tabs smaller then the // minimum widths in TabSizeInfo, and as a result the calculated bounds may go // beyond |width|. std::vector<gfx::Rect> CalculateTabBounds( const TabLayoutConstants& layout_constants, - const std::vector<TabLayoutInfo>& tabs, + const std::vector<TabWidthConstraints>& tabs, int width); std::vector<gfx::Rect> CalculatePinnedTabBounds( const TabLayoutConstants& layout_constants, - const std::vector<TabLayoutInfo>& pinned_tabs); + const std::vector<TabWidthConstraints>& pinned_tabs); #endif // CHROME_BROWSER_UI_VIEWS_TABS_TAB_STRIP_LAYOUT_H_
diff --git a/chrome/browser/ui/views/tabs/tab_strip_layout_helper.cc b/chrome/browser/ui/views/tabs/tab_strip_layout_helper.cc index 463cbcc..cd28d831 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_layout_helper.cc +++ b/chrome/browser/ui/views/tabs/tab_strip_layout_helper.cc
@@ -19,6 +19,7 @@ #include "chrome/browser/ui/views/tabs/tab_slot_view.h" #include "chrome/browser/ui/views/tabs/tab_strip_controller.h" #include "chrome/browser/ui/views/tabs/tab_strip_layout.h" +#include "chrome/browser/ui/views/tabs/tab_strip_layout_types.h" #include "chrome/browser/ui/views/tabs/tab_style_views.h" #include "ui/base/material_design/material_design_controller.h" #include "ui/views/view_model.h" @@ -259,7 +260,8 @@ pinned_tab_count > 0 ? GetSlotIndexForTabModelIndex(pinned_tab_count - 1) : TabStripModel::kNoTab; - std::vector<TabLayoutInfo> tab_layout_info; + TabLayoutConstants layout_constants = GetTabLayoutConstants(); + std::vector<TabWidthConstraints> tab_widths; for (int i = 0; i < int{slots_.size()}; i++) { auto active = i == active_tab_slot_index ? TabAnimationState::TabActiveness::kActive @@ -267,17 +269,18 @@ auto pinned = i <= last_pinned_tab_slot_index ? TabAnimationState::TabPinnedness::kPinned : TabAnimationState::TabPinnedness::kUnpinned; - auto open = slots_[i].animation->target_state().IsFullyClosed() + auto open = slots_[i].animation->IsClosing() ? TabAnimationState::TabOpenness::kClosed : TabAnimationState::TabOpenness::kOpen; TabAnimationState ideal_animation_state = TabAnimationState::ForIdealTabState(open, pinned, active, 0); - tab_layout_info.push_back( - {ideal_animation_state, slots_[i].view->GetTabSizeInfo()}); + TabSizeInfo size_info = slots_[i].view->GetTabSizeInfo(); + tab_widths.push_back(TabWidthConstraints(ideal_animation_state, + layout_constants, size_info)); } - const std::vector<gfx::Rect> bounds = CalculateTabBounds( - GetTabLayoutConstants(), tab_layout_info, available_width); + const std::vector<gfx::Rect> bounds = + CalculateTabBounds(layout_constants, tab_widths, available_width); DCHECK_EQ(slots_.size(), bounds.size()); views::ViewModelT<Tab>* tabs = get_tabs_callback_.Run(); @@ -289,7 +292,7 @@ const TabSlot& slot = slots_[i]; switch (slot.type) { case ViewType::kTab: - if (!slot.animation->target_state().IsFullyClosed()) { + if (!slot.animation->IsClosing()) { tabs->set_ideal_bounds(current_tab_model_index, bounds[i]); UpdateCachedTabWidth(i, bounds[i].width(), i == active_tab_slot_index); @@ -310,20 +313,22 @@ first_non_pinned_tab_index_ = pinned_tab_count; first_non_pinned_tab_x_ = 0; + TabLayoutConstants layout_constants = GetTabLayoutConstants(); if (pinned_tab_count > 0) { - std::vector<TabLayoutInfo> layout_info; + std::vector<TabWidthConstraints> tab_widths; for (int tab_index = 0; tab_index < pinned_tab_count; tab_index++) { TabAnimationState ideal_animation_state = TabAnimationState::ForIdealTabState( TabAnimationState::TabOpenness::kOpen, TabAnimationState::TabPinnedness::kPinned, TabAnimationState::TabActiveness::kInactive, 0); - layout_info.push_back( - {ideal_animation_state, tabs->view_at(tab_index)->GetTabSizeInfo()}); + TabSizeInfo size_info = tabs->view_at(tab_index)->GetTabSizeInfo(); + tab_widths.push_back(TabWidthConstraints(ideal_animation_state, + layout_constants, size_info)); } const std::vector<gfx::Rect> tab_bounds = - CalculatePinnedTabBounds(GetTabLayoutConstants(), layout_info); + CalculatePinnedTabBounds(layout_constants, tab_widths); for (int i = 0; i < pinned_tab_count; ++i) tabs->set_ideal_bounds(i, tab_bounds[i]); @@ -331,14 +336,15 @@ } int TabStripLayoutHelper::LayoutTabs(int available_width) { - views::ViewModelT<Tab>* tabs = get_tabs_callback_.Run(); - std::map<TabGroupId, TabGroupHeader*> group_headers = - get_group_headers_callback_.Run(); - - std::vector<gfx::Rect> bounds = CalculateTabBounds( - GetTabLayoutConstants(), CreateTabLayoutInfo(), available_width); + std::vector<gfx::Rect> bounds = + CalculateTabBounds(GetTabLayoutConstants(), + GetCurrentTabWidthConstraints(), available_width); if (DCHECK_IS_ON()) { + views::ViewModelT<Tab>* tabs = get_tabs_callback_.Run(); + std::map<TabGroupId, TabGroupHeader*> group_headers = + get_group_headers_callback_.Run(); + int num_closing_tabs = 0; for (Tab* tab : GetTabs()) { if (tab->closing()) @@ -367,7 +373,7 @@ current_tab_model_index, bounds[i].width(), current_tab_model_index == active_tab_model_index); } - if (!slots_[i].animation->target_state().IsFullyClosed()) + if (!slots_[i].animation->IsClosing()) ++current_tab_model_index; break; } @@ -385,8 +391,7 @@ int TabStripLayoutHelper::GetSlotIndexForTabModelIndex(int model_index) const { int current_model_index = 0; for (size_t i = 0; i < slots_.size(); i++) { - if (slots_[i].type == ViewType::kTab && - !slots_[i].animation->target_state().IsFullyClosed()) { + if (slots_[i].type == ViewType::kTab && !slots_[i].animation->IsClosing()) { if (current_model_index == model_index) return i; ++current_model_index; @@ -407,11 +412,13 @@ return 0; } -std::vector<TabLayoutInfo> TabStripLayoutHelper::CreateTabLayoutInfo() const { - std::vector<TabLayoutInfo> result; +std::vector<TabWidthConstraints> +TabStripLayoutHelper::GetCurrentTabWidthConstraints() const { + TabLayoutConstants layout_constants = GetTabLayoutConstants(); + std::vector<TabWidthConstraints> result; for (const TabSlot& slot : slots_) { - result.push_back( - {slot.animation->GetCurrentState(), slot.view->GetTabSizeInfo()}); + result.push_back(slot.animation->GetCurrentTabWidthConstraints( + layout_constants, slot.view->GetTabSizeInfo())); } return result; } @@ -442,8 +449,7 @@ void TabStripLayoutHelper::RemoveClosedTabs() { for (auto it = slots_.begin(); it != slots_.end();) { - if (it->animation->GetTimeRemaining().is_zero() && - it->animation->GetCurrentState().IsFullyClosed()) { + if (it->animation->IsClosed()) { it->animation->NotifyCloseCompleted(); it = slots_.erase(it); } else {
diff --git a/chrome/browser/ui/views/tabs/tab_strip_layout_helper.h b/chrome/browser/ui/views/tabs/tab_strip_layout_helper.h index 9456df1..204abd5 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_layout_helper.h +++ b/chrome/browser/ui/views/tabs/tab_strip_layout_helper.h
@@ -13,13 +13,13 @@ #include "base/optional.h" #include "base/timer/timer.h" #include "chrome/browser/ui/views/tabs/tab_animation_state.h" +#include "chrome/browser/ui/views/tabs/tab_width_constraints.h" #include "ui/gfx/geometry/rect.h" #include "ui/views/view_model.h" class Tab; class TabGroupHeader; class TabGroupId; -struct TabLayoutInfo; class TabStripController; // Helper class for TabStrip, that is responsible for calculating and assigning @@ -135,8 +135,8 @@ // in |slots_|. int GetSlotIndexForGroupHeader(TabGroupId group) const; - // Returns the current layout info (animation and sizing) for each View. - std::vector<TabLayoutInfo> CreateTabLayoutInfo() const; + // Returns the current width constraints for each View. + std::vector<TabWidthConstraints> GetCurrentTabWidthConstraints() const; // Runs an animation for the View at |slot_index| towards |target_state|. void AnimateSlot(int slot_index, TabAnimationState target_state);
diff --git a/chrome/browser/ui/views/tabs/tab_strip_layout_types.h b/chrome/browser/ui/views/tabs/tab_strip_layout_types.h new file mode 100644 index 0000000..796b286 --- /dev/null +++ b/chrome/browser/ui/views/tabs/tab_strip_layout_types.h
@@ -0,0 +1,31 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_TABS_TAB_STRIP_LAYOUT_TYPES_H_ +#define CHROME_BROWSER_UI_VIEWS_TABS_TAB_STRIP_LAYOUT_TYPES_H_ + +// Sizing info for individual tabs. +struct TabSizeInfo { + // The width of pinned tabs. + int pinned_tab_width; + + // The min width of active/inactive tabs. + int min_active_width; + int min_inactive_width; + + // The width of a standard tab, which is the largest size active or inactive + // tabs ever have. + int standard_width; +}; + +// Sizing info global to the tabstrip. +struct TabLayoutConstants { + // The height of tabs. + int tab_height; + + // The amount adjacent tabs overlap each other. + int tab_overlap; +}; + +#endif // CHROME_BROWSER_UI_VIEWS_TABS_TAB_STRIP_LAYOUT_TYPES_H_
diff --git a/chrome/browser/ui/views/tabs/tab_strip_layout_unittest.cc b/chrome/browser/ui/views/tabs/tab_strip_layout_unittest.cc index 7712bc8..9476a3e 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_layout_unittest.cc +++ b/chrome/browser/ui/views/tabs/tab_strip_layout_unittest.cc
@@ -5,10 +5,12 @@ #include "chrome/browser/ui/views/tabs/tab_strip_layout.h" #include <stddef.h> +#include <string> #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "chrome/browser/ui/views/tabs/tab_animation_state.h" +#include "chrome/browser/ui/views/tabs/tab_width_constraints.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/geometry/rect.h" @@ -53,17 +55,17 @@ constexpr int kTabOverlap = 4; std::vector<gfx::Rect> CalculateTabBounds(TestCase test_case) { + TabLayoutConstants layout_constants; + layout_constants.tab_height = kTabHeight; + layout_constants.tab_overlap = kTabOverlap; + TabSizeInfo size_info; size_info.pinned_tab_width = kPinnedWidth; size_info.min_active_width = kMinActiveWidth; size_info.min_inactive_width = kMinInactiveWidth; size_info.standard_width = kStandardWidth; - TabLayoutConstants layout_constants; - layout_constants.tab_height = kTabHeight; - layout_constants.tab_overlap = kTabOverlap; - - std::vector<TabLayoutInfo> layout_info; + std::vector<TabWidthConstraints> tab_states; for (int tab_index = 0; tab_index < test_case.num_tabs; tab_index++) { TabAnimationState ideal_animation_state = TabAnimationState::ForIdealTabState( @@ -75,10 +77,11 @@ ? TabAnimationState::TabActiveness::kActive : TabAnimationState::TabActiveness::kInactive, 0); - layout_info.push_back({ideal_animation_state, size_info}); + tab_states.push_back(TabWidthConstraints(ideal_animation_state, + layout_constants, size_info)); } - return CalculateTabBounds(layout_constants, layout_info, + return CalculateTabBounds(layout_constants, tab_states, test_case.tabstrip_width); }
diff --git a/chrome/browser/ui/views/tabs/tab_width_constraints.cc b/chrome/browser/ui/views/tabs/tab_width_constraints.cc new file mode 100644 index 0000000..d8898bc --- /dev/null +++ b/chrome/browser/ui/views/tabs/tab_width_constraints.cc
@@ -0,0 +1,39 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/views/tabs/tab_width_constraints.h" + +#include "chrome/browser/ui/views/tabs/tab_strip_layout.h" +#include "ui/gfx/animation/tween.h" + +TabWidthConstraints::TabWidthConstraints( + const TabAnimationState& state, + const TabLayoutConstants& layout_constants, + const TabSizeInfo& size_info) + : state_(state), + layout_constants_(layout_constants), + size_info_(size_info) {} + +float TabWidthConstraints::GetMinimumWidth() const { + const float min_width = gfx::Tween::FloatValueBetween( + state_.activeness(), size_info_.min_inactive_width, + size_info_.min_active_width); + return TransformForPinnednessAndOpenness(min_width); +} + +float TabWidthConstraints::GetLayoutCrossoverWidth() const { + return TransformForPinnednessAndOpenness(size_info_.min_active_width); +} + +float TabWidthConstraints::GetPreferredWidth() const { + return TransformForPinnednessAndOpenness(size_info_.standard_width); +} + +float TabWidthConstraints::TransformForPinnednessAndOpenness( + float width) const { + const float pinned_width = gfx::Tween::FloatValueBetween( + state_.pinnedness(), width, size_info_.pinned_tab_width); + return gfx::Tween::FloatValueBetween( + state_.openness(), layout_constants_.tab_overlap, pinned_width); +}
diff --git a/chrome/browser/ui/views/tabs/tab_width_constraints.h b/chrome/browser/ui/views/tabs/tab_width_constraints.h new file mode 100644 index 0000000..3823590 --- /dev/null +++ b/chrome/browser/ui/views/tabs/tab_width_constraints.h
@@ -0,0 +1,41 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_TABS_TAB_WIDTH_CONSTRAINTS_H_ +#define CHROME_BROWSER_UI_VIEWS_TABS_TAB_WIDTH_CONSTRAINTS_H_ + +#include <vector> + +#include "chrome/browser/ui/views/tabs/tab_animation_state.h" +#include "chrome/browser/ui/views/tabs/tab_strip_layout_types.h" + +// Provides width information for a single tab during layout. +class TabWidthConstraints { + public: + TabWidthConstraints(const TabAnimationState& state, + const TabLayoutConstants& layout_constants, + const TabSizeInfo& size_info); + + // The smallest width this tab should ever have. + float GetMinimumWidth() const; + + // The width this tab should have at the crossover point between the + // tabstrip's two layout domains. Above this width, inactive tabs have the + // same width as active tabs. Below this width, inactive tabs are smaller + // than active tabs. + float GetLayoutCrossoverWidth() const; + + // The width this tab would like to have, if space is available. + float GetPreferredWidth() const; + + private: + // All widths are affected by pinnedness and activeness in the same way. + float TransformForPinnednessAndOpenness(float width) const; + + TabAnimationState state_; + TabLayoutConstants layout_constants_; + TabSizeInfo size_info_; +}; + +#endif // CHROME_BROWSER_UI_VIEWS_TABS_TAB_WIDTH_CONSTRAINTS_H_
diff --git a/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.cc b/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.cc index 48a08a9..613e12f 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.cc
@@ -17,9 +17,10 @@ ToolbarIconContainerView::ToolbarIconContainerView(bool uses_highlight) : uses_highlight_(uses_highlight) { auto layout_manager = std::make_unique<views::FlexLayout>(); - layout_manager->SetCollapseMargins(true).SetDefault( - views::kMarginsKey, - gfx::Insets(0, 0, 0, GetLayoutConstant(TOOLBAR_ELEMENT_PADDING))); + layout_manager->SetCollapseMargins(true) + .SetIgnoreDefaultMainAxisMargins(true) + .SetDefault(views::kMarginsKey, + gfx::Insets(0, GetLayoutConstant(TOOLBAR_ELEMENT_PADDING))); SetLayoutManager(std::move(layout_manager)); } @@ -29,9 +30,6 @@ void ToolbarIconContainerView::AddMainButton(views::Button* main_button) { DCHECK(!main_button_); - // Set empty margins from this view to remove the default ones set in the - // constructor. - main_button->SetProperty(views::kMarginsKey, gfx::Insets()); main_button->AddObserver(this); main_button->AddButtonObserver(this); main_button_ = main_button;
diff --git a/chrome/browser/ui/web_applications/web_app_browser_controller.cc b/chrome/browser/ui/web_applications/web_app_browser_controller.cc index fb2dd29f..3f923b6 100644 --- a/chrome/browser/ui/web_applications/web_app_browser_controller.cc +++ b/chrome/browser/ui/web_applications/web_app_browser_controller.cc
@@ -5,6 +5,8 @@ #include "chrome/browser/ui/web_applications/web_app_browser_controller.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/web_applications/web_app_dialog_manager.h" +#include "chrome/browser/ui/web_applications/web_app_ui_manager_impl.h" #include "chrome/browser/web_applications/components/web_app_helpers.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "ui/gfx/image/image_skia.h" @@ -89,13 +91,20 @@ } bool WebAppBrowserController::CanUninstall() const { - // TODO(https://crbug.com/966290): Complete implementation. - return false; + return WebAppUiManagerImpl::Get(browser()->profile()) + ->dialog_manager() + .CanUninstallWebApp(app_id_); +} + +void WebAppBrowserController::Uninstall() { + WebAppUiManagerImpl::Get(browser()->profile()) + ->dialog_manager() + .UninstallWebApp(app_id_, WebAppDialogManager::UninstallSource::kAppMenu, + browser()->window(), base::DoNothing()); } bool WebAppBrowserController::IsInstalled() const { - // TODO(https://crbug.com/966290): Complete implementation. - return true; + return registrar_.IsInstalled(app_id_); } } // namespace web_app
diff --git a/chrome/browser/ui/web_applications/web_app_browser_controller.h b/chrome/browser/ui/web_applications/web_app_browser_controller.h index 14da2a2a..277d0ad 100644 --- a/chrome/browser/ui/web_applications/web_app_browser_controller.h +++ b/chrome/browser/ui/web_applications/web_app_browser_controller.h
@@ -47,6 +47,7 @@ GURL GetAppLaunchURL() const override; bool IsUrlInAppScope(const GURL& url) const override; bool CanUninstall() const override; + void Uninstall() override; bool IsInstalled() const override; bool IsHostedApp() const override;
diff --git a/chrome/browser/ui/web_applications/web_app_launch_manager.cc b/chrome/browser/ui/web_applications/web_app_launch_manager.cc index cdc7947..9782902e 100644 --- a/chrome/browser/ui/web_applications/web_app_launch_manager.cc +++ b/chrome/browser/ui/web_applications/web_app_launch_manager.cc
@@ -53,7 +53,6 @@ NavigateParams nav_params(browser, launch_url, ui::PAGE_TRANSITION_AUTO_BOOKMARK); nav_params.disposition = disposition; - nav_params.opener = params.opener; Navigate(&nav_params); content::WebContents* web_contents =
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc index 4f0d21b..ddff7e5 100644 --- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -196,6 +196,8 @@ {"moreFeaturesLinkDescription", IDS_SETTINGS_MORE_FEATURES_LINK_DESCRIPTION}, {"captionsTitle", IDS_SETTINGS_CAPTIONS}, + {"captionsSettings", IDS_SETTINGS_CAPTIONS_SETTINGS}, + {"captionsPreview", IDS_SETTINGS_CAPTIONS_PREVIEW}, {"captionsTextSize", IDS_SETTINGS_CAPTIONS_TEXT_SIZE}, {"captionsTextFont", IDS_SETTINGS_CAPTIONS_TEXT_FONT}, {"captionsTextColor", IDS_SETTINGS_CAPTIONS_TEXT_COLOR}, @@ -1920,7 +1922,7 @@ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_FINGERPRINT_LESS_SECURE}, {"lockScreenDeleteFingerprintLabel", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_DELETE_FINGERPRINT_ARIA_LABEL}, - {"lockScreenMediaKeys", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_MEDIA_KEYS}, + {"lockScreenMediaControls", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_MEDIA_CONTROLS}, {"lockScreenNotificationHide", IDS_ASH_SETTINGS_LOCK_SCREEN_NOTIFICATION_HIDE}, {"lockScreenNotificationHideSensitive",
diff --git a/chrome/browser/ui/webui/settings/settings_ui.cc b/chrome/browser/ui/webui/settings/settings_ui.cc index fb777f8d..dd41d4cb 100644 --- a/chrome/browser/ui/webui/settings/settings_ui.cc +++ b/chrome/browser/ui/webui/settings/settings_ui.cc
@@ -491,8 +491,8 @@ "lockScreenHideSensitiveNotificationsSupported", ash::features::IsLockScreenHideSensitiveNotificationsSupported()); html_source->AddBoolean( - "lockScreenMediaKeysEnabled", - base::FeatureList::IsEnabled(ash::features::kLockScreenMediaKeys)); + "lockScreenMediaControlsEnabled", + base::FeatureList::IsEnabled(ash::features::kLockScreenMediaControls)); html_source->AddBoolean("showTechnologyBadge", !ash::features::IsSeparateNetworkIconsEnabled()); html_source->AddBoolean("hasInternalStylus",
diff --git a/chrome/browser/ui/webui/settings/tts_handler.cc b/chrome/browser/ui/webui/settings/tts_handler.cc index 440e917..3538868 100644 --- a/chrome/browser/ui/webui/settings/tts_handler.cc +++ b/chrome/browser/ui/webui/settings/tts_handler.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/speech/extension_api/tts_engine_extension_api.h" #include "chrome/browser/speech/extension_api/tts_engine_extension_observer.h" +#include "chrome/browser/ui/chrome_pages.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/grit/generated_resources.h" #include "content/public/browser/tts_controller.h" @@ -143,7 +144,8 @@ utterance->SetText(text); utterance->SetVoiceName(name); utterance->SetEngineId(extension_id); - utterance->SetSrcUrl(GURL("chrome://settings/manageAccessibility/tts")); + utterance->SetSrcUrl( + GURL(chrome::GetOSSettingsUrl("manageAccessibility/tts"))); utterance->SetEventDelegate(this); content::TtsController::GetInstance()->Stop();
diff --git a/chrome/browser/ui/xr/xr_session_request_consent_dialog_delegate.cc b/chrome/browser/ui/xr/xr_session_request_consent_dialog_delegate.cc index f8a7bbd..87f4c20 100644 --- a/chrome/browser/ui/xr/xr_session_request_consent_dialog_delegate.cc +++ b/chrome/browser/ui/xr/xr_session_request_consent_dialog_delegate.cc
@@ -78,7 +78,7 @@ base::Optional<int> XrSessionRequestConsentDialogDelegate::GetInitiallyFocusedButton() { - return ui::DIALOG_BUTTON_CANCEL; + return ui::DIALOG_BUTTON_NONE; } } // namespace vr
diff --git a/chrome/browser/upgrade_detector/upgrade_detector_impl.cc b/chrome/browser/upgrade_detector/upgrade_detector_impl.cc index cfb6b7d..1c06aaa 100644 --- a/chrome/browser/upgrade_detector/upgrade_detector_impl.cc +++ b/chrome/browser/upgrade_detector/upgrade_detector_impl.cc
@@ -146,8 +146,8 @@ UpgradeDetectorImpl::UpgradeDetectorImpl(const base::Clock* clock, const base::TickClock* tick_clock) : UpgradeDetector(clock, tick_clock), - blocking_task_runner_(base::CreateSequencedTaskRunnerWithTraits( - {base::TaskPriority::BEST_EFFORT, + blocking_task_runner_(base::CreateSequencedTaskRunner( + {base::ThreadPool(), base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN, base::MayBlock()})), detect_upgrade_timer_(this->tick_clock()),
diff --git a/chrome/browser/vr/OWNERS b/chrome/browser/vr/OWNERS index 6c73cd1..2805546 100644 --- a/chrome/browser/vr/OWNERS +++ b/chrome/browser/vr/OWNERS
@@ -9,6 +9,7 @@ # Browser Test-related. alcooper@chromium.org bsheedy@chromium.org +jacde@chromium.org # TEAM: xr-dev@chromium.org # COMPONENT: UI>Browser>VR
diff --git a/chrome/browser/vr/test/xr_browser_test.cc b/chrome/browser/vr/test/xr_browser_test.cc index 648c624..cdd81ea2 100644 --- a/chrome/browser/vr/test/xr_browser_test.cc +++ b/chrome/browser/vr/test/xr_browser_test.cc
@@ -170,34 +170,6 @@ return XrBrowserTestBase::RuntimeType::RUNTIME_NONE; } -device::XrAxisType XrBrowserTestBase::GetPrimaryAxisType() const { - auto runtime = GetRuntimeType(); - switch (runtime) { - case XrBrowserTestBase::RuntimeType::RUNTIME_OPENVR: - return device::XrAxisType::kTrackpad; - case XrBrowserTestBase::RuntimeType::RUNTIME_WMR: - case XrBrowserTestBase::RuntimeType::RUNTIME_OPENXR: - return device::XrAxisType::kJoystick; - case XrBrowserTestBase::RuntimeType::RUNTIME_NONE: - return device::XrAxisType::kNone; - } - NOTREACHED(); -} - -device::XrAxisType XrBrowserTestBase::GetSecondaryAxisType() const { - auto runtime = GetRuntimeType(); - switch (runtime) { - case XrBrowserTestBase::RuntimeType::RUNTIME_OPENVR: - return device::XrAxisType::kJoystick; - case XrBrowserTestBase::RuntimeType::RUNTIME_WMR: - case XrBrowserTestBase::RuntimeType::RUNTIME_OPENXR: - return device::XrAxisType::kTrackpad; - case XrBrowserTestBase::RuntimeType::RUNTIME_NONE: - return device::XrAxisType::kNone; - } - NOTREACHED(); -} - GURL XrBrowserTestBase::GetFileUrlForHtmlTestFile( const std::string& test_name) { return ui_test_utils::GetTestUrl(
diff --git a/chrome/browser/vr/test/xr_browser_test.h b/chrome/browser/vr/test/xr_browser_test.h index f321f5c..06e6387 100644 --- a/chrome/browser/vr/test/xr_browser_test.h +++ b/chrome/browser/vr/test/xr_browser_test.h
@@ -85,8 +85,6 @@ void TearDown() override; virtual RuntimeType GetRuntimeType() const; - device::XrAxisType GetPrimaryAxisType() const; - device::XrAxisType GetSecondaryAxisType() const; // Returns a GURL to the XR test HTML file of the given name, e.g. // GetHtmlTestFile("foo") returns a GURL for the foo.html file in the XR
diff --git a/chrome/browser/vr/webxr_vr_input_browser_test.cc b/chrome/browser/vr/webxr_vr_input_browser_test.cc index 77180be1..48d290b 100644 --- a/chrome/browser/vr/webxr_vr_input_browser_test.cc +++ b/chrome/browser/vr/webxr_vr_input_browser_test.cc
@@ -128,16 +128,13 @@ UpdateControllerAndWait(index, controller_data); } - unsigned int CreateAndConnectMinimalGamepad( - device::XrAxisType primary_axis_type) { - // Create a controller that only supports select and one TrackPad, i.e. it - // has just enough data to be considered a gamepad. + unsigned int CreateAndConnectMinimalGamepad() { + // Create a controller that only supports select via a trigger, i.e. it has + // just enough data to be considered a gamepad. uint64_t supported_buttons = - device::XrButtonMaskFromId(device::XrButtonId::kAxisTrigger) | - device::XrButtonMaskFromId(device::XrButtonId::kAxisPrimary); + device::XrButtonMaskFromId(device::XrButtonId::kAxisTrigger); std::map<device::XrButtonId, unsigned int> axis_types = { - {device::XrButtonId::kAxisPrimary, primary_axis_type}, {device::XrButtonId::kAxisTrigger, device::XrAxisType::kTrigger}, }; @@ -188,8 +185,10 @@ } private: + // kAxisTrackpad is the first entry in XrButtonId that maps to an axis and the + // subsequent entries are also for input axes. device::XrButtonId GetAxisId(unsigned int offset) { - return static_cast<device::XrButtonId>(device::XrButtonId::kAxisPrimary + + return static_cast<device::XrButtonId>(device::XrButtonId::kAxisTrackpad + offset); } @@ -222,8 +221,7 @@ WebXrVrBrowserTestBase, TestInputHandednessChange) { WebXrControllerInputMock my_mock; - unsigned int controller_index = - my_mock.CreateAndConnectMinimalGamepad(t->GetPrimaryAxisType()); + unsigned int controller_index = my_mock.CreateAndConnectMinimalGamepad(); t->LoadUrlAndAwaitInitialization( t->GetFileUrlForHtmlTestFile("test_webxr_input_same_object")); @@ -273,11 +271,11 @@ // TODO(crbug.com/963676): Figure out if the race is a product or test bug. // There's a potential for a race causing the input sources change event to // fire multiple times if we disconnect a controller that has a gamepad. + // Even just a select trigger is sufficient to have an xr-standard mapping, so + // just expose a grip trigger instead so that we don't connect a gamepad. uint64_t insufficient_buttons = - device::XrButtonMaskFromId(device::XrButtonId::kAxisTrigger); - std::map<device::XrButtonId, unsigned int> insufficient_axis_types = { - {device::XrButtonId::kAxisTrigger, device::XrAxisType::kTrigger}, - }; + device::XrButtonMaskFromId(device::XrButtonId::kGrip); + std::map<device::XrButtonId, unsigned int> insufficient_axis_types = {}; unsigned int controller_index = my_mock.CreateAndConnectController( device::ControllerRole::kControllerRoleRight, insufficient_axis_types, insufficient_buttons); @@ -311,8 +309,7 @@ // it is both added and removed. // Since we're changing the controller state without disconnecting it, we can // (and should) use the minimal gamepad here. - controller_index = - my_mock.CreateAndConnectMinimalGamepad(t->GetPrimaryAxisType()); + controller_index = my_mock.CreateAndConnectMinimalGamepad(); t->PollJavaScriptBooleanOrFail("inputChangeEvents === 3", WebXrVrBrowserTestBase::kPollTimeoutShort); t->RunJavaScriptOrFail("updateCachedInputSource(0)"); @@ -346,21 +343,19 @@ // Create a set of buttons and axes that don't have enough data to be made // into an xr-standard gamepad (which we expect the runtimes to not report). - // Note that we need to set the trigger axis because of how OpenVR handles - // selects. + // Even just setting the select trigger is now enough to create an xr-standard + // gamepad, so we only set the grip trigger in this case. uint64_t insufficient_buttons = - device::XrButtonMaskFromId(device::XrButtonId::kAxisTrigger); - std::map<device::XrButtonId, unsigned int> insufficient_axis_types = { - {device::XrButtonId::kAxisTrigger, device::XrAxisType::kTrigger}, - }; + device::XrButtonMaskFromId(device::XrButtonId::kGrip); + std::map<device::XrButtonId, unsigned int> insufficient_axis_types = {}; // Create a set of buttons and axes that we expect to have enough data to be // made into an xr-standard gamepad (which we expect the runtimes to report). uint64_t sufficient_buttons = device::XrButtonMaskFromId(device::XrButtonId::kAxisTrigger) | - device::XrButtonMaskFromId(device::XrButtonId::kAxisPrimary); + device::XrButtonMaskFromId(device::XrButtonId::kAxisTrackpad); std::map<device::XrButtonId, unsigned int> sufficient_axis_types = { - {device::XrButtonId::kAxisPrimary, device::XrAxisType::kTrackpad}, + {device::XrButtonId::kAxisTrackpad, device::XrAxisType::kTrackpad}, {device::XrButtonId::kAxisTrigger, device::XrAxisType::kTrigger}, }; @@ -381,7 +376,7 @@ RunJavaScriptOrFail("updateCachedInputSource(0)"); // Toggle a button and confirm that the controller is still the same. - my_mock.PressReleasePrimaryTrigger(controller_index); + my_mock.ToggleButtons(controller_index, insufficient_buttons); RunJavaScriptOrFail("validateCachedSourcePresence(true)"); RunJavaScriptOrFail("validateCurrentAndCachedGamepadMatch()"); @@ -442,17 +437,16 @@ TestGamepadMinimumData) { WebXrControllerInputMock my_mock; - unsigned int controller_index = - my_mock.CreateAndConnectMinimalGamepad(t->GetPrimaryAxisType()); + unsigned int controller_index = my_mock.CreateAndConnectMinimalGamepad(); t->LoadUrlAndAwaitInitialization( t->GetFileUrlForHtmlTestFile("test_webxr_gamepad_support")); t->EnterSessionWithUserGestureOrFail(); - // We only actually connect the data for the two buttons, but WMR expects + // We only actually connect the data for the one button, but WMR expects // the WMR controller (which has all of the required and optional buttons) // and so adds dummy/placeholder buttons regardless of what data we send up. - std::string button_count = "2"; + std::string button_count = "1"; if (t->GetRuntimeType() == XrBrowserTestBase::RuntimeType::RUNTIME_WMR) button_count = "4"; @@ -462,19 +456,12 @@ // Press the trigger and set the axis to a non-zero amount, so we can ensure // we aren't getting just default gamepad data. my_mock.TogglePrimaryTrigger(controller_index); - my_mock.SetAxes(controller_index, device::XrButtonId::kAxisPrimary, 0.5, - -0.5); - my_mock.ToggleButtonTouches(controller_index, - device::XrButtonId::kAxisPrimary); - // The trigger should be button 0, and the first set of axes should have it's - // value set. + // The trigger should be button 0. t->PollJavaScriptBooleanOrFail("isMappingEqualTo('xr-standard')", WebXrVrBrowserTestBase::kPollTimeoutShort); t->PollJavaScriptBooleanOrFail("isButtonPressedEqualTo(0, true)", WebXrVrBrowserTestBase::kPollTimeoutShort); - t->PollJavaScriptBooleanOrFail("areAxesValuesEqualTo(0, 0.5, -0.5)", - WebXrVrBrowserTestBase::kPollTimeoutShort); t->RunJavaScriptOrFail("done()"); t->EndTest(); } @@ -492,14 +479,14 @@ // Create a controller that supports all reserved buttons. uint64_t supported_buttons = device::XrButtonMaskFromId(device::XrButtonId::kAxisTrigger) | - device::XrButtonMaskFromId(device::XrButtonId::kAxisPrimary) | - device::XrButtonMaskFromId(device::XrButtonId::kAxisSecondary) | + device::XrButtonMaskFromId(device::XrButtonId::kAxisTrackpad) | + device::XrButtonMaskFromId(device::XrButtonId::kAxisThumbstick) | device::XrButtonMaskFromId(device::XrButtonId::kGrip); std::map<device::XrButtonId, unsigned int> axis_types = { - {device::XrButtonId::kAxisPrimary, t->GetPrimaryAxisType()}, + {device::XrButtonId::kAxisTrackpad, device::XrAxisType::kTrackpad}, {device::XrButtonId::kAxisTrigger, device::XrAxisType::kTrigger}, - {device::XrButtonId::kAxisSecondary, t->GetSecondaryAxisType()}, + {device::XrButtonId::kAxisThumbstick, device::XrAxisType::kJoystick}, }; unsigned int controller_index = my_mock.CreateAndConnectController( @@ -512,14 +499,21 @@ // Setup some state on the optional buttons (as TestGamepadMinimumData should // ensure proper state on the required buttons). - // Set a value on the secondary set of axes. - my_mock.SetAxes(controller_index, device::XrButtonId::kAxisSecondary, 0.25, + // Set a value on the touchpad. + my_mock.SetAxes(controller_index, device::XrButtonId::kAxisTrackpad, 0.25, -0.25); - // Set the secondary trackpad/joystick to be touched. + // Set the touchpad to be touched. my_mock.ToggleButtonTouches( controller_index, - device::XrButtonMaskFromId(device::XrButtonId::kAxisSecondary)); + device::XrButtonMaskFromId(device::XrButtonId::kAxisTrackpad)); + + // Also test the thumbstick. + my_mock.SetAxes(controller_index, device::XrButtonId::kAxisThumbstick, 0.67, + -0.67); + my_mock.ToggleButtons( + controller_index, + device::XrButtonMaskFromId(device::XrButtonId::kAxisThumbstick)); // Set the grip button to be pressed. my_mock.ToggleButtons(controller_index, @@ -533,17 +527,27 @@ t->PollJavaScriptBooleanOrFail("isButtonCountEqualTo(4)", WebXrVrBrowserTestBase::kPollTimeoutShort); - // The secondary set of axes should be set appropriately. - t->PollJavaScriptBooleanOrFail("areAxesValuesEqualTo(1, 0.25, -0.25)", + // The touchpad axes should be set appropriately. + t->PollJavaScriptBooleanOrFail("areAxesValuesEqualTo(0, 0.25, -0.25)", WebVrBrowserTestBase::kPollTimeoutShort); - // Button 2 is reserved for the Grip, and should be pressed. - t->PollJavaScriptBooleanOrFail("isButtonPressedEqualTo(2, true)", + // The thumbstick axes should be set appropriately. + t->PollJavaScriptBooleanOrFail("areAxesValuesEqualTo(1, 0.67, -0.67)", WebVrBrowserTestBase::kPollTimeoutShort); - // Button 3 is reserved for the secondary trackpad/joystick and should be - // touched but not pressed. - t->PollJavaScriptBooleanOrFail("isButtonPressedEqualTo(3, false)", + // Button 1 is reserved for the Grip, and should be pressed. + t->PollJavaScriptBooleanOrFail("isButtonPressedEqualTo(1, true)", + WebVrBrowserTestBase::kPollTimeoutShort); + + // Button 2 is reserved for the trackpad and should be touched but not + // pressed. + t->PollJavaScriptBooleanOrFail("isButtonPressedEqualTo(2, false)", + WebVrBrowserTestBase::kPollTimeoutShort); + t->PollJavaScriptBooleanOrFail("isButtonTouchedEqualTo(2, true)", + WebVrBrowserTestBase::kPollTimeoutShort); + + // Button 3 is reserved for the thumbstick and should be touched and pressed. + t->PollJavaScriptBooleanOrFail("isButtonPressedEqualTo(3, true)", WebVrBrowserTestBase::kPollTimeoutShort); t->PollJavaScriptBooleanOrFail("isButtonTouchedEqualTo(3, true)", WebVrBrowserTestBase::kPollTimeoutShort); @@ -565,13 +569,13 @@ // secondary axis. (Though it is a valid axis) uint64_t supported_buttons = device::XrButtonMaskFromId(device::XrButtonId::kAxisTrigger) | - device::XrButtonMaskFromId(device::XrButtonId::kAxisPrimary) | + device::XrButtonMaskFromId(device::XrButtonId::kAxisTrackpad) | device::XrButtonMaskFromId(device::XrButtonId::kGrip); std::map<device::XrButtonId, unsigned int> axis_types = { - {device::XrButtonId::kAxisPrimary, GetPrimaryAxisType()}, + {device::XrButtonId::kAxisTrackpad, device::XrAxisType::kTrackpad}, {device::XrButtonId::kAxisTrigger, device::XrAxisType::kTrigger}, - {device::XrButtonId::kAxisSecondary, GetSecondaryAxisType()}, + {device::XrButtonId::kAxisThumbstick, device::XrAxisType::kJoystick}, }; unsigned int controller_index = my_mock.CreateAndConnectController( @@ -585,7 +589,7 @@ // Setup some state on the optional buttons (as TestGamepadMinimumData should // ensure proper state on the required buttons). // Set a value on the secondary set of axes. - my_mock.SetAxes(controller_index, device::XrButtonId::kAxisSecondary, 0.25, + my_mock.SetAxes(controller_index, device::XrButtonId::kAxisThumbstick, 0.25, -0.25); // Controller should meet the requirements for the 'xr-standard' mapping. PollJavaScriptBooleanOrFail("isMappingEqualTo('xr-standard')", @@ -619,11 +623,11 @@ // extra button to guarantee that the reserved button is held. uint64_t supported_buttons = device::XrButtonMaskFromId(device::XrButtonId::kAxisTrigger) | - device::XrButtonMaskFromId(device::XrButtonId::kAxisPrimary) | + device::XrButtonMaskFromId(device::XrButtonId::kAxisTrackpad) | device::XrButtonMaskFromId(device::XrButtonId::kA); std::map<device::XrButtonId, unsigned int> axis_types = { - {device::XrButtonId::kAxisPrimary, device::XrAxisType::kJoystick}, + {device::XrButtonId::kAxisTrackpad, device::XrAxisType::kTrackpad}, {device::XrButtonId::kAxisTrigger, device::XrAxisType::kTrigger}, }; @@ -639,7 +643,7 @@ // should be ignored. my_mock.ToggleButtons(controller_index, UINT64_MAX); - // Index 2 and 3 are reserved for the grip and secondary joystick. + // Index 1 and 3 are reserved for the grip and joystick. // As our controller doesn't support them, they should be present but not // pressed, and our "extra" button should be index 4 and should be pressed. PollJavaScriptBooleanOrFail("isMappingEqualTo('xr-standard')", @@ -647,9 +651,9 @@ PollJavaScriptBooleanOrFail("isButtonCountEqualTo(5)", kPollTimeoutShort); PollJavaScriptBooleanOrFail("isButtonPressedEqualTo(0, true)", kPollTimeoutShort); - PollJavaScriptBooleanOrFail("isButtonPressedEqualTo(1, true)", + PollJavaScriptBooleanOrFail("isButtonPressedEqualTo(1, false)", kPollTimeoutShort); - PollJavaScriptBooleanOrFail("isButtonPressedEqualTo(2, false)", + PollJavaScriptBooleanOrFail("isButtonPressedEqualTo(2, true)", kPollTimeoutShort); PollJavaScriptBooleanOrFail("isButtonPressedEqualTo(3, false)", kPollTimeoutShort); @@ -672,11 +676,11 @@ // Create a controller that supports the trigger, primary axis, and grip uint64_t supported_buttons = device::XrButtonMaskFromId(device::XrButtonId::kAxisTrigger) | - device::XrButtonMaskFromId(device::XrButtonId::kAxisPrimary) | + device::XrButtonMaskFromId(device::XrButtonId::kAxisTrackpad) | device::XrButtonMaskFromId(device::XrButtonId::kGrip); std::map<device::XrButtonId, unsigned int> axis_types = { - {device::XrButtonId::kAxisPrimary, GetPrimaryAxisType()}, + {device::XrButtonId::kAxisTrackpad, device::XrAxisType::kTrackpad}, {device::XrButtonId::kAxisTrigger, device::XrAxisType::kTrigger}, }; @@ -708,8 +712,7 @@ TestControllerInputRegistered) { WebXrControllerInputMock my_mock; - unsigned int controller_index = - my_mock.CreateAndConnectMinimalGamepad(t->GetPrimaryAxisType()); + unsigned int controller_index = my_mock.CreateAndConnectMinimalGamepad(); // Load the test page and enter presentation. t->LoadUrlAndAwaitInitialization(
diff --git a/chrome/browser/web_applications/components/app_registrar.h b/chrome/browser/web_applications/components/app_registrar.h index 87b1f538..6deeb4b 100644 --- a/chrome/browser/web_applications/components/app_registrar.h +++ b/chrome/browser/web_applications/components/app_registrar.h
@@ -37,14 +37,14 @@ virtual WebAppRegistrar* AsWebAppRegistrar(); virtual extensions::BookmarkAppRegistrar* AsBookmarkAppRegistrar(); + // Returns true if the app with |app_id| is currently installed. + virtual bool IsInstalled(const AppId& app_id) const = 0; + // Returns true if the app with the specified |start_url| is currently fully // locally installed. The provided |start_url| must exactly match the launch // URL for the app; this method does not consult the app scope or match URLs // that fall within the scope. - virtual bool IsInstalled(const GURL& start_url) const = 0; - - // Returns true if the app with |app_id| is currently installed. - virtual bool IsInstalled(const AppId& app_id) const = 0; + virtual bool IsLocallyInstalled(const GURL& start_url) const = 0; // Returns true if the app with |app_id| was previously uninstalled by the // user. For example, if a user uninstalls a default app ('default apps' are
diff --git a/chrome/browser/web_applications/components/policy/web_app_policy_manager.cc b/chrome/browser/web_applications/components/policy/web_app_policy_manager.cc index 7f97d1ad..7b934b0 100644 --- a/chrome/browser/web_applications/components/policy/web_app_policy_manager.cc +++ b/chrome/browser/web_applications/components/policy/web_app_policy_manager.cc
@@ -80,7 +80,7 @@ } void WebAppPolicyManager::Start() { - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {content::BrowserThread::UI, base::TaskPriority::BEST_EFFORT}, base::BindOnce(&WebAppPolicyManager:: InitChangeRegistrarAndRefreshPolicyInstalledApps,
diff --git a/chrome/browser/web_applications/components/web_app_install_utils.cc b/chrome/browser/web_applications/components/web_app_install_utils.cc index 1f81d7bdc..bb6d7b4 100644 --- a/chrome/browser/web_applications/components/web_app_install_utils.cc +++ b/chrome/browser/web_applications/components/web_app_install_utils.cc
@@ -118,19 +118,6 @@ return web_app_info_icon_urls; } -void MergeInstallableDataIcon(const InstallableData& data, - WebApplicationInfo* web_app_info) { - if (data.primary_icon_url.is_valid()) { - WebApplicationInfo::IconInfo primary_icon_info; - const SkBitmap& icon = *data.primary_icon; - primary_icon_info.url = data.primary_icon_url; - primary_icon_info.data = icon; - primary_icon_info.width = icon.width(); - primary_icon_info.height = icon.height(); - web_app_info->icons.push_back(primary_icon_info); - } -} - void FilterSquareIconsFromInfo(const WebApplicationInfo& web_app_info, std::vector<BitmapAndSource>* square_icons) { // Add all existing icons from WebApplicationInfo. @@ -151,15 +138,6 @@ } } -std::vector<BitmapAndSource> FilterSquareIcons( - const IconsMap& icons_map, - const WebApplicationInfo& web_app_info) { - std::vector<BitmapAndSource> square_icons; - FilterSquareIconsFromMap(icons_map, &square_icons); - FilterSquareIconsFromInfo(web_app_info, &square_icons); - return square_icons; -} - void ResizeDownloadedIconsGenerateMissing( std::vector<BitmapAndSource> downloaded_icons, WebApplicationInfo* web_app_info) {
diff --git a/chrome/browser/web_applications/components/web_app_install_utils.h b/chrome/browser/web_applications/components/web_app_install_utils.h index 156a33d..137fbe8f 100644 --- a/chrome/browser/web_applications/components/web_app_install_utils.h +++ b/chrome/browser/web_applications/components/web_app_install_utils.h
@@ -54,11 +54,6 @@ const WebApplicationInfo& web_app_info, const InstallableData* data); -// Merge primary icon from installability check phase: -// Add the primary icon to the final web app creation data. -void MergeInstallableDataIcon(const InstallableData& data, - WebApplicationInfo* web_app_info); - // Get a list of non-empty square icons from |web_app_info|. void FilterSquareIconsFromInfo(const WebApplicationInfo& web_app_info, std::vector<BitmapAndSource>* square_icons); @@ -67,12 +62,6 @@ void FilterSquareIconsFromMap(const IconsMap& icons_map, std::vector<BitmapAndSource>* square_icons); -// Get a list of non-empty square icons from downloaded |icons_map| and -// |web_app_info| (merged together). -std::vector<BitmapAndSource> FilterSquareIcons( - const IconsMap& icons_map, - const WebApplicationInfo& web_app_info); - // Ensure that the necessary-sized icons are available by resizing larger // icons down to smaller sizes, and generating icons for sizes where resizing // is not possible.
diff --git a/chrome/browser/web_applications/components/web_app_shortcut.cc b/chrome/browser/web_applications/components/web_app_shortcut.cc index 0116b963..408fedd 100644 --- a/chrome/browser/web_applications/components/web_app_shortcut.cc +++ b/chrome/browser/web_applications/components/web_app_shortcut.cc
@@ -102,14 +102,14 @@ scoped_refptr<base::TaskRunner> GetShortcutIOTaskRunner() { constexpr base::TaskTraits traits = { - base::MayBlock(), base::TaskPriority::BEST_EFFORT, + base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::BLOCK_SHUTDOWN}; #if defined(OS_WIN) - return base::CreateCOMSTATaskRunnerWithTraits( + return base::CreateCOMSTATaskRunner( traits, base::SingleThreadTaskRunnerThreadMode::SHARED); #else - return base::CreateTaskRunnerWithTraits(traits); + return base::CreateTaskRunner(traits); #endif }
diff --git a/chrome/browser/web_applications/components/web_app_shortcut_mac.mm b/chrome/browser/web_applications/components/web_app_shortcut_mac.mm index 31e6cdc..a29d866 100644 --- a/chrome/browser/web_applications/components/web_app_shortcut_mac.mm +++ b/chrome/browser/web_applications/components/web_app_shortcut_mac.mm
@@ -100,13 +100,12 @@ if (newValue) { base::scoped_nsobject<TerminationObserver> scoped_self( self, base::scoped_policy::RETAIN); - base::PostTaskWithTraits( - FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce( - [](base::scoped_nsobject<TerminationObserver> observer) { - [observer onTerminated]; - }, - scoped_self)); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, + base::BindOnce( + [](base::scoped_nsobject<TerminationObserver> observer) { + [observer onTerminated]; + }, + scoped_self)); } } @@ -415,17 +414,16 @@ NSWorkspaceLaunchDefault | NSWorkspaceLaunchWithoutActivation), base::scoped_policy::RETAIN); if (app) { - base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(&RunAppLaunchCallbacks, app, - std::move(launched_callback), - std::move(terminated_callback))); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, + base::BindOnce(&RunAppLaunchCallbacks, app, + std::move(launched_callback), + std::move(terminated_callback))); return; } } - base::PostTaskWithTraits( - FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(std::move(launched_callback), base::Process())); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, + base::BindOnce(std::move(launched_callback), base::Process())); } base::FilePath GetLocalizableAppShortcutsSubdirName() { @@ -522,9 +520,9 @@ (*result)[id] = ImageRepForGFXImage(image); } - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, - {base::MayBlock(), base::TaskPriority::USER_VISIBLE, + {base::ThreadPool(), base::MayBlock(), base::TaskPriority::USER_VISIBLE, base::TaskShutdownBehavior::BLOCK_SHUTDOWN}, base::BindOnce(std::move(io_task), std::move(result))); } @@ -592,11 +590,10 @@ base::mac::FilePathToNSString(localized.Append(locale + ".strings")); [strings_dict writeToFile:strings_path atomically:YES]; - base::PostTaskWithTraits( - FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce( - &GetImageResourcesOnUIThread, - base::BindOnce(&SetWorkspaceIconOnWorkerThread, apps_directory))); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, + base::BindOnce(&GetImageResourcesOnUIThread, + base::BindOnce(&SetWorkspaceIconOnWorkerThread, + apps_directory))); return true; } @@ -1131,7 +1128,7 @@ ShimTerminatedCallback terminated_callback, std::unique_ptr<web_app::ShortcutInfo> shortcut_info) { if (web_app::AppShimLaunchDisabled()) { - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {content::BrowserThread::UI}, base::BindOnce(std::move(launched_callback), base::Process())); return;
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_registrar.cc b/chrome/browser/web_applications/extensions/bookmark_app_registrar.cc index bfe94f6..e807fdd 100644 --- a/chrome/browser/web_applications/extensions/bookmark_app_registrar.cc +++ b/chrome/browser/web_applications/extensions/bookmark_app_registrar.cc
@@ -38,7 +38,11 @@ return this; } -bool BookmarkAppRegistrar::IsInstalled(const GURL& start_url) const { +bool BookmarkAppRegistrar::IsInstalled(const web_app::AppId& app_id) const { + return GetExtension(app_id) != nullptr; +} + +bool BookmarkAppRegistrar::IsLocallyInstalled(const GURL& start_url) const { ExtensionRegistry* registry = ExtensionRegistry::Get(profile()); const ExtensionSet& extensions = registry->enabled_extensions(); @@ -58,10 +62,6 @@ return false; } -bool BookmarkAppRegistrar::IsInstalled(const web_app::AppId& app_id) const { - return GetExtension(app_id) != nullptr; -} - bool BookmarkAppRegistrar::WasExternalAppUninstalledByUser( const web_app::AppId& app_id) const { return ExtensionPrefs::Get(profile())->IsExternalExtensionUninstalled(app_id);
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_registrar.h b/chrome/browser/web_applications/extensions/bookmark_app_registrar.h index 64b641d6..fd57ebf2 100644 --- a/chrome/browser/web_applications/extensions/bookmark_app_registrar.h +++ b/chrome/browser/web_applications/extensions/bookmark_app_registrar.h
@@ -26,8 +26,8 @@ // AppRegistrar: void Init(base::OnceClosure callback) override; BookmarkAppRegistrar* AsBookmarkAppRegistrar() override; - bool IsInstalled(const GURL& start_url) const override; bool IsInstalled(const web_app::AppId& app_id) const override; + bool IsLocallyInstalled(const GURL& start_url) const override; bool WasExternalAppUninstalledByUser( const web_app::AppId& app_id) const override; base::Optional<web_app::AppId> FindAppWithUrlInScope(
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_registrar_browsertest.cc b/chrome/browser/web_applications/extensions/bookmark_app_registrar_browsertest.cc index 621847e..e52fda8 100644 --- a/chrome/browser/web_applications/extensions/bookmark_app_registrar_browsertest.cc +++ b/chrome/browser/web_applications/extensions/bookmark_app_registrar_browsertest.cc
@@ -31,6 +31,7 @@ // BookmarkAppRegistrar should not consider app.com as having installed PWAs. web_app::AppRegistrar& registrar = web_app::WebAppProviderBase::GetProviderBase(profile())->registrar(); - EXPECT_FALSE(registrar.IsInstalled(GURL("https://app.com/"))); - EXPECT_FALSE(registrar.IsInstalled(GURL("https://app.com/inner_page.html"))); + EXPECT_FALSE(registrar.IsLocallyInstalled(GURL("https://app.com/"))); + EXPECT_FALSE( + registrar.IsLocallyInstalled(GURL("https://app.com/inner_page.html"))); }
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_util.cc b/chrome/browser/web_applications/extensions/bookmark_app_util.cc index c5985bd..0ea5f31 100644 --- a/chrome/browser/web_applications/extensions/bookmark_app_util.cc +++ b/chrome/browser/web_applications/extensions/bookmark_app_util.cc
@@ -16,8 +16,6 @@ #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" #include "extensions/common/extension.h" -#include "extensions/common/url_pattern.h" -#include "extensions/common/url_pattern_set.h" #include "url/gurl.h" namespace extensions { @@ -108,10 +106,4 @@ return num_user_installed; } -bool IsValidBookmarkAppUrl(const GURL& url) { - URLPattern origin_only_pattern(Extension::kValidBookmarkAppSchemes); - origin_only_pattern.SetMatchAllURLs(true); - return url.is_valid() && origin_only_pattern.MatchesURL(url); -} - } // namespace extensions
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_util.h b/chrome/browser/web_applications/extensions/bookmark_app_util.h index fb475aea..2245e0d 100644 --- a/chrome/browser/web_applications/extensions/bookmark_app_util.h +++ b/chrome/browser/web_applications/extensions/bookmark_app_util.h
@@ -48,9 +48,6 @@ // (non default-installed apps). int CountUserInstalledBookmarkApps(content::BrowserContext* browser_context); -// Returns whether the given |url| is a valid user bookmark app url. -bool IsValidBookmarkAppUrl(const GURL& url); - } // namespace extensions #endif // CHROME_BROWSER_WEB_APPLICATIONS_EXTENSIONS_BOOKMARK_APP_UTIL_H_
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_util_unittest.cc b/chrome/browser/web_applications/extensions/bookmark_app_util_unittest.cc index ce2d565..51d53313 100644 --- a/chrome/browser/web_applications/extensions/bookmark_app_util_unittest.cc +++ b/chrome/browser/web_applications/extensions/bookmark_app_util_unittest.cc
@@ -95,24 +95,4 @@ GURL("chrome-extension://nkoccljplnhpfnfiajclkommnmllphnl/html/path"))); } -TEST(BookmarkAppUtil, IsValidBookmarkAppUrl) { - EXPECT_TRUE(IsValidBookmarkAppUrl(GURL("https://chromium.org"))); - EXPECT_TRUE(IsValidBookmarkAppUrl(GURL("https://www.chromium.org"))); - EXPECT_TRUE(IsValidBookmarkAppUrl( - GURL("https://www.chromium.org/path/to/page.html"))); - EXPECT_TRUE(IsValidBookmarkAppUrl(GURL("http://chromium.org"))); - EXPECT_TRUE(IsValidBookmarkAppUrl(GURL("http://www.chromium.org"))); - EXPECT_TRUE( - IsValidBookmarkAppUrl(GURL("http://www.chromium.org/path/to/page.html"))); - EXPECT_TRUE(IsValidBookmarkAppUrl( - GURL("chrome-extension://oafaagfgbdpldilgjjfjocjglfbolmac"))); - - EXPECT_FALSE(IsValidBookmarkAppUrl(GURL("ftp://www.chromium.org"))); - EXPECT_FALSE(IsValidBookmarkAppUrl(GURL("chrome://flags"))); - EXPECT_FALSE(IsValidBookmarkAppUrl(GURL("about:blank"))); - EXPECT_FALSE( - IsValidBookmarkAppUrl(GURL("file://mhjfbmdgcfjbbpaeojofohoefgiehjai"))); - EXPECT_FALSE(IsValidBookmarkAppUrl(GURL("chrome://extensions"))); -} - } // namespace extensions
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 fe9cda0f..2dc4f6b 100644 --- a/chrome/browser/web_applications/extensions/web_app_extension_shortcut.cc +++ b/chrome/browser/web_applications/extensions/web_app_extension_shortcut.cc
@@ -108,9 +108,8 @@ const ShortcutInfo& shortcut_info) { bool shortcut_created = internals::CreatePlatformShortcuts( shortcut_data_path, creation_locations, creation_reason, shortcut_info); - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::UI}, - base::BindOnce(std::move(callback), shortcut_created)); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(std::move(callback), shortcut_created)); } void ScheduleCreatePlatformShortcut(
diff --git a/chrome/browser/web_applications/extensions/web_app_extension_shortcut_mac.mm b/chrome/browser/web_applications/extensions/web_app_extension_shortcut_mac.mm index 5353d94..3e6090e9 100644 --- a/chrome/browser/web_applications/extensions/web_app_extension_shortcut_mac.mm +++ b/chrome/browser/web_applications/extensions/web_app_extension_shortcut_mac.mm
@@ -103,8 +103,9 @@ if (!command_line.HasSwitch(app_mode::kAppShimError)) return false; - base::PostTaskWithTraitsAndReplyWithResult( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, + base::PostTaskAndReplyWithResult( + FROM_HERE, + {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT}, base::BindOnce(&RecordAppShimErrorAndBuildShortcutInfo, command_line.GetSwitchValuePath(app_mode::kAppShimError)), base::BindOnce(&RebuildAppAndLaunch));
diff --git a/chrome/browser/web_applications/external_web_app_manager.cc b/chrome/browser/web_applications/external_web_app_manager.cc index c0059c37..f7a674c 100644 --- a/chrome/browser/web_applications/external_web_app_manager.cc +++ b/chrome/browser/web_applications/external_web_app_manager.cc
@@ -257,14 +257,14 @@ // // 1. Schedule ScanDir to happen on a background thread, so that we don't // block the UI thread. When that's done, - // base::PostTaskWithTraitsAndReplyWithResult will bounce us back to the - // originating thread (the UI thread). + // base::PostTaskAndReplyWithResult will bounce us back to the originating + // thread (the UI thread). // // 2. In |callback|, forward the vector of ExternalInstallOptions on to the // pending_app_manager_, which can only be called on the UI thread. - base::PostTaskWithTraitsAndReplyWithResult( + base::PostTaskAndReplyWithResult( FROM_HERE, - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, + {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, base::BindOnce(&ScanDir, dir, apps::DetermineUserType(profile_)), std::move(callback));
diff --git a/chrome/browser/web_applications/test/test_app_registrar.cc b/chrome/browser/web_applications/test/test_app_registrar.cc index 5745fb1..eb53fbae 100644 --- a/chrome/browser/web_applications/test/test_app_registrar.cc +++ b/chrome/browser/web_applications/test/test_app_registrar.cc
@@ -38,15 +38,15 @@ void TestAppRegistrar::Init(base::OnceClosure callback) {} -bool TestAppRegistrar::IsInstalled(const GURL& start_url) const { - NOTIMPLEMENTED(); - return false; -} - bool TestAppRegistrar::IsInstalled(const AppId& app_id) const { return base::Contains(installed_apps_, app_id); } +bool TestAppRegistrar::IsLocallyInstalled(const GURL& start_url) const { + NOTIMPLEMENTED(); + return false; +} + bool TestAppRegistrar::WasExternalAppUninstalledByUser( const AppId& app_id) const { return base::Contains(user_uninstalled_external_apps_, app_id);
diff --git a/chrome/browser/web_applications/test/test_app_registrar.h b/chrome/browser/web_applications/test/test_app_registrar.h index 07578bd..cd288c16 100644 --- a/chrome/browser/web_applications/test/test_app_registrar.h +++ b/chrome/browser/web_applications/test/test_app_registrar.h
@@ -39,8 +39,8 @@ // AppRegistrar void Init(base::OnceClosure callback) override; - bool IsInstalled(const GURL& start_url) const override; bool IsInstalled(const AppId& app_id) const override; + bool IsLocallyInstalled(const GURL& start_url) const override; bool WasExternalAppUninstalledByUser(const AppId& app_id) const override; std::map<AppId, GURL> GetExternallyInstalledApps( ExternalInstallSource install_source) const override;
diff --git a/chrome/browser/web_applications/test/test_web_app_provider.cc b/chrome/browser/web_applications/test/test_web_app_provider.cc index 6ae1d8f..eda636b 100644 --- a/chrome/browser/web_applications/test/test_web_app_provider.cc +++ b/chrome/browser/web_applications/test/test_web_app_provider.cc
@@ -22,10 +22,6 @@ namespace web_app { -#define CHECK_NOT_STARTED() \ - CHECK(!started_) << "Attempted to set a WebAppProvider subsystem after " \ - "Start() was called."; - // static std::unique_ptr<KeyedService> TestWebAppProvider::BuildDefault( content::BrowserContext* context) { @@ -58,52 +54,57 @@ TestWebAppProvider::~TestWebAppProvider() = default; -void TestWebAppProvider::StartImpl() { - if (run_subsystem_startup_tasks_) - WebAppProvider::StartImpl(); -} - void TestWebAppProvider::SetRegistrar(std::unique_ptr<AppRegistrar> registrar) { - CHECK_NOT_STARTED(); + CheckNotStarted(); registrar_ = std::move(registrar); } void TestWebAppProvider::SetInstallManager( std::unique_ptr<WebAppInstallManager> install_manager) { - CHECK_NOT_STARTED(); + CheckNotStarted(); install_manager_ = std::move(install_manager); } void TestWebAppProvider::SetInstallFinalizer( std::unique_ptr<InstallFinalizer> install_finalizer) { - CHECK_NOT_STARTED(); + CheckNotStarted(); install_finalizer_ = std::move(install_finalizer); } void TestWebAppProvider::SetPendingAppManager( std::unique_ptr<PendingAppManager> pending_app_manager) { - CHECK_NOT_STARTED(); + CheckNotStarted(); pending_app_manager_ = std::move(pending_app_manager); } void TestWebAppProvider::SetWebAppUiManager( std::unique_ptr<WebAppUiManager> ui_manager) { - CHECK_NOT_STARTED(); + CheckNotStarted(); ui_manager_ = std::move(ui_manager); } void TestWebAppProvider::SetSystemWebAppManager( std::unique_ptr<SystemWebAppManager> system_web_app_manager) { - CHECK_NOT_STARTED(); + CheckNotStarted(); system_web_app_manager_ = std::move(system_web_app_manager); } void TestWebAppProvider::SetWebAppPolicyManager( std::unique_ptr<WebAppPolicyManager> web_app_policy_manager) { - CHECK_NOT_STARTED(); + CheckNotStarted(); web_app_policy_manager_ = std::move(web_app_policy_manager); } +void TestWebAppProvider::CheckNotStarted() const { + CHECK(!started_) << "Attempted to set a WebAppProvider subsystem after " + "Start() was called."; +} + +void TestWebAppProvider::StartImpl() { + if (run_subsystem_startup_tasks_) + WebAppProvider::StartImpl(); +} + TestWebAppProviderCreator::TestWebAppProviderCreator( CreateWebAppProviderCallback callback) : callback_(std::move(callback)) {
diff --git a/chrome/browser/web_applications/test/test_web_app_provider.h b/chrome/browser/web_applications/test/test_web_app_provider.h index b73ffd62..f0c7fb0 100644 --- a/chrome/browser/web_applications/test/test_web_app_provider.h +++ b/chrome/browser/web_applications/test/test_web_app_provider.h
@@ -58,6 +58,8 @@ std::unique_ptr<WebAppPolicyManager> web_app_policy_manager); private: + void CheckNotStarted() const; + // WebAppProvider: void StartImpl() override;
diff --git a/chrome/browser/web_applications/web_app_icon_manager.cc b/chrome/browser/web_applications/web_app_icon_manager.cc index 029eac5..e164c99 100644 --- a/chrome/browser/web_applications/web_app_icon_manager.cc +++ b/chrome/browser/web_applications/web_app_icon_manager.cc
@@ -165,7 +165,7 @@ } constexpr base::TaskTraits kTaskTraits = { - base::MayBlock(), base::TaskPriority::BEST_EFFORT, + base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}; } // namespace @@ -184,7 +184,7 @@ WriteDataCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - base::PostTaskWithTraitsAndReplyWithResult( + base::PostTaskAndReplyWithResult( FROM_HERE, kTaskTraits, base::BindOnce(WriteDataBlocking, utils_->Clone(), web_apps_directory_, std::move(app_id), std::move(web_app_info)), @@ -198,7 +198,7 @@ for (const WebApp::IconInfo& icon_info : web_app.icons()) { if (icon_info.size_in_px == icon_size_in_px) { - base::PostTaskWithTraitsAndReplyWithResult( + base::PostTaskAndReplyWithResult( FROM_HERE, kTaskTraits, base::BindOnce(ReadIconBlocking, utils_->Clone(), web_apps_directory_, web_app.app_id(), icon_size_in_px),
diff --git a/chrome/browser/web_applications/web_app_install_task.cc b/chrome/browser/web_applications/web_app_install_task.cc index f7672fc4..53fecee2 100644 --- a/chrome/browser/web_applications/web_app_install_task.cc +++ b/chrome/browser/web_applications/web_app_install_task.cc
@@ -437,8 +437,10 @@ DCHECK(web_app_info); - std::vector<BitmapAndSource> downloaded_icons = - FilterSquareIcons(icons_map, *web_app_info); + std::vector<BitmapAndSource> downloaded_icons; + FilterSquareIconsFromMap(icons_map, &downloaded_icons); + FilterSquareIconsFromInfo(*web_app_info, &downloaded_icons); + ResizeDownloadedIconsGenerateMissing(std::move(downloaded_icons), web_app_info.get());
diff --git a/chrome/browser/web_applications/web_app_provider.cc b/chrome/browser/web_applications/web_app_provider.cc index 7267b7cf..d957a5b10 100644 --- a/chrome/browser/web_applications/web_app_provider.cc +++ b/chrome/browser/web_applications/web_app_provider.cc
@@ -35,10 +35,6 @@ #include "components/pref_registry/pref_registry_syncable.h" #include "content/public/browser/web_contents.h" -#define DCHECK_IS_CONNECTED() \ - DCHECK(connected_) << "Attempted to access Web App subsystem while " \ - "WebAppProvider is not connected." - namespace web_app { // static @@ -81,32 +77,32 @@ } AppRegistrar& WebAppProvider::registrar() { - DCHECK_IS_CONNECTED(); + CheckIsConnected(); return *registrar_; } InstallManager& WebAppProvider::install_manager() { - DCHECK_IS_CONNECTED(); + CheckIsConnected(); return *install_manager_; } PendingAppManager& WebAppProvider::pending_app_manager() { - DCHECK_IS_CONNECTED(); + CheckIsConnected(); return *pending_app_manager_; } WebAppPolicyManager* WebAppProvider::policy_manager() { - DCHECK_IS_CONNECTED(); + CheckIsConnected(); return web_app_policy_manager_.get(); } WebAppUiManager& WebAppProvider::ui_manager() { - DCHECK_IS_CONNECTED(); + CheckIsConnected(); return *ui_manager_; } SystemWebAppManager& WebAppProvider::system_web_app_manager() { - DCHECK_IS_CONNECTED(); + CheckIsConnected(); return *system_web_app_manager_; } @@ -182,6 +178,11 @@ on_registry_ready_.Signal(); } +void WebAppProvider::CheckIsConnected() const { + DCHECK(connected_) << "Attempted to access Web App subsystem while " + "WebAppProvider is not connected."; +} + // static void WebAppProvider::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) {
diff --git a/chrome/browser/web_applications/web_app_provider.h b/chrome/browser/web_applications/web_app_provider.h index 5d1ef3c..a24e981 100644 --- a/chrome/browser/web_applications/web_app_provider.h +++ b/chrome/browser/web_applications/web_app_provider.h
@@ -109,6 +109,8 @@ void StartRegistry(); void OnRegistryReady(); + void CheckIsConnected() const; + // New extension-independent subsystems: std::unique_ptr<WebAppAudioFocusIdMap> audio_focus_id_map_; std::unique_ptr<WebAppDatabaseFactory> database_factory_;
diff --git a/chrome/browser/web_applications/web_app_registrar.cc b/chrome/browser/web_applications/web_app_registrar.cc index c9eae7e..2cdd1156 100644 --- a/chrome/browser/web_applications/web_app_registrar.cc +++ b/chrome/browser/web_applications/web_app_registrar.cc
@@ -79,15 +79,15 @@ return this; } -bool WebAppRegistrar::IsInstalled(const GURL& start_url) const { - NOTIMPLEMENTED(); - return false; -} - bool WebAppRegistrar::IsInstalled(const AppId& app_id) const { return GetAppById(app_id) != nullptr; } +bool WebAppRegistrar::IsLocallyInstalled(const GURL& start_url) const { + NOTIMPLEMENTED(); + return false; +} + bool WebAppRegistrar::WasExternalAppUninstalledByUser( const AppId& app_id) const { NOTIMPLEMENTED();
diff --git a/chrome/browser/web_applications/web_app_registrar.h b/chrome/browser/web_applications/web_app_registrar.h index a48c730..8a34314 100644 --- a/chrome/browser/web_applications/web_app_registrar.h +++ b/chrome/browser/web_applications/web_app_registrar.h
@@ -38,8 +38,8 @@ // AppRegistrar: void Init(base::OnceClosure callback) override; WebAppRegistrar* AsWebAppRegistrar() override; - bool IsInstalled(const GURL& start_url) const override; bool IsInstalled(const AppId& app_id) const override; + bool IsLocallyInstalled(const GURL& start_url) const override; bool WasExternalAppUninstalledByUser(const AppId& app_id) const override; base::Optional<AppId> FindAppWithUrlInScope(const GURL& url) const override; int CountUserInstalledApps() const override;
diff --git a/chrome/browser/web_launch/web_launch_files_helper.cc b/chrome/browser/web_launch/web_launch_files_helper.cc index 118839e7..f9d9a9c 100644 --- a/chrome/browser/web_launch/web_launch_files_helper.cc +++ b/chrome/browser/web_launch/web_launch_files_helper.cc
@@ -92,7 +92,7 @@ web_contents->GetMainFrame()->GetProcess()->GetID(), web_contents->GetMainFrame()->GetRoutingID()); - base::PostTaskWithTraitsAndReplyWithResult( + base::PostTaskAndReplyWithResult( FROM_HERE, {content::BrowserThread::IO}, base::BindOnce(&GetEntries, std::move(entry_factory), std::move(context), std::move(launch_paths)),
diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc index 1e9bc3b9..10c1982 100644 --- a/chrome/common/chrome_content_client.cc +++ b/chrome/common/chrome_content_client.cc
@@ -672,10 +672,6 @@ resource_id); } -bool ChromeContentClient::IsDataResourceGzipped(int resource_id) { - return ui::ResourceBundle::GetSharedInstance().IsGzipped(resource_id); -} - gfx::Image& ChromeContentClient::GetNativeImageNamed(int resource_id) { return ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed( resource_id);
diff --git a/chrome/common/chrome_content_client.h b/chrome/common/chrome_content_client.h index c5a25907..ff03027 100644 --- a/chrome/common/chrome_content_client.h +++ b/chrome/common/chrome_content_client.h
@@ -89,7 +89,6 @@ base::StringPiece GetDataResource(int resource_id, ui::ScaleFactor scale_factor) override; base::RefCountedMemory* GetDataResourceBytes(int resource_id) override; - bool IsDataResourceGzipped(int resource_id) override; gfx::Image& GetNativeImageNamed(int resource_id) override; base::DictionaryValue GetNetLogConstants() override; std::string GetProcessTypeNameInEnglish(int type) override;
diff --git a/chrome/common/extensions/docs/templates/intros/declarativeNetRequest.html b/chrome/common/extensions/docs/templates/intros/declarativeNetRequest.html index 78720ad..466ef84 100644 --- a/chrome/common/extensions/docs/templates/intros/declarativeNetRequest.html +++ b/chrome/common/extensions/docs/templates/intros/declarativeNetRequest.html
@@ -292,7 +292,7 @@ "declarative_net_request" : { "rule_resources" : ["rules.json"] }, - "permissions" : ["*://google.com/*", "declarativeNetRequest"], + "permissions" : ["*://*.google.com/*", "*://*.abcd.com/*", "*://*.example.com/*", "declarativeNetRequest"], "manifest_version" : 2 } </pre> @@ -313,14 +313,25 @@ { "id" : 3, "priority" : 1, - "action" : { "type" : "redirect", "redirectUrl" : "https://example.com" }, + "action" : { "type" : "redirect", "redirect" : { "url" : "https://example.com" } }, "condition" : { "urlFilter" : "google.com", "resourceTypes" : ["main_frame"] } }, { "id" : 4, "priority" : 1, - "action" : { "type" : "redirect", "redirectUrl" : "/a.jpg" }, + "action" : { "type" : "redirect", "redirect" : { "extensionPath" : "/a.jpg" } }, "condition" : { "urlFilter" : "abcd.com", "resourceTypes" : ["main_frame"] } + }, + { + "id" : 5, + "priority" : 1, + "action" : { + "type" : "redirect", + "redirect" : { + "transform" : { "scheme" : "https", "host" : "new.example.com" } + } + }, + "condition" : { "urlFilter" : "||example.com", "resourceTypes" : ["main_frame"] } } ] </pre> @@ -339,7 +350,12 @@ </li> <li> Consider a navigation to <code>"http://abcd.com"</code>. The rule with id - (4) matches. Since rule (4) specifies a relative URL, the request is + (4) matches. Since rule (4) specifies an extension path, the request is redirected to <code>"chrome-extension://<extension-id>/a.jpg"</code>. </li> + <li> + Consider a navigation to <code>"http://example.com/path"</code>. The rule + with id (5) matches. Since rule (5) specifies a url transform, the request + is redirected to <code>"https://new.example.com/path"</code>. + </li> </ul>
diff --git a/chrome/common/extensions/permissions/permission_set_unittest.cc b/chrome/common/extensions/permissions/permission_set_unittest.cc index baf8d3f..fe26ddd 100644 --- a/chrome/common/extensions/permissions/permission_set_unittest.cc +++ b/chrome/common/extensions/permissions/permission_set_unittest.cc
@@ -766,7 +766,6 @@ skip.insert(APIPermission::kDns); skip.insert(APIPermission::kDownloadsShelf); skip.insert(APIPermission::kEmbeddedExtensionOptions); - skip.insert(APIPermission::kExtensionView); skip.insert(APIPermission::kFontSettings); skip.insert(APIPermission::kFullscreen); skip.insert(APIPermission::kGcm);
diff --git a/chrome/common/instant_mojom_traits.h b/chrome/common/instant_mojom_traits.h index 00f590c0..90e8704 100644 --- a/chrome/common/instant_mojom_traits.h +++ b/chrome/common/instant_mojom_traits.h
@@ -83,4 +83,5 @@ IPC_STRUCT_TRAITS_MEMBER(color_id) IPC_STRUCT_TRAITS_MEMBER(color_dark) IPC_STRUCT_TRAITS_MEMBER(color_light) + IPC_STRUCT_TRAITS_MEMBER(color_picked) IPC_STRUCT_TRAITS_END()
diff --git a/chrome/common/search/instant_types.cc b/chrome/common/search/instant_types.cc index 4f2bab3b..b90c303 100644 --- a/chrome/common/search/instant_types.cc +++ b/chrome/common/search/instant_types.cc
@@ -29,7 +29,8 @@ logo_alternate == rhs.logo_alternate && has_theme_image == rhs.has_theme_image && theme_name == rhs.theme_name && color_id == rhs.color_id && - color_dark == rhs.color_dark && color_light == rhs.color_light; + color_dark == rhs.color_dark && color_light == rhs.color_light && + color_picked == rhs.color_picked; } InstantMostVisitedItem::InstantMostVisitedItem()
diff --git a/chrome/common/search/instant_types.h b/chrome/common/search/instant_types.h index b3bf32b..ec40c4f 100644 --- a/chrome/common/search/instant_types.h +++ b/chrome/common/search/instant_types.h
@@ -115,13 +115,17 @@ // The color id for Chrome Colors. It is -1 if Chrome Colors is not set, 0 // when Chrome Colors is set but not from predefined color list, and > 0 if // Chrome Colors is set from predefined color list. - int color_id = 0; + int color_id = -1; // The dark color for Chrome Colors. Valid only if Chrome Colors is set. SkColor color_dark = gfx::kPlaceholderColor; // The light color for Chrome Colors. Valid only if Chrome Colors is set. SkColor color_light = gfx::kPlaceholderColor; + + // The picked custom color for Chrome Colors. Valid only if Chrome Colors is + // set. + SkColor color_picked = gfx::kPlaceholderColor; }; struct InstantMostVisitedItem {
diff --git a/chrome/renderer/searchbox/searchbox_extension.cc b/chrome/renderer/searchbox/searchbox_extension.cc index bbe2252e..41562bc0 100644 --- a/chrome/renderer/searchbox/searchbox_extension.cc +++ b/chrome/renderer/searchbox/searchbox_extension.cc
@@ -445,6 +445,8 @@ if (theme_info.color_id != -1) { builder.Set("colorDark", SkColorToArray(isolate, theme_info.color_dark)); builder.Set("colorLight", SkColorToArray(isolate, theme_info.color_light)); + builder.Set("colorPicked", + SkColorToArray(isolate, theme_info.color_picked)); } return builder.Build();
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index d3e2c53..90c9b00 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -772,7 +772,6 @@ "../browser/apps/app_shim/test/app_shim_host_manager_test_api_mac.cc", "../browser/apps/app_shim/test/app_shim_host_manager_test_api_mac.h", "../browser/apps/guest_view/app_view_browsertest.cc", - "../browser/apps/guest_view/extension_view/extension_view_browsertest.cc", "../browser/apps/guest_view/web_view_browsertest.cc", "../browser/apps/platform_apps/app_browsertest.cc", "../browser/apps/platform_apps/app_speech_recognition_browsertest.cc", @@ -994,6 +993,7 @@ "../browser/pdf/pdf_extension_test.cc", "../browser/pdf/pdf_extension_test_util.cc", "../browser/pdf/pdf_extension_test_util.h", + "../browser/performance_manager/graph/page_node_impl_browsertest.cc", "../browser/permissions/permission_delegation_browsertest.cc", "../browser/permissions/permission_request_manager_browsertest.cc", "../browser/permissions/permissions_browsertest.cc",
diff --git a/chrome/test/data/android/spatnav.html b/chrome/test/data/android/spatnav.html index ed1ea5f1..ef2bd80 100644 --- a/chrome/test/data/android/spatnav.html +++ b/chrome/test/data/android/spatnav.html
@@ -10,7 +10,12 @@ <a id="a" href="https://google.com">link</a> <form action="" method="get" class="form-example"> <input type="text" name="name" id="name"></input> - <input type="text" name="location" id="location"></input> + <select name="season"> + <option value="1">Spring</option> + <option value="2">Summer</option> + <option value="3">Fall</option> + <option value="4">Winter</option> + </select> <input type="submit" value="submit"></input> </form> </body>
diff --git a/chrome/test/data/extensions/platform_apps/extension_view/creation/main.html b/chrome/test/data/extensions/platform_apps/extension_view/creation/main.html deleted file mode 100644 index 6ee1733..0000000 --- a/chrome/test/data/extensions/platform_apps/extension_view/creation/main.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!doctype html> -<!-- - * 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. ---> -<html> -<body> - <div id="object-container"></div> - <script src="main.js"></script> -</body> -</html>
diff --git a/chrome/test/data/extensions/platform_apps/extension_view/creation/main.js b/chrome/test/data/extensions/platform_apps/extension_view/creation/main.js deleted file mode 100644 index 1f915f9..0000000 --- a/chrome/test/data/extensions/platform_apps/extension_view/creation/main.js +++ /dev/null
@@ -1,69 +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. - -var LOG = function(msg) { - window.console.log(msg); -}; - -var embedder = {}; -embedder.setUp_ = function(config) { - if (!config || !config.testServer) - return; -}; - -window.runTest = function(testName, appToEmbed) { - if (!embedder.test.testList[testName]) { - LOG('Incorrect testName: ' + testName); - embedder.test.fail(); - return; - } - - // Run the test. - embedder.test.testList[testName](appToEmbed); -}; - -embedder.test = {}; -embedder.test.succeed = function() { - chrome.test.sendMessage('TEST_PASSED'); -}; - -embedder.test.fail = function() { - chrome.test.sendMessage('TEST_FAILED'); -}; - -embedder.test.assertFalse = function(condition) { - if (condition) { - LOG('Assertion failed: false != ' + condition); - embedder.test.fail(); - } -}; - -// Tests begin. -function testExtensionViewCreationShouldSucceed(appToEmbed) { - // Checking that there are no instances of <extensionview>. - embedder.test.assertFalse(document.querySelector('extensionview')); - var extensionview = new ExtensionView(); - - // Appending new <extensionview> to DOM. - document.body.appendChild(extensionview); - - // Checking that <extensionview> exists. - if (document.querySelector('extensionview')) { - embedder.test.succeed(); - return; - } - embedder.test.fail(); -}; - -embedder.test.testList = { - 'testExtensionViewCreationShouldSucceed': - testExtensionViewCreationShouldSucceed, -}; - -onload = function() { - chrome.test.getConfig(function(config) { - embedder.setUp_(config); - chrome.test.sendMessage('Launched'); - }); -};
diff --git a/chrome/test/data/extensions/platform_apps/extension_view/creation/manifest.json b/chrome/test/data/extensions/platform_apps/extension_view/creation/manifest.json deleted file mode 100644 index 058baa5f..0000000 --- a/chrome/test/data/extensions/platform_apps/extension_view/creation/manifest.json +++ /dev/null
@@ -1,13 +0,0 @@ -{ - "name": "Platform App Test: <extensionview>", - "manifest_version": 2, - // gdloliindgbiccapnoiglhjmghmdaofi - "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArNspoDDn0ez3ogchmKtGS7euFSoIDfZ/8yX2IDROLGbvUmosnP6dr2jhTjhTGXLF5rVgQRysRGDamiNznWV4Kz2CZWiSGbDG5/u2EBOtXLYSISIjCZAzuvi1/yUBBKGgURaiRJ3iWQfndRM+zuMEHrqUGriM2bbLv9/XvxoB+l76dCIAvob3y6EMmMiP8EB3qxpZKkPhhtXDLFKqt8LSfWc2YRTrXKEHcN/VY/GxlbVKYKXl4lsDXNPYQbUWo7mfgMlYaycFD2dRw2iRMZU9RS7B8Eo2FRDtXjEWCv1JKvbF8ShCw7j5Gkkg8PQ7nftymenoM1+gdeAbpUGCS1pi3QIDAQAB", - "version": "1", - "permissions": ["extensionview"], - "app": { - "background": { - "scripts": ["test.js"] - } - } -}
diff --git a/chrome/test/data/extensions/platform_apps/extension_view/creation/test.js b/chrome/test/data/extensions/platform_apps/extension_view/creation/test.js deleted file mode 100644 index d01f8765..0000000 --- a/chrome/test/data/extensions/platform_apps/extension_view/creation/test.js +++ /dev/null
@@ -1,7 +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. - -chrome.app.runtime.onLaunched.addListener(function() { - chrome.app.window.create('main.html', {}, function () {}); -});
diff --git a/chrome/test/data/extensions/platform_apps/extension_view/extension_attribute/main.html b/chrome/test/data/extensions/platform_apps/extension_view/extension_attribute/main.html deleted file mode 100644 index dbded87..0000000 --- a/chrome/test/data/extensions/platform_apps/extension_view/extension_attribute/main.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!doctype html> -<!-- - * 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. ---> -<html> -<body> - <extensionview></extensionview> - <script src="main.js"></script> -</body> -</html> \ No newline at end of file
diff --git a/chrome/test/data/extensions/platform_apps/extension_view/extension_attribute/main.js b/chrome/test/data/extensions/platform_apps/extension_view/extension_attribute/main.js deleted file mode 100644 index 73a4ab17..0000000 --- a/chrome/test/data/extensions/platform_apps/extension_view/extension_attribute/main.js +++ /dev/null
@@ -1,78 +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. - -var LOG = function(msg) { - window.console.log(msg); -}; - -var embedder = {}; -embedder.setUp_ = function(config) { - if (!config || !config.testServer) - return;0 -}; - -window.runTest = function(testName, appToEmbed) { - if (!embedder.test.testList[testName]) { - LOG('Incorrect testName: ' + testName); - embedder.test.fail(); - return; - } - - // Run the test. - embedder.test.testList[testName](appToEmbed); -}; - -embedder.test = {}; -embedder.test.succeed = function() { - chrome.test.sendMessage('TEST_PASSED'); -}; - -embedder.test.fail = function() { - chrome.test.sendMessage('TEST_FAILED'); -}; - -embedder.test.assertEq = function(a, b) { - if (a != b) { - LOG('assertion failed: ' + a + ' != ' + b); - embedder.test.fail(); - } -}; - -var checkExtensionAttribute = function(element, expectedValue) { - embedder.test.assertEq(expectedValue, element.extension); -}; - -// Tests begin. -function testExtensionAttribute(extensionId) { - var secondExtensionId = 'secondExtensionId'; - var src = 'data:text/html,<body>One</body>'; - var fullUrl = 'chrome-extension://' + extensionId + '/' + src; - - var extensionview = document.querySelector('extensionview'); - // Load a URL to <extensionview>. - extensionview.load(fullUrl) - .then(function onLoadResolved() { - // Check that the extension attribute has been set. - checkExtensionAttribute(extensionview, extensionId); - - // Set the extension attribute using setAttribute. - extensionview.setAttribute('extension', secondExtensionId); - // Check that the extension attribute was not updated. - checkExtensionAttribute(extensionview, extensionId); - embedder.test.succeed(); - }, function onLoadRejected() { - embedder.test.fail(); - }); -}; - -embedder.test.testList = { - 'testExtensionAttribute': testExtensionAttribute, -}; - -onload = function() { - chrome.test.getConfig(function(config) { - embedder.setUp_(config); - chrome.test.sendMessage('Launched'); - }); -};
diff --git a/chrome/test/data/extensions/platform_apps/extension_view/extension_attribute/manifest.json b/chrome/test/data/extensions/platform_apps/extension_view/extension_attribute/manifest.json deleted file mode 100644 index 915d2b4..0000000 --- a/chrome/test/data/extensions/platform_apps/extension_view/extension_attribute/manifest.json +++ /dev/null
@@ -1,13 +0,0 @@ -{ - "name": "Platform App Test: <extensionview> extension", - "manifest_version": 2, - // gdloliindgbiccapnoiglhjmghmdaofi - "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArNspoDDn0ez3ogchmKtGS7euFSoIDfZ/8yX2IDROLGbvUmosnP6dr2jhTjhTGXLF5rVgQRysRGDamiNznWV4Kz2CZWiSGbDG5/u2EBOtXLYSISIjCZAzuvi1/yUBBKGgURaiRJ3iWQfndRM+zuMEHrqUGriM2bbLv9/XvxoB+l76dCIAvob3y6EMmMiP8EB3qxpZKkPhhtXDLFKqt8LSfWc2YRTrXKEHcN/VY/GxlbVKYKXl4lsDXNPYQbUWo7mfgMlYaycFD2dRw2iRMZU9RS7B8Eo2FRDtXjEWCv1JKvbF8ShCw7j5Gkkg8PQ7nftymenoM1+gdeAbpUGCS1pi3QIDAQAB", - "version": "1", - "permissions": ["extensionview"], - "app": { - "background": { - "scripts": ["test.js"] - } - } -} \ No newline at end of file
diff --git a/chrome/test/data/extensions/platform_apps/extension_view/extension_attribute/test.js b/chrome/test/data/extensions/platform_apps/extension_view/extension_attribute/test.js deleted file mode 100644 index a7480c0..0000000 --- a/chrome/test/data/extensions/platform_apps/extension_view/extension_attribute/test.js +++ /dev/null
@@ -1,7 +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. - -chrome.app.runtime.onLaunched.addListener(function() { - chrome.app.window.create('main.html', {}, function () {}); -}); \ No newline at end of file
diff --git a/chrome/test/data/extensions/platform_apps/extension_view/load_api/main.html b/chrome/test/data/extensions/platform_apps/extension_view/load_api/main.html deleted file mode 100644 index dbded87..0000000 --- a/chrome/test/data/extensions/platform_apps/extension_view/load_api/main.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!doctype html> -<!-- - * 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. ---> -<html> -<body> - <extensionview></extensionview> - <script src="main.js"></script> -</body> -</html> \ No newline at end of file
diff --git a/chrome/test/data/extensions/platform_apps/extension_view/load_api/main.js b/chrome/test/data/extensions/platform_apps/extension_view/load_api/main.js deleted file mode 100644 index 33e5565..0000000 --- a/chrome/test/data/extensions/platform_apps/extension_view/load_api/main.js +++ /dev/null
@@ -1,248 +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. - -var LOG = function(msg) { - window.console.log(msg); -}; - -var embedder = {}; -embedder.setUp_ = function(config) { - if (!config || !config.testServer) - return; -}; - -window.runTest = function(testName, appToEmbed, secondAppToEmbed) { - if (!embedder.test.testList[testName]) { - LOG('Incorrect testName: ' + testName); - embedder.test.fail(); - return; - } - - // Run the test. - embedder.test.testList[testName](appToEmbed, secondAppToEmbed); -}; - -embedder.test = {}; -embedder.test.succeed = function() { - chrome.test.sendMessage('TEST_PASSED'); -}; - -embedder.test.fail = function() { - chrome.test.sendMessage('TEST_FAILED'); -}; - -embedder.test.assertEq = function(a, b) { - if (a != b) { - LOG('assertion failed: ' + a + ' != ' + b); - embedder.test.fail(); - } -}; - -var checkExtensionAttribute = function(element, expectedValue) { - embedder.test.assertEq(expectedValue, element.extension); -}; - -var checkSrcAttribute = function(element, expectedValue) { - embedder.test.assertEq(expectedValue, element.src); -}; - -var extensionScheme = 'chrome-extension://'; -var srcOne = 'data:text/html,<body>One</body>'; -var srcTwo = 'data:text/html,<body>Two</body>'; - -// Tests begin. - -// Call load with a specified extension ID and src. -function testLoadAPIFunction(extensionId) { - var extensionview = document.querySelector('extensionview'); - - extensionview.load(extensionScheme + extensionId + '/' + srcOne) - .then(function() { - checkExtensionAttribute(extensionview, extensionId); - checkSrcAttribute( - extensionview, extensionScheme + extensionId + '/' + srcOne); - }) - .then(embedder.test.succeed, embedder.test.fail); -}; - -// Call load with the same extension Id and src. -function testLoadAPISameIdAndSrc(extensionId) { - var extensionview = document.querySelector('extensionview'); - extensionview.load(extensionScheme + extensionId + '/' + srcOne) - .then(function() { - return extensionview.load(extensionScheme + extensionId + '/' + srcOne); - }) - .then(function() { - checkExtensionAttribute(extensionview, extensionId); - checkSrcAttribute( - extensionview, extensionScheme + extensionId + '/' + srcOne); - }) - .then(embedder.test.succeed, embedder.test.fail); -}; - -// Call load with the same extension Id and different src. -function testLoadAPISameIdDifferentSrc(extensionId) { - var extensionview = document.querySelector('extensionview'); - extensionview.load(extensionScheme + extensionId + '/' + srcOne) - .then(function() { - return extensionview.load(extensionScheme + extensionId + '/' + srcTwo); - }) - .then(function() { - checkExtensionAttribute(extensionview, extensionId); - checkSrcAttribute( - extensionview, extensionScheme + extensionId + '/' + srcTwo); - }) - .then(embedder.test.succeed, embedder.test.fail); -}; - -// Call load with a new extension Id and src. -function testLoadAPILoadOtherExtension(extensionIdOne, extensionIdTwo) { - var extensionview = document.querySelector('extensionview'); - extensionview.load(extensionScheme + extensionIdOne + '/' + srcOne) - .then(function() { - return extensionview.load( - extensionScheme + extensionIdTwo + '/' + srcTwo); - }) - .then(function() { - checkExtensionAttribute(extensionview, extensionIdTwo); - checkSrcAttribute( - extensionview, extensionScheme + extensionIdTwo + '/' + srcTwo); - // Try another load of the first extension again to make sure the - // previous load managed to complete without stalling the action queue. - return extensionview.load( - extensionScheme + extensionIdOne + '/' + srcOne); - }) - .then(function() { - checkExtensionAttribute(extensionview, extensionIdOne); - checkSrcAttribute( - extensionview, extensionScheme + extensionIdOne + '/' + srcOne); - }) - .then(embedder.test.succeed, embedder.test.fail); -}; - -// Call load with an invalid extension. -function testLoadAPIInvalidExtension() { - var invalidExtensionId = 'fakeExtension'; - var extensionview = document.querySelector('extensionview'); - extensionview.load(extensionScheme + invalidExtensionId + '/' + srcOne) - .then(embedder.test.fail, embedder.test.succeed); -}; - -// Call load with a valid extension Id and src after an invalid call. -function testLoadAPIAfterInvalidCall(extensionId) { - var invalidExtensionId = 'fakeExtension'; - var extensionview = document.querySelector('extensionview'); - extensionview.load(extensionScheme + invalidExtensionId + '/' + srcOne) - .then( - embedder.test.fail, - function() { - return extensionview.load( - extensionScheme + extensionId + '/' + srcTwo); - }) - .then(embedder.test.succeed, embedder.test.fail); -}; - -// Call load with a null extension. -function testLoadAPINullExtension() { - var extensionview = document.querySelector('extensionview'); - extensionview.load(null).then(embedder.test.fail, embedder.test.succeed); -}; - -function testQueuedLoadAPIFunction(extensionId) { - var extensionview = document.querySelector('extensionview'); - - var loadCallCount = 0; - var load_promises = []; - - // Call load a first time with a specified extension ID and src. - load_promises.push( - extensionview.load(extensionScheme + extensionId + '/' + srcOne) - .then(function() { - loadCallCount++; - embedder.test.assertEq(1, loadCallCount); - })); - - // Call load a second time with the same extension Id and src. - load_promises.push( - extensionview.load(extensionScheme + extensionId + '/' + srcOne) - .then(function() { - loadCallCount++; - embedder.test.assertEq(2, loadCallCount); - })); - - // Call load a third time with the same extension Id and different src. - load_promises.push( - extensionview.load(extensionScheme + extensionId + '/' + srcTwo) - .then(function() { - loadCallCount++; - embedder.test.assertEq(3, loadCallCount); - })); - - Promise.all(load_promises) - .then(function() { - // Ensure we have the expected attributes for the most recent load. - checkExtensionAttribute(extensionview, extensionId); - checkSrcAttribute( - extensionview, extensionScheme + extensionId + '/' + srcTwo); - }) - .then(embedder.test.succeed, embedder.test.fail); -}; - -function testQueuedLoadAPILoadOtherExtension(extensionIdOne, extensionIdTwo) { - var extensionview = document.querySelector('extensionview'); - - var loadCallCount = 0; - var load_promises = []; - - load_promises.push( - extensionview.load(extensionScheme + extensionIdOne + '/' + srcOne) - .then(function() { - loadCallCount++; - embedder.test.assertEq(1, loadCallCount); - })); - - // Enqueue a load to another extension. - load_promises.push( - extensionview.load(extensionScheme + extensionIdTwo + '/' + srcTwo) - .then(function() { - loadCallCount++; - embedder.test.assertEq(2, loadCallCount); - })); - - // Enqueue a load to back to the original extension. - load_promises.push( - extensionview.load(extensionScheme + extensionIdOne + '/' + srcOne) - .then(function() { - loadCallCount++; - embedder.test.assertEq(3, loadCallCount); - })); - - Promise.all(load_promises) - .then(function() { - // Ensure we have the expected attributes for the most recent load. - checkExtensionAttribute(extensionview, extensionIdOne); - checkSrcAttribute( - extensionview, extensionScheme + extensionIdOne + '/' + srcOne); - }) - .then(embedder.test.succeed, embedder.test.fail); -}; - -embedder.test.testList = { - 'testLoadAPIFunction': testLoadAPIFunction, - 'testLoadAPISameIdAndSrc': testLoadAPISameIdAndSrc, - 'testLoadAPISameIdDifferentSrc': testLoadAPISameIdDifferentSrc, - 'testLoadAPILoadOtherExtension': testLoadAPILoadOtherExtension, - 'testLoadAPIInvalidExtension': testLoadAPIInvalidExtension, - 'testLoadAPIAfterInvalidCall': testLoadAPIAfterInvalidCall, - 'testLoadAPINullExtension': testLoadAPINullExtension, - 'testQueuedLoadAPIFunction': testQueuedLoadAPIFunction, - 'testQueuedLoadAPILoadOtherExtension': testQueuedLoadAPILoadOtherExtension, -}; - -onload = function() { - chrome.test.getConfig(function(config) { - embedder.setUp_(config); - chrome.test.sendMessage('Launched'); - }); -};
diff --git a/chrome/test/data/extensions/platform_apps/extension_view/load_api/manifest.json b/chrome/test/data/extensions/platform_apps/extension_view/load_api/manifest.json deleted file mode 100644 index 14f791c..0000000 --- a/chrome/test/data/extensions/platform_apps/extension_view/load_api/manifest.json +++ /dev/null
@@ -1,13 +0,0 @@ -{ - "name": "Platform App Test: <extensionview> load api call", - "manifest_version": 2, - // gdloliindgbiccapnoiglhjmghmdaofi - "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArNspoDDn0ez3ogchmKtGS7euFSoIDfZ/8yX2IDROLGbvUmosnP6dr2jhTjhTGXLF5rVgQRysRGDamiNznWV4Kz2CZWiSGbDG5/u2EBOtXLYSISIjCZAzuvi1/yUBBKGgURaiRJ3iWQfndRM+zuMEHrqUGriM2bbLv9/XvxoB+l76dCIAvob3y6EMmMiP8EB3qxpZKkPhhtXDLFKqt8LSfWc2YRTrXKEHcN/VY/GxlbVKYKXl4lsDXNPYQbUWo7mfgMlYaycFD2dRw2iRMZU9RS7B8Eo2FRDtXjEWCv1JKvbF8ShCw7j5Gkkg8PQ7nftymenoM1+gdeAbpUGCS1pi3QIDAQAB", - "version": "1", - "permissions": ["extensionview"], - "app": { - "background": { - "scripts": ["test.js"] - } - } -}
diff --git a/chrome/test/data/extensions/platform_apps/extension_view/load_api/test.js b/chrome/test/data/extensions/platform_apps/extension_view/load_api/test.js deleted file mode 100644 index a7480c0..0000000 --- a/chrome/test/data/extensions/platform_apps/extension_view/load_api/test.js +++ /dev/null
@@ -1,7 +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. - -chrome.app.runtime.onLaunched.addListener(function() { - chrome.app.window.create('main.html', {}, function () {}); -}); \ No newline at end of file
diff --git a/chrome/test/data/extensions/platform_apps/extension_view/skeleton.crx b/chrome/test/data/extensions/platform_apps/extension_view/skeleton.crx deleted file mode 100644 index ee5070c0..0000000 --- a/chrome/test/data/extensions/platform_apps/extension_view/skeleton.crx +++ /dev/null Binary files differ
diff --git a/chrome/test/data/extensions/platform_apps/extension_view/skeleton.pem b/chrome/test/data/extensions/platform_apps/extension_view/skeleton.pem deleted file mode 100644 index 9a3de96..0000000 --- a/chrome/test/data/extensions/platform_apps/extension_view/skeleton.pem +++ /dev/null
@@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDvX1uz+m8tHS9w -PtFscMv4zZqhYnKvvpSowAXCEs6v1fSDXPdGKzNnpoQ0iH3CndtA53izAIqWwPxm -F5+hfxkRHJ+JrW8fP2cKGoua76lPbHoqJ8GRHfwmbNDwWHHlQfU4piTnX+VarKvE -LQlADhifnzfWCqSdG4JOSO2cQjlC0b+4fZK1iT6ZZNwf7CIEwmnk1k73eHmtQQHh -CRzUPZd1RSfDnVcnLl2L4Vg64TSd3BAARpZyVz2b9DnxXBWc01u9qnhB8XRSfahn -wINnMoB/F0FD1Uvp1SZmytJ8GNR2IW+0uIvpTvPvh/jujU0dOykKOaPcCSim3PSu -CuVBbIfvAgMBAAECggEBALjftTuz19nICLNwUN6n32ExqpOqLVl+n+IVLF1PmUJE -xKwQSQpwoysSeFj6cea1dHkUTSwy5ta4BjfzVt6sAvgsWytCP+iqVzJ+fgQTxXgK -F/Am9GDX/77NnDGEnbKq1nICH85zSfhWE/NXtSU7vdjKZ51wauLMND+yI5Hjs8Xe -KwcQPv1KdBioUWjCp9V1m3fluzSReDDxGgLl7S9QzFSLkjdFIqTWYxiaRgYCFBUB -LaPTKzk4PaQWGs1ALLwEl3cM865VX1Y/vn0k0/GLvz6nGHW5rhDIeKAEgPROD/r2 -Jwt1rNSUJgeUZf0+B1MO8cd7TndALb/cvxleOlrjLkECgYEA+eCqiGt0WryDpEsX -Yv8/EWhzA7eFXUeIvhmfFUnH889g9v+XycRAaWiGH7oJtxqfETy8qWEtlLgHC47r -oxApaUmdqz17GYKUt+27lPM4Fw2xVf8x70yLFAoS1GmMxaRgqKyyyXtttBg1p/g9 -ud18cfj4ORb4xsT7lMTkbjBtDysCgYEA9TzMvPB+FUAmZZZ/75MkLOvky6m7nTbw -kn8w0QM/UksYood0PszaP85mhDSSQAQKhrrLhNtAHyMweWx1aggGOODef8KBNc/f -xWafFZZpmJvkH3rDyvDE0yioxiaKQYMvrB3EVO3QcdUqMNPROzMCI9X+gQ0Xo9/3 -T18b7SCg6E0CgYAx+lGhf3yCOXpK/gnrbwn6PV3jvG0cPxaGjzFWXK91gGDwhiah -4HLRompRJjCTQuvV0sQZTKqFOFmQYkGXF8Bwopy6h017yLZeI1qFbDAnzEFP5f7i -0fhvRaSGf6X8UehTVFdeHSXQA5eXxPrzle0yDo33PTT87KE1HDxkHaNyiQKBgQCu -zWm6e0nD5/f2jXIf2Kf+hR6OtSuQAms0YQjw0vm9tN2YbCjF4srmlD6qmbZtfvPp -2RfcWVO5XiHdSxveOl4FCPRP6Nqk+sksMdvPTWlzaBsQ/Ta2XyxMvzyeETaXP+Up -MAaT6vebTDBIoZMQOWmbFZvVbPmey7PCla6YNZu8OQKBgQDD+Y41atAIPpdSqN4W -S9jKIw7HEPK59pjQNYB8MOSqXRyp83FudwGOrxl41iavqinsExB7buhnGsLVKfLi -/zNqt3EBb2bSIM8IsiMOYUfATstt6MiVPzJyRVtITLbYNxYRGq9MX26tenAXV7qm -2UvMG9E8r9lCSQEcqh7OzLo31Q== ------END PRIVATE KEY-----
diff --git a/chrome/test/data/extensions/platform_apps/extension_view/skeleton/manifest.json b/chrome/test/data/extensions/platform_apps/extension_view/skeleton/manifest.json deleted file mode 100644 index 4d3e077d..0000000 --- a/chrome/test/data/extensions/platform_apps/extension_view/skeleton/manifest.json +++ /dev/null
@@ -1,7 +0,0 @@ -{ - // pemeknaakobkocgmimdeamlcklioagkh - "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA719bs/pvLR0vcD7RbHDL+M2aoWJyr76UqMAFwhLOr9X0g1z3RiszZ6aENIh9wp3bQOd4swCKlsD8ZhefoX8ZERyfia1vHz9nChqLmu+pT2x6KifBkR38JmzQ8Fhx5UH1OKYk51/lWqyrxC0JQA4Yn5831gqknRuCTkjtnEI5QtG/uH2StYk+mWTcH+wiBMJp5NZO93h5rUEB4Qkc1D2XdUUnw51XJy5di+FYOuE0ndwQAEaWclc9m/Q58VwVnNNbvap4QfF0Un2oZ8CDZzKAfxdBQ9VL6dUmZsrSfBjUdiFvtLiL6U7z74f47o1NHTspCjmj3Akoptz0rgrlQWyH7wIDAQAB", - "manifest_version": 2, - "name": "skeleton", - "version": "1.0" -}
diff --git a/chrome/test/data/extensions/platform_apps/extension_view/skeleton_two.crx b/chrome/test/data/extensions/platform_apps/extension_view/skeleton_two.crx deleted file mode 100644 index 73eb8a0..0000000 --- a/chrome/test/data/extensions/platform_apps/extension_view/skeleton_two.crx +++ /dev/null Binary files differ
diff --git a/chrome/test/data/extensions/platform_apps/extension_view/skeleton_two.pem b/chrome/test/data/extensions/platform_apps/extension_view/skeleton_two.pem deleted file mode 100644 index e1f7e6a..0000000 --- a/chrome/test/data/extensions/platform_apps/extension_view/skeleton_two.pem +++ /dev/null
@@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC2G1liqXzycv1y -ERgLrvDIC3ItyDCw927oecGYo7Q0cKLNqDodk+dtO2N+W91bvYp2XwPAjMDg5Q3Z -StxHswAgqeD2WI/zWO0No2dGR+RLGlvHzy1+h+ydl4utzGApBgN1NDB75hafp+9o -lGiSSr9qliLHmLOW41V+Lb8XPoUZJSxYQB4g9IBWCWK4JkPPVIp8hkA8TAX+1oRV -+W7UTjxgWRAFVfDRA1BThQvlLj0d/tjadFm90UTNI4wVQbkAqu892nq8LBsm3eij -Lo8kwP2QjPJ8WjWTDwmTxn4WkiOpNa2SBnBPkkcA6Diy9XMMRVIRr5jZOOBqHS1n -1prD6uRPAgMBAAECggEAJdIaR1Zh/8yH/Ke2Mb78fN97sCxyiF5rJ1caMQRWyclW -1pWItFniZ5o8+KJFn+cGmbzz/4p8CHkp3iYhB7cSYLZHZYJRKz4dxYZZTYxiyoJH -64CIt02tg7FUrhzTH9IC59WV+DV6H2B2ZWblLPTfOljCEmgRbFX8jH8dv8sZQ3ZO -P80ZFcWn6UzBGcI5kdD6CuGpf5hoV1b3iwUi38UQOk8eM6zAmE90ZYsZOE9A508Z -1JyrPIo7KSFIDOaeUGPADKqwlO0r4TgOUR4J6xVssqBtNgtY17WaVaI8JhCXGLq0 -WXyu/2L59CsHe14M++V2a7xarcBSwPhRHYcrhWddcQKBgQDdV28+Xw3yEUxnaSfG -P9GhFKMJQlvJM2J+ZstC0FXqfeDVp/3tlJlef9gDUqgdXdAheRsOugXlNSgrmURZ -u9QA7I2C43hw1OhJJkk87jF1xJbCG/ZI7WCxfn94nrSK2Dd3DDLwgK4iby0xHqH1 -b3R2gdRREicEGuAI2i9/UVx1uQKBgQDSnyznwN77YFroVxNXvH2XdeyS+1T+rPWK -Gb/mmITuTnESO0hli78Tm0xOiBhfnPklyl1z1//3k69xvzeF/r1hh4x6qmGu+i6o -lny6OIdybfSTEt7qA1G7KS9KE0ic/F5lsL8CBE6qsEtfB9Y4fjTRYgZhmXWl5Dyr -xOzPVpcuRwKBgDpR82nHufDyReNpfaVq411CBsNFzNFyzJzpkN0F791dVYR2Qx36 -bX7MyKn3eXxjX5eyRULYGP2PyAnU1IGgT/f+XDsEnJN+RcYgZGO9jyKsrdxvabFF -epjJ7+RkTMXYuqSPfkyIW1mPWaT7oUj+GP2wr7S8x7L5MdajRqiRU39hAoGBAK7x -PZhFsDB1qSyg3tUaH+tFLLos/j0HJm+N0cJUXt2d0/dDvG9z8sLzVB9KlYwdUyib -fKHzAI4AYlKFdDXdECpJL1rX2IlBDq5DSNhYidB3GhVrMDKJjUJ7A+dwOvkB+dpX -Q2AGedz2z7PgS4Pi+DYOSKSalYi0GdzGlbfmAW6TAoGBAJuu0aJ7V4vYaIdZRKXC -Q6t+F6kly73pAVKaeO9bVOZeBROAIUzeoEhnDGQM6D7Ei+7bVr9710OvwexSWh6n -GDqRsW3zxVCOEvWP6/wh9zqznxUJii1QD+fCMSgTMlCVuR89nuXdPANJDGslu3yU -/ywhqyg12KiymsmxqVouzK7Y ------END PRIVATE KEY-----
diff --git a/chrome/test/data/extensions/platform_apps/extension_view/skeleton_two/manifest.json b/chrome/test/data/extensions/platform_apps/extension_view/skeleton_two/manifest.json deleted file mode 100644 index e0b5af53c..0000000 --- a/chrome/test/data/extensions/platform_apps/extension_view/skeleton_two/manifest.json +++ /dev/null
@@ -1,7 +0,0 @@ -{ - // dppcjffonoklmpdmljnpdojmoaefcabf - "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAthtZYql88nL9chEYC67wyAtyLcgwsPdu6HnBmKO0NHCizag6HZPnbTtjflvdW72Kdl8DwIzA4OUN2UrcR7MAIKng9liP81jtDaNnRkfkSxpbx88tfofsnZeLrcxgKQYDdTQwe+YWn6fvaJRokkq/apYix5izluNVfi2/Fz6FGSUsWEAeIPSAVgliuCZDz1SKfIZAPEwF/taEVflu1E48YFkQBVXw0QNQU4UL5S49Hf7Y2nRZvdFEzSOMFUG5AKrvPdp6vCwbJt3ooy6PJMD9kIzyfFo1kw8Jk8Z+FpIjqTWtkgZwT5JHAOg4svVzDEVSEa+Y2Tjgah0tZ9aaw+rkTwIDAQAB", - "manifest_version": 2, - "name": "second skeleton", - "version": "1.0" -}
diff --git a/chrome/test/data/extensions/platform_apps/extension_view/src_attribute/main.html b/chrome/test/data/extensions/platform_apps/extension_view/src_attribute/main.html deleted file mode 100644 index dbded87..0000000 --- a/chrome/test/data/extensions/platform_apps/extension_view/src_attribute/main.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!doctype html> -<!-- - * 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. ---> -<html> -<body> - <extensionview></extensionview> - <script src="main.js"></script> -</body> -</html> \ No newline at end of file
diff --git a/chrome/test/data/extensions/platform_apps/extension_view/src_attribute/main.js b/chrome/test/data/extensions/platform_apps/extension_view/src_attribute/main.js deleted file mode 100644 index 99d481d..0000000 --- a/chrome/test/data/extensions/platform_apps/extension_view/src_attribute/main.js +++ /dev/null
@@ -1,80 +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. - -var LOG = function(msg) { - window.console.log(msg); -}; - -var embedder = {}; -embedder.setUp_ = function(config) { - if (!config || !config.testServer) - return; -}; - -window.runTest = function(testName, appToEmbed) { - if (!embedder.test.testList[testName]) { - LOG('Incorrect testName: ' + testName); - embedder.test.fail(); - return; - } - - // Run the test. - embedder.test.testList[testName](appToEmbed); -}; - -embedder.test = {}; -embedder.test.succeed = function() { - chrome.test.sendMessage('TEST_PASSED'); -}; - -embedder.test.fail = function() { - chrome.test.sendMessage('TEST_FAILED'); -}; - -embedder.test.assertEq = function(a, b) { - if (a != b) { - LOG('assertion failed: ' + a + ' != ' + b); - embedder.test.fail(); - } -}; - -var checkSrcAttribute = function(element, expectedValue) { - embedder.test.assertEq(expectedValue, element.src); -}; - -// Tests begin. -function testSrcAttribute(extensionId) { - var srcOne = 'data:text/html,<body>One</body>'; - var srcTwo = 'data:text/html,<body>Two</body>'; - var fullUrlOne = 'chrome-extension://' + extensionId + '/' + srcOne; - var fullUrlTwo = 'chrome-extension://' + extensionId + '/' + srcTwo; - - var extensionview = document.querySelector('extensionview'); - - // Load a URL to <extensionview>. - extensionview.load(fullUrlOne) - .then(function onLoadResolved() { - // Check that the src attribute has been set. - checkSrcAttribute(extensionview, fullUrlOne); - - // Set the src attribute using setAttribute. - extensionview.setAttribute('src', fullUrlTwo); - // Check that the src attribute was not updated. - checkSrcAttribute(extensionview, fullUrlOne); - embedder.test.succeed(); - }, function onLoadRejected() { - embedder.test.fail(); - }); -}; - -embedder.test.testList = { - 'testSrcAttribute': testSrcAttribute, -}; - -onload = function() { - chrome.test.getConfig(function(config) { - embedder.setUp_(config); - chrome.test.sendMessage('Launched'); - }); -};
diff --git a/chrome/test/data/extensions/platform_apps/extension_view/src_attribute/manifest.json b/chrome/test/data/extensions/platform_apps/extension_view/src_attribute/manifest.json deleted file mode 100644 index 1da99bcd..0000000 --- a/chrome/test/data/extensions/platform_apps/extension_view/src_attribute/manifest.json +++ /dev/null
@@ -1,13 +0,0 @@ -{ - "name": "Platform App Test: <extensionview> src", - "manifest_version": 2, - // gdloliindgbiccapnoiglhjmghmdaofi - "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArNspoDDn0ez3ogchmKtGS7euFSoIDfZ/8yX2IDROLGbvUmosnP6dr2jhTjhTGXLF5rVgQRysRGDamiNznWV4Kz2CZWiSGbDG5/u2EBOtXLYSISIjCZAzuvi1/yUBBKGgURaiRJ3iWQfndRM+zuMEHrqUGriM2bbLv9/XvxoB+l76dCIAvob3y6EMmMiP8EB3qxpZKkPhhtXDLFKqt8LSfWc2YRTrXKEHcN/VY/GxlbVKYKXl4lsDXNPYQbUWo7mfgMlYaycFD2dRw2iRMZU9RS7B8Eo2FRDtXjEWCv1JKvbF8ShCw7j5Gkkg8PQ7nftymenoM1+gdeAbpUGCS1pi3QIDAQAB", - "version": "1", - "permissions": ["extensionview"], - "app": { - "background": { - "scripts": ["test.js"] - } - } -} \ No newline at end of file
diff --git a/chrome/test/data/extensions/platform_apps/extension_view/src_attribute/test.js b/chrome/test/data/extensions/platform_apps/extension_view/src_attribute/test.js deleted file mode 100644 index a7480c0..0000000 --- a/chrome/test/data/extensions/platform_apps/extension_view/src_attribute/test.js +++ /dev/null
@@ -1,7 +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. - -chrome.app.runtime.onLaunched.addListener(function() { - chrome.app.window.create('main.html', {}, function () {}); -}); \ No newline at end of file
diff --git a/chrome/test/data/local_ntp/customize_menu_browsertest.js b/chrome/test/data/local_ntp/customize_menu_browsertest.js index d69bfb1..ece62623 100644 --- a/chrome/test/data/local_ntp/customize_menu_browsertest.js +++ b/chrome/test/data/local_ntp/customize_menu_browsertest.js
@@ -800,6 +800,7 @@ colorId: 0, colorDark: [100, 100, 100], colorLight: [200, 200, 200], + colorPicked: [90, 90, 90], }; init(); $(test.customizeMenu.IDS.EDIT_BG).click();
diff --git a/chrome/test/data/local_ntp/local_ntp_browsertest.html b/chrome/test/data/local_ntp/local_ntp_browsertest.html index c66ccc1..0e3c9292 100644 --- a/chrome/test/data/local_ntp/local_ntp_browsertest.html +++ b/chrome/test/data/local_ntp/local_ntp_browsertest.html
@@ -160,26 +160,6 @@ </dialog> <dialog id="customization-menu" class="customize-dialog"> - <div id="menu-header"> - <div id="menu-back-circle" tabindex="0" role="button" - aria-label="$i18n{backLabel}" title="$i18n{backLabel}"> - <div id="menu-back"></div> - </div> - <div id="menu-title">$i18n{customizeMenu}</div> - <div id="refresh-daily-wrapper"> - <div id="refresh-toggle-wrapper" title="$i18n{refreshDaily}"> - <label class="switch"> - <input id="refresh-daily-toggle" type="checkbox" - aria-labelledby="refresh-text"></input> - <span class="toggle"> - <div class="knob"></div> - <div class="highlight"></div> - </span> - </label> - </div> - <div id="refresh-text">$i18n{refreshDaily}</div> - </div> - </div> <div id="menu-nav-panel" role="tablist" aria-label="$i18n{customizeMenu}"> <button id="backgrounds-button" class="menu-option" tabindex="0" role="tab" aria-controls="backgrounds-menu backgrounds-image-menu" @@ -215,18 +195,40 @@ </button> </div> <div id="menu-contents"> + <div id="menu-header"> + <div id="menu-back-circle" tabindex="0" role="button" + aria-label="$i18n{backLabel}" title="$i18n{backLabel}"> + <div id="menu-back"></div> + </div> + <div id="menu-title">$i18n{customizeMenu}</div> + <div id="refresh-daily-wrapper"> + <div id="refresh-toggle-wrapper" title="$i18n{refreshDaily}"> + <label class="switch"> + <input id="refresh-daily-toggle" type="checkbox" + aria-labelledby="refresh-text"></input> + <span class="toggle"> + <div class="knob"></div> + <div class="highlight"></div> + </span> + </label> + </div> + <div id="refresh-text">$i18n{refreshDaily}</div> + </div> + </div> <div id="backgrounds-menu" class="menu-panel" tabindex="0" role="tabpanel" aria-label="$i18n{backgroundsOption}"> <div id="backgrounds-upload" class="bg-sel-tile-bg"> <div id="backgrounds-upload-icon" class="bg-sel-tile" tabindex="-1" - aria-label="$i18n{uploadImage}" title="$i18n{uploadImage}"> + role="button" aria-label="$i18n{uploadImage}" + title="$i18n{uploadImage}"> <div id="backgrounds-upload-arrow"></div> <div id="backgrounds-upload-text">$i18n{uploadImage}</div> </div> </div> <div id="backgrounds-default" class="bg-sel-tile-bg"> <div id="backgrounds-default-icon" class="bg-sel-tile" tabindex="-1" - aria-label="$i18n{noBackground}" title="$i18n{noBackground}"> + role="button" aria-label="$i18n{noBackground}" + title="$i18n{noBackground}"> <div class="mini-page"> <div class="mini-header-colorful"></div> <div class="mini-shortcuts"></div> @@ -241,7 +243,7 @@ aria-label="$i18n{shortcutsOption}"> <div id="sh-options"> <div class="sh-option"> - <div id="sh-option-cl" class="sh-option-image" tabindex="0" + <div id="sh-option-cl" class="sh-option-image" tabindex="-1" role="button" aria-pressed="false" aria-labelledby="sh-option-cl-title" title="$i18n{myShortcuts}"> @@ -259,7 +261,7 @@ $i18n{shortcutsCurated} </div> <div class="sh-option"> - <div id="sh-option-mv" class="sh-option-image" tabindex="0" + <div id="sh-option-mv" class="sh-option-image" tabindex="-1" role="button" aria-pressed="false" aria-labelledby="sh-option-mv-title" title="$i18n{mostVisited}"> @@ -285,7 +287,7 @@ </div> <div id="sh-hide-toggle-wrapper" title="$i18n{hideShortcuts}"> <label class="switch"> - <input id="sh-hide-toggle" type="checkbox" + <input id="sh-hide-toggle" type="checkbox" tabindex="-1" aria-labelledby="sh-hide-title"></input> <span class="toggle"> <div class="knob"></div> @@ -323,7 +325,8 @@ <div id="colors-default" class="bg-sel-tile-bg" aria-label="$i18n{defaultThemeLabel}" title="$i18n{defaultThemeLabel}"> - <div id="colors-default-icon" class="bg-sel-tile" tabindex="-1"></div> + <div id="colors-default-icon" class="bg-sel-tile" tabindex="-1"> + </div> </div> </div> </div>
diff --git a/chrome/test/data/webui/settings/a11y/crostini_accessibility_test.js b/chrome/test/data/webui/settings/a11y/crostini_accessibility_test.js index 0605a42e..4a47c5e 100644 --- a/chrome/test/data/webui/settings/a11y/crostini_accessibility_test.js +++ b/chrome/test/data/webui/settings/a11y/crostini_accessibility_test.js
@@ -2,7 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -/** @fileoverview Runs the Polymer Accessibility Settings tests. */ +/** + * @fileoverview Runs the Polymer Accessibility Settings tests. + * Chrome OS only. + */ // Polymer BrowserTest fixture and aXe-core accessibility audit. GEN_INCLUDE([ @@ -15,22 +18,28 @@ GEN('#include "chrome/browser/profiles/profile.h"'); GEN('#include "chrome/browser/ui/browser.h"'); GEN('#include "chrome/common/chrome_features.h"'); +GEN('#include "chromeos/constants/chromeos_features.h"'); GEN('#include "components/prefs/pref_service.h"'); -/** - * Test fixture for Accessibility of Chrome Settings. - * @constructor - * @extends {SettingsAccessibilityTest} - */ -function CrostiniAccessibilityTest() {} +// eslint-disable-next-line no-var +var CrostiniAccessibilityTest = class extends PolymerTest { + /** @override */ + get featureList() { + // Always test with SplitSettings on because the pages are the same in the + // legacy combined settings and we don't want to test everything twice. + return { + enabled: ['features::kCrostini', 'chromeos::features::kSplitSettings'] + }; + } -CrostiniAccessibilityTest.prototype = { - __proto__: SettingsAccessibilityTest.prototype, + /** @override */ + get browsePreload() { + return 'chrome://os-settings/'; + } - featureList: {enabled: ['features::kCrostini']}, - - testGenPreamble: function() { + /** @override */ + testGenPreamble() { GEN(' browser()->profile()->GetPrefs()->SetBoolean('); GEN(' crostini::prefs::kCrostiniEnabled, true);'); - }, + } };
diff --git a/chrome/test/data/webui/settings/a11y/google_assistant_a11y_test.js b/chrome/test/data/webui/settings/a11y/google_assistant_a11y_test.js index 32b339f..a9758b6 100644 --- a/chrome/test/data/webui/settings/a11y/google_assistant_a11y_test.js +++ b/chrome/test/data/webui/settings/a11y/google_assistant_a11y_test.js
@@ -9,26 +9,39 @@ // SettingsAccessibilityTest fixture. GEN_INCLUDE([ + '//chrome/test/data/webui/polymer_browser_test_base.js', 'settings_accessibility_test.js', ]); GEN('#include "chromeos/constants/chromeos_features.h"'); // eslint-disable-next-line no-var -var GoogleAssistantAccessibilityTest = class extends SettingsAccessibilityTest { +var GoogleAssistantA11yTest = class extends PolymerTest { /** @override */ get featureList() { - return {enabled: ['chromeos::features::kAssistantFeature']}; + // Always test with SplitSettings on because the pages are the same in the + // legacy combined settings and we don't want to test everything twice. + return { + enabled: [ + 'chromeos::features::kAssistantFeature', + 'chromeos::features::kSplitSettings' + ] + }; + } + + /** @override */ + get browsePreload() { + return 'chrome://os-settings/'; } }; -AccessibilityTest.define('GoogleAssistantAccessibilityTest', { +AccessibilityTest.define('GoogleAssistantA11yTest', { /** @override */ name: 'GOOGLE_ASSISTANT', /** @override */ - axeOptions: GoogleAssistantAccessibilityTest.axeOptions, + axeOptions: SettingsAccessibilityTest.axeOptions, /** @override */ - violationFilter: GoogleAssistantAccessibilityTest.violationFilter, + violationFilter: SettingsAccessibilityTest.violationFilter, /** @override */ setup: function() {
diff --git a/chrome/test/data/webui/settings/a11y/multidevice_a11y_test.js b/chrome/test/data/webui/settings/a11y/multidevice_a11y_test.js index 91688c8..1eb57f3 100644 --- a/chrome/test/data/webui/settings/a11y/multidevice_a11y_test.js +++ b/chrome/test/data/webui/settings/a11y/multidevice_a11y_test.js
@@ -7,12 +7,28 @@ * Chrome OS only. */ -// SettingsAccessibilityTest fixture. GEN_INCLUDE([ + '//chrome/test/data/webui/polymer_browser_test_base.js', 'settings_accessibility_test.js', ]); +GEN('#include "chromeos/constants/chromeos_features.h"'); -AccessibilityTest.define('SettingsAccessibilityTest', { +// eslint-disable-next-line no-var +var MultideviceA11yTest = class extends PolymerTest { + /** @override */ + get featureList() { + // Always test with SplitSettings on because the pages are the same in the + // legacy combined settings and we don't want to test everything twice. + return {enabled: ['chromeos::features::kSplitSettings']}; + } + + /** @override */ + get browsePreload() { + return 'chrome://os-settings/'; + } +}; + +AccessibilityTest.define('MultideviceA11yTest', { /** @override */ name: 'MULTIDEVICE', /** @override */
diff --git a/chrome/test/data/webui/settings/a11y/multidevice_features_a11y_test.js b/chrome/test/data/webui/settings/a11y/multidevice_features_a11y_test.js index 351cca2..841c3feb 100644 --- a/chrome/test/data/webui/settings/a11y/multidevice_features_a11y_test.js +++ b/chrome/test/data/webui/settings/a11y/multidevice_features_a11y_test.js
@@ -7,12 +7,28 @@ * Chrome OS only. */ -// SettingsAccessibilityTest fixture. GEN_INCLUDE([ + '//chrome/test/data/webui/polymer_browser_test_base.js', 'settings_accessibility_test.js', ]); +GEN('#include "chromeos/constants/chromeos_features.h"'); -AccessibilityTest.define('SettingsAccessibilityTest', { +// eslint-disable-next-line no-var +var MultideviceFeaturesA11yTest = class extends PolymerTest { + /** @override */ + get featureList() { + // Always test with SplitSettings on because the pages are the same in the + // legacy combined settings and we don't want to test everything twice. + return {enabled: ['chromeos::features::kSplitSettings']}; + } + + /** @override */ + get browsePreload() { + return 'chrome://os-settings/'; + } +}; + +AccessibilityTest.define('MultideviceFeaturesA11yTest', { /** @override */ name: 'MULTIDEVICE_FEATURES_ACCESSIBILITY', /** @override */
diff --git a/chrome/test/data/webui/settings/chromeos/quick_unlock_authenticate_browsertest_chromeos.js b/chrome/test/data/webui/settings/chromeos/quick_unlock_authenticate_browsertest_chromeos.js index cb8c0c3..72f6d161 100644 --- a/chrome/test/data/webui/settings/chromeos/quick_unlock_authenticate_browsertest_chromeos.js +++ b/chrome/test/data/webui/settings/chromeos/quick_unlock_authenticate_browsertest_chromeos.js
@@ -274,7 +274,7 @@ value: 'hide' }, { - key: 'ash.lock_screen_media_keys_enabled', + key: 'ash.lock_screen_media_controls_enabled', type: chrome.settingsPrivate.PrefType.BOOLEAN, value: true }
diff --git a/chromecast/cast_shell.cmx b/chromecast/cast_shell.cmx index 3fcbdfe..84ab0d96 100644 --- a/chromecast/cast_shell.cmx +++ b/chromecast/cast_shell.cmx
@@ -20,7 +20,6 @@ "fuchsia.media.Audio", "fuchsia.mediacodec.CodecFactory", "fuchsia.net.NameLookup", - "fuchsia.net.SocketProvider", "fuchsia.netstack.Netstack", "fuchsia.posix.socket.Provider", "fuchsia.process.Launcher",
diff --git a/chromecast/common/cast_content_client.cc b/chromecast/common/cast_content_client.cc index e6ee8463..0ac2c97 100644 --- a/chromecast/common/cast_content_client.cc +++ b/chromecast/common/cast_content_client.cc
@@ -124,10 +124,6 @@ resource_id, scale_factor); } -bool CastContentClient::IsDataResourceGzipped(int resource_id) { - return ui::ResourceBundle::GetSharedInstance().IsGzipped(resource_id); -} - gfx::Image& CastContentClient::GetNativeImageNamed(int resource_id) { return ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed( resource_id);
diff --git a/chromecast/common/cast_content_client.h b/chromecast/common/cast_content_client.h index 20b9084..178b790 100644 --- a/chromecast/common/cast_content_client.h +++ b/chromecast/common/cast_content_client.h
@@ -24,7 +24,6 @@ base::string16 GetLocalizedString(int message_id) override; base::StringPiece GetDataResource(int resource_id, ui::ScaleFactor scale_factor) override; - bool IsDataResourceGzipped(int resource_id) override; gfx::Image& GetNativeImageNamed(int resource_id) override; #if defined(OS_ANDROID) ::media::MediaDrmBridgeClient* GetMediaDrmBridgeClient() override;
diff --git a/chromeos/profiles/orderfile.newest.txt b/chromeos/profiles/orderfile.newest.txt index 6c32766..2a0c3d2 100644 --- a/chromeos/profiles/orderfile.newest.txt +++ b/chromeos/profiles/orderfile.newest.txt
@@ -1 +1 @@ -chromeos-chrome-orderfile-field-77-3849.0-benchmark-77.0.3862.0-r1.orderfile.xz +chromeos-chrome-orderfile-field-77-3849.0-1564392858-benchmark-77.0.3865.16-r1.orderfile.xz
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.cc b/chromeos/services/assistant/assistant_manager_service_impl.cc index 16c563d..7f34c72 100644 --- a/chromeos/services/assistant/assistant_manager_service_impl.cc +++ b/chromeos/services/assistant/assistant_manager_service_impl.cc
@@ -1180,6 +1180,12 @@ }); } +void AssistantManagerServiceImpl::MediaSessionChanged( + const base::Optional<base::UnguessableToken>& request_id) { + if (request_id.has_value()) + media_session_audio_focus_id_ = std::move(request_id.value()); +} + void AssistantManagerServiceImpl::MediaSessionInfoChanged( media_session::mojom::MediaSessionInfoPtr info) { media_session_info_ptr_ = std::move(info); @@ -1590,11 +1596,15 @@ return; } - // TODO(llin): MediaSession Integrated providers (include the libassistant - // internal media provider) will trigger media state change event. Only - // update the external media status if the state changes is triggered by - // external providers, after the media session API for identifying the source - // is available. + // MediaSession Integrated providers (include the libassistant internal + // media provider) will trigger media state change event. Only update the + // external media status if the state changes is triggered by external + // providers. + if (media_session_ && media_session_->internal_audio_focus_id() == + media_session_audio_focus_id_) { + return; + } + MediaStatus media_status; // Set media metadata.
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.h b/chromeos/services/assistant/assistant_manager_service_impl.h index 3d2f7ecd..1443259 100644 --- a/chromeos/services/assistant/assistant_manager_service_impl.h +++ b/chromeos/services/assistant/assistant_manager_service_impl.h
@@ -205,7 +205,7 @@ const std::vector<media_session::mojom::MediaSessionAction>& action) override {} void MediaSessionChanged( - const base::Optional<base::UnguessableToken>& request_id) override {} + const base::Optional<base::UnguessableToken>& request_id) override; void MediaSessionPositionChanged( const base::Optional<media_session::MediaPosition>& position) override {} @@ -338,6 +338,9 @@ // the media that was being played has been stopped. base::Optional<media_session::MediaMetadata> media_metadata_ = base::nullopt; + base::UnguessableToken media_session_audio_focus_id_ = + base::UnguessableToken::Null(); + bool start_finished_ = false; mojo::Binding<mojom::AppListEventSubscriber> app_list_subscriber_binding_;
diff --git a/chromeos/services/assistant/media_session/assistant_media_session.cc b/chromeos/services/assistant/media_session/assistant_media_session.cc index 8179967..47bf01d6 100644 --- a/chromeos/services/assistant/media_session/assistant_media_session.cc +++ b/chromeos/services/assistant/media_session/assistant_media_session.cc
@@ -134,6 +134,7 @@ request_client_remote_->AbandonAudioFocus(); request_client_remote_.reset(); audio_focus_remote_.reset(); + internal_audio_focus_id_ = base::UnguessableToken::Null(); } void AssistantMediaSession::EnsureServiceConnection() { @@ -159,6 +160,7 @@ void AssistantMediaSession::FinishInitialAudioFocusRequest( AudioFocusType audio_focus_type, const base::UnguessableToken& request_id) { + internal_audio_focus_id_ = request_id; FinishAudioFocusRequest(audio_focus_type); }
diff --git a/chromeos/services/assistant/media_session/assistant_media_session.h b/chromeos/services/assistant/media_session/assistant_media_session.h index 12f0cff..c38700b8 100644 --- a/chromeos/services/assistant/media_session/assistant_media_session.h +++ b/chromeos/services/assistant/media_session/assistant_media_session.h
@@ -70,6 +70,11 @@ base::WeakPtr<AssistantMediaSession> GetWeakPtr(); + // Returns internal audio focus id. + base::UnguessableToken internal_audio_focus_id() { + return internal_audio_focus_id_; + } + private: // Ensures that |audio_focus_ptr_| is connected. void EnsureServiceConnection(); @@ -129,6 +134,10 @@ media_session::mojom::AudioFocusType audio_focus_type_; + // Audio focus request Id for the internal media which is playing. + base::UnguessableToken internal_audio_focus_id_ = + base::UnguessableToken::Null(); + base::WeakPtrFactory<AssistantMediaSession> weak_factory_; DISALLOW_COPY_AND_ASSIGN(AssistantMediaSession);
diff --git a/chromeos/services/device_sync/BUILD.gn b/chromeos/services/device_sync/BUILD.gn index 2bfa2ce..ccb16e0 100644 --- a/chromeos/services/device_sync/BUILD.gn +++ b/chromeos/services/device_sync/BUILD.gn
@@ -27,6 +27,8 @@ "cryptauth_device_sync_result.h", "cryptauth_device_syncer.cc", "cryptauth_device_syncer.h", + "cryptauth_device_syncer_impl.cc", + "cryptauth_device_syncer_impl.h", "cryptauth_ecies_encryptor.cc", "cryptauth_ecies_encryptor.h", "cryptauth_ecies_encryptor_impl.cc", @@ -222,6 +224,7 @@ "cryptauth_client_impl_unittest.cc", "cryptauth_device_manager_impl_unittest.cc", "cryptauth_device_registry_impl_unittest.cc", + "cryptauth_device_syncer_impl_unittest.cc", "cryptauth_device_unittest.cc", "cryptauth_ecies_encryptor_impl_unittest.cc", "cryptauth_enroller_impl_unittest.cc",
diff --git a/chromeos/services/device_sync/cryptauth_device_sync_result.cc b/chromeos/services/device_sync/cryptauth_device_sync_result.cc index fab9a55..cf9985c 100644 --- a/chromeos/services/device_sync/cryptauth_device_sync_result.cc +++ b/chromeos/services/device_sync/cryptauth_device_sync_result.cc
@@ -8,6 +8,19 @@ namespace device_sync { +// static +CryptAuthDeviceSyncResult::ResultType CryptAuthDeviceSyncResult::GetResultType( + const ResultCode& result_code) { + switch (result_code) { + case CryptAuthDeviceSyncResult::ResultCode::kSuccess: + return CryptAuthDeviceSyncResult::ResultType::kSuccess; + case CryptAuthDeviceSyncResult::ResultCode::kFinishedWithNonFatalErrors: + return CryptAuthDeviceSyncResult::ResultType::kNonFatalError; + default: + return CryptAuthDeviceSyncResult::ResultType::kFatalError; + } +} + CryptAuthDeviceSyncResult::CryptAuthDeviceSyncResult( ResultCode result_code, bool did_device_registry_change, @@ -21,8 +34,13 @@ CryptAuthDeviceSyncResult::~CryptAuthDeviceSyncResult() = default; +CryptAuthDeviceSyncResult::ResultType CryptAuthDeviceSyncResult::GetResultType() + const { + return GetResultType(result_code_); +} + bool CryptAuthDeviceSyncResult::IsSuccess() const { - return result_code_ == ResultCode::kSuccess; + return GetResultType(result_code_) == ResultType::kSuccess; } bool CryptAuthDeviceSyncResult::operator==( @@ -70,8 +88,8 @@ case ResultCode::kErrorNoLocalDeviceMetadataInResponse: stream << "[Error: No local device metadata in SyncMetadata response]"; break; - case ResultCode::kErrorMissingFeatureStatuses: - stream << "[Error: Feature statuses not received for device(s)]"; + case ResultCode::kErrorMissingLocalDeviceFeatureStatuses: + stream << "[Error: No local device feature statuses]"; break; case ResultCode::kErrorMissingLocalDeviceSyncBetterTogetherKey: stream << "[Error: No DeviceSync:BetterTogether key in registry]"; @@ -79,20 +97,6 @@ case ResultCode::kErrorDecryptingGroupPrivateKey: stream << "[Error: Could not decrypt group private key]"; break; - case ResultCode::kErrorInconsistentGroupPrivateKeys: - stream << "[Error: Group private key from SyncMetadata response " - << "unexpectedly disagrees with the one in local storage]"; - break; - case ResultCode::kErrorDecryptingMetadata: - stream << "[Error: Could not decrypt device metadata]"; - break; - case ResultCode::kErrorParsingMetadata: - stream << "[Error: Could not parse device metadata]"; - break; - case ResultCode::kErrorInconsistentLocalDeviceMetadata: - stream << "[Error: Local device metadata disagrees with that in " - << "SyncMetadata response]"; - break; case ResultCode::kErrorEncryptingGroupPrivateKey: stream << "[Error: Could not encrypt group private key]"; break;
diff --git a/chromeos/services/device_sync/cryptauth_device_sync_result.h b/chromeos/services/device_sync/cryptauth_device_sync_result.h index b0649b33..980edbf 100644 --- a/chromeos/services/device_sync/cryptauth_device_sync_result.h +++ b/chromeos/services/device_sync/cryptauth_device_sync_result.h
@@ -31,13 +31,9 @@ kErrorNoMetadataInResponse, kErrorAllResponseMetadataInvalid, kErrorNoLocalDeviceMetadataInResponse, - kErrorMissingFeatureStatuses, + kErrorMissingLocalDeviceFeatureStatuses, kErrorMissingLocalDeviceSyncBetterTogetherKey, kErrorDecryptingGroupPrivateKey, - kErrorInconsistentGroupPrivateKeys, - kErrorDecryptingMetadata, - kErrorParsingMetadata, - kErrorInconsistentLocalDeviceMetadata, kErrorEncryptingGroupPrivateKey, kErrorSyncMetadataApiCallOffline, kErrorSyncMetadataApiCallEndpointNotFound, @@ -73,6 +69,10 @@ kMaxValue = kErrorTimeoutWaitingForShareGroupPrivateKeyResponse }; + enum class ResultType { kSuccess, kNonFatalError, kFatalError }; + + static ResultType GetResultType(const ResultCode& result_code); + CryptAuthDeviceSyncResult( ResultCode result_code, bool did_device_registry_change, @@ -91,6 +91,7 @@ return did_device_registry_change_; } + ResultType GetResultType() const; bool IsSuccess() const; bool operator==(const CryptAuthDeviceSyncResult& other) const;
diff --git a/chromeos/services/device_sync/cryptauth_device_syncer_impl.cc b/chromeos/services/device_sync/cryptauth_device_syncer_impl.cc new file mode 100644 index 0000000..dc0bced --- /dev/null +++ b/chromeos/services/device_sync/cryptauth_device_syncer_impl.cc
@@ -0,0 +1,630 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/services/device_sync/cryptauth_device_syncer_impl.h" + +#include <utility> + +#include "base/bind.h" +#include "base/containers/flat_set.h" +#include "base/memory/ptr_util.h" +#include "base/no_destructor.h" +#include "chromeos/components/multidevice/logging/logging.h" +#include "chromeos/services/device_sync/cryptauth_client.h" +#include "chromeos/services/device_sync/cryptauth_ecies_encryptor_impl.h" +#include "chromeos/services/device_sync/cryptauth_feature_status_getter_impl.h" +#include "chromeos/services/device_sync/cryptauth_group_private_key_sharer_impl.h" +#include "chromeos/services/device_sync/cryptauth_key_registry.h" +#include "chromeos/services/device_sync/cryptauth_metadata_syncer_impl.h" +#include "chromeos/services/device_sync/proto/cryptauth_client_app_metadata.pb.h" +#include "chromeos/services/device_sync/proto/cryptauth_common.pb.h" +#include "chromeos/services/device_sync/value_string_encoding.h" + +namespace chromeos { + +namespace device_sync { + +namespace { + +const cryptauthv2::KeyType kGroupKeyType = cryptauthv2::KeyType::P256; + +// Timeout values for asynchronous operations. +// TODO(https://crbug.com/933656): Tune these values. +constexpr base::TimeDelta kWaitingForEncryptedGroupPrivateKeyProcessingTimeout = + base::TimeDelta::FromSeconds(10); +constexpr base::TimeDelta kWaitingForEncryptedDeviceMetadataProcessingTimeout = + base::TimeDelta::FromSeconds(10); + +} // namespace + +// static +CryptAuthDeviceSyncerImpl::Factory* + CryptAuthDeviceSyncerImpl::Factory::test_factory_ = nullptr; + +// static +CryptAuthDeviceSyncerImpl::Factory* CryptAuthDeviceSyncerImpl::Factory::Get() { + if (test_factory_) + return test_factory_; + + static base::NoDestructor<CryptAuthDeviceSyncerImpl::Factory> factory; + return factory.get(); +} + +// static +void CryptAuthDeviceSyncerImpl::Factory::SetFactoryForTesting( + Factory* test_factory) { + test_factory_ = test_factory; +} + +CryptAuthDeviceSyncerImpl::Factory::~Factory() = default; + +std::unique_ptr<CryptAuthDeviceSyncer> +CryptAuthDeviceSyncerImpl::Factory::BuildInstance( + CryptAuthDeviceRegistry* device_registry, + CryptAuthKeyRegistry* key_registry, + CryptAuthClientFactory* client_factory, + std::unique_ptr<base::OneShotTimer> timer) { + return base::WrapUnique(new CryptAuthDeviceSyncerImpl( + device_registry, key_registry, client_factory, std::move(timer))); +} + +CryptAuthDeviceSyncerImpl::CryptAuthDeviceSyncerImpl( + CryptAuthDeviceRegistry* device_registry, + CryptAuthKeyRegistry* key_registry, + CryptAuthClientFactory* client_factory, + std::unique_ptr<base::OneShotTimer> timer) + : device_registry_(device_registry), + key_registry_(key_registry), + client_factory_(client_factory), + timer_(std::move(timer)) { + DCHECK(device_registry); + DCHECK(key_registry); + DCHECK(client_factory); +} + +CryptAuthDeviceSyncerImpl::~CryptAuthDeviceSyncerImpl() = default; + +// static +base::Optional<base::TimeDelta> CryptAuthDeviceSyncerImpl::GetTimeoutForState( + State state) { + switch (state) { + case State::kWaitingForEncryptedGroupPrivateKeyProcessing: + return kWaitingForEncryptedGroupPrivateKeyProcessingTimeout; + case State::kWaitingForEncryptedDeviceMetadataProcessing: + return kWaitingForEncryptedDeviceMetadataProcessingTimeout; + default: + // Signifies that there should not be a timeout. + // Note: CryptAuthMetadataSyncerImpl, CryptAuthFeatureStatusGetterImpl, + // and CryptAuthGroupPrivateKeySharerImpl guarantee that the callbacks + // passed to their public methods are always invoke; in other words, these + // implementations handle their relevant timeouts internally. + return base::nullopt; + } +} + +// static +base::Optional<CryptAuthDeviceSyncResult::ResultCode> +CryptAuthDeviceSyncerImpl::ResultCodeErrorFromTimeoutDuringState(State state) { + switch (state) { + case State::kWaitingForEncryptedGroupPrivateKeyProcessing: + return CryptAuthDeviceSyncResult::ResultCode:: + kErrorTimeoutWaitingForGroupPrivateKeyDecryption; + case State::kWaitingForEncryptedDeviceMetadataProcessing: + return CryptAuthDeviceSyncResult::ResultCode:: + kErrorTimeoutWaitingForDeviceMetadataDecryption; + default: + return base::nullopt; + } +} + +void CryptAuthDeviceSyncerImpl::OnAttemptStarted( + const cryptauthv2::ClientMetadata& client_metadata, + const cryptauthv2::ClientAppMetadata& client_app_metadata) { + DCHECK_EQ(State::kNotStarted, state_); + + request_context_.set_group(CryptAuthKeyBundle::KeyBundleNameEnumToString( + CryptAuthKeyBundle::Name::kDeviceSyncBetterTogether)); + request_context_.mutable_client_metadata()->CopyFrom(client_metadata); + request_context_.set_device_id(client_app_metadata.instance_id()); + + // TODO(https://crbug.com/990430): This is the IID token for the v2 Enrollment + // service. A different IID token for the v2 DeviceSync service will be + // necessary. + request_context_.set_device_id_token(client_app_metadata.instance_id_token()); + + const CryptAuthKey* user_key_pair = + key_registry_->GetActiveKey(CryptAuthKeyBundle::Name::kUserKeyPair); + if (!user_key_pair) { + FinishAttempt( + CryptAuthDeviceSyncResult::ResultCode::kErrorMissingUserKeyPair); + return; + } + + local_better_together_device_metadata_.set_public_key( + user_key_pair->public_key()); + local_better_together_device_metadata_.set_no_pii_device_name( + client_app_metadata.device_model()); + + AttemptNextStep(); +} + +void CryptAuthDeviceSyncerImpl::SetState(State state) { + timer_->Stop(); + + PA_LOG(INFO) << "Transitioning from " << state_ << " to " << state; + state_ = state; + + base::Optional<base::TimeDelta> timeout_for_state = GetTimeoutForState(state); + if (!timeout_for_state) + return; + + // TODO(https://crbug.com/936273): Add metrics to track failure rates due to + // async timeouts. + timer_->Start(FROM_HERE, *timeout_for_state, + base::BindOnce(&CryptAuthDeviceSyncerImpl::OnTimeout, + base::Unretained(this))); +} + +void CryptAuthDeviceSyncerImpl::OnTimeout() { + // If there's a timeout specified, there should be a corresponding error code. + base::Optional<CryptAuthDeviceSyncResult::ResultCode> error_code = + ResultCodeErrorFromTimeoutDuringState(state_); + DCHECK(error_code); + + FinishAttempt(*error_code); +} + +void CryptAuthDeviceSyncerImpl::AttemptNextStep() { + switch (state_) { + case State::kNotStarted: + SyncMetadata(); + return; + case State::kWaitingForMetadataSync: + GetFeatureStatuses(); + return; + case State::kWaitingForFeatureStatuses: + ProcessEncryptedGroupPrivateKey(); + return; + case State::kWaitingForEncryptedGroupPrivateKeyProcessing: + ProcessEncryptedDeviceMetadata(); + return; + case State::kWaitingForEncryptedDeviceMetadataProcessing: + ShareGroupPrivateKey(); + return; + case State::kWaitingForGroupPrivateKeySharing: { + CryptAuthDeviceSyncResult::ResultCode result_code = + did_non_fatal_error_occur_ + ? CryptAuthDeviceSyncResult::ResultCode:: + kFinishedWithNonFatalErrors + : CryptAuthDeviceSyncResult::ResultCode::kSuccess; + FinishAttempt(result_code); + return; + } + case State::kFinished: + NOTREACHED(); + return; + } +} + +void CryptAuthDeviceSyncerImpl::SyncMetadata() { + SetState(State::kWaitingForMetadataSync); + + metadata_syncer_ = CryptAuthMetadataSyncerImpl::Factory::Get()->BuildInstance( + client_factory_); + metadata_syncer_->SyncMetadata( + request_context_, local_better_together_device_metadata_, + key_registry_->GetActiveKey( + CryptAuthKeyBundle::Name::kDeviceSyncBetterTogetherGroupKey), + base::Bind(&CryptAuthDeviceSyncerImpl::OnSyncMetadataFinished, + base::Unretained(this))); +} + +void CryptAuthDeviceSyncerImpl::OnSyncMetadataFinished( + const CryptAuthMetadataSyncer::IdToDeviceMetadataPacketMap& + id_to_device_metadata_packet_map, + std::unique_ptr<CryptAuthKey> new_group_key, + const base::Optional<cryptauthv2::EncryptedGroupPrivateKey>& + encrypted_group_private_key, + const CryptAuthDeviceSyncResult& device_sync_result) { + DCHECK_EQ(State::kWaitingForMetadataSync, state_); + + id_to_device_metadata_packet_map_ = id_to_device_metadata_packet_map; + encrypted_group_private_key_ = encrypted_group_private_key; + new_client_directive_ = device_sync_result.client_directive(); + + // If a new group key pair was created or if CryptAuth returned a new group + // public key during the metadata sync, add the new group key to the key + // registry. + if (new_group_key) + SetGroupKey(*new_group_key); + + switch (device_sync_result.GetResultType()) { + case CryptAuthDeviceSyncResult::ResultType::kNonFatalError: + did_non_fatal_error_occur_ = true; + FALLTHROUGH; + case CryptAuthDeviceSyncResult::ResultType::kSuccess: + // At a minimum, the local device metadata should be returned if no fatal + // error occurred. + DCHECK(base::Contains(id_to_device_metadata_packet_map_, + request_context_.device_id())); + + // A group key should be established by now if no fatal error occurred. + DCHECK(key_registry_->GetActiveKey( + CryptAuthKeyBundle::Name::kDeviceSyncBetterTogetherGroupKey)); + + AttemptNextStep(); + return; + case CryptAuthDeviceSyncResult::ResultType::kFatalError: + FinishAttempt(device_sync_result.result_code()); + return; + } +} + +void CryptAuthDeviceSyncerImpl::SetGroupKey(const CryptAuthKey& new_group_key) { + DCHECK_EQ(kGroupKeyType, new_group_key.type()); + + const CryptAuthKey* current_group_key = key_registry_->GetActiveKey( + CryptAuthKeyBundle::Name::kDeviceSyncBetterTogetherGroupKey); + if (current_group_key) { + if (*current_group_key == new_group_key) + return; + + PA_LOG(VERBOSE) << "Deleting old DeviceSync BetterTogether group key: " + << "public = " + << util::EncodeAsString(current_group_key->public_key()) + << ", private = " + << (current_group_key->private_key().empty() + ? "[empty]" + : "[not empty]"); + key_registry_->DeleteKey( + CryptAuthKeyBundle::Name::kDeviceSyncBetterTogetherGroupKey, + current_group_key->handle()); + } + + PA_LOG(VERBOSE) << "New DeviceSync BetterTogether group key: " + << "public = " + << util::EncodeAsString(new_group_key.public_key()) + << ", private = " + << (new_group_key.private_key().empty() ? "[empty]" + : "[not empty]"); + + key_registry_->AddKey( + CryptAuthKeyBundle::Name::kDeviceSyncBetterTogetherGroupKey, + new_group_key); +} + +void CryptAuthDeviceSyncerImpl::GetFeatureStatuses() { + SetState(State::kWaitingForFeatureStatuses); + + base::flat_set<std::string> device_ids; + for (const auto& id_packet_pair : id_to_device_metadata_packet_map_) + device_ids.insert(id_packet_pair.first); + + feature_status_getter_ = + CryptAuthFeatureStatusGetterImpl::Factory::Get()->BuildInstance( + client_factory_); + feature_status_getter_->GetFeatureStatuses( + request_context_, device_ids, + base::Bind(&CryptAuthDeviceSyncerImpl::OnGetFeatureStatusesFinished, + base::Unretained(this))); +} + +void CryptAuthDeviceSyncerImpl::OnGetFeatureStatusesFinished( + const CryptAuthFeatureStatusGetter::IdToFeatureStatusMap& + id_to_feature_status_map, + const CryptAuthDeviceSyncResult::ResultCode& device_sync_result_code) { + DCHECK_EQ(State::kWaitingForFeatureStatuses, state_); + + // We require that the local device feature statuses are returned; the local + // device is needed in the registry. + if (!base::Contains(id_to_feature_status_map, request_context_.device_id())) { + FinishAttempt(CryptAuthDeviceSyncResult::ResultCode:: + kErrorMissingLocalDeviceFeatureStatuses); + return; + } + + switch (CryptAuthDeviceSyncResult::GetResultType(device_sync_result_code)) { + case CryptAuthDeviceSyncResult::ResultType::kNonFatalError: + did_non_fatal_error_occur_ = true; + FALLTHROUGH; + case CryptAuthDeviceSyncResult::ResultType::kSuccess: + BuildNewDeviceRegistry(id_to_feature_status_map); + AttemptNextStep(); + return; + case CryptAuthDeviceSyncResult::ResultType::kFatalError: + FinishAttempt(device_sync_result_code); + return; + } +} + +void CryptAuthDeviceSyncerImpl::BuildNewDeviceRegistry( + const CryptAuthFeatureStatusGetter::IdToFeatureStatusMap& + id_to_feature_status_map) { + // Add all device information to the new registry except the remote device + // BetterTogether metadata that will be decrypted and added later if possible. + new_device_registry_map_ = CryptAuthDeviceRegistry::InstanceIdToDeviceMap(); + for (const auto& id_feature_status_pair : id_to_feature_status_map) { + const std::string& id = id_feature_status_pair.first; + const CryptAuthFeatureStatusGetter::FeatureStatusMap& feature_status_map = + id_feature_status_pair.second; + + // The IDs in |id_to_feature_status_map| should be a subset of those in + // |id_to_device_metadata_packet_map|. + const auto packet_it = id_to_device_metadata_packet_map_.find(id); + DCHECK(packet_it != id_to_device_metadata_packet_map_.end()); + const cryptauthv2::DeviceMetadataPacket& packet = packet_it->second; + + // Add BetterTogetherDeviceMetadata only for the local device. + base::Optional<cryptauthv2::BetterTogetherDeviceMetadata> beto_metadata; + if (id == request_context_.device_id()) + beto_metadata = local_better_together_device_metadata_; + + // TODO(https://crbug.com/990441): Add last_update_time when CryptAuth + // starts returning it. + new_device_registry_map_->try_emplace( + id, id, packet.device_name(), packet.device_public_key(), base::Time(), + beto_metadata, feature_status_map); + } +} + +void CryptAuthDeviceSyncerImpl::ProcessEncryptedGroupPrivateKey() { + SetState(State::kWaitingForEncryptedGroupPrivateKeyProcessing); + + // CryptAuth will not return the group private key in the SyncMetadata + // response if the key has not been uploaded by another user device or + // possibly if we already own the group private key. + if (!encrypted_group_private_key_) { + AttemptNextStep(); + return; + } + + const CryptAuthKey* device_sync_better_together_key = + key_registry_->GetActiveKey( + CryptAuthKeyBundle::Name::kDeviceSyncBetterTogether); + if (!device_sync_better_together_key || + device_sync_better_together_key->private_key().empty()) { + FinishAttempt(CryptAuthDeviceSyncResult::ResultCode:: + kErrorMissingLocalDeviceSyncBetterTogetherKey); + return; + } + + encryptor_ = CryptAuthEciesEncryptorImpl::Factory::Get()->BuildInstance(); + encryptor_->Decrypt( + encrypted_group_private_key_->encrypted_private_key(), + device_sync_better_together_key->private_key(), + base::BindOnce(&CryptAuthDeviceSyncerImpl::OnGroupPrivateKeyDecrypted, + base::Unretained(this))); +} + +void CryptAuthDeviceSyncerImpl::OnGroupPrivateKeyDecrypted( + const base::Optional<std::string>& group_private_key_from_cryptauth) { + DCHECK_EQ(State::kWaitingForEncryptedGroupPrivateKeyProcessing, state_); + + if (!group_private_key_from_cryptauth) { + FinishAttempt( + CryptAuthDeviceSyncResult::ResultCode::kErrorDecryptingGroupPrivateKey); + return; + } + + const CryptAuthKey* group_key = key_registry_->GetActiveKey( + CryptAuthKeyBundle::Name::kDeviceSyncBetterTogetherGroupKey); + DCHECK(group_key); + + // If there is no group private key in the key registry, add the newly + // decrypted group private key. If a group private key already exists in the + // key registry, verify it against the newly decrypted group private key. + if (group_key->private_key().empty()) { + SetGroupKey(CryptAuthKey(group_key->public_key(), + *group_private_key_from_cryptauth, + CryptAuthKey::Status::kActive, kGroupKeyType)); + } else if (group_key->private_key() != group_private_key_from_cryptauth) { + // TODO(https://crbug.com/936273): Log metrics for inconsistent group + // private keys. + PA_LOG(ERROR) << "Group private key from CryptAuth unexpectedly " + << "disagrees with the one in local storage. Using " + << "group private key from local key registry."; + did_non_fatal_error_occur_ = true; + } + + AttemptNextStep(); +} + +void CryptAuthDeviceSyncerImpl::ProcessEncryptedDeviceMetadata() { + SetState(State::kWaitingForEncryptedDeviceMetadataProcessing); + + // If we still do not have a group private key, we cannot decrypt device + // metadata nor share the group private key. Finish the DeviceSync attempt and + // wait for a GCM notification alerting us that the group private key is + // available. + const CryptAuthKey* group_key = key_registry_->GetActiveKey( + CryptAuthKeyBundle::Name::kDeviceSyncBetterTogetherGroupKey); + DCHECK(group_key); + if (group_key->private_key().empty()) { + CryptAuthDeviceSyncResult::ResultCode result_code = + did_non_fatal_error_occur_ + ? CryptAuthDeviceSyncResult::ResultCode::kFinishedWithNonFatalErrors + : CryptAuthDeviceSyncResult::ResultCode::kSuccess; + FinishAttempt(result_code); + return; + } + + DCHECK(new_device_registry_map_); + CryptAuthEciesEncryptor::IdToInputMap id_to_encrypted_metadata_map; + for (const auto& id_device_pair : *new_device_registry_map_) { + const auto it = + id_to_device_metadata_packet_map_.find(id_device_pair.first); + DCHECK(it != id_to_device_metadata_packet_map_.end()); + id_to_encrypted_metadata_map[id_device_pair.first] = + CryptAuthEciesEncryptor::PayloadAndKey(it->second.encrypted_metadata(), + group_key->private_key()); + } + + encryptor_ = CryptAuthEciesEncryptorImpl::Factory::Get()->BuildInstance(); + encryptor_->BatchDecrypt( + id_to_encrypted_metadata_map, + base::BindOnce(&CryptAuthDeviceSyncerImpl::OnDeviceMetadataDecrypted, + base::Unretained(this))); +} + +void CryptAuthDeviceSyncerImpl::OnDeviceMetadataDecrypted( + const CryptAuthEciesEncryptor::IdToOutputMap& + id_to_decrypted_metadata_map) { + DCHECK_EQ(State::kWaitingForEncryptedDeviceMetadataProcessing, state_); + + AddDecryptedMetadataToNewDeviceRegistry(id_to_decrypted_metadata_map); + + AttemptNextStep(); +} + +void CryptAuthDeviceSyncerImpl::AddDecryptedMetadataToNewDeviceRegistry( + const CryptAuthEciesEncryptor::IdToOutputMap& + id_to_decrypted_metadata_map) { + DCHECK(new_device_registry_map_); + + // Update the new device registry with BetterTogether device metadata. + for (auto& id_device_pair : *new_device_registry_map_) { + cryptauthv2::BetterTogetherDeviceMetadata decrypted_metadata; + + const auto it = id_to_decrypted_metadata_map.find(id_device_pair.first); + DCHECK(it != id_to_decrypted_metadata_map.end()); + + // TODO(https://crbug.com/936273): Log metrics for metadata decryption + // failure. + bool was_metadata_decrypted = it->second.has_value(); + if (!was_metadata_decrypted) { + PA_LOG(ERROR) << "Metadata for device with Instance ID " << it->first + << " was not able to be decrypted."; + did_non_fatal_error_occur_ = true; + continue; + } + + // TODO(https://crbug.com/936273): Log metrics for metadata parsing failure. + bool was_metadata_parsed = decrypted_metadata.ParseFromString(*it->second); + if (!was_metadata_parsed) { + PA_LOG(ERROR) << "Metadata for device with Instance ID " << it->first + << " was not able to be parsed."; + did_non_fatal_error_occur_ = true; + continue; + } + + // The local device should already have its metadata set. Verify consistency + // with data from CryptAuth. + // TODO(https://crbug.com/936273): Log metrics for inconsistent local device + // metadata. + if (id_device_pair.first == request_context_.device_id()) { + DCHECK(id_device_pair.second.better_together_device_metadata); + bool is_local_device_metadata_consistent = + *it->second == id_device_pair.second.better_together_device_metadata + ->SerializeAsString(); + if (!is_local_device_metadata_consistent) { + PA_LOG(ERROR) << "Local device (Instance ID: " + << request_context_.device_id() + << ") metadata disagrees with that sent in SyncMetadata " + << "response."; + did_non_fatal_error_occur_ = true; + } + + continue; + } + + id_device_pair.second.better_together_device_metadata = decrypted_metadata; + } +} + +void CryptAuthDeviceSyncerImpl::ShareGroupPrivateKey() { + SetState(State::kWaitingForGroupPrivateKeySharing); + + CryptAuthGroupPrivateKeySharer::IdToEncryptingKeyMap id_to_encrypting_key_map; + for (const auto& id_packet_pair : id_to_device_metadata_packet_map_) { + if (!id_packet_pair.second.need_group_private_key()) + continue; + + id_to_encrypting_key_map.insert_or_assign( + id_packet_pair.first, id_packet_pair.second.device_public_key()); + } + + const CryptAuthKey* group_key = key_registry_->GetActiveKey( + CryptAuthKeyBundle::Name::kDeviceSyncBetterTogetherGroupKey); + DCHECK(group_key); + + group_private_key_sharer_ = + CryptAuthGroupPrivateKeySharerImpl::Factory::Get()->BuildInstance( + client_factory_); + group_private_key_sharer_->ShareGroupPrivateKey( + request_context_, *group_key, id_to_encrypting_key_map, + base::Bind(&CryptAuthDeviceSyncerImpl::OnShareGroupPrivateKeyFinished, + base::Unretained(this))); +} + +void CryptAuthDeviceSyncerImpl::OnShareGroupPrivateKeyFinished( + const CryptAuthDeviceSyncResult::ResultCode& device_sync_result_code) { + DCHECK_EQ(State::kWaitingForGroupPrivateKeySharing, state_); + + switch (CryptAuthDeviceSyncResult::GetResultType(device_sync_result_code)) { + case CryptAuthDeviceSyncResult::ResultType::kNonFatalError: + did_non_fatal_error_occur_ = true; + FALLTHROUGH; + case CryptAuthDeviceSyncResult::ResultType::kSuccess: + AttemptNextStep(); + return; + case CryptAuthDeviceSyncResult::ResultType::kFatalError: + FinishAttempt(device_sync_result_code); + return; + } +} + +void CryptAuthDeviceSyncerImpl::FinishAttempt( + const CryptAuthDeviceSyncResult::ResultCode& result_code) { + SetState(State::kFinished); + + metadata_syncer_.reset(); + feature_status_getter_.reset(); + encryptor_.reset(); + group_private_key_sharer_.reset(); + + bool did_device_registry_change = + new_device_registry_map_ && + device_registry_->SetRegistry(*new_device_registry_map_); + + OnAttemptFinished(CryptAuthDeviceSyncResult( + result_code, did_device_registry_change, new_client_directive_)); +} + +std::ostream& operator<<(std::ostream& stream, + const CryptAuthDeviceSyncerImpl::State& state) { + switch (state) { + case CryptAuthDeviceSyncerImpl::State::kNotStarted: + stream << "[DeviceSyncer state: Not started]"; + break; + case CryptAuthDeviceSyncerImpl::State::kWaitingForMetadataSync: + stream << "[DeviceSyncer state: Waiting for metadata sync]"; + break; + case CryptAuthDeviceSyncerImpl::State::kWaitingForFeatureStatuses: + stream << "[DeviceSyncer state: Waiting for feature statuses]"; + break; + case CryptAuthDeviceSyncerImpl::State:: + kWaitingForEncryptedGroupPrivateKeyProcessing: + stream << "[DeviceSyncer state: Waiting for encrypted group private key " + << "processing]"; + break; + case CryptAuthDeviceSyncerImpl::State:: + kWaitingForEncryptedDeviceMetadataProcessing: + stream << "[DeviceSyncer state: Waiting for encrypted device metadata " + "processing]"; + break; + case CryptAuthDeviceSyncerImpl::State::kWaitingForGroupPrivateKeySharing: + stream << "[DeviceSyncer state: Waiting for group private key " + << "to be shared]"; + break; + case CryptAuthDeviceSyncerImpl::State::kFinished: + stream << "[DeviceSyncer state: Finished]"; + break; + } + + return stream; +} + +} // namespace device_sync + +} // namespace chromeos
diff --git a/chromeos/services/device_sync/cryptauth_device_syncer_impl.h b/chromeos/services/device_sync/cryptauth_device_syncer_impl.h new file mode 100644 index 0000000..39f73b5d --- /dev/null +++ b/chromeos/services/device_sync/cryptauth_device_syncer_impl.h
@@ -0,0 +1,203 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_SERVICES_DEVICE_SYNC_CRYPTAUTH_DEVICE_SYNCER_IMPL_H_ +#define CHROMEOS_SERVICES_DEVICE_SYNC_CRYPTAUTH_DEVICE_SYNCER_IMPL_H_ + +#include <memory> +#include <ostream> +#include <string> +#include <vector> + +#include "base/containers/flat_map.h" +#include "base/macros.h" +#include "base/optional.h" +#include "base/time/time.h" +#include "base/timer/timer.h" +#include "chromeos/services/device_sync/cryptauth_device_registry.h" +#include "chromeos/services/device_sync/cryptauth_device_sync_result.h" +#include "chromeos/services/device_sync/cryptauth_device_syncer.h" +#include "chromeos/services/device_sync/cryptauth_ecies_encryptor.h" +#include "chromeos/services/device_sync/cryptauth_feature_status_getter.h" +#include "chromeos/services/device_sync/cryptauth_group_private_key_sharer.h" +#include "chromeos/services/device_sync/cryptauth_key.h" +#include "chromeos/services/device_sync/cryptauth_key_bundle.h" +#include "chromeos/services/device_sync/cryptauth_metadata_syncer.h" +#include "chromeos/services/device_sync/network_request_error.h" +#include "chromeos/services/device_sync/proto/cryptauth_better_together_device_metadata.pb.h" +#include "chromeos/services/device_sync/proto/cryptauth_devicesync.pb.h" +#include "chromeos/services/device_sync/proto/cryptauth_directive.pb.h" + +namespace cryptauthv2 { +class ClientAppMetadata; +class ClientMetadata; +} // namespace cryptauthv2 + +namespace chromeos { + +namespace device_sync { + +class CryptAuthClient; +class CryptAuthClientFactory; +class CryptAuthKeyRegistry; + +// An implementation of CryptAuthDeviceSyncer, using instances of +// CryptAuthClient to make the API calls to CryptAuth. This implementation +// handles timeouts internally, so the callback passed to +// CryptAuthDeviceSyncer::Sync() is always guaranteed to be invoked. +// +// When the DeviceSync flow finishes, the device registry is updated with all +// devices that have a valid device ID, device name, device public key, and +// feature states. If device metadata cannot be decrypted due to an error or +// because the group private key was not returned by CryptAuth, the device is +// still added to the registry without the decrypted metadata. +class CryptAuthDeviceSyncerImpl : public CryptAuthDeviceSyncer { + public: + class Factory { + public: + static Factory* Get(); + static void SetFactoryForTesting(Factory* test_factory); + virtual ~Factory(); + virtual std::unique_ptr<CryptAuthDeviceSyncer> BuildInstance( + CryptAuthDeviceRegistry* device_registry, + CryptAuthKeyRegistry* key_registry, + CryptAuthClientFactory* client_factory, + std::unique_ptr<base::OneShotTimer> timer = + std::make_unique<base::OneShotTimer>()); + + private: + static Factory* test_factory_; + }; + + ~CryptAuthDeviceSyncerImpl() override; + + private: + enum class State { + kNotStarted, + kWaitingForMetadataSync, + kWaitingForFeatureStatuses, + kWaitingForEncryptedGroupPrivateKeyProcessing, + kWaitingForEncryptedDeviceMetadataProcessing, + kWaitingForGroupPrivateKeySharing, + kFinished + }; + + friend std::ostream& operator<<(std::ostream& stream, const State& state); + + static base::Optional<base::TimeDelta> GetTimeoutForState(State state); + static base::Optional<CryptAuthDeviceSyncResult::ResultCode> + ResultCodeErrorFromTimeoutDuringState(State state); + + // |device_registry|: At the end of a DeviceSync flow, the devices in the + // registry are replaced with the devices received from CryptAuth. + // |key_registry|: The syncer will read and possibly write the group key pair, + // and it will read the user key pair and the key used for decrypting the + // group private key. + // |client_factory|: Creates CryptAuthClient instances for making API calls. + // |timer|: Handles timeouts for asynchronous operations. + CryptAuthDeviceSyncerImpl(CryptAuthDeviceRegistry* device_registry, + CryptAuthKeyRegistry* key_registry, + CryptAuthClientFactory* client_factory, + std::unique_ptr<base::OneShotTimer> timer); + + // CryptAuthDeviceSyncer: + void OnAttemptStarted( + const cryptauthv2::ClientMetadata& client_metadata, + const cryptauthv2::ClientAppMetadata& client_app_metadata) override; + + void SetState(State state); + void OnTimeout(); + + // Controls the logical flow of the class. + void AttemptNextStep(); + + void SyncMetadata(); + void OnSyncMetadataFinished( + const CryptAuthMetadataSyncer::IdToDeviceMetadataPacketMap& + id_to_device_metadata_packet_map, + std::unique_ptr<CryptAuthKey> new_group_key, + const base::Optional<cryptauthv2::EncryptedGroupPrivateKey>& + encrypted_group_private_key, + const CryptAuthDeviceSyncResult& device_sync_result); + + void SetGroupKey(const CryptAuthKey& new_group_key); + + void GetFeatureStatuses(); + void OnGetFeatureStatusesFinished( + const CryptAuthFeatureStatusGetter::IdToFeatureStatusMap& + id_to_feature_status_map, + const CryptAuthDeviceSyncResult::ResultCode& device_sync_result_code); + + // Builds a new device registry map with all device information except + // decrypted BetterTogetherDeviceMetadata for remote devices. + void BuildNewDeviceRegistry( + const CryptAuthFeatureStatusGetter::IdToFeatureStatusMap& + id_to_feature_status_map); + + // If an encrypted group private key was sent by CryptAuth, decrypt it. Even + // if we already have the unencrypted group private key in the key registry, + // we verify that they agree. + void ProcessEncryptedGroupPrivateKey(); + void OnGroupPrivateKeyDecrypted( + const base::Optional<std::string>& group_private_key_from_cryptauth); + + void ProcessEncryptedDeviceMetadata(); + void OnDeviceMetadataDecrypted(const CryptAuthEciesEncryptor::IdToOutputMap& + id_to_decrypted_metadata_map); + + // Adds decrypted BetterTogetherDeviceMetadata to the new device registry + // constructed in BuildNewDeviceRegistry(). + void AddDecryptedMetadataToNewDeviceRegistry( + const CryptAuthEciesEncryptor::IdToOutputMap& + id_to_decrypted_metadata_map); + + void ShareGroupPrivateKey(); + void OnShareGroupPrivateKeyFinished( + const CryptAuthDeviceSyncResult::ResultCode& device_sync_result_code); + + // Replaces the current device registry if devices were able to be extracted + // from the DeviceSync attempt. Finishes the DeviceSync attempt, sending back + // the relevant CryptAuthDeviceSyncResult. + void FinishAttempt(const CryptAuthDeviceSyncResult::ResultCode& result_code); + + bool did_non_fatal_error_occur_ = false; + + // Set in OnAttemptStarted() and not modified during the rest of the flow. + cryptauthv2::RequestContext request_context_; + cryptauthv2::BetterTogetherDeviceMetadata + local_better_together_device_metadata_; + + // Output from CryptAuthMetadataSyncer. + CryptAuthMetadataSyncer::IdToDeviceMetadataPacketMap + id_to_device_metadata_packet_map_; + base::Optional<cryptauthv2::EncryptedGroupPrivateKey> + encrypted_group_private_key_; + base::Optional<cryptauthv2::ClientDirective> new_client_directive_; + + // Populated after a successful BatchGetFeatureStatuses call. Device metadata + // is added if device metadata decryption is successful. Replaces the contents + // of the device registry if non-null when the DeviceSync attempt ends, + // successfully or not. + base::Optional<CryptAuthDeviceRegistry::InstanceIdToDeviceMap> + new_device_registry_map_; + + std::unique_ptr<CryptAuthMetadataSyncer> metadata_syncer_; + std::unique_ptr<CryptAuthFeatureStatusGetter> feature_status_getter_; + std::unique_ptr<CryptAuthEciesEncryptor> encryptor_; + std::unique_ptr<CryptAuthGroupPrivateKeySharer> group_private_key_sharer_; + + State state_ = State::kNotStarted; + CryptAuthDeviceRegistry* device_registry_ = nullptr; + CryptAuthKeyRegistry* key_registry_ = nullptr; + CryptAuthClientFactory* client_factory_ = nullptr; + std::unique_ptr<base::OneShotTimer> timer_; + + DISALLOW_COPY_AND_ASSIGN(CryptAuthDeviceSyncerImpl); +}; + +} // namespace device_sync + +} // namespace chromeos + +#endif // CHROMEOS_SERVICES_DEVICE_SYNC_CRYPTAUTH_DEVICE_SYNCER_IMPL_H_
diff --git a/chromeos/services/device_sync/cryptauth_device_syncer_impl_unittest.cc b/chromeos/services/device_sync/cryptauth_device_syncer_impl_unittest.cc new file mode 100644 index 0000000..a03b82d --- /dev/null +++ b/chromeos/services/device_sync/cryptauth_device_syncer_impl_unittest.cc
@@ -0,0 +1,1225 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/services/device_sync/cryptauth_device_syncer_impl.h" + +#include <memory> +#include <string> +#include <utility> + +#include "base/macros.h" +#include "base/no_destructor.h" +#include "base/optional.h" +#include "base/timer/mock_timer.h" +#include "chromeos/services/device_sync/cryptauth_client.h" +#include "chromeos/services/device_sync/cryptauth_device.h" +#include "chromeos/services/device_sync/cryptauth_device_registry.h" +#include "chromeos/services/device_sync/cryptauth_device_registry_impl.h" +#include "chromeos/services/device_sync/cryptauth_device_sync_result.h" +#include "chromeos/services/device_sync/cryptauth_ecies_encryptor_impl.h" +#include "chromeos/services/device_sync/cryptauth_enrollment_constants.h" +#include "chromeos/services/device_sync/cryptauth_feature_status_getter.h" +#include "chromeos/services/device_sync/cryptauth_feature_status_getter_impl.h" +#include "chromeos/services/device_sync/cryptauth_group_private_key_sharer.h" +#include "chromeos/services/device_sync/cryptauth_group_private_key_sharer_impl.h" +#include "chromeos/services/device_sync/cryptauth_key.h" +#include "chromeos/services/device_sync/cryptauth_key_bundle.h" +#include "chromeos/services/device_sync/cryptauth_key_registry.h" +#include "chromeos/services/device_sync/cryptauth_key_registry_impl.h" +#include "chromeos/services/device_sync/cryptauth_metadata_syncer.h" +#include "chromeos/services/device_sync/cryptauth_metadata_syncer_impl.h" +#include "chromeos/services/device_sync/cryptauth_v2_device_sync_test_devices.h" +#include "chromeos/services/device_sync/fake_cryptauth_ecies_encryptor.h" +#include "chromeos/services/device_sync/fake_cryptauth_feature_status_getter.h" +#include "chromeos/services/device_sync/fake_cryptauth_group_private_key_sharer.h" +#include "chromeos/services/device_sync/fake_cryptauth_metadata_syncer.h" +#include "chromeos/services/device_sync/fake_ecies_encryption.h" +#include "chromeos/services/device_sync/mock_cryptauth_client.h" +#include "chromeos/services/device_sync/network_request_error.h" +#include "chromeos/services/device_sync/proto/cryptauth_common.pb.h" +#include "chromeos/services/device_sync/proto/cryptauth_devicesync.pb.h" +#include "chromeos/services/device_sync/proto/cryptauth_v2_test_util.h" +#include "components/prefs/testing_pref_service.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromeos { + +namespace device_sync { + +namespace { + +const cryptauthv2::ClientMetadata& GetClientMetadata() { + static const base::NoDestructor<cryptauthv2::ClientMetadata> client_metadata( + cryptauthv2::BuildClientMetadata(0 /* retry_count */, + cryptauthv2::ClientMetadata::PERIODIC)); + return *client_metadata; +} + +const cryptauthv2::RequestContext& GetRequestContext() { + static const base::NoDestructor<cryptauthv2::RequestContext> request_context( + [] { + return cryptauthv2::BuildRequestContext( + CryptAuthKeyBundle::KeyBundleNameEnumToString( + CryptAuthKeyBundle::Name::kDeviceSyncBetterTogether), + GetClientMetadata(), + cryptauthv2::GetClientAppMetadataForTest().instance_id(), + cryptauthv2::GetClientAppMetadataForTest().instance_id_token()); + }()); + return *request_context; +} + +const CryptAuthKey& GetGroupKey() { + static const base::NoDestructor<CryptAuthKey> group_key([] { + return CryptAuthKey( + kGroupPublicKey, GetPrivateKeyFromPublicKeyForTest(kGroupPublicKey), + CryptAuthKey::Status::kActive, cryptauthv2::KeyType::P256); + }()); + return *group_key; +} + +const CryptAuthKey& GetStaleGroupKey() { + static const base::NoDestructor<CryptAuthKey> stale_group_key([] { + const char kStaleGroupPublicKey[] = "stale_group_public_key"; + return CryptAuthKey(kStaleGroupPublicKey, + GetPrivateKeyFromPublicKeyForTest(kStaleGroupPublicKey), + CryptAuthKey::Status::kActive, + cryptauthv2::KeyType::P256); + }()); + return *stale_group_key; +} + +const CryptAuthKey& GetGroupKeyWithoutPrivateKey() { + static const base::NoDestructor<CryptAuthKey> group_key([] { + return CryptAuthKey(kGroupPublicKey, std::string() /* private_key */, + CryptAuthKey::Status::kActive, + cryptauthv2::KeyType::P256); + }()); + return *group_key; +} + +} // namespace + +class DeviceSyncCryptAuthDeviceSyncerImplTest : public testing::Test { + protected: + DeviceSyncCryptAuthDeviceSyncerImplTest() + : client_factory_(std::make_unique<MockCryptAuthClientFactory>( + MockCryptAuthClientFactory::MockType::MAKE_NICE_MOCKS)), + fake_cryptauth_ecies_encryptor_factory_( + std::make_unique<FakeCryptAuthEciesEncryptorFactory>()), + fake_cryptauth_metadata_syncer_factory_( + std::make_unique<FakeCryptAuthMetadataSyncerFactory>()), + fake_cryptauth_feature_status_getter_factory_( + std::make_unique<FakeCryptAuthFeatureStatusGetterFactory>()), + fake_cryptauth_group_private_key_sharer_factory_( + std::make_unique<FakeCryptAuthGroupPrivateKeySharerFactory>()) { + CryptAuthKeyRegistryImpl::RegisterPrefs(pref_service_.registry()); + key_registry_ = + CryptAuthKeyRegistryImpl::Factory::Get()->BuildInstance(&pref_service_); + + CryptAuthDeviceRegistryImpl::RegisterPrefs(pref_service_.registry()); + device_registry_ = + CryptAuthDeviceRegistryImpl::Factory::Get()->BuildInstance( + &pref_service_); + } + + ~DeviceSyncCryptAuthDeviceSyncerImplTest() override = default; + + // testing::Test: + void SetUp() override { + CryptAuthEciesEncryptorImpl::Factory::SetFactoryForTesting( + fake_cryptauth_ecies_encryptor_factory_.get()); + CryptAuthMetadataSyncerImpl::Factory::SetFactoryForTesting( + fake_cryptauth_metadata_syncer_factory_.get()); + CryptAuthFeatureStatusGetterImpl::Factory::SetFactoryForTesting( + fake_cryptauth_feature_status_getter_factory_.get()); + CryptAuthGroupPrivateKeySharerImpl::Factory::SetFactoryForTesting( + fake_cryptauth_group_private_key_sharer_factory_.get()); + + auto mock_timer = std::make_unique<base::MockOneShotTimer>(); + timer_ = mock_timer.get(); + + syncer_ = CryptAuthDeviceSyncerImpl::Factory::Get()->BuildInstance( + device_registry_.get(), key_registry_.get(), client_factory_.get(), + std::move(mock_timer)); + + std::string local_user_public_key = + GetLocalDeviceForTest().better_together_device_metadata->public_key(); + key_registry_->AddKey( + CryptAuthKeyBundle::Name::kUserKeyPair, + CryptAuthKey(local_user_public_key, + GetPrivateKeyFromPublicKeyForTest(local_user_public_key), + CryptAuthKey::Status::kActive, cryptauthv2::KeyType::P256, + kCryptAuthFixedUserKeyPairHandle)); + + std::string local_beto_public_key = + GetLocalDeviceForTest().device_better_together_public_key; + key_registry_->AddKey( + CryptAuthKeyBundle::Name::kDeviceSyncBetterTogether, + CryptAuthKey(local_beto_public_key, + GetPrivateKeyFromPublicKeyForTest(local_beto_public_key), + CryptAuthKey::Status::kActive, cryptauthv2::KeyType::P256, + base::nullopt /* handle */)); + } + + // testing::Test: + void TearDown() override { + CryptAuthEciesEncryptorImpl::Factory::SetFactoryForTesting(nullptr); + CryptAuthMetadataSyncerImpl::Factory::SetFactoryForTesting(nullptr); + CryptAuthFeatureStatusGetterImpl::Factory::SetFactoryForTesting(nullptr); + CryptAuthGroupPrivateKeySharerImpl::Factory::SetFactoryForTesting(nullptr); + } + + void CallSync() { + syncer_->Sync( + GetClientMetadata(), cryptauthv2::GetClientAppMetadataForTest(), + base::BindOnce( + &DeviceSyncCryptAuthDeviceSyncerImplTest::OnDeviceSyncComplete, + base::Unretained(this))); + } + + void AddInitialGroupKeyToRegistry(const CryptAuthKey& group_key) { + key_registry_->AddKey( + CryptAuthKeyBundle::Name::kDeviceSyncBetterTogetherGroupKey, group_key); + + VerifyGroupKeyInRegistry(group_key); + } + + void VerifyGroupKeyInRegistry(const CryptAuthKey& group_key) { + const CryptAuthKeyBundle* bundle = key_registry_->GetKeyBundle( + CryptAuthKeyBundle::Name::kDeviceSyncBetterTogetherGroupKey); + + ASSERT_TRUE(bundle); + EXPECT_EQ(1u, bundle->handle_to_key_map().size()); + EXPECT_EQ(group_key, *bundle->GetActiveKey()); + } + + void VerifyMetadataSyncerInput( + const CryptAuthKey* expected_initial_group_key) { + EXPECT_EQ(client_factory_.get(), + fake_cryptauth_metadata_syncer_factory_->last_client_factory()); + ASSERT_EQ(1u, fake_cryptauth_metadata_syncer_factory_->instances().size()); + ASSERT_TRUE(metadata_syncer()->request_context()); + ASSERT_TRUE(metadata_syncer()->local_device_metadata()); + ASSERT_TRUE(metadata_syncer()->initial_group_key()); + + EXPECT_EQ(GetRequestContext().SerializeAsString(), + metadata_syncer()->request_context()->SerializeAsString()); + EXPECT_EQ(GetLocalDeviceForTest() + .better_together_device_metadata->SerializeAsString(), + metadata_syncer()->local_device_metadata()->SerializeAsString()); + ASSERT_EQ(expected_initial_group_key == nullptr, + metadata_syncer()->initial_group_key().value() == nullptr); + if (expected_initial_group_key) { + EXPECT_EQ(*expected_initial_group_key, + *metadata_syncer()->initial_group_key().value()); + } + } + + void FinishMetadataSyncerAttempt( + const std::vector<cryptauthv2::DeviceMetadataPacket>& metadata_packets, + const base::Optional<CryptAuthKey>& new_group_key, + const base::Optional<std::string>& encrypted_group_private_key, + const base::Optional<cryptauthv2::ClientDirective> new_client_directive, + const CryptAuthDeviceSyncResult::ResultCode& device_sync_result_code) { + CryptAuthMetadataSyncer::IdToDeviceMetadataPacketMap + id_to_device_metadata_packet_map; + for (const cryptauthv2::DeviceMetadataPacket& packet : metadata_packets) { + id_to_device_metadata_packet_map.insert_or_assign(packet.device_id(), + packet); + } + + base::Optional<cryptauthv2::EncryptedGroupPrivateKey> private_key; + if (encrypted_group_private_key) { + private_key = cryptauthv2::EncryptedGroupPrivateKey(); + private_key->set_encrypted_private_key(*encrypted_group_private_key); + } + std::unique_ptr<CryptAuthKey> new_group_key_ptr = + new_group_key ? std::make_unique<CryptAuthKey>(*new_group_key) + : nullptr; + metadata_syncer()->FinishAttempt( + id_to_device_metadata_packet_map, std::move(new_group_key_ptr), + private_key, + CryptAuthDeviceSyncResult(device_sync_result_code, + false /* did_device_registry_change */, + new_client_directive)); + } + + void VerifyFeatureStatusGetterInput( + const base::flat_set<std::string>& expected_device_ids) { + EXPECT_EQ( + client_factory_.get(), + fake_cryptauth_feature_status_getter_factory_->last_client_factory()); + ASSERT_EQ( + 1u, fake_cryptauth_feature_status_getter_factory_->instances().size()); + ASSERT_TRUE(feature_status_getter()->request_context()); + ASSERT_TRUE(feature_status_getter()->device_ids()); + + EXPECT_EQ(GetRequestContext().SerializeAsString(), + feature_status_getter()->request_context()->SerializeAsString()); + EXPECT_EQ(expected_device_ids, *feature_status_getter()->device_ids()); + } + + void FinishFeatureStatusGetterAttempt( + const base::flat_set<std::string>& device_ids, + const CryptAuthDeviceSyncResult::ResultCode& device_sync_result_code) { + CryptAuthFeatureStatusGetter::IdToFeatureStatusMap id_to_feature_status_map; + for (const std::string& id : device_ids) { + id_to_feature_status_map.insert_or_assign( + id, GetTestDeviceWithId(id).feature_states); + } + + feature_status_getter()->FinishAttempt(id_to_feature_status_map, + device_sync_result_code); + } + + void RunGroupPrivateKeyDecryptor( + const std::string& expected_encrypted_group_private_key, + bool succeed) { + ASSERT_TRUE(encryptor()); + ASSERT_EQ(1u, encryptor()->id_to_input_map().size()); + + const auto it = encryptor()->id_to_input_map().begin(); + EXPECT_EQ(expected_encrypted_group_private_key, it->second.payload); + + std::string local_beto_private_key = GetPrivateKeyFromPublicKeyForTest( + GetLocalDeviceForTest().device_better_together_public_key); + EXPECT_EQ(local_beto_private_key, it->second.key); + + base::Optional<std::string> decrypted_key; + if (succeed) { + decrypted_key = + DecryptFakeEncryptedString(it->second.payload, it->second.key); + } + + encryptor()->FinishAttempt(FakeCryptAuthEciesEncryptor::Action::kDecryption, + {{it->first, decrypted_key}}); + } + + // Fail decryption for IDs in |device_ids_to_fail|. + void RunDeviceMetadataDecryptor( + const std::vector<cryptauthv2::DeviceMetadataPacket>& + expected_device_metadata_packets, + const std::string& expected_unencrypted_group_private_key, + const base::flat_set<std::string>& device_ids_to_fail) { + ASSERT_TRUE(encryptor()); + + CryptAuthEciesEncryptor::IdToInputMap id_to_encrypted_metadata_map; + CryptAuthEciesEncryptor::IdToOutputMap id_to_unencrypted_metadata_map; + for (const cryptauthv2::DeviceMetadataPacket metadata : + expected_device_metadata_packets) { + id_to_encrypted_metadata_map[metadata.device_id()] = + CryptAuthEciesEncryptor::PayloadAndKey( + metadata.encrypted_metadata(), + expected_unencrypted_group_private_key); + + id_to_unencrypted_metadata_map[metadata.device_id()] = + base::Contains(device_ids_to_fail, metadata.device_id()) + ? base::nullopt + : base::make_optional<std::string>(DecryptFakeEncryptedString( + metadata.encrypted_metadata(), + expected_unencrypted_group_private_key)); + } + + EXPECT_EQ(id_to_encrypted_metadata_map, encryptor()->id_to_input_map()); + + encryptor()->FinishAttempt(FakeCryptAuthEciesEncryptor::Action::kDecryption, + id_to_unencrypted_metadata_map); + } + + void VerifyGroupPrivateKeySharerInput( + const CryptAuthKey& expected_group_key, + const base::flat_set<std::string>& expected_device_ids) { + EXPECT_EQ(client_factory_.get(), + fake_cryptauth_group_private_key_sharer_factory_ + ->last_client_factory()); + ASSERT_EQ( + 1u, + fake_cryptauth_group_private_key_sharer_factory_->instances().size()); + ASSERT_TRUE(group_private_key_sharer()->request_context()); + ASSERT_TRUE(group_private_key_sharer()->group_key()); + + EXPECT_EQ( + GetRequestContext().SerializeAsString(), + group_private_key_sharer()->request_context()->SerializeAsString()); + EXPECT_EQ(expected_group_key, *group_private_key_sharer()->group_key()); + + CryptAuthGroupPrivateKeySharer::IdToEncryptingKeyMap + expected_id_to_encrypting_key_map; + for (const std::string& id : expected_device_ids) { + expected_id_to_encrypting_key_map.insert_or_assign( + id, GetTestDeviceWithId(id).device_better_together_public_key); + } + EXPECT_EQ(expected_id_to_encrypting_key_map, + *group_private_key_sharer()->id_to_encrypting_key_map()); + } + + void FinishShareGroupPrivateKeyAttempt( + const CryptAuthDeviceSyncResult::ResultCode& device_sync_result_code) { + group_private_key_sharer()->FinishAttempt(device_sync_result_code); + } + + void VerifyDeviceSyncResult( + const CryptAuthDeviceSyncResult& expected_result, + const std::vector<CryptAuthDevice>& expected_devices_in_registry) { + ASSERT_TRUE(device_sync_result_); + EXPECT_EQ(expected_result, *device_sync_result_); + + CryptAuthDeviceRegistry::InstanceIdToDeviceMap expected_registry; + for (const CryptAuthDevice& device : expected_devices_in_registry) { + expected_registry.insert_or_assign(device.instance_id(), device); + } + EXPECT_EQ(expected_registry, device_registry_->instance_id_to_device_map()); + } + + CryptAuthKeyRegistry* key_registry() { return key_registry_.get(); } + + base::MockOneShotTimer* timer() { return timer_; } + + private: + FakeCryptAuthEciesEncryptor* encryptor() { + return fake_cryptauth_ecies_encryptor_factory_->instance(); + } + + FakeCryptAuthMetadataSyncer* metadata_syncer() { + return fake_cryptauth_metadata_syncer_factory_->instances().back(); + } + + FakeCryptAuthFeatureStatusGetter* feature_status_getter() { + return fake_cryptauth_feature_status_getter_factory_->instances().back(); + } + + FakeCryptAuthGroupPrivateKeySharer* group_private_key_sharer() { + return fake_cryptauth_group_private_key_sharer_factory_->instances().back(); + } + + void OnDeviceSyncComplete( + const CryptAuthDeviceSyncResult& device_sync_result) { + device_sync_result_ = device_sync_result; + } + + std::unique_ptr<MockCryptAuthClientFactory> client_factory_; + std::unique_ptr<FakeCryptAuthEciesEncryptorFactory> + fake_cryptauth_ecies_encryptor_factory_; + std::unique_ptr<FakeCryptAuthMetadataSyncerFactory> + fake_cryptauth_metadata_syncer_factory_; + std::unique_ptr<FakeCryptAuthFeatureStatusGetterFactory> + fake_cryptauth_feature_status_getter_factory_; + std::unique_ptr<FakeCryptAuthGroupPrivateKeySharerFactory> + fake_cryptauth_group_private_key_sharer_factory_; + + TestingPrefServiceSimple pref_service_; + std::unique_ptr<CryptAuthKeyRegistry> key_registry_; + std::unique_ptr<CryptAuthDeviceRegistry> device_registry_; + base::MockOneShotTimer* timer_; + + base::Optional<CryptAuthDeviceSyncResult> device_sync_result_; + + std::unique_ptr<CryptAuthDeviceSyncer> syncer_; + + DISALLOW_COPY_AND_ASSIGN(DeviceSyncCryptAuthDeviceSyncerImplTest); +}; + +TEST_F(DeviceSyncCryptAuthDeviceSyncerImplTest, + Success_FirstDeviceInDeviceSyncGroup) { + CallSync(); + + // Because the local device is the first device joining the group, there is no + // group key yet. Also, no encrypted group private key is not returned but we + // already have the unencrypted group private key. + VerifyMetadataSyncerInput(nullptr /* expected_initial_group_key */); + FinishMetadataSyncerAttempt({GetLocalDeviceMetadataPacketForTest()}, + GetGroupKey() /* new_group_key */, + base::nullopt /* encrypted_group_private_key */, + cryptauthv2::GetClientDirectiveForTest(), + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyGroupKeyInRegistry(GetGroupKey()); + + base::flat_set<std::string> device_ids = { + GetLocalDeviceForTest().instance_id()}; + VerifyFeatureStatusGetterInput(device_ids); + FinishFeatureStatusGetterAttempt( + device_ids, CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + // Skip right to metadata decryption since an encrypted group private key was + // not provided in the SyncMetadata response but we have the unencrypted group + // private key in the key registry. + RunDeviceMetadataDecryptor({GetLocalDeviceMetadataPacketForTest()}, + GetGroupKey().private_key(), + {} /* device_ids_to_fail */); + + VerifyGroupPrivateKeySharerInput(GetGroupKey(), device_ids); + FinishShareGroupPrivateKeyAttempt( + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyDeviceSyncResult( + CryptAuthDeviceSyncResult(CryptAuthDeviceSyncResult::ResultCode::kSuccess, + true /* device_registry_changed */, + cryptauthv2::GetClientDirectiveForTest()), + {GetLocalDeviceForTest()}); +} + +TEST_F(DeviceSyncCryptAuthDeviceSyncerImplTest, Success_InitialGroupKeyValid) { + // Add the correct group key to the registry. + AddInitialGroupKeyToRegistry(GetGroupKey()); + + CallSync(); + + std::string encrypted_group_private_key = MakeFakeEncryptedString( + GetGroupKey().private_key(), + GetLocalDeviceForTest().device_better_together_public_key); + + // The initial group key is valid, so a new group key was not created. + VerifyMetadataSyncerInput(&GetGroupKey()); + FinishMetadataSyncerAttempt( + GetAllTestDeviceMetadataPackets(), base::nullopt /* new_group_key */, + encrypted_group_private_key, cryptauthv2::GetClientDirectiveForTest(), + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyGroupKeyInRegistry(GetGroupKey()); + + VerifyFeatureStatusGetterInput(GetAllTestDeviceIds()); + FinishFeatureStatusGetterAttempt( + GetAllTestDeviceIds(), CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + // Even though we have the unencrypted group private key in the key registry, + // we decrypt the group private key from CryptAuth and check consistency. + RunGroupPrivateKeyDecryptor(encrypted_group_private_key, true /* succeed */); + + RunDeviceMetadataDecryptor(GetAllTestDeviceMetadataPackets(), + GetGroupKey().private_key(), + {} /* device_ids_to_fail */); + + VerifyGroupPrivateKeySharerInput( + GetGroupKey(), GetAllTestDeviceIdsThatNeedGroupPrivateKey()); + FinishShareGroupPrivateKeyAttempt( + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyDeviceSyncResult( + CryptAuthDeviceSyncResult(CryptAuthDeviceSyncResult::ResultCode::kSuccess, + true /* device_registry_changed */, + cryptauthv2::GetClientDirectiveForTest()), + GetAllTestDevices()); +} + +TEST_F(DeviceSyncCryptAuthDeviceSyncerImplTest, + Success_InitialGroupPublicKeyValid_NeedGroupPrivateKey) { + // Add the correct group public key to the registry. Note that we still need + // the group private key from CryptAuth. + AddInitialGroupKeyToRegistry(GetGroupKeyWithoutPrivateKey()); + + CallSync(); + + std::string encrypted_group_private_key = MakeFakeEncryptedString( + GetGroupKey().private_key(), + GetLocalDeviceForTest().device_better_together_public_key); + + // The initial group public key is valid, so a new group key was not created; + // however, we now receive the group private key from CryptAuth. + VerifyMetadataSyncerInput(&GetGroupKeyWithoutPrivateKey()); + FinishMetadataSyncerAttempt( + GetAllTestDeviceMetadataPackets(), base::nullopt /* new_group_key */, + encrypted_group_private_key, cryptauthv2::GetClientDirectiveForTest(), + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyGroupKeyInRegistry(GetGroupKeyWithoutPrivateKey()); + + VerifyFeatureStatusGetterInput(GetAllTestDeviceIds()); + FinishFeatureStatusGetterAttempt( + GetAllTestDeviceIds(), CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + // The new group private key received from CryptAuth is decrypted, bundled + // with the existing group public key, and added to the key registry. + RunGroupPrivateKeyDecryptor(encrypted_group_private_key, true /* succeed */); + VerifyGroupKeyInRegistry(GetGroupKey()); + + // Since we now have the decrypted group private key, device metadata can be + // decrypted. + RunDeviceMetadataDecryptor(GetAllTestDeviceMetadataPackets(), + GetGroupKey().private_key(), + {} /* device_ids_to_fail */); + + VerifyGroupPrivateKeySharerInput( + GetGroupKey(), GetAllTestDeviceIdsThatNeedGroupPrivateKey()); + FinishShareGroupPrivateKeyAttempt( + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyDeviceSyncResult( + CryptAuthDeviceSyncResult(CryptAuthDeviceSyncResult::ResultCode::kSuccess, + true /* device_registry_changed */, + cryptauthv2::GetClientDirectiveForTest()), + GetAllTestDevices()); +} + +TEST_F(DeviceSyncCryptAuthDeviceSyncerImplTest, + Success_InitialGroupKeyStale_CreateNewGroupKey) { + AddInitialGroupKeyToRegistry(GetStaleGroupKey()); + + CallSync(); + + // The initial group key is stale, so CryptAuth instructs us to create the new + // group key. No encrypted private key is returned but we own the unencrypted + // group private key. + VerifyMetadataSyncerInput(&GetStaleGroupKey()); + FinishMetadataSyncerAttempt(GetAllTestDeviceMetadataPackets(), + GetGroupKey() /* new_group_key */, + base::nullopt /* encrypted_group_private_key */, + cryptauthv2::GetClientDirectiveForTest(), + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyGroupKeyInRegistry(GetGroupKey()); + + VerifyFeatureStatusGetterInput(GetAllTestDeviceIds()); + FinishFeatureStatusGetterAttempt( + GetAllTestDeviceIds(), CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + // Decrypt metadata since we own the group private key. + RunDeviceMetadataDecryptor(GetAllTestDeviceMetadataPackets(), + GetGroupKey().private_key(), + {} /* device_ids_to_fail */); + + VerifyGroupPrivateKeySharerInput( + GetGroupKey(), GetAllTestDeviceIdsThatNeedGroupPrivateKey()); + FinishShareGroupPrivateKeyAttempt( + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyDeviceSyncResult( + CryptAuthDeviceSyncResult(CryptAuthDeviceSyncResult::ResultCode::kSuccess, + true /* device_registry_changed */, + cryptauthv2::GetClientDirectiveForTest()), + GetAllTestDevices()); +} + +TEST_F( + DeviceSyncCryptAuthDeviceSyncerImplTest, + Success_InitialGroupKeyStale_GetNewGroupPublicKeyFromCryptAuth_WithGroupPrivateKey) { + AddInitialGroupKeyToRegistry(GetStaleGroupKey()); + + CallSync(); + + std::string encrypted_group_private_key = MakeFakeEncryptedString( + GetGroupKey().private_key(), + GetLocalDeviceForTest().device_better_together_public_key); + + // The initial group key is stale, so CryptAuth provides us with the new + // unencrypted group public key and encrypted group private key. + VerifyMetadataSyncerInput(&GetStaleGroupKey()); + FinishMetadataSyncerAttempt( + GetAllTestDeviceMetadataPackets(), + GetGroupKeyWithoutPrivateKey() /* new_group_key */, + encrypted_group_private_key, cryptauthv2::GetClientDirectiveForTest(), + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + // The group private key will be added after it is decrypted. + VerifyGroupKeyInRegistry(GetGroupKeyWithoutPrivateKey()); + + VerifyFeatureStatusGetterInput(GetAllTestDeviceIds()); + FinishFeatureStatusGetterAttempt( + GetAllTestDeviceIds(), CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + RunGroupPrivateKeyDecryptor(encrypted_group_private_key, true /* succeed */); + VerifyGroupKeyInRegistry(GetGroupKey()); + + RunDeviceMetadataDecryptor(GetAllTestDeviceMetadataPackets(), + GetGroupKey().private_key(), + {} /* device_ids_to_fail */); + + VerifyGroupPrivateKeySharerInput( + GetGroupKey(), GetAllTestDeviceIdsThatNeedGroupPrivateKey()); + FinishShareGroupPrivateKeyAttempt( + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyDeviceSyncResult( + CryptAuthDeviceSyncResult(CryptAuthDeviceSyncResult::ResultCode::kSuccess, + true /* device_registry_changed */, + cryptauthv2::GetClientDirectiveForTest()), + GetAllTestDevices()); +} + +TEST_F( + DeviceSyncCryptAuthDeviceSyncerImplTest, + Success_InitialGroupKeyStale_GetNewGroupPublicKeyFromCryptAuth_WithoutGroupPrivateKey) { + AddInitialGroupKeyToRegistry(GetStaleGroupKey()); + + CallSync(); + + // The initial group key is stale, so CryptAuth provides us with the new + // unencrypted group public key but no encrypted group private key. This can + // happen if the other devices have not shared their encrypted group private + // key with CryptAuth yet. + VerifyMetadataSyncerInput(&GetStaleGroupKey()); + FinishMetadataSyncerAttempt( + GetAllTestDeviceMetadataPackets(), + GetGroupKeyWithoutPrivateKey() /* new_group_key */, + base::nullopt /* encrypted_group_private_key */, + cryptauthv2::GetClientDirectiveForTest(), + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyGroupKeyInRegistry(GetGroupKeyWithoutPrivateKey()); + + VerifyFeatureStatusGetterInput(GetAllTestDeviceIds()); + FinishFeatureStatusGetterAttempt( + GetAllTestDeviceIds(), CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + // Only the local device has its BetterTogetherDeviceMetadata in the device + // registry since the other metadata cannot be decrypted without the group + // private key. + VerifyDeviceSyncResult( + CryptAuthDeviceSyncResult(CryptAuthDeviceSyncResult::ResultCode::kSuccess, + true /* device_registry_changed */, + cryptauthv2::GetClientDirectiveForTest()), + GetAllTestDevicesWithoutRemoteMetadata()); +} + +TEST_F(DeviceSyncCryptAuthDeviceSyncerImplTest, + NonFatalError_FromMetadataSyncer) { + AddInitialGroupKeyToRegistry(GetGroupKey()); + + CallSync(); + + // Say the remote device metadata was invalid and not returned. Aside from the + // result code, everything continues as if only the local device was in the + // DeviceSync group. + VerifyMetadataSyncerInput(&GetGroupKey()); + FinishMetadataSyncerAttempt( + {GetLocalDeviceMetadataPacketForTest()}, + base::nullopt /* new_group_key */, + base::nullopt /* encrypted_group_private_key */, + cryptauthv2::GetClientDirectiveForTest(), + CryptAuthDeviceSyncResult::ResultCode::kFinishedWithNonFatalErrors); + + base::flat_set<std::string> device_ids = { + GetLocalDeviceForTest().instance_id()}; + VerifyFeatureStatusGetterInput(device_ids); + FinishFeatureStatusGetterAttempt( + device_ids, CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + RunDeviceMetadataDecryptor({GetLocalDeviceMetadataPacketForTest()}, + GetGroupKey().private_key(), + {} /* device_ids_to_fail */); + + VerifyGroupPrivateKeySharerInput(GetGroupKey(), device_ids); + FinishShareGroupPrivateKeyAttempt( + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyDeviceSyncResult( + CryptAuthDeviceSyncResult( + CryptAuthDeviceSyncResult::ResultCode::kFinishedWithNonFatalErrors, + true /* device_registry_changed */, + cryptauthv2::GetClientDirectiveForTest()), + {GetLocalDeviceForTest()}); +} + +TEST_F(DeviceSyncCryptAuthDeviceSyncerImplTest, + NonFatalError_FromFeatureStatusGetter_MissingDeviceFeatureStatuses) { + AddInitialGroupKeyToRegistry(GetGroupKey()); + + CallSync(); + + VerifyMetadataSyncerInput(&GetGroupKey()); + FinishMetadataSyncerAttempt(GetAllTestDeviceMetadataPackets(), + base::nullopt /* new_group_key */, + base::nullopt /* encrypted_group_private_key */, + cryptauthv2::GetClientDirectiveForTest(), + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + // The feature statuses are missing for a remote device, so it will not be + // added to the registry. + VerifyFeatureStatusGetterInput(GetAllTestDeviceIds()); + FinishFeatureStatusGetterAttempt( + {GetLocalDeviceForTest().instance_id(), + GetRemoteDeviceHasGroupPrivateKeyForTest().instance_id()}, + CryptAuthDeviceSyncResult::ResultCode::kFinishedWithNonFatalErrors); + + RunDeviceMetadataDecryptor( + {GetLocalDeviceMetadataPacketForTest(), + GetRemoteDeviceMetadataPacketHasGroupPrivateKeyForTest()}, + GetGroupKey().private_key(), {} /* device_ids_to_fail */); + + VerifyGroupPrivateKeySharerInput( + GetGroupKey(), GetAllTestDeviceIdsThatNeedGroupPrivateKey()); + FinishShareGroupPrivateKeyAttempt( + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyDeviceSyncResult( + CryptAuthDeviceSyncResult( + CryptAuthDeviceSyncResult::ResultCode::kFinishedWithNonFatalErrors, + true /* device_registry_changed */, + cryptauthv2::GetClientDirectiveForTest()), + {GetLocalDeviceForTest(), GetRemoteDeviceHasGroupPrivateKeyForTest()}); +} + +TEST_F(DeviceSyncCryptAuthDeviceSyncerImplTest, + NonFatalError_GroupPrivateKeyDisagreement) { + AddInitialGroupKeyToRegistry(GetGroupKey()); + + CallSync(); + + VerifyMetadataSyncerInput(&GetGroupKey()); + + // CryptAuth's group public key agrees with our local storage but the group + // private key differs. We continue using our local group private key and hope + // for the best. + std::string wrong_encrypted_group_private_key = MakeFakeEncryptedString( + GetStaleGroupKey().private_key(), + GetLocalDeviceForTest().device_better_together_public_key); + FinishMetadataSyncerAttempt(GetAllTestDeviceMetadataPackets(), + base::nullopt /* new_group_key */, + wrong_encrypted_group_private_key, + cryptauthv2::GetClientDirectiveForTest(), + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyFeatureStatusGetterInput(GetAllTestDeviceIds()); + FinishFeatureStatusGetterAttempt( + GetAllTestDeviceIds(), CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + RunGroupPrivateKeyDecryptor(wrong_encrypted_group_private_key, + true /* succeed */); + VerifyGroupKeyInRegistry(GetGroupKey()); + + RunDeviceMetadataDecryptor(GetAllTestDeviceMetadataPackets(), + GetGroupKey().private_key(), + {} /* device_ids_to_fail */); + + VerifyGroupPrivateKeySharerInput( + GetGroupKey(), GetAllTestDeviceIdsThatNeedGroupPrivateKey()); + FinishShareGroupPrivateKeyAttempt( + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyDeviceSyncResult( + CryptAuthDeviceSyncResult( + CryptAuthDeviceSyncResult::ResultCode::kFinishedWithNonFatalErrors, + true /* device_registry_changed */, + cryptauthv2::GetClientDirectiveForTest()), + GetAllTestDevices()); +} + +TEST_F(DeviceSyncCryptAuthDeviceSyncerImplTest, + NonFatalError_MetadataDecryptionFailed) { + AddInitialGroupKeyToRegistry(GetGroupKey()); + + CallSync(); + + VerifyMetadataSyncerInput(&GetGroupKey()); + FinishMetadataSyncerAttempt(GetAllTestDeviceMetadataPackets(), + base::nullopt /* new_group_key */, + base::nullopt /* encrypted_group_private_key */, + cryptauthv2::GetClientDirectiveForTest(), + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyFeatureStatusGetterInput(GetAllTestDeviceIds()); + FinishFeatureStatusGetterAttempt( + GetAllTestDeviceIds(), CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + // Fail metadata decryption. + RunDeviceMetadataDecryptor(GetAllTestDeviceMetadataPackets(), + GetGroupKey().private_key(), + GetAllTestDeviceIds() /* device_ids_to_fail */); + + VerifyGroupPrivateKeySharerInput( + GetGroupKey(), GetAllTestDeviceIdsThatNeedGroupPrivateKey()); + FinishShareGroupPrivateKeyAttempt( + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyDeviceSyncResult( + CryptAuthDeviceSyncResult( + CryptAuthDeviceSyncResult::ResultCode::kFinishedWithNonFatalErrors, + true /* device_registry_changed */, + cryptauthv2::GetClientDirectiveForTest()), + GetAllTestDevicesWithoutRemoteMetadata()); +} + +TEST_F(DeviceSyncCryptAuthDeviceSyncerImplTest, + NonFatalError_MetadataParsingFailed) { + AddInitialGroupKeyToRegistry(GetGroupKey()); + + CallSync(); + + VerifyMetadataSyncerInput(&GetGroupKey()); + + // Replace the serialized BetterTogetherDeviceMetadata protos with a string + // that cannot be interpreted as a proto, resulting in a parsing error. + std::vector<cryptauthv2::DeviceMetadataPacket> corrupt_metadata_packets = + GetAllTestDeviceMetadataPackets(); + for (cryptauthv2::DeviceMetadataPacket& packet : corrupt_metadata_packets) { + *packet.mutable_encrypted_metadata() = MakeFakeEncryptedString( + "Not a BetterTogetherDeviceMetadata proto", GetGroupKey().public_key()); + } + + FinishMetadataSyncerAttempt(corrupt_metadata_packets, + base::nullopt /* new_group_key */, + base::nullopt /* encrypted_group_private_key */, + cryptauthv2::GetClientDirectiveForTest(), + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyFeatureStatusGetterInput(GetAllTestDeviceIds()); + FinishFeatureStatusGetterAttempt( + GetAllTestDeviceIds(), CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + RunDeviceMetadataDecryptor(corrupt_metadata_packets, + GetGroupKey().private_key(), + {} /* device_ids_to_fail */); + + VerifyGroupPrivateKeySharerInput( + GetGroupKey(), GetAllTestDeviceIdsThatNeedGroupPrivateKey()); + FinishShareGroupPrivateKeyAttempt( + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyDeviceSyncResult( + CryptAuthDeviceSyncResult( + CryptAuthDeviceSyncResult::ResultCode::kFinishedWithNonFatalErrors, + true /* device_registry_changed */, + cryptauthv2::GetClientDirectiveForTest()), + GetAllTestDevicesWithoutRemoteMetadata()); +} + +TEST_F(DeviceSyncCryptAuthDeviceSyncerImplTest, + NonFatalError_InconsistentLocalDeviceMetadata) { + AddInitialGroupKeyToRegistry(GetGroupKey()); + + CallSync(); + + VerifyMetadataSyncerInput(&GetGroupKey()); + + // The local device's DeviceMetadataPacket from CryptAuth that differs from + // our local device metadata. The local device metadata from CryptAuth is + // never used expect for a sanity check. If the local device metadata is + // inconsistent, an error message is printed. + cryptauthv2::BetterTogetherDeviceMetadata corrupt_beto_metadata; + corrupt_beto_metadata.set_no_pii_device_name("corrupt_device_name"); + cryptauthv2::DeviceMetadataPacket corrupt_local_device_packet = + GetLocalDeviceMetadataPacketForTest(); + corrupt_local_device_packet.set_encrypted_metadata(MakeFakeEncryptedString( + corrupt_beto_metadata.SerializeAsString(), kGroupPublicKey)); + + std::vector<cryptauthv2::DeviceMetadataPacket> device_metadata_packets = { + corrupt_local_device_packet, + GetRemoteDeviceMetadataPacketNeedsGroupPrivateKeyForTest(), + GetRemoteDeviceMetadataPacketHasGroupPrivateKeyForTest()}; + FinishMetadataSyncerAttempt(device_metadata_packets, + base::nullopt /* new_group_key */, + base::nullopt /* encrypted_group_private_key */, + cryptauthv2::GetClientDirectiveForTest(), + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyFeatureStatusGetterInput(GetAllTestDeviceIds()); + FinishFeatureStatusGetterAttempt( + GetAllTestDeviceIds(), CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + RunDeviceMetadataDecryptor(device_metadata_packets, + GetGroupKey().private_key(), + {} /* device_ids_to_fail */); + + VerifyGroupPrivateKeySharerInput( + GetGroupKey(), GetAllTestDeviceIdsThatNeedGroupPrivateKey()); + FinishShareGroupPrivateKeyAttempt( + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyDeviceSyncResult( + CryptAuthDeviceSyncResult( + CryptAuthDeviceSyncResult::ResultCode::kFinishedWithNonFatalErrors, + true /* device_registry_changed */, + cryptauthv2::GetClientDirectiveForTest()), + GetAllTestDevices()); +} + +TEST_F(DeviceSyncCryptAuthDeviceSyncerImplTest, + NonFatalError_FromGroupPrivateKeySharer) { + AddInitialGroupKeyToRegistry(GetGroupKey()); + + CallSync(); + + VerifyMetadataSyncerInput(&GetGroupKey()); + FinishMetadataSyncerAttempt(GetAllTestDeviceMetadataPackets(), + base::nullopt /* new_group_key */, + base::nullopt /* encrypted_group_private_key */, + cryptauthv2::GetClientDirectiveForTest(), + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyFeatureStatusGetterInput(GetAllTestDeviceIds()); + FinishFeatureStatusGetterAttempt( + GetAllTestDeviceIds(), CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + RunDeviceMetadataDecryptor(GetAllTestDeviceMetadataPackets(), + GetGroupKey().private_key(), + {} /* device_ids_to_fail */); + + // Group private key sharer finished with non-fatal errors. This should only + // affect the final result code. + VerifyGroupPrivateKeySharerInput( + GetGroupKey(), GetAllTestDeviceIdsThatNeedGroupPrivateKey()); + FinishShareGroupPrivateKeyAttempt( + CryptAuthDeviceSyncResult::ResultCode::kFinishedWithNonFatalErrors); + + VerifyDeviceSyncResult( + CryptAuthDeviceSyncResult( + CryptAuthDeviceSyncResult::ResultCode::kFinishedWithNonFatalErrors, + true /* device_registry_changed */, + cryptauthv2::GetClientDirectiveForTest()), + GetAllTestDevices()); +} + +TEST_F(DeviceSyncCryptAuthDeviceSyncerImplTest, FatalError_MissingUserKeyPair) { + key_registry()->DeleteKey(CryptAuthKeyBundle::Name::kUserKeyPair, + kCryptAuthFixedUserKeyPairHandle); + + CallSync(); + + VerifyDeviceSyncResult( + CryptAuthDeviceSyncResult( + CryptAuthDeviceSyncResult::ResultCode::kErrorMissingUserKeyPair, + false /* device_registry_changed */, + base::nullopt /* client_directive */), + {} /* expected_devices_in_registry */); +} + +TEST_F(DeviceSyncCryptAuthDeviceSyncerImplTest, FatalError_FromMetadataSyncer) { + AddInitialGroupKeyToRegistry(GetGroupKey()); + + CallSync(); + + VerifyMetadataSyncerInput(&GetGroupKey()); + FinishMetadataSyncerAttempt({} /* metadata_packets */, + base::nullopt /* new_group_key */, + base::nullopt /* encrypted_group_private_key */, + cryptauthv2::GetClientDirectiveForTest(), + CryptAuthDeviceSyncResult::ResultCode:: + kErrorSyncMetadataApiCallBadRequest); + + VerifyDeviceSyncResult( + CryptAuthDeviceSyncResult(CryptAuthDeviceSyncResult::ResultCode:: + kErrorSyncMetadataApiCallBadRequest, + false /* device_registry_changed */, + cryptauthv2::GetClientDirectiveForTest()), + {} /* expected_device_in_registry */); +} + +TEST_F(DeviceSyncCryptAuthDeviceSyncerImplTest, + FatalError_MissingLocalDeviceFeatureStatuses) { + AddInitialGroupKeyToRegistry(GetGroupKey()); + + CallSync(); + + VerifyMetadataSyncerInput(&GetGroupKey()); + FinishMetadataSyncerAttempt(GetAllTestDeviceMetadataPackets(), + base::nullopt /* new_group_key */, + base::nullopt /* encrypted_group_private_key */, + cryptauthv2::GetClientDirectiveForTest(), + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + // The feature statuses are missing for the local device. + VerifyFeatureStatusGetterInput(GetAllTestDeviceIds()); + FinishFeatureStatusGetterAttempt( + {GetRemoteDeviceHasGroupPrivateKeyForTest().instance_id(), + GetRemoteDeviceNeedsGroupPrivateKeyForTest().instance_id()}, + CryptAuthDeviceSyncResult::ResultCode::kFinishedWithNonFatalErrors); + + VerifyDeviceSyncResult( + CryptAuthDeviceSyncResult(CryptAuthDeviceSyncResult::ResultCode:: + kErrorMissingLocalDeviceFeatureStatuses, + false /* device_registry_changed */, + cryptauthv2::GetClientDirectiveForTest()), + {} /* expected_device_in_registry */); +} + +TEST_F(DeviceSyncCryptAuthDeviceSyncerImplTest, + FatalError_FromFeatureStatusGetter) { + AddInitialGroupKeyToRegistry(GetGroupKey()); + + CallSync(); + + VerifyMetadataSyncerInput(&GetGroupKey()); + FinishMetadataSyncerAttempt(GetAllTestDeviceMetadataPackets(), + base::nullopt /* new_group_key */, + base::nullopt /* encrypted_group_private_key */, + cryptauthv2::GetClientDirectiveForTest(), + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + // The feature statuses are missing for the local device. + VerifyFeatureStatusGetterInput(GetAllTestDeviceIds()); + FinishFeatureStatusGetterAttempt( + GetAllTestDeviceIds(), + CryptAuthDeviceSyncResult::ResultCode:: + kErrorBatchGetFeatureStatusesApiCallBadRequest); + + VerifyDeviceSyncResult(CryptAuthDeviceSyncResult( + CryptAuthDeviceSyncResult::ResultCode:: + kErrorBatchGetFeatureStatusesApiCallBadRequest, + false /* device_registry_changed */, + cryptauthv2::GetClientDirectiveForTest()), + {} /* expected_device_in_registry */); +} + +TEST_F(DeviceSyncCryptAuthDeviceSyncerImplTest, + FatalError_MissingLocalDeviceSyncBetterTogetherKey) { + // Our DeviceSync:BetterTogether key is missing from the registry, so the + // group private key cannot be decrypted. + key_registry()->DeleteKey( + CryptAuthKeyBundle::Name::kDeviceSyncBetterTogether, + key_registry() + ->GetActiveKey(CryptAuthKeyBundle::Name::kDeviceSyncBetterTogether) + ->handle()); + + AddInitialGroupKeyToRegistry(GetGroupKey()); + + CallSync(); + + std::string encrypted_group_private_key = MakeFakeEncryptedString( + GetGroupKey().private_key(), + GetLocalDeviceForTest().device_better_together_public_key); + + VerifyMetadataSyncerInput(&GetGroupKey()); + FinishMetadataSyncerAttempt( + GetAllTestDeviceMetadataPackets(), base::nullopt /* new_group_key */, + encrypted_group_private_key, cryptauthv2::GetClientDirectiveForTest(), + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyFeatureStatusGetterInput(GetAllTestDeviceIds()); + FinishFeatureStatusGetterAttempt( + GetAllTestDeviceIds(), CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyDeviceSyncResult(CryptAuthDeviceSyncResult( + CryptAuthDeviceSyncResult::ResultCode:: + kErrorMissingLocalDeviceSyncBetterTogetherKey, + true /* device_registry_changed */, + cryptauthv2::GetClientDirectiveForTest()), + GetAllTestDevicesWithoutRemoteMetadata()); +} + +TEST_F(DeviceSyncCryptAuthDeviceSyncerImplTest, + FatalError_DecryptingGroupPrivateKey) { + AddInitialGroupKeyToRegistry(GetGroupKey()); + + CallSync(); + + std::string encrypted_group_private_key = MakeFakeEncryptedString( + GetGroupKey().private_key(), + GetLocalDeviceForTest().device_better_together_public_key); + + VerifyMetadataSyncerInput(&GetGroupKey()); + FinishMetadataSyncerAttempt( + GetAllTestDeviceMetadataPackets(), base::nullopt /* new_group_key */, + encrypted_group_private_key, cryptauthv2::GetClientDirectiveForTest(), + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyFeatureStatusGetterInput(GetAllTestDeviceIds()); + FinishFeatureStatusGetterAttempt( + GetAllTestDeviceIds(), CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + // Fail group private key decryption. + RunGroupPrivateKeyDecryptor(encrypted_group_private_key, false /* succeed */); + + VerifyDeviceSyncResult( + CryptAuthDeviceSyncResult(CryptAuthDeviceSyncResult::ResultCode:: + kErrorDecryptingGroupPrivateKey, + true /* device_registry_changed */, + cryptauthv2::GetClientDirectiveForTest()), + GetAllTestDevicesWithoutRemoteMetadata()); +} + +TEST_F(DeviceSyncCryptAuthDeviceSyncerImplTest, + FatalError_FromGroupPrivateKeySharer) { + AddInitialGroupKeyToRegistry(GetGroupKey()); + + CallSync(); + + VerifyMetadataSyncerInput(&GetGroupKey()); + FinishMetadataSyncerAttempt(GetAllTestDeviceMetadataPackets(), + base::nullopt /* new_group_key */, + base::nullopt /* encrypted_group_private_key */, + cryptauthv2::GetClientDirectiveForTest(), + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyFeatureStatusGetterInput(GetAllTestDeviceIds()); + FinishFeatureStatusGetterAttempt( + GetAllTestDeviceIds(), CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + RunDeviceMetadataDecryptor(GetAllTestDeviceMetadataPackets(), + GetGroupKey().private_key(), + {} /* device_ids_to_fail */); + + // Group private key sharer finished with fatal errors. This should only + // affect the final result code. + VerifyGroupPrivateKeySharerInput( + GetGroupKey(), GetAllTestDeviceIdsThatNeedGroupPrivateKey()); + FinishShareGroupPrivateKeyAttempt( + CryptAuthDeviceSyncResult::ResultCode:: + kErrorShareGroupPrivateKeyApiCallBadRequest); + + VerifyDeviceSyncResult( + CryptAuthDeviceSyncResult(CryptAuthDeviceSyncResult::ResultCode:: + kErrorShareGroupPrivateKeyApiCallBadRequest, + true /* device_registry_changed */, + cryptauthv2::GetClientDirectiveForTest()), + GetAllTestDevices()); +} + +TEST_F(DeviceSyncCryptAuthDeviceSyncerImplTest, + FatalError_Timeout_GroupPrivateKeyDecryption) { + AddInitialGroupKeyToRegistry(GetGroupKey()); + + CallSync(); + + std::string encrypted_group_private_key = MakeFakeEncryptedString( + GetGroupKey().private_key(), + GetLocalDeviceForTest().device_better_together_public_key); + + VerifyMetadataSyncerInput(&GetGroupKey()); + FinishMetadataSyncerAttempt( + GetAllTestDeviceMetadataPackets(), base::nullopt /* new_group_key */, + encrypted_group_private_key, cryptauthv2::GetClientDirectiveForTest(), + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyFeatureStatusGetterInput(GetAllTestDeviceIds()); + FinishFeatureStatusGetterAttempt( + GetAllTestDeviceIds(), CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + timer()->Fire(); + + VerifyDeviceSyncResult( + CryptAuthDeviceSyncResult( + CryptAuthDeviceSyncResult::ResultCode:: + kErrorTimeoutWaitingForGroupPrivateKeyDecryption, + true /* device_registry_changed */, + cryptauthv2::GetClientDirectiveForTest()), + GetAllTestDevicesWithoutRemoteMetadata()); +} + +TEST_F(DeviceSyncCryptAuthDeviceSyncerImplTest, + FatalError_Timeout_DeviceMetadataDecryption) { + AddInitialGroupKeyToRegistry(GetGroupKey()); + + CallSync(); + + std::string encrypted_group_private_key = MakeFakeEncryptedString( + GetGroupKey().private_key(), + GetLocalDeviceForTest().device_better_together_public_key); + + VerifyMetadataSyncerInput(&GetGroupKey()); + FinishMetadataSyncerAttempt( + GetAllTestDeviceMetadataPackets(), base::nullopt /* new_group_key */, + encrypted_group_private_key, cryptauthv2::GetClientDirectiveForTest(), + CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + VerifyFeatureStatusGetterInput(GetAllTestDeviceIds()); + FinishFeatureStatusGetterAttempt( + GetAllTestDeviceIds(), CryptAuthDeviceSyncResult::ResultCode::kSuccess); + + RunGroupPrivateKeyDecryptor(encrypted_group_private_key, true /* succeed */); + VerifyGroupKeyInRegistry(GetGroupKey()); + + timer()->Fire(); + + VerifyDeviceSyncResult( + CryptAuthDeviceSyncResult( + CryptAuthDeviceSyncResult::ResultCode:: + kErrorTimeoutWaitingForDeviceMetadataDecryption, + true /* device_registry_changed */, + cryptauthv2::GetClientDirectiveForTest()), + GetAllTestDevicesWithoutRemoteMetadata()); +} + +} // namespace device_sync + +} // namespace chromeos
diff --git a/chromeos/services/device_sync/cryptauth_v2_enrollment_manager_impl.cc b/chromeos/services/device_sync/cryptauth_v2_enrollment_manager_impl.cc index ad4c889..f1bdfc05 100644 --- a/chromeos/services/device_sync/cryptauth_v2_enrollment_manager_impl.cc +++ b/chromeos/services/device_sync/cryptauth_v2_enrollment_manager_impl.cc
@@ -53,6 +53,27 @@ kMaxValue = kYesV1KeyYesV2KeyDisagree }; +UserKeyPairState GetUserKeyPairState(const std::string& public_key_v1, + const std::string& private_key_v1, + const CryptAuthKey* key_v2) { + bool v1_key_exists = !public_key_v1.empty() && !private_key_v1.empty(); + + if (v1_key_exists && key_v2) { + if (public_key_v1 == key_v2->public_key() && + private_key_v1 == key_v2->private_key()) { + return UserKeyPairState::kYesV1KeyYesV2KeyAgree; + } else { + return UserKeyPairState::kYesV1KeyYesV2KeyDisagree; + } + } else if (v1_key_exists && !key_v2) { + return UserKeyPairState::kYesV1KeyNoV2Key; + } else if (!v1_key_exists && key_v2) { + return UserKeyPairState::kNoV1KeyYesV2Key; + } else { + return UserKeyPairState::kNoV1KeyNoV2Key; + } +} + cryptauthv2::ClientMetadata::InvocationReason ConvertInvocationReasonV1ToV2( cryptauth::InvocationReason invocation_reason_v1) { switch (invocation_reason_v1) { @@ -98,31 +119,6 @@ result.result_code()); } -void RecordUserKeyPairState(const std::string& public_key_v1, - const std::string& private_key_v1, - const CryptAuthKey* key_v2) { - bool v1_key_exists = !public_key_v1.empty() && !private_key_v1.empty(); - - UserKeyPairState key_pair_state; - if (v1_key_exists && key_v2) { - if (public_key_v1 == key_v2->public_key() && - private_key_v1 == key_v2->private_key()) { - key_pair_state = UserKeyPairState::kYesV1KeyYesV2KeyAgree; - } else { - key_pair_state = UserKeyPairState::kYesV1KeyYesV2KeyDisagree; - } - } else if (v1_key_exists && !key_v2) { - key_pair_state = UserKeyPairState::kYesV1KeyNoV2Key; - } else if (!v1_key_exists && key_v2) { - key_pair_state = UserKeyPairState::kNoV1KeyYesV2Key; - } else { - key_pair_state = UserKeyPairState::kNoV1KeyNoV2Key; - } - - base::UmaHistogramEnumeration("CryptAuth.EnrollmentV2.UserKeyPairState", - key_pair_state); -} - } // namespace // static @@ -235,6 +231,14 @@ scheduler_->StartEnrollmentScheduling( scheduler_weak_ptr_factory_.GetWeakPtr()); + // If the v1 and v2 user key pairs initially disagreed, force a re-enrollment + // with the v1 user key pair that replaced the v2 user key pair. + if (initial_v1_and_v2_user_key_pairs_disagree_) { + ForceEnrollmentNow( + cryptauth::InvocationReason::INVOCATION_REASON_INITIALIZATION, + base::nullopt /* session_id */); + } + // It is possible, though unlikely, that |scheduler_| has previously enrolled // successfully but |key_registry_| no longer holds the enrolled keys, for // example, if keys are deleted from the key registry or if the persisted key @@ -509,24 +513,31 @@ std::string private_key_v1 = GetV1UserPrivateKey(); const CryptAuthKey* key_v2 = key_registry_->GetActiveKey(CryptAuthKeyBundle::Name::kUserKeyPair); + UserKeyPairState user_key_pair_state = + GetUserKeyPairState(public_key_v1, private_key_v1, key_v2); - RecordUserKeyPairState(public_key_v1, private_key_v1, key_v2); + base::UmaHistogramEnumeration("CryptAuth.EnrollmentV2.UserKeyPairState", + user_key_pair_state); - // If the v1 user key pair does not exist, no action is needed. - if (public_key_v1.empty() || private_key_v1.empty()) - return; + initial_v1_and_v2_user_key_pairs_disagree_ = + user_key_pair_state == UserKeyPairState::kYesV1KeyYesV2KeyDisagree; - // If the v1 and v2 user key pairs already agree, no action is needed. - if (key_v2 && key_v2->public_key() == public_key_v1 && - key_v2->private_key() == private_key_v1) { - return; - } - - key_registry_->AddKey( - CryptAuthKeyBundle::Name::kUserKeyPair, - CryptAuthKey(public_key_v1, private_key_v1, CryptAuthKey::Status::kActive, - cryptauthv2::KeyType::P256, - kCryptAuthFixedUserKeyPairHandle)); + switch (user_key_pair_state) { + case (UserKeyPairState::kNoV1KeyNoV2Key): + FALLTHROUGH; + case (UserKeyPairState::kNoV1KeyYesV2Key): + FALLTHROUGH; + case (UserKeyPairState::kYesV1KeyYesV2KeyAgree): + return; + case (UserKeyPairState::kYesV1KeyNoV2Key): + FALLTHROUGH; + case (UserKeyPairState::kYesV1KeyYesV2KeyDisagree): + key_registry_->AddKey(CryptAuthKeyBundle::Name::kUserKeyPair, + CryptAuthKey(public_key_v1, private_key_v1, + CryptAuthKey::Status::kActive, + cryptauthv2::KeyType::P256, + kCryptAuthFixedUserKeyPairHandle)); + }; } std::ostream& operator<<(std::ostream& stream,
diff --git a/chromeos/services/device_sync/cryptauth_v2_enrollment_manager_impl.h b/chromeos/services/device_sync/cryptauth_v2_enrollment_manager_impl.h index 357d5389..93306e1 100644 --- a/chromeos/services/device_sync/cryptauth_v2_enrollment_manager_impl.h +++ b/chromeos/services/device_sync/cryptauth_v2_enrollment_manager_impl.h
@@ -167,6 +167,7 @@ base::Clock* clock_; std::unique_ptr<base::OneShotTimer> timer_; + bool initial_v1_and_v2_user_key_pairs_disagree_ = false; State state_ = State::kIdle; base::Optional<cryptauthv2::ClientMetadata> current_client_metadata_; base::Optional<cryptauthv2::PolicyReference>
diff --git a/chromeos/services/device_sync/cryptauth_v2_enrollment_manager_impl_unittest.cc b/chromeos/services/device_sync/cryptauth_v2_enrollment_manager_impl_unittest.cc index 842eb5d6..cf15423b 100644 --- a/chromeos/services/device_sync/cryptauth_v2_enrollment_manager_impl_unittest.cc +++ b/chromeos/services/device_sync/cryptauth_v2_enrollment_manager_impl_unittest.cc
@@ -727,6 +727,24 @@ enrollment_manager()->GetUserPublicKey()); EXPECT_EQ(expected_user_key_pair_v1.private_key(), enrollment_manager()->GetUserPrivateKey()); + + // Expect re-enrollment using newly added v1 key. + enrollment_manager()->Start(); + cryptauthv2::ClientMetadata expected_client_metadata = + cryptauthv2::BuildClientMetadata( + 0 /* retry_count */, cryptauthv2::ClientMetadata::INITIALIZATION, + base::nullopt /* session_id */); + CryptAuthEnrollmentResult expected_enrollment_result( + CryptAuthEnrollmentResult::ResultCode::kSuccessNewKeysEnrolled, + base::nullopt /* client_directive */); + CompleteGcmRegistration(true /* success */); + HandleGetClientAppMetadataRequest(true /* success */); + FinishEnrollmentAttempt(0u /* expected_enroller_instance_index */, + expected_client_metadata, expected_enrollment_result); + + VerifyInvocationReasonHistogram( + {expected_client_metadata.invocation_reason()}); + VerifyEnrollmentResults({expected_enrollment_result}); } TEST_F(DeviceSyncCryptAuthV2EnrollmentManagerImplTest,
diff --git a/chromeos/services/device_sync/public/cpp/BUILD.gn b/chromeos/services/device_sync/public/cpp/BUILD.gn index 6d76454..87d5152e 100644 --- a/chromeos/services/device_sync/public/cpp/BUILD.gn +++ b/chromeos/services/device_sync/public/cpp/BUILD.gn
@@ -6,6 +6,8 @@ sources = [ "client_app_metadata_provider.h", "cryptauth_device_id_provider.h", + "cryptauth_instance_id_provider.cc", + "cryptauth_instance_id_provider.h", "device_sync_client.cc", "device_sync_client.h", "device_sync_client_impl.cc", @@ -34,6 +36,8 @@ sources = [ "fake_client_app_metadata_provider.cc", "fake_client_app_metadata_provider.h", + "fake_cryptauth_instance_id_provider.cc", + "fake_cryptauth_instance_id_provider.h", "fake_device_sync_client.cc", "fake_device_sync_client.h", "fake_gcm_device_info_provider.cc",
diff --git a/chromeos/services/device_sync/public/cpp/cryptauth_instance_id_provider.cc b/chromeos/services/device_sync/public/cpp/cryptauth_instance_id_provider.cc new file mode 100644 index 0000000..a9e9a5e --- /dev/null +++ b/chromeos/services/device_sync/public/cpp/cryptauth_instance_id_provider.cc
@@ -0,0 +1,32 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/services/device_sync/public/cpp/cryptauth_instance_id_provider.h" + +namespace chromeos { + +namespace device_sync { + +CryptAuthInstanceIdProvider::CryptAuthInstanceIdProvider() = default; + +CryptAuthInstanceIdProvider::~CryptAuthInstanceIdProvider() = default; + +std::ostream& operator<<( + std::ostream& stream, + const CryptAuthInstanceIdProvider::CryptAuthService cryptauth_service) { + switch (cryptauth_service) { + case CryptAuthInstanceIdProvider::CryptAuthService::kEnrollmentV2: + stream << "[CryptAuth service: Enrollment v2]"; + break; + case CryptAuthInstanceIdProvider::CryptAuthService::kDeviceSyncV2: + stream << "[CryptAuth service: DeviceSync v2]"; + break; + } + + return stream; +} + +} // namespace device_sync + +} // namespace chromeos
diff --git a/chromeos/services/device_sync/public/cpp/cryptauth_instance_id_provider.h b/chromeos/services/device_sync/public/cpp/cryptauth_instance_id_provider.h new file mode 100644 index 0000000..fd77b74 --- /dev/null +++ b/chromeos/services/device_sync/public/cpp/cryptauth_instance_id_provider.h
@@ -0,0 +1,60 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_SERVICES_DEVICE_SYNC_PUBLIC_CPP_CRYPTAUTH_INSTANCE_ID_PROVIDER_H_ +#define CHROMEOS_SERVICES_DEVICE_SYNC_PUBLIC_CPP_CRYPTAUTH_INSTANCE_ID_PROVIDER_H_ + +#include <ostream> + +#include "base/callback_forward.h" +#include "base/macros.h" +#include "base/optional.h" + +namespace chromeos { + +namespace device_sync { + +// Provides the user with a unique and immutable GCM Instance ID for use across +// CryptAuth v2 services. Provides unique and immutable Instance ID tokens for +// each CryptAuth v2 service: Enrollment and DeviceSync. +class CryptAuthInstanceIdProvider { + public: + enum class CryptAuthService { kEnrollmentV2, kDeviceSyncV2 }; + + CryptAuthInstanceIdProvider(); + virtual ~CryptAuthInstanceIdProvider(); + + using GetInstanceIdCallback = + base::OnceCallback<void(const base::Optional<std::string>&)>; + using GetInstanceIdTokenCallback = + base::OnceCallback<void(const base::Optional<std::string>&)>; + + // Provides the user with a unique and immutable GCM Instance ID for use + // across CryptAuth v2 services; if the operation fails, null is passed to the + // callback. + virtual void GetInstanceId(GetInstanceIdCallback callback) = 0; + + // Provides the user with a unique and immutable GCM Instance ID token + // corresponding to the CryptAuth service, |cryptauth_service|; if the + // operation fails, null is passed to the callback. + // + // By retrieving a token for a given service, we implicitly authorize that + // service to send us GCM push notifications; the token is the identifier of + // that registration. + virtual void GetInstanceIdToken(CryptAuthService cryptauth_service, + GetInstanceIdTokenCallback callback) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(CryptAuthInstanceIdProvider); +}; + +std::ostream& operator<<( + std::ostream& stream, + const CryptAuthInstanceIdProvider::CryptAuthService cryptauth_service); + +} // namespace device_sync + +} // namespace chromeos + +#endif // CHROMEOS_SERVICES_DEVICE_SYNC_PUBLIC_CPP_CRYPTAUTH_INSTANCE_ID_PROVIDER_H_
diff --git a/chromeos/services/device_sync/public/cpp/fake_cryptauth_instance_id_provider.cc b/chromeos/services/device_sync/public/cpp/fake_cryptauth_instance_id_provider.cc new file mode 100644 index 0000000..0659d9d --- /dev/null +++ b/chromeos/services/device_sync/public/cpp/fake_cryptauth_instance_id_provider.cc
@@ -0,0 +1,29 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/services/device_sync/public/cpp/fake_cryptauth_instance_id_provider.h" + +namespace chromeos { + +namespace device_sync { + +FakeCryptAuthInstanceIdProvider::FakeCryptAuthInstanceIdProvider() = default; + +FakeCryptAuthInstanceIdProvider::~FakeCryptAuthInstanceIdProvider() = default; + +void FakeCryptAuthInstanceIdProvider::GetInstanceId( + GetInstanceIdCallback callback) { + instance_id_callbacks_.push_back(std::move(callback)); +} + +void FakeCryptAuthInstanceIdProvider::GetInstanceIdToken( + CryptAuthService cryptauth_service, + GetInstanceIdTokenCallback callback) { + instance_id_token_callbacks_[cryptauth_service].push_back( + std::move(callback)); +} + +} // namespace device_sync + +} // namespace chromeos
diff --git a/chromeos/services/device_sync/public/cpp/fake_cryptauth_instance_id_provider.h b/chromeos/services/device_sync/public/cpp/fake_cryptauth_instance_id_provider.h new file mode 100644 index 0000000..ced49d65 --- /dev/null +++ b/chromeos/services/device_sync/public/cpp/fake_cryptauth_instance_id_provider.h
@@ -0,0 +1,62 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_SERVICES_DEVICE_SYNC_PUBLIC_CPP_FAKE_CRYPTAUTH_INSTANCE_ID_PROVIDER_H_ +#define CHROMEOS_SERVICES_DEVICE_SYNC_PUBLIC_CPP_FAKE_CRYPTAUTH_INSTANCE_ID_PROVIDER_H_ + +#include <vector> + +#include "base/callback.h" +#include "base/containers/flat_map.h" +#include "base/macros.h" +#include "chromeos/services/device_sync/public/cpp/cryptauth_instance_id_provider.h" + +namespace chromeos { + +namespace device_sync { + +// Implementation of CryptAuthInstanceIdProvider for use in tests. +class FakeCryptAuthInstanceIdProvider : public CryptAuthInstanceIdProvider { + public: + FakeCryptAuthInstanceIdProvider(); + ~FakeCryptAuthInstanceIdProvider() override; + + // CryptAuthInstanceIdProvider: + void GetInstanceId(GetInstanceIdCallback callback) override; + void GetInstanceIdToken(CryptAuthService cryptauth_service, + GetInstanceIdTokenCallback callback) override; + + // Returns the array of callbacks sent to GetInstanceId(), ordered from first + // call to last call. Because this array is returned by reference, the client + // can invoke the callback of the i-th call using the following: + // + // std::move(instance_id_callbacks()[i]).Run(...) + std::vector<GetInstanceIdCallback>& instance_id_callbacks() { + return instance_id_callbacks_; + } + + // Returns the array of callbacks sent to GetInstanceIdToken() for the + // given |cryptauth_service|, ordered from first call to last call. Because + // this array is returned by reference, the client can invoke the callback of + // the i-th call using the following: + // + // std::move(instance_id_token_callbacks(<CryptAuthService>)[i]).Run(...) + std::vector<GetInstanceIdTokenCallback>& instance_id_token_callbacks( + const CryptAuthService& cryptauth_service) { + return instance_id_token_callbacks_[cryptauth_service]; + } + + private: + std::vector<GetInstanceIdCallback> instance_id_callbacks_; + base::flat_map<CryptAuthService, std::vector<GetInstanceIdTokenCallback>> + instance_id_token_callbacks_; + + DISALLOW_COPY_AND_ASSIGN(FakeCryptAuthInstanceIdProvider); +}; + +} // namespace device_sync + +} // namespace chromeos + +#endif // CHROMEOS_SERVICES_DEVICE_SYNC_PUBLIC_CPP_FAKE_CRYPTAUTH_INSTANCE_ID_PROVIDER_H_
diff --git a/chromeos/services/device_sync/public/cpp/gcm_constants.cc b/chromeos/services/device_sync/public/cpp/gcm_constants.cc index 39f8fcc..5b805144f 100644 --- a/chromeos/services/device_sync/public/cpp/gcm_constants.cc +++ b/chromeos/services/device_sync/public/cpp/gcm_constants.cc
@@ -10,7 +10,8 @@ const char kCryptAuthGcmAppId[] = "com.google.chrome.cryptauth"; const char kCryptAuthGcmSenderId[] = "381449029288"; -const char kCryptAuthGcmInstanceIdAuthorizedEntity[] = "16502139086"; +const char kCryptAuthV2EnrollmentAuthorizedEntity[] = "16502139086"; +const char kCryptAuthV2DeviceSyncAuthorizedEntity[] = "302798585788"; } // namespace device_sync
diff --git a/chromeos/services/device_sync/public/cpp/gcm_constants.h b/chromeos/services/device_sync/public/cpp/gcm_constants.h index e4ec664..85ac4234 100644 --- a/chromeos/services/device_sync/public/cpp/gcm_constants.h +++ b/chromeos/services/device_sync/public/cpp/gcm_constants.h
@@ -12,7 +12,8 @@ // ID constants used in GCM for CryptAuth-related calls. extern const char kCryptAuthGcmAppId[]; extern const char kCryptAuthGcmSenderId[]; -extern const char kCryptAuthGcmInstanceIdAuthorizedEntity[]; +extern const char kCryptAuthV2EnrollmentAuthorizedEntity[]; +extern const char kCryptAuthV2DeviceSyncAuthorizedEntity[]; } // namespace device_sync
diff --git a/chromeos/services/multidevice_setup/public/mojom/BUILD.gn b/chromeos/services/multidevice_setup/public/mojom/BUILD.gn index 157fbcb..1cfee24 100644 --- a/chromeos/services/multidevice_setup/public/mojom/BUILD.gn +++ b/chromeos/services/multidevice_setup/public/mojom/BUILD.gn
@@ -13,7 +13,4 @@ public_deps = [ "//chromeos/services/device_sync/public/mojom", ] - - # TODO(https://crbug.com/968369): Change to use new names. - use_old_js_lite_bindings_names = true }
diff --git a/components/autofill/core/common/autofill_payments_features.cc b/components/autofill/core/common/autofill_payments_features.cc index cd6984b..bd755582 100644 --- a/components/autofill/core/common/autofill_payments_features.cc +++ b/components/autofill/core/common/autofill_payments_features.cc
@@ -112,6 +112,10 @@ "AutofillSendExperimentIdsInPaymentsRPCs", base::FEATURE_ENABLED_BY_DEFAULT}; +// Controls whether to show updated UI for the card unmask prompt. +const base::Feature kAutofillUpdatedCardUnmaskPromptUi{ + "AutofillUpdatedCardUnmaskPromptUi", base::FEATURE_DISABLED_BY_DEFAULT}; + // Controls offering credit card upload to Google Payments. Cannot ever be // ENABLED_BY_DEFAULT because it's a country-specific whitelist. There are // countries we simply can't turn this on for, and they change over time, so
diff --git a/components/autofill/core/common/autofill_payments_features.h b/components/autofill/core/common/autofill_payments_features.h index b07d5a8..d30388e 100644 --- a/components/autofill/core/common/autofill_payments_features.h +++ b/components/autofill/core/common/autofill_payments_features.h
@@ -34,6 +34,7 @@ extern const base::Feature kAutofillSaveCardShowNoThanks; extern const base::Feature kAutofillSaveCreditCardUsesImprovedMessaging; extern const base::Feature kAutofillSendExperimentIdsInPaymentsRPCs; +extern const base::Feature kAutofillUpdatedCardUnmaskPromptUi; extern const base::Feature kAutofillUpstream; extern const base::Feature kAutofillUpstreamAllowAllEmailDomains; extern const base::Feature kAutofillUpstreamAlwaysRequestCardholderName;
diff --git a/components/autofill_payments_strings.grdp b/components/autofill_payments_strings.grdp index b50d29c..11764da8 100644 --- a/components/autofill_payments_strings.grdp +++ b/components/autofill_payments_strings.grdp
@@ -307,6 +307,9 @@ <message name="IDS_AUTOFILL_CARD_UNMASK_PROMPT_ERROR_TRY_AGAIN_CVC" desc="Error message that encourages the user to try to re-enter their credit card CVC after a previous failed attempt." formatter_data="android_java"> Check your CVC and try again </message> + <message name="IDS_AUTOFILL_CARD_UNMASK_PROMPT_ERROR_TRY_AGAIN_CVC_AND_EXPIRATION_V2" desc="Error message that encourages the user to try to re-enter their credit card CVC or update the expiration dates after a previous failed attempt, according to August 2019 UI guidelines."> + Check your CVC and try again or update the expiration date + </message> <if expr="is_android"> <message name="IDS_AUTOFILL_CARD_UNMASK_PROMPT_ERROR_TRY_AGAIN_EXPIRATION_DATE" desc="Error message that encourages the user to try to re-enter their credit card expiration date after a previous failed attempt." formatter_data="android_java"> Check your expiration date and try again @@ -331,6 +334,9 @@ <message name="IDS_AUTOFILL_CARD_UNMASK_PROMPT_TITLE" desc="Title for the credit card unmasking dialog."> Enter the CVC for <ph name="CREDIT_CARD">$1<ex>Visa - 5679</ex></ph> </message> + <message name="IDS_AUTOFILL_CARD_UNMASK_PROMPT_TITLE_V2" desc="Title for the credit card unmasking dialog, according to August 2019 UI guidelines."> + Verify your card + </message> <message name="IDS_AUTOFILL_CARD_UNMASK_PROMPT_EXPIRED_TITLE" desc="Title for the credit card unmasking dialog when the credit card is expired."> Enter the expiration date and CVC for <ph name="CREDIT_CARD">$1<ex>Visa - 5679</ex></ph> </message> @@ -340,6 +346,9 @@ <message name="IDS_AUTOFILL_CARD_UNMASK_PROMPT_INSTRUCTIONS_LOCAL_CARD" desc="Text explaining what the user should do in the card unmasking dialog. Appears specifically for local cards already stored on the device."> Once you confirm, your card details will be shared with this site. </message> + <message name="IDS_AUTOFILL_CARD_UNMASK_PROMPT_INSTRUCTIONS_V2" desc="Text explaining what the user should do in the card unmasking dialog, according to August 2019 UI guidelines."> + Confirm the security code to share your card details with this site + </message> <message name="IDS_AUTOFILL_CARD_UNMASK_CVC_IMAGE_DESCRIPTION" desc="Accessible description for the CVC image. It should describe where to find the CVC on a credit card."> The CVC is located behind your card. </message> @@ -391,6 +400,9 @@ <message name="IDS_AUTOFILL_CARD_UNMASK_CONFIRM_BUTTON" desc="Text for button that confirms the credit card CVC entry dialog."> Confirm </message> + <message name="IDS_AUTOFILL_CARD_UNMASK_VERIFY_BUTTON" desc="Label text for the ok button in the credit card CVC entry dialog."> + Verify + </message> <message name="IDS_AUTOFILL_CARD_UNMASK_EXPIRATION_MONTH" desc="Accessible name for card expiry month field."> Month </message>
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc index 337738c1..d52e242 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc
@@ -28,7 +28,6 @@ #include "components/data_reduction_proxy/proto/data_store.pb.h" #include "components/data_use_measurement/core/data_use_measurement.h" #include "components/prefs/pref_service.h" -#include "services/network/public/cpp/features.h" namespace data_reduction_proxy { @@ -70,8 +69,7 @@ } network_quality_tracker_->AddEffectiveConnectionTypeObserver(this); network_quality_tracker_->AddRTTAndThroughputEstimatesObserver(this); - if (base::FeatureList::IsEnabled(network::features::kNetworkService) && - data_use_measurement_) { // null in unit tests. + if (data_use_measurement_) { // null in unit tests. data_use_measurement_->AddServicesDataUseObserver(this); } @@ -90,8 +88,7 @@ network_connection_tracker_->RemoveNetworkConnectionObserver(this); compression_stats_.reset(); db_task_runner_->DeleteSoon(FROM_HERE, db_data_owner_.release()); - if (base::FeatureList::IsEnabled(network::features::kNetworkService) && - data_use_measurement_) { // null in unit tests. + if (data_use_measurement_) { // null in unit tests. data_use_measurement_->RemoveServicesDataUseObserver(this); } } @@ -384,7 +381,6 @@ if (compression_stats_) { // Record non-content initiated traffic to the Other bucket for data saver // site-breakdown. - DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService)); compression_stats_->RecordDataUseByHost( util::GetSiteBreakdownOtherHostName(), sent_bytes, sent_bytes, base::Time::Now());
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc index a0b22172..b8024f1 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc
@@ -24,7 +24,6 @@ #include "components/prefs/pref_service.h" #include "net/base/network_change_notifier.h" #include "net/http/http_request_headers.h" -#include "services/network/public/cpp/features.h" namespace { @@ -142,8 +141,7 @@ } bool DataReductionProxySettings::IsDataReductionProxyEnabled() const { - if (base::FeatureList::IsEnabled(network::features::kNetworkService) && - !params::IsEnabledWithNetworkService()) { + if (!params::IsEnabledWithNetworkService()) { return false; } return IsDataSaverEnabledByUser(GetOriginalProfilePrefs());
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc index 0d05569a..ef5e55f 100644 --- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc +++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc
@@ -22,7 +22,6 @@ #include "net/base/host_port_pair.h" #include "net/base/proxy_server.h" #include "net/http/http_status_code.h" -#include "services/network/public/cpp/features.h" #include "url/url_constants.h" #if defined(OS_ANDROID) @@ -364,9 +363,8 @@ bool IsEnabledWithNetworkService() { return base::FeatureList::IsEnabled( - data_reduction_proxy::features:: - kDataReductionProxyEnabledWithNetworkService) && - base::FeatureList::IsEnabled(network::features::kNetworkService); + data_reduction_proxy::features:: + kDataReductionProxyEnabledWithNetworkService); } base::Optional<DataReductionProxyTypeInfo> FindConfiguredProxyInVector(
diff --git a/components/previews/core/previews_experiments.cc b/components/previews/core/previews_experiments.cc index 57c76ad6..8f026c2f 100644 --- a/components/previews/core/previews_experiments.cc +++ b/components/previews/core/previews_experiments.cc
@@ -48,7 +48,6 @@ const char kNoScriptInflationPercent[] = "NoScriptInflationPercent"; const char kNoScriptInflationBytes[] = "NoScriptInflationBytes"; - // Inflation parameters for estimating ResourceLoadingHints data savings. const char kResourceLoadingHintsInflationPercent[] = "ResourceLoadingHintsInflationPercent"; @@ -228,6 +227,20 @@ true); } +bool LitePageRedirectOnlyTriggerOnSuccessfulProbe() { + return base::GetFieldTrialParamByFeatureAsBool( + features::kLitePageServerPreviews, "only_trigger_after_probe_success", + true); +} + +GURL LitePageRedirectProbeURL() { + GURL url(GetFieldTrialParamValueByFeature(features::kLitePageServerPreviews, + "full_probe_url")); + if (url.is_valid()) + return url; + return GURL("https://litepages.googlezip.net/e2e_probe"); +} + base::TimeDelta LitePageRedirectPreviewPresolveInterval() { return base::TimeDelta::FromSeconds(base::GetFieldTrialParamByFeatureAsInt( features::kLitePageServerPreviews, "preresolve_interval_in_seconds", 60));
diff --git a/components/previews/core/previews_experiments.h b/components/previews/core/previews_experiments.h index 44b6659d..2c291914 100644 --- a/components/previews/core/previews_experiments.h +++ b/components/previews/core/previews_experiments.h
@@ -138,6 +138,15 @@ // Whether we should preresolve the lite page redirect server. bool LitePageRedirectPreviewShouldPresolve(); +// Whether to only trigger a lite page preview if there has been a successful +// probe to the server. This is returns true, lite page redirect previews should +// only been attempted when a probe to the previews server has completed +// successfully. +bool LitePageRedirectOnlyTriggerOnSuccessfulProbe(); + +// The URL to probe on the lite pages server. +GURL LitePageRedirectProbeURL(); + // The duration in between preresolving the lite page redirect server. base::TimeDelta LitePageRedirectPreviewPresolveInterval();
diff --git a/components/search_engines/prepopulated_engines.json b/components/search_engines/prepopulated_engines.json index 3dedb8c..d834782 100644 --- a/components/search_engines/prepopulated_engines.json +++ b/components/search_engines/prepopulated_engines.json
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This file is used during build to generate prepopulated_engine.h/cc. +// This file is used during build to generate prepopulated_engines.h/cc. // For more details see tools/json_to_struct/json_to_struct.py. // Engine definitions. See prepopulated_engines_schema.json for the field
diff --git a/components/search_engines/prepopulated_engines_schema.json b/components/search_engines/prepopulated_engines_schema.json index 6977360..c46435e 100644 --- a/components/search_engines/prepopulated_engines_schema.json +++ b/components/search_engines/prepopulated_engines_schema.json
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This file is used by json_to_struct.py to generate prepopulated_engine.h/cc. +// This file is used by json_to_struct.py to generate prepopulated_engines.h/cc. // Any time you modify this file regenerate the .h/.cc. See // prepopulated_engines.json for details.
diff --git a/components/translate/content/renderer/translate_helper.cc b/components/translate/content/renderer/translate_helper.cc index 85701f0..2974dcf 100644 --- a/components/translate/content/renderer/translate_helper.cc +++ b/components/translate/content/renderer/translate_helper.cc
@@ -25,7 +25,6 @@ #include "content/public/common/url_constants.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_thread.h" -#include "services/network/public/cpp/features.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/common/loader/url_loader_factory_bundle.h" #include "third_party/blink/public/platform/web_isolated_world_info.h" @@ -292,10 +291,8 @@ url::Origin translate_origin = url::Origin::Create(GetTranslateSecurityOrigin()); - if (base::FeatureList::IsEnabled(network::features::kNetworkService)) { - render_frame()->MarkInitiatorAsRequiringSeparateURLLoaderFactory( - translate_origin, std::move(loader_factory_for_translate_script)); - } + render_frame()->MarkInitiatorAsRequiringSeparateURLLoaderFactory( + translate_origin, std::move(loader_factory_for_translate_script)); WebLocalFrame* main_frame = render_frame()->GetWebFrame(); if (!main_frame) {
diff --git a/components/url_formatter/OWNERS b/components/url_formatter/OWNERS index 6e9e161..a7cab0a 100644 --- a/components/url_formatter/OWNERS +++ b/components/url_formatter/OWNERS
@@ -1,5 +1,6 @@ pkasting@chromium.org tommycli@chromium.org +meacer@chromium.org # Changes to FormatUrlForSecurityDisplay and FormatOriginForSecurityDisplay # require a security review to avoid introducing security bugs.
diff --git a/components/url_formatter/spoof_checks/OWNERS b/components/url_formatter/spoof_checks/OWNERS deleted file mode 100644 index 6771584..0000000 --- a/components/url_formatter/spoof_checks/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -meacer@chromium.org
diff --git a/components/url_formatter/spoof_checks/idn_spoof_checker.cc b/components/url_formatter/spoof_checks/idn_spoof_checker.cc index de326f80..6caf88b 100644 --- a/components/url_formatter/spoof_checks/idn_spoof_checker.cc +++ b/components/url_formatter/spoof_checks/idn_spoof_checker.cc
@@ -79,7 +79,7 @@ return *dangerous_pattern_tls; } -#include "components/url_formatter/spoof_checks/top_domains/alexa_domains-trie-inc.cc" +#include "components/url_formatter/spoof_checks/top_domains/domains-trie-inc.cc" // All the domains in the above file have 3 or fewer labels. const size_t kNumberOfLabelsToCheck = 3;
diff --git a/components/url_formatter/spoof_checks/top_domains/BUILD.gn b/components/url_formatter/spoof_checks/top_domains/BUILD.gn index 5a77d0f1..e5ac5ee9 100644 --- a/components/url_formatter/spoof_checks/top_domains/BUILD.gn +++ b/components/url_formatter/spoof_checks/top_domains/BUILD.gn
@@ -40,11 +40,11 @@ # Inputs in order expected by the command line of the tool. inputs = [ - "//components/url_formatter/spoof_checks/top_domains/alexa_domains.skeletons", + "//components/url_formatter/spoof_checks/top_domains/domains.skeletons", "//components/url_formatter/spoof_checks/top_domains/top_domains_trie.template", ] outputs = [ - "$target_gen_dir/alexa_domains-trie-inc.cc", + "$target_gen_dir/domains-trie-inc.cc", ] args = rebase_path(inputs, root_build_dir) + rebase_path(outputs, root_build_dir) @@ -113,7 +113,7 @@ # Inputs in order expected by the command line of the tool. inputs = [ - "//components/url_formatter/spoof_checks/top_domains/alexa_domains.list", + "//components/url_formatter/spoof_checks/top_domains/domains.list", ] outputs = [ "$target_gen_dir/top500-domains-inc.cc",
diff --git a/components/url_formatter/spoof_checks/top_domains/alexa_domains.list b/components/url_formatter/spoof_checks/top_domains/domains.list similarity index 100% rename from components/url_formatter/spoof_checks/top_domains/alexa_domains.list rename to components/url_formatter/spoof_checks/top_domains/domains.list
diff --git a/components/url_formatter/spoof_checks/top_domains/alexa_domains.skeletons b/components/url_formatter/spoof_checks/top_domains/domains.skeletons similarity index 100% rename from components/url_formatter/spoof_checks/top_domains/alexa_domains.skeletons rename to components/url_formatter/spoof_checks/top_domains/domains.skeletons
diff --git a/components/url_formatter/spoof_checks/top_domains/make_top_domain_skeletons.cc b/components/url_formatter/spoof_checks/top_domains/make_top_domain_skeletons.cc index 978b207..dd0d6dd 100644 --- a/components/url_formatter/spoof_checks/top_domains/make_top_domain_skeletons.cc +++ b/components/url_formatter/spoof_checks/top_domains/make_top_domain_skeletons.cc
@@ -126,8 +126,7 @@ << u_errorName(status) << ".\n"; return 1; } - GenerateSkeletons("alexa_domains.list", "alexa_domains.skeletons", - spoof_checker.get()); + GenerateSkeletons("domains.list", "domains.skeletons", spoof_checker.get()); GenerateSkeletons("test_domains.list", "test_domains.skeletons", spoof_checker.get()); }
diff --git a/components/viz/common/frame_sinks/begin_frame_source.cc b/components/viz/common/frame_sinks/begin_frame_source.cc index 9470de7..af269c7 100644 --- a/components/viz/common/frame_sinks/begin_frame_source.cc +++ b/components/viz/common/frame_sinks/begin_frame_source.cc
@@ -140,9 +140,12 @@ switch (gpu_busy_response_state_) { case GpuBusyThrottlingState::kIdle: + if (allow_one_begin_frame_after_gpu_busy_) { gpu_busy_response_state_ = GpuBusyThrottlingState::kOneBeginFrameAfterBusySent; return false; + } + FALLTHROUGH; case GpuBusyThrottlingState::kOneBeginFrameAfterBusySent: gpu_busy_response_state_ = GpuBusyThrottlingState::kThrottled; return true;
diff --git a/components/viz/common/frame_sinks/begin_frame_source.h b/components/viz/common/frame_sinks/begin_frame_source.h index 0eb5691..5db623e 100644 --- a/components/viz/common/frame_sinks/begin_frame_source.h +++ b/components/viz/common/frame_sinks/begin_frame_source.h
@@ -159,6 +159,11 @@ virtual void AsValueInto(base::trace_event::TracedValue* state) const; + void AllowOneBeginFrameAfterGpuBusy() { + DCHECK(!is_gpu_busy_); + allow_one_begin_frame_after_gpu_busy_ = true; + } + protected: // Returns whether begin-frames to clients should be withheld (because the gpu // is still busy, for example). If this returns true, then OnGpuNoLongerBusy() @@ -192,6 +197,8 @@ GpuBusyThrottlingState gpu_busy_response_state_ = GpuBusyThrottlingState::kIdle; + bool allow_one_begin_frame_after_gpu_busy_ = false; + DISALLOW_COPY_AND_ASSIGN(BeginFrameSource); };
diff --git a/components/viz/service/display/display_scheduler_unittest.cc b/components/viz/service/display/display_scheduler_unittest.cc index 41ed7146..f0cd9bd1 100644 --- a/components/viz/service/display/display_scheduler_unittest.cc +++ b/components/viz/service/display/display_scheduler_unittest.cc
@@ -796,6 +796,8 @@ } TEST_F(DisplaySchedulerTest, GpuBusyNotifications) { + fake_begin_frame_source_.AllowOneBeginFrameAfterGpuBusy(); + SurfaceId root_surface_id( kArbitraryFrameSinkId, LocalSurfaceId(1, base::UnguessableToken::Create()));
diff --git a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc index 8342db8..f457d18 100644 --- a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc +++ b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
@@ -78,6 +78,10 @@ external_begin_frame_source = std::make_unique<ExternalBeginFrameSourceAndroid>(restart_id, params->refresh_rate); + if (output_surface->context_provider() && + output_surface->context_provider()->ContextCapabilities().surfaceless) { + external_begin_frame_source->AllowOneBeginFrameAfterGpuBusy(); + } #else if (params->disable_frame_rate_limit) { synthetic_begin_frame_source =
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index c27531e..ace93cb 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -208,7 +208,6 @@ "//third_party/webrtc/modules/desktop_capture:primitives", "//third_party/webrtc/rtc_base:rtc_base", "//third_party/zlib", - "//third_party/zlib/google:compression_utils", "//third_party/zlib/google:zip", "//ui/accessibility", "//ui/accessibility:ax_enums_mojo", @@ -688,15 +687,12 @@ "devtools/devtools_http_handler.h", "devtools/devtools_instrumentation.cc", "devtools/devtools_instrumentation.h", - "devtools/devtools_interceptor_controller.cc", - "devtools/devtools_interceptor_controller.h", "devtools/devtools_io_context.cc", "devtools/devtools_io_context.h", "devtools/devtools_manager.cc", "devtools/devtools_manager.h", "devtools/devtools_network_interceptor.cc", "devtools/devtools_network_interceptor.h", - "devtools/devtools_network_transaction_factory.cc", "devtools/devtools_pipe_handler.cc", "devtools/devtools_pipe_handler.h", "devtools/devtools_protocol_encoding.cc", @@ -711,8 +707,6 @@ "devtools/devtools_stream_file.h", "devtools/devtools_stream_pipe.cc", "devtools/devtools_stream_pipe.h", - "devtools/devtools_target_registry.cc", - "devtools/devtools_target_registry.h", "devtools/devtools_traceable_screenshot.cc", "devtools/devtools_traceable_screenshot.h", "devtools/devtools_url_loader_interceptor.cc", @@ -1744,6 +1738,8 @@ "service_worker/service_worker_unregister_job.h", "service_worker/service_worker_update_checker.cc", "service_worker/service_worker_update_checker.h", + "service_worker/service_worker_updated_script_loader.cc", + "service_worker/service_worker_updated_script_loader.h", "service_worker/service_worker_version.cc", "service_worker/service_worker_version.h", "site_instance_impl.cc",
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm index 657b6941..241f5a41 100644 --- a/content/browser/accessibility/browser_accessibility_cocoa.mm +++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -115,13 +115,91 @@ NSString* const NSAccessibilityLineTextMarkerRangeForTextMarkerParameterizedAttribute = @"AXLineTextMarkerRangeForTextMarker"; -NSString* const NSAccessibilitySelectTextWithCriteriaParameterizedAttribute = - @"AXSelectTextWithCriteria"; +// TODO(nektar): Implement programmatic text operations. +// +// NSString* const NSAccessibilityTextOperationMarkerRanges = +// @"AXTextOperationMarkerRanges"; +NSString* const NSAccessibilityUIElementForTextMarkerParameterizedAttribute = + @"AXUIElementForTextMarker"; +NSString* const + NSAccessibilityTextMarkerRangeForUIElementParameterizedAttribute = + @"AXTextMarkerRangeForUIElement"; +NSString* const NSAccessibilityLineForTextMarkerParameterizedAttribute = + @"AXLineForTextMarker"; +NSString* const NSAccessibilityTextMarkerRangeForLineParameterizedAttribute = + @"AXTextMarkerRangeForLine"; +NSString* const NSAccessibilityStringForTextMarkerRangeParameterizedAttribute = + @"AXStringForTextMarkerRange"; +NSString* const NSAccessibilityTextMarkerForPositionParameterizedAttribute = + @"AXTextMarkerForPosition"; NSString* const NSAccessibilityBoundsForTextMarkerRangeParameterizedAttribute = @"AXBoundsForTextMarkerRange"; NSString* const + NSAccessibilityAttributedStringForTextMarkerRangeParameterizedAttribute = + @"AXAttributedStringForTextMarkerRange"; +NSString* const + NSAccessibilityAttributedStringForTextMarkerRangeWithOptionsParameterizedAttribute = + @"AXAttributedStringForTextMarkerRangeWithOptions"; +NSString* const NSAccessibilityTextMarkerRangeForUnorderedTextMarkersParameterizedAttribute = @"AXTextMarkerRangeForUnorderedTextMarkers"; +NSString* const + NSAccessibilityNextTextMarkerForTextMarkerParameterizedAttribute = + @"AXNextTextMarkerForTextMarker"; +NSString* const + NSAccessibilityPreviousTextMarkerForTextMarkerParameterizedAttribute = + @"AXPreviousTextMarkerForTextMarker"; +NSString* const + NSAccessibilityLeftWordTextMarkerRangeForTextMarkerParameterizedAttribute = + @"AXLeftWordTextMarkerRangeForTextMarker"; +NSString* const + NSAccessibilityRightWordTextMarkerRangeForTextMarkerParameterizedAttribute = + @"AXRightWordTextMarkerRangeForTextMarker"; +NSString* const + NSAccessibilityLeftLineTextMarkerRangeForTextMarkerParameterizedAttribute = + @"AXLeftLineTextMarkerRangeForTextMarker"; +NSString* const + NSAccessibilityRightLineTextMarkerRangeForTextMarkerParameterizedAttribute = + @"AXRightLineTextMarkerRangeForTextMarker"; +NSString* const + NSAccessibilitySentenceTextMarkerRangeForTextMarkerParameterizedAttribute = + @"AXSentenceTextMarkerRangeForTextMarker"; +NSString* const + NSAccessibilityParagraphTextMarkerRangeForTextMarkerParameterizedAttribute = + @"AXParagraphTextMarkerRangeForTextMarker"; +NSString* const + NSAccessibilityNextWordEndTextMarkerForTextMarkerParameterizedAttribute = + @"AXNextWordEndTextMarkerForTextMarker"; +NSString* const + NSAccessibilityPreviousWordStartTextMarkerForTextMarkerParameterizedAttribute = + @"AXPreviousWordStartTextMarkerForTextMarker"; +NSString* const + NSAccessibilityNextLineEndTextMarkerForTextMarkerParameterizedAttribute = + @"AXNextLineEndTextMarkerForTextMarker"; +NSString* const + NSAccessibilityPreviousLineStartTextMarkerForTextMarkerParameterizedAttribute = + @"AXPreviousLineStartTextMarkerForTextMarker"; +NSString* const + NSAccessibilityNextSentenceEndTextMarkerForTextMarkerParameterizedAttribute = + @"AXNextSentenceEndTextMarkerForTextMarker"; +NSString* const + NSAccessibilityPreviousSentenceStartTextMarkerForTextMarkerParameterizedAttribute = + @"AXPreviousSentenceStartTextMarkerForTextMarker"; +NSString* const + NSAccessibilityNextParagraphEndTextMarkerForTextMarkerParameterizedAttribute = + @"AXNextParagraphEndTextMarkerForTextMarker"; +NSString* const + NSAccessibilityPreviousParagraphStartTextMarkerForTextMarkerParameterizedAttribute = + @"AXPreviousParagraphStartTextMarkerForTextMarker"; +NSString* const + NSAccessibilityStyleTextMarkerRangeForTextMarkerParameterizedAttribute = + @"AXStyleTextMarkerRangeForTextMarker"; +NSString* const NSAccessibilityLengthForTextMarkerRangeParameterizedAttribute = + @"AXLengthForTextMarkerRange"; + +// Other private attributes. +NSString* const NSAccessibilitySelectTextWithCriteriaParameterizedAttribute = + @"AXSelectTextWithCriteria"; NSString* const NSAccessibilityIndexForChildUIElementParameterizedAttribute = @"AXIndexForChildUIElement"; NSString* const NSAccessibilityValueAutofillAvailableAttribute = @@ -2484,7 +2562,9 @@ return ToBrowserAccessibilityCocoa(cell); } - if ([attribute isEqualToString:@"AXUIElementForTextMarker"]) { + if ([attribute + isEqualToString: + NSAccessibilityUIElementForTextMarkerParameterizedAttribute]) { BrowserAccessibilityPositionInstance position = CreatePositionFromTextMarker(parameter); if (!position->IsNullPosition()) @@ -2493,7 +2573,9 @@ return nil; } - if ([attribute isEqualToString:@"AXTextMarkerRangeForUIElement"]) { + if ([attribute + isEqualToString: + NSAccessibilityTextMarkerRangeForUIElementParameterizedAttribute]) { BrowserAccessibilityPositionInstance startPosition = owner_->CreatePositionAt(0); BrowserAccessibilityPositionInstance endPosition = @@ -2503,13 +2585,19 @@ return CreateTextMarkerRange(std::move(range)); } - if ([attribute isEqualToString:@"AXStringForTextMarkerRange"]) + if ([attribute + isEqualToString: + NSAccessibilityStringForTextMarkerRangeParameterizedAttribute]) return GetTextForTextMarkerRange(parameter); - if ([attribute isEqualToString:@"AXAttributedStringForTextMarkerRange"]) + if ([attribute + isEqualToString: + NSAccessibilityAttributedStringForTextMarkerRangeParameterizedAttribute]) return GetAttributedTextForTextMarkerRange(parameter); - if ([attribute isEqualToString:@"AXNextTextMarkerForTextMarker"]) { + if ([attribute + isEqualToString: + NSAccessibilityNextTextMarkerForTextMarkerParameterizedAttribute]) { BrowserAccessibilityPositionInstance position = CreatePositionFromTextMarker(parameter); if (position->IsNullPosition()) @@ -2518,7 +2606,9 @@ ui::AXBoundaryBehavior::CrossBoundary)); } - if ([attribute isEqualToString:@"AXPreviousTextMarkerForTextMarker"]) { + if ([attribute + isEqualToString: + NSAccessibilityPreviousTextMarkerForTextMarkerParameterizedAttribute]) { BrowserAccessibilityPositionInstance position = CreatePositionFromTextMarker(parameter); if (position->IsNullPosition()) @@ -2527,7 +2617,9 @@ ui::AXBoundaryBehavior::CrossBoundary)); } - if ([attribute isEqualToString:@"AXLeftWordTextMarkerRangeForTextMarker"]) { + if ([attribute + isEqualToString: + NSAccessibilityLeftWordTextMarkerRangeForTextMarkerParameterizedAttribute]) { BrowserAccessibilityPositionInstance endPosition = CreatePositionFromTextMarker(parameter); if (endPosition->IsNullPosition()) @@ -2546,7 +2638,9 @@ return CreateTextMarkerRange(std::move(range)); } - if ([attribute isEqualToString:@"AXRightWordTextMarkerRangeForTextMarker"]) { + if ([attribute + isEqualToString: + NSAccessibilityRightWordTextMarkerRangeForTextMarkerParameterizedAttribute]) { BrowserAccessibilityPositionInstance startPosition = CreatePositionFromTextMarker(parameter); if (startPosition->IsNullPosition()) @@ -2565,7 +2659,9 @@ return CreateTextMarkerRange(std::move(range)); } - if ([attribute isEqualToString:@"AXNextWordEndTextMarkerForTextMarker"]) { + if ([attribute + isEqualToString: + NSAccessibilityNextWordEndTextMarkerForTextMarkerParameterizedAttribute]) { BrowserAccessibilityPositionInstance position = CreatePositionFromTextMarker(parameter); if (position->IsNullPosition()) @@ -2575,7 +2671,8 @@ } if ([attribute - isEqualToString:@"AXPreviousWordStartTextMarkerForTextMarker"]) { + isEqualToString: + NSAccessibilityPreviousWordStartTextMarkerForTextMarkerParameterizedAttribute]) { BrowserAccessibilityPositionInstance position = CreatePositionFromTextMarker(parameter); if (position->IsNullPosition()) @@ -2584,7 +2681,9 @@ ui::AXBoundaryBehavior::CrossBoundary)); } - if ([attribute isEqualToString:@"AXTextMarkerRangeForLine"]) { + if ([attribute + isEqualToString: + NSAccessibilityTextMarkerRangeForLineParameterizedAttribute]) { BrowserAccessibilityPositionInstance position = CreatePositionFromTextMarker(parameter); if (position->IsNullPosition()) @@ -2600,7 +2699,9 @@ return CreateTextMarkerRange(std::move(range)); } - if ([attribute isEqualToString:@"AXLeftLineTextMarkerRangeForTextMarker"]) { + if ([attribute + isEqualToString: + NSAccessibilityLeftLineTextMarkerRangeForTextMarkerParameterizedAttribute]) { BrowserAccessibilityPositionInstance endPosition = CreatePositionFromTextMarker(parameter); if (endPosition->IsNullPosition()) @@ -2619,7 +2720,9 @@ return CreateTextMarkerRange(std::move(range)); } - if ([attribute isEqualToString:@"AXRightLineTextMarkerRangeForTextMarker"]) { + if ([attribute + isEqualToString: + NSAccessibilityRightLineTextMarkerRangeForTextMarkerParameterizedAttribute]) { BrowserAccessibilityPositionInstance startPosition = CreatePositionFromTextMarker(parameter); if (startPosition->IsNullPosition()) @@ -2638,7 +2741,9 @@ return CreateTextMarkerRange(std::move(range)); } - if ([attribute isEqualToString:@"AXNextLineEndTextMarkerForTextMarker"]) { + if ([attribute + isEqualToString: + NSAccessibilityNextLineEndTextMarkerForTextMarkerParameterizedAttribute]) { BrowserAccessibilityPositionInstance position = CreatePositionFromTextMarker(parameter); if (position->IsNullPosition()) @@ -2648,7 +2753,8 @@ } if ([attribute - isEqualToString:@"AXPreviousLineStartTextMarkerForTextMarker"]) { + isEqualToString: + NSAccessibilityPreviousLineStartTextMarkerForTextMarkerParameterizedAttribute]) { BrowserAccessibilityPositionInstance position = CreatePositionFromTextMarker(parameter); if (position->IsNullPosition()) @@ -2657,9 +2763,97 @@ ui::AXBoundaryBehavior::CrossBoundary)); } - if ([attribute isEqualToString:@"AXLengthForTextMarkerRange"]) { + if ([attribute + isEqualToString: + NSAccessibilityParagraphTextMarkerRangeForTextMarkerParameterizedAttribute]) { + BrowserAccessibilityPositionInstance position = + CreatePositionFromTextMarker(parameter); + if (position->IsNullPosition()) + return nil; + + BrowserAccessibilityPositionInstance startPosition = + position->CreatePreviousParagraphStartPosition( + ui::AXBoundaryBehavior::StopIfAlreadyAtBoundary); + BrowserAccessibilityPositionInstance endPosition = + position->CreateNextParagraphEndPosition( + ui::AXBoundaryBehavior::StopIfAlreadyAtBoundary); + AXPlatformRange range(std::move(startPosition), std::move(endPosition)); + return CreateTextMarkerRange(std::move(range)); + } + + if ([attribute + isEqualToString: + NSAccessibilityNextParagraphEndTextMarkerForTextMarkerParameterizedAttribute]) { + BrowserAccessibilityPositionInstance position = + CreatePositionFromTextMarker(parameter); + if (position->IsNullPosition()) + return nil; + return CreateTextMarker(position->CreateNextParagraphEndPosition( + ui::AXBoundaryBehavior::CrossBoundary)); + } + + if ([attribute + isEqualToString: + NSAccessibilityPreviousParagraphStartTextMarkerForTextMarkerParameterizedAttribute]) { + BrowserAccessibilityPositionInstance position = + CreatePositionFromTextMarker(parameter); + if (position->IsNullPosition()) + return nil; + return CreateTextMarker(position->CreatePreviousParagraphStartPosition( + ui::AXBoundaryBehavior::CrossBoundary)); + } + + if ([attribute + isEqualToString: + NSAccessibilityStyleTextMarkerRangeForTextMarkerParameterizedAttribute]) { + BrowserAccessibilityPositionInstance position = + CreatePositionFromTextMarker(parameter); + if (position->IsNullPosition()) + return nil; + + BrowserAccessibilityPositionInstance startPosition = + position->CreatePositionAtFormatBoundary( + ui::AXBoundaryBehavior::StopIfAlreadyAtBoundary, + /*forwards*/ false); + BrowserAccessibilityPositionInstance endPosition = + position->CreatePositionAtFormatBoundary( + ui::AXBoundaryBehavior::StopIfAlreadyAtBoundary, /*forwards*/ true); + AXPlatformRange range(std::move(startPosition), std::move(endPosition)); + return CreateTextMarkerRange(std::move(range)); + } + + if ([attribute + isEqualToString: + NSAccessibilityLengthForTextMarkerRangeParameterizedAttribute]) { NSString* text = GetTextForTextMarkerRange(parameter); - return [NSNumber numberWithInt:[text length]]; + return @([text length]); + } + + if ([attribute isEqualToString: + NSAccessibilityTextMarkerIsValidParameterizedAttribute]) { + return @(CreatePositionFromTextMarker(parameter)->IsNullPosition()); + } + + if ([attribute isEqualToString: + NSAccessibilityIndexForTextMarkerParameterizedAttribute]) { + BrowserAccessibilityPositionInstance position = + CreatePositionFromTextMarker(parameter); + if (position->IsNullPosition()) + return nil; + return @(position->AsTextPosition()->text_offset()); + } + + if ([attribute isEqualToString: + NSAccessibilityTextMarkerForIndexParameterizedAttribute]) { + int index = [static_cast<NSNumber*>(parameter) intValue]; + if (index < 0) + return nil; + + const BrowserAccessibility* root = owner_->manager()->GetRoot(); + if (!root) + return nil; + + return CreateTextMarker(root->CreatePositionAt(index)); } if ([attribute isEqualToString: @@ -2787,37 +2981,42 @@ // General attributes. NSMutableArray* ret = [NSMutableArray arrayWithObjects: - @"AXUIElementForTextMarker", @"AXTextMarkerRangeForUIElement", - @"AXLineForTextMarker", @"AXTextMarkerRangeForLine", - @"AXStringForTextMarkerRange", @"AXTextMarkerForPosition", - @"AXAttributedStringForTextMarkerRange", - @"AXNextTextMarkerForTextMarker", - @"AXPreviousTextMarkerForTextMarker", - @"AXLeftWordTextMarkerRangeForTextMarker", - @"AXRightWordTextMarkerRangeForTextMarker", - @"AXLeftLineTextMarkerRangeForTextMarker", - @"AXRightLineTextMarkerRangeForTextMarker", - @"AXSentenceTextMarkerRangeForTextMarker", - @"AXParagraphTextMarkerRangeForTextMarker", - @"AXNextWordEndTextMarkerForTextMarker", - @"AXPreviousWordStartTextMarkerForTextMarker", - @"AXNextLineEndTextMarkerForTextMarker", - @"AXPreviousLineStartTextMarkerForTextMarker", - @"AXNextSentenceEndTextMarkerForTextMarker", - @"AXPreviousSentenceStartTextMarkerForTextMarker", - @"AXNextParagraphEndTextMarkerForTextMarker", - @"AXPreviousParagraphStartTextMarkerForTextMarker", - @"AXStyleTextMarkerRangeForTextMarker", @"AXLengthForTextMarkerRange", + NSAccessibilityUIElementForTextMarkerParameterizedAttribute, + NSAccessibilityTextMarkerRangeForUIElementParameterizedAttribute, + NSAccessibilityLineForTextMarkerParameterizedAttribute, + NSAccessibilityTextMarkerRangeForLineParameterizedAttribute, + NSAccessibilityStringForTextMarkerRangeParameterizedAttribute, + NSAccessibilityTextMarkerForPositionParameterizedAttribute, NSAccessibilityBoundsForTextMarkerRangeParameterizedAttribute, + NSAccessibilityAttributedStringForTextMarkerRangeParameterizedAttribute, + NSAccessibilityAttributedStringForTextMarkerRangeWithOptionsParameterizedAttribute, NSAccessibilityTextMarkerRangeForUnorderedTextMarkersParameterizedAttribute, + NSAccessibilityNextTextMarkerForTextMarkerParameterizedAttribute, + NSAccessibilityPreviousTextMarkerForTextMarkerParameterizedAttribute, + NSAccessibilityLeftWordTextMarkerRangeForTextMarkerParameterizedAttribute, + NSAccessibilityRightWordTextMarkerRangeForTextMarkerParameterizedAttribute, + NSAccessibilityLeftLineTextMarkerRangeForTextMarkerParameterizedAttribute, + NSAccessibilityRightLineTextMarkerRangeForTextMarkerParameterizedAttribute, + NSAccessibilitySentenceTextMarkerRangeForTextMarkerParameterizedAttribute, + NSAccessibilityParagraphTextMarkerRangeForTextMarkerParameterizedAttribute, + NSAccessibilityNextWordEndTextMarkerForTextMarkerParameterizedAttribute, + NSAccessibilityPreviousWordStartTextMarkerForTextMarkerParameterizedAttribute, + NSAccessibilityNextLineEndTextMarkerForTextMarkerParameterizedAttribute, + NSAccessibilityPreviousLineStartTextMarkerForTextMarkerParameterizedAttribute, + NSAccessibilityNextSentenceEndTextMarkerForTextMarkerParameterizedAttribute, + NSAccessibilityPreviousSentenceStartTextMarkerForTextMarkerParameterizedAttribute, + NSAccessibilityNextParagraphEndTextMarkerForTextMarkerParameterizedAttribute, + NSAccessibilityPreviousParagraphStartTextMarkerForTextMarkerParameterizedAttribute, + NSAccessibilityStyleTextMarkerRangeForTextMarkerParameterizedAttribute, + NSAccessibilityLengthForTextMarkerRangeParameterizedAttribute, + NSAccessibilityEndTextMarkerForBoundsParameterizedAttribute, + NSAccessibilityStartTextMarkerForBoundsParameterizedAttribute, + NSAccessibilityLineTextMarkerRangeForTextMarkerParameterizedAttribute, NSAccessibilityIndexForChildUIElementParameterizedAttribute, NSAccessibilityBoundsForRangeParameterizedAttribute, NSAccessibilityStringForRangeParameterizedAttribute, NSAccessibilityUIElementCountForSearchPredicateParameterizedAttribute, NSAccessibilityUIElementsForSearchPredicateParameterizedAttribute, - NSAccessibilityEndTextMarkerForBoundsParameterizedAttribute, - NSAccessibilityStartTextMarkerForBoundsParameterizedAttribute, - NSAccessibilityLineTextMarkerRangeForTextMarkerParameterizedAttribute, NSAccessibilitySelectTextWithCriteriaParameterizedAttribute, nil]; if ([[self role] isEqualToString:NSAccessibilityTableRole] ||
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc index f8c3d543..5b1efadd 100644 --- a/content/browser/accessibility/browser_accessibility_manager_win.cc +++ b/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -248,6 +248,7 @@ FireWinAccessibilityEvent(EVENT_OBJECT_SHOW, node); FireUiaStructureChangedEvent(StructureChangeType_ChildAdded, node); } + aria_properties_events_.insert(node); break; case ui::AXEventGenerator::Event::IMAGE_ANNOTATION_CHANGED: FireWinAccessibilityEvent(EVENT_OBJECT_NAMECHANGE, node); @@ -460,10 +461,16 @@ return; if (!ShouldFireEventForNode(node)) return; - // Suppress events when |IGNORED_CHANGED| + + // Suppress events when |IGNORED_CHANGED| with the exception for firing + // UIA_AriaPropertiesPropertyId-hidden event on non-text node marked as + // ignored. if (node->HasState(ax::mojom::State::kIgnored) || - base::Contains(ignored_changed_nodes_, node)) - return; + base::Contains(ignored_changed_nodes_, node)) { + if (uia_property != UIA_AriaPropertiesPropertyId || + node->IsTextOnlyObject()) + return; + } // The old value is not used by the system VARIANT old_value = {};
diff --git a/content/browser/accessibility/dump_accessibility_events_browsertest.cc b/content/browser/accessibility/dump_accessibility_events_browsertest.cc index 9bf21e6..abbfeb9 100644 --- a/content/browser/accessibility/dump_accessibility_events_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_events_browsertest.cc
@@ -283,6 +283,11 @@ } IN_PROC_BROWSER_TEST_P(DumpAccessibilityEventsTest, + AccessibilityEventsAriaHiddenChanged) { + RunEventTest(FILE_PATH_LITERAL("aria-hidden-changed.html")); +} + +IN_PROC_BROWSER_TEST_P(DumpAccessibilityEventsTest, AccessibilityEventsAriaInvalidChanged) { RunEventTest(FILE_PATH_LITERAL("aria-invalid-changed.html")); } @@ -485,18 +490,9 @@ RunEventTest(FILE_PATH_LITERAL("disabled-state-changed.html")); } -// http://crbug.com/982998 -// Test fails on Mac due to https://crbug.com/985925. -#if defined(OS_WIN) || defined(OS_MACOSX) -#define MAYBE_AccessibilityEventsExpandedChange \ - DISABLED_AccessibilityEventsExpandedChange -#else -#define MAYBE_AccessibilityEventsExpandedChange \ - AccessibilityEventsExpandedChange -#endif IN_PROC_BROWSER_TEST_P(DumpAccessibilityEventsTest, - MAYBE_AccessibilityEventsExpandedChange) { - RunEventTest(FILE_PATH_LITERAL("expanded-change.html")); + AccessibilityEventsExpandedChanged) { + RunEventTest(FILE_PATH_LITERAL("expanded-changed.html")); } IN_PROC_BROWSER_TEST_P(DumpAccessibilityEventsTest, @@ -733,6 +729,11 @@ RunEventTest(FILE_PATH_LITERAL("tbody-focus.html")); } +IN_PROC_BROWSER_TEST_P(DumpAccessibilityEventsTest, + AccessibilityEventsVisibilityHiddenChanged) { + RunEventTest(FILE_PATH_LITERAL("visibility-hidden-changed.html")); +} + // Even with the deflaking in WaitForAccessibilityTreeToContainNodeWithName, // this test is still flaky on Windows. // TODO(aboxhall, dmazzoni, meredithl): re-enable with better fix for above.
diff --git a/content/browser/cache_storage/cache_storage_manager_unittest.cc b/content/browser/cache_storage/cache_storage_manager_unittest.cc index 59db93d..d4605b2 100644 --- a/content/browser/cache_storage/cache_storage_manager_unittest.cc +++ b/content/browser/cache_storage/cache_storage_manager_unittest.cc
@@ -1402,16 +1402,37 @@ CacheStorageHandle cache_storage = CacheStorageForOrigin(origin1_); auto cache_handle = LegacyCacheStorage::From(cache_storage)->GetLoadedCache(kCacheName); - base::FilePath index_path = - LegacyCacheStorageCache::From(cache_handle)->path().AppendASCII("index"); + base::FilePath cache_path = + LegacyCacheStorageCache::From(cache_handle)->path(); + base::FilePath storage_path = cache_path.DirName(); + base::FilePath index_path = cache_path.AppendASCII("index"); cache_handle = CacheStorageCacheHandle(); + // Do our best to flush any pending cache_storage index file writes to disk + // before proceeding. This does not guarantee the simple disk_cache index + // is written, though. + EXPECT_TRUE(FlushCacheStorageIndex(origin1_)); + EXPECT_FALSE(FlushCacheStorageIndex(origin1_)); + DestroyStorageManager(); // Truncate the SimpleCache index to force an error when next opened. ASSERT_FALSE(index_path.empty()); ASSERT_EQ(5, base::WriteFile(index_path, "hello", 5)); + // The cache_storage index and simple disk_cache index files are written from + // background threads. They may be written in unexpected orders due to timing + // differences. We need to ensure the cache directory to have a newer time + // stamp, though, in order for the Size() method to actually try calculating + // the size from the corrupted simple disk_cache. Therefore we force the + // cache_storage index to have a much older time to ensure that it is not used + // in the following Size() call. + base::FilePath cache_index_path = + storage_path.AppendASCII(LegacyCacheStorage::kIndexFileName); + base::Time t = base::Time::Now() + base::TimeDelta::FromHours(-1); + EXPECT_TRUE(base::TouchFile(cache_index_path, t, t)); + EXPECT_FALSE(IsIndexFileCurrent(storage_path)); + CreateStorageManager(); EXPECT_TRUE(Open(origin1_, kCacheName));
diff --git a/content/browser/cache_storage/legacy/legacy_cache_storage.cc b/content/browser/cache_storage/legacy/legacy_cache_storage.cc index a064cef4..b1a4d62c 100644 --- a/content/browser/cache_storage/legacy/legacy_cache_storage.cc +++ b/content/browser/cache_storage/legacy/legacy_cache_storage.cc
@@ -571,18 +571,27 @@ quota_manager_proxy_(quota_manager_proxy), owner_(owner), cache_storage_manager_(cache_storage_manager) { - if (memory_only) + if (memory_only) { cache_loader_.reset(new MemoryLoader( cache_task_runner_.get(), std::move(scheduler_task_runner), quota_manager_proxy.get(), blob_context, this, origin, owner)); - else - cache_loader_.reset(new SimpleCacheLoader( - origin_path_, cache_task_runner_.get(), - std::move(scheduler_task_runner), quota_manager_proxy.get(), - blob_context, this, origin, owner)); + return; + } + + cache_loader_.reset(new SimpleCacheLoader( + origin_path_, cache_task_runner_.get(), std::move(scheduler_task_runner), + quota_manager_proxy.get(), blob_context, this, origin, owner)); + +#if defined(OS_ANDROID) + app_status_listener_ = base::android::ApplicationStatusListener::New( + base::BindRepeating(&LegacyCacheStorage::OnApplicationStateChange, + weak_factory_.GetWeakPtr())); +#endif } -LegacyCacheStorage::~LegacyCacheStorage() {} +LegacyCacheStorage::~LegacyCacheStorage() { + FlushIndexIfDirty(); +} CacheStorageHandle LegacyCacheStorage::CreateHandle() { return CacheStorageHandle(weak_factory_.GetWeakPtr()); @@ -810,14 +819,19 @@ } void LegacyCacheStorage::ScheduleWriteIndex() { - static const int64_t kWriteIndexDelaySecs = 5; + // These values are chosen to be equal or greater than the simple disk_cache + // index write delays. We want the cache_storage index to be written last. + static const int64_t kWriteIndexDelayMilliseconds = 20050; + static const int64_t kWriteIndexBackgroundDelayMilliseconds = 150; + int64_t delay_ms = app_on_background_ ? kWriteIndexBackgroundDelayMilliseconds + : kWriteIndexDelayMilliseconds; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); index_write_task_.Reset(base::BindOnce(&LegacyCacheStorage::WriteIndex, weak_factory_.GetWeakPtr(), base::DoNothing::Once<bool>())); base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, index_write_task_.callback(), - base::TimeDelta::FromSeconds(kWriteIndexDelaySecs)); + base::TimeDelta::FromMilliseconds(delay_ms)); } void LegacyCacheStorage::WriteIndex(base::OnceCallback<void(bool)> callback) { @@ -1014,6 +1028,7 @@ cache_ptr->cache_padding_key()->key())); CacheStorageCacheHandle handle = cache_ptr->CreateHandle(); + index_write_task_.Cancel(); cache_loader_->WriteIndex( *cache_index_, base::BindOnce(&LegacyCacheStorage::CreateCacheDidWriteIndex, @@ -1072,6 +1087,7 @@ DCHECK(scheduler_->IsRunningExclusiveOperation()); LegacyCacheStorageCache::From(cache_handle)->SetObserver(nullptr); cache_index_->DoomCache(cache_name); + index_write_task_.Cancel(); cache_loader_->WriteIndex( *cache_index_, base::BindOnce(&LegacyCacheStorage::DeleteCacheDidWriteIndex, @@ -1397,4 +1413,24 @@ } } +void LegacyCacheStorage::FlushIndexIfDirty() { + if (!index_write_pending()) + return; + index_write_task_.Cancel(); + cache_loader_->WriteIndex(*cache_index_, base::DoNothing::Once<bool>()); +} + +#if defined(OS_ANDROID) +void LegacyCacheStorage::OnApplicationStateChange( + base::android::ApplicationState state) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (state == base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) { + app_on_background_ = false; + } else if (state == base::android::APPLICATION_STATE_HAS_STOPPED_ACTIVITIES) { + app_on_background_ = true; + FlushIndexIfDirty(); + } +} +#endif + } // namespace content
diff --git a/content/browser/cache_storage/legacy/legacy_cache_storage.h b/content/browser/cache_storage/legacy/legacy_cache_storage.h index 14ae5b6..2e68fe9b 100644 --- a/content/browser/cache_storage/legacy/legacy_cache_storage.h +++ b/content/browser/cache_storage/legacy/legacy_cache_storage.h
@@ -15,11 +15,16 @@ #include "base/memory/memory_pressure_listener.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "build/build_config.h" #include "content/browser/cache_storage/cache_storage.h" #include "content/browser/cache_storage/cache_storage_cache_observer.h" #include "content/browser/cache_storage/cache_storage_scheduler_types.h" #include "content/browser/cache_storage/legacy/legacy_cache_storage_cache.h" +#if defined(OS_ANDROID) +#include "base/android/application_status_listener.h" +#endif + namespace base { class SequencedTaskRunner; } @@ -260,6 +265,12 @@ bool InitiateScheduledIndexWriteForTest( base::OnceCallback<void(bool)> callback); + void FlushIndexIfDirty(); + +#if defined(OS_ANDROID) + void OnApplicationStateChange(base::android::ApplicationState state); +#endif + // Whether or not we've loaded the list of cache names into memory. bool initialized_; bool initializing_; @@ -305,6 +316,14 @@ base::CancelableOnceClosure index_write_task_; size_t handle_ref_count_ = 0; +#if defined(OS_ANDROID) + std::unique_ptr<base::android::ApplicationStatusListener> + app_status_listener_; +#endif + + // True if running on android and the app is in the background. + bool app_on_background_ = false; + SEQUENCE_CHECKER(sequence_checker_); base::WeakPtrFactory<LegacyCacheStorage> weak_factory_{this};
diff --git a/content/browser/devtools/devtools_background_services_context_impl.cc b/content/browser/devtools/devtools_background_services_context_impl.cc index b0891f03..cecfd295 100644 --- a/content/browser/devtools/devtools_background_services_context_impl.cc +++ b/content/browser/devtools/devtools_background_services_context_impl.cc
@@ -147,12 +147,11 @@ GetLoggedBackgroundServiceEventsCallback callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&DevToolsBackgroundServicesContextImpl:: - GetLoggedBackgroundServiceEventsOnIO, - weak_ptr_factory_io_.GetWeakPtr(), service, - std::move(callback))); + base::PostTask(FROM_HERE, {BrowserThread::IO}, + base::BindOnce(&DevToolsBackgroundServicesContextImpl:: + GetLoggedBackgroundServiceEventsOnIO, + weak_ptr_factory_io_.GetWeakPtr(), service, + std::move(callback))); } void DevToolsBackgroundServicesContextImpl:: @@ -199,20 +198,18 @@ return state1.timestamp() < state2.timestamp(); }); - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::UI}, - base::BindOnce(std::move(callback), std::move(events))); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(std::move(callback), std::move(events))); } void DevToolsBackgroundServicesContextImpl::ClearLoggedBackgroundServiceEvents( devtools::proto::BackgroundService service) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&DevToolsBackgroundServicesContextImpl:: - ClearLoggedBackgroundServiceEventsOnIO, - weak_ptr_factory_io_.GetWeakPtr(), service)); + base::PostTask(FROM_HERE, {BrowserThread::IO}, + base::BindOnce(&DevToolsBackgroundServicesContextImpl:: + ClearLoggedBackgroundServiceEventsOnIO, + weak_ptr_factory_io_.GetWeakPtr(), service)); } void DevToolsBackgroundServicesContextImpl:: @@ -233,7 +230,7 @@ const std::map<std::string, std::string>& event_metadata) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::IO}, base::BindOnce( &DevToolsBackgroundServicesContextImpl::LogBackgroundServiceEventOnIO, @@ -256,7 +253,7 @@ if (IsRecordingExpired(ServiceToProtoEnum(service))) { // We should stop recording because of the expiration time. We should // also inform the observers that we stopped recording. - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce( &DevToolsBackgroundServicesContextImpl::OnRecordingTimeExpired, @@ -280,7 +277,7 @@ {{CreateEntryKey(event.background_service()), event.SerializeAsString()}}, base::BindOnce(&DidLogServiceEvent)); - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce( &DevToolsBackgroundServicesContextImpl::NotifyEventObservers,
diff --git a/content/browser/devtools/devtools_http_handler.cc b/content/browser/devtools/devtools_http_handler.cc index 90fbb4fd..2f22c93 100644 --- a/content/browser/devtools/devtools_http_handler.cc +++ b/content/browser/devtools/devtools_http_handler.cc
@@ -225,9 +225,10 @@ if (socket_factory) thread->task_runner()->DeleteSoon(FROM_HERE, std::move(socket_factory)); if (thread) { - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, - {base::WithBaseSyncPrimitives(), base::TaskPriority::BEST_EFFORT}, + {base::ThreadPool(), base::WithBaseSyncPrimitives(), + base::TaskPriority::BEST_EFFORT}, BindOnce([](std::unique_ptr<base::Thread>) {}, std::move(thread))); } } @@ -300,7 +301,7 @@ #endif } - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce(&ServerStartedOnUI, std::move(handler), thread.release(), server_wrapper.release(), socket_factory.release(), @@ -433,18 +434,17 @@ server_->SetSendBufferSize(connection_id, kSendBufferSizeForDevTools); if (base::StartsWith(info.path, "/json", base::CompareCase::SENSITIVE)) { - base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&DevToolsHttpHandler::OnJsonRequest, - handler_, connection_id, info)); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(&DevToolsHttpHandler::OnJsonRequest, handler_, + connection_id, info)); return; } if (info.path.empty() || info.path == "/") { // Discovery page request. - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&DevToolsHttpHandler::OnDiscoveryPageRequest, handler_, - connection_id)); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(&DevToolsHttpHandler::OnDiscoveryPageRequest, + handler_, connection_id)); return; } @@ -467,7 +467,7 @@ } if (bundles_resources_) { - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce(&DevToolsHttpHandler::OnFrontendResourceRequest, handler_, connection_id, filename)); @@ -479,21 +479,19 @@ void ServerWrapper::OnWebSocketRequest( int connection_id, const net::HttpServerRequestInfo& request) { - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&DevToolsHttpHandler::OnWebSocketRequest, handler_, - connection_id, request)); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(&DevToolsHttpHandler::OnWebSocketRequest, + handler_, connection_id, request)); } void ServerWrapper::OnWebSocketMessage(int connection_id, std::string data) { - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&DevToolsHttpHandler::OnWebSocketMessage, handler_, - connection_id, std::move(data))); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(&DevToolsHttpHandler::OnWebSocketMessage, + handler_, connection_id, std::move(data))); } void ServerWrapper::OnClose(int connection_id) { - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce(&DevToolsHttpHandler::OnClose, handler_, connection_id)); }
diff --git a/content/browser/devtools/devtools_http_handler_unittest.cc b/content/browser/devtools/devtools_http_handler_unittest.cc index 423ba0c..474aa3e 100644 --- a/content/browser/devtools/devtools_http_handler_unittest.cc +++ b/content/browser/devtools/devtools_http_handler_unittest.cc
@@ -62,7 +62,7 @@ }; void QuitFromHandlerThread(const base::Closure& quit_closure) { - base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, quit_closure); + base::PostTask(FROM_HERE, {BrowserThread::UI}, quit_closure); } class DummyServerSocketFactory : public DevToolsSocketFactory { @@ -73,7 +73,7 @@ quit_closure_2_(quit_closure_2) {} ~DummyServerSocketFactory() override { - base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, quit_closure_2_); + base::PostTask(FROM_HERE, {BrowserThread::UI}, quit_closure_2_); } protected:
diff --git a/content/browser/devtools/devtools_instrumentation.cc b/content/browser/devtools/devtools_instrumentation.cc index eb3c0d8..9eab8df 100644 --- a/content/browser/devtools/devtools_instrumentation.cc +++ b/content/browser/devtools/devtools_instrumentation.cc
@@ -170,16 +170,6 @@ DevToolsAgentHostImpl* agent_host = RenderFrameDevToolsAgentHost::GetFor(frame_tree_node); - if (agent_host) { - // Interception might throttle navigations in inspected frames. - for (auto* network_handler : - protocol::NetworkHandler::ForAgentHost(agent_host)) { - std::unique_ptr<NavigationThrottle> throttle = - network_handler->CreateThrottleForNavigation(navigation_handle); - if (throttle) - result.push_back(std::move(throttle)); - } - } FrameTreeNode* parent = frame_tree_node->parent(); if (!parent) { if (WebContentsImpl::FromFrameTreeNode(frame_tree_node)->IsPortal() &&
diff --git a/content/browser/devtools/devtools_interceptor_controller.cc b/content/browser/devtools/devtools_interceptor_controller.cc deleted file mode 100644 index db271624..0000000 --- a/content/browser/devtools/devtools_interceptor_controller.cc +++ /dev/null
@@ -1,134 +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. - -#include "content/browser/devtools/devtools_interceptor_controller.h" - -#include "base/bind.h" -#include "base/supports_user_data.h" -#include "base/task/post_task.h" -#include "content/browser/frame_host/frame_tree_node.h" -#include "content/browser/web_contents/web_contents_impl.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" - -namespace content { - -namespace { -const char kDevToolsInterceptorController[] = "DevToolsInterceptorController"; -} - -std::unique_ptr<InterceptionHandle> -DevToolsInterceptorController::StartInterceptingRequests( - const FrameTreeNode* target_frame, - std::vector<Pattern> intercepted_patterns, - RequestInterceptedCallback callback) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - const base::UnguessableToken& target_id = - target_frame->devtools_frame_token(); - - auto filter_entry = std::make_unique<DevToolsNetworkInterceptor::FilterEntry>( - target_id, std::move(intercepted_patterns), std::move(callback)); - DevToolsTargetRegistry::RegistrationHandle registration_handle = - target_registry_->RegisterWebContents( - WebContentsImpl::FromFrameTreeNode(target_frame)); - std::unique_ptr<InterceptionHandle> handle(new InterceptionHandle( - std::move(registration_handle), interceptor_, filter_entry.get())); - - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&DevToolsNetworkInterceptor::AddFilterEntry, interceptor_, - std::move(filter_entry))); - return handle; -} - -void DevToolsInterceptorController::ContinueInterceptedRequest( - std::string interception_id, - std::unique_ptr<Modifications> modifications, - std::unique_ptr<ContinueInterceptedRequestCallback> callback) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&DevToolsNetworkInterceptor::ContinueInterceptedRequest, - interceptor_, interception_id, std::move(modifications), - std::move(callback))); -} - -bool DevToolsInterceptorController::ShouldCancelNavigation( - const GlobalRequestID& global_request_id) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - auto it = canceled_navigation_requests_.find(global_request_id); - if (it == canceled_navigation_requests_.end()) - return false; - canceled_navigation_requests_.erase(it); - return true; -} - -void DevToolsInterceptorController::GetResponseBody( - std::string interception_id, - std::unique_ptr<GetResponseBodyForInterceptionCallback> callback) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&DevToolsNetworkInterceptor::GetResponseBody, interceptor_, - std::move(interception_id), std::move(callback))); -} - -void DevToolsInterceptorController::NavigationStarted( - const std::string& interception_id, - const GlobalRequestID& request_id) { - navigation_requests_[interception_id] = request_id; -} - -void DevToolsInterceptorController::NavigationFinished( - const std::string& interception_id) { - navigation_requests_.erase(interception_id); -} - -// static -DevToolsInterceptorController* -DevToolsInterceptorController::FromBrowserContext(BrowserContext* context) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - return static_cast<DevToolsInterceptorController*>( - context->GetUserData(kDevToolsInterceptorController)); -} - -DevToolsInterceptorController::DevToolsInterceptorController( - base::WeakPtr<DevToolsNetworkInterceptor> interceptor, - std::unique_ptr<DevToolsTargetRegistry> target_registry, - BrowserContext* browser_context) - : interceptor_(interceptor), target_registry_(std::move(target_registry)) { - browser_context->SetUserData( - kDevToolsInterceptorController, - std::unique_ptr<DevToolsInterceptorController>(this)); -} - -DevToolsInterceptorController::~DevToolsInterceptorController() = default; - -InterceptionHandle::InterceptionHandle( - DevToolsTargetRegistry::RegistrationHandle registration, - base::WeakPtr<DevToolsNetworkInterceptor> interceptor, - DevToolsNetworkInterceptor::FilterEntry* entry) - : registration_(registration), - interceptor_(std::move(interceptor)), - entry_(entry) {} - -InterceptionHandle::~InterceptionHandle() { - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&DevToolsNetworkInterceptor::RemoveFilterEntry, - interceptor_, entry_)); -} - -void InterceptionHandle::UpdatePatterns( - std::vector<DevToolsNetworkInterceptor::Pattern> patterns) { - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&DevToolsNetworkInterceptor::UpdatePatterns, interceptor_, - base::Unretained(entry_), std::move(patterns))); -} - -} // namespace content
diff --git a/content/browser/devtools/devtools_interceptor_controller.h b/content/browser/devtools/devtools_interceptor_controller.h deleted file mode 100644 index dcd7cd2..0000000 --- a/content/browser/devtools/devtools_interceptor_controller.h +++ /dev/null
@@ -1,97 +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 CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_INTERCEPTOR_CONTROLLER_ -#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_INTERCEPTOR_CONTROLLER_ - -#include <string> - -#include "base/containers/flat_map.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/supports_user_data.h" -#include "base/unguessable_token.h" -#include "content/browser/devtools/devtools_network_interceptor.h" -#include "content/browser/devtools/devtools_target_registry.h" - -namespace content { - -class BrowserContext; -class FrameTreeNode; -class InterceptionHandle; - -struct GlobalRequestID; - -class DevToolsInterceptorController : public base::SupportsUserData::Data { - public: - using GetResponseBodyForInterceptionCallback = - DevToolsNetworkInterceptor::GetResponseBodyForInterceptionCallback; - using RequestInterceptedCallback = - DevToolsNetworkInterceptor::RequestInterceptedCallback; - using ContinueInterceptedRequestCallback = - DevToolsNetworkInterceptor::ContinueInterceptedRequestCallback; - using Modifications = DevToolsNetworkInterceptor::Modifications; - using Pattern = DevToolsNetworkInterceptor::Pattern; - - static DevToolsInterceptorController* FromBrowserContext( - BrowserContext* context); - - void ContinueInterceptedRequest( - std::string interception_id, - std::unique_ptr<Modifications> modifications, - std::unique_ptr<ContinueInterceptedRequestCallback> callback); - - std::unique_ptr<InterceptionHandle> StartInterceptingRequests( - const FrameTreeNode* target_frame, - std::vector<Pattern> intercepted_patterns, - RequestInterceptedCallback callback); - - bool ShouldCancelNavigation(const GlobalRequestID& global_request_id); - - void GetResponseBody( - std::string request_id, - std::unique_ptr<GetResponseBodyForInterceptionCallback> callback); - - ~DevToolsInterceptorController() override; - - private: - DevToolsInterceptorController( - base::WeakPtr<DevToolsNetworkInterceptor> interceptor, - std::unique_ptr<DevToolsTargetRegistry> target_registry, - BrowserContext* browser_context); - - void NavigationStarted(const std::string& interception_id, - const GlobalRequestID& request_id); - void NavigationFinished(const std::string& interception_id); - - base::WeakPtr<DevToolsNetworkInterceptor> interceptor_; - std::unique_ptr<DevToolsTargetRegistry> target_registry_; - base::flat_map<std::string, GlobalRequestID> navigation_requests_; - base::flat_set<GlobalRequestID> canceled_navigation_requests_; - base::WeakPtrFactory<DevToolsInterceptorController> weak_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(DevToolsInterceptorController); -}; - -class InterceptionHandle { - public: - ~InterceptionHandle(); - void UpdatePatterns(std::vector<DevToolsNetworkInterceptor::Pattern>); - - private: - friend class DevToolsInterceptorController; - InterceptionHandle(DevToolsTargetRegistry::RegistrationHandle registration, - base::WeakPtr<DevToolsNetworkInterceptor> interceptor, - DevToolsNetworkInterceptor::FilterEntry* entry); - - DevToolsTargetRegistry::RegistrationHandle registration_; - base::WeakPtr<DevToolsNetworkInterceptor> interceptor_; - DevToolsNetworkInterceptor::FilterEntry* entry_; - - DISALLOW_COPY_AND_ASSIGN(InterceptionHandle); -}; - -} // namespace content - -#endif // CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_INTERCEPTOR_CONTROLLER_
diff --git a/content/browser/devtools/devtools_network_transaction_factory.cc b/content/browser/devtools/devtools_network_transaction_factory.cc deleted file mode 100644 index ebb3fc4..0000000 --- a/content/browser/devtools/devtools_network_transaction_factory.cc +++ /dev/null
@@ -1,17 +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. - -#include "content/public/browser/devtools_network_transaction_factory.h" - -#include "services/network/throttling/throttling_network_transaction_factory.h" - -namespace content { - -std::unique_ptr<net::HttpTransactionFactory> -CreateDevToolsNetworkTransactionFactory(net::HttpNetworkSession* session) { - return std::make_unique<network::ThrottlingNetworkTransactionFactory>( - session); -} - -} // namespace content
diff --git a/content/browser/devtools/devtools_pipe_handler.cc b/content/browser/devtools/devtools_pipe_handler.cc index 73412287..a69da17d 100644 --- a/content/browser/devtools/devtools_pipe_handler.cc +++ b/content/browser/devtools/devtools_pipe_handler.cc
@@ -68,7 +68,7 @@ void ReadLoop() { ReadLoopInternal(); - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce(&DevToolsPipeHandler::Shutdown, devtools_handler_)); } @@ -103,10 +103,9 @@ } void HandleMessage(std::string buffer) { - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&DevToolsPipeHandler::HandleMessage, devtools_handler_, - std::move(buffer))); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(&DevToolsPipeHandler::HandleMessage, + devtools_handler_, std::move(buffer))); } protected: @@ -298,8 +297,9 @@ // If there is no write thread, only take care of the read thread. if (!write_thread_) { - base::PostTaskWithTraits( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, + base::PostTask( + FROM_HERE, + {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT}, base::BindOnce([](base::Thread* rthread) { delete rthread; }, read_thread_.release())); return; @@ -328,8 +328,9 @@ pipe_reader_.release())); // Post background task that would join and destroy the threads. - base::PostTaskWithTraits( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, + base::PostTask( + FROM_HERE, + {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT}, base::BindOnce( [](base::Thread* rthread, base::Thread* wthread) { delete rthread;
diff --git a/content/browser/devtools/devtools_stream_blob.cc b/content/browser/devtools/devtools_stream_blob.cc index 2a720cd..39d6b29 100644 --- a/content/browser/devtools/devtools_stream_blob.cc +++ b/content/browser/devtools/devtools_stream_blob.cc
@@ -31,7 +31,7 @@ DevToolsStreamBlob::DevToolsStreamBlob() : DevToolsIOContext::Stream( - base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO})), + base::CreateSingleThreadTaskRunner({BrowserThread::IO})), last_read_pos_(0), failed_(false), is_binary_(false) {} @@ -66,19 +66,18 @@ } void DevToolsStreamBlob::ReadRequest::Fail() { - base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(std::move(callback), nullptr, false, - Stream::StatusFailure)); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(std::move(callback), nullptr, false, + Stream::StatusFailure)); } void DevToolsStreamBlob::Open(scoped_refptr<ChromeBlobStorageContext> context, StoragePartition* partition, const std::string& handle, OpenCallback callback) { - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&DevToolsStreamBlob::OpenOnIO, this, context, handle, - std::move(callback))); + base::PostTask(FROM_HERE, {BrowserThread::IO}, + base::BindOnce(&DevToolsStreamBlob::OpenOnIO, this, context, + handle, std::move(callback))); } void DevToolsStreamBlob::Read(off_t position, @@ -86,7 +85,7 @@ ReadCallback callback) { std::unique_ptr<ReadRequest> request( new ReadRequest(position, max_size, std::move(callback))); - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::IO}, base::BindOnce(&DevToolsStreamBlob::ReadOnIO, this, std::move(request))); } @@ -118,8 +117,8 @@ FailOnIO(std::move(open_callback_)); return; } - base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(std::move(open_callback_), true)); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(std::move(open_callback_), true)); if (!pending_reads_.empty()) StartReadRequest(); } @@ -144,8 +143,8 @@ } void DevToolsStreamBlob::FailOnIO(OpenCallback callback) { - base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(std::move(callback), false)); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(std::move(callback), false)); FailOnIO(); } @@ -181,7 +180,7 @@ bytes_read = blob_reader_->net_error(); DCHECK_LT(0, bytes_read); } - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::IO}, base::BindOnce(&DevToolsStreamBlob::OnReadComplete, this, bytes_read)); } @@ -210,10 +209,9 @@ *data = std::string(io_buf_->data(), bytes_read); } } - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::UI}, - base::BindOnce(std::move(request->callback), std::move(data), - base64_encoded, status)); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(std::move(request->callback), std::move(data), + base64_encoded, status)); if (!pending_reads_.empty()) StartReadRequest(); }
diff --git a/content/browser/devtools/devtools_stream_file.cc b/content/browser/devtools/devtools_stream_file.cc index 93759d0..74e0601 100644 --- a/content/browser/devtools/devtools_stream_file.cc +++ b/content/browser/devtools/devtools_stream_file.cc
@@ -121,9 +121,9 @@ base::Base64Encode(raw_data, data.get()); base64_encoded = true; } - base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(std::move(callback), std::move(data), - base64_encoded, status)); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(std::move(callback), std::move(data), + base64_encoded, status)); } void DevToolsStreamFile::AppendOnFileSequence(
diff --git a/content/browser/devtools/devtools_target_registry.cc b/content/browser/devtools/devtools_target_registry.cc deleted file mode 100644 index 01032ddf..0000000 --- a/content/browser/devtools/devtools_target_registry.cc +++ /dev/null
@@ -1,215 +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. - -#include "content/browser/devtools/devtools_target_registry.h" - -#include "base/bind.h" -#include "base/task_runner.h" -#include "base/threading/thread_checker.h" -#include "content/browser/frame_host/frame_tree_node.h" -#include "content/browser/frame_host/render_frame_host_impl.h" -#include "content/browser/web_contents/web_contents_impl.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/web_contents_observer.h" - -namespace content { - -namespace { - -std::unique_ptr<const DevToolsTargetRegistry::TargetInfo> BuildTargetInfo( - RenderFrameHost* rfh) { - std::unique_ptr<DevToolsTargetRegistry::TargetInfo> info( - new DevToolsTargetRegistry::TargetInfo()); - info->child_id = rfh->GetProcess()->GetID(); - info->routing_id = rfh->GetRoutingID(); - - const FrameTreeNode* ftn = - static_cast<RenderFrameHostImpl*>(rfh)->frame_tree_node(); - info->devtools_token = ftn->devtools_frame_token(); - info->frame_tree_node_id = ftn->frame_tree_node_id(); - - // TODO(crbug.com/777516): this actually needs to return the nearest local - // root (or self). However, for now we keep the existing semantics of request - // matching in interceptor, which is intercepting all requests for given - // web contents, that tests (and potentially some clients) depend on. - // When those are fixed, the condition in the loop below should include - // !rfh->IsCrossProcessSubframe(). - // Watch out for current (leaf) frame host being null - // when it's being destroyed. - while (!ftn->IsMainFrame()) { - ftn = ftn->parent(); - rfh = ftn->current_frame_host(); - } - info->devtools_target_id = ftn->devtools_frame_token(); - - return std::move(info); -} - -} // namespace - -class DevToolsTargetRegistry::Impl : public DevToolsTargetRegistry::Resolver { - public: - using TargetInfo = DevToolsTargetRegistry::TargetInfo; - - const DevToolsTargetRegistry::TargetInfo* GetInfoByFrameTreeNodeId( - int frame_node_id) override { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - auto it = target_info_by_ftn_id_.find(frame_node_id); - return it != target_info_by_ftn_id_.end() ? it->second : nullptr; - } - - const DevToolsTargetRegistry::TargetInfo* GetInfoByRenderFramePair( - int child_id, - int routing_id) override { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - - auto it = target_info_by_render_frame_pair_.find( - std::make_pair(child_id, routing_id)); - return it != target_info_by_render_frame_pair_.end() ? it->second.get() - : nullptr; - } - - void Add(std::unique_ptr<const TargetInfo> info) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - if (info->frame_tree_node_id != -1) { - target_info_by_ftn_id_.insert( - std::make_pair(info->frame_tree_node_id, info.get())); - } - auto key = std::make_pair(info->child_id, info->routing_id); - target_info_by_render_frame_pair_.insert( - std::make_pair(key, std::move(info))); - } - - void Remove(const TargetInfo& info) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - if (info.frame_tree_node_id != -1) - target_info_by_ftn_id_.erase(info.frame_tree_node_id); - target_info_by_render_frame_pair_.erase( - std::make_pair(info.child_id, info.routing_id)); - } - - void AddAll(std::vector<std::unique_ptr<const TargetInfo>> infos) { - for (auto& info : infos) - Add(std::move(info)); - } - - void RemoveAll(std::vector<std::unique_ptr<const TargetInfo>> infos) { - for (auto& info : infos) - Remove(*info); - } - - void Update(std::unique_ptr<const TargetInfo> old_info, - std::unique_ptr<const TargetInfo> new_info) { - if (old_info) - Remove(*old_info); - if (new_info) - Add(std::move(new_info)); - } - - Impl() { DETACH_FROM_THREAD(thread_checker_); } - ~Impl() override = default; - - private: - friend class DevToolsTargetRegistry; - - base::flat_map<std::pair<int, int>, std::unique_ptr<const TargetInfo>> - target_info_by_render_frame_pair_; - base::flat_map<int, const TargetInfo*> target_info_by_ftn_id_; - THREAD_CHECKER(thread_checker_); - - base::WeakPtrFactory<DevToolsTargetRegistry::Impl> weak_factory_{this}; -}; - -class DevToolsTargetRegistry::ContentsObserver : public ObserverBase, - public WebContentsObserver { - public: - ContentsObserver(WebContents* web_contents, DevToolsTargetRegistry* registry) - : WebContentsObserver(web_contents), registry_(registry) {} - - private: - void RenderFrameHostChanged(RenderFrameHost* old_host, - RenderFrameHost* new_host) override { - std::unique_ptr<const TargetInfo> old_target; - if (old_host) - old_target = BuildTargetInfo(old_host); - std::unique_ptr<const TargetInfo> new_target = BuildTargetInfo(new_host); - registry_->impl_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&DevToolsTargetRegistry::Impl::Update, registry_->impl_, - std::move(old_target), std::move(new_target))); - } - - void FrameDeleted(RenderFrameHost* render_frame_host) override { - registry_->impl_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&DevToolsTargetRegistry::Impl::Update, registry_->impl_, - BuildTargetInfo(render_frame_host), nullptr)); - } - - void WebContentsDestroyed() override { - NOTREACHED() << "DevToolsTarget Registry clients should be destroyed " - "before WebContents"; - registry_->UnregisterWebContents(web_contents()); - } - - ~ContentsObserver() override { - if (web_contents()) - registry_->UnregisterWebContents(web_contents()); - } - - DevToolsTargetRegistry* registry_; -}; - -DevToolsTargetRegistry::RegistrationHandle -DevToolsTargetRegistry::RegisterWebContents(WebContents* web_contents) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - auto it = observers_.find(web_contents); - if (it != observers_.end()) - return it->second; - - scoped_refptr<ContentsObserver> observer = - new DevToolsTargetRegistry::ContentsObserver(web_contents, this); - observers_.insert(std::make_pair(web_contents, observer.get())); - std::vector<std::unique_ptr<const TargetInfo>> infos; - for (RenderFrameHost* render_frame_host : web_contents->GetAllFrames()) - infos.push_back(BuildTargetInfo(render_frame_host)); - - impl_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&DevToolsTargetRegistry::Impl::AddAll, impl_, - std::move(infos))); - return observer; -} - -std::unique_ptr<DevToolsTargetRegistry::Resolver> -DevToolsTargetRegistry::CreateResolver() { - DCHECK(!impl_); - - auto impl = std::make_unique<Impl>(); - impl_ = impl->weak_factory_.GetWeakPtr(); - return std::move(impl); -} - -void DevToolsTargetRegistry::UnregisterWebContents(WebContents* web_contents) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - size_t count = observers_.erase(web_contents); - DCHECK_NE(count, 0ul); - - std::vector<std::unique_ptr<const TargetInfo>> infos; - for (RenderFrameHost* render_frame_host : web_contents->GetAllFrames()) - infos.push_back(BuildTargetInfo(render_frame_host)); - - impl_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&DevToolsTargetRegistry::Impl::RemoveAll, impl_, - std::move(infos))); -} - -DevToolsTargetRegistry::DevToolsTargetRegistry( - scoped_refptr<base::SequencedTaskRunner> impl_task_runner) - : impl_task_runner_(impl_task_runner) {} - -DevToolsTargetRegistry::~DevToolsTargetRegistry() = default; - -} // namespace content
diff --git a/content/browser/devtools/devtools_target_registry.h b/content/browser/devtools/devtools_target_registry.h deleted file mode 100644 index 27d5e68..0000000 --- a/content/browser/devtools/devtools_target_registry.h +++ /dev/null
@@ -1,77 +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 CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_TARGET_REGISTRY_H_ -#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_TARGET_REGISTRY_H_ - -#include <memory> -#include <utility> -#include <vector> - -#include "base/containers/flat_map.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/singleton.h" -#include "base/memory/weak_ptr.h" -#include "base/sequenced_task_runner.h" -#include "base/threading/thread_checker.h" -#include "base/unguessable_token.h" - -namespace content { - -class WebContents; - -class DevToolsTargetRegistry { - public: - struct TargetInfo { - int child_id; - int routing_id; - int frame_tree_node_id; - base::UnguessableToken devtools_token; - base::UnguessableToken devtools_target_id; - }; - - class ObserverBase : public base::RefCounted<ObserverBase> { - protected: - friend class base::RefCounted<ObserverBase>; - virtual ~ObserverBase() {} - }; - using RegistrationHandle = scoped_refptr<ObserverBase>; - - // Impl thread methods - class Resolver { - public: - virtual const TargetInfo* GetInfoByFrameTreeNodeId(int frame_node_id) = 0; - virtual const TargetInfo* GetInfoByRenderFramePair(int child_id, - int routing_id) = 0; - virtual ~Resolver() {} - }; - - // UI thread method - RegistrationHandle RegisterWebContents(WebContents* web_contents); - std::unique_ptr<Resolver> CreateResolver(); - - explicit DevToolsTargetRegistry( - scoped_refptr<base::SequencedTaskRunner> impl_task_runner); - ~DevToolsTargetRegistry(); - - private: - void UnregisterWebContents(WebContents* web_contents); - - class ContentsObserver; - class Impl; - - scoped_refptr<base::SequencedTaskRunner> impl_task_runner_; - // Observers are owned by the clients and are cleaned up from this - // map when destroyed. - base::flat_map<WebContents*, ContentsObserver*> observers_; - - base::WeakPtr<Impl> impl_; - - DISALLOW_COPY_AND_ASSIGN(DevToolsTargetRegistry); -}; - -} // namespace content - -#endif // CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_TARGET_REGISTRY_H_
diff --git a/content/browser/devtools/devtools_url_loader_interceptor.cc b/content/browser/devtools/devtools_url_loader_interceptor.cc index 636f6081..37da4c9f 100644 --- a/content/browser/devtools/devtools_url_loader_interceptor.cc +++ b/content/browser/devtools/devtools_url_loader_interceptor.cc
@@ -79,10 +79,9 @@ callbacks_.push_back(std::move(callback)); if (data_complete_) { DCHECK_EQ(1UL, callbacks_.size()); - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&BodyReader::DispatchBodyOnUI, std::move(callbacks_), - encoded_body_)); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(&BodyReader::DispatchBodyOnUI, + std::move(callbacks_), encoded_body_)); } } @@ -94,10 +93,9 @@ } void CancelWithError(std::string error) { - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&BodyReader::DispatchErrorOnUI, std::move(callbacks_), - std::move(error))); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(&BodyReader::DispatchErrorOnUI, + std::move(callbacks_), std::move(error))); } private: @@ -138,10 +136,9 @@ body_pipe_drainer_.reset(); // TODO(caseq): only encode if necessary. base::Base64Encode(body_->data(), &encoded_body_); - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&BodyReader::DispatchBodyOnUI, std::move(callbacks_), - encoded_body_)); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(&BodyReader::DispatchBodyOnUI, + std::move(callbacks_), encoded_body_)); std::move(download_complete_callback_).Run(); } @@ -427,11 +424,10 @@ auto it = jobs_.find(id); if (it != jobs_.end()) return it->second; - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::UI}, - base::BindOnce( - &Callback::sendFailure, std::move(*callback), - protocol::Response::InvalidParams("Invalid InterceptionId."))); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(&Callback::sendFailure, std::move(*callback), + protocol::Response::InvalidParams( + "Invalid InterceptionId."))); return nullptr; } @@ -503,7 +499,7 @@ is_download_(is_download), interceptor_(std::move(interceptor)) { DETACH_FROM_SEQUENCE(sequence_checker_); - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::IO}, base::BindOnce(&DevToolsURLLoaderFactoryProxy::StartOnIO, base::Unretained(this), std::move(loader_request), @@ -596,8 +592,7 @@ : enabled_(false), impl_(new DevToolsURLLoaderInterceptor::Impl(std::move(callback)), base::OnTaskRunnerDeleter( - base::CreateSingleThreadTaskRunnerWithTraits( - {BrowserThread::IO}))), + base::CreateSingleThreadTaskRunner({BrowserThread::IO}))), weak_impl_(impl_->AsWeakPtr()) {} DevToolsURLLoaderInterceptor::~DevToolsURLLoaderInterceptor() = default; @@ -607,7 +602,7 @@ bool handle_auth) { enabled_ = !!patterns.size(); DCHECK(enabled_ || !handle_auth); - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::IO}, base::BindOnce(&Impl::SetPatterns, base::Unretained(impl_.get()), std::move(patterns), handle_auth)); @@ -616,7 +611,7 @@ void DevToolsURLLoaderInterceptor::GetResponseBody( const std::string& interception_id, std::unique_ptr<GetResponseBodyForInterceptionCallback> callback) { - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::IO}, base::BindOnce(&Impl::GetResponseBody, base::Unretained(impl_.get()), interception_id, std::move(callback))); @@ -625,7 +620,7 @@ void DevToolsURLLoaderInterceptor::TakeResponseBodyPipe( const std::string& interception_id, DevToolsNetworkInterceptor::TakeResponseBodyPipeCallback callback) { - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::IO}, base::BindOnce(&Impl::TakeResponseBodyPipe, base::Unretained(impl_.get()), interception_id, std::move(callback))); @@ -635,11 +630,10 @@ const std::string& interception_id, std::unique_ptr<Modifications> modifications, std::unique_ptr<ContinueInterceptedRequestCallback> callback) { - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&Impl::ContinueInterceptedRequest, - base::Unretained(impl_.get()), interception_id, - std::move(modifications), std::move(callback))); + base::PostTask(FROM_HERE, {BrowserThread::IO}, + base::BindOnce(&Impl::ContinueInterceptedRequest, + base::Unretained(impl_.get()), interception_id, + std::move(modifications), std::move(callback))); } bool DevToolsURLLoaderInterceptor::CreateProxyForInterception( @@ -756,7 +750,7 @@ std::unique_ptr<GetResponseBodyForInterceptionCallback> callback) { std::string error_reason; if (!CanGetResponseBody(&error_reason)) { - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce(&GetResponseBodyForInterceptionCallback::sendFailure, std::move(callback), @@ -776,7 +770,7 @@ TakeResponseBodyPipeCallback callback) { std::string error_reason; if (!CanGetResponseBody(&error_reason)) { - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce(std::move(callback), Response::Error(std::move(error_reason)), @@ -802,7 +796,7 @@ std::move(callback)) : base::BindOnce(&ContinueInterceptedRequestCallback::sendFailure, std::move(callback), std::move(response)); - base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(task)); + base::PostTask(FROM_HERE, {BrowserThread::UI}, std::move(task)); } void InterceptionJob::Detach() { @@ -1231,10 +1225,9 @@ create_loader_params_->request, cookie_line); waiting_for_resolution_ = true; - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::UI}, - base::BindOnce(interceptor_->request_intercepted_callback_, - std::move(request_info))); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(interceptor_->request_intercepted_callback_, + std::move(request_info))); } void InterceptionJob::Shutdown() { @@ -1381,7 +1374,7 @@ if (pending_response_body_pipe_callback_) { DCHECK_EQ(State::kResponseTaken, state_); DCHECK(!body_reader_); - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce(std::move(pending_response_body_pipe_callback_), Response::OK(), std::move(body),
diff --git a/content/browser/devtools/protocol/devtools_download_manager_delegate.cc b/content/browser/devtools/protocol/devtools_download_manager_delegate.cc index 3ef417e6..9fbcfe6f 100644 --- a/content/browser/devtools/protocol/devtools_download_manager_delegate.cc +++ b/content/browser/devtools/protocol/devtools_download_manager_delegate.cc
@@ -114,9 +114,10 @@ base::Bind(&DevToolsDownloadManagerDelegate::OnDownloadPathGenerated, base::Unretained(this), item->GetId(), callback); - PostTaskWithTraits( + PostTask( FROM_HERE, - {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN, + {base::ThreadPool(), base::MayBlock(), + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN, base::TaskPriority::USER_VISIBLE}, base::BindOnce(&DevToolsDownloadManagerDelegate::GenerateFilename, item->GetURL(), item->GetContentDisposition(), @@ -167,8 +168,8 @@ base::CreateDirectory(suggested_directory); base::FilePath suggested_path(suggested_directory.Append(generated_name)); - base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(callback, suggested_path)); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, + base::BindOnce(callback, suggested_path)); } void DevToolsDownloadManagerDelegate::OnDownloadPathGenerated(
diff --git a/content/browser/devtools/protocol/devtools_mhtml_helper.cc b/content/browser/devtools/protocol/devtools_mhtml_helper.cc index 2e3f8dc..4014ed1a 100644 --- a/content/browser/devtools/protocol/devtools_mhtml_helper.cc +++ b/content/browser/devtools/protocol/devtools_mhtml_helper.cc
@@ -17,14 +17,6 @@ namespace { -constexpr base::TaskTraits kBlockingSkippableTraits = { - // Requires IO. - base::MayBlock(), - - // TaskShutdownBehavior: use SKIP_ON_SHUTDOWN so that the helper's - // fields do not suddenly become invalid. - base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}; - void ClearFileReferenceOnIOThread( scoped_refptr<storage::ShareableFileReference>) {} @@ -37,7 +29,7 @@ DevToolsMHTMLHelper::~DevToolsMHTMLHelper() { if (mhtml_file_.get()) { - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::IO}, base::BindOnce(&ClearFileReferenceOnIOThread, std::move(mhtml_file_))); } @@ -49,8 +41,15 @@ std::unique_ptr<PageHandler::CaptureSnapshotCallback> callback) { scoped_refptr<DevToolsMHTMLHelper> helper = new DevToolsMHTMLHelper(page_handler, std::move(callback)); - base::PostTaskWithTraits( - FROM_HERE, kBlockingSkippableTraits, + base::PostTask( + FROM_HERE, + {base::ThreadPool(), + // Requires IO. + base::MayBlock(), + + // TaskShutdownBehavior: use SKIP_ON_SHUTDOWN so that the helper's + // fields do not suddenly become invalid. + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, base::BindOnce(&DevToolsMHTMLHelper::CreateTemporaryFile, helper)); } @@ -59,7 +58,7 @@ ReportFailure("Unable to create temporary file"); return; } - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::IO}, base::BindOnce(&DevToolsMHTMLHelper::TemporaryFileCreatedOnIO, this)); } @@ -72,8 +71,9 @@ mhtml_file_ = storage::ShareableFileReference::GetOrCreate( mhtml_snapshot_path_, storage::ShareableFileReference::DELETE_ON_FINAL_RELEASE, - base::CreateSequencedTaskRunnerWithTraits( - {// Requires IO. + base::CreateSequencedTaskRunner( + {base::ThreadPool(), + // Requires IO. base::MayBlock(), // Because we are using DELETE_ON_FINAL_RELEASE here, the @@ -83,7 +83,7 @@ base::TaskShutdownBehavior::BLOCK_SHUTDOWN}) .get()); - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce(&DevToolsMHTMLHelper::TemporaryFileCreatedOnUI, this)); } @@ -111,9 +111,15 @@ ReportFailure("Failed to generate MHTML"); return; } - base::PostTaskWithTraits( - FROM_HERE, kBlockingSkippableTraits, - base::BindOnce(&DevToolsMHTMLHelper::ReadMHTML, this)); + base::PostTask(FROM_HERE, + {base::ThreadPool(), + // Requires IO. + base::MayBlock(), + + // TaskShutdownBehavior: use SKIP_ON_SHUTDOWN so that the + // helper's fields do not suddenly become invalid. + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, + base::BindOnce(&DevToolsMHTMLHelper::ReadMHTML, this)); } void DevToolsMHTMLHelper::ReadMHTML() { @@ -130,7 +136,7 @@ void DevToolsMHTMLHelper::ReportFailure(const std::string& message) { if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce(&DevToolsMHTMLHelper::ReportFailure, this, message)); return; @@ -144,9 +150,9 @@ void DevToolsMHTMLHelper::ReportSuccess( std::unique_ptr<std::string> mhtml_snapshot) { if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { - base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&DevToolsMHTMLHelper::ReportSuccess, - this, std::move(mhtml_snapshot))); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(&DevToolsMHTMLHelper::ReportSuccess, this, + std::move(mhtml_snapshot))); return; } callback_->sendSuccess(*mhtml_snapshot);
diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc index 76ddadde..fce20e6a 100644 --- a/content/browser/devtools/protocol/network_handler.cc +++ b/content/browser/devtools/protocol/network_handler.cc
@@ -20,7 +20,6 @@ #include "base/time/time.h" #include "content/browser/background_sync/background_sync_manager.h" #include "content/browser/devtools/devtools_agent_host_impl.h" -#include "content/browser/devtools/devtools_interceptor_controller.h" #include "content/browser/devtools/devtools_io_context.h" #include "content/browser/devtools/devtools_stream_pipe.h" #include "content/browser/devtools/devtools_url_loader_interceptor.h" @@ -63,15 +62,12 @@ #include "net/cert/x509_certificate.h" #include "net/cert/x509_util.h" #include "net/cookies/canonical_cookie.h" -#include "net/cookies/cookie_store.h" #include "net/cookies/cookie_util.h" #include "net/http/http_response_headers.h" #include "net/http/http_status_code.h" #include "net/http/http_util.h" #include "net/ssl/ssl_cipher_suite_names.h" #include "net/ssl/ssl_connection_status_flags.h" -#include "net/url_request/url_request_context.h" -#include "net/url_request/url_request_context_getter.h" #include "services/network/public/cpp/data_element.h" #include "services/network/public/cpp/features.h" #include "services/network/public/cpp/http_raw_request_response_info.h" @@ -520,71 +516,16 @@ return protocol; } -class NetworkNavigationThrottle : public content::NavigationThrottle { - public: - NetworkNavigationThrottle( - base::WeakPtr<protocol::NetworkHandler> network_handler, - content::NavigationHandle* navigation_handle) - : content::NavigationThrottle(navigation_handle), - network_handler_(network_handler) {} - - ~NetworkNavigationThrottle() override {} - - // content::NavigationThrottle implementation: - NavigationThrottle::ThrottleCheckResult WillProcessResponse() override { - if (network_handler_ && network_handler_->ShouldCancelNavigation( - navigation_handle()->GetGlobalRequestID())) { - return CANCEL_AND_IGNORE; - } - return PROCEED; - } - - const char* GetNameForLogging() override { - return "DevToolsNetworkNavigationThrottle"; - } - - private: - base::WeakPtr<protocol::NetworkHandler> network_handler_; - DISALLOW_COPY_AND_ASSIGN(NetworkNavigationThrottle); -}; - -bool GetPostData(const net::URLRequest* request, std::string* post_data) { - if (!request->has_upload()) - return false; - - const net::UploadDataStream* stream = request->get_upload(); - if (!stream->GetElementReaders()) - return false; - - const auto* element_readers = stream->GetElementReaders(); - - if (element_readers->empty()) - return false; - - post_data->clear(); - for (const auto& element_reader : *element_readers) { - const net::UploadBytesElementReader* reader = - element_reader->AsBytesReader(); - // TODO(caseq): Also support blobs. - if (!reader) { - post_data->clear(); - return false; - } - // TODO(caseq): This should really be base64 encoded. - post_data->append(reader->bytes(), reader->length()); - } - return true; -} - -// TODO(caseq): all problems in the above function should be fixed here as well. bool GetPostData(const network::ResourceRequestBody& request_body, std::string* result) { const std::vector<network::DataElement>* elements = request_body.elements(); if (elements->empty()) return false; for (const auto& element : *elements) { + // TODO(caseq): Also support blobs. if (element.type() != network::mojom::DataElementType::kBytes) return false; + // TODO(caseq): This should rather be sent as Binary. result->append(element.bytes(), element.length()); } return true; @@ -810,7 +751,7 @@ static_cast<StoragePartitionImpl*>(storage_partition_) ->GetBackgroundSyncContext(); if (offline) { - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::IO}, base::BindOnce( &SetServiceWorkerOfflineOnIO, sync_context, @@ -819,10 +760,9 @@ service_worker_host->version_id(), offline_sw_registration_id_.get())); } else { - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&SetServiceWorkerOnlineOnIO, sync_context, - offline_sw_registration_id_.get())); + base::PostTask(FROM_HERE, {BrowserThread::IO}, + base::BindOnce(&SetServiceWorkerOnlineOnIO, sync_context, + offline_sw_registration_id_.get())); } } @@ -1099,7 +1039,6 @@ Response NetworkHandler::Disable() { enabled_ = false; - interception_handle_.reset(); url_loader_interceptor_.reset(); SetNetworkConditions(nullptr); extra_headers_.clear(); @@ -1792,7 +1731,6 @@ std::unique_ptr<protocol::Array<protocol::Network::RequestPattern>> patterns) { if (patterns->empty()) { - interception_handle_.reset(); if (url_loader_interceptor_) { url_loader_interceptor_.reset(); update_loader_factories_callback_.Run(); @@ -1820,38 +1758,15 @@ if (!host_) return Response::InternalError(); - if (base::FeatureList::IsEnabled(network::features::kNetworkService)) { - if (!url_loader_interceptor_) { - url_loader_interceptor_ = std::make_unique<DevToolsURLLoaderInterceptor>( - base::BindRepeating(&NetworkHandler::RequestIntercepted, - weak_factory_.GetWeakPtr())); - url_loader_interceptor_->SetPatterns(interceptor_patterns, true); - update_loader_factories_callback_.Run(); - } else { - url_loader_interceptor_->SetPatterns(interceptor_patterns, true); - } - return Response::OK(); - } - - WebContents* web_contents = WebContents::FromRenderFrameHost(host_); - if (!web_contents) - return Response::InternalError(); - - DevToolsInterceptorController* interceptor = - DevToolsInterceptorController::FromBrowserContext( - web_contents->GetBrowserContext()); - if (!interceptor) - return Response::Error("Interception not supported"); - - if (interception_handle_) { - interception_handle_->UpdatePatterns(interceptor_patterns); + if (!url_loader_interceptor_) { + url_loader_interceptor_ = + std::make_unique<DevToolsURLLoaderInterceptor>(base::BindRepeating( + &NetworkHandler::RequestIntercepted, weak_factory_.GetWeakPtr())); + url_loader_interceptor_->SetPatterns(interceptor_patterns, true); + update_loader_factories_callback_.Run(); } else { - interception_handle_ = interceptor->StartInterceptingRequests( - host_->frame_tree_node(), interceptor_patterns, - base::BindRepeating(&NetworkHandler::RequestIntercepted, - weak_factory_.GetWeakPtr())); + url_loader_interceptor_->SetPatterns(interceptor_patterns, true); } - return Response::OK(); } @@ -1949,38 +1864,21 @@ std::move(method), std::move(post_data), std::move(override_headers), std::move(override_auth)); - if (url_loader_interceptor_) { - url_loader_interceptor_->ContinueInterceptedRequest( - interception_id, std::move(modifications), std::move(callback)); + if (!url_loader_interceptor_) return; - } - DevToolsInterceptorController* interceptor = - DevToolsInterceptorController::FromBrowserContext(browser_context_); - if (!interceptor) { - callback->sendFailure(Response::InternalError()); - return; - } - interceptor->ContinueInterceptedRequest( + url_loader_interceptor_->ContinueInterceptedRequest( interception_id, std::move(modifications), std::move(callback)); } void NetworkHandler::GetResponseBodyForInterception( const String& interception_id, std::unique_ptr<GetResponseBodyForInterceptionCallback> callback) { - if (url_loader_interceptor_) { - url_loader_interceptor_->GetResponseBody(interception_id, - std::move(callback)); + if (!url_loader_interceptor_) return; - } - DevToolsInterceptorController* interceptor = - DevToolsInterceptorController::FromBrowserContext(browser_context_); - if (!interceptor) { - callback->sendFailure(Response::InternalError()); - return; - } - interceptor->GetResponseBody(interception_id, std::move(callback)); + url_loader_interceptor_->GetResponseBody(interception_id, + std::move(callback)); } void NetworkHandler::TakeResponseBodyForInterceptionAsStream( @@ -2060,58 +1958,6 @@ return request_object; } -// static -std::unique_ptr<Network::Request> NetworkHandler::CreateRequestFromURLRequest( - const net::URLRequest* request, - const std::string& cookie) { - std::unique_ptr<DictionaryValue> headers_dict(DictionaryValue::create()); - for (net::HttpRequestHeaders::Iterator it(request->extra_request_headers()); - it.GetNext();) { - headers_dict->setString(it.name(), it.value()); - } - if (!cookie.empty()) - headers_dict->setString(net::HttpRequestHeaders::kCookie, cookie); - if (!request->referrer().empty()) { - headers_dict->setString(net::HttpRequestHeaders::kReferer, - request->referrer()); - } - std::string url_fragment; - std::unique_ptr<protocol::Network::Request> request_object = - Network::Request::Create() - .SetUrl(ExtractFragment(request->url(), &url_fragment)) - .SetMethod(request->method()) - .SetHeaders(Object::fromValue(headers_dict.get(), nullptr)) - .SetInitialPriority(resourcePriority(request->priority())) - .SetReferrerPolicy(referrerPolicy(request->referrer_policy())) - .Build(); - if (!url_fragment.empty()) - request_object->SetUrlFragment(url_fragment); - std::string post_data; - if (GetPostData(request, &post_data)) - request_object->SetPostData(std::move(post_data)); - return request_object; -} - -std::unique_ptr<NavigationThrottle> NetworkHandler::CreateThrottleForNavigation( - NavigationHandle* navigation_handle) { - if (!interception_handle_) - return nullptr; - std::unique_ptr<NavigationThrottle> throttle(new NetworkNavigationThrottle( - weak_factory_.GetWeakPtr(), navigation_handle)); - return throttle; -} - -bool NetworkHandler::ShouldCancelNavigation( - const GlobalRequestID& global_request_id) { - WebContents* web_contents = WebContents::FromRenderFrameHost(host_); - if (!web_contents) - return false; - DevToolsInterceptorController* interceptor = - DevToolsInterceptorController::FromBrowserContext( - web_contents->GetBrowserContext()); - return interceptor && interceptor->ShouldCancelNavigation(global_request_id); -} - bool NetworkHandler::MaybeCreateProxyForInterception( RenderProcessHost* rph, const base::UnguessableToken& frame_token,
diff --git a/content/browser/devtools/protocol/network_handler.h b/content/browser/devtools/protocol/network_handler.h index d6c42bd2..6c11c0c1 100644 --- a/content/browser/devtools/protocol/network_handler.h +++ b/content/browser/devtools/protocol/network_handler.h
@@ -24,7 +24,6 @@ namespace net { class HttpRequestHeaders; -class URLRequest; class SSLInfo; class X509Certificate; } // namespace net @@ -41,13 +40,9 @@ class DevToolsIOContext; class RenderFrameHostImpl; class RenderProcessHost; -class InterceptionHandle; -class NavigationHandle; class NavigationRequest; -class NavigationThrottle; class SignedExchangeEnvelope; class StoragePartition; -struct GlobalRequestID; struct InterceptedRequestInfo; struct SignedExchangeError; @@ -206,13 +201,7 @@ static std::unique_ptr<Network::Request> CreateRequestFromResourceRequest( const network::ResourceRequest& request, const std::string& cookie_line); - static std::unique_ptr<Network::Request> CreateRequestFromURLRequest( - const net::URLRequest* request, - const std::string& cookie); - std::unique_ptr<NavigationThrottle> CreateThrottleForNavigation( - NavigationHandle* navigation_handle); - bool ShouldCancelNavigation(const GlobalRequestID& global_request_id); void WillSendNavigationRequest(net::HttpRequestHeaders* headers, bool* skip_service_worker, bool* disable_cache); @@ -239,7 +228,6 @@ RenderFrameHostImpl* host_; bool enabled_; std::vector<std::pair<std::string, std::string>> extra_headers_; - std::unique_ptr<InterceptionHandle> interception_handle_; std::unique_ptr<DevToolsURLLoaderInterceptor> url_loader_interceptor_; bool bypass_service_worker_; bool cache_disabled_;
diff --git a/content/browser/devtools/protocol/page_handler.cc b/content/browser/devtools/protocol/page_handler.cc index c5705ca..d48a742 100644 --- a/content/browser/devtools/protocol/page_handler.cc +++ b/content/browser/devtools/protocol/page_handler.cc
@@ -1173,8 +1173,9 @@ --frames_in_flight_; return; } - base::PostTaskWithTraitsAndReplyWithResult( - FROM_HERE, {base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + base::PostTaskAndReplyWithResult( + FROM_HERE, + {base::ThreadPool(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, base::BindOnce(&EncodeSkBitmap, bitmap, screencast_format_, screencast_quality_), base::BindOnce(&PageHandler::ScreencastFrameEncoded,
diff --git a/content/browser/devtools/protocol/service_worker_handler.cc b/content/browser/devtools/protocol/service_worker_handler.cc index 494cfb3e..5f4285b 100644 --- a/content/browser/devtools/protocol/service_worker_handler.cc +++ b/content/browser/devtools/protocol/service_worker_handler.cc
@@ -92,7 +92,7 @@ const base::Callback<void(int, int)>& callback) { if (content::ServiceWorkerVersion* version = context->GetLiveVersion(version_id)) { - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce( callback, version->embedded_worker()->process_id(), @@ -247,9 +247,8 @@ int64_t id = 0; if (!base::StringToInt64(version_id, &id)) return CreateInvalidVersionIdErrorResponse(); - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&StopServiceWorkerOnIO, context_, id)); + base::PostTask(FROM_HERE, {BrowserThread::IO}, + base::BindOnce(&StopServiceWorkerOnIO, context_, id)); return Response::OK(); } @@ -286,7 +285,7 @@ int64_t id = blink::mojom::kInvalidServiceWorkerVersionId; if (!base::StringToInt64(version_id, &id)) return CreateInvalidVersionIdErrorResponse(); - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::IO}, base::BindOnce(&GetDevToolsRouteInfoOnIO, context_, id, base::Bind(&ServiceWorkerHandler::OpenNewDevToolsWindow, @@ -340,10 +339,10 @@ BackgroundSyncContextImpl* sync_context = storage_partition_->GetBackgroundSyncContext(); - base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&DispatchSyncEventOnIO, context_, - base::WrapRefCounted(sync_context), - GURL(origin), id, tag, last_chance)); + base::PostTask(FROM_HERE, {BrowserThread::IO}, + base::BindOnce(&DispatchSyncEventOnIO, context_, + base::WrapRefCounted(sync_context), + GURL(origin), id, tag, last_chance)); return Response::OK(); }
diff --git a/content/browser/devtools/protocol/storage_handler.cc b/content/browser/devtools/protocol/storage_handler.cc index 40421045..0398bfe4 100644 --- a/content/browser/devtools/protocol/storage_handler.cc +++ b/content/browser/devtools/protocol/storage_handler.cc
@@ -82,7 +82,7 @@ int64_t quota, blink::mojom::UsageBreakdownPtr usage_breakdown) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce(ReportUsageAndQuotaDataOnUIThread, std::move(callback), code, usage, quota, std::move(usage_breakdown))); @@ -193,10 +193,9 @@ auto found = origins_.find(origin); if (found == origins_.end()) return; - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&StorageHandler::NotifyIndexedDBListChanged, owner_, - origin.Serialize())); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(&StorageHandler::NotifyIndexedDBListChanged, + owner_, origin.Serialize())); } void OnIndexedDBContentChanged( @@ -206,7 +205,7 @@ auto found = origins_.find(origin); if (found == origins_.end()) return; - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce(&StorageHandler::NotifyIndexedDBContentChanged, owner_, origin.Serialize(), database_name, object_store_name)); @@ -320,7 +319,7 @@ } storage::QuotaManager* manager = storage_partition_->GetQuotaManager(); - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::IO}, base::BindOnce(&GetUsageAndQuotaOnIOThread, base::RetainedRef(manager), url::Origin::Create(origin_url), std::move(callback)));
diff --git a/content/browser/devtools/protocol/system_info_handler.cc b/content/browser/devtools/protocol/system_info_handler.cc index 4f2663f5..fa675b7 100644 --- a/content/browser/devtools/protocol/system_info_handler.cc +++ b/content/browser/devtools/protocol/system_info_handler.cc
@@ -270,7 +270,7 @@ explicit SystemInfoHandlerGpuObserver( std::unique_ptr<GetInfoCallback> callback) : callback_(std::move(callback)) { - base::PostDelayedTaskWithTraits( + base::PostDelayedTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce(&SystemInfoHandlerGpuObserver::ObserverWatchdogCallback, weak_factory_.GetWeakPtr()), @@ -410,7 +410,7 @@ AddRendererProcessInfo(process_info.get()); // Collect child processes info on the IO thread. - base::PostTaskWithTraitsAndReplyWithResult( + base::PostTaskAndReplyWithResult( FROM_HERE, {BrowserThread::IO}, base::BindOnce(&AddChildProcessInfo, std::move(process_info)), base::BindOnce(&GetProcessInfoCallback::sendSuccess,
diff --git a/content/browser/devtools/protocol/tethering_handler.cc b/content/browser/devtools/protocol/tethering_handler.cc index 6d265507..eab85ac 100644 --- a/content/browser/devtools/protocol/tethering_handler.cc +++ b/content/browser/devtools/protocol/tethering_handler.cc
@@ -288,7 +288,7 @@ void TetheringHandler::TetheringImpl::Bind( uint16_t port, std::unique_ptr<BindCallback> callback) { if (bound_sockets_.find(port) != bound_sockets_.end()) { - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce(&BindCallback::sendFailure, std::move(callback), Response::Error("Port already bound"))); @@ -300,7 +300,7 @@ std::unique_ptr<BoundSocket> bound_socket = std::make_unique<BoundSocket>(std::move(accepted), socket_callback_); if (!bound_socket->Listen(port)) { - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce(&BindCallback::sendFailure, std::move(callback), Response::Error("Could not bind port"))); @@ -308,7 +308,7 @@ } bound_sockets_[port] = std::move(bound_socket); - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce(&BindCallback::sendSuccess, std::move(callback))); } @@ -317,7 +317,7 @@ uint16_t port, std::unique_ptr<UnbindCallback> callback) { auto it = bound_sockets_.find(port); if (it == bound_sockets_.end()) { - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce(&UnbindCallback::sendFailure, std::move(callback), Response::InvalidParams("Port is not bound"))); @@ -325,14 +325,14 @@ } bound_sockets_.erase(it); - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce(&UnbindCallback::sendSuccess, std::move(callback))); } void TetheringHandler::TetheringImpl::Accepted(uint16_t port, const std::string& name) { - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce(&TetheringHandler::Accepted, handler_, port, name)); }
diff --git a/content/browser/devtools/protocol/tracing_handler.cc b/content/browser/devtools/protocol/tracing_handler.cc index 2c0b1dfc..39f0db5 100644 --- a/content/browser/devtools/protocol/tracing_handler.cc +++ b/content/browser/devtools/protocol/tracing_handler.cc
@@ -143,10 +143,9 @@ void ReceiveTraceChunk(std::unique_ptr<std::string> chunk) override { if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&DevToolsStreamEndpoint::ReceiveTraceChunk, this, - std::move(chunk))); + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(&DevToolsStreamEndpoint::ReceiveTraceChunk, + this, std::move(chunk))); return; } @@ -156,7 +155,7 @@ void ReceiveTraceFinalContents( std::unique_ptr<const base::DictionaryValue> metadata) override { if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce(&DevToolsStreamEndpoint::ReceiveTraceFinalContents, this, std::move(metadata))); @@ -797,7 +796,7 @@ } // GPU process id can only be retrieved on IO thread. Do some thread hopping. - base::PostTaskWithTraitsAndReplyWithResult( + base::PostTaskAndReplyWithResult( FROM_HERE, {BrowserThread::IO}, base::BindOnce([]() { GpuProcessHost* gpu_process_host = GpuProcessHost::Get(GPU_PROCESS_KIND_SANDBOXED,
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc index 083269f9..023470d 100644 --- a/content/browser/devtools/render_frame_devtools_agent_host.cc +++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -730,7 +730,7 @@ static_cast<RenderFrameHostImpl*>(frame_host)->frame_tree_node())); if (dtah) { // Unblock the compositor. - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::UI}, base::BindOnce( &RenderFrameDevToolsAgentHost::SynchronousSwapCompositorFrame,
diff --git a/content/browser/devtools/service_worker_devtools_agent_host.cc b/content/browser/devtools/service_worker_devtools_agent_host.cc index ab26e45..d54149515 100644 --- a/content/browser/devtools/service_worker_devtools_agent_host.cc +++ b/content/browser/devtools/service_worker_devtools_agent_host.cc
@@ -111,7 +111,7 @@ } bool ServiceWorkerDevToolsAgentHost::Close() { - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {BrowserThread::IO}, base::BindOnce(&TerminateServiceWorkerOnIO, context_weak_, version_id_)); return true; @@ -195,10 +195,9 @@ } void ServiceWorkerDevToolsAgentHost::UpdateIsAttached(bool attached) { - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&SetDevToolsAttachedOnIO, context_weak_, version_id_, - attached)); + base::PostTask(FROM_HERE, {BrowserThread::IO}, + base::BindOnce(&SetDevToolsAttachedOnIO, context_weak_, + version_id_, attached)); } void ServiceWorkerDevToolsAgentHost::UpdateLoaderFactories( @@ -213,7 +212,7 @@ rph, worker_route_id_, origin); auto subresource_bundle = EmbeddedWorkerInstance::CreateFactoryBundleOnUI( rph, worker_route_id_, origin); - base::PostTaskWithTraitsAndReply( + base::PostTaskAndReply( FROM_HERE, {BrowserThread::IO}, base::BindOnce(&UpdateLoaderFactoriesOnIO, context_weak_, version_id_, std::move(script_bundle), std::move(subresource_bundle)),
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 4426758..57a65485 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -4176,9 +4176,12 @@ if (!permission_service_context_) permission_service_context_.reset(new PermissionServiceContext(this)); - registry_->AddInterface( - base::Bind(&PermissionServiceContext::CreateService, - base::Unretained(permission_service_context_.get()))); + registry_->AddInterface(base::BindRepeating( + [](PermissionServiceContext* context, + blink::mojom::PermissionServiceRequest request) { + context->CreateService(std::move(request)); + }, + base::Unretained(permission_service_context_.get()))); registry_->AddInterface( base::Bind(&RenderFrameHostImpl::BindPresentationServiceRequest,
diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc index 186febf64..f978b29 100644 --- a/content/browser/indexed_db/indexed_db_database.cc +++ b/content/browser/indexed_db/indexed_db_database.cc
@@ -69,30 +69,6 @@ namespace content { namespace { -// Used for WebCore.IndexedDB.Schema.ObjectStore.KeyPathType and -// WebCore.IndexedDB.Schema.Index.KeyPathType histograms. Do not -// modify (delete, re-order, renumber) these values other than -// the _MAX value. -enum HistogramIDBKeyPathType { - KEY_PATH_TYPE_NONE = 0, - KEY_PATH_TYPE_STRING = 1, - KEY_PATH_TYPE_ARRAY = 2, - KEY_PATH_TYPE_MAX = 3, // Keep as last/max entry, for histogram range. -}; - -HistogramIDBKeyPathType HistogramKeyPathType(const IndexedDBKeyPath& key_path) { - switch (key_path.type()) { - case blink::mojom::IDBKeyPathType::Null: - return KEY_PATH_TYPE_NONE; - case blink::mojom::IDBKeyPathType::String: - return KEY_PATH_TYPE_STRING; - case blink::mojom::IDBKeyPathType::Array: - return KEY_PATH_TYPE_ARRAY; - } - NOTREACHED(); - return KEY_PATH_TYPE_NONE; -} - IndexedDBDatabaseError CreateError(uint16_t code, const char* message, IndexedDBTransaction* transaction) { @@ -723,11 +699,6 @@ return; } - UMA_HISTOGRAM_ENUMERATION("WebCore.IndexedDB.Schema.ObjectStore.KeyPathType", - HistogramKeyPathType(key_path), KEY_PATH_TYPE_MAX); - UMA_HISTOGRAM_BOOLEAN("WebCore.IndexedDB.Schema.ObjectStore.AutoIncrement", - auto_increment); - // Store creation is done synchronously, as it may be followed by // index creation (also sync) since preemptive OpenCursor/SetIndexKeys // may follow. @@ -821,12 +792,6 @@ if (!ValidateObjectStoreIdAndNewIndexId(object_store_id, index_id)) return; - UMA_HISTOGRAM_ENUMERATION("WebCore.IndexedDB.Schema.Index.KeyPathType", - HistogramKeyPathType(key_path), KEY_PATH_TYPE_MAX); - UMA_HISTOGRAM_BOOLEAN("WebCore.IndexedDB.Schema.Index.Unique", unique); - UMA_HISTOGRAM_BOOLEAN("WebCore.IndexedDB.Schema.Index.MultiEntry", - multi_entry); - // TODO(dmurph): Remove this call once this method is asynchronous (scheduled // on the transaction). transaction->EnsureBackingStoreTransactionBegun();
diff --git a/content/browser/loader/cross_site_document_blocking_browsertest.cc b/content/browser/loader/cross_site_document_blocking_browsertest.cc index 421f09ee..bfdc53f 100644 --- a/content/browser/loader/cross_site_document_blocking_browsertest.cc +++ b/content/browser/loader/cross_site_document_blocking_browsertest.cc
@@ -95,21 +95,15 @@ const std::string& resource_name, ResourceType resource_type, bool special_request_initiator_origin_lock_check_for_appcache = false) { - // //services/network doesn't have access to content::ResourceType and - // therefore cannot log some CORB UMAs. - bool is_restricted_uma_expected = false; - if (base::FeatureList::IsEnabled(network::features::kNetworkService)) { - is_restricted_uma_expected = true; - FetchHistogramsFromChildProcesses(); + FetchHistogramsFromChildProcesses(); - auto expected_lock_compatibility = - special_request_initiator_origin_lock_check_for_appcache - ? network::InitiatorLockCompatibility::kBrowserProcess - : network::InitiatorLockCompatibility::kCompatibleLock; - histograms.ExpectUniqueSample( - "NetworkService.URLLoader.RequestInitiatorOriginLockCompatibility", - expected_lock_compatibility, 1); - } + auto expected_lock_compatibility = + special_request_initiator_origin_lock_check_for_appcache + ? network::InitiatorLockCompatibility::kBrowserProcess + : network::InitiatorLockCompatibility::kCompatibleLock; + histograms.ExpectUniqueSample( + "NetworkService.URLLoader.RequestInitiatorOriginLockCompatibility", + expected_lock_compatibility, 1); CorbMimeType expected_mime_type = CorbMimeType::kInvalidMimeType; if (base::MatchPattern(resource_name, "*.html")) { @@ -470,14 +464,9 @@ VerifyImgRequest(resource, expectations, GURL("http://foo.com/title1.html")); - // Pre-NetworkService CORB implementation doesn't have an equivalent of - // URLLoaderFactoryParams::is_corb_enabled and therefore there is no way to - // turn off CORB only when allow_universal_access_from_file_urls is false. - if (base::FeatureList::IsEnabled(network::features::kNetworkService)) { - // Test from a file: origin. - VerifyImgRequest(resource, expectations, - GetTestUrl(nullptr, "title1.html")); - } + // Test from a file: origin. + VerifyImgRequest(resource, expectations, + GetTestUrl(nullptr, "title1.html")); } void VerifyImgRequest(std::string resource, @@ -956,13 +945,9 @@ )"; EXPECT_TRUE(ExecJs(shell(), JsReplace(kFetchStartTemplate, bar_url))); - // Verify the intercepted request (intercepting requests from SharedWorkers is - // only possible when NetworkService is enabled). - if (base::FeatureList::IsEnabled(network::features::kNetworkService)) { - interceptor.WaitForRequestCompletion(); - interceptor.Verify(kShouldBeBlockedWithoutSniffing, - "no resource body needed for blocking verification"); - } + interceptor.WaitForRequestCompletion(); + interceptor.Verify(kShouldBeBlockedWithoutSniffing, + "no resource body needed for blocking verification"); // Wait for fetch result (really needed only without NetworkService, if no // interceptor.WaitForRequestCompletion was called above). @@ -1091,11 +1076,6 @@ AppCache_InitiatorEnforcement) { embedded_test_server()->StartAcceptingConnections(); - // Verification of |request_initiator| is only done in the NetworkService code - // path. - if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) - return; - // No kills are expected unless the fetch requesting process is locked to a // specific site URL. Therefore, the test should be skipped unless the full // Site Isolation is enabled. @@ -1151,11 +1131,6 @@ AppCache_NoNavigationsEnforcement) { embedded_test_server()->StartAcceptingConnections(); - // Verification of |request_initiator| is only done in the NetworkService code - // path. - if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) - return; - // No kills are expected unless the fetch requesting process is locked to a // specific site URL. Therefore, the test should be skipped unless the full // Site Isolation is enabled. @@ -1362,17 +1337,11 @@ ExecuteScriptAsync(shell()->web_contents(), script); interceptor.WaitForRequestCompletion(); - if (base::FeatureList::IsEnabled(network::features::kNetworkService)) { - // NetworkService enforices |request_initiator_site_lock| for CORB, - // which means that legitimate fetches from HTML Imported scripts may get - // incorrectly blocked. - interceptor.Verify(CorbExpectations::kShouldBeBlockedWithoutSniffing, - "no resource body needed for blocking verification"); - } else { - // Without |request_initiator_site_lock| no CORB blocking is expected. - interceptor.Verify(CorbExpectations::kShouldBeAllowedWithoutSniffing, - GetTestFileContents("site_isolation", "nosniff.json")); - } + // NetworkService enforices |request_initiator_site_lock| for CORB, + // which means that legitimate fetches from HTML Imported scripts may get + // incorrectly blocked. + interceptor.Verify(CorbExpectations::kShouldBeBlockedWithoutSniffing, + "no resource body needed for blocking verification"); } } @@ -1620,8 +1589,7 @@ // Make sure that the histograms generated by a service worker registration // have been recorded. - if (base::FeatureList::IsEnabled(network::features::kNetworkService)) - FetchHistogramsFromChildProcesses(); + FetchHistogramsFromChildProcesses(); // Build a script for XHR-ing a cross-origin, nosniff HTML document. GURL cross_origin_url =
diff --git a/content/browser/media/android/media_player_renderer.cc b/content/browser/media/android/media_player_renderer.cc index a93d75a..8ea9497 100644 --- a/content/browser/media/android/media_player_renderer.cc +++ b/content/browser/media/android/media_player_renderer.cc
@@ -127,7 +127,7 @@ url_params.media_url, url_params.site_for_cookies, user_agent, false, // hide_url_log this, // MediaPlayerBridge::Client - allow_credentials)); + allow_credentials, url_params.is_hls)); media_player_->Initialize(); UpdateVolume();
diff --git a/content/browser/native_file_system/native_file_system_handle_base.cc b/content/browser/native_file_system/native_file_system_handle_base.cc index 44d1b69..7a5b202 100644 --- a/content/browser/native_file_system/native_file_system_handle_base.cc +++ b/content/browser/native_file_system/native_file_system_handle_base.cc
@@ -23,12 +23,16 @@ is_directory_(is_directory), directory_path_(directory_path) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (web_contents() && is_directory_) - web_contents()->AddNativeFileSystemDirectoryHandle(directory_path_); + if (web_contents()) { + web_contents()->IncrementNativeFileSystemHandleCount(); + if (is_directory_) + web_contents()->AddNativeFileSystemDirectoryHandle(directory_path_); + } } ~UsageIndicatorTracker() override { if (web_contents()) { + web_contents()->DecrementNativeFileSystemHandleCount(); if (is_directory_ && is_readable_) web_contents()->RemoveNativeFileSystemDirectoryHandle(directory_path_); if (is_writable_)
diff --git a/content/browser/permissions/permission_service_context.cc b/content/browser/permissions/permission_service_context.cc index 8a4e881..ed539c4 100644 --- a/content/browser/permissions/permission_service_context.cc +++ b/content/browser/permissions/permission_service_context.cc
@@ -15,17 +15,17 @@ #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" - -using blink::mojom::PermissionObserverPtr; +#include "mojo/public/cpp/bindings/remote.h" namespace content { class PermissionServiceContext::PermissionSubscription { public: - PermissionSubscription(PermissionServiceContext* context, - PermissionObserverPtr observer) + PermissionSubscription( + PermissionServiceContext* context, + mojo::PendingRemote<blink::mojom::PermissionObserver> observer) : context_(context), observer_(std::move(observer)) { - observer_.set_connection_error_handler(base::BindOnce( + observer_.set_disconnect_handler(base::BindOnce( &PermissionSubscription::OnConnectionError, base::Unretained(this))); } @@ -51,7 +51,7 @@ private: PermissionServiceContext* context_; - PermissionObserverPtr observer_; + mojo::Remote<blink::mojom::PermissionObserver> observer_; int id_ = 0; }; @@ -73,30 +73,38 @@ } void PermissionServiceContext::CreateService( - blink::mojom::PermissionServiceRequest request) { + mojo::PendingReceiver<blink::mojom::PermissionService> receiver) { DCHECK(render_frame_host_); - services_.AddBinding(std::make_unique<PermissionServiceImpl>( - this, render_frame_host_->GetLastCommittedOrigin()), - std::move(request)); + services_.Add(std::make_unique<PermissionServiceImpl>( + this, render_frame_host_->GetLastCommittedOrigin()), + std::move(receiver)); } void PermissionServiceContext::CreateServiceForWorker( - blink::mojom::PermissionServiceRequest request, + mojo::PendingReceiver<blink::mojom::PermissionService> receiver, const url::Origin& origin) { - services_.AddBinding(std::make_unique<PermissionServiceImpl>(this, origin), - std::move(request)); + services_.Add(std::make_unique<PermissionServiceImpl>(this, origin), + std::move(receiver)); } void PermissionServiceContext::CreateSubscription( PermissionType permission_type, const url::Origin& origin, - PermissionObserverPtr observer) { + blink::mojom::PermissionStatus current_status, + blink::mojom::PermissionStatus last_known_status, + mojo::PendingRemote<blink::mojom::PermissionObserver> observer) { BrowserContext* browser_context = GetBrowserContext(); if (!browser_context) return; auto subscription = std::make_unique<PermissionSubscription>(this, std::move(observer)); + + if (current_status != last_known_status) { + subscription->OnPermissionStatusChanged(current_status); + last_known_status = current_status; + } + GURL requesting_origin(origin.Serialize()); int subscription_id = PermissionControllerImpl::FromBrowserContext(browser_context) @@ -139,7 +147,7 @@ if (render_frame_host != render_frame_host_) return; - services_.CloseAllBindings(); + services_.Clear(); subscriptions_.clear(); }
diff --git a/content/browser/permissions/permission_service_context.h b/content/browser/permissions/permission_service_context.h index 4670db4..4b6d362 100644 --- a/content/browser/permissions/permission_service_context.h +++ b/content/browser/permissions/permission_service_context.h
@@ -9,7 +9,9 @@ #include "content/common/content_export.h" #include "content/public/browser/permission_type.h" #include "content/public/browser/web_contents_observer.h" -#include "mojo/public/cpp/bindings/strong_binding_set.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/unique_receiver_set.h" #include "third_party/blink/public/mojom/permissions/permission.mojom.h" namespace url { @@ -32,13 +34,18 @@ explicit PermissionServiceContext(RenderProcessHost* render_process_host); ~PermissionServiceContext() override; - void CreateService(blink::mojom::PermissionServiceRequest request); - void CreateServiceForWorker(blink::mojom::PermissionServiceRequest request, - const url::Origin& origin); + void CreateService( + mojo::PendingReceiver<blink::mojom::PermissionService> receiver); + void CreateServiceForWorker( + mojo::PendingReceiver<blink::mojom::PermissionService> receiver, + const url::Origin& origin); - void CreateSubscription(PermissionType permission_type, - const url::Origin& origin, - blink::mojom::PermissionObserverPtr observer); + void CreateSubscription( + PermissionType permission_type, + const url::Origin& origin, + blink::mojom::PermissionStatus current_status, + blink::mojom::PermissionStatus last_known_status, + mojo::PendingRemote<blink::mojom::PermissionObserver> observer); // Called when the connection to a PermissionObserver has an error. void ObserverHadConnectionError(int subscription_id); @@ -56,10 +63,6 @@ private: class PermissionSubscription; - void CreateServiceForWorkerImpl( - blink::mojom::PermissionServiceRequest request, - const url::Origin& origin); - // WebContentsObserver void RenderFrameHostChanged(RenderFrameHost* old_host, RenderFrameHost* new_host) override; @@ -70,7 +73,7 @@ RenderFrameHost* render_frame_host_; RenderProcessHost* render_process_host_; - mojo::StrongBindingSet<blink::mojom::PermissionService> services_; + mojo::UniqueReceiverSet<blink::mojom::PermissionService> services_; std::unordered_map<int, std::unique_ptr<PermissionSubscription>> subscriptions_;
diff --git a/content/browser/permissions/permission_service_impl.cc b/content/browser/permissions/permission_service_impl.cc index 4c5760c..4fffcdd 100644 --- a/content/browser/permissions/permission_service_impl.cc +++ b/content/browser/permissions/permission_service_impl.cc
@@ -22,7 +22,6 @@ using blink::mojom::PermissionDescriptorPtr; using blink::mojom::PermissionName; -using blink::mojom::PermissionObserverPtr; using blink::mojom::PermissionStatus; namespace content { @@ -267,20 +266,15 @@ void PermissionServiceImpl::AddPermissionObserver( PermissionDescriptorPtr permission, PermissionStatus last_known_status, - PermissionObserverPtr observer) { - PermissionStatus current_status = GetPermissionStatus(permission); - if (current_status != last_known_status) { - observer->OnPermissionStatusChange(current_status); - last_known_status = current_status; - } - + mojo::PendingRemote<blink::mojom::PermissionObserver> observer) { PermissionType type; if (!PermissionDescriptorToPermissionType(permission, &type)) { ReceivedBadMessage(); return; } - context_->CreateSubscription(type, origin_, std::move(observer)); + context_->CreateSubscription(type, origin_, GetPermissionStatus(permission), + last_known_status, std::move(observer)); } PermissionStatus PermissionServiceImpl::GetPermissionStatus(
diff --git a/content/browser/permissions/permission_service_impl.h b/content/browser/permissions/permission_service_impl.h index a1bca4f..9f7d6c11 100644 --- a/content/browser/permissions/permission_service_impl.h +++ b/content/browser/permissions/permission_service_impl.h
@@ -11,6 +11,7 @@ #include "base/memory/weak_ptr.h" #include "content/browser/permissions/permission_service_context.h" #include "content/common/content_export.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "third_party/blink/public/mojom/permissions/permission.mojom.h" #include "url/origin.h" @@ -56,7 +57,7 @@ void AddPermissionObserver( blink::mojom::PermissionDescriptorPtr permission, blink::mojom::PermissionStatus last_known_status, - blink::mojom::PermissionObserverPtr observer) override; + mojo::PendingRemote<blink::mojom::PermissionObserver> observer) override; void OnRequestPermissionsResponse( int pending_request_id,
diff --git a/content/browser/renderer_host/render_widget_host_view_event_handler.cc b/content/browser/renderer_host/render_widget_host_view_event_handler.cc index 21f93de0..6074939 100644 --- a/content/browser/renderer_host/render_widget_host_view_event_handler.cc +++ b/content/browser/renderer_host/render_widget_host_view_event_handler.cc
@@ -123,7 +123,6 @@ mouse_locked_(false), pinch_zoom_enabled_(content::IsPinchToZoomEnabled()), set_focus_on_mouse_down_or_key_event_(false), - synthetic_move_sent_(false), enable_consolidated_movement_( base::FeatureList::IsEnabled(features::kConsolidatedMovementXY)), host_(host), @@ -745,8 +744,6 @@ } } } else { - gfx::Point center(gfx::Rect(window_->bounds().size()).CenterPoint()); - // If we receive non client mouse messages while we are in the locked state // it probably means that the mouse left the borders of our window and // needs to be moved back to the center. @@ -759,37 +756,12 @@ blink::WebMouseEvent mouse_event = ui::MakeWebMouseEvent(*event); - bool is_move_to_center_event = - (event->type() == ui::ET_MOUSE_MOVED || - event->type() == ui::ET_MOUSE_DRAGGED) && - mouse_event.PositionInWidget().x == center.x() && - mouse_event.PositionInWidget().y == center.y(); - - // For fractional scale factors, the conversion from pixels to dip and - // vice versa could result in off by 1 or 2 errors which hurts us because - // we want to avoid sending the artificial move to center event to the - // renderer. Sending the move to center to the renderer cause the cursor - // to bounce around the center of the screen leading to the lock operation - // not working correctly. - // Workaround is to treat a mouse move or drag event off by at most 2 px - // from the center as a move to center event. - if (synthetic_move_sent_ && - IsFractionalScaleFactor(host_view_->current_device_scale_factor())) { - if (event->type() == ui::ET_MOUSE_MOVED || - event->type() == ui::ET_MOUSE_DRAGGED) { - if ((std::abs(mouse_event.PositionInWidget().x - center.x()) <= 2) && - (std::abs(mouse_event.PositionInWidget().y - center.y()) <= 2)) { - is_move_to_center_event = true; - } - } - } - - bool should_not_forward = is_move_to_center_event && synthetic_move_sent_; + bool should_not_forward = MatchesSynthesizedMovePosition(mouse_event); ModifyEventMovementAndCoords(*event, &mouse_event); if (!enable_consolidated_movement_ && should_not_forward) { - synthetic_move_sent_ = false; + synthetic_move_position_.reset(); } else { bool is_selection_popup = NeedsInputGrab(popup_child_host_view_); // Forward event to renderer. @@ -812,8 +784,9 @@ // stored global_mouse_position_. if (ShouldMoveToCenter(enable_consolidated_movement_ ? gfx::PointF(mouse_event.PositionInScreen()) - : global_mouse_position_)) + : global_mouse_position_)) { MoveCursorToCenter(event); + } } } if (!ShouldGenerateAppCommand(event)) @@ -855,9 +828,8 @@ // consolidated_movement disabled. We can not guarantee that |MoveCursorTo| // is taking effect immediately, so wait for the event that has matching // coordiantes to marked as synthesized event. - if (enable_consolidated_movement_ && synthetic_move_position_.has_value() && - synthetic_move_position_.value() == - gfx::ToRoundedPoint(event->PositionInScreen())) { + if (enable_consolidated_movement_ && mouse_locked_ && + MatchesSynthesizedMovePosition(*event)) { event->SetModifiers(event->GetModifiers() | blink::WebInputEvent::Modifiers::kRelativeMotionEvent); synthetic_move_position_.reset(); @@ -883,33 +855,55 @@ void RenderWidgetHostViewEventHandler::MoveCursorToCenter( ui::MouseEvent* event) { - gfx::PointF center_in_screen(window_->GetBoundsInScreen().CenterPoint()); + gfx::Point center(gfx::Rect(window_->bounds().size()).CenterPoint()); + gfx::Point center_in_screen(window_->GetBoundsInScreen().CenterPoint()); + window_->MoveCursorTo(center); #if defined(OS_WIN) // TODO(crbug.com/781182): Set the global position when move cursor to center. // This is a workaround for a bug from Windows update 16299, and should be // remove once the bug is fixed in OS. When consolidate_movement_ flag is // enabled, send a synthesized event to update the blink side states. - global_mouse_position_ = center_in_screen; + global_mouse_position_ = gfx::PointF(center_in_screen); if (enable_consolidated_movement_ && event) { blink::WebMouseEvent mouse_event = ui::MakeWebMouseEvent(*event); mouse_event.SetModifiers( mouse_event.GetModifiers() | blink::WebInputEvent::Modifiers::kRelativeMotionEvent); - mouse_event.SetPositionInScreen(center_in_screen); + mouse_event.SetPositionInScreen(gfx::PointF(center_in_screen)); if (ShouldRouteEvents()) { host_->delegate()->GetInputEventRouter()->RouteMouseEvent( - host_view_, &mouse_event, *event->latency()); + host_view_, &mouse_event, ui::LatencyInfo()); } else { - ProcessMouseEvent(mouse_event, *event->latency()); + ProcessMouseEvent(mouse_event, ui::LatencyInfo()); + } + return; + } +#endif + synthetic_move_position_ = center_in_screen; +} + +bool RenderWidgetHostViewEventHandler::MatchesSynthesizedMovePosition( + const blink::WebMouseEvent& event) { + if (event.GetType() == blink::WebInputEvent::kMouseMove && + synthetic_move_position_.has_value()) { + if (IsFractionalScaleFactor(host_view_->current_device_scale_factor())) { + // For fractional scale factors, the conversion from pixels to dip and + // vice versa could result in off by 1 or 2 errors which hurts us because + // the artificial move to center event cause the cursor to bounce around + // the center of the screen leading to the lock operation not working + // correctly. Workaround is to treat a mouse move or drag event off by + // atmost 2 px from the center as a move to center event. + // TODO(crbug.com/991236): figure out a way to avoid the conversion error. + return ((std::abs(event.PositionInScreen().x - + synthetic_move_position_->x()) <= 2) && + (std::abs(event.PositionInScreen().y - + synthetic_move_position_->y()) <= 2)); + } else { + return synthetic_move_position_.value() == + gfx::ToRoundedPoint(event.PositionInScreen()); } } -#else - synthetic_move_sent_ = true; -#endif - - gfx::Point center(gfx::Rect(window_->bounds().size()).CenterPoint()); - window_->MoveCursorTo(center); - synthetic_move_position_ = gfx::ToFlooredPoint(center_in_screen); + return false; } void RenderWidgetHostViewEventHandler::SetKeyboardFocus() {
diff --git a/content/browser/renderer_host/render_widget_host_view_event_handler.h b/content/browser/renderer_host/render_widget_host_view_event_handler.h index 9d620c8..a12e6af 100644 --- a/content/browser/renderer_host/render_widget_host_view_event_handler.h +++ b/content/browser/renderer_host/render_widget_host_view_event_handler.h
@@ -217,6 +217,9 @@ // moved to center. bool ShouldMoveToCenter(gfx::PointF mouse_screen_position); + // Return whether the event is a synthesized move from |MoveCursorTo|. + bool MatchesSynthesizedMovePosition(const blink::WebMouseEvent& event); + // Returns true when we can hit test input events with location data to be // sent to the targeted RenderWidgetHost. bool ShouldRouteEvents() const; @@ -268,12 +271,11 @@ gfx::PointF global_mouse_position_; // In mouse locked mode, we synthetically move the mouse cursor to the center // of the window when it reaches the window borders to avoid it going outside. - // This flag is used to differentiate between these synthetic mouse move + // This value is used to differentiate between these synthetic mouse move // events vs. normal mouse move events. - bool synthetic_move_sent_; + base::Optional<gfx::Point> synthetic_move_position_; bool enable_consolidated_movement_; - base::Optional<gfx::Point> synthetic_move_position_; // Stores the current state of the active pointers targeting this // object.
diff --git a/content/browser/service_worker/service_worker_new_script_loader.cc b/content/browser/service_worker/service_worker_new_script_loader.cc index 74c6dac..8e23de22 100644 --- a/content/browser/service_worker/service_worker_new_script_loader.cc +++ b/content/browser/service_worker/service_worker_new_script_loader.cc
@@ -46,7 +46,7 @@ }; std::unique_ptr<ServiceWorkerNewScriptLoader> -ServiceWorkerNewScriptLoader::CreateForNetworkOnly( +ServiceWorkerNewScriptLoader::CreateAndStart( int32_t routing_id, int32_t request_id, uint32_t options, @@ -60,17 +60,6 @@ version, loader_factory, traffic_annotation)); } -std::unique_ptr<ServiceWorkerNewScriptLoader> -ServiceWorkerNewScriptLoader::CreateForResume( - uint32_t options, - const network::ResourceRequest& original_request, - network::mojom::URLLoaderClientPtr client, - scoped_refptr<ServiceWorkerVersion> version) { - DCHECK(blink::ServiceWorkerUtils::IsImportedScriptUpdateCheckEnabled()); - return base::WrapUnique(new ServiceWorkerNewScriptLoader( - options, original_request, std::move(client), version)); -} - // TODO(nhiroki): We're doing multiple things in the ctor. Consider factors out // some of them into a separate function. ServiceWorkerNewScriptLoader::ServiceWorkerNewScriptLoader( @@ -84,18 +73,14 @@ const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) : request_url_(original_request.url), resource_type_(static_cast<ResourceType>(original_request.resource_type)), + original_options_(options), version_(version), network_client_binding_(this), network_watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL, base::SequencedTaskRunnerHandle::Get()), loader_factory_(std::move(loader_factory)), - client_(std::move(client)), - original_options_(options), - type_(Type::kNetworkOnly), - client_producer_watcher_(FROM_HERE, - mojo::SimpleWatcher::ArmingPolicy::MANUAL, - base::SequencedTaskRunnerHandle::Get()) { + client_(std::move(client)) { network::ResourceRequest resource_request(original_request); #if DCHECK_IS_ON() CheckVersionStatusBeforeLoad(); @@ -170,80 +155,8 @@ loader_factory_->CreateLoaderAndStart( mojo::MakeRequest(&network_loader_), routing_id, request_id, options, resource_request, std::move(network_client), traffic_annotation); - DCHECK_EQ(NetworkLoaderState::kNotStarted, network_loader_state_); - network_loader_state_ = NetworkLoaderState::kLoadingHeader; -} - -ServiceWorkerNewScriptLoader::ServiceWorkerNewScriptLoader( - uint32_t options, - const network::ResourceRequest& original_request, - network::mojom::URLLoaderClientPtr client, - scoped_refptr<ServiceWorkerVersion> version) - : request_url_(original_request.url), - resource_type_(static_cast<ResourceType>(original_request.resource_type)), - version_(std::move(version)), - network_client_binding_(this), - network_watcher_(FROM_HERE, - mojo::SimpleWatcher::ArmingPolicy::MANUAL, - base::SequencedTaskRunnerHandle::Get()), - client_(std::move(client)), - original_options_(options), - type_(Type::kResume), - client_producer_watcher_(FROM_HERE, - mojo::SimpleWatcher::ArmingPolicy::MANUAL, - base::SequencedTaskRunnerHandle::Get()), - request_start_(base::TimeTicks::Now()) { -#if DCHECK_IS_ON() - CheckVersionStatusBeforeLoad(); -#endif // DCHECK_IS_ON() - - DCHECK(client_); - ServiceWorkerUpdateChecker::ComparedScriptInfo info = - version_->TakeComparedScriptInfo(request_url_); - if (info.result == ServiceWorkerSingleScriptUpdateChecker::Result::kFailed) { - DCHECK(!info.paused_state); - // A network error received during update checking. This replays it. - CommitCompleted(info.failure_info->network_status, - info.failure_info->error_message); - return; - } - - cache_writer_ = std::move(info.paused_state->cache_writer); - DCHECK(cache_writer_); - - network_loader_ = std::move(info.paused_state->network_loader); - DCHECK(network_loader_); - - network_client_request_ = - std::move(info.paused_state->network_client_request); - DCHECK(network_client_request_); - - network_consumer_ = std::move(info.paused_state->network_consumer); - - // Headers must have already been received during update check. - header_writer_state_ = WriterState::kCompleted; - - network_loader_state_ = info.paused_state->network_loader_state; - DCHECK(network_loader_state_ == NetworkLoaderState::kLoadingBody || - network_loader_state_ == NetworkLoaderState::kCompleted); - - body_writer_state_ = info.paused_state->body_writer_state; - DCHECK(body_writer_state_ == WriterState::kWriting || - body_writer_state_ == WriterState::kCompleted); - - version_->script_cache_map()->NotifyStartedCaching( - request_url_, cache_writer_->WriterResourceId()); - - // Resume the cache writer and observe its writes, so all data written - // is sent to |client_|. - cache_writer_->set_write_observer(this); - net::Error error = cache_writer_->Resume( - base::BindOnce(&ServiceWorkerNewScriptLoader::OnCacheWriterResumed, - weak_factory_.GetWeakPtr())); - - if (error != net::ERR_IO_PENDING) { - OnCacheWriterResumed(error); - } + DCHECK_EQ(LoaderState::kNotStarted, network_loader_state_); + network_loader_state_ = LoaderState::kLoadingHeader; } ServiceWorkerNewScriptLoader::~ServiceWorkerNewScriptLoader() = default; @@ -277,8 +190,7 @@ void ServiceWorkerNewScriptLoader::OnReceiveResponse( const network::ResourceResponseHead& response_head) { - DCHECK_EQ(type_, Type::kNetworkOnly); - DCHECK_EQ(NetworkLoaderState::kLoadingHeader, network_loader_state_); + DCHECK_EQ(LoaderState::kLoadingHeader, network_loader_state_); if (!version_->context() || version_->is_redundant()) { CommitCompleted(network::URLLoaderCompletionStatus(net::ERR_FAILED), ServiceWorkerConsts::kServiceWorkerFetchScriptError); @@ -321,7 +233,7 @@ version_->SetMainScriptHttpResponseInfo(*response_info); } - network_loader_state_ = NetworkLoaderState::kWaitingForBody; + network_loader_state_ = LoaderState::kWaitingForBody; WriteHeaders( base::MakeRefCounted<HttpResponseInfoIOBuffer>(std::move(response_info))); @@ -342,7 +254,6 @@ void ServiceWorkerNewScriptLoader::OnReceiveRedirect( const net::RedirectInfo& redirect_info, const network::ResourceResponseHead& response_head) { - DCHECK_EQ(type_, Type::kNetworkOnly); // Resource requests for service worker scripts should not follow redirects. // // Step 9.5: "Set request's redirect mode to "error"." @@ -357,7 +268,6 @@ int64_t current_position, int64_t total_size, OnUploadProgressCallback ack_callback) { - DCHECK_EQ(type_, Type::kNetworkOnly); client_->OnUploadProgress(current_position, total_size, std::move(ack_callback)); } @@ -374,8 +284,7 @@ void ServiceWorkerNewScriptLoader::OnStartLoadingResponseBody( mojo::ScopedDataPipeConsumerHandle consumer) { - DCHECK_EQ(type_, Type::kNetworkOnly); - DCHECK_EQ(NetworkLoaderState::kWaitingForBody, network_loader_state_); + DCHECK_EQ(LoaderState::kWaitingForBody, network_loader_state_); // Create a pair of the consumer and producer for responding to the client. mojo::ScopedDataPipeConsumerHandle client_consumer; if (mojo::CreateDataPipe(nullptr, &client_producer_, &client_consumer) != @@ -389,196 +298,46 @@ client_->OnStartLoadingResponseBody(std::move(client_consumer)); network_consumer_ = std::move(consumer); - network_loader_state_ = NetworkLoaderState::kLoadingBody; + network_loader_state_ = LoaderState::kLoadingBody; MaybeStartNetworkConsumerHandleWatcher(); } void ServiceWorkerNewScriptLoader::OnComplete( const network::URLLoaderCompletionStatus& status) { - NetworkLoaderState previous_state = network_loader_state_; - network_loader_state_ = NetworkLoaderState::kCompleted; + LoaderState previous_state = network_loader_state_; + network_loader_state_ = LoaderState::kCompleted; if (status.error_code != net::OK) { CommitCompleted(status, ServiceWorkerConsts::kServiceWorkerFetchScriptError); return; } - // Response body is empty. - if (previous_state == NetworkLoaderState::kWaitingForBody) { - // Type::kResume doesn't reach here since OnComplete() must have been - // called during update check when the body is empty. - DCHECK_EQ(type_, Type::kNetworkOnly); - DCHECK_EQ(WriterState::kNotStarted, body_writer_state_); - body_writer_state_ = WriterState::kCompleted; - switch (header_writer_state_) { - case WriterState::kNotStarted: - NOTREACHED() - << "Response header should be received before OnComplete()"; - break; - case WriterState::kWriting: - // Wait until it's written. OnWriteHeadersComplete() will call - // CommitCompleted(). - return; - case WriterState::kCompleted: - DCHECK(!network_consumer_.is_valid()); - CommitCompleted(network::URLLoaderCompletionStatus(net::OK), - std::string() /* status_message */); - return; - } - NOTREACHED(); - } + DCHECK_EQ(LoaderState::kLoadingBody, previous_state); - // Response body exists. - if (previous_state == NetworkLoaderState::kLoadingBody) { - switch (body_writer_state_) { - case WriterState::kNotStarted: - DCHECK_EQ(type_, Type::kNetworkOnly); - // Wait until it's written. OnNetworkDataAvailable() will call - // CommitCompleted() after all data from |network_consumer_| is - // consumed. - DCHECK_EQ(WriterState::kWriting, header_writer_state_); - return; - case WriterState::kWriting: - // Wait until it's written. OnNetworkDataAvailable() will call - // CommitCompleted() after all data from |network_consumer_| is - // consumed. - DCHECK_EQ(WriterState::kCompleted, header_writer_state_); - return; - case WriterState::kCompleted: - DCHECK_EQ(WriterState::kCompleted, header_writer_state_); - CommitCompleted(network::URLLoaderCompletionStatus(net::OK), - std::string() /* status_message */); - return; - } - NOTREACHED(); + switch (body_writer_state_) { + case WriterState::kNotStarted: + // The header is still being written. Wait until both the header and body + // are written. OnNetworkDataAvailable() will call CommitCompleted() after + // all data from |network_consumer_| is consumed. + DCHECK_EQ(WriterState::kWriting, header_writer_state_); + return; + case WriterState::kWriting: + // Wait until it's written. OnNetworkDataAvailable() will call + // CommitCompleted() after all data from |network_consumer_| is + // consumed. + DCHECK_EQ(WriterState::kCompleted, header_writer_state_); + return; + case WriterState::kCompleted: + DCHECK_EQ(WriterState::kCompleted, header_writer_state_); + CommitCompleted(network::URLLoaderCompletionStatus(net::OK), + std::string() /* status_message */); + return; } - NOTREACHED(); } // End of URLLoaderClient ------------------------------------------------------ -int ServiceWorkerNewScriptLoader::WillWriteInfo( - scoped_refptr<HttpResponseInfoIOBuffer> response_info) { - DCHECK_EQ(type_, Type::kResume); - DCHECK(response_info); - const net::HttpResponseInfo* info = response_info->http_info.get(); - DCHECK(info); - - if (resource_type_ == ResourceType::kServiceWorker) { - version_->SetMainScriptHttpResponseInfo(*info); - } - - auto response = ServiceWorkerUtils::CreateResourceResponseHeadAndMetadata( - info, original_options_, request_start_, base::TimeTicks::Now(), - response_info->response_data_size); - client_->OnReceiveResponse(std::move(response.head)); - if (!response.metadata.empty()) - client_->OnReceiveCachedMetadata(std::move(response.metadata)); - - mojo::ScopedDataPipeConsumerHandle client_consumer; - if (mojo::CreateDataPipe(nullptr, &client_producer_, &client_consumer) != - MOJO_RESULT_OK) { - // Reports error to cache writer and finally the loader would process this - // failure in OnCacheWriterResumed() - return net::ERR_INSUFFICIENT_RESOURCES; - } - - // Pass the consumer handle to the client. - client_->OnStartLoadingResponseBody(std::move(client_consumer)); - client_producer_watcher_.Watch( - client_producer_.get(), MOJO_HANDLE_SIGNAL_WRITABLE, - base::BindRepeating(&ServiceWorkerNewScriptLoader::OnClientWritable, - weak_factory_.GetWeakPtr())); - return net::OK; -} - -void ServiceWorkerNewScriptLoader::OnClientWritable(MojoResult) { - DCHECK_EQ(type_, Type::kResume); - DCHECK(data_to_send_); - DCHECK_GE(data_length_, bytes_sent_to_client_); - DCHECK(client_producer_); - - // Cap the buffer size up to |kReadBufferSize|. The remaining will be written - // next time. - uint32_t bytes_newly_sent = - std::min<uint32_t>(kReadBufferSize, data_length_ - bytes_sent_to_client_); - - MojoResult result = - client_producer_->WriteData(data_to_send_->data() + bytes_sent_to_client_, - &bytes_newly_sent, MOJO_WRITE_DATA_FLAG_NONE); - - if (result == MOJO_RESULT_SHOULD_WAIT) { - // No data was written to |client_producer_| because the pipe was full. - // Retry when the pipe becomes ready again. - client_producer_watcher_.ArmOrNotify(); - return; - } - - if (result != MOJO_RESULT_OK) { - ServiceWorkerMetrics::CountWriteResponseResult( - ServiceWorkerMetrics::WRITE_DATA_ERROR); - CommitCompleted(network::URLLoaderCompletionStatus(net::ERR_FAILED), - ServiceWorkerConsts::kServiceWorkerFetchScriptError); - return; - } - - bytes_sent_to_client_ += bytes_newly_sent; - if (bytes_sent_to_client_ != data_length_) { - // Not all data is sent. Send the rest in another task. - client_producer_watcher_.ArmOrNotify(); - return; - } - std::move(write_observer_complete_callback_).Run(net::OK); -} - -int ServiceWorkerNewScriptLoader::WillWriteData( - scoped_refptr<net::IOBuffer> data, - int length, - base::OnceCallback<void(net::Error)> callback) { - DCHECK_EQ(type_, Type::kResume); - DCHECK(!write_observer_complete_callback_); - DCHECK(client_producer_); - - data_to_send_ = std::move(data); - data_length_ = length; - bytes_sent_to_client_ = 0; - write_observer_complete_callback_ = std::move(callback); - client_producer_watcher_.ArmOrNotify(); - return net::ERR_IO_PENDING; -} - -void ServiceWorkerNewScriptLoader::OnCacheWriterResumed(net::Error error) { - DCHECK_EQ(type_, Type::kResume); - DCHECK_NE(error, net::ERR_IO_PENDING); - // Stop observing write operations in cache writer as further data are - // from network which would be processed by OnNetworkDataAvailable(). - cache_writer_->set_write_observer(nullptr); - - if (error != net::OK) { - CommitCompleted(network::URLLoaderCompletionStatus(error), - ServiceWorkerConsts::kServiceWorkerFetchScriptError); - return; - } - // If the script has no body or all the body has already been read when it - // was paused, we don't have to wait for more data from network. - if (body_writer_state_ == WriterState::kCompleted) { - CommitCompleted(network::URLLoaderCompletionStatus(net::OK), std::string()); - return; - } - - // Continue to load the rest of the body from the network. - DCHECK_EQ(body_writer_state_, WriterState::kWriting); - DCHECK(network_consumer_); - network_client_binding_.Bind(std::move(network_client_request_)); - network_watcher_.Watch( - network_consumer_.get(), - MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, - base::BindRepeating(&ServiceWorkerNewScriptLoader::OnNetworkDataAvailable, - weak_factory_.GetWeakPtr())); - network_watcher_.ArmOrNotify(); -} - #if DCHECK_IS_ON() void ServiceWorkerNewScriptLoader::CheckVersionStatusBeforeLoad() { DCHECK(version_); @@ -600,7 +359,6 @@ void ServiceWorkerNewScriptLoader::WriteHeaders( scoped_refptr<HttpResponseInfoIOBuffer> info_buffer) { - DCHECK_EQ(type_, Type::kNetworkOnly); DCHECK_EQ(WriterState::kNotStarted, header_writer_state_); header_writer_state_ = WriterState::kWriting; net::Error error = cache_writer_->MaybeWriteHeaders( @@ -630,7 +388,7 @@ // If all other states are kCompleted the response body is empty, we can // finish now. - if (network_loader_state_ == NetworkLoaderState::kCompleted && + if (network_loader_state_ == LoaderState::kCompleted && body_writer_state_ == WriterState::kCompleted) { CommitCompleted(network::URLLoaderCompletionStatus(net::OK), std::string() /* status_message */); @@ -641,7 +399,7 @@ } void ServiceWorkerNewScriptLoader::MaybeStartNetworkConsumerHandleWatcher() { - if (network_loader_state_ == NetworkLoaderState::kWaitingForBody) { + if (network_loader_state_ == LoaderState::kWaitingForBody) { // OnStartLoadingResponseBody() or OnComplete() will continue the sequence. return; } @@ -757,7 +515,7 @@ // the request if OnComplete() has already been received. DCHECK(!pending_buffer); body_writer_state_ = WriterState::kCompleted; - if (network_loader_state_ == NetworkLoaderState::kCompleted) { + if (network_loader_state_ == LoaderState::kCompleted) { CommitCompleted(network::URLLoaderCompletionStatus(net::OK), std::string() /* status_message */); } @@ -777,7 +535,7 @@ net::Error error_code = static_cast<net::Error>(status.error_code); int bytes_written = -1; if (error_code == net::OK) { - DCHECK_EQ(NetworkLoaderState::kCompleted, network_loader_state_); + DCHECK_EQ(LoaderState::kCompleted, network_loader_state_); DCHECK_EQ(WriterState::kCompleted, header_writer_state_); DCHECK_EQ(WriterState::kCompleted, body_writer_state_); // If all the calls to WriteHeaders/WriteData succeeded, but the incumbent @@ -802,14 +560,13 @@ client_->OnComplete(status); client_producer_.reset(); - client_producer_watcher_.Cancel(); network_loader_.reset(); network_client_binding_.Close(); network_consumer_.reset(); network_watcher_.Cancel(); cache_writer_.reset(); - network_loader_state_ = NetworkLoaderState::kCompleted; + network_loader_state_ = LoaderState::kCompleted; header_writer_state_ = WriterState::kCompleted; body_writer_state_ = WriterState::kCompleted; }
diff --git a/content/browser/service_worker/service_worker_new_script_loader.h b/content/browser/service_worker/service_worker_new_script_loader.h index 05dace4..6c559dbb 100644 --- a/content/browser/service_worker/service_worker_new_script_loader.h +++ b/content/browser/service_worker/service_worker_new_script_loader.h
@@ -27,16 +27,7 @@ // returns the response to |client|, while also writing the response into the // service worker script storage. // -// There are two types of ServiceWorkerNewScriptLoader: -// 1. Network-only type -// This is for downloading a new script from network only. -// 2. Resume type -// This loader reads part of the script, which has already been loaded -// during an update check, from ServiceWorkerCacheWriter and resumes to -// load the rest of the script from the network after that. See also -// ServiceWorkerUpdateChecker for more details. -// -// In the common case, the network-only type loader works as follows: +// This loader works as follows: // 1. Makes a network request. // 2. OnReceiveResponse() is called, writes the response headers to the // service worker script storage and responds with them to the |client| @@ -47,27 +38,6 @@ // 4. OnComplete() for the network load and OnWriteDataComplete() are called, // calls CommitCompleted() and closes the connections with the network // service and the renderer process. -// In an uncommon case, the response body is empty so -// OnStartLoadingResponseBody() is not called. -// -// The work flow of resume type loader is different from network-only type: -// OnReceiveResponse() and OnStartLoadingResponseBody() are not called as they -// must have been called during update check. -// -// In the common case, the resume type loader works as follows: -// 1. The ServiceWorkerCacheWriter used in the update check is resumed. This -// will read part of the script data already loaded and respond with it -// to the |client| and write to service worker script storage. -// 2. The network download is resumed. The rest of the script data is -// responded to the |client| and written to service worker storage. -// 3. OnComplete() for the network load and OnWriteDataComplete() are called, -// calls CommitCompleted() and closes the connections with the network -// service and the renderer process. -// In an uncommon case, OnComplete() is not called. For example, if a script -// was changed to have no body. OnComplete() would have been called during -// update check to find this change, thus it would never be called again. -// In this case, CommitCompleted() would be called after -// ServiceWorkerCacheWriter::Resume() is done. // // A set of |network_loader_state_|, |header_writer_state_|, and // |body_writer_state_| is the state of this loader. Each of them is changed @@ -88,17 +58,11 @@ // "network" request in comments and naming. "network" is meant to distinguish // from the load this URLLoader does for its client: // "network" <------> SWNewScriptLoader <------> client -class CONTENT_EXPORT ServiceWorkerNewScriptLoader +class CONTENT_EXPORT ServiceWorkerNewScriptLoader final : public network::mojom::URLLoader, - public network::mojom::URLLoaderClient, - public ServiceWorkerCacheWriter::WriteObserver { + public network::mojom::URLLoaderClient { public: - enum class Type { - kNetworkOnly, // For loaders created by CreateForNetworkOnly(). - kResume, // For loaders created by CreateForResume(). - }; - - enum class NetworkLoaderState { + enum class LoaderState { kNotStarted, kLoadingHeader, kWaitingForBody, @@ -108,8 +72,7 @@ enum class WriterState { kNotStarted, kWriting, kCompleted }; - // Creates a loader for a script to be loaded entirely from the network. - static std::unique_ptr<ServiceWorkerNewScriptLoader> CreateForNetworkOnly( + static std::unique_ptr<ServiceWorkerNewScriptLoader> CreateAndStart( int32_t routing_id, int32_t request_id, uint32_t options, @@ -119,15 +82,6 @@ scoped_refptr<network::SharedURLLoaderFactory> loader_factory, const net::MutableNetworkTrafficAnnotationTag& traffic_annotation); - // ServiceWorkerImportedScriptUpdateCheck: - // Creates a loader to continue downloading of a script paused during update - // check. - static std::unique_ptr<ServiceWorkerNewScriptLoader> CreateForResume( - uint32_t options, - const network::ResourceRequest& original_request, - network::mojom::URLLoaderClientPtr client, - scoped_refptr<ServiceWorkerVersion> version); - ~ServiceWorkerNewScriptLoader() override; // network::mojom::URLLoader: @@ -154,24 +108,12 @@ mojo::ScopedDataPipeConsumerHandle body) override; void OnComplete(const network::URLLoaderCompletionStatus& status) override; - // Implements ServiceWorkerCacheWriter::WriteObserver. - // These two methods are only used for resume loaders. - int WillWriteInfo( - scoped_refptr<HttpResponseInfoIOBuffer> response_info) override; - int WillWriteData(scoped_refptr<net::IOBuffer> data, - int length, - base::OnceCallback<void(net::Error)> callback) override; - - Type type() const { return type_; } - // Buffer size for reading script data from network. const static uint32_t kReadBufferSize; private: class WrappedIOBuffer; - // This is for constructing network-only script loaders. - // |loader_factory| is used to load the script, see class comments. ServiceWorkerNewScriptLoader( int32_t routing_id, int32_t request_id, @@ -182,12 +124,6 @@ scoped_refptr<network::SharedURLLoaderFactory> loader_factory, const net::MutableNetworkTrafficAnnotationTag& traffic_annotation); - // This is for constructing resume loaders. - ServiceWorkerNewScriptLoader(uint32_t options, - const network::ResourceRequest& original_request, - network::mojom::URLLoaderClientPtr client, - scoped_refptr<ServiceWorkerVersion> version); - // Writes the given headers into the service worker script storage. void WriteHeaders(scoped_refptr<HttpResponseInfoIOBuffer> info_buffer); void OnWriteHeadersComplete(net::Error error); @@ -234,13 +170,18 @@ // ResourceType::kScript for an imported script. const ResourceType resource_type_; + // Load options originally passed to this loader. The options passed to the + // network loader might be different from this. + const uint32_t original_options_; + scoped_refptr<ServiceWorkerVersion> version_; std::unique_ptr<ServiceWorkerCacheWriter> cache_writer_; - // Used for fetching the script from network, which might not actually - // use the direct network factory, see class comments. + // Used for fetching the script from network (or other loaders like extensions + // sometimes). network::mojom::URLLoaderPtr network_loader_; + mojo::Binding<network::mojom::URLLoaderClient> network_client_binding_; mojo::ScopedDataPipeConsumerHandle network_consumer_; mojo::SimpleWatcher network_watcher_; @@ -263,7 +204,7 @@ // CreateLoaderAndStart(): kNotStarted -> kLoadingHeader // OnReceiveResponse(): kLoadingHeader -> kWaitingForBody // OnComplete(): kWaitingForBody -> kCompleted - NetworkLoaderState network_loader_state_ = NetworkLoaderState::kNotStarted; + LoaderState network_loader_state_ = LoaderState::kNotStarted; // Represents the state of |cache_writer_|. // Set to kWriting when it starts to write the header, and set to kCompleted @@ -277,40 +218,12 @@ // Set to kWriting when |this| starts watching |network_consumer_|, and set to // kCompleted when all data has been written to |cache_writer_|. // - // When response body exists: // OnStartLoadingResponseBody() && OnWriteHeadersComplete(): // kNotStarted -> kWriting // OnNetworkDataAvailable() && MOJO_RESULT_FAILED_PRECONDITION: // kWriting -> kCompleted - // - // When response body is empty: - // OnComplete(): kNotStarted -> kCompleted WriterState body_writer_state_ = WriterState::kNotStarted; - const uint32_t original_options_; - - const Type type_; - - // ---------- Start of Type::kResume loader members ---------- - mojo::SimpleWatcher client_producer_watcher_; - base::TimeTicks request_start_; - network::mojom::URLLoaderClientRequest network_client_request_; - - // This is the data notified by OnBeforeWriteData() which would be sent - // to |client_|. - scoped_refptr<net::IOBuffer> data_to_send_; - - // Length of |data_to_send_| in bytes. - int data_length_ = 0; - - // Length of data in |data_to_send_| already sent to |client_|. - int bytes_sent_to_client_ = 0; - - // Run this to notify ServiceWorkerCacheWriter that the observer completed - // its work. net::OK means all |data_to_send_| has been sent to |client_|. - base::OnceCallback<void(net::Error)> write_observer_complete_callback_; - // ---------- End of Type::kResume loader members ---------- - base::WeakPtrFactory<ServiceWorkerNewScriptLoader> weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(ServiceWorkerNewScriptLoader);
diff --git a/content/browser/service_worker/service_worker_new_script_loader_unittest.cc b/content/browser/service_worker/service_worker_new_script_loader_unittest.cc index d96da29..7dc02c0 100644 --- a/content/browser/service_worker/service_worker_new_script_loader_unittest.cc +++ b/content/browser/service_worker/service_worker_new_script_loader_unittest.cc
@@ -230,9 +230,7 @@ void DoRequest(const GURL& url, std::unique_ptr<network::TestURLLoaderClient>* out_client, - std::unique_ptr<ServiceWorkerNewScriptLoader>* out_loader, - ServiceWorkerNewScriptLoader::Type type = - ServiceWorkerNewScriptLoader::Type::kNetworkOnly) { + std::unique_ptr<ServiceWorkerNewScriptLoader>* out_loader) { DCHECK(registration_); DCHECK(version_); @@ -249,13 +247,7 @@ : ResourceType::kScript); *out_client = std::make_unique<network::TestURLLoaderClient>(); - if (type == ServiceWorkerNewScriptLoader::Type::kResume) { - *out_loader = ServiceWorkerNewScriptLoader::CreateForResume( - options, request, (*out_client)->CreateInterfacePtr(), version_); - return; - } - - *out_loader = ServiceWorkerNewScriptLoader::CreateForNetworkOnly( + *out_loader = ServiceWorkerNewScriptLoader::CreateAndStart( routing_id, request_id, options, request, (*out_client)->CreateInterfacePtr(), version_, helper_->url_loader_factory_getter()->GetNetworkFactory(), @@ -880,273 +872,5 @@ EXPECT_FALSE(version_->embedded_worker()->network_accessed_for_script()); } -// ServiceWorkerNewScriptLoaderResumeTest is for testing operations for -// resuming paused download of scripts when ImportedScriptUpdateCheck -// is enabled. -class ServiceWorkerNewScriptLoaderResumeTest - : public ServiceWorkerNewScriptLoaderTest { - public: - ServiceWorkerNewScriptLoaderResumeTest() : kScriptURL(kNormalScriptURL) { - feature_list_.InitAndEnableFeature( - blink::features::kServiceWorkerImportedScriptUpdateCheck); - } - ~ServiceWorkerNewScriptLoaderResumeTest() override = default; - - void SetUp() override { - ServiceWorkerNewScriptLoaderTest::SetUp(); - SetUpRegistration(kScriptURL); - // Create the old script resource in storage. - WriteToDiskCacheSync(context()->storage(), kScriptURL, kOldResourceId, - kOldHeaders, kOldData, std::string()); - } - - void SetUpComparedScriptInfo( - size_t bytes_compared, - const std::string& new_headers, - const std::string& diff_data_block, - ServiceWorkerNewScriptLoader::NetworkLoaderState network_loader_state, - ServiceWorkerNewScriptLoader::WriterState body_writer_state) { - // Create a data pipe which has the new block sent from the network. - ASSERT_EQ(MOJO_RESULT_OK, mojo::CreateDataPipe(nullptr, &network_producer_, - &network_consumer_)); - ServiceWorkerUpdateCheckTestUtils::CreateAndSetComparedScriptInfoForVersion( - kScriptURL, bytes_compared, new_headers, diff_data_block, - kOldResourceId, kNewResourceId, helper_.get(), network_loader_state, - body_writer_state, std::move(network_consumer_), - ServiceWorkerSingleScriptUpdateChecker::Result::kDifferent, - version_.get()); - } - - void NotifyLoaderCompletion(net::Error error) { - network::URLLoaderCompletionStatus status; - status.error_code = error; - loader_->OnComplete(status); - } - - // Verify the received response. - void CheckReceivedResponse(const std::string& expected_body) { - EXPECT_TRUE(client_->has_received_response()); - EXPECT_TRUE(client_->response_body().is_valid()); - - // The response should also be stored in the storage. - EXPECT_TRUE(ServiceWorkerUpdateCheckTestUtils::VerifyStoredResponse( - LookupResourceId(kScriptURL), context()->storage(), expected_body)); - - std::string response; - EXPECT_TRUE(mojo::BlockingCopyToString(client_->response_body_release(), - &response)); - EXPECT_EQ(expected_body, response); - } - - protected: - base::test::ScopedFeatureList feature_list_; - const GURL kScriptURL; - std::unique_ptr<network::TestURLLoaderClient> client_; - std::unique_ptr<ServiceWorkerNewScriptLoader> loader_; - const std::vector<std::pair<std::string, std::string>> kOldHeaders = { - {"Content-Type", "text/javascript"}, - {"Content-Length", "14"}}; - const std::string kOldData = "old-block-data"; - const int64_t kOldResourceId = 1; - const int64_t kNewResourceId = 2; - mojo::ScopedDataPipeProducerHandle network_producer_; - mojo::ScopedDataPipeConsumerHandle network_consumer_; -}; - -// Tests resume type loader when the first script data block is different. -TEST_F(ServiceWorkerNewScriptLoaderResumeTest, FirstBlockDifferent) { - const std::string kNewHeaders = - "HTTP/1.0 200 OK\0Content-Type: text/javascript\0Content-Length: 24\0\0"; - const std::string kDiffBlock = "diff-block-"; - const std::string kNetworkBlock = "network-block"; - const std::string kNewData = kDiffBlock + kNetworkBlock; - - SetUpComparedScriptInfo( - 0, kNewHeaders, kDiffBlock, - ServiceWorkerNewScriptLoader::NetworkLoaderState::kLoadingBody, - ServiceWorkerNewScriptLoader::WriterState::kWriting); - - DoRequest(kScriptURL, &client_, &loader_, - ServiceWorkerNewScriptLoader::Type::kResume); - - // Send network data. - ASSERT_TRUE(mojo::BlockingCopyFromString(kNetworkBlock, network_producer_)); - network_producer_.reset(); - - // Notify the completion of network loader. - NotifyLoaderCompletion(net::OK); - client_->RunUntilComplete(); - - EXPECT_EQ(net::OK, client_->completion_status().error_code); - - // The client should have received the response. - CheckReceivedResponse(kNewData); -} - -// Tests resume type loader when the script data block in the middle is -// different. -TEST_F(ServiceWorkerNewScriptLoaderResumeTest, MiddleBlockDifferent) { - const std::string kNewHeaders = - "HTTP/1.0 200 OK\0Content-Type: text/javascript\0Content-Length: 34\0\0"; - const std::string kSameBlock = "old-block"; - const std::string kDiffBlock = "|diff-block|"; - const std::string kNetworkBlock = "network-block"; - const std::string kNewData = kSameBlock + kDiffBlock + kNetworkBlock; - - SetUpComparedScriptInfo( - kSameBlock.length(), kNewHeaders, kDiffBlock, - ServiceWorkerNewScriptLoader::NetworkLoaderState::kLoadingBody, - ServiceWorkerNewScriptLoader::WriterState::kWriting); - - DoRequest(kScriptURL, &client_, &loader_, - ServiceWorkerNewScriptLoader::Type::kResume); - - // Send network data. - ASSERT_TRUE(mojo::BlockingCopyFromString(kNetworkBlock, network_producer_)); - network_producer_.reset(); - - // Notify the completion of network loader. - NotifyLoaderCompletion(net::OK); - client_->RunUntilComplete(); - - EXPECT_EQ(net::OK, client_->completion_status().error_code); - - // The client should have received the response. - CheckReceivedResponse(kNewData); -} - -// Tests resume type loader when the last script data block is different. -TEST_F(ServiceWorkerNewScriptLoaderResumeTest, LastBlockDifferent) { - const std::string kNewHeaders = - "HTTP/1.0 200 OK\0Content-Type: text/javascript\0Content-Length: 21\0\0"; - const std::string kSameBlock = "old-block"; - const std::string kDiffBlock = "|diff-block|"; - const std::string kNewData = kSameBlock + kDiffBlock; - - SetUpComparedScriptInfo( - kSameBlock.length(), kNewHeaders, kDiffBlock, - ServiceWorkerNewScriptLoader::NetworkLoaderState::kLoadingBody, - ServiceWorkerNewScriptLoader::WriterState::kWriting); - - DoRequest(kScriptURL, &client_, &loader_, - ServiceWorkerNewScriptLoader::Type::kResume); - network_producer_.reset(); - - // Notify the completion of network loader. - NotifyLoaderCompletion(net::OK); - client_->RunUntilComplete(); - - EXPECT_EQ(net::OK, client_->completion_status().error_code); - - // The client should have received the response. - CheckReceivedResponse(kNewData); -} - -// Tests resume type loader when the last script data block is different and -// OnCompleted() has been called during update check. -TEST_F(ServiceWorkerNewScriptLoaderResumeTest, LastBlockDifferentCompleted) { - const std::string kNewHeaders = - "HTTP/1.0 200 OK\0Content-Type: text/javascript\0Content-Length: 21\0\0"; - const std::string kSameBlock = "old-block"; - const std::string kDiffBlock = "|diff-block|"; - const std::string kNewData = kSameBlock + kDiffBlock; - - SetUpComparedScriptInfo( - kSameBlock.length(), kNewHeaders, kDiffBlock, - ServiceWorkerNewScriptLoader::NetworkLoaderState::kCompleted, - ServiceWorkerNewScriptLoader::WriterState::kWriting); - - DoRequest(kScriptURL, &client_, &loader_, - ServiceWorkerNewScriptLoader::Type::kResume); - network_producer_.reset(); - client_->RunUntilComplete(); - - EXPECT_EQ(net::OK, client_->completion_status().error_code); - - // The client should have received the response. - CheckReceivedResponse(kNewData); -} - -// Tests resume type loader when the new script has more data appended. -TEST_F(ServiceWorkerNewScriptLoaderResumeTest, NewScriptLargerThanOld) { - const std::string kNewHeaders = - "HTTP/1.0 200 OK\0Content-Type: text/javascript\0Content-Length: 39\0\0"; - const std::string kSameBlock = kOldData; - const std::string kDiffBlock = "|diff-block|"; - const std::string kNetworkBlock = "network-block"; - const std::string kNewData = kSameBlock + kDiffBlock + kNetworkBlock; - - SetUpComparedScriptInfo( - kSameBlock.length(), kNewHeaders, kDiffBlock, - ServiceWorkerNewScriptLoader::NetworkLoaderState::kLoadingBody, - ServiceWorkerNewScriptLoader::WriterState::kWriting); - - DoRequest(kScriptURL, &client_, &loader_, - ServiceWorkerNewScriptLoader::Type::kResume); - - // Send network data. - ASSERT_TRUE(mojo::BlockingCopyFromString(kNetworkBlock, network_producer_)); - network_producer_.reset(); - - // Notify the completion of network loader. - NotifyLoaderCompletion(net::OK); - client_->RunUntilComplete(); - - EXPECT_EQ(net::OK, client_->completion_status().error_code); - - // The client should have received the response. - CheckReceivedResponse(kNewData); -} - -// Tests resume type loader when the script changed to have no body. -TEST_F(ServiceWorkerNewScriptLoaderResumeTest, NewScriptEmptyBody) { - const std::string kNewHeaders = - "HTTP/1.0 200 OK\0Content-Type: text/javascript\0Content-Length: 0\0\0"; - const std::string kNewData = ""; - - SetUpComparedScriptInfo( - 0, kNewHeaders, kNewData, - ServiceWorkerNewScriptLoader::NetworkLoaderState::kCompleted, - ServiceWorkerNewScriptLoader::WriterState::kCompleted); - - DoRequest(kScriptURL, &client_, &loader_, - ServiceWorkerNewScriptLoader::Type::kResume); - - network_producer_.reset(); - client_->RunUntilComplete(); - - EXPECT_EQ(net::OK, client_->completion_status().error_code); - - CheckReceivedResponse(kNewData); -} - -// Tests resume type loader could report error when the resumed network -// download completed with error. -TEST_F(ServiceWorkerNewScriptLoaderResumeTest, CompleteFailed) { - const std::string kNewHeaders = - "HTTP/1.0 200 OK\0Content-Type: text/javascript\0Content-Length: 34\0\0"; - const std::string kSameBlock = "old-block"; - const std::string kDiffBlock = "|diff-block|"; - const std::string kNetworkBlock = "network-block"; - const std::string kNewData = kSameBlock + kDiffBlock + kNetworkBlock; - - SetUpComparedScriptInfo( - kSameBlock.length(), kNewHeaders, kDiffBlock, - ServiceWorkerNewScriptLoader::NetworkLoaderState::kLoadingBody, - ServiceWorkerNewScriptLoader::WriterState::kWriting); - - DoRequest(kScriptURL, &client_, &loader_, - ServiceWorkerNewScriptLoader::Type::kResume); - network_producer_.reset(); - - // Notify the failed completion of network loader. - NotifyLoaderCompletion(net::ERR_FAILED); - client_->RunUntilComplete(); - - EXPECT_EQ(net::ERR_FAILED, client_->completion_status().error_code); - EXPECT_EQ(ServiceWorkerConsts::kInvalidServiceWorkerResourceId, - LookupResourceId(kScriptURL)); -} - } // namespace service_worker_new_script_loader_unittest } // namespace content
diff --git a/content/browser/service_worker/service_worker_script_loader_factory.cc b/content/browser/service_worker/service_worker_script_loader_factory.cc index b507f36..ff766d7 100644 --- a/content/browser/service_worker/service_worker_script_loader_factory.cc +++ b/content/browser/service_worker/service_worker_script_loader_factory.cc
@@ -15,6 +15,7 @@ #include "content/browser/service_worker/service_worker_installed_script_loader.h" #include "content/browser/service_worker/service_worker_new_script_loader.h" #include "content/browser/service_worker/service_worker_provider_host.h" +#include "content/browser/service_worker/service_worker_updated_script_loader.h" #include "content/browser/service_worker/service_worker_version.h" #include "mojo/public/cpp/bindings/strong_binding.h" #include "services/network/public/cpp/resource_response.h" @@ -65,21 +66,18 @@ // storage (use ServiceWorkerInstalledScriptLoader) // D) service worker is not installed, script is not installed: // When ServiceWorkerImportedScriptsUpdateCheck is enabled, there are - // three sub cases: + // three sub cases (D.1 to D.3). When not, D.3 always happens. // 1) If compared script info exists and specifies that the script is // installed in an old service worker and content is not changed, then // copy the old script into the new service worker and load it using // ServiceWorkerInstalledScriptLoader. // 2) If compared script info exists and specifies that the script is // installed in an old service worker but content has changed, then - // ServiceWorkerNewScriptLoader::CreateForResume() is called to create - // a ServiceWorkerNewScriptLoader to resume the paused state in the - // compared script info. + // ServiceWorkerUpdatedScriptLoader::CreateAndStart() is called to + // resume the paused state stored in the compared script info. // 3) For other cases or if ServiceWorkerImportedScriptsUpdateCheck is not - // enabled, serve from network with installing the script - // (use ServiceWorkerNewScriptLoader::CreateForNetworkOnly() to - // create a ServiceWorkerNewScriptLoader). - // This is the common case: load the script and install it. + // enabled, serve from network with installing the script by using + // ServiceWorkerNewScriptLoader. // Case A and C: scoped_refptr<ServiceWorkerVersion> version = @@ -128,7 +126,7 @@ case ServiceWorkerSingleScriptUpdateChecker::Result::kDifferent: // Case D.2: mojo::MakeStrongBinding( - ServiceWorkerNewScriptLoader::CreateForResume( + ServiceWorkerUpdatedScriptLoader::CreateAndStart( options, resource_request, std::move(client), version), std::move(request)); return; @@ -143,7 +141,7 @@ // Case D.3: mojo::MakeStrongBinding( - ServiceWorkerNewScriptLoader::CreateForNetworkOnly( + ServiceWorkerNewScriptLoader::CreateAndStart( routing_id, request_id, options, resource_request, std::move(client), provider_host_->running_hosted_version(), loader_factory_for_new_scripts_, traffic_annotation),
diff --git a/content/browser/service_worker/service_worker_script_loader_factory_unittest.cc b/content/browser/service_worker/service_worker_script_loader_factory_unittest.cc index 3e2a567..0ad7288 100644 --- a/content/browser/service_worker/service_worker_script_loader_factory_unittest.cc +++ b/content/browser/service_worker/service_worker_script_loader_factory_unittest.cc
@@ -195,9 +195,8 @@ &network_consumer)); ServiceWorkerUpdateCheckTestUtils::CreateAndSetComparedScriptInfoForVersion( script_url_, 0, kNewHeaders, kNewData, kOldResourceId, kNewResourceId, - helper_.get(), - ServiceWorkerNewScriptLoader::NetworkLoaderState::kCompleted, - ServiceWorkerNewScriptLoader::WriterState::kCompleted, + helper_.get(), ServiceWorkerUpdatedScriptLoader::LoaderState::kCompleted, + ServiceWorkerUpdatedScriptLoader::WriterState::kCompleted, std::move(network_consumer), ServiceWorkerSingleScriptUpdateChecker::Result::kDifferent, version_.get());
diff --git a/content/browser/service_worker/service_worker_single_script_update_checker.cc b/content/browser/service_worker/service_worker_single_script_update_checker.cc index fc7f16b..ed0f5eb8 100644 --- a/content/browser/service_worker/service_worker_single_script_update_checker.cc +++ b/content/browser/service_worker/service_worker_single_script_update_checker.cc
@@ -208,9 +208,9 @@ std::move(network_client), net::MutableNetworkTrafficAnnotationTag(kUpdateCheckTrafficAnnotation)); DCHECK_EQ(network_loader_state_, - ServiceWorkerNewScriptLoader::NetworkLoaderState::kNotStarted); + ServiceWorkerUpdatedScriptLoader::LoaderState::kNotStarted); network_loader_state_ = - ServiceWorkerNewScriptLoader::NetworkLoaderState::kLoadingHeader; + ServiceWorkerUpdatedScriptLoader::LoaderState::kLoadingHeader; } ServiceWorkerSingleScriptUpdateChecker:: @@ -221,7 +221,7 @@ void ServiceWorkerSingleScriptUpdateChecker::OnReceiveResponse( const network::ResourceResponseHead& response_head) { DCHECK_EQ(network_loader_state_, - ServiceWorkerNewScriptLoader::NetworkLoaderState::kLoadingHeader); + ServiceWorkerUpdatedScriptLoader::LoaderState::kLoadingHeader); blink::ServiceWorkerStatusCode service_worker_status; network::URLLoaderCompletionStatus completion_status; @@ -254,7 +254,7 @@ } network_loader_state_ = - ServiceWorkerNewScriptLoader::NetworkLoaderState::kWaitingForBody; + ServiceWorkerUpdatedScriptLoader::LoaderState::kWaitingForBody; network_accessed_ = response_head.network_accessed; WriteHeaders( @@ -292,48 +292,48 @@ void ServiceWorkerSingleScriptUpdateChecker::OnStartLoadingResponseBody( mojo::ScopedDataPipeConsumerHandle consumer) { DCHECK_EQ(network_loader_state_, - ServiceWorkerNewScriptLoader::NetworkLoaderState::kWaitingForBody); + ServiceWorkerUpdatedScriptLoader::LoaderState::kWaitingForBody); network_consumer_ = std::move(consumer); network_loader_state_ = - ServiceWorkerNewScriptLoader::NetworkLoaderState::kLoadingBody; + ServiceWorkerUpdatedScriptLoader::LoaderState::kLoadingBody; MaybeStartNetworkConsumerHandleWatcher(); } void ServiceWorkerSingleScriptUpdateChecker::OnComplete( const network::URLLoaderCompletionStatus& status) { - ServiceWorkerNewScriptLoader::NetworkLoaderState previous_loader_state = + ServiceWorkerUpdatedScriptLoader::LoaderState previous_loader_state = network_loader_state_; network_loader_state_ = - ServiceWorkerNewScriptLoader::NetworkLoaderState::kCompleted; + ServiceWorkerUpdatedScriptLoader::LoaderState::kCompleted; if (status.error_code != net::OK) { Fail(blink::ServiceWorkerStatusCode::kErrorNetwork, ServiceWorkerConsts::kServiceWorkerFetchScriptError, status); return; } - DCHECK( - previous_loader_state == - ServiceWorkerNewScriptLoader::NetworkLoaderState::kWaitingForBody || - previous_loader_state == - ServiceWorkerNewScriptLoader::NetworkLoaderState::kLoadingBody); + DCHECK(previous_loader_state == + ServiceWorkerUpdatedScriptLoader::LoaderState::kWaitingForBody || + previous_loader_state == + ServiceWorkerUpdatedScriptLoader::LoaderState::kLoadingBody); // Response body is empty. if (previous_loader_state == - ServiceWorkerNewScriptLoader::NetworkLoaderState::kWaitingForBody) { + ServiceWorkerUpdatedScriptLoader::LoaderState::kWaitingForBody) { DCHECK_EQ(body_writer_state_, - ServiceWorkerNewScriptLoader::WriterState::kNotStarted); - body_writer_state_ = ServiceWorkerNewScriptLoader::WriterState::kCompleted; + ServiceWorkerUpdatedScriptLoader::WriterState::kNotStarted); + body_writer_state_ = + ServiceWorkerUpdatedScriptLoader::WriterState::kCompleted; switch (header_writer_state_) { - case ServiceWorkerNewScriptLoader::WriterState::kNotStarted: + case ServiceWorkerUpdatedScriptLoader::WriterState::kNotStarted: NOTREACHED() << "Response header should be received before OnComplete()"; break; - case ServiceWorkerNewScriptLoader::WriterState::kWriting: + case ServiceWorkerUpdatedScriptLoader::WriterState::kWriting: // Wait until it's written. OnWriteHeadersComplete() will call // Finish(). return; - case ServiceWorkerNewScriptLoader::WriterState::kCompleted: + case ServiceWorkerUpdatedScriptLoader::WriterState::kCompleted: DCHECK(!network_consumer_.is_valid()); // Compare the cached data with an empty data to notify |cache_writer_| // of the end of the comparison. @@ -344,19 +344,19 @@ // Response body exists. if (previous_loader_state == - ServiceWorkerNewScriptLoader::NetworkLoaderState::kLoadingBody) { + ServiceWorkerUpdatedScriptLoader::LoaderState::kLoadingBody) { switch (body_writer_state_) { - case ServiceWorkerNewScriptLoader::WriterState::kNotStarted: + case ServiceWorkerUpdatedScriptLoader::WriterState::kNotStarted: DCHECK_EQ(header_writer_state_, - ServiceWorkerNewScriptLoader::WriterState::kWriting); + ServiceWorkerUpdatedScriptLoader::WriterState::kWriting); return; - case ServiceWorkerNewScriptLoader::WriterState::kWriting: + case ServiceWorkerUpdatedScriptLoader::WriterState::kWriting: DCHECK_EQ(header_writer_state_, - ServiceWorkerNewScriptLoader::WriterState::kCompleted); + ServiceWorkerUpdatedScriptLoader::WriterState::kCompleted); return; - case ServiceWorkerNewScriptLoader::WriterState::kCompleted: + case ServiceWorkerUpdatedScriptLoader::WriterState::kCompleted: DCHECK_EQ(header_writer_state_, - ServiceWorkerNewScriptLoader::WriterState::kCompleted); + ServiceWorkerUpdatedScriptLoader::WriterState::kCompleted); Succeed(Result::kIdentical); return; } @@ -368,8 +368,9 @@ void ServiceWorkerSingleScriptUpdateChecker::WriteHeaders( scoped_refptr<HttpResponseInfoIOBuffer> info_buffer) { DCHECK_EQ(header_writer_state_, - ServiceWorkerNewScriptLoader::WriterState::kNotStarted); - header_writer_state_ = ServiceWorkerNewScriptLoader::WriterState::kWriting; + ServiceWorkerUpdatedScriptLoader::WriterState::kNotStarted); + header_writer_state_ = + ServiceWorkerUpdatedScriptLoader::WriterState::kWriting; // Pass the header to the cache_writer_. This is written to the storage when // the body had changes. @@ -390,9 +391,10 @@ void ServiceWorkerSingleScriptUpdateChecker::OnWriteHeadersComplete( net::Error error) { DCHECK_EQ(header_writer_state_, - ServiceWorkerNewScriptLoader::WriterState::kWriting); + ServiceWorkerUpdatedScriptLoader::WriterState::kWriting); DCHECK_NE(error, net::ERR_IO_PENDING); - header_writer_state_ = ServiceWorkerNewScriptLoader::WriterState::kCompleted; + header_writer_state_ = + ServiceWorkerUpdatedScriptLoader::WriterState::kCompleted; if (error != net::OK) { Fail(blink::ServiceWorkerStatusCode::kErrorFailed, ServiceWorkerConsts::kServiceWorkerFetchScriptError, @@ -406,21 +408,21 @@ void ServiceWorkerSingleScriptUpdateChecker:: MaybeStartNetworkConsumerHandleWatcher() { if (network_loader_state_ == - ServiceWorkerNewScriptLoader::NetworkLoaderState::kWaitingForBody) { + ServiceWorkerUpdatedScriptLoader::LoaderState::kWaitingForBody) { // OnStartLoadingResponseBody() or OnComplete() will continue the sequence. return; } if (header_writer_state_ != - ServiceWorkerNewScriptLoader::WriterState::kCompleted) { + ServiceWorkerUpdatedScriptLoader::WriterState::kCompleted) { DCHECK_EQ(header_writer_state_, - ServiceWorkerNewScriptLoader::WriterState::kWriting); + ServiceWorkerUpdatedScriptLoader::WriterState::kWriting); // OnWriteHeadersComplete() will continue the sequence. return; } DCHECK_EQ(body_writer_state_, - ServiceWorkerNewScriptLoader::WriterState::kNotStarted); - body_writer_state_ = ServiceWorkerNewScriptLoader::WriterState::kWriting; + ServiceWorkerUpdatedScriptLoader::WriterState::kNotStarted); + body_writer_state_ = ServiceWorkerUpdatedScriptLoader::WriterState::kWriting; network_watcher_.Watch( network_consumer_.get(), @@ -436,7 +438,7 @@ MojoResult, const mojo::HandleSignalsState& state) { DCHECK_EQ(header_writer_state_, - ServiceWorkerNewScriptLoader::WriterState::kCompleted); + ServiceWorkerUpdatedScriptLoader::WriterState::kCompleted); DCHECK(network_consumer_.is_valid()); scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer; uint32_t bytes_available = 0; @@ -448,12 +450,12 @@ return; case MOJO_RESULT_FAILED_PRECONDITION: body_writer_state_ = - ServiceWorkerNewScriptLoader::WriterState::kCompleted; + ServiceWorkerUpdatedScriptLoader::WriterState::kCompleted; // Closed by peer. This indicates all the data from the network service // are read or there is an error. In the error case, the reason is // notified via OnComplete(). if (network_loader_state_ == - ServiceWorkerNewScriptLoader::NetworkLoaderState::kCompleted) { + ServiceWorkerUpdatedScriptLoader::LoaderState::kCompleted) { // Compare the cached data with an empty data to notify |cache_writer_| // the end of the comparison. CompareData(nullptr /* pending_buffer */, 0 /* bytes_available */); @@ -578,8 +580,8 @@ network::mojom::URLLoaderPtr network_loader, network::mojom::URLLoaderClientRequest network_client_request, mojo::ScopedDataPipeConsumerHandle network_consumer, - ServiceWorkerNewScriptLoader::NetworkLoaderState network_loader_state, - ServiceWorkerNewScriptLoader::WriterState body_writer_state) + ServiceWorkerUpdatedScriptLoader::LoaderState network_loader_state, + ServiceWorkerUpdatedScriptLoader::WriterState body_writer_state) : cache_writer(std::move(cache_writer)), network_loader(std::move(network_loader)), network_client_request(std::move(network_client_request)),
diff --git a/content/browser/service_worker/service_worker_single_script_update_checker.h b/content/browser/service_worker/service_worker_single_script_update_checker.h index 9e267f5..381639c5 100644 --- a/content/browser/service_worker/service_worker_single_script_update_checker.h +++ b/content/browser/service_worker/service_worker_single_script_update_checker.h
@@ -6,7 +6,7 @@ #define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_SINGLE_SCRIPT_UPDATE_CHECKER_H_ #include "content/browser/service_worker/service_worker_disk_cache.h" -#include "content/browser/service_worker/service_worker_new_script_loader.h" +#include "content/browser/service_worker/service_worker_updated_script_loader.h" #include "content/common/content_export.h" #include "mojo/public/cpp/bindings/binding.h" #include "services/network/public/mojom/url_loader.mojom.h" @@ -61,8 +61,8 @@ network::mojom::URLLoaderPtr network_loader, network::mojom::URLLoaderClientRequest network_client_request, mojo::ScopedDataPipeConsumerHandle network_consumer, - ServiceWorkerNewScriptLoader::NetworkLoaderState network_loader_state, - ServiceWorkerNewScriptLoader::WriterState body_writer_state); + ServiceWorkerUpdatedScriptLoader::LoaderState network_loader_state, + ServiceWorkerUpdatedScriptLoader::WriterState body_writer_state); PausedState(const PausedState& other) = delete; PausedState& operator=(const PausedState& other) = delete; ~PausedState(); @@ -71,8 +71,8 @@ network::mojom::URLLoaderPtr network_loader; network::mojom::URLLoaderClientRequest network_client_request; mojo::ScopedDataPipeConsumerHandle network_consumer; - ServiceWorkerNewScriptLoader::NetworkLoaderState network_loader_state; - ServiceWorkerNewScriptLoader::WriterState body_writer_state; + ServiceWorkerUpdatedScriptLoader::LoaderState network_loader_state; + ServiceWorkerUpdatedScriptLoader::WriterState body_writer_state; }; // This callback is only called after all of the work is done by the checker. @@ -180,8 +180,8 @@ // CreateLoaderAndStart(): kNotStarted -> kLoadingHeader // OnReceiveResponse(): kLoadingHeader -> kWaitingForBody // OnComplete(): kWaitingForBody -> kCompleted - ServiceWorkerNewScriptLoader::NetworkLoaderState network_loader_state_ = - ServiceWorkerNewScriptLoader::NetworkLoaderState::kNotStarted; + ServiceWorkerUpdatedScriptLoader::LoaderState network_loader_state_ = + ServiceWorkerUpdatedScriptLoader::LoaderState::kNotStarted; // Represents the state of |cache_writer_|. // Set to kWriting when it starts to send the header to |cache_writer_|, and @@ -189,8 +189,8 @@ // // OnReceiveResponse(): kNotStarted -> kWriting (in WriteHeaders()) // OnWriteHeadersComplete(): kWriting -> kCompleted - ServiceWorkerNewScriptLoader::WriterState header_writer_state_ = - ServiceWorkerNewScriptLoader::WriterState::kNotStarted; + ServiceWorkerUpdatedScriptLoader::WriterState header_writer_state_ = + ServiceWorkerUpdatedScriptLoader::WriterState::kNotStarted; // Represents the state of |cache_writer_| and |network_consumer_|. // Set to kWriting when |this| starts watching |network_consumer_|, and set to @@ -206,8 +206,8 @@ // // When response body is empty: // OnComplete(): kNotStarted -> kCompleted - ServiceWorkerNewScriptLoader::WriterState body_writer_state_ = - ServiceWorkerNewScriptLoader::WriterState::kNotStarted; + ServiceWorkerUpdatedScriptLoader::WriterState body_writer_state_ = + ServiceWorkerUpdatedScriptLoader::WriterState::kNotStarted; base::WeakPtrFactory<ServiceWorkerSingleScriptUpdateChecker> weak_factory_{ this};
diff --git a/content/browser/service_worker/service_worker_test_utils.cc b/content/browser/service_worker/service_worker_test_utils.cc index 08d5c1e..b4ef15ce 100644 --- a/content/browser/service_worker/service_worker_test_utils.cc +++ b/content/browser/service_worker/service_worker_test_utils.cc
@@ -597,8 +597,8 @@ std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker::PausedState> ServiceWorkerUpdateCheckTestUtils::CreateUpdateCheckerPausedState( std::unique_ptr<ServiceWorkerCacheWriter> cache_writer, - ServiceWorkerNewScriptLoader::NetworkLoaderState network_loader_state, - ServiceWorkerNewScriptLoader::WriterState body_writer_state, + ServiceWorkerUpdatedScriptLoader::LoaderState network_loader_state, + ServiceWorkerUpdatedScriptLoader::WriterState body_writer_state, mojo::ScopedDataPipeConsumerHandle network_consumer) { network::mojom::URLLoaderPtr network_loader; network::mojom::URLLoaderClientPtr network_loader_client; @@ -634,8 +634,8 @@ int64_t old_resource_id, int64_t new_resource_id, EmbeddedWorkerTestHelper* worker_test_helper, - ServiceWorkerNewScriptLoader::NetworkLoaderState network_loader_state, - ServiceWorkerNewScriptLoader::WriterState body_writer_state, + ServiceWorkerUpdatedScriptLoader::LoaderState network_loader_state, + ServiceWorkerUpdatedScriptLoader::WriterState body_writer_state, mojo::ScopedDataPipeConsumerHandle network_consumer, ServiceWorkerSingleScriptUpdateChecker::Result compare_result, ServiceWorkerVersion* version) {
diff --git a/content/browser/service_worker/service_worker_test_utils.h b/content/browser/service_worker/service_worker_test_utils.h index 4171f3f..14e6afa 100644 --- a/content/browser/service_worker/service_worker_test_utils.h +++ b/content/browser/service_worker/service_worker_test_utils.h
@@ -357,8 +357,8 @@ static std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker::PausedState> CreateUpdateCheckerPausedState( std::unique_ptr<ServiceWorkerCacheWriter> cache_writer, - ServiceWorkerNewScriptLoader::NetworkLoaderState network_loader_state, - ServiceWorkerNewScriptLoader::WriterState body_writer_state, + ServiceWorkerUpdatedScriptLoader::LoaderState network_loader_state, + ServiceWorkerUpdatedScriptLoader::WriterState body_writer_state, mojo::ScopedDataPipeConsumerHandle network_consumer); static void SetComparedScriptInfoForVersion( @@ -379,8 +379,8 @@ int64_t old_resource_id, int64_t new_resource_id, EmbeddedWorkerTestHelper* worker_test_helper, - ServiceWorkerNewScriptLoader::NetworkLoaderState network_loader_state, - ServiceWorkerNewScriptLoader::WriterState body_writer_state, + ServiceWorkerUpdatedScriptLoader::LoaderState network_loader_state, + ServiceWorkerUpdatedScriptLoader::WriterState body_writer_state, mojo::ScopedDataPipeConsumerHandle network_consumer, ServiceWorkerSingleScriptUpdateChecker::Result compare_result, ServiceWorkerVersion* version);
diff --git a/content/browser/service_worker/service_worker_updated_script_loader.cc b/content/browser/service_worker/service_worker_updated_script_loader.cc new file mode 100644 index 0000000..0ca5b50a --- /dev/null +++ b/content/browser/service_worker/service_worker_updated_script_loader.cc
@@ -0,0 +1,511 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/service_worker/service_worker_updated_script_loader.h" + +#include <memory> +#include <vector> + +#include "base/bind.h" +#include "base/numerics/safe_conversions.h" +#include "base/task/post_task.h" +#include "content/browser/appcache/appcache_response.h" +#include "content/browser/service_worker/service_worker_cache_writer.h" +#include "content/browser/service_worker/service_worker_consts.h" +#include "content/browser/service_worker/service_worker_context_core.h" +#include "content/browser/service_worker/service_worker_disk_cache.h" +#include "content/browser/service_worker/service_worker_loader_helpers.h" +#include "content/browser/service_worker/service_worker_storage.h" +#include "content/browser/service_worker/service_worker_version.h" +#include "content/browser/url_loader_factory_getter.h" +#include "content/common/service_worker/service_worker_utils.h" +#include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/content_browser_client.h" +#include "net/base/ip_endpoint.h" +#include "net/base/load_flags.h" +#include "net/base/net_errors.h" +#include "net/cert/cert_status_flags.h" +#include "services/network/public/cpp/resource_response.h" +#include "third_party/blink/public/common/service_worker/service_worker_utils.h" + +namespace content { + +// We chose this size because the AppCache uses this. +const uint32_t ServiceWorkerUpdatedScriptLoader::kReadBufferSize = 32768; + +// This is for debugging https://crbug.com/959627. +// The purpose is to see where the IOBuffer comes from by checking |__vfptr|. +class ServiceWorkerUpdatedScriptLoader::WrappedIOBuffer + : public net::WrappedIOBuffer { + public: + WrappedIOBuffer(const char* data) : net::WrappedIOBuffer(data) {} + + private: + ~WrappedIOBuffer() override = default; + + // This is to make sure that the vtable is not merged with other classes. + virtual void dummy() { NOTREACHED(); } +}; + +std::unique_ptr<ServiceWorkerUpdatedScriptLoader> +ServiceWorkerUpdatedScriptLoader::CreateAndStart( + uint32_t options, + const network::ResourceRequest& original_request, + network::mojom::URLLoaderClientPtr client, + scoped_refptr<ServiceWorkerVersion> version) { + DCHECK(blink::ServiceWorkerUtils::IsImportedScriptUpdateCheckEnabled()); + return base::WrapUnique(new ServiceWorkerUpdatedScriptLoader( + options, original_request, std::move(client), version)); +} + +ServiceWorkerUpdatedScriptLoader::ServiceWorkerUpdatedScriptLoader( + uint32_t options, + const network::ResourceRequest& original_request, + network::mojom::URLLoaderClientPtr client, + scoped_refptr<ServiceWorkerVersion> version) + : request_url_(original_request.url), + resource_type_(static_cast<ResourceType>(original_request.resource_type)), + options_(options), + version_(std::move(version)), + network_client_binding_(this), + network_watcher_(FROM_HERE, + mojo::SimpleWatcher::ArmingPolicy::MANUAL, + base::SequencedTaskRunnerHandle::Get()), + client_(std::move(client)), + client_producer_watcher_(FROM_HERE, + mojo::SimpleWatcher::ArmingPolicy::MANUAL, + base::SequencedTaskRunnerHandle::Get()), + request_start_(base::TimeTicks::Now()) { +#if DCHECK_IS_ON() + CheckVersionStatusBeforeLoad(); +#endif // DCHECK_IS_ON() + + DCHECK(client_); + ServiceWorkerUpdateChecker::ComparedScriptInfo info = + version_->TakeComparedScriptInfo(request_url_); + if (info.result == ServiceWorkerSingleScriptUpdateChecker::Result::kFailed) { + DCHECK(!info.paused_state); + // A network error received during update checking. This replays it. + CommitCompleted(info.failure_info->network_status, + info.failure_info->error_message); + return; + } + + cache_writer_ = std::move(info.paused_state->cache_writer); + DCHECK(cache_writer_); + + network_loader_ = std::move(info.paused_state->network_loader); + network_client_request_ = + std::move(info.paused_state->network_client_request); + network_consumer_ = std::move(info.paused_state->network_consumer); + + network_loader_state_ = info.paused_state->network_loader_state; + DCHECK(network_loader_state_ == LoaderState::kLoadingBody || + network_loader_state_ == LoaderState::kCompleted); + + body_writer_state_ = info.paused_state->body_writer_state; + DCHECK(body_writer_state_ == WriterState::kWriting || + body_writer_state_ == WriterState::kCompleted); + + version_->script_cache_map()->NotifyStartedCaching( + request_url_, cache_writer_->WriterResourceId()); + + // Resume the cache writer and observe its writes, so all data written + // is sent to |client_|. + cache_writer_->set_write_observer(this); + net::Error error = cache_writer_->Resume( + base::BindOnce(&ServiceWorkerUpdatedScriptLoader::OnCacheWriterResumed, + weak_factory_.GetWeakPtr())); + + if (error != net::ERR_IO_PENDING) { + OnCacheWriterResumed(error); + } +} + +ServiceWorkerUpdatedScriptLoader::~ServiceWorkerUpdatedScriptLoader() = default; + +void ServiceWorkerUpdatedScriptLoader::FollowRedirect( + const std::vector<std::string>& removed_headers, + const net::HttpRequestHeaders& modified_headers, + const base::Optional<GURL>& new_url) { + // Resource requests for service worker scripts should not follow redirects. + // See comments in OnReceiveRedirect(). + NOTREACHED(); +} + +void ServiceWorkerUpdatedScriptLoader::SetPriority( + net::RequestPriority priority, + int32_t intra_priority_value) { + if (network_loader_) + network_loader_->SetPriority(priority, intra_priority_value); +} + +void ServiceWorkerUpdatedScriptLoader::PauseReadingBodyFromNet() { + if (network_loader_) + network_loader_->PauseReadingBodyFromNet(); +} + +void ServiceWorkerUpdatedScriptLoader::ResumeReadingBodyFromNet() { + if (network_loader_) + network_loader_->ResumeReadingBodyFromNet(); +} + +// URLLoaderClient for network loader ------------------------------------------ + +void ServiceWorkerUpdatedScriptLoader::OnReceiveResponse( + const network::ResourceResponseHead& response_head) { + NOTREACHED(); +} + +void ServiceWorkerUpdatedScriptLoader::OnReceiveRedirect( + const net::RedirectInfo& redirect_info, + const network::ResourceResponseHead& response_head) { + NOTREACHED(); +} + +void ServiceWorkerUpdatedScriptLoader::OnUploadProgress( + int64_t current_position, + int64_t total_size, + OnUploadProgressCallback ack_callback) { + NOTREACHED(); +} + +void ServiceWorkerUpdatedScriptLoader::OnReceiveCachedMetadata( + mojo_base::BigBuffer data) { + client_->OnReceiveCachedMetadata(std::move(data)); +} + +void ServiceWorkerUpdatedScriptLoader::OnTransferSizeUpdated( + int32_t transfer_size_diff) { + client_->OnTransferSizeUpdated(transfer_size_diff); +} + +void ServiceWorkerUpdatedScriptLoader::OnStartLoadingResponseBody( + mojo::ScopedDataPipeConsumerHandle consumer) { + NOTREACHED(); +} + +void ServiceWorkerUpdatedScriptLoader::OnComplete( + const network::URLLoaderCompletionStatus& status) { + LoaderState previous_state = network_loader_state_; + network_loader_state_ = LoaderState::kCompleted; + if (status.error_code != net::OK) { + CommitCompleted(status, + ServiceWorkerConsts::kServiceWorkerFetchScriptError); + return; + } + + DCHECK_EQ(LoaderState::kLoadingBody, previous_state); + switch (body_writer_state_) { + case WriterState::kNotStarted: + NOTREACHED(); + return; + case WriterState::kWriting: + // Wait until it's written. OnNetworkDataAvailable() will call + // CommitCompleted() after all data from |network_consumer_| is + // consumed. + return; + case WriterState::kCompleted: + CommitCompleted(network::URLLoaderCompletionStatus(net::OK), + std::string() /* status_message */); + return; + } + NOTREACHED(); +} + +// End of URLLoaderClient ------------------------------------------------------ + +int ServiceWorkerUpdatedScriptLoader::WillWriteInfo( + scoped_refptr<HttpResponseInfoIOBuffer> response_info) { + DCHECK(response_info); + const net::HttpResponseInfo* info = response_info->http_info.get(); + DCHECK(info); + + if (resource_type_ == ResourceType::kServiceWorker) { + version_->SetMainScriptHttpResponseInfo(*info); + } + + auto response = ServiceWorkerUtils::CreateResourceResponseHeadAndMetadata( + info, options_, request_start_, base::TimeTicks::Now(), + response_info->response_data_size); + client_->OnReceiveResponse(std::move(response.head)); + if (!response.metadata.empty()) + client_->OnReceiveCachedMetadata(std::move(response.metadata)); + + mojo::ScopedDataPipeConsumerHandle client_consumer; + if (mojo::CreateDataPipe(nullptr, &client_producer_, &client_consumer) != + MOJO_RESULT_OK) { + // Reports error to cache writer and finally the loader would process this + // failure in OnCacheWriterResumed() + return net::ERR_INSUFFICIENT_RESOURCES; + } + + // Pass the consumer handle to the client. + client_->OnStartLoadingResponseBody(std::move(client_consumer)); + client_producer_watcher_.Watch( + client_producer_.get(), MOJO_HANDLE_SIGNAL_WRITABLE, + base::BindRepeating(&ServiceWorkerUpdatedScriptLoader::OnClientWritable, + weak_factory_.GetWeakPtr())); + return net::OK; +} + +void ServiceWorkerUpdatedScriptLoader::OnClientWritable(MojoResult) { + DCHECK(data_to_send_); + DCHECK_GE(data_length_, bytes_sent_to_client_); + DCHECK(client_producer_); + + // Cap the buffer size up to |kReadBufferSize|. The remaining will be written + // next time. + uint32_t bytes_newly_sent = + std::min<uint32_t>(kReadBufferSize, data_length_ - bytes_sent_to_client_); + + MojoResult result = + client_producer_->WriteData(data_to_send_->data() + bytes_sent_to_client_, + &bytes_newly_sent, MOJO_WRITE_DATA_FLAG_NONE); + + if (result == MOJO_RESULT_SHOULD_WAIT) { + // No data was written to |client_producer_| because the pipe was full. + // Retry when the pipe becomes ready again. + client_producer_watcher_.ArmOrNotify(); + return; + } + + if (result != MOJO_RESULT_OK) { + ServiceWorkerMetrics::CountWriteResponseResult( + ServiceWorkerMetrics::WRITE_DATA_ERROR); + CommitCompleted(network::URLLoaderCompletionStatus(net::ERR_FAILED), + ServiceWorkerConsts::kServiceWorkerFetchScriptError); + return; + } + + bytes_sent_to_client_ += bytes_newly_sent; + if (bytes_sent_to_client_ != data_length_) { + // Not all data is sent. Send the rest in another task. + client_producer_watcher_.ArmOrNotify(); + return; + } + std::move(write_observer_complete_callback_).Run(net::OK); +} + +int ServiceWorkerUpdatedScriptLoader::WillWriteData( + scoped_refptr<net::IOBuffer> data, + int length, + base::OnceCallback<void(net::Error)> callback) { + DCHECK(!write_observer_complete_callback_); + DCHECK(client_producer_); + + data_to_send_ = std::move(data); + data_length_ = length; + bytes_sent_to_client_ = 0; + write_observer_complete_callback_ = std::move(callback); + client_producer_watcher_.ArmOrNotify(); + return net::ERR_IO_PENDING; +} + +void ServiceWorkerUpdatedScriptLoader::OnCacheWriterResumed(net::Error error) { + DCHECK_NE(error, net::ERR_IO_PENDING); + // Stop observing write operations in cache writer as further data are + // from network which would be processed by OnNetworkDataAvailable(). + cache_writer_->set_write_observer(nullptr); + + if (error != net::OK) { + CommitCompleted(network::URLLoaderCompletionStatus(error), + ServiceWorkerConsts::kServiceWorkerFetchScriptError); + return; + } + // If the script has no body or all the body has already been read when it + // was paused, we don't have to wait for more data from network. + if (body_writer_state_ == WriterState::kCompleted) { + CommitCompleted(network::URLLoaderCompletionStatus(net::OK), std::string()); + return; + } + + // Continue to load the rest of the body from the network. + DCHECK_EQ(body_writer_state_, WriterState::kWriting); + DCHECK(network_consumer_); + network_client_binding_.Bind(std::move(network_client_request_)); + network_watcher_.Watch( + network_consumer_.get(), + MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, + base::BindRepeating( + &ServiceWorkerUpdatedScriptLoader::OnNetworkDataAvailable, + weak_factory_.GetWeakPtr())); + network_watcher_.ArmOrNotify(); +} + +#if DCHECK_IS_ON() +void ServiceWorkerUpdatedScriptLoader::CheckVersionStatusBeforeLoad() { + DCHECK(version_); + + // ServiceWorkerUpdatedScriptLoader is used for fetching the service worker + // main script (RESOURCE_TYPE_SERVICE_WORKER) during worker startup or + // importScripts() (RESOURCE_TYPE_SCRIPT). + // TODO(nhiroki): In the current implementation, importScripts() can be called + // in any ServiceWorkerVersion::Status except for REDUNDANT, but the spec + // defines importScripts() works only on the initial script evaluation and the + // install event. Update this check once importScripts() is fixed. + // (https://crbug.com/719052) + DCHECK((resource_type_ == ResourceType::kServiceWorker && + version_->status() == ServiceWorkerVersion::NEW) || + (resource_type_ == ResourceType::kScript && + version_->status() != ServiceWorkerVersion::REDUNDANT)); +} +#endif // DCHECK_IS_ON() + +void ServiceWorkerUpdatedScriptLoader::OnNetworkDataAvailable(MojoResult) { + DCHECK_EQ(WriterState::kWriting, body_writer_state_); + DCHECK(network_consumer_.is_valid()); + scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer; + uint32_t bytes_available = 0; + MojoResult result = network::MojoToNetPendingBuffer::BeginRead( + &network_consumer_, &pending_buffer, &bytes_available); + switch (result) { + case MOJO_RESULT_OK: + WriteData(std::move(pending_buffer), bytes_available); + return; + case MOJO_RESULT_FAILED_PRECONDITION: + // Call WriteData() with null buffer to let the cache writer know that + // body from the network reaches to the end. + WriteData(/*pending_buffer=*/nullptr, /*bytes_available=*/0); + return; + case MOJO_RESULT_SHOULD_WAIT: + network_watcher_.ArmOrNotify(); + return; + } + NOTREACHED() << static_cast<int>(result); +} + +void ServiceWorkerUpdatedScriptLoader::WriteData( + scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer, + uint32_t bytes_available) { + // Cap the buffer size up to |kReadBufferSize|. The remaining will be written + // next time. + uint32_t bytes_written = std::min<uint32_t>(kReadBufferSize, bytes_available); + + auto buffer = base::MakeRefCounted<WrappedIOBuffer>( + pending_buffer ? pending_buffer->buffer() : nullptr); + MojoResult result = client_producer_->WriteData( + buffer->data(), &bytes_written, MOJO_WRITE_DATA_FLAG_NONE); + switch (result) { + case MOJO_RESULT_OK: + break; + case MOJO_RESULT_FAILED_PRECONDITION: + ServiceWorkerMetrics::CountWriteResponseResult( + ServiceWorkerMetrics::WRITE_DATA_ERROR); + CommitCompleted(network::URLLoaderCompletionStatus(net::ERR_FAILED), + ServiceWorkerConsts::kServiceWorkerFetchScriptError); + return; + case MOJO_RESULT_SHOULD_WAIT: + // No data was written to |client_producer_| because the pipe was full. + // Retry when the pipe becomes ready again. + pending_buffer->CompleteRead(0); + network_consumer_ = pending_buffer->ReleaseHandle(); + network_watcher_.ArmOrNotify(); + return; + default: + NOTREACHED() << static_cast<int>(result); + return; + } + + // Write the buffer in the service worker script storage up to the size we + // successfully wrote to the data pipe (i.e., |bytes_written|). + // A null buffer and zero |bytes_written| are passed when this is the end of + // the body. + net::Error error = cache_writer_->MaybeWriteData( + buffer.get(), base::strict_cast<size_t>(bytes_written), + base::BindOnce(&ServiceWorkerUpdatedScriptLoader::OnWriteDataComplete, + weak_factory_.GetWeakPtr(), pending_buffer, + bytes_written)); + if (error == net::ERR_IO_PENDING) { + // OnWriteDataComplete() will be called asynchronously. + return; + } + // MaybeWriteData() doesn't run the callback if it finishes synchronously, so + // explicitly call it here. + OnWriteDataComplete(std::move(pending_buffer), bytes_written, error); +} + +void ServiceWorkerUpdatedScriptLoader::OnWriteDataComplete( + scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer, + uint32_t bytes_written, + net::Error error) { + DCHECK_NE(net::ERR_IO_PENDING, error); + if (error != net::OK) { + ServiceWorkerMetrics::CountWriteResponseResult( + ServiceWorkerMetrics::WRITE_DATA_ERROR); + CommitCompleted(network::URLLoaderCompletionStatus(error), + ServiceWorkerConsts::kServiceWorkerFetchScriptError); + return; + } + ServiceWorkerMetrics::CountWriteResponseResult( + ServiceWorkerMetrics::WRITE_OK); + + if (bytes_written == 0) { + // Zero |bytes_written| with net::OK means that all data has been read from + // the network and the Mojo data pipe has been closed. Thus we can complete + // the request if OnComplete() has already been received. + DCHECK(!pending_buffer); + body_writer_state_ = WriterState::kCompleted; + if (network_loader_state_ == LoaderState::kCompleted) { + CommitCompleted(network::URLLoaderCompletionStatus(net::OK), + std::string() /* status_message */); + } + return; + } + + DCHECK(pending_buffer); + pending_buffer->CompleteRead(bytes_written); + // Get the consumer handle from a previous read operation if we have one. + network_consumer_ = pending_buffer->ReleaseHandle(); + network_watcher_.ArmOrNotify(); +} + +void ServiceWorkerUpdatedScriptLoader::CommitCompleted( + const network::URLLoaderCompletionStatus& status, + const std::string& status_message) { + net::Error error_code = static_cast<net::Error>(status.error_code); + int bytes_written = -1; + if (error_code == net::OK) { + DCHECK(cache_writer_); + DCHECK_EQ(LoaderState::kCompleted, network_loader_state_); + DCHECK_EQ(WriterState::kCompleted, body_writer_state_); + // If all the calls to WriteHeaders/WriteData succeeded, but the incumbent + // entry wasn't actually replaced because the new entry was equivalent, the + // new version didn't actually install because it already exists. + if (!cache_writer_->did_replace()) { + version_->SetStartWorkerStatusCode( + blink::ServiceWorkerStatusCode::kErrorExists); + error_code = net::ERR_FILE_EXISTS; + } + bytes_written = cache_writer_->bytes_written(); + } else { + // AddMessageConsole must be called before notifying that an error occurred + // because the worker stops soon after receiving the error response. + // TODO(nhiroki): Consider replacing this hacky way with the new error code + // handling mechanism in URLLoader. + version_->embedded_worker()->AddMessageToConsole( + blink::mojom::ConsoleMessageLevel::kError, status_message); + } + + // Cache writer could be nullptr when update checking observed a network error + // and this loader hasn't started the caching yet. + if (cache_writer_) { + version_->script_cache_map()->NotifyFinishedCaching( + request_url_, bytes_written, error_code, status_message); + } + + client_->OnComplete(status); + client_producer_.reset(); + client_producer_watcher_.Cancel(); + + network_loader_.reset(); + network_client_binding_.Close(); + network_consumer_.reset(); + network_watcher_.Cancel(); + cache_writer_.reset(); + network_loader_state_ = LoaderState::kCompleted; + body_writer_state_ = WriterState::kCompleted; +} + +} // namespace content
diff --git a/content/browser/service_worker/service_worker_updated_script_loader.h b/content/browser/service_worker/service_worker_updated_script_loader.h new file mode 100644 index 0000000..e5acab20 --- /dev/null +++ b/content/browser/service_worker/service_worker_updated_script_loader.h
@@ -0,0 +1,226 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_UPDATED_SCRIPT_LOADER_H_ +#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_UPDATED_SCRIPT_LOADER_H_ + +#include "base/macros.h" +#include "content/browser/service_worker/service_worker_cache_writer.h" +#include "content/common/content_export.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/common/resource_type.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "net/traffic_annotation/network_traffic_annotation.h" +#include "services/network/public/cpp/net_adapters.h" +#include "services/network/public/cpp/resource_request.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" +#include "services/network/public/mojom/url_loader.mojom.h" +#include "url/gurl.h" + +namespace content { + +class ServiceWorkerVersion; +struct HttpResponseInfoIOBuffer; + +// Used only for ServiceWorkerImportedScriptUpdateCheck. +// +// This is the URLLoader used for loading scripts for a new (installing) service +// worker. This is used for a script which has an update on the script during +// update checking in the browser process. Also used when the request was a +// network error during the update checking so that the same network error can +// be observed at the initial script evaluation in the renderer. +// +// This loader works as follows: +// 1. The ServiceWorkerCacheWriter used in the update check is resumed. After +// that, the writer starts to make a new resource by copying the header and +// body which has already been provided by the update checker. This loader +// observes the copy (WillWriteInfo()/WillWriteData()), and sends the data +// to |client_|. +// 2. After the copy has done, it resumes the network load. The rest of the +// script body is responded to the |client_| and also written to service +// worker storage. +// 3. When OnComplete() is called and the Mojo data pipe for the script body +// is closed, it calls CommitCompleted() and closes the connections with +// the network service and the renderer process. +// +// NOTE: To perform the network request, this class uses |loader_factory_| which +// may internally use a non-NetworkService factory if URL has a non-http(s) +// scheme, e.g., a chrome-extension:// URL. Regardless, that is still called a +// "network" request in comments and naming. "network" is meant to distinguish +// from the load this URLLoader does for its client: +// "network" <------> SWResumeScriptLoader <------> client +class CONTENT_EXPORT ServiceWorkerUpdatedScriptLoader final + : public network::mojom::URLLoader, + public network::mojom::URLLoaderClient, + public ServiceWorkerCacheWriter::WriteObserver { + public: + enum class LoaderState { + kNotStarted, + kLoadingHeader, + kWaitingForBody, + kLoadingBody, + kCompleted, + }; + + enum class WriterState { kNotStarted, kWriting, kCompleted }; + + // Creates a loader to continue downloading of a script paused during update + // check. + static std::unique_ptr<ServiceWorkerUpdatedScriptLoader> CreateAndStart( + uint32_t options, + const network::ResourceRequest& original_request, + network::mojom::URLLoaderClientPtr client, + scoped_refptr<ServiceWorkerVersion> version); + + ~ServiceWorkerUpdatedScriptLoader() override; + + // network::mojom::URLLoader: + void FollowRedirect(const std::vector<std::string>& removed_headers, + const net::HttpRequestHeaders& modified_headers, + const base::Optional<GURL>& new_url) override; + void SetPriority(net::RequestPriority priority, + int32_t intra_priority_value) override; + void PauseReadingBodyFromNet() override; + void ResumeReadingBodyFromNet() override; + + // network::mojom::URLLoaderClient for the network load: + void OnReceiveResponse( + const network::ResourceResponseHead& response_head) override; + void OnReceiveRedirect( + const net::RedirectInfo& redirect_info, + const network::ResourceResponseHead& response_head) override; + void OnUploadProgress(int64_t current_position, + int64_t total_size, + OnUploadProgressCallback ack_callback) override; + void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override; + void OnTransferSizeUpdated(int32_t transfer_size_diff) override; + void OnStartLoadingResponseBody( + mojo::ScopedDataPipeConsumerHandle body) override; + void OnComplete(const network::URLLoaderCompletionStatus& status) override; + + // Implements ServiceWorkerCacheWriter::WriteObserver. + int WillWriteInfo( + scoped_refptr<HttpResponseInfoIOBuffer> response_info) override; + int WillWriteData(scoped_refptr<net::IOBuffer> data, + int length, + base::OnceCallback<void(net::Error)> callback) override; + + // Buffer size for reading script data from network. + const static uint32_t kReadBufferSize; + + private: + class WrappedIOBuffer; + + ServiceWorkerUpdatedScriptLoader( + uint32_t options, + const network::ResourceRequest& original_request, + network::mojom::URLLoaderClientPtr client, + scoped_refptr<ServiceWorkerVersion> version); + + // Called when |network_consumer_| is ready to be read. Can be called multiple + // times. + void OnNetworkDataAvailable(MojoResult); + + // Writes the given data into the service worker script storage. + void WriteData(scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer, + uint32_t bytes_available); + void OnWriteDataComplete( + scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer, + uint32_t bytes_written, + net::Error error); + + // This is the last method that is called on this class. Notifies the final + // result to |client_| and clears all mojo connections etc. + void CommitCompleted(const network::URLLoaderCompletionStatus& status, + const std::string& status_message); + + // Called when |client_producer_| is writable. It writes |data_to_send_| + // to |client_producer_|. If all data is written, the observer has completed + // its work and |write_observer_complete_callback_| is called. Otherwise, + // |client_producer_watcher_| is armed to wait for |client_producer_| to be + // writable again. + void OnClientWritable(MojoResult); + + // Called when ServiceWorkerCacheWriter::Resume() completes its work. + // If not all data are received, it continues to download from network. + void OnCacheWriterResumed(net::Error error); + +#if DCHECK_IS_ON() + void CheckVersionStatusBeforeLoad(); +#endif // DCHECK_IS_ON() + + const GURL request_url_; + + // This is ResourceType::kServiceWorker for the main script or + // ResourceType::kScript for an imported script. + const ResourceType resource_type_; + + // Loader options to pass to the network loader. + const uint32_t options_; + + scoped_refptr<ServiceWorkerVersion> version_; + + std::unique_ptr<ServiceWorkerCacheWriter> cache_writer_; + + // Used for fetching the script from network (or other loaders like extensions + // sometimes). + network::mojom::URLLoaderPtr network_loader_; + + mojo::Binding<network::mojom::URLLoaderClient> network_client_binding_; + mojo::ScopedDataPipeConsumerHandle network_consumer_; + mojo::SimpleWatcher network_watcher_; + + // Used for responding with the fetched script to this loader's client. + network::mojom::URLLoaderClientPtr client_; + mojo::ScopedDataPipeProducerHandle client_producer_; + + // Represents the state of |network_loader_|. + // Corresponds to the steps of calls as a URLLoaderClient. + // + // CreateLoaderAndStart(): kNotStarted -> kLoadingHeader + // OnReceiveResponse(): kLoadingHeader -> kWaitingForBody + // OnStartLoadingResponseBody(): kWaitingForBody -> kLoadingBody + // OnComplete(): kLoadingBody -> kCompleted + // + // When this loader is created, the state should be kLoadingBody or kCompleted + // because the update checking pauses the cache writer during loading the + // body for byte-for-byte comparison. + LoaderState network_loader_state_ = LoaderState::kNotStarted; + + // State of the cache writer. + // kNotStarted: not started to write the body. + // kWriting: writing the body into the cache writer. + // kCompleted: all body has been written into the cache writer. + // + // When this loader is created, |body_writer_state_| should be kWriting or + // kCompleted because the response body should have started to be read during + // update checking. + WriterState body_writer_state_ = WriterState::kNotStarted; + + mojo::SimpleWatcher client_producer_watcher_; + const base::TimeTicks request_start_; + network::mojom::URLLoaderClientRequest network_client_request_; + + // This is the data notified by OnBeforeWriteData() which would be sent + // to |client_|. + scoped_refptr<net::IOBuffer> data_to_send_; + + // Length of |data_to_send_| in bytes. + int data_length_ = 0; + + // Length of data in |data_to_send_| already sent to |client_|. + int bytes_sent_to_client_ = 0; + + // Run this to notify ServiceWorkerCacheWriter that the observer completed + // its work. net::OK means all |data_to_send_| has been sent to |client_|. + base::OnceCallback<void(net::Error)> write_observer_complete_callback_; + + base::WeakPtrFactory<ServiceWorkerUpdatedScriptLoader> weak_factory_{this}; + + DISALLOW_COPY_AND_ASSIGN(ServiceWorkerUpdatedScriptLoader); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_UPDATED_SCRIPT_LOADER_H_
diff --git a/content/browser/service_worker/service_worker_updated_script_loader_unittest.cc b/content/browser/service_worker/service_worker_updated_script_loader_unittest.cc new file mode 100644 index 0000000..ed157d9 --- /dev/null +++ b/content/browser/service_worker/service_worker_updated_script_loader_unittest.cc
@@ -0,0 +1,400 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/service_worker/service_worker_updated_script_loader.h" + +#include <map> +#include <memory> +#include <string> +#include <utility> +#include "base/bind_helpers.h" +#include "base/run_loop.h" +#include "base/strings/string_util.h" +#include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" +#include "content/browser/service_worker/embedded_worker_test_helper.h" +#include "content/browser/service_worker/service_worker_consts.h" +#include "content/browser/service_worker/service_worker_context_core.h" +#include "content/browser/service_worker/service_worker_disk_cache.h" +#include "content/browser/service_worker/service_worker_test_utils.h" +#include "content/browser/url_loader_factory_getter.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "mojo/public/cpp/bindings/strong_binding.h" +#include "mojo/public/cpp/system/data_pipe_utils.h" +#include "net/base/load_flags.h" +#include "net/base/test_completion_callback.h" +#include "net/http/http_util.h" +#include "net/traffic_annotation/network_traffic_annotation.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" +#include "net/url_request/redirect_info.h" +#include "services/network/public/cpp/url_loader_completion_status.h" +#include "services/network/public/mojom/url_loader_factory.mojom.h" +#include "services/network/test/test_url_loader_client.h" +#include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h" + +namespace content { +namespace service_worker_updated_script_loader_unittest { + +const char kNormalScriptURL[] = "https://example.com/normal.js"; + +// MockHTTPServer is a utility to provide mocked responses for +// ServiceWorkerUpdatedScriptLoader. +class MockHTTPServer { + public: + struct Response { + Response(const std::string& headers, const std::string& body) + : headers(headers), body(body) {} + + const std::string headers; + const std::string body; + bool has_certificate_error = false; + }; + + void Set(const GURL& url, const Response& response) { + responses_.erase(url); + responses_.emplace(url, response); + } + + const Response& Get(const GURL& url) { + auto found = responses_.find(url); + EXPECT_TRUE(found != responses_.end()); + return found->second; + } + + private: + std::map<GURL, Response> responses_; +}; + +// ServiceWorkerUpdatedScriptLoaderTest is for testing the handling of requests +// for installing service worker scripts via ServiceWorkerUpdatedScriptLoader. +class ServiceWorkerUpdatedScriptLoaderTest : public testing::Test { + public: + ServiceWorkerUpdatedScriptLoaderTest() + : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP), + kScriptURL(kNormalScriptURL) { + feature_list_.InitAndEnableFeature( + blink::features::kServiceWorkerImportedScriptUpdateCheck); + } + ~ServiceWorkerUpdatedScriptLoaderTest() override = default; + + ServiceWorkerContextCore* context() { return helper_->context(); } + + void SetUp() override { + helper_ = std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath()); + InitializeStorage(); + SetUpRegistration(kScriptURL); + + // Create the old script resource in storage. + WriteToDiskCacheSync(context()->storage(), kScriptURL, kOldResourceId, + kOldHeaders, kOldData, std::string()); + } + + void InitializeStorage() { + base::RunLoop run_loop; + context()->storage()->LazyInitializeForTest(run_loop.QuitClosure()); + run_loop.Run(); + } + + // Sets up ServiceWorkerRegistration and ServiceWorkerVersion. This should be + // called before DoRequest(). + void SetUpRegistration(const GURL& script_url) { + blink::mojom::ServiceWorkerRegistrationOptions options; + options.scope = script_url.GetWithoutFilename(); + SetUpRegistrationWithOptions(script_url, options); + } + void SetUpRegistrationWithOptions( + const GURL& script_url, + blink::mojom::ServiceWorkerRegistrationOptions options) { + registration_ = base::MakeRefCounted<ServiceWorkerRegistration>( + options, context()->storage()->NewRegistrationId(), + context()->AsWeakPtr()); + SetUpVersion(script_url); + } + + // After this is called, |version_| will be a new, uninstalled version. The + // next time DoRequest() is called, |version_| will attempt to install, + // possibly updating if registration has an installed worker. + void SetUpVersion(const GURL& script_url) { + version_ = base::MakeRefCounted<ServiceWorkerVersion>( + registration_.get(), script_url, blink::mojom::ScriptType::kClassic, + context()->storage()->NewVersionId(), context()->AsWeakPtr()); + version_->SetStatus(ServiceWorkerVersion::NEW); + } + + void DoRequest( + const GURL& url, + std::unique_ptr<network::TestURLLoaderClient>* out_client, + std::unique_ptr<ServiceWorkerUpdatedScriptLoader>* out_loader) { + DCHECK(registration_); + DCHECK(version_); + + // Dummy values. + uint32_t options = 0; + + network::ResourceRequest request; + request.url = url; + request.method = "GET"; + request.resource_type = static_cast<int>((url == version_->script_url()) + ? ResourceType::kServiceWorker + : ResourceType::kScript); + + *out_client = std::make_unique<network::TestURLLoaderClient>(); + *out_loader = ServiceWorkerUpdatedScriptLoader::CreateAndStart( + options, request, (*out_client)->CreateInterfacePtr(), version_); + } + + int64_t LookupResourceId(const GURL& url) { + return version_->script_cache_map()->LookupResourceId(url); + } + + void SetUpComparedScriptInfo( + size_t bytes_compared, + const std::string& new_headers, + const std::string& diff_data_block, + ServiceWorkerUpdatedScriptLoader::LoaderState network_loader_state, + ServiceWorkerUpdatedScriptLoader::WriterState body_writer_state) { + // Create a data pipe which has the new block sent from the network. + ASSERT_EQ(MOJO_RESULT_OK, mojo::CreateDataPipe(nullptr, &network_producer_, + &network_consumer_)); + ServiceWorkerUpdateCheckTestUtils::CreateAndSetComparedScriptInfoForVersion( + kScriptURL, bytes_compared, new_headers, diff_data_block, + kOldResourceId, kNewResourceId, helper_.get(), network_loader_state, + body_writer_state, std::move(network_consumer_), + ServiceWorkerSingleScriptUpdateChecker::Result::kDifferent, + version_.get()); + } + + void NotifyLoaderCompletion(net::Error error) { + network::URLLoaderCompletionStatus status; + status.error_code = error; + loader_->OnComplete(status); + } + + // Verify the received response. + void CheckReceivedResponse(const std::string& expected_body) { + EXPECT_TRUE(client_->has_received_response()); + EXPECT_TRUE(client_->response_body().is_valid()); + + // The response should also be stored in the storage. + EXPECT_TRUE(ServiceWorkerUpdateCheckTestUtils::VerifyStoredResponse( + LookupResourceId(kScriptURL), context()->storage(), expected_body)); + + std::string response; + EXPECT_TRUE(mojo::BlockingCopyToString(client_->response_body_release(), + &response)); + EXPECT_EQ(expected_body, response); + } + + protected: + TestBrowserThreadBundle thread_bundle_; + base::test::ScopedFeatureList feature_list_; + + std::unique_ptr<EmbeddedWorkerTestHelper> helper_; + + scoped_refptr<ServiceWorkerRegistration> registration_; + scoped_refptr<ServiceWorkerVersion> version_; + + const GURL kScriptURL; + std::unique_ptr<network::TestURLLoaderClient> client_; + std::unique_ptr<ServiceWorkerUpdatedScriptLoader> loader_; + const std::vector<std::pair<std::string, std::string>> kOldHeaders = { + {"Content-Type", "text/javascript"}, + {"Content-Length", "14"}}; + const std::string kOldData = "old-block-data"; + const int64_t kOldResourceId = 1; + const int64_t kNewResourceId = 2; + mojo::ScopedDataPipeProducerHandle network_producer_; + mojo::ScopedDataPipeConsumerHandle network_consumer_; +}; + +// Tests the loader when the first script data block is different. +TEST_F(ServiceWorkerUpdatedScriptLoaderTest, FirstBlockDifferent) { + const std::string kNewHeaders = + "HTTP/1.0 200 OK\0Content-Type: text/javascript\0Content-Length: 24\0\0"; + const std::string kDiffBlock = "diff-block-"; + const std::string kNetworkBlock = "network-block"; + const std::string kNewData = kDiffBlock + kNetworkBlock; + + SetUpComparedScriptInfo( + 0, kNewHeaders, kDiffBlock, + ServiceWorkerUpdatedScriptLoader::LoaderState::kLoadingBody, + ServiceWorkerUpdatedScriptLoader::WriterState::kWriting); + + DoRequest(kScriptURL, &client_, &loader_); + + // Send network data. + ASSERT_TRUE(mojo::BlockingCopyFromString(kNetworkBlock, network_producer_)); + network_producer_.reset(); + + // Notify the completion of network loader. + NotifyLoaderCompletion(net::OK); + client_->RunUntilComplete(); + + EXPECT_EQ(net::OK, client_->completion_status().error_code); + + // The client should have received the response. + CheckReceivedResponse(kNewData); +} + +// Tests the loader when the script data block in the middle is different. +TEST_F(ServiceWorkerUpdatedScriptLoaderTest, MiddleBlockDifferent) { + const std::string kNewHeaders = + "HTTP/1.0 200 OK\0Content-Type: text/javascript\0Content-Length: 34\0\0"; + const std::string kSameBlock = "old-block"; + const std::string kDiffBlock = "|diff-block|"; + const std::string kNetworkBlock = "network-block"; + const std::string kNewData = kSameBlock + kDiffBlock + kNetworkBlock; + + SetUpComparedScriptInfo( + kSameBlock.length(), kNewHeaders, kDiffBlock, + ServiceWorkerUpdatedScriptLoader::LoaderState::kLoadingBody, + ServiceWorkerUpdatedScriptLoader::WriterState::kWriting); + + DoRequest(kScriptURL, &client_, &loader_); + + // Send network data. + ASSERT_TRUE(mojo::BlockingCopyFromString(kNetworkBlock, network_producer_)); + network_producer_.reset(); + + // Notify the completion of network loader. + NotifyLoaderCompletion(net::OK); + client_->RunUntilComplete(); + + EXPECT_EQ(net::OK, client_->completion_status().error_code); + + // The client should have received the response. + CheckReceivedResponse(kNewData); +} + +// Tests the loader when the last script data block is different. +TEST_F(ServiceWorkerUpdatedScriptLoaderTest, LastBlockDifferent) { + const std::string kNewHeaders = + "HTTP/1.0 200 OK\0Content-Type: text/javascript\0Content-Length: 21\0\0"; + const std::string kSameBlock = "old-block"; + const std::string kDiffBlock = "|diff-block|"; + const std::string kNewData = kSameBlock + kDiffBlock; + + SetUpComparedScriptInfo( + kSameBlock.length(), kNewHeaders, kDiffBlock, + ServiceWorkerUpdatedScriptLoader::LoaderState::kLoadingBody, + ServiceWorkerUpdatedScriptLoader::WriterState::kWriting); + + DoRequest(kScriptURL, &client_, &loader_); + network_producer_.reset(); + + // Notify the completion of network loader. + NotifyLoaderCompletion(net::OK); + client_->RunUntilComplete(); + + EXPECT_EQ(net::OK, client_->completion_status().error_code); + + // The client should have received the response. + CheckReceivedResponse(kNewData); +} + +// Tests the loader when the last script data block is different and +// OnCompleted() has been called during update check. +TEST_F(ServiceWorkerUpdatedScriptLoaderTest, LastBlockDifferentCompleted) { + const std::string kNewHeaders = + "HTTP/1.0 200 OK\0Content-Type: text/javascript\0Content-Length: 21\0\0"; + const std::string kSameBlock = "old-block"; + const std::string kDiffBlock = "|diff-block|"; + const std::string kNewData = kSameBlock + kDiffBlock; + + SetUpComparedScriptInfo( + kSameBlock.length(), kNewHeaders, kDiffBlock, + ServiceWorkerUpdatedScriptLoader::LoaderState::kCompleted, + ServiceWorkerUpdatedScriptLoader::WriterState::kWriting); + + DoRequest(kScriptURL, &client_, &loader_); + network_producer_.reset(); + client_->RunUntilComplete(); + + EXPECT_EQ(net::OK, client_->completion_status().error_code); + + // The client should have received the response. + CheckReceivedResponse(kNewData); +} + +// Tests the loader when the new script has more data appended. +TEST_F(ServiceWorkerUpdatedScriptLoaderTest, NewScriptLargerThanOld) { + const std::string kNewHeaders = + "HTTP/1.0 200 OK\0Content-Type: text/javascript\0Content-Length: 39\0\0"; + const std::string kSameBlock = kOldData; + const std::string kDiffBlock = "|diff-block|"; + const std::string kNetworkBlock = "network-block"; + const std::string kNewData = kSameBlock + kDiffBlock + kNetworkBlock; + + SetUpComparedScriptInfo( + kSameBlock.length(), kNewHeaders, kDiffBlock, + ServiceWorkerUpdatedScriptLoader::LoaderState::kLoadingBody, + ServiceWorkerUpdatedScriptLoader::WriterState::kWriting); + + DoRequest(kScriptURL, &client_, &loader_); + + // Send network data. + ASSERT_TRUE(mojo::BlockingCopyFromString(kNetworkBlock, network_producer_)); + network_producer_.reset(); + + // Notify the completion of network loader. + NotifyLoaderCompletion(net::OK); + client_->RunUntilComplete(); + + EXPECT_EQ(net::OK, client_->completion_status().error_code); + + // The client should have received the response. + CheckReceivedResponse(kNewData); +} + +// Tests the loader when the script changed to have no body. +TEST_F(ServiceWorkerUpdatedScriptLoaderTest, NewScriptEmptyBody) { + const std::string kNewHeaders = + "HTTP/1.0 200 OK\0Content-Type: text/javascript\0Content-Length: 0\0\0"; + const std::string kNewData = ""; + + SetUpComparedScriptInfo( + 0, kNewHeaders, kNewData, + ServiceWorkerUpdatedScriptLoader::LoaderState::kCompleted, + ServiceWorkerUpdatedScriptLoader::WriterState::kCompleted); + + DoRequest(kScriptURL, &client_, &loader_); + + network_producer_.reset(); + client_->RunUntilComplete(); + + EXPECT_EQ(net::OK, client_->completion_status().error_code); + + CheckReceivedResponse(kNewData); +} + +// Tests the loader could report error when the resumed network +// download completed with error. +TEST_F(ServiceWorkerUpdatedScriptLoaderTest, CompleteFailed) { + const std::string kNewHeaders = + "HTTP/1.0 200 OK\0Content-Type: text/javascript\0Content-Length: 34\0\0"; + const std::string kSameBlock = "old-block"; + const std::string kDiffBlock = "|diff-block|"; + const std::string kNetworkBlock = "network-block"; + const std::string kNewData = kSameBlock + kDiffBlock + kNetworkBlock; + + SetUpComparedScriptInfo( + kSameBlock.length(), kNewHeaders, kDiffBlock, + ServiceWorkerUpdatedScriptLoader::LoaderState::kLoadingBody, + ServiceWorkerUpdatedScriptLoader::WriterState::kWriting); + + DoRequest(kScriptURL, &client_, &loader_); + network_producer_.reset(); + + // Notify the failed completion of network loader. + NotifyLoaderCompletion(net::ERR_FAILED); + client_->RunUntilComplete(); + + EXPECT_EQ(net::ERR_FAILED, client_->completion_status().error_code); + EXPECT_EQ(ServiceWorkerConsts::kInvalidServiceWorkerResourceId, + LookupResourceId(kScriptURL)); +} + +} // namespace service_worker_updated_script_loader_unittest +} // namespace content
diff --git a/content/browser/sms/sms_provider_android.cc b/content/browser/sms/sms_provider_android.cc index 603e71c..d43990af8 100644 --- a/content/browser/sms/sms_provider_android.cc +++ b/content/browser/sms/sms_provider_android.cc
@@ -2,10 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "content/browser/sms/sms_provider_android.h" + #include <string> #include "base/bind.h" -#include "content/browser/sms/sms_provider_android.h" #include "url/gurl.h" #include "url/origin.h" @@ -13,7 +14,6 @@ using base::android::AttachCurrentThread; using base::android::ConvertJavaStringToUTF8; -using base::android::ScopedJavaLocalRef; namespace content { @@ -46,4 +46,9 @@ void SmsProviderAndroid::OnTimeout(JNIEnv* env) {} +base::android::ScopedJavaGlobalRef<jobject> +SmsProviderAndroid::GetSmsReceiverForTesting() const { + return j_sms_receiver_; +} + } // namespace content
diff --git a/content/browser/sms/sms_provider_android.h b/content/browser/sms/sms_provider_android.h index ff206ea..618c68f4 100644 --- a/content/browser/sms/sms_provider_android.h +++ b/content/browser/sms/sms_provider_android.h
@@ -11,20 +11,23 @@ #include "base/android/scoped_java_ref.h" #include "base/macros.h" #include "content/browser/sms/sms_provider.h" +#include "content/common/content_export.h" namespace content { -class SmsProviderAndroid : public SmsProvider { +class CONTENT_EXPORT SmsProviderAndroid : public SmsProvider { public: SmsProviderAndroid(); ~SmsProviderAndroid() override; void Retrieve() override; - void OnReceive(JNIEnv*, - jstring message); + void OnReceive(JNIEnv*, jstring message); + void OnTimeout(JNIEnv* env); + base::android::ScopedJavaGlobalRef<jobject> GetSmsReceiverForTesting() const; + private: base::android::ScopedJavaGlobalRef<jobject> j_sms_receiver_;
diff --git a/content/browser/sms/sms_provider_android_unittest.cc b/content/browser/sms/sms_provider_android_unittest.cc new file mode 100644 index 0000000..48cc382a --- /dev/null +++ b/content/browser/sms/sms_provider_android_unittest.cc
@@ -0,0 +1,97 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/sms/sms_service.h" + +#include <string> + +#include "base/android/jni_string.h" +#include "base/android/scoped_java_ref.h" +#include "content/browser/sms/sms_provider.h" +#include "content/browser/sms/sms_provider_android.h" +#include "content/public/test/test_renderer_host.h" +#include "content/test/content_unittests_jni_headers/Fakes_jni.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using base::android::AttachCurrentThread; +using ::testing::NiceMock; +using url::Origin; + +namespace content { + +namespace { + +class MockObserver : public SmsProvider::Observer { + public: + MockObserver() = default; + ~MockObserver() override = default; + + MOCK_METHOD2(OnReceive, bool(const Origin&, const std::string& sms)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockObserver); +}; + +// SmsProviderAndroidTest tests the JNI bindings to the android SmsReceiver +// and the handling of the SMS upon retrieval. +class SmsProviderAndroidTest : public RenderViewHostTestHarness { + protected: + SmsProviderAndroidTest() {} + ~SmsProviderAndroidTest() override {} + + void SetUp() override { + RenderViewHostTestHarness::SetUp(); + j_fake_sms_retriever_client_.Reset( + Java_FakeSmsRetrieverClient_create(AttachCurrentThread())); + Java_Fakes_setClientForTesting(AttachCurrentThread(), + provider_.GetSmsReceiverForTesting(), + j_fake_sms_retriever_client_); + provider_.AddObserver(&observer_); + } + + void TriggerSms(const std::string& sms) { + JNIEnv* env = base::android::AttachCurrentThread(); + Java_FakeSmsRetrieverClient_triggerSms( + env, j_fake_sms_retriever_client_, + base::android::ConvertUTF8ToJavaString(env, sms)); + } + + SmsProviderAndroid& provider() { return provider_; } + + NiceMock<MockObserver>* observer() { return &observer_; } + + private: + SmsProviderAndroid provider_; + NiceMock<MockObserver> observer_; + base::android::ScopedJavaGlobalRef<jobject> j_fake_sms_retriever_client_; + + DISALLOW_COPY_AND_ASSIGN(SmsProviderAndroidTest); +}; + +} // namespace + +TEST_F(SmsProviderAndroidTest, Retrieve) { + std::string test_url = "https://www.google.com"; + std::string expected_sms = "Hi \nFor: " + test_url; + + EXPECT_CALL(*observer(), + OnReceive(Origin::Create(GURL(test_url)), expected_sms)); + provider().Retrieve(); + TriggerSms(expected_sms); +} + +TEST_F(SmsProviderAndroidTest, IgnoreBadSms) { + std::string test_url = "https://www.google.com"; + std::string good_sms = "Hi \nFor: " + test_url; + std::string bad_sms = "Hi \nFor: http://b.com"; + + EXPECT_CALL(*observer(), OnReceive(Origin::Create(GURL(test_url)), good_sms)); + + provider().Retrieve(); + TriggerSms(bad_sms); + TriggerSms(good_sms); +} + +} // namespace content
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 5d0e901..7ce96d6 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -405,12 +405,12 @@ class WebContentsImpl::ColorChooser : public blink::mojom::ColorChooser { public: ColorChooser(content::ColorChooser* chooser, - blink::mojom::ColorChooserRequest request, - blink::mojom::ColorChooserClientPtr client) + mojo::PendingReceiver<blink::mojom::ColorChooser> receiver, + mojo::PendingRemote<blink::mojom::ColorChooserClient> client) : chooser_(chooser), - binding_(this, std::move(request)), + receiver_(this, std::move(receiver)), client_(std::move(client)) { - binding_.set_connection_error_handler( + receiver_.set_disconnect_handler( base::BindOnce([](content::ColorChooser* chooser) { chooser->End(); }, base::Unretained(chooser))); } @@ -429,11 +429,11 @@ // Color chooser that was opened by this tab. std::unique_ptr<content::ColorChooser> chooser_; - // mojo bindings. - mojo::Binding<blink::mojom::ColorChooser> binding_; + // mojo receiver. + mojo::Receiver<blink::mojom::ColorChooser> receiver_; // mojo renderer client. - blink::mojom::ColorChooserClientPtr client_; + mojo::Remote<blink::mojom::ColorChooserClient> client_; }; // WebContentsImpl::WebContentsTreeNode ---------------------------------------- @@ -606,7 +606,7 @@ display_cutout_host_impl_ = std::make_unique<DisplayCutoutHostImpl>(this); #endif - registry_.AddInterface(base::BindRepeating( + binders_.Add(base::BindRepeating( &WebContentsImpl::OnColorChooserFactoryRequest, base::Unretained(this))); ui::NativeTheme* native_theme = ui::NativeTheme::GetInstanceForWeb(); @@ -1566,6 +1566,9 @@ return serial_active_frame_count_ > 0; } +bool WebContentsImpl::HasNativeFileSystemHandles() { + return native_file_system_handle_count_ > 0; +} bool WebContentsImpl::HasNativeFileSystemDirectoryHandles() { return !native_file_system_directory_handles_.empty(); } @@ -4922,13 +4925,13 @@ } void WebContentsImpl::OnColorChooserFactoryRequest( - blink::mojom::ColorChooserFactoryRequest request) { - color_chooser_factory_bindings_.AddBinding(this, std::move(request)); + mojo::PendingReceiver<blink::mojom::ColorChooserFactory> receiver) { + color_chooser_factory_receivers_.Add(this, std::move(receiver)); } void WebContentsImpl::OpenColorChooser( - blink::mojom::ColorChooserRequest chooser_request, - blink::mojom::ColorChooserClientPtr client, + mojo::PendingReceiver<blink::mojom::ColorChooser> chooser_receiver, + mojo::PendingRemote<blink::mojom::ColorChooserClient> client, SkColor color, std::vector<blink::mojom::ColorSuggestionPtr> suggestions) { content::ColorChooser* new_color_chooser = @@ -4939,7 +4942,7 @@ color_chooser_.reset(); color_chooser_ = std::make_unique<ColorChooser>( - new_color_chooser, std::move(chooser_request), std::move(client)); + new_color_chooser, std::move(chooser_receiver), std::move(client)); } #if BUILDFLAG(ENABLE_PLUGINS) @@ -5281,7 +5284,7 @@ RenderFrameHost* render_frame_host, const std::string& interface_name, mojo::ScopedMessagePipeHandle* interface_pipe) { - registry_.TryBindInterface(interface_name, interface_pipe); + binders_.TryBind(interface_name, interface_pipe); for (auto& observer : observers_) { observer.OnInterfaceRequestFromFrame(render_frame_host, interface_name, interface_pipe); @@ -6890,6 +6893,39 @@ NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB); } +void WebContentsImpl::IncrementNativeFileSystemHandleCount() { + // Trying to invalidate the tab state while being destroyed could result in a + // use after free. + if (IsBeingDestroyed()) + return; + + // Notify for UI updates if the state changes. Need both TYPE_TAB and TYPE_URL + // to update both the tab-level usage indicator and the usage indicator in the + // omnibox. + native_file_system_handle_count_++; + if (native_file_system_handle_count_ == 1) { + NotifyNavigationStateChanged(static_cast<content::InvalidateTypes>( + INVALIDATE_TYPE_TAB | INVALIDATE_TYPE_URL)); + } +} + +void WebContentsImpl::DecrementNativeFileSystemHandleCount() { + // Trying to invalidate the tab state while being destroyed could result in a + // use after free. + if (IsBeingDestroyed()) + return; + + // Notify for UI updates if the state changes. Need both TYPE_TAB and TYPE_URL + // to update both the tab-level usage indicator and the usage indicator in the + // omnibox. + DCHECK_NE(0u, native_file_system_handle_count_); + native_file_system_handle_count_--; + if (native_file_system_handle_count_ == 0) { + NotifyNavigationStateChanged(static_cast<content::InvalidateTypes>( + INVALIDATE_TYPE_TAB | INVALIDATE_TYPE_URL)); + } +} + void WebContentsImpl::AddNativeFileSystemDirectoryHandle( const base::FilePath& path) { // Trying to invalidate the tab state while being destroyed could result in a
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 7d23b840..cc22c4d 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -354,6 +354,7 @@ bool IsCurrentlyAudible() override; bool IsConnectedToBluetoothDevice() override; bool IsConnectedToSerialPort() override; + bool HasNativeFileSystemHandles() override; bool HasNativeFileSystemDirectoryHandles() override; std::vector<base::FilePath> GetNativeFileSystemDirectoryHandles() override; bool HasWritableNativeFileSystemHandles() override; @@ -857,10 +858,10 @@ // blink::mojom::ColorChooserFactory --------------------------------------- void OnColorChooserFactoryRequest( - blink::mojom::ColorChooserFactoryRequest request); + mojo::PendingReceiver<blink::mojom::ColorChooserFactory> receiver); void OpenColorChooser( - blink::mojom::ColorChooserRequest chooser, - blink::mojom::ColorChooserClientPtr client, + mojo::PendingReceiver<blink::mojom::ColorChooser> chooser, + mojo::PendingRemote<blink::mojom::ColorChooserClient> client, SkColor color, std::vector<blink::mojom::ColorSuggestionPtr> suggestions) override; @@ -973,6 +974,10 @@ void IncrementSerialActiveFrameCount(); void DecrementSerialActiveFrameCount(); + // Modify the counter of native file system handles for this WebContents. + void IncrementNativeFileSystemHandleCount(); + void DecrementNativeFileSystemHandleCount(); + // Add and remove a reference for a native file system directory handle for a // certain |path|. Multiple Add calls should be balanced by the same number of // Remove calls for the same |path|. @@ -1788,10 +1793,10 @@ std::unique_ptr<WakeLockContextHost> wake_lock_context_host_; - service_manager::BinderRegistry registry_; + service_manager::BinderMap binders_; - mojo::BindingSet<blink::mojom::ColorChooserFactory> - color_chooser_factory_bindings_; + mojo::ReceiverSet<blink::mojom::ColorChooserFactory> + color_chooser_factory_receivers_; #if defined(OS_ANDROID) std::unique_ptr<NFCHost> nfc_host_; @@ -1817,6 +1822,7 @@ size_t bluetooth_connected_device_count_ = 0; size_t serial_active_frame_count_ = 0; + size_t native_file_system_handle_count_ = 0; std::map<base::FilePath, size_t> native_file_system_directory_handles_; size_t native_file_system_writable_handle_count_ = 0;
diff --git a/content/browser/web_package/bundled_exchanges_handle.cc b/content/browser/web_package/bundled_exchanges_handle.cc index ef404c4..cfdcd7e 100644 --- a/content/browser/web_package/bundled_exchanges_handle.cc +++ b/content/browser/web_package/bundled_exchanges_handle.cc
@@ -62,10 +62,10 @@ // A class to provide a network::mojom::URLLoader interface to redirect a // request to the BundledExchanges to the main resource url. -class BundledExchangesHandle::StartURLRedirectLoader final +class BundledExchangesHandle::PrimaryURLRedirectLoader final : public network::mojom::URLLoader { public: - StartURLRedirectLoader( + PrimaryURLRedirectLoader( const network::ResourceRequest& resource_request, mojo::PendingRemote<network::mojom::URLLoaderClient> client) : client_(std::move(client)) { @@ -99,7 +99,7 @@ client_->OnReceiveRedirect(redirect_info_, response_head); } - base::WeakPtr<StartURLRedirectLoader> GetWeakPtr() { + base::WeakPtr<PrimaryURLRedirectLoader> GetWeakPtr() { return weak_factory_.GetWeakPtr(); } @@ -118,9 +118,9 @@ mojo::Remote<network::mojom::URLLoaderClient> client_; net::RedirectInfo redirect_info_; - base::WeakPtrFactory<StartURLRedirectLoader> weak_factory_{this}; + base::WeakPtrFactory<PrimaryURLRedirectLoader> weak_factory_{this}; - DISALLOW_COPY_AND_ASSIGN(StartURLRedirectLoader); + DISALLOW_COPY_AND_ASSIGN(PrimaryURLRedirectLoader); }; BundledExchangesHandle::BundledExchangesHandle( @@ -141,7 +141,7 @@ BundledExchangesHandle::CreateInterceptor() { DCHECK_CURRENTLY_ON(BrowserThread::UI); return std::make_unique<Interceptor>( - base::BindRepeating(&BundledExchangesHandle::CreateStartURLLoader, + base::BindRepeating(&BundledExchangesHandle::CreatePrimaryURLLoader, weak_factory_.GetWeakPtr())); } @@ -153,7 +153,7 @@ NOTIMPLEMENTED(); } -void BundledExchangesHandle::CreateStartURLLoader( +void BundledExchangesHandle::CreatePrimaryURLLoader( const network::ResourceRequest& resource_request, network::mojom::URLLoaderRequest request, network::mojom::URLLoaderClientPtr client) { @@ -166,7 +166,7 @@ DCHECK(!redirect_loader_); is_redirected_ = true; auto redirect_loader = - std::make_unique<BundledExchangesHandle::StartURLRedirectLoader>( + std::make_unique<BundledExchangesHandle::PrimaryURLRedirectLoader>( resource_request, client.PassInterface()); redirect_loader_ = redirect_loader->GetWeakPtr(); std::unique_ptr<network::mojom::URLLoader> url_loader( @@ -174,22 +174,22 @@ mojo::MakeSelfOwnedReceiver( std::move(url_loader), mojo::PendingReceiver<network::mojom::URLLoader>(std::move(request))); - MayRedirectStartURLLoader(); + MayRedirectPrimaryURLLoader(); } else { // TODO(crbug.com/966753): Implement. } } -void BundledExchangesHandle::MayRedirectStartURLLoader() { +void BundledExchangesHandle::MayRedirectPrimaryURLLoader() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - // CreatedStartURLLoader() and OnMetadataReady() both should be called + // CreatedPrimaryURLLoader() and OnMetadataReady() both should be called // beforehand. Otherwise, do nothing and wait the next call. - if (!redirect_loader_ || (!start_url_.is_valid() && !start_url_error_)) + if (!redirect_loader_ || (!primary_url_.is_valid() && !metadata_error_)) return; - redirect_loader_->OnReadyToRedirect(std::move(start_url_), - std::move(start_url_error_)); + redirect_loader_->OnReadyToRedirect(std::move(primary_url_), + std::move(metadata_error_)); redirect_loader_.reset(); } @@ -197,9 +197,9 @@ data_decoder::mojom::BundleMetadataParseErrorPtr error) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - start_url_ = std::move(reader_->GetStartURL()); - start_url_error_ = std::move(error); - MayRedirectStartURLLoader(); + primary_url_ = std::move(reader_->GetPrimaryURL()); + metadata_error_ = std::move(error); + MayRedirectPrimaryURLLoader(); } } // namespace content
diff --git a/content/browser/web_package/bundled_exchanges_handle.h b/content/browser/web_package/bundled_exchanges_handle.h index e493a31..0b822a9 100644 --- a/content/browser/web_package/bundled_exchanges_handle.h +++ b/content/browser/web_package/bundled_exchanges_handle.h
@@ -43,20 +43,20 @@ mojo::Remote<network::mojom::URLLoaderFactory> fallback_factory); private: - class StartURLRedirectLoader; + class PrimaryURLRedirectLoader; - void CreateStartURLLoader(const network::ResourceRequest& resource_request, - network::mojom::URLLoaderRequest request, - network::mojom::URLLoaderClientPtr client); - void MayRedirectStartURLLoader(); + void CreatePrimaryURLLoader(const network::ResourceRequest& resource_request, + network::mojom::URLLoaderRequest request, + network::mojom::URLLoaderClientPtr client); + void MayRedirectPrimaryURLLoader(); void OnMetadataReady(data_decoder::mojom::BundleMetadataParseErrorPtr error); const BundledExchangesSource source_; - base::WeakPtr<StartURLRedirectLoader> redirect_loader_; + base::WeakPtr<PrimaryURLRedirectLoader> redirect_loader_; std::unique_ptr<BundledExchangesReader> reader_; - GURL start_url_; - data_decoder::mojom::BundleMetadataParseErrorPtr start_url_error_; + GURL primary_url_; + data_decoder::mojom::BundleMetadataParseErrorPtr metadata_error_; bool is_redirected_ = false; base::WeakPtrFactory<BundledExchangesHandle> weak_factory_{this};
diff --git a/content/browser/web_package/bundled_exchanges_reader.cc b/content/browser/web_package/bundled_exchanges_reader.cc index 3c0d18f..5b8860c 100644 --- a/content/browser/web_package/bundled_exchanges_reader.cc +++ b/content/browser/web_package/bundled_exchanges_reader.cc
@@ -161,12 +161,18 @@ DCHECK(metadata_ready_); auto it = entries_.find(url); - if (it == entries_.end()) { + if (it == entries_.end() || it->second->response_locations.empty()) { PostTask(FROM_HERE, base::BindOnce(std::move(callback), nullptr)); return; } + + // For now, this always reads the first response in |response_locations|. + // TODO(crbug.com/966753): This method should take request headers and choose + // the most suitable response based on the variant matching algorithm + // (https://tools.ietf.org/html/draft-ietf-httpbis-variants-05#section-4). parser_.ParseResponse( - it->second->response_offset, it->second->response_length, + it->second->response_locations[0]->offset, + it->second->response_locations[0]->length, base::BindOnce(&BundledExchangesReader::OnResponseParsed, base::Unretained(this), std::move(callback))); } @@ -197,11 +203,11 @@ return entries_.contains(url); } -const GURL& BundledExchangesReader::GetStartURL() const { +const GURL& BundledExchangesReader::GetPrimaryURL() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(metadata_ready_); - return start_url_; + return primary_url_; } void BundledExchangesReader::SetBundledExchangesParserFactoryForTesting( @@ -239,13 +245,8 @@ metadata_ready_ = true; if (metadata) { - // TODO(crbug.com/966753): Use the primary (fallback) URL that the new - // BundledExchanges format defines. - if (!metadata->index.empty()) - start_url_ = metadata->index[0]->request_url; - - for (auto& item : metadata->index) - entries_.insert(std::make_pair(item->request_url, std::move(item))); + primary_url_ = metadata->primary_url; + entries_ = std::move(metadata->requests); } std::move(callback).Run(std::move(error)); }
diff --git a/content/browser/web_package/bundled_exchanges_reader.h b/content/browser/web_package/bundled_exchanges_reader.h index 92d90911..8f19605 100644 --- a/content/browser/web_package/bundled_exchanges_reader.h +++ b/content/browser/web_package/bundled_exchanges_reader.h
@@ -63,9 +63,9 @@ // Should be called after ReadMetadata finishes. bool HasEntry(const GURL& url) const; - // Returns start page URL. + // Returns the bundle's primary URL. // Should be called after ReadMetadata finishes. - const GURL& GetStartURL() const; + const GURL& GetPrimaryURL() const; void SetBundledExchangesParserFactoryForTesting( mojo::Remote<data_decoder::mojom::BundledExchangesParserFactory> factory); @@ -106,8 +106,8 @@ data_decoder::SafeBundledExchangesParser parser_; scoped_refptr<SharedFile> file_; - GURL start_url_; - base::flat_map<GURL, data_decoder::mojom::BundleIndexItemPtr> entries_; + GURL primary_url_; + base::flat_map<GURL, data_decoder::mojom::BundleIndexValuePtr> entries_; bool metadata_ready_ = false; base::WeakPtrFactory<BundledExchangesReader> weak_factory_{this};
diff --git a/content/browser/web_package/bundled_exchanges_reader_unittest.cc b/content/browser/web_package/bundled_exchanges_reader_unittest.cc index efb1af4a..daa41eff 100644 --- a/content/browser/web_package/bundled_exchanges_reader_unittest.cc +++ b/content/browser/web_package/bundled_exchanges_reader_unittest.cc
@@ -154,24 +154,22 @@ }, run_loop.QuitClosure())); - std::vector<data_decoder::mojom::BundleIndexItemPtr> items; - data_decoder::mojom::BundleIndexItemPtr item = - data_decoder::mojom::BundleIndexItem::New(); - item->request_url = start_url_; - item->response_offset = 573u; - item->response_length = 765u; - items.push_back(std::move(item)); + base::flat_map<GURL, data_decoder::mojom::BundleIndexValuePtr> items; + data_decoder::mojom::BundleIndexValuePtr item = + data_decoder::mojom::BundleIndexValue::New(); + item->response_locations.push_back( + data_decoder::mojom::BundleResponseLocation::New(573u, 765u)); + items.insert({primary_url_, std::move(item)}); data_decoder::mojom::BundleMetadataPtr metadata = - data_decoder::mojom::BundleMetadata::New(GURL() /* primary_url */, - std::move(items), + data_decoder::mojom::BundleMetadata::New(primary_url_, std::move(items), GURL() /* manifest_url */); factory_->RunMetadataCallback(std::move(metadata)); run_loop.Run(); } BundledExchangesReader* GetReader() { return reader_.get(); } MockParserFactory* GetFactory() { return factory_; } - const GURL& GetStartURL() const { return start_url_; } + const GURL& GetPrimaryURL() const { return primary_url_; } const std::string& GetBody() const { return body_; } private: @@ -180,35 +178,35 @@ base::FilePath temp_file_path_; std::unique_ptr<BundledExchangesReader> reader_; MockParserFactory* factory_; - const GURL start_url_ = GURL("https://www.google.com/"); + const GURL primary_url_ = GURL("https://www.google.com/"); const std::string body_ = std::string("hello new open world."); }; TEST_F(BundledExchangesReaderTest, ReadMetadata) { ReadMetadata(); - EXPECT_EQ(GetStartURL(), GetReader()->GetStartURL()); - EXPECT_TRUE(GetReader()->HasEntry(GetStartURL())); + EXPECT_EQ(GetPrimaryURL(), GetReader()->GetPrimaryURL()); + EXPECT_TRUE(GetReader()->HasEntry(GetPrimaryURL())); EXPECT_FALSE(GetReader()->HasEntry(GURL("https://www.google.com/404"))); } TEST_F(BundledExchangesReaderTest, ReadResponse) { ReadMetadata(); - ASSERT_TRUE(GetReader()->HasEntry(GetStartURL())); + ASSERT_TRUE(GetReader()->HasEntry(GetPrimaryURL())); base::RunLoop run_loop; GetReader()->ReadResponse( - GetStartURL(), base::BindOnce( - [](base::Closure quit_closure, - data_decoder::mojom::BundleResponsePtr response) { - EXPECT_TRUE(response); - if (response) { - EXPECT_EQ(200, response->response_code); - EXPECT_EQ(0xdeadu, response->payload_offset); - EXPECT_EQ(0xbeafu, response->payload_length); - } - std::move(quit_closure).Run(); - }, - run_loop.QuitClosure())); + GetPrimaryURL(), base::BindOnce( + [](base::Closure quit_closure, + data_decoder::mojom::BundleResponsePtr response) { + EXPECT_TRUE(response); + if (response) { + EXPECT_EQ(200, response->response_code); + EXPECT_EQ(0xdeadu, response->payload_offset); + EXPECT_EQ(0xbeafu, response->payload_length); + } + std::move(quit_closure).Run(); + }, + run_loop.QuitClosure())); data_decoder::mojom::BundleResponsePtr response = data_decoder::mojom::BundleResponse::New();
diff --git a/content/browser/webui/shared_resources_data_source.cc b/content/browser/webui/shared_resources_data_source.cc index 9d894c7..0bf848b 100644 --- a/content/browser/webui/shared_resources_data_source.cc +++ b/content/browser/webui/shared_resources_data_source.cc
@@ -324,7 +324,7 @@ bytes = GetContentClient()->GetDataResourceBytes(idr); } - callback.Run(bytes.get()); + callback.Run(std::move(bytes)); } bool SharedResourcesDataSource::AllowCaching() { @@ -414,10 +414,6 @@ return origin; } -bool SharedResourcesDataSource::IsGzipped(const std::string& path) { - return GetContentClient()->IsDataResourceGzipped(GetIdrForPath(path)); -} - #if defined(OS_CHROMEOS) void SharedResourcesDataSource::DisablePolymer2ForHost( const std::string& host) {
diff --git a/content/browser/webui/shared_resources_data_source.h b/content/browser/webui/shared_resources_data_source.h index 3775ca0..e8f3617 100644 --- a/content/browser/webui/shared_resources_data_source.h +++ b/content/browser/webui/shared_resources_data_source.h
@@ -32,7 +32,6 @@ const std::string& path) override; std::string GetAccessControlAllowOriginForOrigin( const std::string& origin) override; - bool IsGzipped(const std::string& path) override; #if defined(OS_CHROMEOS) void DisablePolymer2ForHost(const std::string& host) override; #endif // defined (OS_CHROMEOS)
diff --git a/content/browser/webui/url_data_manager_backend.cc b/content/browser/webui/url_data_manager_backend.cc index c98ea4f..5d96fc45 100644 --- a/content/browser/webui/url_data_manager_backend.cc +++ b/content/browser/webui/url_data_manager_backend.cc
@@ -34,7 +34,6 @@ #include "content/public/common/url_constants.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" -#include "net/filter/gzip_source_stream.h" #include "net/filter/source_stream.h" #include "net/http/http_status_code.h" #include "net/log/net_log_util.h"
diff --git a/content/browser/webui/web_ui_data_source_impl.cc b/content/browser/webui/web_ui_data_source_impl.cc index 03636a1..1cd6992 100644 --- a/content/browser/webui/web_ui_data_source_impl.cc +++ b/content/browser/webui/web_ui_data_source_impl.cc
@@ -97,9 +97,6 @@ return parent_->deny_xframe_options_; } bool ShouldServeMimeTypeAsContentTypeHeader() override { return true; } - bool IsGzipped(const std::string& path) override { - return parent_->IsGzipped(path); - } private: WebUIDataSourceImpl* parent_; @@ -300,28 +297,6 @@ return &localized_strings_; } -bool WebUIDataSourceImpl::IsGzipped(const std::string& path) const { - // Note: In the hypothetical case of requests handled by |filter_callback_| - // that involve gzipped data, the callback itself is responsible for - // ungzipping, and IsGzipped will return false for such cases. - if (!should_handle_request_callback_.is_null() && - should_handle_request_callback_.Run(path)) { - return false; - } - - if (!json_path_.empty() && path == json_path_) { - return false; - } - - std::string file_path = CleanUpPath(path); - int idr = PathToIdrOrDefault(file_path); - if (idr == -1) { - return false; - } - - return GetContentClient()->IsDataResourceGzipped(idr); -} - int WebUIDataSourceImpl::PathToIdrOrDefault(const std::string& path) const { auto it = path_to_idr_map_.find(path); return it == path_to_idr_map_.end() ? default_resource_ : it->second;
diff --git a/content/browser/webui/web_ui_data_source_impl.h b/content/browser/webui/web_ui_data_source_impl.h index 2942c35..5038f82 100644 --- a/content/browser/webui/web_ui_data_source_impl.h +++ b/content/browser/webui/web_ui_data_source_impl.h
@@ -77,10 +77,6 @@ friend class WebUIDataSource; friend class WebUIDataSourceTest; - FRIEND_TEST_ALL_PREFIXES(WebUIDataSourceTest, IsGzipped); - FRIEND_TEST_ALL_PREFIXES(WebUIDataSourceTest, IsGzippedNoDefaultResource); - FRIEND_TEST_ALL_PREFIXES(WebUIDataSourceTest, IsGzippedWithRequestFiltering); - // Methods that match URLDataSource which are called by // InternalDataSource. std::string GetMimeType(const std::string& path) const; @@ -95,8 +91,6 @@ add_load_time_data_defaults_ = false; } - bool IsGzipped(const std::string& path) const; - // The name of this source. // E.g., for favicons, this could be "favicon", which results in paths for // specific resources like "favicon/34" getting sent to this source.
diff --git a/content/browser/webui/web_ui_data_source_unittest.cc b/content/browser/webui/web_ui_data_source_unittest.cc index 3a2519b..8f595e0 100644 --- a/content/browser/webui/web_ui_data_source_unittest.cc +++ b/content/browser/webui/web_ui_data_source_unittest.cc
@@ -24,7 +24,6 @@ class TestClient : public TestContentClient { public: - TestClient() : is_gzipped_(false) {} ~TestClient() override {} base::string16 GetLocalizedString(int message_id) override { @@ -44,14 +43,6 @@ } return bytes; } - - bool IsDataResourceGzipped(int resource_id) override { return is_gzipped_; } - - // Sets the response for |IsDataResourceGzipped()|. - void SetIsDataResourceGzipped(bool is_gzipped) { is_gzipped_ = is_gzipped; } - - private: - bool is_gzipped_; }; } // namespace @@ -223,51 +214,6 @@ EXPECT_EQ(GetMimeType("foo.js?abc?abc"), js); } -TEST_F(WebUIDataSourceTest, IsGzipped) { - source()->SetJsonPath("strings.js"); - source()->SetDefaultResource(kDummyDefaultResourceId); - - // Test that WebUIDataSource delegates IsGzipped to the content client. - client_.SetIsDataResourceGzipped(false); - EXPECT_FALSE(source()->IsGzipped("foobar")); - EXPECT_FALSE(source()->IsGzipped("")); - // Test that |json_path_| is correctly reported as non-gzipped. - EXPECT_FALSE(source()->IsGzipped("strings.js")); - - client_.SetIsDataResourceGzipped(true); - EXPECT_TRUE(source()->IsGzipped("foobar")); - EXPECT_TRUE(source()->IsGzipped("")); - // Test that |json_path_| is correctly reported as non-gzipped. - EXPECT_FALSE(source()->IsGzipped("strings.js")); -} - -TEST_F(WebUIDataSourceTest, IsGzippedNoDefaultResource) { - // Test that WebUIDataSource reports non existing resources as non-gzipped - // and does not trigger any CHECKs. - client_.SetIsDataResourceGzipped(false); - EXPECT_FALSE(source()->IsGzipped("foobar")); - - client_.SetIsDataResourceGzipped(true); - EXPECT_FALSE(source()->IsGzipped("foobar")); -} - -TEST_F(WebUIDataSourceTest, IsGzippedWithRequestFiltering) { - source()->SetRequestFilter( - base::BindRepeating( - [](const std::string& path) { return path == "json/special/path"; }), - base::BindRepeating(&WebUIDataSourceTest::HandleRequest, - base::Unretained(this))); - source()->SetDefaultResource(kDummyDefaultResourceId); - - client_.SetIsDataResourceGzipped(false); - EXPECT_FALSE(source()->IsGzipped("json/special/path")); - EXPECT_FALSE(source()->IsGzipped("other/path")); - - client_.SetIsDataResourceGzipped(true); - EXPECT_FALSE(source()->IsGzipped("json/special/path")); - EXPECT_TRUE(source()->IsGzipped("other/path")); -} - TEST_F(WebUIDataSourceTest, ShouldServeMimeTypeAsContentTypeHeader) { EXPECT_TRUE(source()->source()->ShouldServeMimeTypeAsContentTypeHeader()); }
diff --git a/content/browser/webui/web_ui_url_loader_factory.cc b/content/browser/webui/web_ui_url_loader_factory.cc index 3ef29b7..0ba5cf0 100644 --- a/content/browser/webui/web_ui_url_loader_factory.cc +++ b/content/browser/webui/web_ui_url_loader_factory.cc
@@ -32,7 +32,6 @@ #include "content/public/common/url_constants.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "services/network/public/mojom/network_service.mojom.h" -#include "third_party/zlib/google/compression_utils.h" #include "ui/base/template_expressions.h" namespace content { @@ -56,7 +55,6 @@ void ReadData(scoped_refptr<network::ResourceResponse> headers, const ui::TemplateReplacements* replacements, - bool gzipped, scoped_refptr<URLDataSourceImpl> data_source, network::mojom::URLLoaderClientPtrInfo client_info, scoped_refptr<base::RefCountedMemory> bytes) { @@ -69,34 +67,16 @@ client.Bind(std::move(client_info)); client->OnReceiveResponse(headers->head); - base::StringPiece input(reinterpret_cast<const char*>(bytes->front()), - bytes->size()); - - // Treats empty gzipped data as unzipped. - if (!bytes->size()) - gzipped = false; - if (replacements) { - std::string temp_string; // We won't know the the final output size ahead of time, so we have to // use an intermediate string. - base::StringPiece source; - std::string temp_str; - if (gzipped) { - temp_str.resize(compression::GetUncompressedSize(input)); - source.set(temp_str.c_str(), temp_str.size()); - CHECK(compression::GzipUncompress(input, source)); - gzipped = false; - } else { - source = input; - } - temp_str = ui::ReplaceTemplateExpressions(source, *replacements); + base::StringPiece input(reinterpret_cast<const char*>(bytes->front()), + bytes->size()); + std::string temp_str = ui::ReplaceTemplateExpressions(input, *replacements); bytes = base::RefCountedString::TakeString(&temp_str); - input.set(reinterpret_cast<const char*>(bytes->front()), bytes->size()); } - uint32_t output_size = - gzipped ? compression::GetUncompressedSize(input) : bytes->size(); + uint32_t output_size = bytes->size(); mojo::DataPipe data_pipe(output_size); @@ -107,12 +87,7 @@ CHECK_EQ(result, MOJO_RESULT_OK); CHECK_GE(num_bytes, output_size); - if (gzipped) { - base::StringPiece output(static_cast<char*>(buffer), output_size); - CHECK(compression::GzipUncompress(input, output)); - } else { - memcpy(buffer, bytes->front(), output_size); - } + memcpy(buffer, bytes->front(), output_size); result = data_pipe.producer_handle->EndWriteData(output_size); CHECK_EQ(result, MOJO_RESULT_OK); @@ -126,7 +101,6 @@ void DataAvailable(scoped_refptr<network::ResourceResponse> headers, const ui::TemplateReplacements* replacements, - bool gzipped, scoped_refptr<URLDataSourceImpl> source, network::mojom::URLLoaderClientPtrInfo client_info, scoped_refptr<base::RefCountedMemory> bytes) { @@ -137,8 +111,8 @@ {base::ThreadPool(), base::TaskPriority::USER_BLOCKING, base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}) ->PostTask(FROM_HERE, - base::BindOnce(ReadData, headers, replacements, gzipped, - source, std::move(client_info), bytes)); + base::BindOnce(ReadData, headers, replacements, source, + std::move(client_info), bytes)); } void StartURLLoader(const network::ResourceRequest& request, @@ -184,15 +158,14 @@ WebContents::Getter wc_getter = base::Bind(WebContents::FromFrameTreeNodeId, frame_tree_node_id); - bool gzipped = source->source()->IsGzipped(path); const ui::TemplateReplacements* replacements = nullptr; if (source->source()->GetMimeType(path) == "text/html") replacements = source->GetReplacements(); // To keep the same behavior as the old WebUI code, we call the source to get - // the value for |gzipped| and |replacements| on the IO thread. Since - // |replacements| is owned by |source| keep a reference to it in the callback. + // the value for |replacements| on the IO thread. Since |replacements| is + // owned by |source| keep a reference to it in the callback. auto data_available_callback = - base::Bind(DataAvailable, resource_response, replacements, gzipped, + base::Bind(DataAvailable, resource_response, replacements, base::RetainedRef(source), base::Passed(&client_info)); // TODO(jam): once we only have this code path for WebUI, and not the
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index 68cda70..9035e007 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -292,9 +292,6 @@ if (base::FeatureList::IsEnabled(features::kServiceWorkerPaymentApps)) WebRuntimeFeatures::EnablePaymentApp(true); - WebRuntimeFeatures::EnableNetworkService( - base::FeatureList::IsEnabled(network::features::kNetworkService)); - if (base::FeatureList::IsEnabled(features::kCompositeOpaqueFixedPosition)) WebRuntimeFeatures::EnableFeatureFromString("CompositeOpaqueFixedPosition", true);
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn index 87987b7..0e2f82f 100644 --- a/content/public/android/BUILD.gn +++ b/content/public/android/BUILD.gn
@@ -149,7 +149,6 @@ "java/src/org/chromium/content/browser/RenderCoordinatesImpl.java", "java/src/org/chromium/content/browser/RenderWidgetHostViewImpl.java", "java/src/org/chromium/content/browser/ScreenOrientationProviderImpl.java", - "java/src/org/chromium/content/browser/SmsReceiver.java", "java/src/org/chromium/content/browser/SpareChildConnection.java", "java/src/org/chromium/content/browser/SpeechRecognitionImpl.java", "java/src/org/chromium/content/browser/SyntheticGestureTarget.java", @@ -234,6 +233,8 @@ "java/src/org/chromium/content/browser/selection/SmartSelectionClient.java", "java/src/org/chromium/content/browser/selection/SmartSelectionMetricsLogger.java", "java/src/org/chromium/content/browser/selection/SmartSelectionProvider.java", + "java/src/org/chromium/content/browser/sms/SmsReceiver.java", + "java/src/org/chromium/content/browser/sms/Wrappers.java", "java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java", "java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java", "java/src/org/chromium/content/common/ContentSwitchUtils.java", @@ -407,7 +408,6 @@ "java/src/org/chromium/content/browser/NfcHost.java", "java/src/org/chromium/content/browser/RenderWidgetHostViewImpl.java", "java/src/org/chromium/content/browser/ScreenOrientationProviderImpl.java", - "java/src/org/chromium/content/browser/SmsReceiver.java", "java/src/org/chromium/content/browser/SpeechRecognitionImpl.java", "java/src/org/chromium/content/browser/SyntheticGestureTarget.java", "java/src/org/chromium/content/browser/TracingControllerAndroidImpl.java", @@ -426,6 +426,7 @@ "java/src/org/chromium/content/browser/input/TextSuggestionHost.java", "java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java", "java/src/org/chromium/content/browser/selection/SmartSelectionClient.java", + "java/src/org/chromium/content/browser/sms/SmsReceiver.java", "java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java", "java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java", "java/src/org/chromium/content/common/ServiceManagerConnectionImpl.java",
diff --git a/content/public/android/java/src/org/chromium/content/browser/SmsReceiver.java b/content/public/android/java/src/org/chromium/content/browser/sms/SmsReceiver.java similarity index 78% rename from content/public/android/java/src/org/chromium/content/browser/SmsReceiver.java rename to content/public/android/java/src/org/chromium/content/browser/sms/SmsReceiver.java index fa2222e..ced78b5 100644 --- a/content/public/android/java/src/org/chromium/content/browser/SmsReceiver.java +++ b/content/public/android/java/src/org/chromium/content/browser/sms/SmsReceiver.java
@@ -2,7 +2,7 @@ // 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; +package org.chromium.content.browser.sms; import android.content.BroadcastReceiver; import android.content.Context; @@ -10,14 +10,15 @@ import android.content.IntentFilter; import com.google.android.gms.auth.api.phone.SmsRetriever; -import com.google.android.gms.auth.api.phone.SmsRetrieverClient; import com.google.android.gms.common.api.CommonStatusCodes; import com.google.android.gms.common.api.Status; import com.google.android.gms.tasks.Task; import org.chromium.base.ContextUtils; import org.chromium.base.Log; +import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.annotations.JNIAdditionalImport; import org.chromium.base.annotations.JNINamespace; /** @@ -25,17 +26,20 @@ * SMS retriever. */ @JNINamespace("content") +@JNIAdditionalImport(Wrappers.class) public class SmsReceiver extends BroadcastReceiver { private static final String TAG = "SmsReceiver"; private static final boolean DEBUG = false; private final long mSmsProviderAndroid; private boolean mDestroyed; + private Wrappers.SmsRetrieverClientWrapper mClient; + private Wrappers.SmsReceiverContext mContext; private SmsReceiver(long smsProviderAndroid) { mDestroyed = false; mSmsProviderAndroid = smsProviderAndroid; - final Context context = ContextUtils.getApplicationContext(); + mContext = new Wrappers.SmsReceiverContext(ContextUtils.getApplicationContext()); // A broadcast receiver is registered upon the creation of this class // which happens when the SMS Retriever API is used for the first time @@ -47,7 +51,7 @@ if (DEBUG) Log.d(TAG, "Registering intent filters."); IntentFilter filter = new IntentFilter(); filter.addAction(SmsRetriever.SMS_RETRIEVED_ACTION); - context.registerReceiver(this, filter); + mContext.registerReceiver(this, filter); } @CalledByNative @@ -60,8 +64,7 @@ private void destroy() { if (DEBUG) Log.d(TAG, "Destroying SmsReceiver."); mDestroyed = true; - final Context context = ContextUtils.getApplicationContext(); - context.unregisterReceiver(this); + mContext.unregisterReceiver(this); } @Override @@ -104,14 +107,27 @@ @CalledByNative private void listen() { - final Context context = ContextUtils.getApplicationContext(); - - SmsRetrieverClient client = SmsRetriever.getClient(context); + Wrappers.SmsRetrieverClientWrapper client = getClient(); Task<Void> task = client.startSmsRetriever(); if (DEBUG) Log.d(TAG, "Installed task"); } + private Wrappers.SmsRetrieverClientWrapper getClient() { + if (mClient != null) { + return mClient; + } + mClient = new Wrappers.SmsRetrieverClientWrapper(SmsRetriever.getClient(mContext)); + return mClient; + } + + @VisibleForTesting + public void setClientForTesting(Wrappers.SmsRetrieverClientWrapper client) { + assert mClient == null; + mClient = client; + mClient.setContext(mContext); + } + private static native void nativeOnReceive(long nativeSmsProviderAndroid, String sms); private static native void nativeOnTimeout(long nativeSmsProviderAndroid); }
diff --git a/content/public/android/java/src/org/chromium/content/browser/sms/Wrappers.java b/content/public/android/java/src/org/chromium/content/browser/sms/Wrappers.java new file mode 100644 index 0000000..416a049 --- /dev/null +++ b/content/public/android/java/src/org/chromium/content/browser/sms/Wrappers.java
@@ -0,0 +1,74 @@ +// 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. + +package org.chromium.content.browser.sms; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.ContextWrapper; +import android.content.Intent; +import android.content.IntentFilter; + +import com.google.android.gms.auth.api.phone.SmsRetrieverClient; +import com.google.android.gms.tasks.Task; + +class Wrappers { + // Prevent instantiation. + private Wrappers() {} + + /** + * Wraps com.google.android.gms.auth.api.phone.SmsRetrieverClient. + */ + static class SmsRetrieverClientWrapper { + private final SmsRetrieverClient mSmsRetrieverClient; + private SmsReceiverContext mContext; + + public SmsRetrieverClientWrapper(SmsRetrieverClient smsRetrieverClient) { + mSmsRetrieverClient = smsRetrieverClient; + } + + public void setContext(SmsReceiverContext context) { + mContext = context; + } + + public SmsReceiverContext getContext() { + return mContext; + } + + public Task<Void> startSmsRetriever() { + return mSmsRetrieverClient.startSmsRetriever(); + } + } + + /** + * Extends android.content.ContextWrapper to store and retrieve the + * registered BroadcastReceiver. + */ + static class SmsReceiverContext extends ContextWrapper { + private BroadcastReceiver mReceiver; + + public SmsReceiverContext(Context context) { + super(context); + } + + public BroadcastReceiver getRegisteredReceiver() { + return mReceiver; + } + + // --------------------------------------------------------------------- + // Context overrides: + + @Override + public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { + mReceiver = receiver; + return super.registerReceiver(receiver, filter); + } + + @Override + public void unregisterReceiver(BroadcastReceiver receiver) { + mReceiver = null; + super.unregisterReceiver(receiver); + } + } +}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/sms/Fakes.java b/content/public/android/javatests/src/org/chromium/content/browser/sms/Fakes.java new file mode 100644 index 0000000..0769aa4 --- /dev/null +++ b/content/public/android/javatests/src/org/chromium/content/browser/sms/Fakes.java
@@ -0,0 +1,78 @@ +// 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. + +package org.chromium.content.browser.sms; + +import android.content.BroadcastReceiver; +import android.content.Intent; +import android.os.Bundle; + +import com.google.android.gms.auth.api.phone.SmsRetriever; +import com.google.android.gms.common.api.CommonStatusCodes; +import com.google.android.gms.common.api.Status; +import com.google.android.gms.tasks.Task; +import com.google.android.gms.tasks.Tasks; + +import org.chromium.base.Log; +import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.annotations.JNIAdditionalImport; +import org.chromium.base.annotations.JNINamespace; + +@JNINamespace("content") +@JNIAdditionalImport(Wrappers.class) +class Fakes { + private static final String TAG = "SmsReceiver"; + + /** + * Fakes com.google.android.gms.auth.api.phone.SmsRetrieverClient. + **/ + static class FakeSmsRetrieverClient extends Wrappers.SmsRetrieverClientWrapper { + @CalledByNative("FakeSmsRetrieverClient") + private static FakeSmsRetrieverClient create() { + Log.v(TAG, "FakeSmsRetrieverClient.create"); + return new FakeSmsRetrieverClient(); + } + + private FakeSmsRetrieverClient() { + super(null); + } + + @CalledByNative("FakeSmsRetrieverClient") + private Task<Void> triggerSms(String sms) { + Wrappers.SmsReceiverContext context = super.getContext(); + if (context == null) { + Log.v(TAG, "FakeSmsRetrieverClient.triggerSms failed: no context was set"); + return Tasks.forResult(null); + } + + Intent intent = new Intent(SmsRetriever.SMS_RETRIEVED_ACTION); + Bundle bundle = new Bundle(); + bundle.putParcelable(SmsRetriever.EXTRA_STATUS, new Status(CommonStatusCodes.SUCCESS)); + bundle.putString(SmsRetriever.EXTRA_SMS_MESSAGE, sms); + intent.putExtras(bundle); + + BroadcastReceiver receiver = context.getRegisteredReceiver(); + receiver.onReceive(context, intent); + return Tasks.forResult(null); + } + + // --------------------------------------------------------------------- + // SmsRetrieverClient overrides: + + @Override + public Task<Void> startSmsRetriever() { + return Tasks.forResult(null); + } + } + + /** + * Sets SmsRetrieverClient to SmsReceiver to allow faking SMSes from android + * client. + **/ + @CalledByNative + private static void setClientForTesting( + SmsReceiver receiver, Wrappers.SmsRetrieverClientWrapper client) { + receiver.setClientForTesting(client); + } +}
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h index 18b1df13..0bdb9e8 100644 --- a/content/public/browser/web_contents.h +++ b/content/public/browser/web_contents.h
@@ -488,6 +488,10 @@ virtual bool IsConnectedToSerialPort() = 0; // Indicates whether any frame in the WebContents has native file system + // handles. + virtual bool HasNativeFileSystemHandles() = 0; + + // Indicates whether any frame in the WebContents has native file system // directory handles. virtual bool HasNativeFileSystemDirectoryHandles() = 0;
diff --git a/content/public/common/content_client.cc b/content/public/common/content_client.cc index fb44bda5..4a8b56d6 100644 --- a/content/public/common/content_client.cc +++ b/content/public/common/content_client.cc
@@ -90,10 +90,6 @@ return nullptr; } -bool ContentClient::IsDataResourceGzipped(int resource_id) { - return false; -} - gfx::Image& ContentClient::GetNativeImageNamed(int resource_id) { static base::NoDestructor<gfx::Image> kEmptyImage; return *kEmptyImage;
diff --git a/content/public/common/content_client.h b/content/public/common/content_client.h index 59656ba..004abd7 100644 --- a/content/public/common/content_client.h +++ b/content/public/common/content_client.h
@@ -165,9 +165,6 @@ // Returns the raw bytes of a scale independent data resource. virtual base::RefCountedMemory* GetDataResourceBytes(int resource_id); - // Returns whether the contents of a resource are compressed (with gzip). - virtual bool IsDataResourceGzipped(int resource_id); - // Returns a native image given its id. virtual gfx::Image& GetNativeImageNamed(int resource_id);
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index f1b9a8a..61ea721 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -110,7 +110,7 @@ // When enabled, event.movement is calculated in blink instead of in browser. const base::Feature kConsolidatedMovementXY{"ConsolidatedMovementXY", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; // Show messages in the DevTools console about upcoming deprecations // that would affect sent/received cookies.
diff --git a/content/public/renderer/render_frame.h b/content/public/renderer/render_frame.h index 68eff93..cf1d870 100644 --- a/content/public/renderer/render_frame.h +++ b/content/public/renderer/render_frame.h
@@ -319,6 +319,9 @@ // a local root. virtual void UpdateAllLifecyclePhasesAndCompositeForTesting() = 0; + // Sets that cross browsing instance frame lookup is allowed. + virtual void SetAllowsCrossBrowsingInstanceFrameLookup() = 0; + protected: ~RenderFrame() override {}
diff --git a/content/renderer/media/media_permission_dispatcher.cc b/content/renderer/media/media_permission_dispatcher.cc index 73bcdb5..44bc50b6 100644 --- a/content/renderer/media/media_permission_dispatcher.cc +++ b/content/renderer/media/media_permission_dispatcher.cc
@@ -131,8 +131,8 @@ MediaPermissionDispatcher::GetPermissionService() { if (!permission_service_) { render_frame_->GetRemoteInterfaces()->GetInterface( - mojo::MakeRequest(&permission_service_)); - permission_service_.set_connection_error_handler(base::BindOnce( + permission_service_.BindNewPipeAndPassReceiver()); + permission_service_.set_disconnect_handler(base::BindOnce( &MediaPermissionDispatcher::OnConnectionError, base::Unretained(this))); }
diff --git a/content/renderer/media/media_permission_dispatcher.h b/content/renderer/media/media_permission_dispatcher.h index ed1a490..e3d48f7a 100644 --- a/content/renderer/media/media_permission_dispatcher.h +++ b/content/renderer/media/media_permission_dispatcher.h
@@ -16,6 +16,7 @@ #include "content/common/content_export.h" #include "content/renderer/render_frame_impl.h" #include "media/base/media_permission.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/permissions/permission.mojom.h" namespace base { @@ -63,7 +64,7 @@ scoped_refptr<base::SingleThreadTaskRunner> task_runner_; uint32_t next_request_id_; RequestMap requests_; - blink::mojom::PermissionServicePtr permission_service_; + mojo::Remote<blink::mojom::PermissionService> permission_service_; // The |RenderFrameImpl| that owns this MediaPermissionDispatcher. It's okay // to hold a raw pointer here because the lifetime of this object is bounded
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index bc13bb58..29411d2 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -6218,6 +6218,9 @@ DCHECK(!(was_within_same_document && interface_params)); UpdateStateForCommit(item, commit_type, transition); + if (render_view_->renderer_wide_named_frame_lookup()) + GetWebFrame()->SetAllowsCrossBrowsingInstanceFrameLookup(); + // This invocation must precede any calls to allowScripts(), allowImages(), or // allowPlugins() for the new page. This ensures that when these functions // send ViewHostMsg_ContentBlocked messages, those arrive after the browser @@ -7565,6 +7568,10 @@ NOTREACHED(); } +void RenderFrameImpl::SetAllowsCrossBrowsingInstanceFrameLookup() { + GetWebFrame()->SetAllowsCrossBrowsingInstanceFrameLookup(); +} + #if BUILDFLAG(ENABLE_PLUGINS) void RenderFrameImpl::PepperInstanceCreated( PepperPluginInstanceImpl* instance) {
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 306f1bb..3040c30 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -520,6 +520,7 @@ void SetRenderFrameMediaPlaybackOptions( const RenderFrameMediaPlaybackOptions& opts) override; void UpdateAllLifecyclePhasesAndCompositeForTesting() override; + void SetAllowsCrossBrowsingInstanceFrameLookup() override; // blink::mojom::AutoplayConfigurationClient implementation: void AddAutoplayFlags(const url::Origin& origin,
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc index 15432c3..6fbe4b3 100644 --- a/content/shell/browser/shell_content_browser_client.cc +++ b/content/shell/browser/shell_content_browser_client.cc
@@ -413,6 +413,10 @@ } else { prefs->preferred_color_scheme = blink::PreferredColorScheme::kLight; } + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kForceHighContrast)) { + prefs->forced_colors = blink::ForcedColors::kActive; + } } DevToolsManagerDelegate*
diff --git a/content/shell/browser/web_test/blink_test_controller.cc b/content/shell/browser/web_test/blink_test_controller.cc index b2ee3b5..fce7fd5f 100644 --- a/content/shell/browser/web_test/blink_test_controller.cc +++ b/content/shell/browser/web_test/blink_test_controller.cc
@@ -78,6 +78,7 @@ #include "services/network/public/cpp/features.h" #include "services/network/public/mojom/network_service.mojom.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" +#include "ui/base/ui_base_switches.h" #include "ui/gfx/codec/png_codec.h" #if defined(OS_MACOSX) @@ -565,6 +566,10 @@ prefs->accelerated_2d_canvas_enabled = true; prefs->mock_scrollbars_enabled = true; } + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kForceHighContrast)) { + prefs->forced_colors = blink::ForcedColors::kActive; + } } }
diff --git a/content/shell/common/shell_content_client.cc b/content/shell/common/shell_content_client.cc index 05fa780..9d91e1b 100644 --- a/content/shell/common/shell_content_client.cc +++ b/content/shell/common/shell_content_client.cc
@@ -70,10 +70,6 @@ resource_id); } -bool ShellContentClient::IsDataResourceGzipped(int resource_id) { - return ui::ResourceBundle::GetSharedInstance().IsGzipped(resource_id); -} - gfx::Image& ShellContentClient::GetNativeImageNamed(int resource_id) { return ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed( resource_id);
diff --git a/content/shell/common/shell_content_client.h b/content/shell/common/shell_content_client.h index 49c58c1..96cd5fb 100644 --- a/content/shell/common/shell_content_client.h +++ b/content/shell/common/shell_content_client.h
@@ -23,7 +23,6 @@ base::StringPiece GetDataResource(int resource_id, ui::ScaleFactor scale_factor) override; base::RefCountedMemory* GetDataResourceBytes(int resource_id) override; - bool IsDataResourceGzipped(int resource_id) override; gfx::Image& GetNativeImageNamed(int resource_id) override; base::DictionaryValue GetNetLogConstants() override; blink::OriginTrialPolicy* GetOriginTrialPolicy() override;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 8bfe2b60..291adb4 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -20,6 +20,10 @@ import("//ui/base/mpris/buildflags/buildflags.gni") import("//v8/gni/v8.gni") +if (is_android) { + import("//build/config/android/rules.gni") # For generate_jni(). +} + # Use a static library here because many test binaries depend on this but don't # require many files from it. This makes linking more efficient. jumbo_static_library("test_support") { @@ -1790,6 +1794,7 @@ "../browser/service_worker/service_worker_script_loader_factory_unittest.cc", "../browser/service_worker/service_worker_single_script_update_checker_unittest.cc", "../browser/service_worker/service_worker_storage_unittest.cc", + "../browser/service_worker/service_worker_updated_script_loader_unittest.cc", "../browser/service_worker/service_worker_version_unittest.cc", "../browser/shareable_file_reference_unittest.cc", "../browser/site_instance_impl_unittest.cc", @@ -2224,12 +2229,15 @@ "../browser/font_unique_name_lookup/font_unique_name_lookup_unittest.cc", "../browser/media/capture/screen_capture_device_android_unittest.cc", "../browser/renderer_host/render_widget_host_view_android_unittest.cc", + "../browser/sms/sms_provider_android_unittest.cc", "../renderer/java/gin_java_bridge_value_converter_unittest.cc", "../renderer/media/android/stream_texture_wrapper_impl_unittest.cc", ] sources -= [ "../browser/tracing/tracing_ui_unittest.cc" ] deps += [ + ":content_unittests_java", + ":content_unittests_jni_headers", "//base:base_java_unittest_support", "//build/config/freetype", "//components/download/internal/common:internal_java", @@ -2395,3 +2403,24 @@ "//content/test/gpu/gather_swarming_json_results.py", ] } + +if (is_android) { + content_java_sources_needing_jni = [ "//content/public/android/javatests/src/org/chromium/content/browser/sms/Fakes.java" ] + + generate_jni("content_unittests_jni_headers") { + sources = content_java_sources_needing_jni + } + + android_library("content_unittests_java") { + testonly = true + java_files = content_java_sources_needing_jni + deps = [ + "$google_play_services_package:google_play_services_auth_api_phone_java", + "$google_play_services_package:google_play_services_base_java", + "$google_play_services_package:google_play_services_basement_java", + "$google_play_services_package:google_play_services_tasks_java", + "//base:base_java", + "//content/public/android:content_java", + ] + } +}
diff --git a/content/test/data/accessibility/event/add-hidden-attribute-expected-win.txt b/content/test/data/accessibility/event/add-hidden-attribute-expected-win.txt index 2c3b971..4b87b52 100644 --- a/content/test/data/accessibility/event/add-hidden-attribute-expected-win.txt +++ b/content/test/data/accessibility/event/add-hidden-attribute-expected-win.txt
@@ -1,3 +1,3 @@ -EVENT_OBJECT_HIDE on <div#item3> role=ROLE_SYSTEM_LISTITEM name="Item 3" +EVENT_OBJECT_HIDE on <div#item3> role=ROLE_SYSTEM_LISTITEM name="Item 3" PosInSet=3 SetSize=3 EVENT_OBJECT_REORDER on <div> role=ROLE_SYSTEM_LIST SetSize=2 IA2_EVENT_TEXT_REMOVED on <div> role=ROLE_SYSTEM_LIST SetSize=2 old_text={'<obj>' start=2 end=3}
diff --git a/content/test/data/accessibility/event/add-hidden-attribute-subtree-expected-win.txt b/content/test/data/accessibility/event/add-hidden-attribute-subtree-expected-win.txt index 60c866202..c7a7def 100644 --- a/content/test/data/accessibility/event/add-hidden-attribute-subtree-expected-win.txt +++ b/content/test/data/accessibility/event/add-hidden-attribute-subtree-expected-win.txt
@@ -1,3 +1,3 @@ -EVENT_OBJECT_HIDE on <li#item3> role=ROLE_SYSTEM_LISTITEM +EVENT_OBJECT_HIDE on <li#item3> role=ROLE_SYSTEM_LISTITEM PosInSet=3 SetSize=3 EVENT_OBJECT_REORDER on <ul> role=ROLE_SYSTEM_LIST SetSize=2 IA2_EVENT_TEXT_REMOVED on <ul> role=ROLE_SYSTEM_LIST SetSize=2 old_text={'<obj>' start=2 end=3}
diff --git a/content/test/data/accessibility/event/aria-combo-box-delay-show-list-expected-win.txt b/content/test/data/accessibility/event/aria-combo-box-delay-show-list-expected-win.txt index 55aef2f..c00b1f6 100644 --- a/content/test/data/accessibility/event/aria-combo-box-delay-show-list-expected-win.txt +++ b/content/test/data/accessibility/event/aria-combo-box-delay-show-list-expected-win.txt
@@ -1,5 +1,5 @@ EVENT_OBJECT_FOCUS on <li#op1> role=ROLE_SYSTEM_LISTITEM name="Apple" SELECTED,FOCUSED,FOCUSABLE,SELECTABLE PosInSet=1 SetSize=1 -EVENT_OBJECT_HIDE on <body> role=BODY +EVENT_OBJECT_HIDE on <body> role=BODY INVISIBLE IA2_EVENT_ACTIVE_DESCENDANT_CHANGED on <input> role=ROLE_SYSTEM_COMBOBOX EXPANDED,FOCUSABLE,HASPOPUP IA2_STATE_EDITABLE,IA2_STATE_SELECTABLE_TEXT,IA2_STATE_SINGLE_LINE,IA2_STATE_SUPPORTS_AUTOCOMPLETION IA2_EVENT_TEXT_INSERTED on <#document> role=ROLE_SYSTEM_DOCUMENT value~=[doc-url] FOCUSABLE new_text={'<obj><obj>' start=0 end=2} IA2_EVENT_TEXT_REMOVED on <#document> role=ROLE_SYSTEM_DOCUMENT value~=[doc-url] FOCUSABLE old_text={'<obj>' start=0 end=1}
diff --git a/content/test/data/accessibility/event/aria-hidden-changed-expected-uia-win.txt b/content/test/data/accessibility/event/aria-hidden-changed-expected-uia-win.txt new file mode 100644 index 0000000..073c1f8 --- /dev/null +++ b/content/test/data/accessibility/event/aria-hidden-changed-expected-uia-win.txt
@@ -0,0 +1,3 @@ +AriaProperties changed on role=heading, name=Item2 +AriaProperties changed on role=heading, name=Item3 +AriaProperties changed on role=heading, name=Item4
diff --git a/content/test/data/accessibility/event/aria-hidden-changed.html b/content/test/data/accessibility/event/aria-hidden-changed.html new file mode 100644 index 0000000..dd97f6c --- /dev/null +++ b/content/test/data/accessibility/event/aria-hidden-changed.html
@@ -0,0 +1,28 @@ +<!-- +@UIA-WIN-DENY:* +@UIA-WIN-ALLOW:AriaProperties* +--> +<!DOCTYPE html> +<html> +<body> + <h4 id="d1">Item1</h4> + <h4 id="d2" aria-hidden="true">Item2</h4> + <h4 id="d3" aria-hidden="false">Item3</h4> + <h4 id="d4" aria-hidden="true">Item4</h4> + <script> + function go() { + // Set aria-hidden from [removed]->false; should not fire an event. + document.getElementById('d1').setAttribute('aria-hidden', 'false'); + + // Set aria-hidden from true->false; should fire an event. + document.getElementById('d2').setAttribute('aria-hidden', 'false'); + + // Set aria-hidden from false->true; should fire an event. + document.getElementById('d3').setAttribute('aria-hidden', 'true'); + + // Set aria-hidden from true->[removed]; should fire an event. + document.getElementById('d4').removeAttribute('aria-hidden'); + } + </script> +</body> +</html>
diff --git a/content/test/data/accessibility/event/css-visibility-expected-win.txt b/content/test/data/accessibility/event/css-visibility-expected-win.txt index d04c621..9a4e893 100644 --- a/content/test/data/accessibility/event/css-visibility-expected-win.txt +++ b/content/test/data/accessibility/event/css-visibility-expected-win.txt
@@ -1,4 +1,4 @@ -EVENT_OBJECT_HIDE on <div.a> role=DIV name="Heading" level=2 +EVENT_OBJECT_HIDE on <div.a> role=DIV name="Heading" INVISIBLE level=2 EVENT_OBJECT_REORDER on <div> role=ROLE_SYSTEM_TOOLBAR IA2_STATE_HORIZONTAL EVENT_OBJECT_SHOW on <div.b> role=ROLE_SYSTEM_GROUPING name="Banner" IA2_EVENT_TEXT_INSERTED on <div> role=ROLE_SYSTEM_TOOLBAR IA2_STATE_HORIZONTAL new_text={'<obj>' start=0 end=1}
diff --git a/content/test/data/accessibility/event/expanded-change-expected-uia-win.txt b/content/test/data/accessibility/event/expanded-change-expected-uia-win.txt deleted file mode 100644 index be21082..0000000 --- a/content/test/data/accessibility/event/expanded-change-expected-uia-win.txt +++ /dev/null
@@ -1,2 +0,0 @@ -AriaProperties changed on role=link, name=Toggle -ExpandCollapseExpandCollapseState changed on role=link, name=Toggle
diff --git a/content/test/data/accessibility/event/expanded-change.html b/content/test/data/accessibility/event/expanded-change.html deleted file mode 100644 index cf52871..0000000 --- a/content/test/data/accessibility/event/expanded-change.html +++ /dev/null
@@ -1,36 +0,0 @@ -<!-- - @UIA-WIN-DENY:* - @UIA-WIN-ALLOW:ExpandCollapse* - @UIA-WIN-ALLOW:AriaProperties* ---> -<!DOCTYPE html> -<html> -<body> -<a role="link" aria-expanded="false" id="title" href="#" onclick="go()">Toggle</a> -<ul id="list" style="visibility: hidden;"> - <li>ListItem 1</li> - <li>ListItem 2</li> - <li>ListItem 3</li> - <li>ListItem 4</li> -</ul> -<script> - function toggle(listNode, titleNode) { - var list = document.getElementById(listNode); - if (list.style.visibility != 'hidden') { - list.style.visibility = 'hidden'; - document.getElementById(titleNode).setAttribute('aria-expanded', 'false'); - } else { - list.style.visibility = 'visible'; - document.getElementById(titleNode).setAttribute('aria-expanded', 'true'); - } - } - function go() { - toggle('list', 'title'); - } - - window.onload = function() { - go(); - } -</script> -</body> -</html>
diff --git a/content/test/data/accessibility/event/expanded-change-expected-mac.txt b/content/test/data/accessibility/event/expanded-changed-expected-mac.txt similarity index 100% rename from content/test/data/accessibility/event/expanded-change-expected-mac.txt rename to content/test/data/accessibility/event/expanded-changed-expected-mac.txt
diff --git a/content/test/data/accessibility/event/expanded-changed-expected-uia-win.txt b/content/test/data/accessibility/event/expanded-changed-expected-uia-win.txt new file mode 100644 index 0000000..220897bf --- /dev/null +++ b/content/test/data/accessibility/event/expanded-changed-expected-uia-win.txt
@@ -0,0 +1,6 @@ +AriaProperties changed on role=link, name=Toggle +AriaProperties changed on role=list, name=list +AriaProperties changed on role=listitem, name=list item 1 +AriaProperties changed on role=listitem, name=list item 2 +AriaProperties changed on role=listitem, name=list item 3 +ExpandCollapseExpandCollapseState changed on role=link, name=Toggle
diff --git a/content/test/data/accessibility/event/expanded-changed.html b/content/test/data/accessibility/event/expanded-changed.html new file mode 100644 index 0000000..d39c742 --- /dev/null +++ b/content/test/data/accessibility/event/expanded-changed.html
@@ -0,0 +1,22 @@ +<!-- + @UIA-WIN-DENY:* + @UIA-WIN-ALLOW:ExpandCollapse* + @UIA-WIN-ALLOW:AriaProperties* +--> +<!DOCTYPE html> +<html> +<body> +<a role="link" aria-expanded="false" id="title" href="#">Toggle</a> +<ul id="list" aria-label="list" style="visibility: hidden;"> + <li aria-label="list item 1">ListItem 1</li> + <li aria-label="list item 2">ListItem 2</li> + <li aria-label="list item 3">ListItem 3</li> +</ul> +<script> + function go() { + document.getElementById('list').style.visibility = 'visible'; + document.getElementById('title').setAttribute('aria-expanded', 'true'); + } +</script> +</body> +</html>
diff --git a/content/test/data/accessibility/event/menu-opened-closed-expected-win.txt b/content/test/data/accessibility/event/menu-opened-closed-expected-win.txt index edd46247..32f673a 100644 --- a/content/test/data/accessibility/event/menu-opened-closed-expected-win.txt +++ b/content/test/data/accessibility/event/menu-opened-closed-expected-win.txt
@@ -2,6 +2,6 @@ === Start Continuation === EVENT_SYSTEM_MENUPOPUPSTART on <div#submenu> role=ROLE_SYSTEM_MENUPOPUP IA2_STATE_VERTICAL SetSize=1 === Start Continuation === -EVENT_SYSTEM_MENUPOPUPEND on <div#submenu> role=ROLE_SYSTEM_MENUPOPUP IA2_STATE_VERTICAL +EVENT_SYSTEM_MENUPOPUPEND on <div#submenu> role=ROLE_SYSTEM_MENUPOPUP IA2_STATE_VERTICAL SetSize=1 === Start Continuation === -EVENT_SYSTEM_MENUPOPUPEND on <div#menu> role=ROLE_SYSTEM_MENUPOPUP name="menu" IA2_STATE_VERTICAL +EVENT_SYSTEM_MENUPOPUPEND on <div#menu> role=ROLE_SYSTEM_MENUPOPUP name="menu" IA2_STATE_VERTICAL SetSize=2
diff --git a/content/test/data/accessibility/event/remove-child-expected-win.txt b/content/test/data/accessibility/event/remove-child-expected-win.txt index 2c3b971..4b87b52 100644 --- a/content/test/data/accessibility/event/remove-child-expected-win.txt +++ b/content/test/data/accessibility/event/remove-child-expected-win.txt
@@ -1,3 +1,3 @@ -EVENT_OBJECT_HIDE on <div#item3> role=ROLE_SYSTEM_LISTITEM name="Item 3" +EVENT_OBJECT_HIDE on <div#item3> role=ROLE_SYSTEM_LISTITEM name="Item 3" PosInSet=3 SetSize=3 EVENT_OBJECT_REORDER on <div> role=ROLE_SYSTEM_LIST SetSize=2 IA2_EVENT_TEXT_REMOVED on <div> role=ROLE_SYSTEM_LIST SetSize=2 old_text={'<obj>' start=2 end=3}
diff --git a/content/test/data/accessibility/event/visibility-hidden-changed-expected-uia-win.txt b/content/test/data/accessibility/event/visibility-hidden-changed-expected-uia-win.txt new file mode 100644 index 0000000..d5810d5 --- /dev/null +++ b/content/test/data/accessibility/event/visibility-hidden-changed-expected-uia-win.txt
@@ -0,0 +1,4 @@ +AriaProperties changed on role=heading, name=Item1 +AriaProperties changed on role=heading, name=Item2 +AriaProperties changed on role=heading, name=Item3 +AriaProperties changed on role=heading, name=Item4
diff --git a/content/test/data/accessibility/event/visibility-hidden-changed.html b/content/test/data/accessibility/event/visibility-hidden-changed.html new file mode 100644 index 0000000..5084bb5 --- /dev/null +++ b/content/test/data/accessibility/event/visibility-hidden-changed.html
@@ -0,0 +1,28 @@ +<!-- +@UIA-WIN-DENY:* +@UIA-WIN-ALLOW:AriaProperties* +--> +<!DOCTYPE html> +<html> +<body> + <h4 id="d1">Item1</h4> + <h4 id="d2" style="visibility: hidden">Item2</h4> + <h4 id="d3" style="visibility: visible">Item3</h4> + <h4 id="d4" style="visibility: hidden">Item4</h4> + <script> + function go() { + // Set style from [none]->visibility: hidden; should fire an event. + document.getElementById('d1').setAttribute('style', 'visibility: hidden'); + + // Set style from visibility: hidden->visibility: visible; should fire an event. + document.getElementById('d2').setAttribute('style', 'visibility: visible'); + + // Set style from visibility: visible->visibility: hidden; should fire an event. + document.getElementById('d3').setAttribute('style', 'visibility: hidden'); + + // Remove style visibility; should fire an event. + document.getElementById('d4').removeAttribute('style'); + } + </script> +</body> +</html>
diff --git a/content/test/gpu/gpu_tests/gpu_integration_test.py b/content/test/gpu/gpu_tests/gpu_integration_test.py index 59ceddc..167d2ba5 100644 --- a/content/test/gpu/gpu_tests/gpu_integration_test.py +++ b/content/test/gpu/gpu_tests/gpu_integration_test.py
@@ -21,8 +21,8 @@ _SUPPORTED_WIN_VERSIONS_WITH_DIRECT_COMPOSITION = ['win10'] _SUPPORTED_WIN_GPU_VENDORS = [0x8086, 0x10de, 0x1002] _SUPPORTED_WIN_INTEL_GPUS = [0x5912, 0x3e92] -_SUPPORTED_WIN_INTEL_GPUS_WITH_YUY2_OVERLAYS = [0x5912] -_SUPPORTED_WIN_INTEL_GPUS_WITH_NV12_OVERLAYS = [0x5912] +_SUPPORTED_WIN_INTEL_GPUS_WITH_YUY2_OVERLAYS = [0x5912, 0x3e92] +_SUPPORTED_WIN_INTEL_GPUS_WITH_NV12_OVERLAYS = [0x5912, 0x3e92] class GpuIntegrationTest( serially_executed_browser_test_case.SeriallyExecutedBrowserTestCase):
diff --git a/device/fido/bio/enrollment_handler.cc b/device/fido/bio/enrollment_handler.cc index c0180da..7872339 100644 --- a/device/fido/bio/enrollment_handler.cc +++ b/device/fido/bio/enrollment_handler.cc
@@ -74,7 +74,7 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); authenticator_->BioEnrollRename( *pin_token_response_, std::move(template_id), std::move(name), - base::BindOnce(&BioEnrollmentHandler::OnRenameTemplate, + base::BindOnce(&BioEnrollmentHandler::OnStatusCallback, weak_factory_.GetWeakPtr(), std::move(callback))); } @@ -83,7 +83,7 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); authenticator_->BioEnrollDelete( *pin_token_response_, std::move(template_id), - base::BindOnce(&BioEnrollmentHandler::OnDeleteTemplate, + base::BindOnce(&BioEnrollmentHandler::OnStatusCallback, weak_factory_.GetWeakPtr(), std::move(callback))); } @@ -104,7 +104,6 @@ } authenticator_ = nullptr; - std::move(error_callback_) .Run(pin_token_response_ ? FidoReturnCode::kAuthenticatorRemovedDuringPINEntry @@ -144,7 +143,8 @@ base::Optional<pin::RetriesResponse> response) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!response || code != CtapDeviceResponseCode::kSuccess) { - FIDO_LOG(DEBUG) << "OnRetriesResponse failed: " << static_cast<int>(code); + FIDO_LOG(DEBUG) << "OnRetriesResponse failed with response code " + << static_cast<int>(code); std::move(error_callback_) .Run(FidoReturnCode::kAuthenticatorResponseInvalid); return; @@ -172,7 +172,8 @@ CtapDeviceResponseCode code, base::Optional<pin::KeyAgreementResponse> response) { if (code != CtapDeviceResponseCode::kSuccess) { - FIDO_LOG(DEBUG) << "OnHaveEphemeralKey failed: " << static_cast<int>(code); + FIDO_LOG(DEBUG) << "OnHaveEphemeralKey failed with response code " + << static_cast<int>(code); std::move(error_callback_) .Run(FidoReturnCode::kAuthenticatorResponseInvalid); return; @@ -187,13 +188,12 @@ void BioEnrollmentHandler::OnHavePINToken( CtapDeviceResponseCode code, base::Optional<pin::TokenResponse> response) { - if (code == CtapDeviceResponseCode::kCtap2ErrPinInvalid) { - authenticator_->GetRetries(base::BindOnce( - &BioEnrollmentHandler::OnRetriesResponse, weak_factory_.GetWeakPtr())); - return; - } - switch (code) { + case CtapDeviceResponseCode::kCtap2ErrPinInvalid: + authenticator_->GetRetries( + base::BindOnce(&BioEnrollmentHandler::OnRetriesResponse, + weak_factory_.GetWeakPtr())); + return; case CtapDeviceResponseCode::kCtap2ErrPinAuthBlocked: std::move(error_callback_).Run(FidoReturnCode::kSoftPINBlock); return; @@ -209,7 +209,7 @@ break; } - pin_token_response_ = *response; + pin_token_response_ = std::move(response); std::move(ready_callback_).Run(); } @@ -223,7 +223,7 @@ std::move(callback).Run(CtapDeviceResponseCode::kCtap2ErrOther); return; } - FIDO_LOG(DEBUG) << "Finished bio enrollment with code " + FIDO_LOG(DEBUG) << "Finished bio enrollment with response code " << static_cast<int>(code); std::move(callback).Run(code); } @@ -253,14 +253,7 @@ std::move(callback).Run(code, std::move(*response->template_infos)); } -void BioEnrollmentHandler::OnRenameTemplate( - StatusCallback callback, - CtapDeviceResponseCode code, - base::Optional<BioEnrollmentResponse> response) { - std::move(callback).Run(code); -} - -void BioEnrollmentHandler::OnDeleteTemplate( +void BioEnrollmentHandler::OnStatusCallback( StatusCallback callback, CtapDeviceResponseCode code, base::Optional<BioEnrollmentResponse> response) {
diff --git a/device/fido/bio/enrollment_handler.h b/device/fido/bio/enrollment_handler.h index 4a0680d..1964f66 100644 --- a/device/fido/bio/enrollment_handler.h +++ b/device/fido/bio/enrollment_handler.h
@@ -42,8 +42,7 @@ base::OnceClosure ready_callback, ErrorCallback error_callback, GetPINCallback get_pin_callback, - FidoDiscoveryFactory* factory = - std::make_unique<FidoDiscoveryFactory>().get()); + FidoDiscoveryFactory* factory); ~BioEnrollmentHandler() override; // Returns the modality of the authenticator's user verification. @@ -103,10 +102,7 @@ void OnEnumerateTemplates(EnumerationCallback, CtapDeviceResponseCode, base::Optional<BioEnrollmentResponse>); - void OnRenameTemplate(StatusCallback, - CtapDeviceResponseCode, - base::Optional<BioEnrollmentResponse>); - void OnDeleteTemplate(StatusCallback, + void OnStatusCallback(StatusCallback, CtapDeviceResponseCode, base::Optional<BioEnrollmentResponse>);
diff --git a/device/vr/BUILD.gn b/device/vr/BUILD.gn index 34c3dff..d5afc67a 100644 --- a/device/vr/BUILD.gn +++ b/device/vr/BUILD.gn
@@ -28,6 +28,8 @@ "util/sample_queue.h", "util/sliding_average.cc", "util/sliding_average.h", + "util/xr_standard_gamepad_builder.cc", + "util/xr_standard_gamepad_builder.h", "vr_device.h", "vr_device_base.cc", "vr_device_base.h",
diff --git a/device/vr/OWNERS b/device/vr/OWNERS index c31ef2534..ba95d89 100644 --- a/device/vr/OWNERS +++ b/device/vr/OWNERS
@@ -1,6 +1,7 @@ alcooper@chromium.org bajones@chromium.org bialpio@chromium.org +jacde@chromium.org per-file *.mojom=set noparent per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/device/vr/oculus/oculus_gamepad_helper.cc b/device/vr/oculus/oculus_gamepad_helper.cc index 5a93ddf9..ccac8116 100644 --- a/device/vr/oculus/oculus_gamepad_helper.cc +++ b/device/vr/oculus/oculus_gamepad_helper.cc
@@ -9,7 +9,7 @@ #include "base/logging.h" #include "device/gamepad/public/cpp/gamepads.h" -#include "device/vr/util/gamepad_builder.h" +#include "device/vr/util/xr_standard_gamepad_builder.h" #include "device/vr/vr_device.h" #include "third_party/libovr/src/Include/OVR_CAPI.h" #include "ui/gfx/transform.h" @@ -196,50 +196,83 @@ } } -class OculusGamepadBuilder : public GamepadBuilder { +class OculusGamepadBuilder : public XRStandardGamepadBuilder { public: - // TODO(https://crbug.com/942201): Get correct ID string once WebXR spec issue - // #550 (https://github.com/immersive-web/webxr/issues/550) is resolved. OculusGamepadBuilder(ovrInputState state, ovrHandType hand) - : GamepadBuilder("oculus-touch", - GamepadMapping::kXrStandard, - OculusToMojomHand(hand)), - state_(state) {} + : XRStandardGamepadBuilder(OculusToMojomHand(hand)), + state_(state), + ovr_hand_(hand) { + switch (ovr_hand_) { + case ovrHand_Left: + SetPrimaryButton(GetTouchTriggerButton(ovrTouch_LIndexTrigger, + state_.IndexTrigger[ovr_hand_])); + SetSecondaryButton(GetTriggerButton(state_.HandTrigger[ovr_hand_])); + SetThumbstickData(GetThumbstickData(ovrButton_LThumb)); + AddOptionalButtonData(GetStandardButton(ovrButton_X)); + AddOptionalButtonData(GetStandardButton(ovrButton_Y)); + AddOptionalButtonData(GetTouchButton(ovrTouch_LThumbRest)); + break; + case ovrHand_Right: + SetPrimaryButton(GetTouchTriggerButton(ovrTouch_RIndexTrigger, + state_.IndexTrigger[ovr_hand_])); + SetSecondaryButton(GetTriggerButton(state_.HandTrigger[ovr_hand_])); + SetThumbstickData(GetThumbstickData(ovrButton_RThumb)); + AddOptionalButtonData(GetStandardButton(ovrButton_A)); + AddOptionalButtonData(GetStandardButton(ovrButton_B)); + AddOptionalButtonData(GetTouchButton(ovrTouch_RThumbRest)); + break; + default: + DLOG(WARNING) << "Unsupported hand configuration."; + } + } ~OculusGamepadBuilder() override = default; - void AddStandardButton(ovrButton id) { + private: + GamepadButton GetStandardButton(ovrButton id) { bool pressed = (state_.Buttons & id) != 0; bool touched = (state_.Touches & id) != 0; double value = pressed ? 1.0 : 0.0; - AddButton(GamepadButton(pressed, touched, value)); + return GamepadButton(pressed, touched, value); } - void AddTouchButton(ovrTouch id) { + GamepadButton GetTouchButton(ovrTouch id) { bool touched = (state_.Touches & id) != 0; - AddButton(GamepadButton(false, touched, 0.0f)); + return GamepadButton(false, touched, 0.0f); } - void AddTriggerButton(float value) { + GamepadButton GetTriggerButton(float value) { value = ApplyTriggerDeadzone(value); bool pressed = value != 0; bool touched = pressed; - AddButton(GamepadButton(pressed, touched, value)); + return GamepadButton(pressed, touched, value); } - void AddTouchTriggerButton(ovrTouch id, float value) { + GamepadButton GetTouchTriggerButton(ovrTouch id, float value) { value = ApplyTriggerDeadzone(value); bool pressed = value != 0; bool touched = (state_.Touches & id) != 0; - AddButton(GamepadButton(pressed, touched, value)); + return GamepadButton(pressed, touched, value); } - bool IsValid() const override { - return GamepadBuilder::IsValid() && GetHandedness() != GamepadHand::kNone; + GamepadBuilder::ButtonData GetThumbstickData(ovrButton id) { + GamepadButton button = GetStandardButton(id); + GamepadBuilder::ButtonData data; + data.touched = button.touched; + data.pressed = button.pressed; + data.value = button.value; + + // Invert the y axis because -1 is up in the Gamepad API but down in Oculus. + data.type = GamepadBuilder::ButtonData::Type::kThumbstick; + data.x_axis = state_.Thumbstick[ovr_hand_].x; + data.y_axis = -state_.Thumbstick[ovr_hand_].y; + + return data; } private: ovrInputState state_; + ovrHandType ovr_hand_; DISALLOW_COPY_AND_ASSIGN(OculusGamepadBuilder); }; @@ -274,12 +307,18 @@ // Order of buttons 1-4 is dictated by the xr-standard Gamepad mapping. // Buttons 5-7 are in order of decreasing importance. // 1) index trigger (primary trigger/button) -// 2) thumb joystick button -// 3) hand trigger (primary trigger/button) -// 4) EMPTY (no secondary joystick/touchpad exists) +// 2) hand trigger (secondary trigger/button) +// 3) EMPTY (no touchpad press) +// 4) thumbstick press // 5) A or X // 6) B or Y // 7) thumbrest touch sensor +// +// Order of axes 1-4 is dictated by the xr-standard Gamepad mapping. +// 1) EMPTY (no touchpad) +// 2) EMPTY (no touchpad) +// 3) thumbstick X +// 4) thumbstick Y base::Optional<Gamepad> OculusGamepadHelper::CreateGamepad(ovrSession session, ovrHandType hand) { ovrInputState input_touch; @@ -290,37 +329,6 @@ } OculusGamepadBuilder touch(input_touch, hand); - - // Invert the y axis because -1 is up in the Gamepad API, but down in Oculus. - touch.AddAxis(input_touch.Thumbstick[hand].x); - touch.AddAxis(-input_touch.Thumbstick[hand].y); - - switch (hand) { - case ovrHand_Left: - touch.AddTouchTriggerButton(ovrTouch_LIndexTrigger, - input_touch.IndexTrigger[hand]); - touch.AddStandardButton(ovrButton_LThumb); - touch.AddTriggerButton(input_touch.HandTrigger[hand]); - touch.AddPlaceholderButton(); - touch.AddStandardButton(ovrButton_X); - touch.AddStandardButton(ovrButton_Y); - touch.AddTouchButton(ovrTouch_LThumbRest); - break; - case ovrHand_Right: - touch.AddTouchTriggerButton(ovrTouch_RIndexTrigger, - input_touch.IndexTrigger[hand]); - touch.AddStandardButton(ovrButton_RThumb); - touch.AddTriggerButton(input_touch.HandTrigger[hand]); - touch.AddPlaceholderButton(); - touch.AddStandardButton(ovrButton_A); - touch.AddStandardButton(ovrButton_B); - touch.AddTouchButton(ovrTouch_RThumbRest); - break; - default: - DLOG(WARNING) << "Unsupported hand configuration."; - return base::nullopt; - } - return touch.GetGamepad(); }
diff --git a/device/vr/openvr/openvr_gamepad_helper.cc b/device/vr/openvr/openvr_gamepad_helper.cc index 1f73992..1f9f460 100644 --- a/device/vr/openvr/openvr_gamepad_helper.cc +++ b/device/vr/openvr/openvr_gamepad_helper.cc
@@ -13,6 +13,7 @@ #include "base/strings/utf_string_conversions.h" #include "device/gamepad/public/cpp/gamepads.h" #include "device/vr/util/gamepad_builder.h" +#include "device/vr/util/xr_standard_gamepad_builder.h" #include "device/vr/vr_device.h" #include "third_party/openvr/src/headers/openvr.h" #include "ui/gfx/transform.h" @@ -64,16 +65,21 @@ double x_axis = controller_state.rAxis[j].x; double y_axis = -controller_state.rAxis[j].y; + if (axis_type == vr::k_eControllerAxis_Joystick) { + button_data.type = GamepadBuilder::ButtonData::Type::kThumbstick; + + // We only want to apply the deadzone to joysticks, since various + // runtimes may not have already done that, but touchpads should + // be fine. + x_axis = std::fabs(x_axis) < kJoystickDeadzone ? 0 : x_axis; + y_axis = std::fabs(y_axis) < kJoystickDeadzone ? 0 : y_axis; + } else if (axis_type == vr::k_eControllerAxis_TrackPad) { + button_data.type = GamepadBuilder::ButtonData::Type::kTouchpad; + } + switch (axis_type) { case vr::k_eControllerAxis_Joystick: - // We only want to apply the deadzone to joysticks, since various - // runtimes may not have already done that, but touchpads should - // be fine. - x_axis = std::fabs(x_axis) < kJoystickDeadzone ? 0 : x_axis; - y_axis = std::fabs(y_axis) < kJoystickDeadzone ? 0 : y_axis; - FALLTHROUGH; case vr::k_eControllerAxis_TrackPad: { - button_data.has_both_axes = true; button_data.x_axis = x_axis; button_data.y_axis = y_axis; vr::EVRButtonId button_id = GetAxisId(j); @@ -202,7 +208,7 @@ GamepadBuilder::ButtonData data = button_data_pair.second; gamepad->buttons.push_back(GetMojomGamepadButton(data)); - if (data.has_both_axes) { + if (data.type != GamepadBuilder::ButtonData::Type::kButton) { gamepad->axes.push_back(data.x_axis); gamepad->axes.push_back(data.y_axis); } @@ -247,7 +253,7 @@ } // Helper classes and WebXR Getters -class OpenVRGamepadBuilder : public GamepadBuilder { +class OpenVRGamepadBuilder : public XRStandardGamepadBuilder { public: enum class AxesRequirement { kOptional = 0, @@ -258,74 +264,112 @@ uint32_t controller_id, vr::VRControllerState_t controller_state, device::mojom::XRHandedness handedness) - : GamepadBuilder(GetGamepadId(vr_system, controller_id), - GamepadMapping::kXrStandard, - handedness), + : XRStandardGamepadBuilder(handedness), controller_state_(controller_state) { supported_buttons_ = vr_system->GetUint64TrackedDeviceProperty( controller_id, vr::Prop_SupportedButtons_Uint64); axes_data_ = GetAxesButtons(vr_system, controller_state_, supported_buttons_, controller_id); + + base::Optional<GamepadBuilder::ButtonData> primary_button = + TryGetAxesOrTriggerButton(vr::k_EButton_SteamVR_Trigger); + + if (!primary_button) { + return; + } + + SetPrimaryButton(primary_button.value()); + + base::Optional<GamepadButton> secondary_button = + TryGetButton(vr::k_EButton_Grip); + if (secondary_button) { + SetSecondaryButton(secondary_button.value()); + } + + base::Optional<GamepadBuilder::ButtonData> touchpad_data = + TryGetNextUnusedButtonOfType( + GamepadBuilder::ButtonData::Type::kTouchpad); + if (touchpad_data) { + SetTouchpadData(touchpad_data.value()); + } + + base::Optional<GamepadBuilder::ButtonData> thumbstick_data = + TryGetNextUnusedButtonOfType( + GamepadBuilder::ButtonData::Type::kThumbstick); + if (thumbstick_data) { + SetThumbstickData(thumbstick_data.value()); + } + + // Now that all of the xr-standard reserved buttons have been filled in, we + // add the rest of the buttons in order of decreasing importance. + // First add regular buttons. + for (const auto& id : kWebXRButtonOrder) { + base::Optional<GamepadButton> button = TryGetButton(id); + if (button) { + AddOptionalButtonData(button.value()); + } + } + + // Finally, add any remaining axis buttons (triggers/josysticks/touchpads) + AddRemainingTriggersAndAxes(); } ~OpenVRGamepadBuilder() override = default; - bool TryAddAxesOrTriggerButton( + private: + base::Optional<GamepadBuilder::ButtonData> TryGetAxesOrTriggerButton( vr::EVRButtonId button_id, AxesRequirement requirement = AxesRequirement::kOptional) { if (!IsInAxesData(button_id)) - return false; + return base::nullopt; bool require_axes = (requirement == AxesRequirement::kRequireBoth); - if (require_axes && !axes_data_[button_id].has_both_axes) - return false; + if (require_axes && + axes_data_[button_id].type == GamepadBuilder::ButtonData::Type::kButton) + return base::nullopt; - AddButton(axes_data_[button_id]); used_axes_.insert(button_id); - - return true; + return axes_data_[button_id]; } - bool TryAddNextUnusedButtonWithAxes() { + base::Optional<GamepadBuilder::ButtonData> TryGetNextUnusedButtonOfType( + GamepadBuilder::ButtonData::Type type) { for (const auto& axes_data_pair : axes_data_) { vr::EVRButtonId button_id = axes_data_pair.first; if (IsUsed(button_id)) continue; - if (TryAddAxesOrTriggerButton(button_id, AxesRequirement::kRequireBoth)) - return true; + if (axes_data_pair.second.type != type) + continue; + + return TryGetAxesOrTriggerButton(button_id, + AxesRequirement::kRequireBoth); } - return false; + return base::nullopt; } - bool TryAddButton(vr::EVRButtonId button_id) { + base::Optional<GamepadButton> TryGetButton(vr::EVRButtonId button_id) { GamepadButton button; if (TryGetGamepadButton(controller_state_, supported_buttons_, button_id, &button)) { - AddButton(button); - return true; + return button; } - return false; + return base::nullopt; } // This will add any remaining unused values from axes_data to the gamepad. // Returns a bool indicating whether any additional axes were added. - bool AddRemainingTriggersAndAxes() { - bool added_axes = false; + void AddRemainingTriggersAndAxes() { for (const auto& axes_data_pair : axes_data_) { if (!IsUsed(axes_data_pair.first)) { - added_axes = true; - AddButton(axes_data_pair.second); + AddOptionalButtonData(axes_data_pair.second); } } - - return added_axes; } - private: static bool IsControllerHTCVive(vr::IVRSystem* vr_system, uint32_t controller_id) { std::string model = @@ -364,7 +408,7 @@ const vr::VRControllerState_t controller_state_; uint64_t supported_buttons_; - std::map<vr::EVRButtonId, ButtonData> axes_data_; + std::map<vr::EVRButtonId, GamepadBuilder::ButtonData> axes_data_; std::unordered_set<vr::EVRButtonId> used_axes_; DISALLOW_COPY_AND_ASSIGN(OpenVRGamepadBuilder); @@ -377,59 +421,6 @@ device::mojom::XRHandedness handedness) { OpenVRGamepadBuilder builder(vr_system, controller_id, controller_state, handedness); - - if (!builder.TryAddAxesOrTriggerButton(vr::k_EButton_SteamVR_Trigger)) - return base::nullopt; - - if (!builder.TryAddNextUnusedButtonWithAxes()) - return base::nullopt; - - bool added_placeholder_grip = false; - if (!builder.TryAddButton(vr::k_EButton_Grip)) { - added_placeholder_grip = true; - builder.AddPlaceholderButton(); - } - - // If we can't find any secondary button with an x and y axis, add a fake - // button. Note that we're not worried about ensuring that the axes data gets - // added, because if there were any other axes to add, we would've added them. - bool added_placeholder_axes = false; - if (!builder.TryAddNextUnusedButtonWithAxes()) { - added_placeholder_axes = true; - builder.AddPlaceholderButton(); - } - - // Now that all of the xr-standard reserved buttons have been filled in, we - // add the rest of the buttons in order of decreasing importance. - // First add regular buttons - bool added_optional_buttons = false; - for (const auto& button : kWebXRButtonOrder) { - added_optional_buttons = - builder.TryAddButton(button) || added_optional_buttons; - } - - // Finally, add any remaining axis buttons (triggers/josysticks/touchpads) - bool added_optional_axes = builder.AddRemainingTriggersAndAxes(); - - // If we didn't add any optional buttons, we need to remove our placeholder - // buttons. - if (!(added_optional_buttons || added_optional_axes)) { - // If we didn't add any optional buttons, see if we need to remove the most - // recent placeholder (the secondary axes). - // Note that if we added a placeholder axes, the only optional axes that - // should have been added are triggers, and so we don't need to worry about - // the order - if (added_placeholder_axes) { - builder.RemovePlaceholderButton(); - - // Only if the axes button was a placeholder can we remove the grip - // if it was also a placeholder. - if (added_placeholder_grip) { - builder.RemovePlaceholderButton(); - } - } - } - return builder.GetGamepad(); }
diff --git a/device/vr/openvr/test/test_helper.cc b/device/vr/openvr/test/test_helper.cc index 365bc15..83cc4a45 100644 --- a/device/vr/openvr/test/test_helper.cc +++ b/device/vr/openvr/test/test_helper.cc
@@ -136,10 +136,10 @@ {device::XrButtonId::kA, vr::EVRButtonId::k_EButton_A}, {device::XrButtonId::kProximitySensor, vr::EVRButtonId::k_EButton_ProximitySensor}, - {device::XrButtonId::kAxisPrimary, vr::EVRButtonId::k_EButton_Axis0}, + {device::XrButtonId::kAxisTrackpad, vr::EVRButtonId::k_EButton_Axis0}, {device::XrButtonId::kAxisTrigger, vr::EVRButtonId::k_EButton_SteamVR_Trigger}, - {device::XrButtonId::kAxisSecondary, vr::EVRButtonId::k_EButton_Axis2}, + {device::XrButtonId::kAxisThumbstick, vr::EVRButtonId::k_EButton_Axis2}, {device::XrButtonId::kAxisTertiary, vr::EVRButtonId::k_EButton_Axis3}, {device::XrButtonId::kAxisQuaternary, vr::EVRButtonId::k_EButton_Axis4}, };
diff --git a/device/vr/test/test_hook.h b/device/vr/test/test_hook.h index e98bdb61..a5c6513 100644 --- a/device/vr/test/test_hook.h +++ b/device/vr/test/test_hook.h
@@ -29,9 +29,9 @@ kDpadDown = 6, kA = 7, kProximitySensor = 31, - kAxisPrimary = 32, + kAxisTrackpad = 32, kAxisTrigger = 33, - kAxisSecondary = 34, + kAxisThumbstick = 34, kAxisTertiary = 35, kAxisQuaternary = 36, kMax = 64 @@ -49,10 +49,10 @@ } inline unsigned int XrAxisOffsetFromId(XrButtonId id) { - DCHECK(XrButtonId::kAxisPrimary <= id && - id < XrButtonId::kAxisPrimary + kMaxNumAxes); + DCHECK(XrButtonId::kAxisTrackpad <= id && + id < XrButtonId::kAxisTrackpad + kMaxNumAxes); return static_cast<unsigned int>(id) - - static_cast<unsigned int>(XrButtonId::kAxisPrimary); + static_cast<unsigned int>(XrButtonId::kAxisTrackpad); } struct Color {
diff --git a/device/vr/util/gamepad_builder.cc b/device/vr/util/gamepad_builder.cc index 0289cf3..214b53fe 100644 --- a/device/vr/util/gamepad_builder.cc +++ b/device/vr/util/gamepad_builder.cc
@@ -43,9 +43,8 @@ bool GamepadBuilder::IsValid() const { switch (GetMapping()) { case GamepadMapping::kXrStandard: - // In order to satisfy the XRStandard mapping at least two buttons and one - // set of axes need to have been added. - return gamepad_.axes_length >= 2 && gamepad_.buttons_length >= 2; + // Just a single primary button is sufficient for the xr-standard mapping. + return gamepad_.buttons_length > 0; case GamepadMapping::kStandard: case GamepadMapping::kNone: // Neither standard requires any buttons to be set, and all other data @@ -56,7 +55,7 @@ NOTREACHED(); } -base::Optional<Gamepad> GamepadBuilder::GetGamepad() const { +base::Optional<Gamepad> GamepadBuilder::GetGamepad() { if (IsValid()) return gamepad_; @@ -75,7 +74,7 @@ void GamepadBuilder::AddButton(const ButtonData& data) { AddButton(GamepadButton(data.pressed, data.touched, data.value)); - if (data.has_both_axes) + if (data.type != ButtonData::Type::kButton) AddAxes(data); } @@ -85,7 +84,14 @@ } void GamepadBuilder::AddAxes(const ButtonData& data) { - DCHECK(data.has_both_axes); + DCHECK_NE(data.type, ButtonData::Type::kButton); + + if (data.type == ButtonData::Type::kTouchpad && !data.touched) { + // Untouched touchpads must have axes set to 0. + AddPlaceholderAxes(); + return; + } + AddAxis(data.x_axis); AddAxis(data.y_axis); } @@ -106,6 +112,11 @@ gamepad_.buttons_length--; } +void GamepadBuilder::AddPlaceholderAxes() { + AddAxis(0.0); + AddAxis(0.0); +} + double GamepadBuilder::ApplyAxisDeadzoneToValue(double value) const { return std::fabs(value) < axis_deadzone_ ? 0 : value; }
diff --git a/device/vr/util/gamepad_builder.h b/device/vr/util/gamepad_builder.h index 09ac202..24eac5a 100644 --- a/device/vr/util/gamepad_builder.h +++ b/device/vr/util/gamepad_builder.h
@@ -17,11 +17,13 @@ // Helper struct that we don't want to pollute the device namespace struct ButtonData { + enum class Type { kButton, kThumbstick, kTouchpad }; + bool touched = false; bool pressed = false; double value = 0.0; - bool has_both_axes = false; + Type type = Type::kButton; double x_axis = 0.0; double y_axis = 0.0; }; @@ -32,12 +34,13 @@ virtual ~GamepadBuilder(); virtual bool IsValid() const; - base::Optional<Gamepad> GetGamepad() const; + virtual base::Optional<Gamepad> GetGamepad(); void SetAxisDeadzone(double value); void AddButton(const GamepadButton& button); void AddButton(const ButtonData& data); void AddAxis(double value); + void AddPlaceholderAxes(); void AddPlaceholderButton(); void RemovePlaceholderButton(); @@ -48,12 +51,14 @@ GamepadHand GetHandedness() const { return gamepad_.hand; } GamepadMapping GetMapping() const { return gamepad_.mapping; } + Gamepad gamepad_; + private: double axis_deadzone_ = 0.0; - Gamepad gamepad_; DISALLOW_COPY_AND_ASSIGN(GamepadBuilder); }; } // namespace device + #endif // DEVICE_VR_UTIL_GAMEPAD_BUILDER_H_
diff --git a/device/vr/util/xr_standard_gamepad_builder.cc b/device/vr/util/xr_standard_gamepad_builder.cc new file mode 100644 index 0000000..66d25228 --- /dev/null +++ b/device/vr/util/xr_standard_gamepad_builder.cc
@@ -0,0 +1,75 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +#include "device/vr/util/xr_standard_gamepad_builder.h" + +namespace device { + +XRStandardGamepadBuilder::XRStandardGamepadBuilder( + device::mojom::XRHandedness handedness, + double axis_deadzone) + : handedness_(handedness), axis_deadzone_(axis_deadzone) {} + +XRStandardGamepadBuilder::~XRStandardGamepadBuilder() = default; + +void XRStandardGamepadBuilder::AddOptionalButtonData( + const GamepadBuilder::ButtonData& data) { + optional_button_data_.push_back(data); + if (data.type != GamepadBuilder::ButtonData::Type::kButton) { + has_optional_axes_ = true; + } +} + +void XRStandardGamepadBuilder::AddOptionalButtonData( + const GamepadButton& button) { + GamepadBuilder::ButtonData data; + data.touched = button.touched; + data.pressed = button.pressed; + data.value = button.value; + AddOptionalButtonData(data); +} + +base::Optional<Gamepad> XRStandardGamepadBuilder::GetGamepad() const { + if (!primary_button_) { + return base::nullopt; + } + + GamepadBuilder builder("", GamepadMapping::kXrStandard, handedness_); + builder.SetAxisDeadzone(axis_deadzone_); + builder.AddButton(primary_button_.value()); + + const bool has_optional_buttons = !optional_button_data_.empty(); + if (secondary_button_) { + builder.AddButton(secondary_button_.value()); + } else if (touchpad_data_ || thumbstick_data_ || has_optional_buttons) { + builder.AddPlaceholderButton(); + } + + if (touchpad_data_) { + builder.AddButton(touchpad_data_.value()); + } else if (thumbstick_data_ || has_optional_axes_) { + builder.AddPlaceholderButton(); + builder.AddPlaceholderAxes(); + } else if (has_optional_buttons) { + // Only add a placeholder button because there are no more axes. + builder.AddPlaceholderButton(); + } + + if (thumbstick_data_) { + builder.AddButton(thumbstick_data_.value()); + } else if (has_optional_axes_) { + builder.AddPlaceholderButton(); + builder.AddPlaceholderAxes(); + } else if (has_optional_buttons) { + // Only add a placeholder button because there are no more axes. + builder.AddPlaceholderButton(); + } + + for (const auto& data : optional_button_data_) { + builder.AddButton(data); + } + + return builder.GetGamepad(); +} + +} // namespace device
diff --git a/device/vr/util/xr_standard_gamepad_builder.h b/device/vr/util/xr_standard_gamepad_builder.h new file mode 100644 index 0000000..aeb33e9 --- /dev/null +++ b/device/vr/util/xr_standard_gamepad_builder.h
@@ -0,0 +1,64 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +#ifndef DEVICE_VR_UTIL_XR_STANDARD_GAMEPAD_BUILDER_H_ +#define DEVICE_VR_UTIL_XR_STANDARD_GAMEPAD_BUILDER_H_ + +#include "base/macros.h" +#include "device/vr/public/mojom/isolated_xr_service.mojom.h" +#include "device/vr/util/gamepad_builder.h" + +namespace device { + +// Centralizes the logic of properly ordering the buttons and input axes for +// xr-standard Gamepads so that the various platforms don't have to worry about +// it themselves. +class XRStandardGamepadBuilder { + public: + XRStandardGamepadBuilder(device::mojom::XRHandedness handedness, + double axis_deadzone = 0.0); + virtual ~XRStandardGamepadBuilder(); + void SetPrimaryButton(const GamepadButton& button) { + primary_button_ = button; + } + void SetPrimaryButton(const GamepadBuilder::ButtonData& data) { + SetPrimaryButton(GamepadButton(data.pressed, data.touched, data.value)); + } + void SetSecondaryButton(const GamepadButton& button) { + secondary_button_ = button; + } + void SetSecondaryButton(const GamepadBuilder::ButtonData& data) { + SetSecondaryButton(GamepadButton(data.pressed, data.touched, data.value)); + } + void SetTouchpadData(const GamepadBuilder::ButtonData& data) { + touchpad_data_ = data; + } + void SetThumbstickData(const GamepadBuilder::ButtonData& data) { + thumbstick_data_ = data; + } + void AddOptionalButtonData(const GamepadBuilder::ButtonData& data); + void AddOptionalButtonData(const GamepadButton& button); + + base::Optional<Gamepad> GetGamepad() const; + + private: + base::Optional<GamepadButton> primary_button_; + base::Optional<GamepadButton> secondary_button_; + + base::Optional<GamepadBuilder::ButtonData> touchpad_data_; + base::Optional<GamepadBuilder::ButtonData> thumbstick_data_; + + std::vector<GamepadBuilder::ButtonData> optional_button_data_; + + // Has one or more optional buttons that also have associated axes. + bool has_optional_axes_ = false; + + device::mojom::XRHandedness handedness_; + double axis_deadzone_; + + DISALLOW_COPY_AND_ASSIGN(XRStandardGamepadBuilder); +}; + +} // namespace device + +#endif // DEVICE_VR_UTIL_XR_STANDARD_GAMEPAD_BUILDER_H_
diff --git a/device/vr/windows_mixed_reality/mixed_reality_input_helper.cc b/device/vr/windows_mixed_reality/mixed_reality_input_helper.cc index 43a9400..5866834e 100644 --- a/device/vr/windows_mixed_reality/mixed_reality_input_helper.cc +++ b/device/vr/windows_mixed_reality/mixed_reality_input_helper.cc
@@ -18,6 +18,7 @@ #include "device/gamepad/public/cpp/gamepads.h" #include "device/vr/public/mojom/isolated_xr_service.mojom.h" #include "device/vr/util/gamepad_builder.h" +#include "device/vr/util/xr_standard_gamepad_builder.h" #include "device/vr/windows_mixed_reality/mixed_reality_renderloop.h" #include "device/vr/windows_mixed_reality/wrappers/wmr_input_location.h" #include "device/vr/windows_mixed_reality/wrappers/wmr_input_manager.h" @@ -235,21 +236,17 @@ if (input_state.source_state && input_state.source_state->description) handedness = input_state.source_state->description->handedness; - // TODO(https://crbug.com/942201): Get correct ID string once WebXR spec issue - // #550 (https://github.com/immersive-web/webxr/issues/550) is resolved. - GamepadBuilder builder("windows-mixed-reality", GamepadMapping::kXrStandard, - handedness); + XRStandardGamepadBuilder builder(handedness, kDeadzoneMinimum); + builder.SetPrimaryButton(input_state.button_data[ButtonName::kSelect]); + builder.SetSecondaryButton(input_state.button_data[ButtonName::kGrip]); - builder.SetAxisDeadzone(kDeadzoneMinimum); + // button_data will either have both kTouchpad and kThumbstick, or neither. + if (input_state.button_data.find(ButtonName::kTouchpad) != + input_state.button_data.end()) { + builder.SetTouchpadData(input_state.button_data[ButtonName::kTouchpad]); + builder.SetThumbstickData(input_state.button_data[ButtonName::kThumbstick]); + } - // The order of these buttons is dictated by the xr-standard Gamepad mapping. - // Thumbstick is considered the primary 2D input axis, while the touchpad is - // the secondary 2D input axis. If any of these are missing, map will give - // us a default version, which is fine. - builder.AddButton(input_state.button_data[ButtonName::kSelect]); - builder.AddButton(input_state.button_data[ButtonName::kThumbstick]); - builder.AddButton(input_state.button_data[ButtonName::kGrip]); - builder.AddButton(input_state.button_data[ButtonName::kTouchpad]); return builder.GetGamepad(); } @@ -264,7 +261,7 @@ data.pressed = source_state->IsSelectPressed(); data.touched = data.pressed; data.value = source_state->SelectPressedValue(); - data.has_both_axes = false; + data.type = GamepadBuilder::ButtonData::Type::kButton; button_map[ButtonName::kSelect] = data; // Add the grip button @@ -272,7 +269,7 @@ data.pressed = source_state->IsGrasped(); data.touched = data.pressed; data.value = data.pressed ? 1.0 : 0.0; - data.has_both_axes = false; + data.type = GamepadBuilder::ButtonData::Type::kButton; button_map[ButtonName::kGrip] = data; // Select and grip are the only two required buttons, if we can't get the @@ -287,7 +284,7 @@ data.value = data.pressed ? 1.0 : 0.0; // Invert the y axis because -1 is up in the Gamepad API, but down in WMR. - data.has_both_axes = true; + data.type = GamepadBuilder::ButtonData::Type::kThumbstick; data.x_axis = source_state->ThumbstickX(); data.y_axis = -source_state->ThumbstickY(); @@ -300,7 +297,7 @@ data.value = data.pressed ? 1.0 : 0.0; // The Touchpad does have Axes, but if it's not touched, they are 0. - data.has_both_axes = true; + data.type = GamepadBuilder::ButtonData::Type::kTouchpad; if (data.touched) { // Invert the y axis because -1 is up in the Gamepad API, but down in WMR. data.x_axis = source_state->TouchpadX(); @@ -558,21 +555,17 @@ } else if (is_controller) { description->target_ray_mode = device::mojom::XRTargetRayMode::POINTING; description->handedness = WindowsToMojoHandedness(source->Handedness()); + + description->profiles.push_back("windows-mixed-reality"); + description->profiles.push_back("touchpad-thumbstick-controller"); + + source_state->gamepad = GetWebXRGamepad(input_state); } else { NOTREACHED(); } - if (is_controller) { - description->profiles.push_back("windows-mixed-reality"); - description->profiles.push_back("touchpad-thumbstick-controller"); - } - source_state->description = std::move(description); - input_state.source_state = std::move(source_state); - - input_state.source_state->gamepad = GetWebXRGamepad(input_state); - return input_state; }
diff --git a/device/vr/windows_mixed_reality/wrappers/test/mock_wmr_input_manager.cc b/device/vr/windows_mixed_reality/wrappers/test/mock_wmr_input_manager.cc index bca48e1b..85dc8c9 100644 --- a/device/vr/windows_mixed_reality/wrappers/test/mock_wmr_input_manager.cc +++ b/device/vr/windows_mixed_reality/wrappers/test/mock_wmr_input_manager.cc
@@ -27,11 +27,11 @@ {device::XrButtonMaskFromId(device::XrButtonId::kGrip), ABI::Windows::UI::Input::Spatial::SpatialInteractionPressKind_Grasp}, // Touchpad. - {device::XrButtonMaskFromId(device::XrButtonId::kAxisSecondary), + {device::XrButtonMaskFromId(device::XrButtonId::kAxisTrackpad), ABI::Windows::UI::Input::Spatial:: SpatialInteractionPressKind_Touchpad}, // Joystick. - {device::XrButtonMaskFromId(device::XrButtonId::kAxisPrimary), + {device::XrButtonMaskFromId(device::XrButtonId::kAxisThumbstick), ABI::Windows::UI::Input::Spatial:: SpatialInteractionPressKind_Thumbstick}, };
diff --git a/device/vr/windows_mixed_reality/wrappers/test/mock_wmr_input_source_state.cc b/device/vr/windows_mixed_reality/wrappers/test/mock_wmr_input_source_state.cc index 8243aa7..8137526 100644 --- a/device/vr/windows_mixed_reality/wrappers/test/mock_wmr_input_source_state.cc +++ b/device/vr/windows_mixed_reality/wrappers/test/mock_wmr_input_source_state.cc
@@ -47,21 +47,22 @@ } bool MockWMRInputSourceState::IsThumbstickPressed() const { - return IsButtonPressed(XrButtonId::kAxisPrimary); + return IsButtonPressed(XrButtonId::kAxisThumbstick); } bool MockWMRInputSourceState::IsTouchpadPressed() const { - return IsButtonPressed(XrButtonId::kAxisSecondary); + return IsButtonPressed(XrButtonId::kAxisTrackpad); } bool MockWMRInputSourceState::IsTouchpadTouched() const { auto touched = data_.supported_buttons & data_.buttons_touched & - XrButtonMaskFromId(XrButtonId::kAxisSecondary); + XrButtonMaskFromId(XrButtonId::kAxisTrackpad); return touched != 0; } double MockWMRInputSourceState::ThumbstickX() const { - double val = data_.axis_data[XrAxisOffsetFromId(XrButtonId::kAxisPrimary)].x; + double val = + data_.axis_data[XrAxisOffsetFromId(XrButtonId::kAxisThumbstick)].x; // Should be in [-1, 1] for joysticks. DCHECK(val <= 1); DCHECK(val >= -1); @@ -70,7 +71,8 @@ // Invert the y axis because -1 is up in the Gamepad API, but down in WMR. double MockWMRInputSourceState::ThumbstickY() const { - double val = data_.axis_data[XrAxisOffsetFromId(XrButtonId::kAxisPrimary)].y; + double val = + data_.axis_data[XrAxisOffsetFromId(XrButtonId::kAxisThumbstick)].y; // Should be in [-1, 1] for joysticks. DCHECK(val <= 1); DCHECK(val >= -1); @@ -78,8 +80,7 @@ } double MockWMRInputSourceState::TouchpadX() const { - double val = - data_.axis_data[XrAxisOffsetFromId(XrButtonId::kAxisSecondary)].x; + double val = data_.axis_data[XrAxisOffsetFromId(XrButtonId::kAxisTrackpad)].x; // Should be in [-1, 1] for touchpads. DCHECK(val <= 1); DCHECK(val >= -1); @@ -88,8 +89,7 @@ // Invert the y axis because -1 is up in the Gamepad API, but down in WMR. double MockWMRInputSourceState::TouchpadY() const { - double val = - data_.axis_data[XrAxisOffsetFromId(XrButtonId::kAxisSecondary)].y; + double val = data_.axis_data[XrAxisOffsetFromId(XrButtonId::kAxisTrackpad)].y; // Should be in [-1, 1] for touchpads. DCHECK(val <= 1); DCHECK(val >= -1);
diff --git a/docs/speed/bot_health_sheriffing/main.md b/docs/speed/bot_health_sheriffing/main.md index 97bad19..e6b2d16 100644 --- a/docs/speed/bot_health_sheriffing/main.md +++ b/docs/speed/bot_health_sheriffing/main.md
@@ -42,19 +42,24 @@ ## Workflow -Incoming failures are shown in [Sheriff-o-matic](https://sheriff-o-matic.appspot.com/chromium.perf), which acts as a task management system for bot health sheriffs. Failures are divided into three groups on the dashboard: +~~Incoming failures are shown in [Sheriff-o-matic](https://sheriff-o-matic.appspot.com/chromium.perf), which acts as a task management system for bot health sheriffs. Failures are divided into three groups on the dashboard:~~ -* **Infra failures** show general infrastructure problems that are affecting benchmarks. Besides surfacing in Sheriff-o-matic, we also need to check for down bots in the lame duck pool. Please file a ticket for any bots you see in [this list](https://chrome-swarming.appspot.com/botlist?c=id&c=os&c=task&c=status&c=os&c=task&c=status&c=pool&f=status%3Adead&f=pool%3Achrome.tests.perf&l=100&q=pool%3Achrome.tests.perf&s=id%3Aasc) or [this list for webview](https://chrome-swarming.appspot.com/botlist?c=id&c=os&c=task&c=status&c=os&c=task&c=status&c=pool&f=status%3Adead&f=pool%3Achrome.tests.perf-webview&l=100&q=pool%3Achrome.tests.perf&s=id%3Aasc) as they will not show up in Sheriff-o-matic. +* ~~**Infra failures** show general infrastructure problems that are affecting benchmarks. Besides surfacing in Sheriff-o-matic, we also need to check for down bots in the lame duck pool. Please file a ticket for any bots you see in [this list](https://chrome-swarming.appspot.com/botlist?c=id&c=os&c=task&c=status&c=os&c=task&c=status&c=pool&f=status%3Adead&f=pool%3Achrome.tests.perf&l=100&q=pool%3Achrome.tests.perf&s=id%3Aasc) or [this list for webview](https://chrome-swarming.appspot.com/botlist?c=id&c=os&c=task&c=status&c=os&c=task&c=status&c=pool&f=status%3Adead&f=pool%3Achrome.tests.perf-webview&l=100&q=pool%3Achrome.tests.perf&s=id%3Aasc) as they will not show up in Sheriff-o-matic.~~ -* **Consistent failures** show benchmarks that have been failing for a while. +* ~~**Consistent failures** show benchmarks that have been failing for a while.~~ -* **New failures** show benchmarks that benchmarks that have recently started failing. +* ~~**New failures** show benchmarks that benchmarks that have recently started failing.~~ -Of these three groups, the sheriff should only be concerned with **infra failures** and **consistent failures.** New failures are too likely to be one-off flakes to warrant investigation. +~~Of these three groups, the sheriff should only be concerned with **infra failures** and **consistent failures.** New failures are too likely to be one-off flakes to warrant investigation.~~ -The high-level workflow is to start at the top of the list of the list of failures and address one alert at a time. The alerts are ordered roughly in order of their impact. +~~The high-level workflow is to start at the top of the list of the list of failures and address one alert at a time. The alerts are ordered roughly in order of their impact.~~ -As the sheriff addresses alerts, the number of alerts will generally decrease as problems with the same cause get grouped together and failures get fixed. Addressed alerts will also move to the bottom of the list. Ideally, Sheriff-o-matic should reflect the work you've done so that a new sheriff could potentially take over at any time and pick up at the top of the list. +~~As the sheriff addresses alerts, the number of alerts will generally decrease as problems with the same cause get grouped together and failures get fixed. Addressed alerts will also move to the bottom of the list. Ideally, Sheriff-o-matic should reflect the work you've done so that a new sheriff could potentially take over at any time and pick up at the top of the list.~~ + +**Note that Sheriff-O-Matic currently doesn't work for the perf waterfall +[crbug.com/984159](https://crbug.com/984159). +Please use [Milo chrome.perf +console](https://ci.chromium.org/p/chrome/g/chrome.perf/console) instead.** ## How to address each alert
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn index 2876a09..79ad0b7 100644 --- a/extensions/browser/BUILD.gn +++ b/extensions/browser/BUILD.gn
@@ -213,12 +213,6 @@ "guest_view/extension_options/extension_options_guest.h", "guest_view/extension_options/extension_options_guest_delegate.cc", "guest_view/extension_options/extension_options_guest_delegate.h", - "guest_view/extension_view/extension_view_constants.cc", - "guest_view/extension_view/extension_view_constants.h", - "guest_view/extension_view/extension_view_guest.cc", - "guest_view/extension_view/extension_view_guest.h", - "guest_view/extension_view/whitelist/extension_view_whitelist.cc", - "guest_view/extension_view/whitelist/extension_view_whitelist.h", "guest_view/extensions_guest_view_manager_delegate.cc", "guest_view/extensions_guest_view_manager_delegate.h", "guest_view/extensions_guest_view_message_filter.cc",
diff --git a/extensions/browser/api/BUILD.gn b/extensions/browser/api/BUILD.gn index 133e877..d394098 100644 --- a/extensions/browser/api/BUILD.gn +++ b/extensions/browser/api/BUILD.gn
@@ -26,8 +26,6 @@ "extensions_api_client.h", "guest_view/app_view/app_view_guest_internal_api.cc", "guest_view/app_view/app_view_guest_internal_api.h", - "guest_view/extension_view/extension_view_internal_api.cc", - "guest_view/extension_view/extension_view_internal_api.h", "guest_view/guest_view_internal_api.cc", "guest_view/guest_view_internal_api.h", "guest_view/web_view/web_view_internal_api.cc",
diff --git a/extensions/browser/api/bluetooth/bluetooth_private_api.cc b/extensions/browser/api/bluetooth/bluetooth_private_api.cc index d88298e..9dba360 100644 --- a/extensions/browser/api/bluetooth/bluetooth_private_api.cc +++ b/extensions/browser/api/bluetooth/bluetooth_private_api.cc
@@ -697,6 +697,8 @@ RecordPairingResult(params_->success, params_->transport, params_->pairing_duration_ms); RecordPairingTransport(params_->transport); + + Respond(NoArguments()); } //////////////////////////////////////////////////////////////////////////////// @@ -720,6 +722,8 @@ base::UmaHistogramBoolean( "Bluetooth.ChromeOS.UserInitiatedReconnectionAttempt.Result.Settings", params_->success); + + Respond(NoArguments()); } //////////////////////////////////////////////////////////////////////////////// @@ -758,6 +762,8 @@ base::TimeDelta::FromMilliseconds(params_->selection_duration_ms), device::BluetoothUiSurface::kSettings, params_->was_paired, transport); #endif + + Respond(NoArguments()); } ////////////////////////////////////////////////////////////////////////////////
diff --git a/extensions/browser/api/declarative_net_request/composite_matcher_unittest.cc b/extensions/browser/api/declarative_net_request/composite_matcher_unittest.cc index 16cc9ab3..215911b 100644 --- a/extensions/browser/api/declarative_net_request/composite_matcher_unittest.cc +++ b/extensions/browser/api/declarative_net_request/composite_matcher_unittest.cc
@@ -47,7 +47,8 @@ redirect_rule_1.condition->url_filter = std::string("example.com"); redirect_rule_1.priority = kMinValidPriority; redirect_rule_1.action->type = std::string("redirect"); - redirect_rule_1.action->redirect_url = std::string("http://ruleset1.com"); + redirect_rule_1.action->redirect.emplace(); + redirect_rule_1.action->redirect->url = std::string("http://ruleset1.com"); redirect_rule_1.id = kMinValidID + 1; // Create the first ruleset matcher. @@ -64,7 +65,8 @@ TestRule allow_rule = block_rule; allow_rule.action->type = std::string("allow"); TestRule redirect_rule_2 = redirect_rule_1; - redirect_rule_2.action->redirect_url = std::string("http://ruleset2.com"); + redirect_rule_2.action->redirect.emplace(); + redirect_rule_2.action->redirect->url = std::string("http://ruleset2.com"); std::unique_ptr<RulesetMatcher> matcher_2; ASSERT_TRUE(CreateVerifiedMatcher( {allow_rule, redirect_rule_2}, @@ -158,7 +160,8 @@ redirect_rule_2.condition->url_filter = std::string("google.com"); redirect_rule_2.priority = kMinValidPriority; redirect_rule_2.action->type = std::string("redirect"); - redirect_rule_2.action->redirect_url = std::string("http://ruleset2.com"); + redirect_rule_2.action->redirect.emplace(); + redirect_rule_2.action->redirect->url = std::string("http://ruleset2.com"); redirect_rule_2.id = kMinValidID + 1; // Create a second ruleset matcher, which allows requests to example.com and @@ -243,7 +246,8 @@ redirect_rule.condition->url_filter = std::string("google.com"); redirect_rule.priority = kMinValidPriority; redirect_rule.action->type = std::string("redirect"); - redirect_rule.action->redirect_url = std::string("http://ruleset1.com"); + redirect_rule.action->redirect.emplace(); + redirect_rule.action->redirect->url = std::string("http://ruleset1.com"); redirect_rule.id = kMinValidID; TestRule upgrade_rule = CreateGenericRule(); @@ -321,7 +325,8 @@ abc_redirect.condition->url_filter = std::string("*abc*"); abc_redirect.priority = kMinValidPriority; abc_redirect.action->type = std::string("redirect"); - abc_redirect.action->redirect_url = std::string("http://google.com"); + abc_redirect.action->redirect.emplace(); + abc_redirect.action->redirect->url = std::string("http://google.com"); abc_redirect.id = kMinValidID; TestRule def_upgrade = CreateGenericRule(); @@ -334,7 +339,8 @@ ghi_redirect.condition->url_filter = std::string("*ghi*"); ghi_redirect.priority = kMinValidPriority + 2; ghi_redirect.action->type = std::string("redirect"); - ghi_redirect.action->redirect_url = std::string("http://example.com"); + ghi_redirect.action->redirect.emplace(); + ghi_redirect.action->redirect->url = std::string("http://example.com"); ghi_redirect.id = kMinValidID + 2; // In terms of priority: ghi > def > abc.
diff --git a/extensions/browser/api/declarative_net_request/constants.h b/extensions/browser/api/declarative_net_request/constants.h index b48b4eb..9b83bd3 100644 --- a/extensions/browser/api/declarative_net_request/constants.h +++ b/extensions/browser/api/declarative_net_request/constants.h
@@ -19,7 +19,6 @@ ERROR_RESOURCE_TYPE_DUPLICATED, ERROR_EMPTY_REDIRECT_RULE_PRIORITY, ERROR_EMPTY_UPGRADE_RULE_PRIORITY, - ERROR_EMPTY_REDIRECT_URL, ERROR_INVALID_RULE_ID, ERROR_INVALID_REDIRECT_RULE_PRIORITY, ERROR_INVALID_UPGRADE_RULE_PRIORITY,
diff --git a/extensions/browser/api/declarative_net_request/file_sequence_helper_unittest.cc b/extensions/browser/api/declarative_net_request/file_sequence_helper_unittest.cc index dba51a41..bda889b 100644 --- a/extensions/browser/api/declarative_net_request/file_sequence_helper_unittest.cc +++ b/extensions/browser/api/declarative_net_request/file_sequence_helper_unittest.cc
@@ -268,7 +268,8 @@ TestRule rule = CreateGenericRule(); rule.id = kMinValidID + 1; rule.action->type = std::string("redirect"); - rule.action->redirect_url = std::string("http://google.com"); + rule.action->redirect.emplace(); + rule.action->redirect->url = std::string("http://google.com"); api_rules.clear(); api_rules.push_back(GetAPIRule(rule)); TestAddDynamicRules(
diff --git a/extensions/browser/api/declarative_net_request/flat/extension_ruleset.fbs b/extensions/browser/api/declarative_net_request/flat/extension_ruleset.fbs index f1d4dfd..1fa30e7 100644 --- a/extensions/browser/api/declarative_net_request/flat/extension_ruleset.fbs +++ b/extensions/browser/api/declarative_net_request/flat/extension_ruleset.fbs
@@ -23,8 +23,6 @@ port : string; clear_path : bool = false; - - /// Includes the '/' separator for standard (http/https etc.) urls. path : string; clear_query : bool = false;
diff --git a/extensions/browser/api/declarative_net_request/indexed_rule.cc b/extensions/browser/api/declarative_net_request/indexed_rule.cc index c1516a7f..8d8bf33 100644 --- a/extensions/browser/api/declarative_net_request/indexed_rule.cc +++ b/extensions/browser/api/declarative_net_request/indexed_rule.cc
@@ -341,31 +341,6 @@ return ParseResult::ERROR_INVALID_REDIRECT; } -// Parses the "action.redirectUrl" key of a dnr_api::Rule. -ParseResult ParseRedirectUrl(std::string redirect_url, - const GURL& base_url, - base::Optional<std::string>* parsed_redirect_url) { - DCHECK(parsed_redirect_url); - - if (redirect_url.empty()) - return ParseResult::ERROR_EMPTY_REDIRECT_URL; - - if (IsRedirectUrlRelative(redirect_url)) { - GURL url = base_url.Resolve(redirect_url); - if (!url.is_valid()) - return ParseResult::ERROR_INVALID_REDIRECT_URL; - *parsed_redirect_url = url.spec(); - return ParseResult::SUCCESS; - } - - if (GURL(redirect_url).is_valid()) { - *parsed_redirect_url = std::move(redirect_url); - return ParseResult::SUCCESS; - } - - return ParseResult::ERROR_INVALID_REDIRECT_URL; -} - } // namespace IndexedRule::IndexedRule() = default; @@ -398,18 +373,13 @@ } if (is_redirect_rule) { - // Either the redirect url or the redirect dictionary should be specified. // TODO(crbug.com/983685): Prevent extensions from specifying redirects to // Javascript urls. - ParseResult result = ParseResult::ERROR_EMPTY_REDIRECT_URL; - if (parsed_rule.action.redirect_url) { - result = ParseRedirectUrl(std::move(*parsed_rule.action.redirect_url), - base_url, &indexed_rule->redirect_url); - } else if (parsed_rule.action.redirect) { - result = ParseRedirect(std::move(*parsed_rule.action.redirect), base_url, - indexed_rule); - } + if (!parsed_rule.action.redirect) + return ParseResult::ERROR_INVALID_REDIRECT; + ParseResult result = ParseRedirect(std::move(*parsed_rule.action.redirect), + base_url, indexed_rule); if (result != ParseResult::SUCCESS) return result; }
diff --git a/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc b/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc index a26a6e7..4913da0d 100644 --- a/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc +++ b/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc
@@ -35,6 +35,12 @@ return Extension::GetBaseURLFromExtensionId(kTestExtensionId); } +std::unique_ptr<dnr_api::Redirect> MakeRedirectUrl(const char* redirect_url) { + auto redirect = std::make_unique<dnr_api::Redirect>(); + redirect->url = std::make_unique<std::string>(redirect_url); + return redirect; +} + dnr_api::Rule CreateGenericParsedRule() { dnr_api::Rule rule; rule.id = kMinValidID; @@ -113,8 +119,7 @@ rule.action.type = cases[i].action_type; if (cases[i].action_type == dnr_api::RULE_ACTION_TYPE_REDIRECT) { - rule.action.redirect_url = - std::make_unique<std::string>("http://google.com"); + rule.action.redirect = MakeRedirectUrl("http://google.com"); } IndexedRule indexed_rule; @@ -411,26 +416,20 @@ TEST_F(IndexedRuleTest, RedirectUrlParsing) { struct { - std::unique_ptr<std::string> redirect_url; + const char* redirect_url; const ParseResult expected_result; // Only valid if |expected_result| is SUCCESS. const std::string expected_redirect_url; } cases[] = { - {std::make_unique<std::string>(""), ParseResult::ERROR_EMPTY_REDIRECT_URL, - ""}, - {nullptr, ParseResult::ERROR_EMPTY_REDIRECT_URL, ""}, - {std::make_unique<std::string>("http://google.com"), ParseResult::SUCCESS, - "http://google.com"}, - {std::make_unique<std::string>("/relative/url?q=1"), ParseResult::SUCCESS, - "chrome-extension://" + std::string(kTestExtensionId) + - "/relative/url?q=1"}, - {std::make_unique<std::string>("abc"), - ParseResult::ERROR_INVALID_REDIRECT_URL, ""}}; + {"", ParseResult::ERROR_INVALID_REDIRECT_URL, ""}, + {"http://google.com", ParseResult::SUCCESS, "http://google.com"}, + {"/relative/url?q=1", ParseResult::ERROR_INVALID_REDIRECT_URL, ""}, + {"abc", ParseResult::ERROR_INVALID_REDIRECT_URL, ""}}; for (size_t i = 0; i < base::size(cases); ++i) { SCOPED_TRACE(base::StringPrintf("Testing case[%" PRIuS "]", i)); dnr_api::Rule rule = CreateGenericParsedRule(); - rule.action.redirect_url = std::move(cases[i].redirect_url); + rule.action.redirect = MakeRedirectUrl(cases[i].redirect_url); rule.action.type = dnr_api::RULE_ACTION_TYPE_REDIRECT; rule.priority = std::make_unique<int>(kMinValidPriority); @@ -438,7 +437,7 @@ ParseResult result = IndexedRule::CreateIndexedRule( std::move(rule), GetBaseURL(), &indexed_rule); - EXPECT_EQ(cases[i].expected_result, result); + EXPECT_EQ(cases[i].expected_result, result) << static_cast<int>(result); if (result == ParseResult::SUCCESS) EXPECT_EQ(cases[i].expected_redirect_url, indexed_rule.redirect_url); } @@ -492,26 +491,33 @@ struct { std::string redirect_dictionary_json; ParseResult expected_result; - } cases[] = {// clang-format off + base::Optional<std::string> expected_redirect_url; + } cases[] = { + // clang-format off { "{}", - ParseResult::ERROR_INVALID_REDIRECT + ParseResult::ERROR_INVALID_REDIRECT, + base::nullopt }, { R"({"url": "xyz"})", - ParseResult::ERROR_INVALID_REDIRECT_URL + ParseResult::ERROR_INVALID_REDIRECT_URL, + base::nullopt }, { R"({"url": "http://google.com"})", - ParseResult::SUCCESS + ParseResult::SUCCESS, + std::string("http://google.com") }, { R"({"extensionPath": "foo/xyz/"})", - ParseResult::ERROR_INVALID_EXTENSION_PATH + ParseResult::ERROR_INVALID_EXTENSION_PATH, + base::nullopt }, { R"({"extensionPath": "/foo/xyz?q=1"})", - ParseResult::SUCCESS + ParseResult::SUCCESS, + GetBaseURL().Resolve("/foo/xyz?q=1").spec() }, { R"( @@ -520,7 +526,7 @@ "scheme": "", "host": "foo.com" } - })", ParseResult::ERROR_INVALID_TRANSFORM_SCHEME + })", ParseResult::ERROR_INVALID_TRANSFORM_SCHEME, base::nullopt }, { R"( @@ -529,7 +535,7 @@ "scheme": "javascript", "host": "foo.com" } - })", ParseResult::ERROR_INVALID_TRANSFORM_SCHEME + })", ParseResult::ERROR_INVALID_TRANSFORM_SCHEME, base::nullopt }, { R"( @@ -538,7 +544,7 @@ "scheme": "http", "port": "-1" } - })", ParseResult::ERROR_INVALID_TRANSFORM_PORT + })", ParseResult::ERROR_INVALID_TRANSFORM_PORT, base::nullopt }, { R"( @@ -547,19 +553,22 @@ "scheme": "http", "query": "abc" } - })", ParseResult::ERROR_INVALID_TRANSFORM_QUERY + })", ParseResult::ERROR_INVALID_TRANSFORM_QUERY, base::nullopt }, { R"({"transform": {"path": "abc"}})", - ParseResult::SUCCESS + ParseResult::SUCCESS, + base::nullopt }, { R"({"transform": {"fragment": "abc"}})", - ParseResult::ERROR_INVALID_TRANSFORM_FRAGMENT + ParseResult::ERROR_INVALID_TRANSFORM_FRAGMENT, + base::nullopt }, { R"({"transform": {"path": ""}})", - ParseResult::SUCCESS + ParseResult::SUCCESS, + base::nullopt }, { R"( @@ -571,7 +580,7 @@ "removeParams": ["abc"] } } - })", ParseResult::ERROR_QUERY_AND_TRANSFORM_BOTH_SPECIFIED + })", ParseResult::ERROR_QUERY_AND_TRANSFORM_BOTH_SPECIFIED, base::nullopt }, { R"( @@ -590,7 +599,7 @@ "fragment": "", "username": "user" } - })", ParseResult::SUCCESS + })", ParseResult::SUCCESS, base::nullopt } }; // clang-format on @@ -619,6 +628,7 @@ EXPECT_TRUE(indexed_rule.url_transform || indexed_rule.redirect_url); EXPECT_FALSE(indexed_rule.url_transform && indexed_rule.redirect_url); + EXPECT_EQ(cases[i].expected_redirect_url, indexed_rule.redirect_url); } }
diff --git a/extensions/browser/api/declarative_net_request/parse_info.cc b/extensions/browser/api/declarative_net_request/parse_info.cc index ce95c68..a2e1e0b 100644 --- a/extensions/browser/api/declarative_net_request/parse_info.cc +++ b/extensions/browser/api/declarative_net_request/parse_info.cc
@@ -55,11 +55,6 @@ error = ErrorUtils::FormatErrorMessage(kErrorEmptyUpgradeRulePriority, base::NumberToString(*rule_id_)); break; - case ParseResult::ERROR_EMPTY_REDIRECT_URL: - error = ErrorUtils::FormatErrorMessage(kErrorEmptyRedirectRuleKey, - base::NumberToString(*rule_id_), - kRedirectUrlKey); - break; case ParseResult::ERROR_INVALID_RULE_ID: error = ErrorUtils::FormatErrorMessage( kErrorInvalidRuleKey, base::NumberToString(*rule_id_), kIDKey, @@ -91,7 +86,7 @@ case ParseResult::ERROR_INVALID_REDIRECT_URL: error = ErrorUtils::FormatErrorMessage(kErrorInvalidRedirectUrl, base::NumberToString(*rule_id_), - kRedirectUrlKey); + kRedirectUrlPath); break; case ParseResult::ERROR_DUPLICATE_IDS: error = ErrorUtils::FormatErrorMessage(kErrorDuplicateIDs,
diff --git a/extensions/browser/api/declarative_net_request/ruleset_matcher.cc b/extensions/browser/api/declarative_net_request/ruleset_matcher.cc index 642f0a4..9e2cebc 100644 --- a/extensions/browser/api/declarative_net_request/ruleset_matcher.cc +++ b/extensions/browser/api/declarative_net_request/ruleset_matcher.cc
@@ -4,6 +4,7 @@ #include "extensions/browser/api/declarative_net_request/ruleset_matcher.h" +#include <algorithm> #include <limits> #include <utility> @@ -12,6 +13,7 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" +#include "base/strings/strcat.h" #include "base/timer/elapsed_timer.h" #include "content/public/common/resource_type.h" #include "extensions/browser/api/declarative_net_request/constants.h" @@ -20,7 +22,9 @@ #include "extensions/browser/api/web_request/web_request_info.h" #include "extensions/common/api/declarative_net_request.h" #include "extensions/common/api/declarative_net_request/utils.h" +#include "net/base/escape.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" +#include "net/base/url_util.h" namespace extensions { namespace declarative_net_request { @@ -77,8 +81,7 @@ if (request.url.SchemeIsWSOrWSS()) return flat_rule::ElementType_WEBSOCKET; - return request.type.has_value() ? GetElementType(request.type.value()) - : flat_rule::ElementType_OTHER; + return GetElementType(request.type); } // Returns whether the request to |url| is third party to its |document_origin|. @@ -144,6 +147,147 @@ return false; } +base::StringPiece CreateStringPiece(const ::flatbuffers::String& str) { + return base::StringPiece(str.c_str(), str.size()); +} + +// Performs any required query transformations on the |url|. Returns true if the +// query should be modified and populates |modified_query|. +bool GetModifiedQuery(const GURL& url, + const flat::UrlTransform& transform, + std::string* modified_query) { + DCHECK(modified_query); + + // TODO(crbug.com/983685): We should be able to reduce the work here by + // storing the escaped query params in the indexed format. + const bool use_plus = true; + std::set<std::string> escaped_remove_query_params; + if (transform.remove_query_params()) { + for (const ::flatbuffers::String* str : *transform.remove_query_params()) { + escaped_remove_query_params.insert( + net::EscapeQueryParamValue(CreateStringPiece(*str), use_plus)); + } + } + + // We don't use a map from keys to vector of values to ensure the relative + // order of different params specified by the extension is respected. We use + // a std::list to support fast removal from middle of the list. + std::list<std::pair<std::string, std::string>> + escaped_add_or_replace_query_params; + if (transform.add_or_replace_query_params()) { + for (const flat::QueryKeyValue* query_pair : + *transform.add_or_replace_query_params()) { + DCHECK(query_pair->key()); + DCHECK(query_pair->value()); + std::string key = net::EscapeQueryParamValue( + CreateStringPiece(*query_pair->key()), use_plus); + std::string value = net::EscapeQueryParamValue( + CreateStringPiece(*query_pair->value()), use_plus); + escaped_add_or_replace_query_params.emplace_back(std::move(key), + std::move(value)); + } + } + + if (escaped_add_or_replace_query_params.empty() && + escaped_remove_query_params.empty()) { + return false; + } + + std::vector<std::string> query_parts; + + auto create_query_part = [](base::StringPiece key, base::StringPiece value) { + return base::StrCat({key, "=", value}); + }; + + bool query_changed = false; + for (net::QueryIterator it(url); !it.IsAtEnd(); it.Advance()) { + std::string key = it.GetKey(); + // Remove query param. + if (base::Contains(escaped_remove_query_params, key)) { + query_changed = true; + continue; + } + + auto replace_iterator = + std::find_if(escaped_add_or_replace_query_params.begin(), + escaped_add_or_replace_query_params.end(), + [&key](const std::pair<std::string, std::string>& param) { + return param.first == key; + }); + + // Nothing to do. + if (replace_iterator == escaped_add_or_replace_query_params.end()) { + query_parts.push_back(create_query_part(key, it.GetValue())); + continue; + } + + // Replace query param. + query_changed = true; + query_parts.push_back(create_query_part(key, replace_iterator->second)); + escaped_add_or_replace_query_params.erase(replace_iterator); + } + + // Append any remaining query params. + for (const auto& params : escaped_add_or_replace_query_params) { + query_changed = true; + query_parts.push_back(create_query_part(params.first, params.second)); + } + + if (!query_changed) + return false; + + *modified_query = base::JoinString(query_parts, "&"); + return true; +} + +GURL GetTransformedURL(const RequestParams& params, + const flat::UrlTransform& transform) { + GURL::Replacements replacements; + + if (transform.scheme()) + replacements.SetSchemeStr(CreateStringPiece(*transform.scheme())); + + if (transform.host()) + replacements.SetHostStr(CreateStringPiece(*transform.host())); + + DCHECK(!(transform.clear_port() && transform.port())); + if (transform.clear_port()) + replacements.ClearPort(); + else if (transform.port()) + replacements.SetPortStr(CreateStringPiece(*transform.port())); + + DCHECK(!(transform.clear_path() && transform.path())); + if (transform.clear_path()) + replacements.ClearPath(); + else if (transform.path()) + replacements.SetPathStr(CreateStringPiece(*transform.path())); + + // |query| is defined outside the if conditions since url::Replacements does + // not own the strings it uses. + std::string query; + if (transform.clear_query()) { + replacements.ClearQuery(); + } else if (transform.query()) { + replacements.SetQueryStr(CreateStringPiece(*transform.query())); + } else if (GetModifiedQuery(*params.url, transform, &query)) { + replacements.SetQueryStr(query); + } + + DCHECK(!(transform.clear_fragment() && transform.fragment())); + if (transform.clear_fragment()) + replacements.ClearRef(); + else if (transform.fragment()) + replacements.SetRefStr(CreateStringPiece(*transform.fragment())); + + if (transform.password()) + replacements.SetPasswordStr(CreateStringPiece(*transform.password())); + + if (transform.username()) + replacements.SetUsernameStr(CreateStringPiece(*transform.username())); + + return params.url->ReplaceComponents(replacements); +} + } // namespace RequestParams::RequestParams(const WebRequestInfo& info) @@ -256,12 +400,16 @@ // There must be a UrlRuleMetadata object corresponding to each redirect rule. DCHECK(metadata); DCHECK_EQ(metadata->id(), rule->id()); + DCHECK(metadata->redirect_url() || metadata->transform()); - *redirect_url = GURL(base::StringPiece(metadata->redirect_url()->c_str(), - metadata->redirect_url()->size())); - DCHECK(redirect_url->is_valid()); + if (metadata->redirect_url()) + *redirect_url = GURL(CreateStringPiece(*metadata->redirect_url())); + else + *redirect_url = GetTransformedURL(params, *metadata->transform()); + // Prevent a redirect loop where a URL continuously redirects to itself. - return *params.url == *redirect_url ? nullptr : rule; + return (redirect_url->is_valid() && *params.url != *redirect_url) ? rule + : nullptr; } const flat_rule::UrlRule* RulesetMatcher::GetUpgradeRule(
diff --git a/extensions/browser/api/declarative_net_request/ruleset_matcher_unittest.cc b/extensions/browser/api/declarative_net_request/ruleset_matcher_unittest.cc index 0849769..3df466c 100644 --- a/extensions/browser/api/declarative_net_request/ruleset_matcher_unittest.cc +++ b/extensions/browser/api/declarative_net_request/ruleset_matcher_unittest.cc
@@ -9,6 +9,8 @@ #include "base/files/file_util.h" #include "base/logging.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" #include "components/url_pattern_index/flat/url_pattern_index_generated.h" #include "components/version_info/version_info.h" #include "extensions/browser/api/declarative_net_request/constants.h" @@ -69,7 +71,8 @@ rule.condition->url_filter = std::string("google.com"); rule.priority = kMinValidPriority; rule.action->type = std::string("redirect"); - rule.action->redirect_url = std::string("http://yahoo.com"); + rule.action->redirect.emplace(); + rule.action->redirect->url = std::string("http://yahoo.com"); std::unique_ptr<RulesetMatcher> matcher; ASSERT_TRUE(CreateVerifiedMatcher({rule}, CreateTemporarySource(), &matcher)); @@ -101,7 +104,8 @@ rule.condition->url_filter = std::string("go*"); rule.priority = kMinValidPriority; rule.action->type = std::string("redirect"); - rule.action->redirect_url = std::string("http://google.com"); + rule.action->redirect.emplace(); + rule.action->redirect->url = std::string("http://google.com"); std::unique_ptr<RulesetMatcher> matcher; ASSERT_TRUE(CreateVerifiedMatcher({rule}, CreateTemporarySource(), &matcher)); @@ -210,6 +214,197 @@ EXPECT_EQ(current_mask, matcher->GetRemoveHeadersMask(params, current_mask)); } +// Tests a rule to redirect to an extension path. +TEST_F(RulesetMatcherTest, RedirectToExtensionPath) { + TestRule rule = CreateGenericRule(); + rule.condition->url_filter = std::string("example.com"); + rule.action->type = std::string("redirect"); + rule.priority = kMinValidPriority; + rule.action->redirect.emplace(); + rule.action->redirect->extension_path = "/path/newfile.js?query#fragment"; + + std::unique_ptr<RulesetMatcher> matcher; + const size_t kId = 1; + const size_t kPriority = 1; + const size_t kRuleCountLimit = 10; + const ExtensionId extension_id = "extension_id"; + ASSERT_TRUE(CreateVerifiedMatcher( + {rule}, + CreateTemporarySource(kId, kPriority, kRuleCountLimit, extension_id), + &matcher)); + + GURL example_url("http://example.com"); + RequestParams params; + params.url = &example_url; + + GURL redirect_url; + EXPECT_TRUE(matcher->GetRedirectRule(params, &redirect_url)); + GURL expected_redirect_url( + "chrome-extension://extension_id/path/newfile.js?query#fragment"); + EXPECT_EQ(expected_redirect_url, redirect_url); +} + +// Tests a rule to redirect to a static url. +TEST_F(RulesetMatcherTest, RedirectToStaticUrl) { + TestRule rule = CreateGenericRule(); + rule.condition->url_filter = std::string("example.com"); + rule.action->type = std::string("redirect"); + rule.priority = kMinValidPriority; + rule.action->redirect.emplace(); + rule.action->redirect->url = "https://google.com"; + + std::unique_ptr<RulesetMatcher> matcher; + ASSERT_TRUE(CreateVerifiedMatcher({rule}, CreateTemporarySource(), &matcher)); + + GURL example_url("http://example.com"); + RequestParams params; + params.url = &example_url; + + GURL redirect_url; + GURL expected_redirect_url("https://google.com"); + EXPECT_TRUE(matcher->GetRedirectRule(params, &redirect_url)); + EXPECT_EQ(expected_redirect_url, redirect_url); +} + +// Tests url transformation rules. +TEST_F(RulesetMatcherTest, UrlTransform) { + struct TestCase { + std::string url; + // Valid if a redirect is expected. + base::Optional<std::string> expected_redirect_url; + }; + + std::vector<TestCase> cases; + std::vector<TestRule> rules; + + auto create_transform_rule = [](size_t id, const std::string& filter) { + TestRule rule = CreateGenericRule(); + rule.id = id; + rule.condition->url_filter = filter; + rule.priority = kMinValidPriority; + rule.action->type = std::string("redirect"); + rule.action->redirect.emplace(); + rule.action->redirect->transform.emplace(); + return rule; + }; + + TestRule rule = create_transform_rule(1, "||1.com"); + rule.action->redirect->transform->scheme = "https"; + rules.push_back(rule); + cases.push_back({"http://1.com/path?query", "https://1.com/path?query"}); + + rule = create_transform_rule(2, "||2.com"); + rule.action->redirect->transform->scheme = "ftp"; + rule.action->redirect->transform->host = "ftp.host.com"; + rule.action->redirect->transform->port = "70"; + rules.push_back(rule); + cases.push_back( + {"http://2.com:100/path?query", "ftp://ftp.host.com:70/path?query"}); + + rule = create_transform_rule(3, "||3.com"); + rule.action->redirect->transform->port = ""; + rule.action->redirect->transform->path = ""; + rule.action->redirect->transform->query = "?new_query"; + rule.action->redirect->transform->fragment = "#fragment"; + rules.push_back(rule); + // The path separator '/' is output even when cleared, except when there is no + // authority, query and fragment. + cases.push_back( + {"http://3.com:100/path?query", "http://3.com/?new_query#fragment"}); + + rule = create_transform_rule(4, "||4.com"); + rule.action->redirect->transform->scheme = "http"; + rule.action->redirect->transform->path = " "; + rules.push_back(rule); + cases.push_back({"http://4.com/xyz", "http://4.com/%20"}); + + rule = create_transform_rule(5, "||5.com"); + rule.action->redirect->transform->path = "/"; + rule.action->redirect->transform->query = ""; + rule.action->redirect->transform->fragment = "#"; + rules.push_back(rule); + cases.push_back( + {"http://5.com:100/path?query#fragment", "http://5.com:100/#"}); + + rule = create_transform_rule(6, "||6.com"); + rule.action->redirect->transform->path = "/path?query"; + rules.push_back(rule); + // The "?" in path is url encoded since it's not part of the query. + cases.push_back({"http://6.com/xyz?q1", "http://6.com/path%3Fquery?q1"}); + + rule = create_transform_rule(7, "||7.com"); + rule.action->redirect->transform->username = "new_user"; + rule.action->redirect->transform->password = "new_pass"; + rules.push_back(rule); + cases.push_back( + {"http://user@7.com/xyz", "http://new_user:new_pass@7.com/xyz"}); + + auto make_query = [](const std::string& key, const std::string& value) { + TestRuleQueryKeyValue query; + query.key = key; + query.value = value; + return query; + }; + + rule = create_transform_rule(8, "||8.com"); + rule.action->redirect->transform->query_transform.emplace(); + rule.action->redirect->transform->query_transform->remove_params = + std::vector<std::string>({"r1", "r2"}); + rule.action->redirect->transform->query_transform->add_or_replace_params = + std::vector<TestRuleQueryKeyValue>( + {make_query("a1", "#"), make_query("a2", ""), + make_query("a1", "new2"), make_query("a1", "new3")}); + rules.push_back(rule); + cases.push_back( + {"http://8.com/" + "path?r1&r1=val1&a1=val1&r2=val&x3=val&a1=val2&a2=val&r1=val2", + "http://8.com/path?a1=%23&x3=val&a1=new2&a2=&a1=new3"}); + cases.push_back({"http://8.com/path?query", + "http://8.com/path?query=&a1=%23&a2=&a1=new2&a1=new3"}); + + rule = create_transform_rule(9, "||9.com"); + rule.action->redirect->transform->query_transform.emplace(); + rule.action->redirect->transform->query_transform->remove_params = + std::vector<std::string>({"r1", "r2"}); + rules.push_back(rule); + // No redirect is performed since the url won't change. + cases.push_back({"http://9.com/path?query#fragment", base::nullopt}); + + rule = create_transform_rule(10, "||10.com"); + rule.action->redirect->transform->query_transform.emplace(); + rule.action->redirect->transform->query_transform->remove_params = + std::vector<std::string>({"q1"}); + rule.action->redirect->transform->query_transform->add_or_replace_params = + std::vector<TestRuleQueryKeyValue>({make_query("q1", "new")}); + rules.push_back(rule); + cases.push_back( + {"https://10.com/path?q1=1&q1=2&q1=3", "https://10.com/path?q1=new"}); + + std::unique_ptr<RulesetMatcher> matcher; + ASSERT_TRUE(CreateVerifiedMatcher(rules, CreateTemporarySource(), &matcher)); + + for (const auto& test_case : cases) { + SCOPED_TRACE(base::StringPrintf("Testing url %s", test_case.url.c_str())); + + GURL url(test_case.url); + ASSERT_TRUE(url.is_valid()) << test_case.url; + RequestParams params; + params.url = &url; + + GURL redirect_url; + if (!test_case.expected_redirect_url) { + EXPECT_FALSE(matcher->GetRedirectRule(params, &redirect_url)) + << redirect_url.spec(); + continue; + } + + ASSERT_TRUE(GURL(*test_case.expected_redirect_url).is_valid()) + << *test_case.expected_redirect_url; + EXPECT_TRUE(matcher->GetRedirectRule(params, &redirect_url)); + EXPECT_EQ(*test_case.expected_redirect_url, redirect_url.spec()); + } +} + } // namespace } // namespace declarative_net_request } // namespace extensions
diff --git a/extensions/browser/api/declarative_net_request/test_utils.cc b/extensions/browser/api/declarative_net_request/test_utils.cc index 84e800c6..91236ec3 100644 --- a/extensions/browser/api/declarative_net_request/test_utils.cc +++ b/extensions/browser/api/declarative_net_request/test_utils.cc
@@ -49,7 +49,7 @@ IndexAndPersistJSONRulesetResult result = source.IndexAndPersistJSONRulesetUnsafe(); if (!result.success) { - DCHECK(result.error.empty()); + DCHECK(result.error.empty()) << result.error; return false; }
diff --git a/extensions/browser/api/guest_view/extension_view/extension_view_internal_api.cc b/extensions/browser/api/guest_view/extension_view/extension_view_internal_api.cc deleted file mode 100644 index 5110afa..0000000 --- a/extensions/browser/api/guest_view/extension_view/extension_view_internal_api.cc +++ /dev/null
@@ -1,82 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "extensions/browser/api/guest_view/extension_view/extension_view_internal_api.h" - -#include <utility> - -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "components/crx_file/id_util.h" -#include "content/public/browser/storage_partition.h" -#include "content/public/browser/web_contents.h" -#include "content/public/common/stop_find_action.h" -#include "extensions/browser/guest_view/extension_view/whitelist/extension_view_whitelist.h" -#include "extensions/common/api/extension_view_internal.h" -#include "extensions/common/constants.h" - -namespace extensionview = extensions::api::extension_view_internal; - -namespace extensions { - -bool ExtensionViewInternalExtensionFunction::PreRunValidation( - std::string* error) { - int instance_id = 0; - EXTENSION_FUNCTION_PRERUN_VALIDATE(args_->GetInteger(0, &instance_id)); - guest_ = ExtensionViewGuest::From(source_process_id(), instance_id); - return guest_ != nullptr; -} - -// Checks the validity of |src|, including that it follows the chrome extension -// scheme and that its extension ID is valid. -// Returns true if |src| is valid. -bool IsSrcValid(const GURL& src) { - // Check if src is valid and matches the extension scheme. - if (!src.is_valid() || !src.SchemeIs(kExtensionScheme)) - return false; - - // Get the extension id and check if it is valid. - std::string extension_id = src.host(); - if (!crx_file::id_util::IdIsValid(extension_id) || - !IsExtensionIdWhitelisted(extension_id)) - return false; - - return true; -} - -ExtensionFunction::ResponseAction ExtensionViewInternalLoadSrcFunction::Run() { - std::unique_ptr<extensionview::LoadSrc::Params> params( - extensionview::LoadSrc::Params::Create(*args_)); - EXTENSION_FUNCTION_VALIDATE(params.get()); - std::string src = params->src; - GURL url(src); - bool has_load_succeeded = false; - bool is_src_valid = IsSrcValid(url); - - if (is_src_valid) { - has_load_succeeded = - guest_->NavigateGuest(src, true /* force_navigation */); - } - - // Return whether load is successful. - return RespondNow( - OneArgument(std::make_unique<base::Value>(has_load_succeeded))); -} - -ExtensionFunction::ResponseAction ExtensionViewInternalParseSrcFunction::Run() { - std::unique_ptr<extensionview::ParseSrc::Params> params( - extensionview::ParseSrc::Params::Create(*args_)); - EXTENSION_FUNCTION_VALIDATE(params.get()); - GURL url(params->src); - bool is_src_valid = IsSrcValid(url); - - // Return whether the src is valid and the current extension ID to - // the callback. - auto result_list = std::make_unique<base::ListValue>(); - result_list->AppendBoolean(is_src_valid); - result_list->AppendString(url.host()); - return RespondNow(ArgumentList(std::move(result_list))); -} - -} // namespace extensions
diff --git a/extensions/browser/api/guest_view/extension_view/extension_view_internal_api.h b/extensions/browser/api/guest_view/extension_view/extension_view_internal_api.h deleted file mode 100644 index 6dbd6a6..0000000 --- a/extensions/browser/api/guest_view/extension_view/extension_view_internal_api.h +++ /dev/null
@@ -1,67 +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 EXTENSIONS_BROWSER_API_GUEST_VIEW_EXTENSION_VIEW_EXTENSION_VIEW_INTERNAL_API_H_ -#define EXTENSIONS_BROWSER_API_GUEST_VIEW_EXTENSION_VIEW_EXTENSION_VIEW_INTERNAL_API_H_ - -#include "base/macros.h" -#include "extensions/browser/api/execute_code_function.h" -#include "extensions/browser/extension_function.h" -#include "extensions/browser/guest_view/extension_view/extension_view_guest.h" - -namespace extensions { - -// An abstract base class for async extensionview APIs. It does a process ID -// check in PreRunValidation. -class ExtensionViewInternalExtensionFunction : public ExtensionFunction { - public: - ExtensionViewInternalExtensionFunction() {} - - protected: - ~ExtensionViewInternalExtensionFunction() override {} - - // ExtensionFunction implementation. - bool PreRunValidation(std::string* error) final; - - ExtensionViewGuest* guest_ = nullptr; -}; - -// Attempts to load a src into the extensionview. -class ExtensionViewInternalLoadSrcFunction - : public ExtensionViewInternalExtensionFunction { - public: - DECLARE_EXTENSION_FUNCTION("extensionViewInternal.loadSrc", - EXTENSIONVIEWINTERNAL_LOADSRC) - ExtensionViewInternalLoadSrcFunction() {} - - protected: - ~ExtensionViewInternalLoadSrcFunction() override {} - - private: - // ExtensionFunction implementation. - ResponseAction Run() final; - - DISALLOW_COPY_AND_ASSIGN(ExtensionViewInternalLoadSrcFunction); -}; - -// Parses a src and determines whether or not it is valid. -class ExtensionViewInternalParseSrcFunction : public ExtensionFunction { - public: - DECLARE_EXTENSION_FUNCTION("extensionViewInternal.parseSrc", - EXTENSIONVIEWINTERNAL_PARSESRC) - ExtensionViewInternalParseSrcFunction() {} - - protected: - ~ExtensionViewInternalParseSrcFunction() override {} - - private: - // ExtensionFunction implementation. - ResponseAction Run() final; - - DISALLOW_COPY_AND_ASSIGN(ExtensionViewInternalParseSrcFunction); -}; - -} // namespace extensions - -#endif // EXTENSIONS_BROWSER_API_GUEST_VIEW_EXTENSION_VIEW_EXTENSION_VIEW_INTERNAL_API_H_
diff --git a/extensions/browser/api/management/management_api.cc b/extensions/browser/api/management/management_api.cc index c7a9648..d1af375 100644 --- a/extensions/browser/api/management/management_api.cc +++ b/extensions/browser/api/management/management_api.cc
@@ -821,6 +821,106 @@ return RespondLater(); } +ManagementCanInstallReplacementAndroidAppFunction:: + ManagementCanInstallReplacementAndroidAppFunction() {} + +ManagementCanInstallReplacementAndroidAppFunction:: + ~ManagementCanInstallReplacementAndroidAppFunction() {} + +ExtensionFunction::ResponseAction +ManagementCanInstallReplacementAndroidAppFunction::Run() { + if (ExtensionsBrowserClient::Get()->IsRunningInForcedAppMode()) + return RespondNow(Error(keys::kNotAllowedInKioskError)); + + if (!extension()->from_webstore()) { + return RespondNow( + Error(keys::kInstallReplacementAndroidAppNotFromWebstoreError)); + } + + auto* api_delegate = ManagementAPI::GetFactoryInstance() + ->Get(browser_context()) + ->GetDelegate(); + + DCHECK(api_delegate); + + if (!api_delegate->CanContextInstallAndroidApps(browser_context())) { + return RespondNow(ArgumentList( + management::CanInstallReplacementAndroidApp::Results::Create(false))); + } + + DCHECK(ReplacementAppsInfo::HasReplacementAndroidApp(extension())); + + const std::string& package_name = + ReplacementAppsInfo::GetReplacementAndroidApp(extension()); + + api_delegate->CheckAndroidAppInstallStatus( + package_name, + base::BindOnce(&ManagementCanInstallReplacementAndroidAppFunction:: + OnFinishedAndroidAppCheck, + this)); + + // Response is sent async in FinishCheckAndroidApp(). + return RespondLater(); +} + +void ManagementCanInstallReplacementAndroidAppFunction:: + OnFinishedAndroidAppCheck(bool installable) { + Respond( + ArgumentList(management::CanInstallReplacementAndroidApp::Results::Create( + installable))); +} + +ManagementInstallReplacementAndroidAppFunction:: + ManagementInstallReplacementAndroidAppFunction() {} + +ManagementInstallReplacementAndroidAppFunction:: + ~ManagementInstallReplacementAndroidAppFunction() {} + +ExtensionFunction::ResponseAction +ManagementInstallReplacementAndroidAppFunction::Run() { + if (ExtensionsBrowserClient::Get()->IsRunningInForcedAppMode()) + return RespondNow(Error(keys::kNotAllowedInKioskError)); + + if (!extension()->from_webstore()) { + return RespondNow( + Error(keys::kInstallReplacementAndroidAppNotFromWebstoreError)); + } + + if (!user_gesture()) { + return RespondNow( + Error(keys::kGestureNeededForInstallReplacementAndroidAppError)); + } + + auto* api_delegate = ManagementAPI::GetFactoryInstance() + ->Get(browser_context()) + ->GetDelegate(); + + DCHECK(api_delegate); + if (!api_delegate->CanContextInstallAndroidApps(browser_context())) { + return RespondNow( + Error(keys::kInstallReplacementAndroidAppInvalidContextError)); + } + + DCHECK(ReplacementAppsInfo::HasReplacementAndroidApp(extension())); + + api_delegate->InstallReplacementAndroidApp( + ReplacementAppsInfo::GetReplacementAndroidApp(extension()), + base::BindOnce(&ManagementInstallReplacementAndroidAppFunction:: + OnAppInstallInitiated, + this)); + + // Response is sent async in OnAppInstallInitiated(). + return RespondLater(); +} + +void ManagementInstallReplacementAndroidAppFunction::OnAppInstallInitiated( + bool initiated) { + if (!initiated) + return Respond(Error(keys::kInstallReplacementAndroidAppCannotInstallApp)); + + return Respond(NoArguments()); +} + ManagementInstallReplacementWebAppFunction:: ManagementInstallReplacementWebAppFunction() {} @@ -873,14 +973,6 @@ return RespondLater(); } -ManagementEventRouter::ManagementEventRouter(content::BrowserContext* context) - : browser_context_(context), extension_registry_observer_(this) { - extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); -} - -ManagementEventRouter::~ManagementEventRouter() { -} - void ManagementInstallReplacementWebAppFunction::FinishCreateWebApp( ManagementAPIDelegate::InstallWebAppResult result) { ResponseValue response; @@ -897,6 +989,13 @@ Respond(std::move(response)); } +ManagementEventRouter::ManagementEventRouter(content::BrowserContext* context) + : browser_context_(context), extension_registry_observer_(this) { + extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); +} + +ManagementEventRouter::~ManagementEventRouter() {} + void ManagementEventRouter::OnExtensionLoaded( content::BrowserContext* browser_context, const Extension* extension) {
diff --git a/extensions/browser/api/management/management_api.h b/extensions/browser/api/management/management_api.h index 7b802e4..d51007f 100644 --- a/extensions/browser/api/management/management_api.h +++ b/extensions/browser/api/management/management_api.h
@@ -214,6 +214,40 @@ std::unique_ptr<AppForLinkDelegate> app_for_link_delegate_; }; +class ManagementCanInstallReplacementAndroidAppFunction + : public ExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION("management.canInstallReplacementAndroidApp", + MANAGEMENT_CANINSTALLREPLACEMENTANDROIDAPP) + + ManagementCanInstallReplacementAndroidAppFunction(); + + protected: + ~ManagementCanInstallReplacementAndroidAppFunction() override; + + ResponseAction Run() override; + + private: + void OnFinishedAndroidAppCheck(bool result); +}; + +class ManagementInstallReplacementAndroidAppFunction + : public ExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION("management.installReplacementAndroidApp", + MANAGEMENT_INSTALLREPLACEMENTANDROIDAPP) + + ManagementInstallReplacementAndroidAppFunction(); + + protected: + ~ManagementInstallReplacementAndroidAppFunction() override; + + ResponseAction Run() override; + + private: + void OnAppInstallInitiated(bool installable); +}; + class ManagementInstallReplacementWebAppFunction : public ExtensionFunction { public: DECLARE_EXTENSION_FUNCTION("management.installReplacementWebApp",
diff --git a/extensions/browser/api/management/management_api_constants.cc b/extensions/browser/api/management/management_api_constants.cc index 24136b3..873662d148 100644 --- a/extensions/browser/api/management/management_api_constants.cc +++ b/extensions/browser/api/management/management_api_constants.cc
@@ -57,5 +57,13 @@ "Only extensions from the web store can install replacement web apps."; const char kGestureNeededForInstallReplacementWebAppError[] = "chrome.management.installReplacementWebApp requires a user gesture."; +const char kGestureNeededForInstallReplacementAndroidAppError[] = + "chrome.management.installReplacementAndroidApp requires a user gesture."; +const char kInstallReplacementAndroidAppInvalidContextError[] = + "Android apps can't be installed in the current user profile."; +const char kInstallReplacementAndroidAppNotFromWebstoreError[] = + "Only extensions from the web store can install replacement Android apps."; +const char kInstallReplacementAndroidAppCannotInstallApp[] = + "Could not install Android App."; } // namespace extension_management_api_constants
diff --git a/extensions/browser/api/management/management_api_constants.h b/extensions/browser/api/management/management_api_constants.h index 643fd08..79a46da 100644 --- a/extensions/browser/api/management/management_api_constants.h +++ b/extensions/browser/api/management/management_api_constants.h
@@ -41,6 +41,10 @@ extern const char kInstallReplacementWebAppInvalidContextError[]; extern const char kInstallReplacementWebAppNotFromWebstoreError[]; extern const char kGestureNeededForInstallReplacementWebAppError[]; +extern const char kGestureNeededForInstallReplacementAndroidAppError[]; +extern const char kInstallReplacementAndroidAppCannotInstallApp[]; +extern const char kInstallReplacementAndroidAppInvalidContextError[]; +extern const char kInstallReplacementAndroidAppNotFromWebstoreError[]; } // namespace extension_management_api_constants
diff --git a/extensions/browser/api/management/management_api_delegate.h b/extensions/browser/api/management/management_api_delegate.h index 0fce178..03eb0146 100644 --- a/extensions/browser/api/management/management_api_delegate.h +++ b/extensions/browser/api/management/management_api_delegate.h
@@ -49,6 +49,9 @@ public: virtual ~ManagementAPIDelegate() {} + using AndroidAppInstallStatusCallback = base::OnceCallback<void(bool)>; + using InstallAndroidAppCallback = base::OnceCallback<void(bool)>; + enum class InstallWebAppResult { kSuccess, kInvalidWebApp, kUnknownError }; typedef base::OnceCallback<void(InstallWebAppResult)> InstallWebAppCallback; @@ -134,6 +137,20 @@ const GURL& web_app_url, InstallWebAppCallback callback) const = 0; + // Returns whether arc apps can be installed in the given |context|. + virtual bool CanContextInstallAndroidApps( + content::BrowserContext* context) const = 0; + + // Checks the installation status of |package_name|. + virtual void CheckAndroidAppInstallStatus( + const std::string& package_name, + AndroidAppInstallStatusCallback callback) const = 0; + + // Installs an Arc app for |package_name|. + virtual void InstallReplacementAndroidApp( + const std::string& package_name, + InstallAndroidAppCallback callback) const = 0; + // Forwards the call to ExtensionIconSource::GetIconURL in chrome. virtual GURL GetIconURL(const Extension* extension, int icon_size,
diff --git a/extensions/browser/api/web_request/web_request_info.cc b/extensions/browser/api/web_request/web_request_info.cc index c18a61a..a330972 100644 --- a/extensions/browser/api/web_request/web_request_info.cc +++ b/extensions/browser/api/web_request/web_request_info.cc
@@ -179,7 +179,7 @@ else if (is_download) web_request_type = WebRequestResourceType::OTHER; else - web_request_type = ToWebRequestResourceType(type.value()); + web_request_type = ToWebRequestResourceType(type); InitializeWebViewAndFrameData(navigation_ui_data.get());
diff --git a/extensions/browser/api/web_request/web_request_info.h b/extensions/browser/api/web_request/web_request_info.h index c4f6ae0..bbe9337 100644 --- a/extensions/browser/api/web_request/web_request_info.h +++ b/extensions/browser/api/web_request/web_request_info.h
@@ -62,7 +62,7 @@ std::string method; bool is_navigation_request = false; base::Optional<url::Origin> initiator; - base::Optional<content::ResourceType> type; + content::ResourceType type = content::ResourceType::kSubResource; WebRequestResourceType web_request_type = WebRequestResourceType::OTHER; bool is_async = false; net::HttpRequestHeaders extra_request_headers; @@ -123,9 +123,8 @@ // initiate this request. ExtensionApiFrameIdMap::FrameData frame_data; - // The type of the request (e.g. main frame, subresource, XHR, etc). May have - // no value if the request did not originate from a ResourceDispatcher. - const base::Optional<content::ResourceType> type; + // The type of the request (e.g. main frame, subresource, XHR, etc). + const content::ResourceType type; // A partially mirrored copy of |type| which is slightly less granular and // which also identifies WebSocket requests separately from other types.
diff --git a/extensions/browser/api/web_request/web_request_permissions.cc b/extensions/browser/api/web_request/web_request_permissions.cc index bf4d32f..8eb46c35 100644 --- a/extensions/browser/api/web_request/web_request_permissions.cc +++ b/extensions/browser/api/web_request/web_request_permissions.cc
@@ -336,7 +336,7 @@ bool crosses_incognito, HostPermissionsCheck host_permissions_check, const base::Optional<url::Origin>& initiator, - const base::Optional<content::ResourceType>& resource_type) { + content::ResourceType resource_type) { return CanExtensionAccessURLInternal( permission_helper, extension_id, url, tab_id, crosses_incognito, host_permissions_check, initiator, resource_type);
diff --git a/extensions/browser/api/web_request/web_request_permissions.h b/extensions/browser/api/web_request/web_request_permissions.h index e8dc992..6b7b172 100644 --- a/extensions/browser/api/web_request/web_request_permissions.h +++ b/extensions/browser/api/web_request/web_request_permissions.h
@@ -56,7 +56,7 @@ bool crosses_incognito, HostPermissionsCheck host_permissions_check, const base::Optional<url::Origin>& initiator, - const base::Optional<content::ResourceType>& resource_type); + content::ResourceType resource_type); static bool CanExtensionAccessInitiator( extensions::PermissionHelper* permission_helper,
diff --git a/extensions/browser/api/web_request/web_request_permissions_unittest.cc b/extensions/browser/api/web_request/web_request_permissions_unittest.cc index 04e2cd26..d195edac 100644 --- a/extensions/browser/api/web_request/web_request_permissions_unittest.cc +++ b/extensions/browser/api/web_request/web_request_permissions_unittest.cc
@@ -209,8 +209,7 @@ auto get_access = [extension, this]( const GURL& url, const base::Optional<url::Origin>& initiator, - const base::Optional<content::ResourceType>& - resource_type) { + const content::ResourceType resource_type) { constexpr int kTabId = 42; constexpr WebRequestPermissions::HostPermissionsCheck kPermissionsCheck = WebRequestPermissions::REQUIRE_HOST_PERMISSION_FOR_URL; @@ -228,9 +227,8 @@ GURL urls[] = {example_com, chromium_org}; base::Optional<url::Origin> initiators[] = {base::nullopt, example_com_origin, chromium_org_origin}; - base::Optional<content::ResourceType> resource_types[] = { - base::nullopt, content::ResourceType::kSubResource, - content::ResourceType::kMainFrame}; + content::ResourceType resource_types[] = {content::ResourceType::kSubResource, + content::ResourceType::kMainFrame}; // With all permissions withheld, the result of any request should be // kWithheld. @@ -270,8 +268,6 @@ EXPECT_EQ(PermissionsData::PageAccess::kAllowed, get_access(example_com, chromium_org_origin, content::ResourceType::kSubResource)); - EXPECT_EQ(PermissionsData::PageAccess::kAllowed, - get_access(example_com, chromium_org_origin, base::nullopt)); EXPECT_EQ(PermissionsData::PageAccess::kWithheld, get_access(example_com, chromium_org_origin, content::ResourceType::kSubFrame)); @@ -322,8 +318,7 @@ auto get_access = [extension, this]( const GURL& url, const base::Optional<url::Origin>& initiator, - const base::Optional<content::ResourceType>& - resource_type) { + content::ResourceType resource_type) { constexpr int kTabId = 42; constexpr WebRequestPermissions::HostPermissionsCheck kPermissionsCheck = WebRequestPermissions::REQUIRE_HOST_PERMISSION_FOR_URL_AND_INITIATOR; @@ -380,8 +375,6 @@ EXPECT_EQ(get_access(test_case.url, test_case.initiator, content::ResourceType::kSubResource), test_case.expected_access_subresource); - EXPECT_EQ(get_access(test_case.url, test_case.initiator, base::nullopt), - test_case.expected_access_subresource); EXPECT_EQ(get_access(test_case.url, test_case.initiator, content::ResourceType::kSubFrame), test_case.expected_access_navigation);
diff --git a/extensions/browser/extension_event_histogram_value.h b/extensions/browser/extension_event_histogram_value.h index 665e37e..0403f0a 100644 --- a/extensions/browser/extension_event_histogram_value.h +++ b/extensions/browser/extension_event_histogram_value.h
@@ -363,7 +363,8 @@ TYPES_CHROME_SETTING_ON_CHANGE = 342, DELETED_TYPES_PRIVATE_CHROME_DIRECT_SETTING_ON_CHANGE = 343, WEB_VIEW_INTERNAL_ON_MESSAGE = 344, - EXTENSION_VIEW_INTERNAL_ON_LOAD_COMMIT = 345, + // Obsolete: crbug.com/982858 + DELETED_EXTENSION_VIEW_INTERNAL_ON_LOAD_COMMIT = 345, RUNTIME_ON_REQUEST = 346, RUNTIME_ON_REQUEST_EXTERNAL = 347, CHROME_WEB_VIEW_INTERNAL_ON_CONTEXT_MENU_SHOW = 348,
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h index e4b0ca2..69e40ad 100644 --- a/extensions/browser/extension_function_histogram_value.h +++ b/extensions/browser/extension_function_histogram_value.h
@@ -1012,7 +1012,7 @@ FILESYSTEMPROVIDER_GET = 951, FILEMANAGERPRIVATE_SEARCHFILESBYHASHES = 952, DELETED_EASYUNLOCKPRIVATE_SHOWERRORBUBBLE = 953, - EXTENSIONVIEWINTERNAL_NAVIGATE = 954, + DELETED_EXTENSIONVIEWINTERNAL_NAVIGATE = 954, // Obsolete: crbug.com/982858 NETWORKING_CONFIG_SETNETWORKFILTER = 955, NETWORKING_CONFIG_FINISHAUTHENTICATION = 956, PLATFORMKEYSINTERNAL_SELECTCLIENTCERTIFICATES = 957, @@ -1113,8 +1113,8 @@ WEBCAMPRIVATE_CLOSEWEBCAM = 1052, SERIAL_SETBREAK = 1053, SERIAL_CLEARBREAK = 1054, - EXTENSIONVIEWINTERNAL_LOADSRC = 1055, - EXTENSIONVIEWINTERNAL_PARSESRC = 1056, + DELETED_EXTENSIONVIEWINTERNAL_LOADSRC = 1055, // Obsolete: crbug.com/982858 + DELETED_EXTENSIONVIEWINTERNAL_PARSESRC = 1056, // Obsolete: crbug.com/982858 HID_GETUSERSELECTEDDEVICES = 1057, FILESYSTEMPROVIDERINTERNAL_GETACTIONSREQUESTEDSUCCESS = 1058, DASHBOARDPRIVATE_SHOWPERMISSIONPROMPTFORDELEGATEDBUNDLEINSTALL = 1059, @@ -1427,6 +1427,8 @@ ACTION_DISABLE = 1364, FILEMANAGERPRIVATEINTERNAL_IMPORTCROSTINIIMAGE = 1365, AUTOTESTPRIVATE_GETSHELFITEMS = 1366, + MANAGEMENT_INSTALLREPLACEMENTANDROIDAPP = 1367, + MANAGEMENT_CANINSTALLREPLACEMENTANDROIDAPP = 1368, // Last entry: Add new entries above, then run: // python tools/metrics/histograms/update_extension_histograms.py ENUM_BOUNDARY
diff --git a/extensions/browser/guest_view/extension_view/extension_view_constants.cc b/extensions/browser/guest_view/extension_view/extension_view_constants.cc deleted file mode 100644 index 49adead0..0000000 --- a/extensions/browser/guest_view/extension_view/extension_view_constants.cc +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "extensions/browser/guest_view/extension_view/extension_view_constants.h" - -namespace extensionview { - -// API namespace. -const char kAPINamespace[] = "extensionViewInternal"; - -// Attributes. -const char kAttributeExtension[] = "extension"; -const char kAttributeSrc[] = "src"; - -// Events. -const char kEventLoadCommit[] = "extensionViewInternal.onLoadCommit"; - -} // namespace extensionview
diff --git a/extensions/browser/guest_view/extension_view/extension_view_constants.h b/extensions/browser/guest_view/extension_view/extension_view_constants.h deleted file mode 100644 index cbfd7e20..0000000 --- a/extensions/browser/guest_view/extension_view/extension_view_constants.h +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef EXTENSIONS_BROWSER_GUEST_VIEW_EXTENSION_VIEW_EXTENSION_VIEW_CONSTANTS_H_ -#define EXTENSIONS_BROWSER_GUEST_VIEW_EXTENSION_VIEW_EXTENSION_VIEW_CONSTANTS_H_ - -namespace extensionview { - -// API namespace. -extern const char kAPINamespace[]; - -// Attributes. -extern const char kAttributeExtension[]; -extern const char kAttributeSrc[]; - -// Events. -extern const char kEventLoadCommit[]; - -} // namespace extensionview - -#endif // EXTENSIONS_BROWSER_GUEST_VIEW_EXTENSION_VIEW_EXTENSION_VIEW_CONSTANTS_H_
diff --git a/extensions/browser/guest_view/extension_view/extension_view_guest.cc b/extensions/browser/guest_view/extension_view/extension_view_guest.cc deleted file mode 100644 index 7b6f2054..0000000 --- a/extensions/browser/guest_view/extension_view/extension_view_guest.cc +++ /dev/null
@@ -1,139 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "extensions/browser/guest_view/extension_view/extension_view_guest.h" - -#include <memory> -#include <string> -#include <utility> - -#include "components/crx_file/id_util.h" -#include "components/guest_view/browser/guest_view_event.h" -#include "content/public/browser/navigation_handle.h" -#include "content/public/browser/render_frame_host.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/common/result_codes.h" -#include "extensions/browser/api/extensions_api_client.h" -#include "extensions/browser/bad_message.h" -#include "extensions/browser/guest_view/extension_view/extension_view_constants.h" -#include "extensions/browser/guest_view/extension_view/whitelist/extension_view_whitelist.h" -#include "extensions/common/constants.h" -#include "extensions/common/extension_messages.h" -#include "extensions/strings/grit/extensions_strings.h" -#include "url/origin.h" - -using content::WebContents; -using guest_view::GuestViewBase; -using guest_view::GuestViewEvent; - -namespace extensions { - -// static -const char ExtensionViewGuest::Type[] = "extensionview"; - -ExtensionViewGuest::ExtensionViewGuest(WebContents* owner_web_contents) - : GuestView<ExtensionViewGuest>(owner_web_contents) {} - -ExtensionViewGuest::~ExtensionViewGuest() { -} - -// static -GuestViewBase* ExtensionViewGuest::Create(WebContents* owner_web_contents) { - return new ExtensionViewGuest(owner_web_contents); -} - -bool ExtensionViewGuest::NavigateGuest(const std::string& src, - bool force_navigation) { - GURL url = extension_url_.Resolve(src); - - // If the URL is not valid, about:blank, or the same origin as the extension, - // then navigate to about:blank. - bool url_not_allowed = - url != url::kAboutBlankURL && !url::IsSameOriginWith(url, extension_url_); - if (!url.is_valid() || url_not_allowed) - return NavigateGuest(url::kAboutBlankURL, true /* force_navigation */); - - if (!force_navigation && (url_ == url)) - return false; - - web_contents()->GetMainFrame()->GetProcess()->FilterURL(false, &url); - web_contents()->GetController().LoadURL(url, content::Referrer(), - ui::PAGE_TRANSITION_AUTO_TOPLEVEL, - std::string()); - - url_ = url; - return true; -} - -// GuestViewBase implementation. -void ExtensionViewGuest::CreateWebContents( - const base::DictionaryValue& create_params, - WebContentsCreatedCallback callback) { - // Gets the extension ID. - std::string extension_id; - create_params.GetString(extensionview::kAttributeExtension, &extension_id); - - if (!crx_file::id_util::IdIsValid(extension_id) || - !IsExtensionIdWhitelisted(extension_id)) { - std::move(callback).Run(nullptr); - return; - } - - // Gets the extension URL. - extension_url_ = - extensions::Extension::GetBaseURLFromExtensionId(extension_id); - - if (!extension_url_.is_valid()) { - std::move(callback).Run(nullptr); - return; - } - - WebContents::CreateParams params( - browser_context(), - content::SiteInstance::CreateForURL(browser_context(), extension_url_)); - params.guest_delegate = this; - // TODO(erikchen): Fix ownership semantics for guest views. - // https://crbug.com/832879. - std::move(callback).Run(WebContents::Create(params).release()); -} - -void ExtensionViewGuest::DidInitialize( - const base::DictionaryValue& create_params) { - ExtensionsAPIClient::Get()->AttachWebContentsHelpers(web_contents()); - - ApplyAttributes(create_params); -} - -void ExtensionViewGuest::DidAttachToEmbedder() { - ApplyAttributes(*attach_params()); -} - -const char* ExtensionViewGuest::GetAPINamespace() const { - return extensionview::kAPINamespace; -} - -int ExtensionViewGuest::GetTaskPrefix() const { - return IDS_EXTENSION_TASK_MANAGER_EXTENSIONVIEW_TAG_PREFIX; -} - -void ExtensionViewGuest::DidFinishNavigation( - content::NavigationHandle* navigation_handle) { - if (!navigation_handle->HasCommitted() || !navigation_handle->IsInMainFrame()) - return; - - url_ = navigation_handle->GetURL(); - - std::unique_ptr<base::DictionaryValue> args(new base::DictionaryValue()); - args->SetString(guest_view::kUrl, url_.spec()); - DispatchEventToView(std::make_unique<GuestViewEvent>( - extensionview::kEventLoadCommit, std::move(args))); -} - -void ExtensionViewGuest::ApplyAttributes(const base::DictionaryValue& params) { - std::string src; - params.GetString(extensionview::kAttributeSrc, &src); - NavigateGuest(src, false /* force_navigation */); -} - -} // namespace extensions
diff --git a/extensions/browser/guest_view/extension_view/extension_view_guest.h b/extensions/browser/guest_view/extension_view/extension_view_guest.h deleted file mode 100644 index 2b32890..0000000 --- a/extensions/browser/guest_view/extension_view/extension_view_guest.h +++ /dev/null
@@ -1,55 +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 EXTENSIONS_BROWSER_GUEST_VIEW_EXTENSION_VIEW_EXTENSION_VIEW_GUEST_H_ -#define EXTENSIONS_BROWSER_GUEST_VIEW_EXTENSION_VIEW_EXTENSION_VIEW_GUEST_H_ - -#include "base/macros.h" -#include "components/guest_view/browser/guest_view.h" -#include "extensions/browser/extension_function_dispatcher.h" -#include "url/gurl.h" - -namespace extensions { - -class ExtensionViewGuest - : public guest_view::GuestView<ExtensionViewGuest> { - public: - static const char Type[]; - static guest_view::GuestViewBase* Create( - content::WebContents* owner_web_contents); - - // Request navigating the guest to the provided |src| URL. - // Returns true if the navigation is successful. - bool NavigateGuest(const std::string& src, bool force_navigation); - - private: - ExtensionViewGuest(content::WebContents* owner_web_contents); - ~ExtensionViewGuest() override; - - // GuestViewBase implementation. - void CreateWebContents(const base::DictionaryValue& create_params, - WebContentsCreatedCallback callback) final; - void DidInitialize(const base::DictionaryValue& create_params) final; - void DidAttachToEmbedder() final; - const char* GetAPINamespace() const final; - int GetTaskPrefix() const final; - - // content::WebContentsObserver implementation. - void DidFinishNavigation(content::NavigationHandle* navigation_handle) final; - - // Applies attributes to the extensionview. - void ApplyAttributes(const base::DictionaryValue& params); - - // The full URL that the extensionview is currently navigated to. - GURL url_; - - // The extension URL, including the extension scheme and extension ID. - GURL extension_url_; - - DISALLOW_COPY_AND_ASSIGN(ExtensionViewGuest); -}; - -} // namespace extensions - -#endif // EXTENSIONS_BROWSER_GUEST_VIEW_EXTENSION_VIEW_EXTENSION_VIEW_GUEST_H_
diff --git a/extensions/browser/guest_view/extension_view/whitelist/OWNERS b/extensions/browser/guest_view/extension_view/whitelist/OWNERS deleted file mode 100644 index c7ff256..0000000 --- a/extensions/browser/guest_view/extension_view/whitelist/OWNERS +++ /dev/null
@@ -1,8 +0,0 @@ -# Whitelisting new extension ids for ExtensionView use requires approval from -# chrome-eng-review@google.com. -set noparent - -file://ENG_REVIEW_OWNERS - -# TEAM: extensions-dev@chromium.org -# COMPONENT: Platform>Extensions
diff --git a/extensions/browser/guest_view/extension_view/whitelist/extension_view_whitelist.cc b/extensions/browser/guest_view/extension_view/whitelist/extension_view_whitelist.cc deleted file mode 100644 index a83a476..0000000 --- a/extensions/browser/guest_view/extension_view/whitelist/extension_view_whitelist.cc +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "extensions/browser/guest_view/extension_view/whitelist/extension_view_whitelist.h" - -#include <stddef.h> - -#include "base/logging.h" -#include "base/stl_util.h" - -namespace extensions { - -namespace { - -// ============================================================================= -// -// ADDING NEW EXTENSIONS REQUIRES APPROVAL from chrome-eng-review@google.com -// -// ============================================================================= - -const char* const kWhitelist[] = { - "pemeknaakobkocgmimdeamlcklioagkh", // Used in browser tests - "dppcjffonoklmpdmljnpdojmoaefcabf", // Used in browser tests - "enhhojjnijigcajfphajepfemndkmdlo", // Media Router Dev - "pkedcjkdefgpdelpbcmbmeomcjbeemfm", // Media Router Stable -}; - -} // namespace - -// static -bool IsExtensionIdWhitelisted(const std::string& extension_id) { - for (size_t i = 0; i < base::size(kWhitelist); ++i) { - if (extension_id == kWhitelist[i]) - return true; - } - - return false; -} - -} // namespace extensions
diff --git a/extensions/browser/guest_view/extension_view/whitelist/extension_view_whitelist.h b/extensions/browser/guest_view/extension_view/whitelist/extension_view_whitelist.h deleted file mode 100644 index 512600b..0000000 --- a/extensions/browser/guest_view/extension_view/whitelist/extension_view_whitelist.h +++ /dev/null
@@ -1,17 +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 EXTENSIONS_BROWSER_GUEST_VIEW_EXTENSION_VIEW_WHITELIST_EXTENSION_VIEW_WHITELIST_H_ -#define EXTENSIONS_BROWSER_GUEST_VIEW_EXTENSION_VIEW_WHITELIST_EXTENSION_VIEW_WHITELIST_H_ - -#include <string> - -namespace extensions { - -// Checks whether |extension_id| is whitelisted to be used by ExtensionView. -bool IsExtensionIdWhitelisted(const std::string& extension_id); - -} // namespace extensions - -#endif // EXTENSIONS_BROWSER_GUEST_VIEW_EXTENSION_VIEW_WHITELIST_EXTENSION_VIEW_WHITELIST_H_
diff --git a/extensions/browser/guest_view/extensions_guest_view_manager_delegate.cc b/extensions/browser/guest_view/extensions_guest_view_manager_delegate.cc index 8558d4a..5fe6992 100644 --- a/extensions/browser/guest_view/extensions_guest_view_manager_delegate.cc +++ b/extensions/browser/guest_view/extensions_guest_view_manager_delegate.cc
@@ -19,7 +19,6 @@ #include "extensions/browser/event_router.h" #include "extensions/browser/guest_view/app_view/app_view_guest.h" #include "extensions/browser/guest_view/extension_options/extension_options_guest.h" -#include "extensions/browser/guest_view/extension_view/extension_view_guest.h" #include "extensions/browser/guest_view/guest_view_events.h" #include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h" #include "extensions/browser/guest_view/web_view/web_view_guest.h" @@ -114,7 +113,6 @@ GuestViewManager* manager = GuestViewManager::FromBrowserContext(context_); manager->RegisterGuestViewType<AppViewGuest>(); manager->RegisterGuestViewType<ExtensionOptionsGuest>(); - manager->RegisterGuestViewType<ExtensionViewGuest>(); manager->RegisterGuestViewType<MimeHandlerViewGuest>(); manager->RegisterGuestViewType<WebViewGuest>(); }
diff --git a/extensions/browser/guest_view/guest_view_events.cc b/extensions/browser/guest_view/guest_view_events.cc index 36da971..3b42d33 100644 --- a/extensions/browser/guest_view/guest_view_events.cc +++ b/extensions/browser/guest_view/guest_view_events.cc
@@ -10,7 +10,6 @@ #include "base/macros.h" #include "components/guest_view/common/guest_view_constants.h" #include "extensions/browser/guest_view/extension_options/extension_options_constants.h" -#include "extensions/browser/guest_view/extension_view/extension_view_constants.h" #include "extensions/browser/guest_view/web_view/web_view_constants.h" #include "extensions/common/api/extension_options_internal.h" @@ -34,8 +33,6 @@ events::EXTENSION_OPTIONS_INTERNAL_ON_LOAD}, {api::extension_options_internal::OnPreferredSizeChanged::kEventName, events::EXTENSION_OPTIONS_INTERNAL_ON_PREFERRED_SIZE_CHANGED}, - {extensionview::kEventLoadCommit, - events::EXTENSION_VIEW_INTERNAL_ON_LOAD_COMMIT}, {guest_view::kEventResize, events::GUEST_VIEW_INTERNAL_ON_RESIZE}, {webview::kEventAudioStateChanged, events::WEB_VIEW_INTERNAL_ON_AUDIO_STATE_CHANGED},
diff --git a/extensions/common/api/_api_features.json b/extensions/common/api/_api_features.json index 97baa25..35a6308e 100644 --- a/extensions/common/api/_api_features.json +++ b/extensions/common/api/_api_features.json
@@ -195,18 +195,6 @@ "extension_types": ["extension", "legacy_packaged_app", "platform_app"], "contexts": ["blessed_extension"] }, - "extensionViewInternal": [ - { - "internal": true, - "contexts": ["blessed_extension"], - "dependencies": ["permission:extensionview"] - }, { - "internal": true, - "channel": "stable", - "contexts": ["webui"], - "matches": ["chrome://cast/*"] - } - ], "events": { "internal": true, "channel": "stable", @@ -302,6 +290,17 @@ "channel": "stable", "extension_types": ["extension", "legacy_packaged_app", "platform_app"] }, + "management.canInstallReplacementAndroidApp": { + "dependencies": ["manifest:replacement_android_app"], + // TODO(jshikaram): add test coverage before trunk promotion. + "channel": "trunk", + "extension_types": ["platform_app"] + }, + "management.installReplacementAndroidApp": { + "dependencies": ["manifest:replacement_android_app"], + "channel": "trunk", + "extension_types": ["platform_app"] + }, "management.installReplacementWebApp": { "dependencies": ["manifest:replacement_web_app"], "channel": "stable",
diff --git a/extensions/common/api/_permission_features.json b/extensions/common/api/_permission_features.json index eff2ba43..9663eda0 100644 --- a/extensions/common/api/_permission_features.json +++ b/extensions/common/api/_permission_features.json
@@ -252,14 +252,6 @@ "extension_types": ["extension", "platform_app"], "platforms": ["chromeos"] }, - "extensionview": { - "channel": "stable", - "extension_types": ["platform_app"], - "whitelist": [ - // Used in browser tests: http://crbug.com/515284 - "BD2EB5085B5324203BCCC3DF3CF102B8AB850402" - ] - }, "externally_connectable.all_urls": { "channel": "stable", "extension_types": [
diff --git a/extensions/common/api/declarative_net_request.idl b/extensions/common/api/declarative_net_request.idl index baccaec..f255773 100644 --- a/extensions/common/api/declarative_net_request.idl +++ b/extensions/common/api/declarative_net_request.idl
@@ -56,17 +56,13 @@ removeHeaders }; - // TODO(crbug.com/983685): Remove nodoc. // Represents a query key-value pair. - [nodoc] dictionary QueryKeyValue { DOMString key; DOMString value; }; - // TODO(crbug.com/983685): Remove nodoc. // Describes modification to the url query. - [nodoc] dictionary QueryTransform { // The list of query keys to be removed. DOMString[]? removeParams; @@ -74,9 +70,7 @@ QueryKeyValue[]? addOrReplaceParams; }; - // TODO(crbug.com/983685): Remove nodoc. // Describes modification to various url components. - [nodoc] dictionary URLTransform { // The new scheme for the request. DOMString? scheme; @@ -88,8 +82,6 @@ DOMString? port; // The new path for the request. If empty, the existing path is cleared. - // For urls with schemes like "http" or "https", this should include the - // preceding slash '/'. DOMString? path; // The new query for the request. Should be either empty, in which case the @@ -110,8 +102,6 @@ DOMString? password; }; - // TODO(crbug.com/983685): Remove nodoc. - [nodoc] dictionary Redirect { // Path relative to the extension directory. Should start with '/'. DOMString? extensionPath; @@ -193,15 +183,8 @@ // The type of action to perform. RuleActionType type; - // The redirect url. Only valid if RuleActionType is "redirect". Can be - // specified as an absolute url or a relative url (starting with '/'), which - // is relative to the extension which specified the rule. - DOMString? redirectUrl; - - // TODO(crbug.com/983685): Remove nodoc. // Describes how the redirect should be performed. Only valid for redirect // rules. - [nodoc] Redirect? redirect; // The headers to remove from the request. Only valid if RuleActionType is
diff --git a/extensions/common/api/declarative_net_request/constants.cc b/extensions/common/api/declarative_net_request/constants.cc index 74a0efa..7e01c4f9 100644 --- a/extensions/common/api/declarative_net_request/constants.cc +++ b/extensions/common/api/declarative_net_request/constants.cc
@@ -22,7 +22,6 @@ const char kExcludedResourceTypesKey[] = "excludedResourceTypes"; const char kDomainTypeKey[] = "domainType"; const char kRuleActionTypeKey[] = "type"; -const char kRedirectUrlKey[] = "redirectUrl"; const char kRemoveHeadersListKey[] = "removeHeadersList"; const char kRedirectPath[] = "action.redirect"; const char kExtensionPathPath[] = "action.redirect.extensionPath"; @@ -32,6 +31,24 @@ const char kTransformFragmentPath[] = "action.redirect.transform.fragment"; const char kTransformQueryTransformPath[] = "action.redirect.transform.queryTransform"; +const char kRedirectKey[] = "redirect"; +const char kExtensionPathKey[] = "extensionPath"; +const char kRedirectUrlKey[] = "url"; +const char kRedirectUrlPath[] = "action.redirect.url"; +const char kTransformKey[] = "transform"; +const char kTransformSchemeKey[] = "scheme"; +const char kTransformHostKey[] = "host"; +const char kTransformPortKey[] = "port"; +const char kTransformPathKey[] = "path"; +const char kTransformQueryKey[] = "query"; +const char kTransformQueryTransformKey[] = "queryTransform"; +const char kTransformFragmentKey[] = "fragment"; +const char kTransformUsernameKey[] = "username"; +const char kTransformPasswordKey[] = "password"; +const char kQueryTransformRemoveParamsKey[] = "removeParams"; +const char kQueryTransformAddReplaceParamsKey[] = "addOrReplaceParams"; +const char kQueryKeyKey[] = "key"; +const char kQueryValueKey[] = "value"; } // namespace declarative_net_request } // namespace extensions
diff --git a/extensions/common/api/declarative_net_request/constants.h b/extensions/common/api/declarative_net_request/constants.h index 7b7c734..f86e3f2 100644 --- a/extensions/common/api/declarative_net_request/constants.h +++ b/extensions/common/api/declarative_net_request/constants.h
@@ -37,7 +37,6 @@ extern const char kExcludedResourceTypesKey[]; extern const char kDomainTypeKey[]; extern const char kRuleActionTypeKey[]; -extern const char kRedirectUrlKey[]; extern const char kRemoveHeadersListKey[]; extern const char kRedirectPath[]; extern const char kExtensionPathPath[]; @@ -46,6 +45,24 @@ extern const char kTransformQueryPath[]; extern const char kTransformFragmentPath[]; extern const char kTransformQueryTransformPath[]; +extern const char kRedirectKey[]; +extern const char kExtensionPathKey[]; +extern const char kRedirectUrlKey[]; +extern const char kRedirectUrlPath[]; +extern const char kTransformKey[]; +extern const char kTransformSchemeKey[]; +extern const char kTransformHostKey[]; +extern const char kTransformPortKey[]; +extern const char kTransformPathKey[]; +extern const char kTransformQueryKey[]; +extern const char kTransformQueryTransformKey[]; +extern const char kTransformFragmentKey[]; +extern const char kTransformUsernameKey[]; +extern const char kTransformPasswordKey[]; +extern const char kQueryTransformRemoveParamsKey[]; +extern const char kQueryTransformAddReplaceParamsKey[]; +extern const char kQueryKeyKey[]; +extern const char kQueryValueKey[]; } // namespace declarative_net_request } // namespace extensions
diff --git a/extensions/common/api/declarative_net_request/test_utils.cc b/extensions/common/api/declarative_net_request/test_utils.cc index 0732b48..f7dec83 100644 --- a/extensions/common/api/declarative_net_request/test_utils.cc +++ b/extensions/common/api/declarative_net_request/test_utils.cc
@@ -21,6 +21,40 @@ const base::FilePath::CharType kBackgroundScriptFilepath[] = FILE_PATH_LITERAL("background.js"); +std::unique_ptr<base::Value> ToValue(const std::string& t) { + return std::make_unique<base::Value>(t); +} + +std::unique_ptr<base::Value> ToValue(int t) { + return std::make_unique<base::Value>(t); +} + +std::unique_ptr<base::Value> ToValue(bool t) { + return std::make_unique<base::Value>(t); +} + +std::unique_ptr<base::Value> ToValue(const DictionarySource& source) { + return source.ToValue(); +} + +template <typename T> +std::unique_ptr<base::Value> ToValue(const std::vector<T>& vec) { + ListBuilder builder; + for (const T& t : vec) + builder.Append(ToValue(t)); + return builder.Build(); +} + +template <typename T> +void SetValue(base::DictionaryValue* dict, + const char* key, + const base::Optional<T>& value) { + if (!value) + return; + + dict->Set(key, ToValue(*value)); +} + } // namespace TestRuleCondition::TestRuleCondition() = default; @@ -30,25 +64,79 @@ default; std::unique_ptr<base::DictionaryValue> TestRuleCondition::ToValue() const { - auto value = std::make_unique<base::DictionaryValue>(); - if (url_filter) - value->SetString(kUrlFilterKey, *url_filter); - if (is_url_filter_case_sensitive) { - value->SetBoolean(kIsUrlFilterCaseSensitiveKey, - *is_url_filter_case_sensitive); - } - if (domains) - value->Set(kDomainsKey, ToListValue(*domains)); - if (excluded_domains) - value->Set(kExcludedDomainsKey, ToListValue(*excluded_domains)); - if (resource_types) - value->Set(kResourceTypesKey, ToListValue(*resource_types)); - if (excluded_resource_types) - value->Set(kExcludedResourceTypesKey, - ToListValue(*excluded_resource_types)); - if (domain_type) - value->SetString(kDomainTypeKey, *domain_type); - return value; + auto dict = std::make_unique<base::DictionaryValue>(); + SetValue(dict.get(), kUrlFilterKey, url_filter); + SetValue(dict.get(), kIsUrlFilterCaseSensitiveKey, + is_url_filter_case_sensitive); + SetValue(dict.get(), kDomainsKey, domains); + SetValue(dict.get(), kExcludedDomainsKey, excluded_domains); + SetValue(dict.get(), kResourceTypesKey, resource_types); + SetValue(dict.get(), kExcludedResourceTypesKey, excluded_resource_types); + SetValue(dict.get(), kDomainTypeKey, domain_type); + return dict; +} + +TestRuleQueryKeyValue::TestRuleQueryKeyValue() = default; +TestRuleQueryKeyValue::~TestRuleQueryKeyValue() = default; +TestRuleQueryKeyValue::TestRuleQueryKeyValue(const TestRuleQueryKeyValue&) = + default; +TestRuleQueryKeyValue& TestRuleQueryKeyValue::operator=( + const TestRuleQueryKeyValue&) = default; + +std::unique_ptr<base::DictionaryValue> TestRuleQueryKeyValue::ToValue() const { + auto dict = std::make_unique<base::DictionaryValue>(); + SetValue(dict.get(), kQueryKeyKey, key); + SetValue(dict.get(), kQueryValueKey, value); + return dict; +} + +TestRuleQueryTransform::TestRuleQueryTransform() = default; +TestRuleQueryTransform::~TestRuleQueryTransform() = default; +TestRuleQueryTransform::TestRuleQueryTransform(const TestRuleQueryTransform&) = + default; +TestRuleQueryTransform& TestRuleQueryTransform::operator=( + const TestRuleQueryTransform&) = default; + +std::unique_ptr<base::DictionaryValue> TestRuleQueryTransform::ToValue() const { + auto dict = std::make_unique<base::DictionaryValue>(); + SetValue(dict.get(), kQueryTransformRemoveParamsKey, remove_params); + SetValue(dict.get(), kQueryTransformAddReplaceParamsKey, + add_or_replace_params); + return dict; +} + +TestRuleTransform::TestRuleTransform() = default; +TestRuleTransform::~TestRuleTransform() = default; +TestRuleTransform::TestRuleTransform(const TestRuleTransform&) = default; +TestRuleTransform& TestRuleTransform::operator=(const TestRuleTransform&) = + default; + +std::unique_ptr<base::DictionaryValue> TestRuleTransform::ToValue() const { + auto dict = std::make_unique<base::DictionaryValue>(); + SetValue(dict.get(), kTransformSchemeKey, scheme); + SetValue(dict.get(), kTransformHostKey, host); + SetValue(dict.get(), kTransformPortKey, port); + SetValue(dict.get(), kTransformPathKey, path); + SetValue(dict.get(), kTransformQueryKey, query); + SetValue(dict.get(), kTransformQueryTransformKey, query_transform); + SetValue(dict.get(), kTransformFragmentKey, fragment); + SetValue(dict.get(), kTransformUsernameKey, username); + SetValue(dict.get(), kTransformPasswordKey, password); + return dict; +} + +TestRuleRedirect::TestRuleRedirect() = default; +TestRuleRedirect::~TestRuleRedirect() = default; +TestRuleRedirect::TestRuleRedirect(const TestRuleRedirect&) = default; +TestRuleRedirect& TestRuleRedirect::operator=(const TestRuleRedirect&) = + default; + +std::unique_ptr<base::DictionaryValue> TestRuleRedirect::ToValue() const { + auto dict = std::make_unique<base::DictionaryValue>(); + SetValue(dict.get(), kExtensionPathKey, extension_path); + SetValue(dict.get(), kTransformKey, transform); + SetValue(dict.get(), kRedirectUrlKey, url); + return dict; } TestRuleAction::TestRuleAction() = default; @@ -57,14 +145,11 @@ TestRuleAction& TestRuleAction::operator=(const TestRuleAction&) = default; std::unique_ptr<base::DictionaryValue> TestRuleAction::ToValue() const { - auto value = std::make_unique<base::DictionaryValue>(); - if (type) - value->SetString(kRuleActionTypeKey, *type); - if (redirect_url) - value->SetString(kRedirectUrlKey, *redirect_url); - if (remove_headers_list) - value->Set(kRemoveHeadersListKey, ToListValue(*remove_headers_list)); - return value; + auto dict = std::make_unique<base::DictionaryValue>(); + SetValue(dict.get(), kRuleActionTypeKey, type); + SetValue(dict.get(), kRemoveHeadersListKey, remove_headers_list); + SetValue(dict.get(), kRedirectKey, redirect); + return dict; } TestRule::TestRule() = default; @@ -73,16 +158,12 @@ TestRule& TestRule::operator=(const TestRule&) = default; std::unique_ptr<base::DictionaryValue> TestRule::ToValue() const { - auto value = std::make_unique<base::DictionaryValue>(); - if (id) - value->SetInteger(kIDKey, *id); - if (priority) - value->SetInteger(kPriorityKey, *priority); - if (condition) - value->Set(kRuleConditionKey, condition->ToValue()); - if (action) - value->Set(kRuleActionKey, action->ToValue()); - return value; + auto dict = std::make_unique<base::DictionaryValue>(); + SetValue(dict.get(), kIDKey, id); + SetValue(dict.get(), kPriorityKey, priority); + SetValue(dict.get(), kRuleConditionKey, condition); + SetValue(dict.get(), kRuleActionKey, action); + return dict; } TestRule CreateGenericRule() {
diff --git a/extensions/common/api/declarative_net_request/test_utils.h b/extensions/common/api/declarative_net_request/test_utils.h index 3ba15f0c..46dce0ad 100644 --- a/extensions/common/api/declarative_net_request/test_utils.h +++ b/extensions/common/api/declarative_net_request/test_utils.h
@@ -22,13 +22,19 @@ namespace extensions { namespace declarative_net_request { +struct DictionarySource { + DictionarySource() = default; + virtual ~DictionarySource() = default; + virtual std::unique_ptr<base::DictionaryValue> ToValue() const = 0; +}; + // Helper structs to simplify building base::Values which can later be used to // serialize to JSON. The generated implementation for the JSON rules schema is // not used since it's not flexible enough to generate the base::Value/JSON we // want for tests. -struct TestRuleCondition { +struct TestRuleCondition : public DictionarySource { TestRuleCondition(); - ~TestRuleCondition(); + ~TestRuleCondition() override; TestRuleCondition(const TestRuleCondition&); TestRuleCondition& operator=(const TestRuleCondition&); @@ -39,24 +45,82 @@ base::Optional<std::vector<std::string>> resource_types; base::Optional<std::vector<std::string>> excluded_resource_types; base::Optional<std::string> domain_type; - std::unique_ptr<base::DictionaryValue> ToValue() const; + + std::unique_ptr<base::DictionaryValue> ToValue() const override; }; -struct TestRuleAction { +struct TestRuleQueryKeyValue : public DictionarySource { + TestRuleQueryKeyValue(); + ~TestRuleQueryKeyValue() override; + TestRuleQueryKeyValue(const TestRuleQueryKeyValue&); + TestRuleQueryKeyValue& operator=(const TestRuleQueryKeyValue&); + + base::Optional<std::string> key; + base::Optional<std::string> value; + + std::unique_ptr<base::DictionaryValue> ToValue() const override; +}; + +struct TestRuleQueryTransform : public DictionarySource { + TestRuleQueryTransform(); + ~TestRuleQueryTransform() override; + TestRuleQueryTransform(const TestRuleQueryTransform&); + TestRuleQueryTransform& operator=(const TestRuleQueryTransform&); + + base::Optional<std::vector<std::string>> remove_params; + base::Optional<std::vector<TestRuleQueryKeyValue>> add_or_replace_params; + + std::unique_ptr<base::DictionaryValue> ToValue() const override; +}; + +struct TestRuleTransform : public DictionarySource { + TestRuleTransform(); + ~TestRuleTransform() override; + TestRuleTransform(const TestRuleTransform&); + TestRuleTransform& operator=(const TestRuleTransform&); + + base::Optional<std::string> scheme; + base::Optional<std::string> host; + base::Optional<std::string> port; + base::Optional<std::string> path; + base::Optional<std::string> query; + base::Optional<TestRuleQueryTransform> query_transform; + base::Optional<std::string> fragment; + base::Optional<std::string> username; + base::Optional<std::string> password; + + std::unique_ptr<base::DictionaryValue> ToValue() const override; +}; + +struct TestRuleRedirect : public DictionarySource { + TestRuleRedirect(); + ~TestRuleRedirect() override; + TestRuleRedirect(const TestRuleRedirect&); + TestRuleRedirect& operator=(const TestRuleRedirect&); + + base::Optional<std::string> extension_path; + base::Optional<TestRuleTransform> transform; + base::Optional<std::string> url; + + std::unique_ptr<base::DictionaryValue> ToValue() const override; +}; + +struct TestRuleAction : public DictionarySource { TestRuleAction(); - ~TestRuleAction(); + ~TestRuleAction() override; TestRuleAction(const TestRuleAction&); TestRuleAction& operator=(const TestRuleAction&); base::Optional<std::string> type; - base::Optional<std::string> redirect_url; base::Optional<std::vector<std::string>> remove_headers_list; - std::unique_ptr<base::DictionaryValue> ToValue() const; + base::Optional<TestRuleRedirect> redirect; + + std::unique_ptr<base::DictionaryValue> ToValue() const override; }; -struct TestRule { +struct TestRule : public DictionarySource { TestRule(); - ~TestRule(); + ~TestRule() override; TestRule(const TestRule&); TestRule& operator=(const TestRule&); @@ -64,7 +128,8 @@ base::Optional<int> priority; base::Optional<TestRuleCondition> condition; base::Optional<TestRuleAction> action; - std::unique_ptr<base::DictionaryValue> ToValue() const; + + std::unique_ptr<base::DictionaryValue> ToValue() const override; }; // Helper function to build a generic TestRule.
diff --git a/extensions/common/api/extension_view_internal.json b/extensions/common/api/extension_view_internal.json deleted file mode 100644 index 3160c683..0000000 --- a/extensions/common/api/extension_view_internal.json +++ /dev/null
@@ -1,66 +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. - -[ - { - "namespace": "extensionViewInternal", - "description": "none", - "compiler_options": { - "implemented_in": "extensions/browser/api/guest_view/extension_view/extension_view_internal_api.h" - }, - "functions": [ - { - "name": "loadSrc", - "type": "function", - "parameters": [ - { - "type": "integer", - "name": "instanceId" - }, - { - "type": "string", - "name": "src" - }, - { - "type": "function", - "name": "callback", - "parameters": [ - { - "name": "hasLoadSucceeded", - "type": "boolean", - "description": "Whether or not loading the src has succeeded." - } - ] - } - ] - }, - { - "name": "parseSrc", - "type": "function", - "parameters": [ - { - "type": "string", - "name": "src" - }, - { - "type": "function", - "name": "callback", - "parameters": [ - { - "name": "isSrcValid", - "type": "boolean", - "description": "Whether or not the src is valid." - }, - { - "name": "extensionId", - "type": "string", - "description": "The extension ID of the src." - } - ] - } - ] - } - ] - } -]
diff --git a/extensions/common/api/management.json b/extensions/common/api/management.json index 4a7ba8a..fa78307 100644 --- a/extensions/common/api/management.json +++ b/extensions/common/api/management.json
@@ -426,6 +426,34 @@ ] }, { + "name": "canInstallReplacementAndroidApp", + "description": "Checks if the replacement android app can be installed. Errors generated by this API are reported by setting $(ref:runtime.lastError) and executing the function's regular callback.", + "parameters": [ + { + "name": "callback", + "type": "function", + "parameters": [ + { + "name": "result", + "type": "boolean" + } + ] + } + ] + }, + { + "name": "installReplacementAndroidApp", + "description": "Prompts the user to install the replacement Android app from the manifest. Errors generated by this API are reported by setting $(ref:runtime.lastError) and executing the function's regular callback.", + "parameters": [ + { + "name": "callback", + "type": "function", + "optional": true, + "parameters": [] + } + ] + }, + { "name": "installReplacementWebApp", "description": "Prompts the user to install the replacement web app from the manifest.", "parameters": [
diff --git a/extensions/common/api/schema.gni b/extensions/common/api/schema.gni index 7473c42..ac2a944 100644 --- a/extensions/common/api/schema.gni +++ b/extensions/common/api/schema.gni
@@ -25,7 +25,6 @@ "events.json", "extensions_manifest_types.json", "extension_options_internal.idl", - "extension_view_internal.json", "extension_types.json", "feedback_private.idl", "file_system.idl",
diff --git a/extensions/common/manifest_handlers/replacement_apps.cc b/extensions/common/manifest_handlers/replacement_apps.cc index 5128a008..cb8690c 100644 --- a/extensions/common/manifest_handlers/replacement_apps.cc +++ b/extensions/common/manifest_handlers/replacement_apps.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "extensions/common/manifest.h" #include "extensions/common/manifest_constants.h" @@ -56,7 +57,7 @@ } // static -std::string ReplacementAppsInfo::GetReplacementAndroidApp( +const std::string& ReplacementAppsInfo::GetReplacementAndroidApp( const Extension* extension) { const ReplacementAppsInfo* info = GetReplacementAppsInfo(extension);
diff --git a/extensions/common/manifest_handlers/replacement_apps.h b/extensions/common/manifest_handlers/replacement_apps.h index 20c57ceb..4846507 100644 --- a/extensions/common/manifest_handlers/replacement_apps.h +++ b/extensions/common/manifest_handlers/replacement_apps.h
@@ -31,7 +31,8 @@ static bool HasReplacementAndroidApp(const Extension* extension); // Returns the replacement android app package name for |extension|. - static std::string GetReplacementAndroidApp(const Extension* extension); + static const std::string& GetReplacementAndroidApp( + const Extension* extension); bool Parse(const Extension* extension, base::string16* error);
diff --git a/extensions/common/permissions/api_permission.h b/extensions/common/permissions/api_permission.h index 671a3d2..609cab4 100644 --- a/extensions/common/permissions/api_permission.h +++ b/extensions/common/permissions/api_permission.h
@@ -103,7 +103,7 @@ kEnterprisePlatformKeysPrivate = 59, kDeleted_ExperienceSamplingPrivate = 60, kExperimental = 61, - kExtensionView = 62, + kDeleted_ExtensionView = 62, // crbug.com/982858 kExternallyConnectableAllUrls = 63, kFeedbackPrivate = 64, kFileBrowserHandler = 65,
diff --git a/extensions/common/permissions/extensions_api_permissions.cc b/extensions/common/permissions/extensions_api_permissions.cc index 21789e75..5ab5e13 100644 --- a/extensions/common/permissions/extensions_api_permissions.cc +++ b/extensions/common/permissions/extensions_api_permissions.cc
@@ -50,8 +50,6 @@ {APIPermission::kDisplaySource, "displaySource"}, {APIPermission::kDns, "dns"}, {APIPermission::kDocumentScan, "documentScan"}, - {APIPermission::kExtensionView, "extensionview", - APIPermissionInfo::kFlagCannotBeOptional}, {APIPermission::kExternallyConnectableAllUrls, "externally_connectable.all_urls"}, {APIPermission::kFeedbackPrivate, "feedbackPrivate",
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc index 1b8d6f08..1814e7a 100644 --- a/extensions/renderer/dispatcher.cc +++ b/extensions/renderer/dispatcher.cc
@@ -659,13 +659,6 @@ {"extensionOptionsAttributes", IDR_EXTENSION_OPTIONS_ATTRIBUTES_JS}, {"extensionOptionsConstants", IDR_EXTENSION_OPTIONS_CONSTANTS_JS}, {"extensionOptionsEvents", IDR_EXTENSION_OPTIONS_EVENTS_JS}, - {"extensionView", IDR_EXTENSION_VIEW_JS}, - {"extensionViewElement", IDR_EXTENSION_VIEW_ELEMENT_JS}, - {"extensionViewApiMethods", IDR_EXTENSION_VIEW_API_METHODS_JS}, - {"extensionViewAttributes", IDR_EXTENSION_VIEW_ATTRIBUTES_JS}, - {"extensionViewConstants", IDR_EXTENSION_VIEW_CONSTANTS_JS}, - {"extensionViewEvents", IDR_EXTENSION_VIEW_EVENTS_JS}, - {"extensionViewInternal", IDR_EXTENSION_VIEW_INTERNAL_CUSTOM_BINDINGS_JS}, {"feedbackPrivate", IDR_FEEDBACK_PRIVATE_CUSTOM_BINDINGS_JS}, {"fileEntryBindingUtil", IDR_FILE_ENTRY_BINDING_UTIL_JS}, {"fileSystem", IDR_FILE_SYSTEM_CUSTOM_BINDINGS_JS}, @@ -1254,9 +1247,6 @@ blink::WebCustomElement::AddEmbedderCustomElementName("extensionoptions"); blink::WebCustomElement::AddEmbedderCustomElementName( "extensionoptionsbrowserplugin"); - blink::WebCustomElement::AddEmbedderCustomElementName("extensionview"); - blink::WebCustomElement::AddEmbedderCustomElementName( - "extensionviewbrowserplugin"); blink::WebCustomElement::AddEmbedderCustomElementName("webview"); blink::WebCustomElement::AddEmbedderCustomElementName("webviewbrowserplugin"); } @@ -1348,12 +1338,6 @@ module_system->Require("extensionOptionsElement"); } - // Require ExtensionView. - if (context->GetAvailability("extensionViewInternal").is_available()) { - requires_guest_view_module = true; - module_system->Require("extensionViewElement"); - } - // Require WebView. if (context->GetAvailability("webViewInternal").is_available()) { requires_guest_view_module = true;
diff --git a/extensions/renderer/extension_frame_helper.cc b/extensions/renderer/extension_frame_helper.cc index eb5762d..87c7a19 100644 --- a/extensions/renderer/extension_frame_helper.cc +++ b/extensions/renderer/extension_frame_helper.cc
@@ -329,6 +329,16 @@ // TODO(devlin): Add constants for main world id, no extension group. } +void ExtensionFrameHelper::DidCommitProvisionalLoad( + bool is_same_document_navigation, + ui::PageTransition transition) { + // Grant cross browsing instance frame lookup if we are an extension. This + // should match the conditions in FindFrame. + content::RenderFrame* frame = render_frame(); + if (GetExtensionFromFrame(frame)) + frame->SetAllowsCrossBrowsingInstanceFrameLookup(); +} + void ExtensionFrameHelper::DidCreateScriptContext( v8::Local<v8::Context> context, int32_t world_id) {
diff --git a/extensions/renderer/extension_frame_helper.h b/extensions/renderer/extension_frame_helper.h index b923b8e..9142935d 100644 --- a/extensions/renderer/extension_frame_helper.h +++ b/extensions/renderer/extension_frame_helper.h
@@ -125,6 +125,8 @@ void DidCreateNewDocument() override; void ReadyToCommitNavigation( blink::WebDocumentLoader* document_loader) override; + void DidCommitProvisionalLoad(bool is_same_document_navigation, + ui::PageTransition transition) override; void DidCreateScriptContext(v8::Local<v8::Context>, int32_t world_id) override; void WillReleaseScriptContext(v8::Local<v8::Context>,
diff --git a/extensions/renderer/extension_throttle_simulation_unittest.cc b/extensions/renderer/extension_throttle_simulation_unittest.cc index 5a16900..c6e8411 100644 --- a/extensions/renderer/extension_throttle_simulation_unittest.cc +++ b/extensions/renderer/extension_throttle_simulation_unittest.cc
@@ -22,8 +22,8 @@ #include "base/environment.h" #include "base/macros.h" #include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop.h" #include "base/rand_util.h" +#include "base/test/scoped_task_environment.h" #include "base/time/time.h" #include "extensions/renderer/extension_throttle_entry.h" #include "extensions/renderer/extension_throttle_test_support.h" @@ -507,7 +507,8 @@ } TEST(URLRequestThrottlerSimulation, HelpsInAttack) { - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment scoped_task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); Server unprotected_server(30, 1.0); RequesterResults unprotected_attacker_results; RequesterResults unprotected_client_results; @@ -587,7 +588,8 @@ } TEST(URLRequestThrottlerSimulation, PerceivedDowntimeRatio) { - base::MessageLoopForIO message_loop; + base::test::ScopedTaskEnvironment scoped_task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); struct Stats { // Expected interval that we expect the ratio of downtime when anti-DDoS // is enabled and downtime when anti-DDoS is not enabled to fall within.
diff --git a/extensions/renderer/native_extension_bindings_system.cc b/extensions/renderer/native_extension_bindings_system.cc index 425ed61..430ad55 100644 --- a/extensions/renderer/native_extension_bindings_system.cc +++ b/extensions/renderer/native_extension_bindings_system.cc
@@ -653,10 +653,6 @@ ipc_message_sender_->SendOnRequestResponseReceivedIPC(request_id); } -RequestSender* NativeExtensionBindingsSystem::GetRequestSender() { - return nullptr; -} - IPCMessageSender* NativeExtensionBindingsSystem::GetIPCMessageSender() { return ipc_message_sender_.get(); }
diff --git a/extensions/renderer/native_extension_bindings_system.h b/extensions/renderer/native_extension_bindings_system.h index f65141c..86d8f20e 100644 --- a/extensions/renderer/native_extension_bindings_system.h +++ b/extensions/renderer/native_extension_bindings_system.h
@@ -18,7 +18,6 @@ namespace extensions { class IPCMessageSender; -class RequestSender; class ScriptContext; class ScriptContextSetIterable; @@ -67,10 +66,6 @@ const base::ListValue& response, const std::string& error); - // Returns the associated RequestSender, if any. - // TODO(devlin): Factor this out. - RequestSender* GetRequestSender(); - // Returns the associated IPC message sender. IPCMessageSender* GetIPCMessageSender();
diff --git a/extensions/renderer/resources/extensions_renderer_resources.grd b/extensions/renderer/resources/extensions_renderer_resources.grd index 208aa7b3..7d688ba 100644 --- a/extensions/renderer/resources/extensions_renderer_resources.grd +++ b/extensions/renderer/resources/extensions_renderer_resources.grd
@@ -19,13 +19,6 @@ <include name="IDR_EXTENSION_OPTIONS_ATTRIBUTES_JS" file="guest_view/extension_options/extension_options_attributes.js" type="BINDATA"/> <include name="IDR_EXTENSION_OPTIONS_CONSTANTS_JS" file="guest_view/extension_options/extension_options_constants.js" type="BINDATA"/> <include name="IDR_EXTENSION_OPTIONS_EVENTS_JS" file="guest_view/extension_options/extension_options_events.js" type="BINDATA"/> - <include name="IDR_EXTENSION_VIEW_JS" file="guest_view/extension_view/extension_view.js" type="BINDATA" /> - <include name="IDR_EXTENSION_VIEW_ELEMENT_JS" file="guest_view/extension_view/extension_view_element.js" type="BINDATA" /> - <include name="IDR_EXTENSION_VIEW_API_METHODS_JS" file="guest_view/extension_view/extension_view_api_methods.js" type="BINDATA" /> - <include name="IDR_EXTENSION_VIEW_ATTRIBUTES_JS" file="guest_view/extension_view/extension_view_attributes.js" type="BINDATA" /> - <include name="IDR_EXTENSION_VIEW_CONSTANTS_JS" file="guest_view/extension_view/extension_view_constants.js" type="BINDATA" /> - <include name="IDR_EXTENSION_VIEW_EVENTS_JS" file="guest_view/extension_view/extension_view_events.js" type="BINDATA" /> - <include name="IDR_EXTENSION_VIEW_INTERNAL_CUSTOM_BINDINGS_JS" file="guest_view/extension_view/extension_view_internal.js" type="BINDATA" /> <include name="IDR_FEEDBACK_PRIVATE_CUSTOM_BINDINGS_JS" file="feedback_private_custom_bindings.js" type="BINDATA" /> <include name="IDR_GUEST_VIEW_ATTRIBUTES_JS" file="guest_view/guest_view_attributes.js" type="BINDATA" /> <include name="IDR_GUEST_VIEW_CONTAINER_JS" file="guest_view/guest_view_container.js" type="BINDATA" />
diff --git a/extensions/renderer/resources/guest_view/extension_view/extension_view.js b/extensions/renderer/resources/guest_view/extension_view/extension_view.js deleted file mode 100644 index 5445568b..0000000 --- a/extensions/renderer/resources/guest_view/extension_view/extension_view.js +++ /dev/null
@@ -1,154 +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. - -// This module implements the ExtensionView <extensionview>. - -var GuestViewContainer = require('guestViewContainer').GuestViewContainer; -var ExtensionViewConstants = - require('extensionViewConstants').ExtensionViewConstants; -var ExtensionViewAttributes = - require('extensionViewAttributes').ExtensionViewAttributes; -var ExtensionViewEvents = require('extensionViewEvents').ExtensionViewEvents; -var ExtensionViewInternal = getInternalApi('extensionViewInternal'); - -function ExtensionViewImpl(extensionviewElement) { - $Function.call( - GuestViewContainer, this, extensionviewElement, 'extensionview'); - - // A queue of objects in the order they should be loaded. - // Every load call will add the given src, as well as the resolve and reject - // functions. Each src will be loaded in the order they were called. - this.loadQueue = []; - - // The current src that is loading. - // @type {Object<!string, function, function>} - this.pendingLoad = null; - - new ExtensionViewEvents(this, this.viewInstanceId); -} - -ExtensionViewImpl.prototype.__proto__ = GuestViewContainer.prototype; - -ExtensionViewImpl.prototype.createGuest = function(callback) { - this.guest.create(this.buildParams(), $Function.bind(function() { - this.attachWindow$(); - callback(); - }, this)); -}; - -ExtensionViewImpl.prototype.buildContainerParams = function() { - var params = $Object.create(null); - for (var i in this.attributes) { - params[i] = this.attributes[i].getValue(); - } - return params; -}; - -// Sets up all of the extensionview attributes. -ExtensionViewImpl.prototype.setupAttributes = function() { - this.attributes[ExtensionViewConstants.ATTRIBUTE_EXTENSION] = - new ExtensionViewAttributes.ExtensionAttribute(this); - this.attributes[ExtensionViewConstants.ATTRIBUTE_SRC] = - new ExtensionViewAttributes.SrcAttribute(this); -}; - -ExtensionViewImpl.prototype.onElementDetached = function() { - this.guest.destroy(); - - // Reset all attributes. - for (var i in this.attributes) { - this.attributes[i].setValueIgnoreMutation(); - } -}; - -// Updates src upon loadcommit. -ExtensionViewImpl.prototype.onLoadCommit = function(url) { - this.attributes[ExtensionViewConstants.ATTRIBUTE_SRC]. - setValueIgnoreMutation(url); -}; - -// Loads the next pending src from |loadQueue| to the extensionview. -ExtensionViewImpl.prototype.loadNextSrc = function() { - // If extensionview isn't currently loading a src, load the next src - // in |loadQueue|. Otherwise, do nothing. - if (!this.pendingLoad && this.loadQueue.length) { - this.pendingLoad = $Array.shift(this.loadQueue); - var src = this.pendingLoad.src; - var resolve = this.pendingLoad.resolve; - var reject = this.pendingLoad.reject; - - // The extensionview validates the |src| twice, once in |parseSrc| and then - // in |loadSrc|. The |src| isn't checked directly in |loadNextSrc| for - // validity since the sending renderer (WebUI) is trusted. - ExtensionViewInternal.parseSrc( - src, $Function.bind(function(isSrcValid, extensionId) { - // Check if the src is valid. - if (!isSrcValid) { - reject('Failed to load: src is not valid.'); - return; - } - - // Destroy the current guest and create a new one if extension ID - // is different. - // - // This may happen if the extensionview is loads an extension page, and - // is then intended to load a page served from a different extension in - // the same part of the WebUI. - // - // The two calls may look like the following: - // extensionview.load('chrome-extension://firstId/page.html'); - // extensionview.load('chrome-extension://secondId/page.html'); - // The second time load is called, we destroy the current guest since - // we will be loading content from a different extension. - if (extensionId != - this.attributes[ExtensionViewConstants.ATTRIBUTE_EXTENSION] - .getValue()) { - this.guest.destroy($Function.bind(this.prepareForReattach$, this)); - - // Update the extension and src attributes. - this.attributes[ExtensionViewConstants.ATTRIBUTE_EXTENSION] - .setValueIgnoreMutation(extensionId); - this.attributes[ExtensionViewConstants.ATTRIBUTE_SRC] - .setValueIgnoreMutation(src); - - this.createGuest($Function.bind(function() { - if (this.guest.getId() <= 0) { - reject('Failed to load: guest creation failed.'); - } else { - resolve('Successful load.'); - } - }, this)); - } else { - ExtensionViewInternal.loadSrc(this.guest.getId(), src, - $Function.bind(function(hasLoadSucceeded) { - if (!hasLoadSucceeded) { - reject('Failed to load.'); - } else { - // Update the src attribute. - this.attributes[ExtensionViewConstants.ATTRIBUTE_SRC] - .setValueIgnoreMutation(src); - resolve('Successful load.'); - } - }, this)); - } - }, this)); - } -}; - -ExtensionViewImpl.prototype.load = function(src) { - return new Promise($Function.bind(function(resolve, reject) { - $Array.push(this.loadQueue, {src: src, resolve: resolve, reject: reject}); - this.loadNextSrc(); - }, this)).then($Function.bind(function onLoadResolved() { - this.pendingLoad = null; - this.loadNextSrc(); - }, this), $Function.bind(function onLoadRejected(reason) { - this.pendingLoad = null; - this.loadNextSrc(); - return Promise.reject(reason); - }, this)); -}; - -// Exports. -exports.$set('ExtensionViewImpl', ExtensionViewImpl);
diff --git a/extensions/renderer/resources/guest_view/extension_view/extension_view_api_methods.js b/extensions/renderer/resources/guest_view/extension_view/extension_view_api_methods.js deleted file mode 100644 index 120520a..0000000 --- a/extensions/renderer/resources/guest_view/extension_view/extension_view_api_methods.js +++ /dev/null
@@ -1,17 +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. - -// This module contains the public-facing API functions for the -// <extensionview> tag. - -var EXTENSION_VIEW_API_METHODS = [ - // Loads the given src into extensionview. Must be called every time the - // the extensionview should load a new page. This is the only way to set - // the extension and src attributes. Returns a promise indicating whether - // or not load was successful. - 'load' -]; - -// Exports. -exports.$set('EXTENSION_VIEW_API_METHODS', EXTENSION_VIEW_API_METHODS);
diff --git a/extensions/renderer/resources/guest_view/extension_view/extension_view_attributes.js b/extensions/renderer/resources/guest_view/extension_view/extension_view_attributes.js deleted file mode 100644 index d0e5adc..0000000 --- a/extensions/renderer/resources/guest_view/extension_view/extension_view_attributes.js +++ /dev/null
@@ -1,52 +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. - -// This module implements the attributes of the <extensionview> tag. - -var GuestViewAttributes = require('guestViewAttributes').GuestViewAttributes; -var ExtensionViewConstants = - require('extensionViewConstants').ExtensionViewConstants; - -// ----------------------------------------------------------------------------- -// ExtensionAttribute object. - -// Attribute that handles the extension associated with the extensionview. -function ExtensionAttribute(view) { - $Function.call( - GuestViewAttributes.ReadOnlyAttribute, this, - ExtensionViewConstants.ATTRIBUTE_EXTENSION, view); -} - -ExtensionAttribute.prototype.__proto__ = - GuestViewAttributes.ReadOnlyAttribute.prototype; - -// ----------------------------------------------------------------------------- -// SrcAttribute object. - -// Attribute that handles the location and navigation of the extensionview. -// This is read only because we only want to be able to navigate to a src -// through the load API call, which checks for URL validity and the extension -// ID of the new src. -function SrcAttribute(view) { - $Function.call( - GuestViewAttributes.ReadOnlyAttribute, this, - ExtensionViewConstants.ATTRIBUTE_SRC, view); -} - -SrcAttribute.prototype.__proto__ = - GuestViewAttributes.ReadOnlyAttribute.prototype; - -SrcAttribute.prototype.handleMutation = function(oldValue, newValue) { - console.log('src is read only. Use .load(url) to navigate to a new ' + - 'extension page.'); - this.setValueIgnoreMutation(oldValue); -}; - -var ExtensionViewAttributes = { - ExtensionAttribute: ExtensionAttribute, - SrcAttribute: SrcAttribute -}; - -// Exports. -exports.$set('ExtensionViewAttributes', ExtensionViewAttributes);
diff --git a/extensions/renderer/resources/guest_view/extension_view/extension_view_constants.js b/extensions/renderer/resources/guest_view/extension_view/extension_view_constants.js deleted file mode 100644 index 80934cf..0000000 --- a/extensions/renderer/resources/guest_view/extension_view/extension_view_constants.js +++ /dev/null
@@ -1,14 +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. - -// This module contains constants used in extensionview. - -// Container for the extensionview constants. -var ExtensionViewConstants = { - // Attributes. - ATTRIBUTE_EXTENSION: 'extension', - ATTRIBUTE_SRC: 'src', -}; - -exports.$set('ExtensionViewConstants', $Object.freeze(ExtensionViewConstants));
diff --git a/extensions/renderer/resources/guest_view/extension_view/extension_view_element.js b/extensions/renderer/resources/guest_view/extension_view/extension_view_element.js deleted file mode 100644 index eb9e285..0000000 --- a/extensions/renderer/resources/guest_view/extension_view/extension_view_element.js +++ /dev/null
@@ -1,35 +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. - -// The <extensionview> custom element. - -var registerElement = require('guestViewContainerElement').registerElement; -var forwardApiMethods = require('guestViewContainerElement').forwardApiMethods; -var GuestViewContainerElement = - require('guestViewContainerElement').GuestViewContainerElement; -var ExtensionViewImpl = require('extensionView').ExtensionViewImpl; -var ExtensionViewConstants = - require('extensionViewConstants').ExtensionViewConstants; -var EXTENSION_VIEW_API_METHODS = - require('extensionViewApiMethods').EXTENSION_VIEW_API_METHODS; - -class ExtensionViewElement extends GuestViewContainerElement { - static get observedAttributes() { - return [ - ExtensionViewConstants.ATTRIBUTE_EXTENSION, - ExtensionViewConstants.ATTRIBUTE_SRC - ]; - } - - constructor() { - super(); - privates(this).internal = new ExtensionViewImpl(this); - } -} - -// Forward ExtensionViewElement.foo* method calls to ExtensionViewImpl.foo*. -forwardApiMethods( - ExtensionViewElement, ExtensionViewImpl, null, EXTENSION_VIEW_API_METHODS); - -registerElement('ExtensionView', ExtensionViewElement);
diff --git a/extensions/renderer/resources/guest_view/extension_view/extension_view_events.js b/extensions/renderer/resources/guest_view/extension_view/extension_view_events.js deleted file mode 100644 index e5a0e955..0000000 --- a/extensions/renderer/resources/guest_view/extension_view/extension_view_events.js +++ /dev/null
@@ -1,32 +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. - -// Event management for ExtensionView. - -var CreateEvent = require('guestViewEvents').CreateEvent; -var GuestViewEvents = require('guestViewEvents').GuestViewEvents; - -function ExtensionViewEvents(extensionViewImpl) { - $Function.call(GuestViewEvents, this, extensionViewImpl); -} - -ExtensionViewEvents.prototype.__proto__ = GuestViewEvents.prototype; - -ExtensionViewEvents.EVENTS = { - 'loadcommit': { - evt: CreateEvent('extensionViewInternal.onLoadCommit'), - handler: 'handleLoadCommitEvent', - internal: true - } -}; - -ExtensionViewEvents.prototype.getEvents = function() { - return ExtensionViewEvents.EVENTS; -}; - -ExtensionViewEvents.prototype.handleLoadCommitEvent = function(event) { - this.view.onLoadCommit(event.url); -}; - -exports.$set('ExtensionViewEvents', ExtensionViewEvents);
diff --git a/extensions/renderer/resources/guest_view/extension_view/extension_view_internal.js b/extensions/renderer/resources/guest_view/extension_view/extension_view_internal.js deleted file mode 100644 index 8ef2a9ba..0000000 --- a/extensions/renderer/resources/guest_view/extension_view/extension_view_internal.js +++ /dev/null
@@ -1,9 +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. - -if (!apiBridge) { - exports.$set( - 'ExtensionViewInternal', - require('binding').Binding.create('extensionViewInternal').generate()); -}
diff --git a/extensions/renderer/resources/guest_view/guest_view_deny.js b/extensions/renderer/resources/guest_view/guest_view_deny.js index cbdc9efe..64e353b 100644 --- a/extensions/renderer/resources/guest_view/guest_view_deny.js +++ b/extensions/renderer/resources/guest_view/guest_view_deny.js
@@ -19,7 +19,6 @@ var VIEW_TYPES = [ 'AppView', 'ExtensionOptions', - 'ExtensionView', 'WebView' ];
diff --git a/extensions/renderer/runtime_hooks_delegate.cc b/extensions/renderer/runtime_hooks_delegate.cc index 6dc92ed..d25bd6cd 100644 --- a/extensions/renderer/runtime_hooks_delegate.cc +++ b/extensions/renderer/runtime_hooks_delegate.cc
@@ -104,10 +104,10 @@ std::string url = base::StringPrintf( "chrome-extension://%s%s%s", script_context->extension()->id().c_str(), !path.empty() && path[0] == '/' ? "" : "/", path.c_str()); + // GURL considers any possible path valid. Since the argument is only appended + // as part of the path, there should be no way this could conceivably fail. + DCHECK(GURL(url).is_valid()); result.return_value = gin::StringToV8(isolate, url); - // TODO(tjudkins): Gather data on how often this is passed a bad URL (i.e. not - // a relative file path for the extension), so we can decide if it's fine to - // throw an error in those cases. return result; }
diff --git a/extensions/strings/extensions_strings.grd b/extensions/strings/extensions_strings.grd index cae80a8..1e4d9dce 100644 --- a/extensions/strings/extensions_strings.grd +++ b/extensions/strings/extensions_strings.grd
@@ -324,9 +324,6 @@ <message name="IDS_EXTENSION_TASK_MANAGER_EXTENSIONOPTIONS_TAG_PREFIX" desc="The prefix for a guest page loaded in an extensionoptions tag in the Task Manager"> Options: <ph name="EXTENSIONOPTIONS_TAG_NAME">$1<ex>Google Hangouts</ex></ph> </message> - <message name="IDS_EXTENSION_TASK_MANAGER_EXTENSIONVIEW_TAG_PREFIX" desc="The prefix for a guest page loaded in an extensionview tag in the Task Manager"> - ExtensionView: <ph name="EXTENSIONVIEW_TAG_NAME">$1<ex>Google Hangouts</ex></ph> - </message> <message name="IDS_EXTENSION_TASK_MANAGER_MIMEHANDLERVIEW_TAG_PREFIX" desc="The prefix for a guest page loaded in a mime handler view page in the task manager"> Mimehandler: <ph name="MIMEHANDLERVIEW_TAG_NAME">$1<ex>My mime handler view</ex></ph> </message>
diff --git a/fuchsia/engine/browser/frame_impl_browsertest.cc b/fuchsia/engine/browser/frame_impl_browsertest.cc index 2264192..d7a07105 100644 --- a/fuchsia/engine/browser/frame_impl_browsertest.cc +++ b/fuchsia/engine/browser/frame_impl_browsertest.cc
@@ -1474,6 +1474,78 @@ navigation_listener2.RunUntilUrlAndTitleEquals(page_url, kPage1Title); } +// Check loading an invalid URL in NavigationController.LoadUrl() sets the right +// error. +IN_PROC_BROWSER_TEST_F(FrameImplTest, InvalidUrl) { + fuchsia::web::FramePtr frame = CreateFrame(); + fuchsia::web::NavigationControllerPtr controller; + frame->GetNavigationController(controller.NewRequest()); + + base::RunLoop run_loop; + cr_fuchsia::ResultReceiver<fuchsia::web::NavigationController_LoadUrl_Result> + result(run_loop.QuitClosure()); + controller->LoadUrl( + "http:google.com:foo", fuchsia::web::LoadUrlParams(), + cr_fuchsia::CallbackToFitFunction(result.GetReceiveCallback())); + run_loop.Run(); + + ASSERT_TRUE(result->is_err()); + EXPECT_EQ(result->err(), + fuchsia::web::NavigationControllerError::INVALID_URL); +} + +// Check setting invalid headers in NavigationController.LoadUrl() sets the +// right error. +IN_PROC_BROWSER_TEST_F(FrameImplTest, InvalidHeader) { + fuchsia::web::FramePtr frame = CreateFrame(); + fuchsia::web::NavigationControllerPtr controller; + frame->GetNavigationController(controller.NewRequest()); + + { + // Set an invalid header name. + fuchsia::web::LoadUrlParams load_url_params; + fuchsia::net::http::Header header; + header.name = cr_fuchsia::StringToBytes("Invalid:Header"); + header.value = cr_fuchsia::StringToBytes("1"); + load_url_params.set_headers({header}); + + base::RunLoop run_loop; + cr_fuchsia::ResultReceiver< + fuchsia::web::NavigationController_LoadUrl_Result> + result(run_loop.QuitClosure()); + controller->LoadUrl( + "http://site.ext/", std::move(load_url_params), + cr_fuchsia::CallbackToFitFunction(result.GetReceiveCallback())); + run_loop.Run(); + + ASSERT_TRUE(result->is_err()); + EXPECT_EQ(result->err(), + fuchsia::web::NavigationControllerError::INVALID_HEADER); + } + + { + // Set an invalid header value. + fuchsia::web::LoadUrlParams load_url_params; + fuchsia::net::http::Header header; + header.name = cr_fuchsia::StringToBytes("Header"); + header.value = cr_fuchsia::StringToBytes("Invalid\rValue"); + load_url_params.set_headers({header}); + + base::RunLoop run_loop; + cr_fuchsia::ResultReceiver< + fuchsia::web::NavigationController_LoadUrl_Result> + result(run_loop.QuitClosure()); + controller->LoadUrl( + "http://site.ext/", std::move(load_url_params), + cr_fuchsia::CallbackToFitFunction(result.GetReceiveCallback())); + run_loop.Run(); + + ASSERT_TRUE(result->is_err()); + EXPECT_EQ(result->err(), + fuchsia::web::NavigationControllerError::INVALID_HEADER); + } +} + class RequestMonitoringFrameImplBrowserTest : public FrameImplTest { public: RequestMonitoringFrameImplBrowserTest() = default;
diff --git a/fuchsia/engine/browser/navigation_controller_impl.cc b/fuchsia/engine/browser/navigation_controller_impl.cc index fd2aea1..5f5257b 100644 --- a/fuchsia/engine/browser/navigation_controller_impl.cc +++ b/fuchsia/engine/browser/navigation_controller_impl.cc
@@ -11,6 +11,7 @@ #include "content/public/browser/web_contents.h" #include "content/public/common/was_activated_option.mojom.h" #include "fuchsia/base/string_util.h" +#include "net/http/http_util.h" #include "ui/base/page_transition_types.h" namespace { @@ -141,10 +142,17 @@ std::vector<std::string> extra_headers; extra_headers.reserve(params.headers().size()); for (const auto& header : params.headers()) { - // TODO(crbug.com/990525): Validate |header.name| and |header.value|. + base::StringPiece header_name = cr_fuchsia::BytesAsString(header.name); + base::StringPiece header_value = cr_fuchsia::BytesAsString(header.value); + if (!net::HttpUtil::IsValidHeaderName(header_name) || + !net::HttpUtil::IsValidHeaderValue(header_value)) { + result.set_err(fuchsia::web::NavigationControllerError::INVALID_HEADER); + callback(std::move(result)); + return; + } + extra_headers.emplace_back( - base::StrCat({cr_fuchsia::BytesAsString(header.name), ": ", - cr_fuchsia::BytesAsString(header.value)})); + base::StrCat({header_name, ": ", header_value})); } params_converted.extra_headers = base::JoinString(extra_headers, "\n"); }
diff --git a/fuchsia/engine/web_engine_integration_tests.cmx b/fuchsia/engine/web_engine_integration_tests.cmx index 3c0c9ca..1dfd8af 100644 --- a/fuchsia/engine/web_engine_integration_tests.cmx +++ b/fuchsia/engine/web_engine_integration_tests.cmx
@@ -12,7 +12,6 @@ "fuchsia.fonts.Provider", "fuchsia.logger.LogSink", "fuchsia.net.NameLookup", - "fuchsia.net.SocketProvider", "fuchsia.netstack.Netstack", "fuchsia.posix.socket.Provider", "fuchsia.process.Launcher",
diff --git a/fuchsia/http/http.cmx b/fuchsia/http/http.cmx index b4cde0cf..389f2b5 100644 --- a/fuchsia/http/http.cmx +++ b/fuchsia/http/http.cmx
@@ -9,7 +9,6 @@ "fuchsia.device.NameProvider", "fuchsia.logger.LogSink", "fuchsia.net.NameLookup", - "fuchsia.net.SocketProvider", "fuchsia.netstack.Netstack", "fuchsia.posix.socket.Provider" ]
diff --git a/fuchsia/runners/cast/cast_runner.cmx b/fuchsia/runners/cast/cast_runner.cmx index cdb498d..0905fd8 100644 --- a/fuchsia/runners/cast/cast_runner.cmx +++ b/fuchsia/runners/cast/cast_runner.cmx
@@ -10,10 +10,9 @@ "fuchsia.fonts.Provider", "fuchsia.logger.LogSink", "fuchsia.media.Audio", - "fuchsia.media.drm.WidevineContentDecryptionModule", + "fuchsia.media.drm.Widevine", "fuchsia.mediacodec.CodecFactory", "fuchsia.net.NameLookup", - "fuchsia.net.SocketProvider", "fuchsia.netstack.Netstack", "fuchsia.posix.socket.Provider", "fuchsia.process.Launcher",
diff --git a/fuchsia/runners/web/web_runner.cmx b/fuchsia/runners/web/web_runner.cmx index 83648b53..4e54486 100644 --- a/fuchsia/runners/web/web_runner.cmx +++ b/fuchsia/runners/web/web_runner.cmx
@@ -10,10 +10,9 @@ "fuchsia.fonts.Provider", "fuchsia.logger.LogSink", "fuchsia.media.Audio", - "fuchsia.media.drm.WidevineContentDecryptionModule", + "fuchsia.media.drm.Widevine", "fuchsia.mediacodec.CodecFactory", "fuchsia.net.NameLookup", - "fuchsia.net.SocketProvider", "fuchsia.netstack.Netstack", "fuchsia.posix.socket.Provider", "fuchsia.process.Launcher",
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc index 867f320f..2035b4a 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc +++ b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc
@@ -766,23 +766,17 @@ SharedImageBackingFactoryAHB::~SharedImageBackingFactoryAHB() = default; -std::unique_ptr<SharedImageBacking> -SharedImageBackingFactoryAHB::CreateSharedImage( - const Mailbox& mailbox, - viz::ResourceFormat format, - const gfx::Size& size, - const gfx::ColorSpace& color_space, +bool SharedImageBackingFactoryAHB::ValidateUsage( uint32_t usage, - bool is_thread_safe) { - DCHECK(base::AndroidHardwareBufferCompat::IsSupportAvailable()); - + const gfx::Size& size, + viz::ResourceFormat format) const { const FormatInfo& format_info = format_info_[format]; // Check if the format is supported by AHardwareBuffer. if (!format_info.ahb_supported) { LOG(ERROR) << "viz::ResourceFormat " << format << " not supported by AHardwareBuffer"; - return nullptr; + return false; } // SHARED_IMAGE_USAGE_RASTER is set when we want to write on Skia @@ -802,7 +796,7 @@ LOG(ERROR) << "viz::ResourceFormat " << format << " can not be used to create a GL texture from AHardwareBuffer."; - return nullptr; + return false; } } @@ -814,6 +808,23 @@ size.width() > max_gl_texture_size_ || size.height() > max_gl_texture_size_) { LOG(ERROR) << "CreateSharedImage: invalid size"; + return false; + } + + return true; +} + +std::unique_ptr<SharedImageBacking> +SharedImageBackingFactoryAHB::CreateSharedImage( + const Mailbox& mailbox, + viz::ResourceFormat format, + const gfx::Size& size, + const gfx::ColorSpace& color_space, + uint32_t usage, + bool is_thread_safe) { + DCHECK(base::AndroidHardwareBufferCompat::IsSupportAvailable()); + + if (!ValidateUsage(usage, size, format)) { return nullptr; } @@ -824,6 +835,8 @@ return nullptr; } + const FormatInfo& format_info = format_info_[format]; + // Setup AHardwareBuffer. AHardwareBuffer* buffer = nullptr; AHardwareBuffer_Desc hwb_desc; @@ -875,7 +888,7 @@ bool SharedImageBackingFactoryAHB::CanImportGpuMemoryBuffer( gfx::GpuMemoryBufferType memory_buffer_type) { - return false; + return memory_buffer_type == gfx::ANDROID_HARDWARE_BUFFER; } SharedImageBackingFactoryAHB::FormatInfo::FormatInfo() = default; @@ -891,8 +904,28 @@ const gfx::Size& size, const gfx::ColorSpace& color_space, uint32_t usage) { - NOTIMPLEMENTED(); - return nullptr; + // TODO(vasilyt): support SHARED_MEMORY_BUFFER? + if (handle.type != gfx::ANDROID_HARDWARE_BUFFER) { + NOTIMPLEMENTED(); + return nullptr; + } + + auto resource_format = viz::GetResourceFormat(buffer_format); + + if (!ValidateUsage(usage, size, resource_format)) { + return nullptr; + } + + size_t estimated_size; + if (!viz::ResourceSizes::MaybeSizeInBytes(size, resource_format, + &estimated_size)) { + LOG(ERROR) << "Failed to calculate SharedImage size"; + return nullptr; + } + + return std::make_unique<SharedImageBackingAHB>( + mailbox, resource_format, size, color_space, usage, + std::move(handle.android_hardware_buffer), estimated_size, false); } } // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.h b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.h index 49cf7fea..2eba957 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.h +++ b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.h
@@ -59,6 +59,10 @@ gfx::GpuMemoryBufferType memory_buffer_type) override; private: + bool ValidateUsage(uint32_t usage, + const gfx::Size& size, + viz::ResourceFormat format) const; + struct FormatInfo { FormatInfo(); ~FormatInfo();
diff --git a/gpu/command_buffer/service/shared_image_factory.cc b/gpu/command_buffer/service/shared_image_factory.cc index aa7b1d0..873afc1a 100644 --- a/gpu/command_buffer/service/shared_image_factory.cc +++ b/gpu/command_buffer/service/shared_image_factory.cc
@@ -299,6 +299,12 @@ share_between_gl_vulkan || using_dawn || share_between_gl_metal; + // TODO(vasilyt): Android required AHB for overlays + // What about other platforms? +#if defined(OS_ANDROID) + using_interop_factory |= usage & SHARED_IMAGE_USAGE_SCANOUT; +#endif + // wrapped_sk_image_factory_ is only used for OOPR and supports // a limited number of flags (e.g. no SHARED_IMAGE_USAGE_SCANOUT). constexpr auto kWrappedSkImageUsage = SHARED_IMAGE_USAGE_RASTER |
diff --git a/gpu/command_buffer/tests/webgpu_test.cc b/gpu/command_buffer/tests/webgpu_test.cc index 3f97e54..76c6107e 100644 --- a/gpu/command_buffer/tests/webgpu_test.cc +++ b/gpu/command_buffer/tests/webgpu_test.cc
@@ -24,6 +24,7 @@ WebGPUTest::~WebGPUTest() = default; bool WebGPUTest::WebGPUSupported() const { + DCHECK(is_initialized_); // Did you call WebGPUTest::Initialize? return context_ != nullptr; } @@ -48,6 +49,8 @@ } void WebGPUTest::Initialize(const Options& options) { + is_initialized_ = true; + // crbug.com(941685): Vulkan driver crashes on Linux FYI Release (AMD R7 240). if (GPUTestBotConfig::CurrentConfigMatches("Linux AMD")) { return; @@ -106,12 +109,13 @@ } TEST_F(WebGPUTest, FlushNoCommands) { + Initialize(WebGPUTest::Options()); + if (!WebGPUSupported()) { LOG(ERROR) << "Test skipped because WebGPU isn't supported"; return; } - Initialize(WebGPUTest::Options()); webgpu()->FlushCommands(); }
diff --git a/gpu/command_buffer/tests/webgpu_test.h b/gpu/command_buffer/tests/webgpu_test.h index e2f382a..92b37b3 100644 --- a/gpu/command_buffer/tests/webgpu_test.h +++ b/gpu/command_buffer/tests/webgpu_test.h
@@ -56,6 +56,7 @@ private: std::unique_ptr<viz::TestGpuServiceHolder> gpu_service_holder_; std::unique_ptr<WebGPUInProcessContext> context_; + bool is_initialized_ = false; }; } // namespace gpu
diff --git a/gpu/config/gpu_preferences.h b/gpu/config/gpu_preferences.h index d35b883..da1fbce7 100644 --- a/gpu/config/gpu_preferences.h +++ b/gpu/config/gpu_preferences.h
@@ -10,12 +10,15 @@ #include <vector> #include "base/macros.h" -#include "base/message_loop/message_pump_type.h" #include "build/build_config.h" #include "gpu/gpu_export.h" #include "media/media_buildflags.h" #include "ui/gfx/buffer_types.h" +#if defined(USE_OZONE) +#include "base/message_loop/message_pump_type.h" +#endif + namespace gpu { // The size to set for the program cache for default and low-end device cases. @@ -215,8 +218,10 @@ // Enable the WebGPU command buffer. bool enable_webgpu = false; +#if defined(USE_OZONE) // Determines message pump type for the GPU thread. base::MessagePumpType message_pump_type = base::MessagePumpType::DEFAULT; +#endif // Please update gpu_preferences_unittest.cc when making additions or // changes to this struct.
diff --git a/gpu/config/gpu_preferences_unittest.cc b/gpu/config/gpu_preferences_unittest.cc index 2d86720..35fc0b9 100644 --- a/gpu/config/gpu_preferences_unittest.cc +++ b/gpu/config/gpu_preferences_unittest.cc
@@ -73,7 +73,9 @@ EXPECT_EQ(left.enable_gpu_benchmarking_extension, right.enable_gpu_benchmarking_extension); EXPECT_EQ(left.enable_webgpu, right.enable_webgpu); +#if defined(USE_OZONE) EXPECT_EQ(left.message_pump_type, right.message_pump_type); +#endif } } // namespace @@ -156,8 +158,10 @@ mojom::VulkanImplementationName::kNative) GPU_PREFERENCES_FIELD(enable_gpu_benchmarking_extension, true) GPU_PREFERENCES_FIELD(enable_webgpu, true) +#if defined(USE_OZONE) GPU_PREFERENCES_FIELD_ENUM(message_pump_type, base::MessagePumpType::UI, base::MessagePumpType::UI) +#endif input_prefs.texture_target_exception_list.emplace_back( gfx::BufferUsage::SCANOUT, gfx::BufferFormat::RGBA_8888);
diff --git a/gpu/ipc/common/BUILD.gn b/gpu/ipc/common/BUILD.gn index 98cb614..50bab0e 100644 --- a/gpu/ipc/common/BUILD.gn +++ b/gpu/ipc/common/BUILD.gn
@@ -4,6 +4,7 @@ import("//build/config/ui.gni") import("//mojo/public/tools/bindings/mojom.gni") +import("//ui/ozone/ozone.gni") group("common") { if (is_component_build) { @@ -222,6 +223,11 @@ "//mojo/public/mojom/base", "//ui/gfx/mojom", ] + + enabled_features = [] + if (use_ozone) { + enabled_features += [ "use_ozone" ] + } } mojom("test_interfaces") {
diff --git a/gpu/ipc/common/gpu_preferences.mojom b/gpu/ipc/common/gpu_preferences.mojom index 34f7e75..d4c0b72 100644 --- a/gpu/ipc/common/gpu_preferences.mojom +++ b/gpu/ipc/common/gpu_preferences.mojom
@@ -5,7 +5,9 @@ // gpu/config/gpu_preferences.h module gpu.mojom; +[EnableIf=use_ozone] import "mojo/public/mojom/base/message_pump_type.mojom"; + import "ui/gfx/mojom/buffer_types.mojom"; // Corresponds to gpu::VulkanImplementationName. @@ -68,5 +70,7 @@ bool enable_metal; bool enable_gpu_benchmarking_extension; bool enable_webgpu; + + [EnableIf=use_ozone] mojo_base.mojom.MessagePumpType message_pump_type; };
diff --git a/gpu/ipc/common/gpu_preferences_mojom_traits.h b/gpu/ipc/common/gpu_preferences_mojom_traits.h index 339cf0e4..172667e 100644 --- a/gpu/ipc/common/gpu_preferences_mojom_traits.h +++ b/gpu/ipc/common/gpu_preferences_mojom_traits.h
@@ -7,12 +7,15 @@ #include <vector> -#include "base/message_loop/message_pump_type.h" #include "gpu/config/gpu_preferences.h" #include "gpu/ipc/common/gpu_preferences.mojom.h" -#include "mojo/public/cpp/base/message_pump_type_mojom_traits.h" #include "ui/gfx/mojom/buffer_types_mojom_traits.h" +#if defined(USE_OZONE) +#include "base/message_loop/message_pump_type.h" +#include "mojo/public/cpp/base/message_pump_type_mojom_traits.h" +#endif + namespace mojo { template <> @@ -121,8 +124,12 @@ out->enable_gpu_benchmarking_extension = prefs.enable_gpu_benchmarking_extension(); out->enable_webgpu = prefs.enable_webgpu(); + +#if defined(USE_OZONE) if (!prefs.ReadMessagePumpType(&out->message_pump_type)) return false; +#endif + return true; } @@ -272,10 +279,12 @@ static bool enable_webgpu(const gpu::GpuPreferences& prefs) { return prefs.enable_webgpu; } +#if defined(USE_OZONE) static base::MessagePumpType message_pump_type( const gpu::GpuPreferences& prefs) { return prefs.message_pump_type; } +#endif }; } // namespace mojo
diff --git a/infra/config/cr-buildbucket.cfg b/infra/config/cr-buildbucket.cfg index 574b0b6a..70af8adb 100644 --- a/infra/config/cr-buildbucket.cfg +++ b/infra/config/cr-buildbucket.cfg
@@ -1644,6 +1644,13 @@ } builders { + name: "linux-bfcache-rel" + mixins: "builderless" + mixins: "fyi-ci" + mixins: "linux-xenial" + } + + builders { name: "linux-fieldtrial-rel" mixins: "builderless" mixins: "fyi-ci" @@ -1764,6 +1771,11 @@ } builders { + name: "Linux FYI SkiaRenderer Vulkan (Intel HD 630)" + mixins: "linux-gpu-fyi-ci-tester" + } + + builders { name: "Linux FYI SkiaRenderer Vulkan (NVIDIA)" mixins: "linux-gpu-fyi-ci-tester" } @@ -2314,6 +2326,9 @@ builders { name: "Win10 FYI x64 Release (Intel UHD 630)" mixins: "linux-gpu-fyi-ci-tester" + # TODO(https://crbug.com/986939): Remove this increased timeout once + # more devices are added. + execution_timeout_secs: 43200 # 12h. } builders { name: "Win10 FYI x64 Release (NVIDIA GeForce GTX 1660)" @@ -4035,6 +4050,10 @@ } builders { mixins: "linux-optional-gpu-try" + name: "gpu-fyi-try-linux-intel-skv" + } + builders { + mixins: "linux-optional-gpu-try" name: "gpu-fyi-try-linux-nvidia-dbg" } builders {
diff --git a/infra/config/luci-milo.cfg b/infra/config/luci-milo.cfg index 0aca1fa..a1dd093e 100644 --- a/infra/config/luci-milo.cfg +++ b/infra/config/luci-milo.cfg
@@ -2263,6 +2263,10 @@ category: "linux" } builders { + name: "buildbucket/luci.chromium.ci/linux-bfcache-rel" + category: "linux" + } + builders { name: "buildbucket/luci.chromium.ci/linux-fieldtrial-rel" category: "linux" } @@ -3447,6 +3451,11 @@ short_name: "dqp" } builders { + name: "buildbucket/luci.chromium.ci/Linux FYI SkiaRenderer Vulkan (Intel HD 630)" + category: "Linux|Intel" + short_name: "skv" + } + builders { name: "buildbucket/luci.chromium.ci/Linux FYI SkiaRenderer Vulkan (NVIDIA)" category: "Linux|Nvidia" short_name: "skv" @@ -4239,6 +4248,9 @@ name: "buildbucket/luci.chromium.try/gpu-fyi-try-linux-intel-rel" } builders { + name: "buildbucket/luci.chromium.try/gpu-fyi-try-linux-intel-skv" + } + builders { name: "buildbucket/luci.chromium.try/gpu-fyi-try-linux-nvidia-dbg" } builders { @@ -4862,6 +4874,9 @@ name: "buildbucket/luci.chromium.try/gpu-fyi-try-linux-intel-rel" } builders { + name: "buildbucket/luci.chromium.try/gpu-fyi-try-linux-intel-skv" + } + builders { name: "buildbucket/luci.chromium.try/gpu-fyi-try-linux-nvidia-dbg" } builders {
diff --git a/infra/config/luci-scheduler.cfg b/infra/config/luci-scheduler.cfg index e6648d5..2175d98 100644 --- a/infra/config/luci-scheduler.cfg +++ b/infra/config/luci-scheduler.cfg
@@ -344,6 +344,7 @@ triggers: "ios13-sdk-device" triggers: "ios13-sdk-simulator" triggers: "linux-annotator-rel" + triggers: "linux-bfcache-rel" triggers: "linux-blink-animation-use-time-delta" triggers: "linux-blink-heap-concurrent-marking-tsan-rel" triggers: "linux-blink-heap-verification" @@ -1530,6 +1531,17 @@ } job { + id: "Linux FYI SkiaRenderer Vulkan (Intel HD 630)" + # Triggered by "GPU FYI Linux Builder". + acl_sets: "triggered-by-parent-builders" + buildbucket: { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "Linux FYI SkiaRenderer Vulkan (Intel HD 630)" + } +} + +job { id: "Linux FYI SkiaRenderer Vulkan (NVIDIA)" # Triggered by "GPU FYI Linux Builder". acl_sets: "triggered-by-parent-builders" @@ -1794,6 +1806,16 @@ } job { + id: "linux-bfcache-rel" + acl_sets: "default" + buildbucket: { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "linux-bfcache-rel" + } +} + +job { id: "linux-fieldtrial-rel" acl_sets: "default" buildbucket: {
diff --git a/ios/chrome/browser/metrics/BUILD.gn b/ios/chrome/browser/metrics/BUILD.gn index 0c0c42e..a9dc481 100644 --- a/ios/chrome/browser/metrics/BUILD.gn +++ b/ios/chrome/browser/metrics/BUILD.gn
@@ -61,8 +61,6 @@ "ios_profile_session_durations_service.mm", "ios_profile_session_durations_service_factory.h", "ios_profile_session_durations_service_factory.mm", - "ios_user_type_metrics_provider.h", - "ios_user_type_metrics_provider.mm", "mobile_session_shutdown_metrics_provider.h", "mobile_session_shutdown_metrics_provider.mm", "previous_session_info.h", @@ -271,6 +269,7 @@ "//ios/chrome/browser/ui/popup_menu:constants", "//ios/chrome/browser/ui/util", "//ios/chrome/browser/web_state_list", + "//ios/chrome/test:eg_test_support", "//ios/chrome/test/app:test_support", "//ios/chrome/test/earl_grey:test_support", "//ui/base",
diff --git a/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.mm b/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.mm index 24c20d7..19c5877 100644 --- a/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.mm +++ b/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.mm
@@ -55,7 +55,6 @@ #include "ios/chrome/browser/history/history_service_factory.h" #include "ios/chrome/browser/metrics/chrome_browser_state_client.h" #include "ios/chrome/browser/metrics/ios_chrome_stability_metrics_provider.h" -#include "ios/chrome/browser/metrics/ios_user_type_metrics_provider.h" #include "ios/chrome/browser/metrics/mobile_session_shutdown_metrics_provider.h" #include "ios/chrome/browser/signin/ios_chrome_signin_status_metrics_provider_delegate.h" #include "ios/chrome/browser/sync/device_info_sync_service_factory.h" @@ -243,9 +242,6 @@ std::make_unique<translate::TranslateRankerMetricsProvider>()); metrics_service_->RegisterMetricsProvider( - std::make_unique<IOSUserTypeMetricsProvider>()); - - metrics_service_->RegisterMetricsProvider( std::make_unique<metrics::DemographicMetricsProvider>( std::make_unique<metrics::ChromeBrowserStateClient>())); }
diff --git a/ios/chrome/browser/metrics/ios_user_type_metrics_provider.h b/ios/chrome/browser/metrics/ios_user_type_metrics_provider.h deleted file mode 100644 index efc91ce..0000000 --- a/ios/chrome/browser/metrics/ios_user_type_metrics_provider.h +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_METRICS_IOS_USER_TYPE_METRICS_PROVIDER_H_ -#define IOS_CHROME_BROWSER_METRICS_IOS_USER_TYPE_METRICS_PROVIDER_H_ - -#include "base/macros.h" -#include "components/metrics/metrics_provider.h" - -// IOSUserTypeMetricsProvider logs user type related metrics. -class IOSUserTypeMetricsProvider : public metrics::MetricsProvider { - public: - IOSUserTypeMetricsProvider(); - ~IOSUserTypeMetricsProvider() override; - - // metrics::MetricsDataProvider: - void ProvideCurrentSessionData( - metrics::ChromeUserMetricsExtension* uma_proto) override; - - private: - DISALLOW_COPY_AND_ASSIGN(IOSUserTypeMetricsProvider); -}; - -#endif // IOS_CHROME_BROWSER_METRICS_IOS_USER_TYPE_METRICS_PROVIDER_H_
diff --git a/ios/chrome/browser/metrics/ios_user_type_metrics_provider.mm b/ios/chrome/browser/metrics/ios_user_type_metrics_provider.mm deleted file mode 100644 index 579c587..0000000 --- a/ios/chrome/browser/metrics/ios_user_type_metrics_provider.mm +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ios/chrome/browser/metrics/ios_user_type_metrics_provider.h" - -#include "ios/public/provider/chrome/browser/chrome_browser_provider.h" -#include "ios/public/provider/chrome/browser/user/special_user_provider.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -IOSUserTypeMetricsProvider::IOSUserTypeMetricsProvider() {} - -IOSUserTypeMetricsProvider::~IOSUserTypeMetricsProvider() {} - -void IOSUserTypeMetricsProvider::ProvideCurrentSessionData( - metrics::ChromeUserMetricsExtension* uma_proto) { - ios::GetChromeBrowserProvider() - ->GetSpecialUserProvider() - ->RecordUserTypeMetrics(); -}
diff --git a/ios/chrome/browser/metrics/tab_usage_recorder_test_util.mm b/ios/chrome/browser/metrics/tab_usage_recorder_test_util.mm index abb2b6d0..142e231 100644 --- a/ios/chrome/browser/metrics/tab_usage_recorder_test_util.mm +++ b/ios/chrome/browser/metrics/tab_usage_recorder_test_util.mm
@@ -20,6 +20,7 @@ #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" +#import "ios/chrome/test/scoped_eg_synchronization_disabler.h" #import "ios/testing/nserror_util.h" #include "ui/base/l10n/l10n_util_mac.h" @@ -94,18 +95,15 @@ [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCellAtIndex( tab_index)] performAction:grey_tap()]; + BOOL success = NO; // Turn off synchronization of GREYAssert to test the pending states. - [[GREYConfiguration sharedInstance] - setValue:@(NO) - forConfigKey:kGREYConfigKeySynchronizationEnabled]; + { + ScopedSynchronizationDisabler disabler; + success = WaitUntilConditionOrTimeout(kWaitElementTimeout, ^{ + return ![ChromeEarlGrey isIncognitoMode]; + }); + } - bool success = WaitUntilConditionOrTimeout(kWaitElementTimeout, ^{ - return ![ChromeEarlGrey isIncognitoMode]; - }); - - [[GREYConfiguration sharedInstance] - setValue:@(YES) - forConfigKey:kGREYConfigKeySynchronizationEnabled]; if (!success) { // TODO(crbug.com/951600): Avoid asserting directly unless the test fails, // due to timing issues.
diff --git a/ios/chrome/browser/ui/autofill/BUILD.gn b/ios/chrome/browser/ui/autofill/BUILD.gn index d54d0ac1..9f317a3 100644 --- a/ios/chrome/browser/ui/autofill/BUILD.gn +++ b/ios/chrome/browser/ui/autofill/BUILD.gn
@@ -145,6 +145,7 @@ "//components/leveldb_proto", "//components/strings:components_strings_grit", "//ios/chrome/browser/autofill", + "//ios/chrome/test:eg_test_support", "//ios/chrome/test/app:test_support", "//ios/chrome/test/earl_grey:test_support", "//ios/web/public/js_messaging",
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn b/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn index b45c715..e8bd34d 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn +++ b/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn
@@ -216,6 +216,7 @@ "//ios/chrome/browser/ui/settings/autofill", "//ios/chrome/browser/ui/settings/password", "//ios/chrome/browser/ui/util", + "//ios/chrome/test:eg_test_support", "//ios/chrome/test/app:test_support", "//ios/chrome/test/earl_grey:test_support", "//ios/testing/earl_grey:earl_grey_support",
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/keyboard_observer_egtest.mm b/ios/chrome/browser/ui/autofill/manual_fill/keyboard_observer_egtest.mm index 0d26b3d9..1d4ac33 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/keyboard_observer_egtest.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/keyboard_observer_egtest.mm
@@ -14,6 +14,7 @@ #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h" +#import "ios/chrome/test/scoped_eg_synchronization_disabler.h" #import "ios/web/public/test/earl_grey/web_view_actions.h" #import "ios/web/public/test/earl_grey/web_view_matchers.h" #include "ios/web/public/test/element_selector.h" @@ -99,27 +100,19 @@ "http://ios/testing/data/http_server_files/multi_field_form.html"); [ChromeEarlGrey loadURL:URL]; [ChromeEarlGrey waitForWebStateContainingText:"hello!"]; - - // Opening the keyboard from a webview blocks EarlGrey's synchronization. - [[GREYConfiguration sharedInstance] - setValue:@NO - forConfigKey:kGREYConfigKeySynchronizationEnabled]; } - (void)tearDown { self.notificationToken = nil; self.keyboardObserverDelegateMock = nil; self.keyboardObserver = nil; - - // |setUp| disables synchronization. Reenable here. - [[GREYConfiguration sharedInstance] - setValue:@YES - forConfigKey:kGREYConfigKeySynchronizationEnabled]; [super tearDown]; } // Tests the observer correctly identifies when the keyboard stays on screen. - (void)testKeyboardDidStayOnScreen { + // Opening the keyboard from a webview blocks EarlGrey's synchronization. + ScopedSynchronizationDisabler disabler; // Brings up the keyboard by tapping on one of the form's field. TapOnWebElementWithID(kFormElementID1); @@ -166,6 +159,8 @@ // Tests that when the keyboard actually dismiss the right callback is done. // TODO(crbug.com/914374): Address flakiness and reenable. - (void)DISABLED_testKeyboardDidHide { + // Opening the keyboard from a webview blocks EarlGrey's synchronization. + ScopedSynchronizationDisabler disabler; // Brings up the keyboard by tapping on one of the form's field. TapOnWebElementWithID(kFormElementID1);
diff --git a/ios/chrome/browser/ui/autofill/save_card_infobar_egtest.mm b/ios/chrome/browser/ui/autofill/save_card_infobar_egtest.mm index 9e7bcf47..5bf86cad 100644 --- a/ios/chrome/browser/ui/autofill/save_card_infobar_egtest.mm +++ b/ios/chrome/browser/ui/autofill/save_card_infobar_egtest.mm
@@ -26,6 +26,7 @@ #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h" +#import "ios/chrome/test/scoped_eg_synchronization_disabler.h" #import "ios/web/public/js_messaging/web_frames_manager.h" #import "ios/web/public/test/http_server/http_server.h" #import "ios/web/public/web_state/web_state.h" @@ -497,21 +498,15 @@ @"Save card infobar failed to show."); // Disable EarlGrey's synchronization since it's blocked by infobar animation. - [[GREYConfiguration sharedInstance] - setValue:@NO - forConfigKey:kGREYConfigKeySynchronizationEnabled]; - - [self resetEventWaiterForEvents:{InfobarEvent::SENT_UPLOAD_CARD_REQUEST} - timeout:kWaitForDownloadTimeout]; - // Tap the save button. - [[EarlGrey selectElementWithMatcher:saveButtonMatcher()] - performAction:grey_tap()]; - [self waitForEvents]; - - // Reenable synchronization now that the infobar animation is over. - [[GREYConfiguration sharedInstance] - setValue:@YES - forConfigKey:kGREYConfigKeySynchronizationEnabled]; + { + ScopedSynchronizationDisabler disabler; + [self resetEventWaiterForEvents:{InfobarEvent::SENT_UPLOAD_CARD_REQUEST} + timeout:kWaitForDownloadTimeout]; + // Tap the save button. + [[EarlGrey selectElementWithMatcher:saveButtonMatcher()] + performAction:grey_tap()]; + [self waitForEvents]; + } // Wait until the save card infobar disappears. GREYAssert([self waitForUIElementToDisappearOrTimeout:
diff --git a/ios/chrome/browser/ui/bookmarks/resources/bookmark_blue_check.imageset/Contents.json b/ios/chrome/browser/ui/bookmarks/resources/bookmark_blue_check.imageset/Contents.json index b1d6305..2616c6fd 100644 --- a/ios/chrome/browser/ui/bookmarks/resources/bookmark_blue_check.imageset/Contents.json +++ b/ios/chrome/browser/ui/bookmarks/resources/bookmark_blue_check.imageset/Contents.json
@@ -2,11 +2,6 @@ "images": [ { "idiom": "universal", - "scale": "1x", - "filename": "bookmark_blue_check.png" - }, - { - "idiom": "universal", "scale": "2x", "filename": "bookmark_blue_check@2x.png" },
diff --git a/ios/chrome/browser/ui/bookmarks/resources/bookmark_blue_folder.imageset/Contents.json b/ios/chrome/browser/ui/bookmarks/resources/bookmark_blue_folder.imageset/Contents.json index fb9f144..981b052 100644 --- a/ios/chrome/browser/ui/bookmarks/resources/bookmark_blue_folder.imageset/Contents.json +++ b/ios/chrome/browser/ui/bookmarks/resources/bookmark_blue_folder.imageset/Contents.json
@@ -2,11 +2,6 @@ "images": [ { "idiom": "universal", - "scale": "1x", - "filename": "bookmark_blue_folder.png" - }, - { - "idiom": "universal", "scale": "2x", "filename": "bookmark_blue_folder@2x.png" },
diff --git a/ios/chrome/browser/ui/bookmarks/resources/bookmark_blue_new_folder.imageset/Contents.json b/ios/chrome/browser/ui/bookmarks/resources/bookmark_blue_new_folder.imageset/Contents.json index 669c2ec3..42a82456 100644 --- a/ios/chrome/browser/ui/bookmarks/resources/bookmark_blue_new_folder.imageset/Contents.json +++ b/ios/chrome/browser/ui/bookmarks/resources/bookmark_blue_new_folder.imageset/Contents.json
@@ -2,11 +2,6 @@ "images": [ { "idiom": "universal", - "scale": "1x", - "filename": "bookmark_blue_new_folder.png" - }, - { - "idiom": "universal", "scale": "2x", "filename": "bookmark_blue_new_folder@2x.png" },
diff --git a/ios/chrome/browser/ui/dialogs/BUILD.gn b/ios/chrome/browser/ui/dialogs/BUILD.gn index 1ae4f03..4ca0224 100644 --- a/ios/chrome/browser/ui/dialogs/BUILD.gn +++ b/ios/chrome/browser/ui/dialogs/BUILD.gn
@@ -131,6 +131,7 @@ "//components/url_formatter", "//ios/chrome/app/strings", "//ios/chrome/browser/ui/util", + "//ios/chrome/test:eg_test_support", "//ios/chrome/test/app:test_support", "//ios/chrome/test/earl_grey:test_support", "//ios/testing/earl_grey:earl_grey_support",
diff --git a/ios/chrome/browser/ui/dialogs/javascript_dialog_egtest.mm b/ios/chrome/browser/ui/dialogs/javascript_dialog_egtest.mm index 1b213f4..65468f5 100644 --- a/ios/chrome/browser/ui/dialogs/javascript_dialog_egtest.mm +++ b/ios/chrome/browser/ui/dialogs/javascript_dialog_egtest.mm
@@ -23,6 +23,7 @@ #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h" +#import "ios/chrome/test/scoped_eg_synchronization_disabler.h" #include "ios/testing/earl_grey/disabled_test_macros.h" #import "ios/testing/earl_grey/matchers.h" #import "ios/web/public/test/earl_grey/web_view_matchers.h" @@ -376,11 +377,6 @@ chrome_test_util::ButtonWithAccessibilityLabelId(IDS_OK); [[EarlGrey selectElementWithMatcher:OKButton] performAction:grey_tap() error:&errorOK]; - // Reenable synchronization in case it was disabled by a test. See comments - // in testShowJavaScriptAfterNewTabAnimation for details. - [[GREYConfiguration sharedInstance] - setValue:@(YES) - forConfigKey:kGREYConfigKeySynchronizationEnabled]; if (!errorOK || !errorCancel) { GREYFail(@"There are still alerts"); @@ -607,28 +603,23 @@ // continues to animate until the dialog is closed. Disabling EarlGrey // synchronization code for iPad allows the test to detect and dismiss the // dialog while this animation is occurring. - if ([ChromeEarlGrey isIPadIdiom]) { - [[GREYConfiguration sharedInstance] - setValue:@(NO) - forConfigKey:kGREYConfigKeySynchronizationEnabled]; - } + { + std::unique_ptr<ScopedSynchronizationDisabler> disabler = + std::make_unique<ScopedSynchronizationDisabler>(); + if (![ChromeEarlGrey isIPadIdiom]) { + disabler.reset(); + } - // Wait for the alert to be shown. - WaitForJavaScriptDialogToBeShown(self.onLoadPageURL); + // Wait for the alert to be shown. + WaitForJavaScriptDialogToBeShown(self.onLoadPageURL); - // Verify that the omnibox shows the correct URL when the dialog is visible. - std::string title = - base::UTF16ToUTF8(web::GetDisplayTitleForUrl(self.onLoadPageURL)); - [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText(title)] - assertWithMatcher:grey_notNil()]; + // Verify that the omnibox shows the correct URL when the dialog is visible. + std::string title = + base::UTF16ToUTF8(web::GetDisplayTitleForUrl(self.onLoadPageURL)); + [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText(title)] + assertWithMatcher:grey_notNil()]; - [[EarlGrey selectElementWithMatcher:OKButton()] performAction:grey_tap()]; - - // Reenable synchronization on iPads now that the dialog has been dismissed. - if ([ChromeEarlGrey isIPadIdiom]) { - [[GREYConfiguration sharedInstance] - setValue:@(YES) - forConfigKey:kGREYConfigKeySynchronizationEnabled]; + [[EarlGrey selectElementWithMatcher:OKButton()] performAction:grey_tap()]; } }
diff --git a/ios/chrome/browser/ui/fullscreen/BUILD.gn b/ios/chrome/browser/ui/fullscreen/BUILD.gn index d7bc9e5..4728a8d8 100644 --- a/ios/chrome/browser/ui/fullscreen/BUILD.gn +++ b/ios/chrome/browser/ui/fullscreen/BUILD.gn
@@ -170,6 +170,7 @@ "//base/test:test_support", "//ios/chrome/browser/ui/side_swipe", "//ios/chrome/browser/ui/util", + "//ios/chrome/test:eg_test_support", "//ios/chrome/test/app:test_support", "//ios/chrome/test/earl_grey:test_support", "//ios/web:earl_grey_test_support",
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_egtest.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_egtest.mm index e53da1b..2db1855 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_egtest.mm +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_egtest.mm
@@ -19,6 +19,7 @@ #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h" +#import "ios/chrome/test/scoped_eg_synchronization_disabler.h" #import "ios/web/common/features.h" #import "ios/web/public/test/earl_grey/web_view_matchers.h" #import "ios/web/public/test/http_server/error_page_response_provider.h" @@ -123,31 +124,28 @@ "http://ios/testing/data/http_server_files/single_page_wide.pdf"); [ChromeEarlGrey loadURL:URL]; - // TODO(crbug.com/852393): Investigate why synchronization isn't working. Is - // an animation going on forever? - if (@available(iOS 12, *)) { - [[GREYConfiguration sharedInstance] - setValue:@NO - forConfigKey:kGREYConfigKeySynchronizationEnabled]; - } + { + std::unique_ptr<ScopedSynchronizationDisabler> disabler = + std::make_unique<ScopedSynchronizationDisabler>(); + // TODO(crbug.com/852393): Investigate why synchronization isn't working. Is + // an animation going on forever? + if (@available(iOS 12, *)) { + // Disabled synchonization needs only for iOS 12. + } else { + disabler.reset(); + } - // Test that the toolbar is still visible after a user swipes down. - [[EarlGrey - selectElementWithMatcher:WebViewScrollView( - chrome_test_util::GetCurrentWebState())] - performAction:grey_swipeFastInDirection(kGREYDirectionDown)]; - [ChromeEarlGreyUI waitForToolbarVisible:YES]; + // Test that the toolbar is still visible after a user swipes down. + [[EarlGrey + selectElementWithMatcher:WebViewScrollView( + chrome_test_util::GetCurrentWebState())] + performAction:grey_swipeFastInDirection(kGREYDirectionDown)]; + [ChromeEarlGreyUI waitForToolbarVisible:YES]; - // Test that the toolbar is still visible even after attempting to hide it - // on swipe up. - HideToolbarUsingUI(); - [ChromeEarlGreyUI waitForToolbarVisible:YES]; - - // Reenable synchronization. - if (@available(iOS 12, *)) { - [[GREYConfiguration sharedInstance] - setValue:@YES - forConfigKey:kGREYConfigKeySynchronizationEnabled]; + // Test that the toolbar is still visible even after attempting to hide it + // on swipe up. + HideToolbarUsingUI(); + [ChromeEarlGreyUI waitForToolbarVisible:YES]; } }
diff --git a/ios/chrome/browser/ui/payments/BUILD.gn b/ios/chrome/browser/ui/payments/BUILD.gn index 8718dbc..9923339 100644 --- a/ios/chrome/browser/ui/payments/BUILD.gn +++ b/ios/chrome/browser/ui/payments/BUILD.gn
@@ -304,6 +304,7 @@ "//ios/chrome/browser/ui/popup_menu:constants", "//ios/chrome/browser/ui/settings", "//ios/chrome/browser/ui/settings/autofill", + "//ios/chrome/test:eg_test_support", "//ios/chrome/test/app:test_support", "//ios/chrome/test/earl_grey:test_support", "//ios/testing/earl_grey:earl_grey_support",
diff --git a/ios/chrome/browser/ui/payments/payment_request_show_egtest.mm b/ios/chrome/browser/ui/payments/payment_request_show_egtest.mm index 59c96f6..444e7125 100644 --- a/ios/chrome/browser/ui/payments/payment_request_show_egtest.mm +++ b/ios/chrome/browser/ui/payments/payment_request_show_egtest.mm
@@ -11,6 +11,7 @@ #import "ios/chrome/browser/ui/payments/payment_request_error_view_controller.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" +#import "ios/chrome/test/scoped_eg_synchronization_disabler.h" #import "ios/web/public/test/http_server/http_server.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -85,51 +86,47 @@ // Buy button is enabled. - (void)testBuyWithResolvingPromise { [ChromeEarlGrey loadURL:web::test::HttpServer::MakeUrl(kShowPromisePage)]; + { + // Disable EarlGrey's synchronization. Needed likely due to + // MDCActivityIndicator being present on the payment request view. + ScopedSynchronizationDisabler disabler; - // Disable EarlGrey's synchronization. Needed likely due to - // MDCActivityIndicator being present on the payment request view. - [[GREYConfiguration sharedInstance] - setValue:@NO - forConfigKey:kGREYConfigKeySynchronizationEnabled]; + [ChromeEarlGrey tapWebStateElementWithID:@"buyWithResolvingPromise"]; - [ChromeEarlGrey tapWebStateElementWithID:@"buyWithResolvingPromise"]; + // Wait until the payment request view shows. + ConditionBlock condition = ^{ + NSError* error = nil; + [[EarlGrey + selectElementWithMatcher:chrome_test_util::PaymentRequestView()] + assertWithMatcher:grey_notNil() + error:&error]; + return error == nil; + }; + GREYAssert(WaitUntilConditionOrTimeout(kShowPromiseTimeout, condition), + @"Payment request view failed to show."); - // Wait until the payment request view shows. - ConditionBlock condition = ^{ - NSError* error = nil; - [[EarlGrey selectElementWithMatcher:chrome_test_util::PaymentRequestView()] - assertWithMatcher:grey_notNil() - error:&error]; - return error == nil; - }; - GREYAssert(WaitUntilConditionOrTimeout(kShowPromiseTimeout, condition), - @"Payment request view failed to show."); - - // Verify that the Buy button is not enabled. - [[EarlGrey selectElementWithMatcher:ButtonWithAccessibilityLabelId( - IDS_PAYMENTS_PAY_BUTTON)] - assertWithMatcher:grey_not(grey_enabled())]; - - // Wait until the Buy button becomes enabled. - condition = ^{ - NSError* error = nil; + // Verify that the Buy button is not enabled. [[EarlGrey selectElementWithMatcher:ButtonWithAccessibilityLabelId( IDS_PAYMENTS_PAY_BUTTON)] - assertWithMatcher:grey_enabled() - error:&error]; - return error == nil; - }; - GREYAssert(WaitUntilConditionOrTimeout(kShowPromiseTimeout, condition), - @"Show promise failed to resolve."); + assertWithMatcher:grey_not(grey_enabled())]; - // Verify that the updated total amount is displayed. - [[EarlGrey selectElementWithMatcher:PriceCellMatcher(@"Donation, USD $0.99")] - assertWithMatcher:grey_notNil()]; + // Wait until the Buy button becomes enabled. + condition = ^{ + NSError* error = nil; + [[EarlGrey selectElementWithMatcher:ButtonWithAccessibilityLabelId( + IDS_PAYMENTS_PAY_BUTTON)] + assertWithMatcher:grey_enabled() + error:&error]; + return error == nil; + }; + GREYAssert(WaitUntilConditionOrTimeout(kShowPromiseTimeout, condition), + @"Show promise failed to resolve."); - // Reenable EarlGrey's synchronization. - [[GREYConfiguration sharedInstance] - setValue:@YES - forConfigKey:kGREYConfigKeySynchronizationEnabled]; + // Verify that the updated total amount is displayed. + [[EarlGrey + selectElementWithMatcher:PriceCellMatcher(@"Donation, USD $0.99")] + assertWithMatcher:grey_notNil()]; + } } // Tests when PaymentRequest.show() is called with a promise, the payment sheet @@ -140,44 +137,40 @@ // Disable EarlGrey's synchronization. Needed likely due to // MDCActivityIndicator being present on the payment request view. - [[GREYConfiguration sharedInstance] - setValue:@NO - forConfigKey:kGREYConfigKeySynchronizationEnabled]; + { + ScopedSynchronizationDisabler disabler; - [ChromeEarlGrey tapWebStateElementWithID:@"buyWithRejectingPromise"]; + [ChromeEarlGrey tapWebStateElementWithID:@"buyWithRejectingPromise"]; - // Wait until the payment request view shows. - ConditionBlock condition = ^{ - NSError* error = nil; - [[EarlGrey selectElementWithMatcher:chrome_test_util::PaymentRequestView()] - assertWithMatcher:grey_notNil() - error:&error]; - return error == nil; - }; - GREYAssert(WaitUntilConditionOrTimeout(kShowPromiseTimeout, condition), - @"Payment request view failed to show."); + // Wait until the payment request view shows. + ConditionBlock condition = ^{ + NSError* error = nil; + [[EarlGrey + selectElementWithMatcher:chrome_test_util::PaymentRequestView()] + assertWithMatcher:grey_notNil() + error:&error]; + return error == nil; + }; + GREYAssert(WaitUntilConditionOrTimeout(kShowPromiseTimeout, condition), + @"Payment request view failed to show."); - // Verify that the Buy button is not enabled. - [[EarlGrey selectElementWithMatcher:ButtonWithAccessibilityLabelId( - IDS_PAYMENTS_PAY_BUTTON)] - assertWithMatcher:grey_not(grey_enabled())]; + // Verify that the Buy button is not enabled. + [[EarlGrey selectElementWithMatcher:ButtonWithAccessibilityLabelId( + IDS_PAYMENTS_PAY_BUTTON)] + assertWithMatcher:grey_not(grey_enabled())]; - // Wait until the error screen becomes visible. - condition = ^{ - NSError* error = nil; - [[EarlGrey - selectElementWithMatcher:chrome_test_util::PaymentRequestErrorView()] - assertWithMatcher:grey_notNil() - error:&error]; - return error == nil; - }; - GREYAssert(WaitUntilConditionOrTimeout(kShowPromiseTimeout, condition), - @"Show promise failed to resolve."); - - // Reenable EarlGrey's synchronization. - [[GREYConfiguration sharedInstance] - setValue:@YES - forConfigKey:kGREYConfigKeySynchronizationEnabled]; + // Wait until the error screen becomes visible. + condition = ^{ + NSError* error = nil; + [[EarlGrey + selectElementWithMatcher:chrome_test_util::PaymentRequestErrorView()] + assertWithMatcher:grey_notNil() + error:&error]; + return error == nil; + }; + GREYAssert(WaitUntilConditionOrTimeout(kShowPromiseTimeout, condition), + @"Show promise failed to resolve."); + } // Confirm the error. [[EarlGrey
diff --git a/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_mediator.mm b/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_mediator.mm index 5c560fb0..b98f4a6 100644 --- a/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_mediator.mm +++ b/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_mediator.mm
@@ -51,24 +51,13 @@ expirationMonth:(NSString*)expirationMonth expirationYear:(NSString*)expirationYear { autofill::CreditCard creditCard = autofill::CreditCard(); + [self updateCreditCard:&creditCard + cardHolderName:cardHolderName + cardNumber:cardNumber + expirationMonth:expirationMonth + expirationYear:expirationYear]; - const std::string& appLocal = GetApplicationContext()->GetApplicationLocale(); - creditCard.SetInfo(autofill::AutofillType(AutofillTypeFromAutofillUIType( - AutofillUITypeCreditCardHolderFullName)), - base::SysNSStringToUTF16(cardHolderName), appLocal); - - creditCard.SetInfo(autofill::AutofillType(AutofillTypeFromAutofillUIType( - AutofillUITypeCreditCardNumber)), - base::SysNSStringToUTF16(cardNumber), appLocal); - - creditCard.SetInfo(autofill::AutofillType(AutofillTypeFromAutofillUIType( - AutofillUITypeCreditCardExpMonth)), - base::SysNSStringToUTF16(expirationMonth), appLocal); - - creditCard.SetInfo(autofill::AutofillType(AutofillTypeFromAutofillUIType( - AutofillUITypeCreditCardExpYear)), - base::SysNSStringToUTF16(expirationYear), appLocal); - + // Validates the credit card number and expiration date. if (!creditCard.HasValidCardNumber()) { [self.addCreditCardMediatorDelegate creditCardMediatorHasInvalidCardNumber:self]; @@ -81,7 +70,27 @@ return; } - self.personalDataManager->AddCreditCard(creditCard); + autofill::CreditCard* savedCreditCard = + self.personalDataManager->GetCreditCardByNumber( + base::SysNSStringToUTF8(cardNumber)); + + // If the credit card number already exist in saved credit card + // |savedCreditCard| then update saved credit card |savedCreditCardCopy| + // with the new data. + if (savedCreditCard != nil) { + autofill::CreditCard savedCreditCardCopy(*savedCreditCard); + + [self updateCreditCard:&savedCreditCardCopy + cardHolderName:cardHolderName + cardNumber:cardNumber + expirationMonth:expirationMonth + expirationYear:expirationYear]; + + self.personalDataManager->UpdateCreditCard(savedCreditCardCopy); + } else { + self.personalDataManager->AddCreditCard(creditCard); + } + [self.addCreditCardMediatorDelegate creditCardMediatorDidFinish:self]; } @@ -89,4 +98,41 @@ [self.addCreditCardMediatorDelegate creditCardMediatorDidFinish:self]; } +#pragma mark - Private + +// Updates received credit card with received data. +- (void)updateCreditCard:(autofill::CreditCard*)creditCard + cardHolderName:(NSString*)cardHolderName + cardNumber:(NSString*)cardNumber + expirationMonth:(NSString*)expirationMonth + expirationYear:(NSString*)expirationYear { + [self updateCreditCard:creditCard + cardProperty:cardHolderName + autofillUIType:AutofillUITypeCreditCardHolderFullName]; + + [self updateCreditCard:creditCard + cardProperty:cardNumber + autofillUIType:AutofillUITypeCreditCardNumber]; + + [self updateCreditCard:creditCard + cardProperty:expirationMonth + autofillUIType:AutofillUITypeCreditCardExpMonth]; + + [self updateCreditCard:creditCard + cardProperty:expirationYear + autofillUIType:AutofillUITypeCreditCardExpYear]; +} + +// Updates the |AutofillUIType| of the |creditCard| with the value of +// |cardProperty|. +- (void)updateCreditCard:(autofill::CreditCard*)creditCard + cardProperty:(NSString*)cardValue + autofillUIType:(AutofillUIType)fieldType { + const std::string& appLocal = GetApplicationContext()->GetApplicationLocale(); + + creditCard->SetInfo( + autofill::AutofillType(AutofillTypeFromAutofillUIType(fieldType)), + base::SysNSStringToUTF16(cardValue), appLocal); +} + @end
diff --git a/ios/chrome/browser/ui/signin_interaction/BUILD.gn b/ios/chrome/browser/ui/signin_interaction/BUILD.gn index 3766d69..6b7ab43 100644 --- a/ios/chrome/browser/ui/signin_interaction/BUILD.gn +++ b/ios/chrome/browser/ui/signin_interaction/BUILD.gn
@@ -77,6 +77,7 @@ "//ios/chrome/browser/ui/table_view/cells", "//ios/chrome/browser/ui/util", "//ios/chrome/browser/web_state_list", + "//ios/chrome/test:eg_test_support", "//ios/chrome/test/app:test_support", "//ios/chrome/test/earl_grey:test_support", "//ios/public/provider/chrome/browser/signin:test_support",
diff --git a/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm b/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm index 26e58edb..cfac49ca 100644 --- a/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm +++ b/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm
@@ -29,6 +29,7 @@ #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h" +#import "ios/chrome/test/scoped_eg_synchronization_disabler.h" #import "ios/public/provider/chrome/browser/signin/fake_chrome_identity.h" #import "ios/public/provider/chrome/browser/signin/fake_chrome_identity_service.h" #import "ios/web/public/web_state/web_state.h" @@ -162,12 +163,13 @@ [ChromeEarlGreyUI tapSettingsMenuButton:SecondarySignInButton()]; [SigninEarlGreyUI selectIdentityWithEmail:identity.userEmail]; - // Synchronization off due to an infinite spinner. - SetEarlGreySynchronizationEnabled(NO); - WaitForMatcher(chrome_test_util::ButtonWithAccessibilityLabelId( - IDS_IOS_MANAGED_SIGNIN_ACCEPT_BUTTON)); - TapButtonWithLabelId(IDS_IOS_MANAGED_SIGNIN_ACCEPT_BUTTON); - SetEarlGreySynchronizationEnabled(YES); + { + // Synchronization off due to an infinite spinner. + ScopedSynchronizationDisabler disabler; + WaitForMatcher(chrome_test_util::ButtonWithAccessibilityLabelId( + IDS_IOS_MANAGED_SIGNIN_ACCEPT_BUTTON)); + TapButtonWithLabelId(IDS_IOS_MANAGED_SIGNIN_ACCEPT_BUTTON); + } [SigninEarlGreyUI confirmSigninConfirmationDialog]; [SigninEarlGreyUtils checkSignedInWithIdentity:identity];
diff --git a/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest_util.h b/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest_util.h index a8f64ae..a4c1fa2 100644 --- a/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest_util.h +++ b/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest_util.h
@@ -8,9 +8,6 @@ #import <EarlGrey/EarlGrey.h> #import <Foundation/Foundation.h> -// Changes the EarlGrey synchronization status to |enabled|. -void SetEarlGreySynchronizationEnabled(BOOL enabled); - // Taps the button with accessibility label |label|. void TapButtonWithAccessibilityLabel(NSString* label);
diff --git a/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest_util.mm b/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest_util.mm index 92037e39..c7902f1 100644 --- a/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest_util.mm +++ b/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest_util.mm
@@ -17,12 +17,6 @@ #error "This file requires ARC support." #endif -void SetEarlGreySynchronizationEnabled(BOOL enabled) { - [[GREYConfiguration sharedInstance] - setValue:[NSNumber numberWithBool:enabled] - forConfigKey:kGREYConfigKeySynchronizationEnabled]; -} - void TapButtonWithAccessibilityLabel(NSString* label) { id<GREYMatcher> matcher = chrome_test_util::ButtonWithAccessibilityLabel(label);
diff --git a/ios/chrome/browser/web/chrome_web_client.h b/ios/chrome/browser/web/chrome_web_client.h index 259af279..e81ab7f 100644 --- a/ios/chrome/browser/web/chrome_web_client.h +++ b/ios/chrome/browser/web/chrome_web_client.h
@@ -34,7 +34,6 @@ int resource_id, ui::ScaleFactor scale_factor) const override; base::RefCountedMemory* GetDataResourceBytes(int resource_id) const override; - bool IsDataResourceGzipped(int resource_id) const override; void GetAdditionalWebUISchemes( std::vector<std::string>* additional_schemes) override; void PostBrowserURLRewriterCreation(
diff --git a/ios/chrome/browser/web/chrome_web_client.mm b/ios/chrome/browser/web/chrome_web_client.mm index aeb0edcc..fd42dcf 100644 --- a/ios/chrome/browser/web/chrome_web_client.mm +++ b/ios/chrome/browser/web/chrome_web_client.mm
@@ -145,10 +145,6 @@ resource_id); } -bool ChromeWebClient::IsDataResourceGzipped(int resource_id) const { - return ui::ResourceBundle::GetSharedInstance().IsGzipped(resource_id); -} - void ChromeWebClient::GetAdditionalWebUISchemes( std::vector<std::string>* additional_schemes) { additional_schemes->push_back(dom_distiller::kDomDistillerScheme);
diff --git a/ios/chrome/browser/web/forms_egtest.mm b/ios/chrome/browser/web/forms_egtest.mm index 9a2e99a..a04383c 100644 --- a/ios/chrome/browser/web/forms_egtest.mm +++ b/ios/chrome/browser/web/forms_egtest.mm
@@ -614,53 +614,48 @@ - (void)submitFormUsingKeyboardGoButtonWithInputID:(const std::string&)ID { // Disable EarlGrey's synchronization since it is blocked by opening the // keyboard from a web view. - [[GREYConfiguration sharedInstance] - setValue:@NO - forConfigKey:kGREYConfigKeySynchronizationEnabled]; + { + ScopedSynchronizationDisabler disabler; - // Wait for web view to be interactable before tapping. - GREYCondition* interactableCondition = [GREYCondition - conditionWithName:@"Wait for web view to be interactable." - block:^BOOL { - NSError* error = nil; - id<GREYMatcher> webViewMatcher = WebViewInWebState( - chrome_test_util::GetCurrentWebState()); - [[EarlGrey selectElementWithMatcher:webViewMatcher] - assertWithMatcher:grey_interactable() - error:&error]; - return !error; - }]; - GREYAssert([interactableCondition - waitWithTimeout:base::test::ios::kWaitForUIElementTimeout], - @"Web view did not become interactable."); + // Wait for web view to be interactable before tapping. + GREYCondition* interactableCondition = [GREYCondition + conditionWithName:@"Wait for web view to be interactable." + block:^BOOL { + NSError* error = nil; + id<GREYMatcher> webViewMatcher = WebViewInWebState( + chrome_test_util::GetCurrentWebState()); + [[EarlGrey selectElementWithMatcher:webViewMatcher] + assertWithMatcher:grey_interactable() + error:&error]; + return !error; + }]; + GREYAssert([interactableCondition + waitWithTimeout:base::test::ios::kWaitForUIElementTimeout], + @"Web view did not become interactable."); - web::WebState* currentWebState = chrome_test_util::GetCurrentWebState(); - [[EarlGrey selectElementWithMatcher:WebViewMatcher()] - performAction:web::WebViewTapElement( - currentWebState, - [ElementSelector selectorWithElementID:ID])]; + web::WebState* currentWebState = chrome_test_util::GetCurrentWebState(); + [[EarlGrey selectElementWithMatcher:WebViewMatcher()] + performAction:web::WebViewTapElement( + currentWebState, + [ElementSelector selectorWithElementID:ID])]; - // Wait until the keyboard shows up before tapping. - GREYCondition* condition = [GREYCondition - conditionWithName:@"Wait for the keyboard to show up." - block:^BOOL { - NSError* error = nil; - [[EarlGrey selectElementWithMatcher:GoButtonMatcher()] - assertWithMatcher:grey_notNil() - error:&error]; - return (error == nil); - }]; - GREYAssert( - [condition waitWithTimeout:base::test::ios::kWaitForUIElementTimeout], - @"No keyboard with 'Go' button showed up."); + // Wait until the keyboard shows up before tapping. + GREYCondition* condition = [GREYCondition + conditionWithName:@"Wait for the keyboard to show up." + block:^BOOL { + NSError* error = nil; + [[EarlGrey selectElementWithMatcher:GoButtonMatcher()] + assertWithMatcher:grey_notNil() + error:&error]; + return (error == nil); + }]; + GREYAssert( + [condition waitWithTimeout:base::test::ios::kWaitForUIElementTimeout], + @"No keyboard with 'Go' button showed up."); - [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Go")] - performAction:grey_tap()]; - - // Reenable synchronization now that the keyboard has been closed. - [[GREYConfiguration sharedInstance] - setValue:@YES - forConfigKey:kGREYConfigKeySynchronizationEnabled]; + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Go")] + performAction:grey_tap()]; + } } @end
diff --git a/ios/chrome/test/earl_grey/chrome_test_case.mm b/ios/chrome/test/earl_grey/chrome_test_case.mm index b62a705..f261c1e 100644 --- a/ios/chrome/test/earl_grey/chrome_test_case.mm +++ b/ios/chrome/test/earl_grey/chrome_test_case.mm
@@ -104,6 +104,12 @@ } // namespace +// Category for overriding private methods on XCTestCase. See crbug.com/991338 +// for more information. +@interface XCTestCase (Private) +- (void)_recordFailure:(id)arg1; +@end + #if defined(CHROME_EARL_GREY_2) GREY_STUB_CLASS_IN_APP_MAIN_QUEUE(ChromeTestCaseAppInterface) #endif @@ -180,6 +186,16 @@ } } +- (void)_recordFailure:(id)arg1 { + if (@available(iOS 13, *)) { + // _recordFailure internally spends a very long time symbolicating + // on iOS13. Skipping this seems to be safe. See crbug.com/991338 + // for more information. + } else { + [super _recordFailure:arg1]; + } +} + #if defined(CHROME_EARL_GREY_1) + (void)setUp { [super setUp];
diff --git a/ios/web/public/test/fakes/test_web_client.h b/ios/web/public/test/fakes/test_web_client.h index 58055ead..f3d3621 100644 --- a/ios/web/public/test/fakes/test_web_client.h +++ b/ios/web/public/test/fakes/test_web_client.h
@@ -36,7 +36,6 @@ base::string16 GetPluginNotSupportedText() const override; base::RefCountedMemory* GetDataResourceBytes(int id) const override; - bool IsDataResourceGzipped(int resource_id) const override; NSString* GetDocumentStartScriptForMainFrame( BrowserState* browser_state) const override;
diff --git a/ios/web/public/test/fakes/test_web_client.mm b/ios/web/public/test/fakes/test_web_client.mm index 1907f0c3..3619656 100644 --- a/ios/web/public/test/fakes/test_web_client.mm +++ b/ios/web/public/test/fakes/test_web_client.mm
@@ -51,12 +51,6 @@ resource_id); } -bool TestWebClient::IsDataResourceGzipped(int resource_id) const { - if (!ui::ResourceBundle::HasSharedInstance()) - return false; - return ui::ResourceBundle::GetSharedInstance().IsGzipped(resource_id); -} - NSString* TestWebClient::GetDocumentStartScriptForMainFrame( BrowserState* browser_state) const { return early_page_script_ ? early_page_script_ : @"";
diff --git a/ios/web/public/web_client.h b/ios/web/public/web_client.h index dfc9e4d0..192c8c8 100644 --- a/ios/web/public/web_client.h +++ b/ios/web/public/web_client.h
@@ -101,9 +101,6 @@ // Returns the raw bytes of a scale independent data resource. virtual base::RefCountedMemory* GetDataResourceBytes(int resource_id) const; - // Returns whether the contents of a resource are compressed (with gzip). - virtual bool IsDataResourceGzipped(int resource_id) const; - // Returns a list of additional WebUI schemes, if any. These additional // schemes act as aliases to the about: scheme. The additional schemes may or // may not serve specific WebUI pages depending on the particular
diff --git a/ios/web/public/webui/url_data_source_ios.h b/ios/web/public/webui/url_data_source_ios.h index 2c0ccde..43e49fb 100644 --- a/ios/web/public/webui/url_data_source_ios.h +++ b/ios/web/public/webui/url_data_source_ios.h
@@ -77,9 +77,6 @@ // happening, return false. It is OK to return false as needed. virtual bool ShouldDenyXFrameOptions() const; - // Whether |path| is gzipped (and should be transmitted gzipped). - virtual bool IsGzipped(const std::string& path) const; - // By default, only chrome: requests are allowed. Override in specific WebUI // data sources to enable for additional schemes or to implement fancier // access control. Typically used in concert with
diff --git a/ios/web/shell/shell_web_client.h b/ios/web/shell/shell_web_client.h index 3a616f57..ba9954f 100644 --- a/ios/web/shell/shell_web_client.h +++ b/ios/web/shell/shell_web_client.h
@@ -27,7 +27,6 @@ int resource_id, ui::ScaleFactor scale_factor) const override; base::RefCountedMemory* GetDataResourceBytes(int resource_id) const override; - bool IsDataResourceGzipped(int resource_id) const override; void BindInterfaceReceiverFromMainFrame( WebState* web_state, mojo::GenericPendingReceiver receiver) override;
diff --git a/ios/web/shell/shell_web_client.mm b/ios/web/shell/shell_web_client.mm index 0f8b952..626cea6 100644 --- a/ios/web/shell/shell_web_client.mm +++ b/ios/web/shell/shell_web_client.mm
@@ -74,10 +74,6 @@ resource_id); } -bool ShellWebClient::IsDataResourceGzipped(int resource_id) const { - return ui::ResourceBundle::GetSharedInstance().IsGzipped(resource_id); -} - void ShellWebClient::BindInterfaceReceiverFromMainFrame( WebState* web_state, mojo::GenericPendingReceiver receiver) {
diff --git a/ios/web/web_client.mm b/ios/web/web_client.mm index 86e520e..8a2ed50 100644 --- a/ios/web/web_client.mm +++ b/ios/web/web_client.mm
@@ -66,10 +66,6 @@ return nullptr; } -bool WebClient::IsDataResourceGzipped(int resource_id) const { - return false; -} - NSString* WebClient::GetDocumentStartScriptForAllFrames( BrowserState* browser_state) const { return @"";
diff --git a/ios/web/webui/shared_resources_data_source_ios.h b/ios/web/webui/shared_resources_data_source_ios.h index 4751719..82bddd4 100644 --- a/ios/web/webui/shared_resources_data_source_ios.h +++ b/ios/web/webui/shared_resources_data_source_ios.h
@@ -22,7 +22,6 @@ const std::string& path, const URLDataSourceIOS::GotDataCallback& callback) override; std::string GetMimeType(const std::string& path) const override; - bool IsGzipped(const std::string& path) const override; private: ~SharedResourcesDataSourceIOS() override;
diff --git a/ios/web/webui/shared_resources_data_source_ios.mm b/ios/web/webui/shared_resources_data_source_ios.mm index b386a6ce..9578687 100644 --- a/ios/web/webui/shared_resources_data_source_ios.mm +++ b/ios/web/webui/shared_resources_data_source_ios.mm
@@ -74,10 +74,4 @@ return mime_type; } -bool SharedResourcesDataSourceIOS::IsGzipped(const std::string& path) const { - const GritResourceMap* resource = PathToResource(path); - int idr = resource ? resource->value : -1; - return idr == -1 ? false : GetWebClient()->IsDataResourceGzipped(idr); -} - } // namespace web
diff --git a/ios/web/webui/url_data_manager_ios_backend.mm b/ios/web/webui/url_data_manager_ios_backend.mm index e73bc74..5cd1f108 100644 --- a/ios/web/webui/url_data_manager_ios_backend.mm +++ b/ios/web/webui/url_data_manager_ios_backend.mm
@@ -27,7 +27,6 @@ #include "ios/web/webui/url_data_source_ios_impl.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" -#include "net/filter/gzip_source_stream.h" #include "net/filter/source_stream.h" #include "net/http/http_response_headers.h" #include "net/http/http_status_code.h" @@ -132,8 +131,6 @@ deny_xframe_options_ = deny_xframe_options; } - void set_is_gzipped(bool is_gzipped) { is_gzipped_ = is_gzipped; } - void set_source(scoped_refptr<URLDataSourceIOSImpl> source) { source_ = source; } @@ -179,10 +176,6 @@ // If true, sets the "X-Frame-Options: DENY" header. bool deny_xframe_options_; - // True when gzip encoding should be used. NOTE: this requires the original - // resources in resources.pak use compress="gzip". - bool is_gzipped_; - // The URLDataSourceIOSImpl that is servicing this request. This is a shared // pointer so that the request can continue to be served even if the source is // detached from the backend that initially owned it. @@ -218,7 +211,6 @@ content_security_policy_object_source_("object-src 'none';"), content_security_policy_frame_source_("frame-src 'none';"), deny_xframe_options_(true), - is_gzipped_(false), send_content_type_header_(false), is_incognito_(is_incognito), browser_state_(browser_state), @@ -285,9 +277,6 @@ if (deny_xframe_options_) info->headers->AddHeader(kChromeURLXFrameOptionsHeader); - if (is_gzipped_) - info->headers->AddHeader("Content-Encoding: gzip"); - if (!allow_caching_) info->headers->AddHeader("Cache-Control: no-cache"); @@ -302,11 +291,6 @@ std::unique_ptr<net::SourceStream> source_stream = net::URLRequestJob::SetUpSourceStream(); - if (is_gzipped_) { - source_stream = net::GzipSourceStream::Create(std::move(source_stream), - net::SourceStream::TYPE_GZIP); - } - // The URLRequestJob and the SourceStreams we are creating are owned by the // same parent URLRequest, thus it is safe to pass the replacements via a raw // pointer. @@ -503,7 +487,6 @@ source->source()->GetContentSecurityPolicyObjectSrc()); job->set_content_security_policy_frame_source("frame-src 'none';"); job->set_deny_xframe_options(source->source()->ShouldDenyXFrameOptions()); - job->set_is_gzipped(source->source()->IsGzipped(path)); job->set_send_content_type_header(false); // Forward along the request to the data source.
diff --git a/ios/web/webui/url_data_source_ios.mm b/ios/web/webui/url_data_source_ios.mm index 804951b..5b975d1 100644 --- a/ios/web/webui/url_data_source_ios.mm +++ b/ios/web/webui/url_data_source_ios.mm
@@ -35,10 +35,6 @@ return true; } -bool URLDataSourceIOS::IsGzipped(const std::string& path) const { - return false; -} - bool URLDataSourceIOS::ShouldServiceRequest(const GURL& url) const { return GetWebClient()->IsAppSpecificURL(url); }
diff --git a/ios/web/webui/web_ui_ios_data_source_impl.h b/ios/web/webui/web_ui_ios_data_source_impl.h index cf71f40..d08b76e 100644 --- a/ios/web/webui/web_ui_ios_data_source_impl.h +++ b/ios/web/webui/web_ui_ios_data_source_impl.h
@@ -63,8 +63,6 @@ int PathToIdrOrDefault(const std::string& path) const; - bool IsGzipped(const std::string& path) const; - // The name of this source. // E.g., for favicons, this could be "favicon", which results in paths for // specific resources like "favicon/34" getting sent to this source.
diff --git a/ios/web/webui/web_ui_ios_data_source_impl.mm b/ios/web/webui/web_ui_ios_data_source_impl.mm index d1981cd2..9bf4067 100644 --- a/ios/web/webui/web_ui_ios_data_source_impl.mm +++ b/ios/web/webui/web_ui_ios_data_source_impl.mm
@@ -56,9 +56,6 @@ bool ShouldDenyXFrameOptions() const override { return parent_->deny_xframe_options_; } - bool IsGzipped(const std::string& path) const override { - return parent_->IsGzipped(path); - } private: WebUIIOSDataSourceImpl* parent_; @@ -189,12 +186,4 @@ return it == path_to_idr_map_.end() ? default_resource_ : it->second; } -bool WebUIIOSDataSourceImpl::IsGzipped(const std::string& path) const { - if (!json_path_.empty() && path == json_path_) { - return false; - } - - return GetWebClient()->IsDataResourceGzipped(PathToIdrOrDefault(path)); -} - } // namespace web
diff --git a/ios/web_view/internal/web_view_web_client.h b/ios/web_view/internal/web_view_web_client.h index 87f98908..71cada6 100644 --- a/ios/web_view/internal/web_view_web_client.h +++ b/ios/web_view/internal/web_view_web_client.h
@@ -25,7 +25,6 @@ int resource_id, ui::ScaleFactor scale_factor) const override; base::RefCountedMemory* GetDataResourceBytes(int resource_id) const override; - bool IsDataResourceGzipped(int resource_id) const override; NSString* GetDocumentStartScriptForMainFrame( web::BrowserState* browser_state) const override; base::string16 GetPluginNotSupportedText() const override;
diff --git a/ios/web_view/internal/web_view_web_client.mm b/ios/web_view/internal/web_view_web_client.mm index 2912f183..f6fc15b0 100644 --- a/ios/web_view/internal/web_view_web_client.mm +++ b/ios/web_view/internal/web_view_web_client.mm
@@ -79,10 +79,6 @@ resource_id); } -bool WebViewWebClient::IsDataResourceGzipped(int resource_id) const { - return ui::ResourceBundle::GetSharedInstance().IsGzipped(resource_id); -} - NSString* WebViewWebClient::GetDocumentStartScriptForMainFrame( web::BrowserState* browser_state) const { NSMutableArray* scripts = [NSMutableArray array];
diff --git a/media/audio/audio_debug_file_writer.h b/media/audio/audio_debug_file_writer.h index 66f0f91d..b128025d 100644 --- a/media/audio/audio_debug_file_writer.h +++ b/media/audio/audio_debug_file_writer.h
@@ -63,8 +63,9 @@ // The task runner to do file output operations on. const scoped_refptr<base::SequencedTaskRunner> file_task_runner_ = - base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, + base::CreateSequencedTaskRunner( + {base::ThreadPool(), base::MayBlock(), + base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::BLOCK_SHUTDOWN}); AudioFileWriterUniquePtr file_writer_;
diff --git a/media/audio/audio_debug_recording_session_impl.cc b/media/audio/audio_debug_recording_session_impl.cc index 125e7a15..2d433cd 100644 --- a/media/audio/audio_debug_recording_session_impl.cc +++ b/media/audio/audio_debug_recording_session_impl.cc
@@ -58,9 +58,9 @@ return; } - base::PostTaskWithTraitsAndReplyWithResult( + base::PostTaskAndReplyWithResult( FROM_HERE, - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, + {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, base::BindOnce( [](const base::FilePath& file_name) {
diff --git a/media/audio/audio_thread_hang_monitor.cc b/media/audio/audio_thread_hang_monitor.cc index 727e198..37351e1 100644 --- a/media/audio/audio_thread_hang_monitor.cc +++ b/media/audio/audio_thread_hang_monitor.cc
@@ -47,7 +47,7 @@ scoped_refptr<base::SingleThreadTaskRunner> audio_thread_task_runner, scoped_refptr<base::SequencedTaskRunner> monitor_task_runner) { if (!monitor_task_runner) - monitor_task_runner = base::CreateSequencedTaskRunnerWithTraits({}); + monitor_task_runner = base::CreateSequencedTaskRunner({base::ThreadPool()}); auto monitor = Ptr(new AudioThreadHangMonitor(hang_action, hang_deadline, clock,
diff --git a/media/base/android/media_player_bridge.cc b/media/base/android/media_player_bridge.cc index 6037d2c..dbbc285 100644 --- a/media/base/android/media_player_bridge.cc +++ b/media/base/android/media_player_bridge.cc
@@ -38,6 +38,32 @@ const double kDefaultVolume = 1.0; +constexpr base::TimeDelta kWatchTimeReportingInterval = + base::TimeDelta::FromMilliseconds(750); + +const char kWatchTimeHistogram[] = "Media.Android.MediaPlayerWatchTime"; + +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class WatchTimeType { + kNonHls = 0, + kHlsAudioOnly = 1, + kHlsVideo = 2, + kMaxValue = kHlsVideo, +}; + +void RecordWatchTimeUMA(bool is_hls, bool has_video) { + WatchTimeType type = WatchTimeType::kNonHls; + if (is_hls) { + if (!has_video) { + type = WatchTimeType::kHlsAudioOnly; + } else { + type = WatchTimeType::kHlsVideo; + } + } + UMA_HISTOGRAM_ENUMERATION(kWatchTimeHistogram, type); +} + } // namespace MediaPlayerBridge::MediaPlayerBridge(const GURL& url, @@ -45,7 +71,8 @@ const std::string& user_agent, bool hide_url_log, Client* client, - bool allow_credentials) + bool allow_credentials, + bool is_hls) : prepared_(false), pending_play_(false), should_seek_on_prepare_(false), @@ -62,6 +89,9 @@ is_active_(false), has_error_(false), has_ever_started_(false), + is_hls_(is_hls), + unreported_watch_time_ms_(0), + last_current_time_(kNoTimestamp), client_(client), weak_factory_(this) { listener_ = std::make_unique<MediaPlayerListener>( @@ -324,6 +354,7 @@ } void MediaPlayerBridge::Release() { + StopWatchTimeTimer(); is_active_ = false; if (j_media_player_bridge_.is_null()) @@ -446,9 +477,11 @@ void MediaPlayerBridge::StartInternal() { JNIEnv* env = base::android::AttachCurrentThread(); Java_MediaPlayerBridge_start(env, j_media_player_bridge_); + StartWatchTimeTimer(); } void MediaPlayerBridge::PauseInternal() { + StopWatchTimeTimer(); JNIEnv* env = base::android::AttachCurrentThread(); Java_MediaPlayerBridge_pause(env, j_media_player_bridge_); } @@ -474,6 +507,10 @@ return; } + // Note: we do not want to count changes in media time due to seeks as watch + // time, but tracking pending seeks is not completely trivial. Instead seeks + // larger than kWatchTimeReportingInterval * 2 will be discarded by the sanity + // checks and shorter seeks will be counted. JNIEnv* env = base::android::AttachCurrentThread(); CHECK(env); int time_msec = static_cast<int>(time.InMilliseconds()); @@ -488,4 +525,44 @@ return site_for_cookies_; } +void MediaPlayerBridge::StartWatchTimeTimer() { + if (watch_time_timer_.IsRunning()) + return; + + last_current_time_ = GetCurrentTime(); + watch_time_timer_.Start(FROM_HERE, kWatchTimeReportingInterval, this, + &MediaPlayerBridge::UpdateWatchTime); +} + +void MediaPlayerBridge::StopWatchTimeTimer() { + if (!watch_time_timer_.IsRunning()) + return; + + UpdateWatchTime(); + watch_time_timer_.Stop(); +} + +void MediaPlayerBridge::UpdateWatchTime() { + if (!watch_time_timer_.IsRunning()) + return; + + // Note: this calculation assumes that the playback rate is 1.0, which + // currently it always is. + base::TimeDelta current_time = GetCurrentTime(); + base::TimeDelta duration = current_time - last_current_time_; + last_current_time_ = current_time; + + // Discard crazy values. + if (duration > base::TimeDelta() && + duration < kWatchTimeReportingInterval * 2) { + unreported_watch_time_ms_ += duration.InMilliseconds(); + } + + // Report to the nearest 1s. + if (unreported_watch_time_ms_ >= 500) { + RecordWatchTimeUMA(is_hls_, height_ > 0); + unreported_watch_time_ms_ -= 1000; + } +} + } // namespace media
diff --git a/media/base/android/media_player_bridge.h b/media/base/android/media_player_bridge.h index dfe10664..5021e34 100644 --- a/media/base/android/media_player_bridge.h +++ b/media/base/android/media_player_bridge.h
@@ -80,7 +80,8 @@ const std::string& user_agent, bool hide_url_log, Client* client, - bool allow_credentials); + bool allow_credentials, + bool is_hls); virtual ~MediaPlayerBridge(); // Initialize this object and extract the metadata from the media. @@ -188,6 +189,11 @@ // Sets the underlying MediaPlayer's volume. void UpdateVolumeInternal(); + // Watch time reporting. + void StartWatchTimeTimer(); + void StopWatchTimeTimer(); + void UpdateWatchTime(); + base::WeakPtr<MediaPlayerBridge> WeakPtrForUIThread(); // Whether the player is prepared for playback. @@ -248,6 +254,12 @@ // The flag is set if Start() has been called at least once. bool has_ever_started_; + // State for watch time reporting. + bool is_hls_; + int unreported_watch_time_ms_; + base::TimeDelta last_current_time_; + base::RepeatingTimer watch_time_timer_; + // A reference to the owner of |this|. Client* client_;
diff --git a/media/base/android/media_player_bridge_unittest.cc b/media/base/android/media_player_bridge_unittest.cc index a34bfa8..3766892d 100644 --- a/media/base/android/media_player_bridge_unittest.cc +++ b/media/base/android/media_player_bridge_unittest.cc
@@ -31,7 +31,7 @@ class MediaPlayerBridgeTest : public testing::Test { public: MediaPlayerBridgeTest() - : bridge_(GURL(), GURL(), "", false, &client_, false) {} + : bridge_(GURL(), GURL(), "", false, &client_, false, false) {} protected: void SimulateDurationChange(base::TimeDelta duration) {
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc index 17c6dbe0..f424101 100644 --- a/media/blink/webmediaplayer_impl.cc +++ b/media/blink/webmediaplayer_impl.cc
@@ -243,9 +243,9 @@ // used because virtual memory overhead is not considered blocking I/O; and // CONTINUE_ON_SHUTDOWN is used to allow process termination to not block on // completing the task. - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, - {base::TaskPriority::BEST_EFFORT, + {base::ThreadPool(), base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, base::BindOnce( [](scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
diff --git a/media/capabilities/learning_helper.cc b/media/capabilities/learning_helper.cc index eee53f0..8cd11535 100644 --- a/media/capabilities/learning_helper.cc +++ b/media/capabilities/learning_helper.cc
@@ -50,9 +50,9 @@ // it's likely that the session will live on the main thread, and handle // delegation of LearningTaskControllers to other threads. However, for now, // do it here. - learning_session_ = std::make_unique<LearningSessionImpl>( - base::CreateSequencedTaskRunnerWithTraits( - {base::TaskPriority::BEST_EFFORT, + learning_session_ = + std::make_unique<LearningSessionImpl>(base::CreateSequencedTaskRunner( + {base::ThreadPool(), base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})); // Register a few learning tasks.
diff --git a/media/capabilities/video_decode_stats_db_impl.cc b/media/capabilities/video_decode_stats_db_impl.cc index cf08f74..447cb56 100644 --- a/media/capabilities/video_decode_stats_db_impl.cc +++ b/media/capabilities/video_decode_stats_db_impl.cc
@@ -75,8 +75,9 @@ auto proto_db = leveldb_proto::ProtoDatabaseProvider::CreateUniqueDB<DecodeStatsProto>( - base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, + base::CreateSequencedTaskRunner( + {base::ThreadPool(), base::MayBlock(), + base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})); return base::WrapUnique(
diff --git a/media/capture/video/chromeos/reprocess_manager.cc b/media/capture/video/chromeos/reprocess_manager.cc index d2c9798..df045dd 100644 --- a/media/capture/video/chromeos/reprocess_manager.cc +++ b/media/capture/video/chromeos/reprocess_manager.cc
@@ -45,8 +45,8 @@ } ReprocessManager::ReprocessManager(CameraInfoGetter get_camera_info) - : sequenced_task_runner_(base::CreateSequencedTaskRunnerWithTraits( - {base::TaskPriority::USER_VISIBLE})), + : sequenced_task_runner_(base::CreateSequencedTaskRunner( + {base::ThreadPool(), base::TaskPriority::USER_VISIBLE})), impl(std::make_unique<ReprocessManager::ReprocessManagerImpl>( std::move(get_camera_info))) {}
diff --git a/media/device_monitors/device_monitor_udev.cc b/media/device_monitors/device_monitor_udev.cc index cd8ae1c..0c73ddf3 100644 --- a/media/device_monitors/device_monitor_udev.cc +++ b/media/device_monitors/device_monitor_udev.cc
@@ -114,8 +114,9 @@ } DeviceMonitorLinux::DeviceMonitorLinux() - : blocking_task_runner_(base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::USER_VISIBLE, + : blocking_task_runner_(base::CreateSequencedTaskRunner( + {base::ThreadPool(), base::MayBlock(), + base::TaskPriority::USER_VISIBLE, base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})), blocking_task_helper_(new BlockingTaskRunnerHelper, base::OnTaskRunnerDeleter(blocking_task_runner_)) {
diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc index 7033eb4..049b0185 100644 --- a/media/filters/ffmpeg_demuxer.cc +++ b/media/filters/ffmpeg_demuxer.cc
@@ -913,8 +913,9 @@ // FFmpeg has no asynchronous API, so we use base::WaitableEvents inside // the BlockingUrlProtocol to handle hops to the render thread for network // reads and seeks. - blocking_task_runner_(base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::USER_BLOCKING})), + blocking_task_runner_( + base::CreateSequencedTaskRunner({base::ThreadPool(), base::MayBlock(), + base::TaskPriority::USER_BLOCKING})), stopped_(false), pending_read_(false), data_source_(data_source),
diff --git a/media/filters/offloading_video_decoder.cc b/media/filters/offloading_video_decoder.cc index 93f62a9..1cf837d5 100644 --- a/media/filters/offloading_video_decoder.cc +++ b/media/filters/offloading_video_decoder.cc
@@ -137,8 +137,8 @@ } if (!offload_task_runner_) { - offload_task_runner_ = base::CreateSequencedTaskRunnerWithTraits( - {base::TaskPriority::USER_BLOCKING}); + offload_task_runner_ = base::CreateSequencedTaskRunner( + {base::ThreadPool(), base::TaskPriority::USER_BLOCKING}); } offload_task_runner_->PostTask(
diff --git a/media/gpu/android/codec_allocator.cc b/media/gpu/android/codec_allocator.cc index 4bd8b0e00..f6ca0eb5 100644 --- a/media/gpu/android/codec_allocator.cc +++ b/media/gpu/android/codec_allocator.cc
@@ -45,8 +45,8 @@ } scoped_refptr<base::SequencedTaskRunner> CreateCodecTaskRunner() { - return base::CreateSequencedTaskRunnerWithTraits( - {base::TaskPriority::USER_VISIBLE, base::MayBlock(), + return base::CreateSequencedTaskRunner( + {base::ThreadPool(), base::TaskPriority::USER_VISIBLE, base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}); }
diff --git a/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.cc b/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.cc index 90713477..7c8b6c9 100644 --- a/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.cc
@@ -1457,8 +1457,7 @@ qbuf.m.planes[i].m.fd = (i < fds.size()) ? fds[i].get() : fds.back().get(); qbuf.m.planes[i].data_offset = planes[i].offset; qbuf.m.planes[i].bytesused += qbuf.m.planes[i].data_offset; - qbuf.m.planes[i].length = - planes[i].size + qbuf.m.planes[i].data_offset; + qbuf.m.planes[i].length = planes[i].size + qbuf.m.planes[i].data_offset; } IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QBUF, &qbuf);
diff --git a/media/gpu/v4l2/v4l2_slice_video_decoder.cc b/media/gpu/v4l2/v4l2_slice_video_decoder.cc index aa059e75..cab0fed 100644 --- a/media/gpu/v4l2/v4l2_slice_video_decoder.cc +++ b/media/gpu/v4l2/v4l2_slice_video_decoder.cc
@@ -161,8 +161,9 @@ : device_(std::move(device)), frame_pool_(std::move(frame_pool)), client_task_runner_(std::move(client_task_runner)), - decoder_task_runner_(base::CreateSequencedTaskRunnerWithTraits( - {base::WithBaseSyncPrimitives(), base::TaskPriority::USER_VISIBLE})), + decoder_task_runner_(base::CreateSequencedTaskRunner( + {base::ThreadPool(), base::WithBaseSyncPrimitives(), + base::TaskPriority::USER_VISIBLE})), device_poll_thread_("V4L2SliceVideoDecoderDevicePollThread"), weak_this_factory_(this) { DETACH_FROM_SEQUENCE(client_sequence_checker_);
diff --git a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc index 28a10a1..8cccff4 100644 --- a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
@@ -671,10 +671,20 @@ return true; } - if (new_frame_size != device_input_layout_->coded_size()) { + // Here we should compare |device_input_layout_->coded_size()|. However, VEA + // requests a client |input_allocated_size_|, which might be a larger size + // than |device_input_layout_->coded_size()|. The size is larger if there is + // an extra data in planes, that happens on MediaTek. + // This comparison will work because VEAClient within Chrome gives the buffer + // whose frame size as |input_allocated_size_|. VEAClient for ARC++ might give + // a different frame size but |input_allocated_size_| is always the same as + // |device_input_layout_->coded_size()|. + if (new_frame_size != input_allocated_size_) { VLOGF(2) << "Call S_FMT with a new size=" << new_frame_size.ToString() << ", the previous size =" - << device_input_layout_->coded_size().ToString(); + << device_input_layout_->coded_size().ToString() + << " (the size requested to client=" + << input_allocated_size_.ToString(); if (input_streamon_ || output_streamon_) { VLOGF(1) << "Input frame size is changed during encoding"; NOTIFY_ERROR(kInvalidArgumentError);
diff --git a/media/gpu/vaapi/vaapi_image_decode_accelerator_worker.cc b/media/gpu/vaapi/vaapi_image_decode_accelerator_worker.cc index 2a25b1ae..3d402ce3 100644 --- a/media/gpu/vaapi/vaapi_image_decode_accelerator_worker.cc +++ b/media/gpu/vaapi/vaapi_image_decode_accelerator_worker.cc
@@ -152,7 +152,8 @@ VaapiImageDecodeAcceleratorWorker::VaapiImageDecodeAcceleratorWorker( VaapiImageDecoderVector decoders) { DETACH_FROM_SEQUENCE(io_sequence_checker_); - decoder_task_runner_ = base::CreateSequencedTaskRunnerWithTraits({}); + decoder_task_runner_ = + base::CreateSequencedTaskRunnerWithTraits({base::ThreadPool()}); DCHECK(decoder_task_runner_); DCHECK(!decoders.empty());
diff --git a/media/gpu/vaapi/vaapi_jpeg_encode_accelerator.cc b/media/gpu/vaapi/vaapi_jpeg_encode_accelerator.cc index b076751..cde410ee 100644 --- a/media/gpu/vaapi/vaapi_jpeg_encode_accelerator.cc +++ b/media/gpu/vaapi/vaapi_jpeg_encode_accelerator.cc
@@ -431,8 +431,9 @@ return PLATFORM_FAILURE; } - encoder_task_runner_ = base::CreateSingleThreadTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::USER_BLOCKING}); + encoder_task_runner_ = + base::CreateSingleThreadTaskRunner({base::ThreadPool(), base::MayBlock(), + base::TaskPriority::USER_BLOCKING}); if (!encoder_task_runner_) { VLOGF(1) << "Failed to create encoder task runner."; return THREAD_CREATION_FAILED;
diff --git a/media/gpu/vaapi/vp8_encoder.cc b/media/gpu/vaapi/vp8_encoder.cc index 310d1f5..fa1212f5 100644 --- a/media/gpu/vaapi/vp8_encoder.cc +++ b/media/gpu/vaapi/vp8_encoder.cc
@@ -60,13 +60,6 @@ DVLOGF(1) << "Input visible size could not be empty"; return false; } - // 4:2:0 format has to be 2-aligned. - if ((config.input_visible_size.width() % 2 != 0) || - (config.input_visible_size.height() % 2 != 0)) { - DVLOGF(1) << "The pixel sizes are not even: " - << config.input_visible_size.ToString(); - return false; - } visible_size_ = config.input_visible_size; coded_size_ = gfx::Size(base::bits::Align(visible_size_.width(), 16),
diff --git a/media/gpu/video_encode_accelerator_unittest.cc b/media/gpu/video_encode_accelerator_unittest.cc index e110931..9a829e77 100644 --- a/media/gpu/video_encode_accelerator_unittest.cc +++ b/media/gpu/video_encode_accelerator_unittest.cc
@@ -559,25 +559,34 @@ int64_t src_file_size = 0; LOG_ASSERT(base::GetFileSize(src_file, &src_file_size)); - size_t visible_buffer_size = - VideoFrame::AllocationSize(pixel_format, test_stream->visible_size); - LOG_ASSERT(src_file_size % visible_buffer_size == 0U) + // NOTE: VideoFrame::AllocationSize() cannot used here because the width and + // height on each plane is aligned by 2 for YUV format. + size_t frame_buffer_size = 0; + for (size_t i = 0; i < num_planes; ++i) { + size_t row_bytes = VideoFrame::RowBytes(i, pixel_format, + test_stream->visible_size.width()); + size_t rows = + VideoFrame::Rows(i, pixel_format, test_stream->visible_size.height()); + frame_buffer_size += rows * row_bytes; + } + + LOG_ASSERT(src_file_size % frame_buffer_size == 0U) << "Stream byte size is not a product of calculated frame byte size"; test_stream->num_frames = - static_cast<unsigned int>(src_file_size / visible_buffer_size); + static_cast<unsigned int>(src_file_size / frame_buffer_size); LOG_ASSERT(test_stream->aligned_buffer_size > 0UL); test_stream->aligned_in_file_data.resize(test_stream->aligned_buffer_size * test_stream->num_frames); base::File src(src_file, base::File::FLAG_OPEN | base::File::FLAG_READ); - std::vector<char> src_data(visible_buffer_size); + std::vector<char> src_data(frame_buffer_size); off_t src_offset = 0, dest_offset = 0; for (size_t frame = 0; frame < test_stream->num_frames; frame++) { LOG_ASSERT(src.Read(src_offset, &src_data[0], - static_cast<int>(visible_buffer_size)) == - static_cast<int>(visible_buffer_size)); + static_cast<int>(frame_buffer_size)) == + static_cast<int>(frame_buffer_size)); const char* src_ptr = &src_data[0]; for (size_t i = 0; i < num_planes; i++) { // Assert that each plane of frame starts at required byte boundary. @@ -591,7 +600,7 @@ } dest_offset += static_cast<off_t>(padding_sizes[i]); } - src_offset += static_cast<off_t>(visible_buffer_size); + src_offset += static_cast<off_t>(frame_buffer_size); } src.Close();
diff --git a/media/webrtc/audio_processor.cc b/media/webrtc/audio_processor.cc index be4a916c..97ebeda 100644 --- a/media/webrtc/audio_processor.cc +++ b/media/webrtc/audio_processor.cc
@@ -148,8 +148,9 @@ if (!audio_processing_) { // The destructor of File is blocking. Post it to a task runner to avoid // blocking the main thread. - base::PostTaskWithTraits( - FROM_HERE, {base::TaskPriority::LOWEST, base::MayBlock()}, + base::PostTask( + FROM_HERE, + {base::ThreadPool(), base::TaskPriority::LOWEST, base::MayBlock()}, base::BindOnce([](base::File) {}, std::move(file))); return; }
diff --git a/mojo/docs/OWNERS b/mojo/docs/OWNERS new file mode 100644 index 0000000..ae32960 --- /dev/null +++ b/mojo/docs/OWNERS
@@ -0,0 +1,2 @@ +dcheng@chromium.org +rsesek@chromium.org
diff --git a/mojo/docs/basics.md b/mojo/docs/basics.md new file mode 100644 index 0000000..7636ac4a --- /dev/null +++ b/mojo/docs/basics.md
@@ -0,0 +1,166 @@ +# Mojo Basics + +This document aims to provide a brief overview of the different concepts in Mojo +and how they work together. For more details about more complex and/or +Chrome-specific Mojo use cases, please consult the [Mojo cookbook](cookbook.md). + +[TOC] + +## Interfaces + +Mojo provides a [C++-like interface definition language][mojo-idl] for defining +interfaces for making interprocess calls (IPCs): + +``` +module math.mojom; + +interface Math { + // Adds two int32s and returns the result as an int64 (to avoid + // overflow issues). + Add(int32 x, int32 y) => (int64 sum); +}; +``` + +Interfaces are built using the `mojom` (or `mojom_component`) [GN +template][gn-template]: +``` +mojom("mojom") { + sources = ["math.mojom"] +} +``` + +This will generate C++ (and optionally, Java and JavaScript) interfaces. Writing +code to handle IPCs is a simple matter of implementing the generated interface: + +``` +class MathImpl : public math::mojom::Math { + public: + explicit MathImpl(mojo::PendingReceiver<math::mojom::Math> receiver) + : receiver_(this, std::move(receiver)) {} + + // math::mojom::Math overrides: + // Note: AddCallback is a type alias for base::OnceCallback<void(int64_t)>. + // The parameters to the callback are the reply parameters specified in the + // Mojo IDL method definition. This is part of the boilerplate generated by + // Mojo: invoking |reply| will send a reply to the caller. + void Add(int32_t x, int32_t y, AddCallback reply) override { + // Note: Mojo always returns results via callback. While it is possible to + // make a sync IPC which blocks on the reply, the handler will always return + // the result via callback. + std::move(reply).Run(static_cast<int64_t>(x) + y); + } + + private: + // Wraps a message pipe endpoint that receives incoming messages. See the + // message pipes section below for more information. + mojo::Receiver<math::mojom::Math> receiver_; +}; +``` + +Note: the build process also generates proxy classes (e.g. `MathProxy`) which +encapsulate the details of making the actual cross-process call. These are +used internally and are an implementation detail that can typically be ignored. + +## Message Pipes + +Interfaces are layered on top of low-level [message pipes][message-pipe]. Each +message pipe has two bidirectional endpoints. The Mojo bindings enforce +additional conventions on top of message pipes, where one endpoint is the +sender/caller, represented as: + +``` +// Wraps a message pipe endpoint for making remote calls. May only be used on +// the sequence where the mojo::Remote was bound. +mojo::Remote<math::mojom::Math> remote_math = ...; +``` + +And the other endpoint is the receiving/callee, represented as: + +``` +// Usually a class member. Wraps a message pipe endpoint that receives incoming +// messages. Routes and dispatches IPCs to the handler—typically |this|—on the +// sequence where the mojo::Receiver was bound. +mojo::Receiver<math::mojom::Math> receiver_; +``` + +This allows limited bidirectional communication: the sender can make any number +of calls to the receiver, and the receiver may send a single reply for each +call. More expressive APIs (that require any number of calls to flow in both +directions) are often implemented as a pair of message pipes. + +Message pipe endpoints are typically created using one of: + +### mojo::Remote<T>::BindNewPipeAndPassReceiver + +Here, the sender/caller creates the endpoints. One endpoint is retained for +itself to send IPCs, and the other endpoint is returned as an unbound +`mojo::PendingReceiver<T>` for the receiver/callee to bind to a +`mojo::Receiver<T>`. + +``` +mojo::Remote<math::mojom::Math> remote_math; + +// BindNewPipeAndPassReceiver() returns a +// mojo::PendingReceiver<math::mojom::Math>. This may be bound to a +// mojo::Receiver<math::mojom::Math> to handle calls received from +// |remote_math|. +LaunchAndBindRemoteMath(remote_math.BindNewPipeAndPassReceiver()); + +// |remote_math| may be immediately used. The Add() call will be buffered by the +// receiving end and dispatched when mojo::PendingReceiver<math::mojom::Math> is +// bound to a mojo::Receiver<math::mojom::Math>. +remote_math->Add(2, 2, base::BindOnce(...)); +``` + +### mojo::Receiver<T>::BindNewPipeAndPassRemote + +Alternatively, the receiver/callee can create the endpoints. One endpoint is +retained for itself to receive IPCs, and the other endpoint is returned as an +unbound `mojo::PendingRemote<T>` for the sender/callee to bind to a +`mojo::Remote<T>`. +``` +class MathImpl : public math::mojom::MathImpl { + // ...addition to the previous MathImpl definition... + + mojo::PendingRemote<math::mojom::Math> GetRemoteMath() { + // BindNewPipeAndPassRemote() returns a + // `mojo::PendingRemote<math::mojom::Math>`. This may be bound to a + // `mojo::Remote<math::mojom::Math> which can be used to send IPCs that will + // be handled by |this|. + return receiver_.BindNewPipeAndPassRemote(); + } +}; +``` + +### mojo::PendingReceiver<T>::InitWithNewPipeAndPassReceiver + +Less common, but very similar to `BindNewPipeAndPassReceiver()`, except it +returns a `mojo::PendingReceiver<T>` instead of a `mojo::Receiver<T>`. + +### mojo::Remote<T>/mojo::Receiver<T> and mojo::PendingRemote<T>/mojo::PendingReceiver<T> + +Both `mojo::Remote<T>` and `mojo::Receiver<T>` have a corresponding unbound +version: this allows either endpoint to be passed between sequences in the same +process or even between processes over IPC. + +``` +mojo::Remote<math::mojom::MathImpl> remote = ...; +// |pending_remote| is movable and may be passed around. While unbound, the +// endpoint cannot be used to send IPCs. The pending remote may be passed to +// the mojo::Remote<T> constructor or mojo::Remote<T>::Bind() to rebind the +// endpoint. +mojo::PendingRemote<math::mojom::MathImpl> pending_remote = remote.Unbind(); +``` + +``` +mojo::Receiver<math::mojom::MathImpl> receiver = ...; +// |pending_receiver| is movable and may be passed around. While unbound, +// received IPCs are buffered and not processed. The pending receiver may be +// passed to the mojo::Receiver<T> constructor or mojo::Receiver<T>::Bind() to +// rebind the endpoint. +mojo::PendingReceiver<math::mojom::MathImpl> pending_receiver = receiver.Unbind(); +``` + +[mojo-idl]: https://chromium.googlesource.com/chromium/src/+/master/mojo/public/tools/bindings/README.md +[gn-template]: https://cs.chromium.org/chromium/src/mojo/public/tools/bindings/mojom.gni +[message-pipe]: https://cs.chromium.org/chromium/src/mojo/public/cpp/system/message_pipe.h
diff --git a/mojo/public/cpp/bindings/array_data_view.h b/mojo/public/cpp/bindings/array_data_view.h index d02a884..157cd2f 100644 --- a/mojo/public/cpp/bindings/array_data_view.h +++ b/mojo/public/cpp/bindings/array_data_view.h
@@ -22,7 +22,7 @@ class ArrayDataViewImpl< T, typename std::enable_if< - BelongsTo<T, MojomTypeCategory::POD>::value>::type> { + BelongsTo<T, MojomTypeCategory::kPOD>::value>::type> { public: using Data_ = typename MojomTypeTraits<ArrayDataView<T>>::Data; @@ -42,7 +42,7 @@ class ArrayDataViewImpl< T, typename std::enable_if< - BelongsTo<T, MojomTypeCategory::BOOLEAN>::value>::type> { + BelongsTo<T, MojomTypeCategory::kBoolean>::value>::type> { public: using Data_ = typename MojomTypeTraits<ArrayDataView<T>>::Data; @@ -60,7 +60,7 @@ class ArrayDataViewImpl< T, typename std::enable_if< - BelongsTo<T, MojomTypeCategory::ENUM>::value>::type> { + BelongsTo<T, MojomTypeCategory::kEnum>::value>::type> { public: static_assert(sizeof(T) == sizeof(int32_t), "Unexpected enum size"); @@ -88,10 +88,10 @@ T, typename std::enable_if< BelongsTo<T, - MojomTypeCategory::ASSOCIATED_INTERFACE | - MojomTypeCategory::ASSOCIATED_INTERFACE_REQUEST | - MojomTypeCategory::INTERFACE | - MojomTypeCategory::INTERFACE_REQUEST>::value>::type> { + MojomTypeCategory::kAssociatedInterface | + MojomTypeCategory::kAssociatedInterfaceRequest | + MojomTypeCategory::kInterface | + MojomTypeCategory::kInterfaceRequest>::value>::type> { public: using Data_ = typename MojomTypeTraits<ArrayDataView<T>>::Data; @@ -115,7 +115,7 @@ class ArrayDataViewImpl< T, typename std::enable_if< - BelongsTo<T, MojomTypeCategory::HANDLE>::value>::type> { + BelongsTo<T, MojomTypeCategory::kHandle>::value>::type> { public: using Data_ = typename MojomTypeTraits<ArrayDataView<T>>::Data; @@ -135,12 +135,13 @@ }; template <typename T> -class ArrayDataViewImpl<T, - typename std::enable_if<BelongsTo< - T, - MojomTypeCategory::ARRAY | MojomTypeCategory::MAP | - MojomTypeCategory::STRING | - MojomTypeCategory::STRUCT>::value>::type> { +class ArrayDataViewImpl< + T, + typename std::enable_if< + BelongsTo<T, + MojomTypeCategory::kArray | MojomTypeCategory::kMap | + MojomTypeCategory::kString | + MojomTypeCategory::kStruct>::value>::type> { public: using Data_ = typename MojomTypeTraits<ArrayDataView<T>>::Data; @@ -165,7 +166,7 @@ class ArrayDataViewImpl< T, typename std::enable_if< - BelongsTo<T, MojomTypeCategory::UNION>::value>::type> { + BelongsTo<T, MojomTypeCategory::kUnion>::value>::type> { public: using Data_ = typename MojomTypeTraits<ArrayDataView<T>>::Data;
diff --git a/mojo/public/cpp/bindings/lib/array_serialization.h b/mojo/public/cpp/bindings/lib/array_serialization.h index 8323b5f..7ccccea 100644 --- a/mojo/public/cpp/bindings/lib/array_serialization.h +++ b/mojo/public/cpp/bindings/lib/array_serialization.h
@@ -106,7 +106,7 @@ MaybeConstUserType, UserTypeIterator, typename std::enable_if<BelongsTo<typename MojomType::Element, - MojomTypeCategory::POD>::value>::type> { + MojomTypeCategory::kPOD>::value>::type> { using UserType = typename std::remove_const<MaybeConstUserType>::type; using Data = typename MojomTypeTraits<MojomType>::Data; using DataElement = typename Data::Element; @@ -174,7 +174,7 @@ MaybeConstUserType, UserTypeIterator, typename std::enable_if<BelongsTo<typename MojomType::Element, - MojomTypeCategory::ENUM>::value>::type> { + MojomTypeCategory::kEnum>::value>::type> { using UserType = typename std::remove_const<MaybeConstUserType>::type; using Data = typename MojomTypeTraits<MojomType>::Data; using DataElement = typename Data::Element; @@ -224,7 +224,7 @@ UserTypeIterator, typename std::enable_if<BelongsTo< typename MojomType::Element, - MojomTypeCategory::BOOLEAN>::value>::type> { + MojomTypeCategory::kBoolean>::value>::type> { using UserType = typename std::remove_const<MaybeConstUserType>::type; using Traits = ArrayTraits<UserType>; using Data = typename MojomTypeTraits<MojomType>::Data; @@ -268,12 +268,12 @@ MojomType, MaybeConstUserType, UserTypeIterator, - typename std::enable_if< - BelongsTo<typename MojomType::Element, - MojomTypeCategory::ASSOCIATED_INTERFACE | - MojomTypeCategory::ASSOCIATED_INTERFACE_REQUEST | - MojomTypeCategory::HANDLE | MojomTypeCategory::INTERFACE | - MojomTypeCategory::INTERFACE_REQUEST>::value>::type> { + typename std::enable_if<BelongsTo< + typename MojomType::Element, + MojomTypeCategory::kAssociatedInterface | + MojomTypeCategory::kAssociatedInterfaceRequest | + MojomTypeCategory::kHandle | MojomTypeCategory::kInterface | + MojomTypeCategory::kInterfaceRequest>::value>::type> { using UserType = typename std::remove_const<MaybeConstUserType>::type; using Data = typename MojomTypeTraits<MojomType>::Data; using Element = typename MojomType::Element; @@ -296,8 +296,8 @@ static const ValidationError kError = BelongsTo<Element, - MojomTypeCategory::ASSOCIATED_INTERFACE | - MojomTypeCategory::ASSOCIATED_INTERFACE_REQUEST>::value + MojomTypeCategory::kAssociatedInterface | + MojomTypeCategory::kAssociatedInterfaceRequest>::value ? VALIDATION_ERROR_UNEXPECTED_INVALID_INTERFACE_ID : VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE; MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( @@ -334,9 +334,9 @@ UserTypeIterator, typename std::enable_if<BelongsTo< typename MojomType::Element, - MojomTypeCategory::ARRAY | MojomTypeCategory::MAP | - MojomTypeCategory::STRING | - MojomTypeCategory::STRUCT>::value>::type> { + MojomTypeCategory::kArray | MojomTypeCategory::kMap | + MojomTypeCategory::kString | + MojomTypeCategory::kStruct>::value>::type> { using UserType = typename std::remove_const<MaybeConstUserType>::type; using Data = typename MojomTypeTraits<MojomType>::Data; using Element = typename MojomType::Element; @@ -382,9 +382,9 @@ private: template <typename T, - bool is_array_or_map = BelongsTo<T, - MojomTypeCategory::ARRAY | - MojomTypeCategory::MAP>::value> + bool is_array_or_map = BelongsTo< + T, + MojomTypeCategory::kArray | MojomTypeCategory::kMap>::value> struct SerializeCaller { template <typename InputElementType> static void Run(InputElementType&& input, @@ -414,12 +414,12 @@ template <typename MojomType, typename MaybeConstUserType, typename UserTypeIterator> -struct ArraySerializer< - MojomType, - MaybeConstUserType, - UserTypeIterator, - typename std::enable_if<BelongsTo<typename MojomType::Element, - MojomTypeCategory::UNION>::value>::type> { +struct ArraySerializer<MojomType, + MaybeConstUserType, + UserTypeIterator, + typename std::enable_if< + BelongsTo<typename MojomType::Element, + MojomTypeCategory::kUnion>::value>::type> { using UserType = typename std::remove_const<MaybeConstUserType>::type; using Data = typename MojomTypeTraits<MojomType>::Data; using Element = typename MojomType::Element;
diff --git a/mojo/public/cpp/bindings/lib/bindings_internal.h b/mojo/public/cpp/bindings/lib/bindings_internal.h index 8bdb9c7..1137ae8 100644 --- a/mojo/public/cpp/bindings/lib/bindings_internal.h +++ b/mojo/public/cpp/bindings/lib/bindings_internal.h
@@ -183,20 +183,20 @@ }; enum class MojomTypeCategory : uint32_t { - ARRAY = 1 << 0, - ASSOCIATED_INTERFACE = 1 << 1, - ASSOCIATED_INTERFACE_REQUEST = 1 << 2, - BOOLEAN = 1 << 3, - ENUM = 1 << 4, - HANDLE = 1 << 5, - INTERFACE = 1 << 6, - INTERFACE_REQUEST = 1 << 7, - MAP = 1 << 8, + kArray = 1 << 0, + kAssociatedInterface = 1 << 1, + kAssociatedInterfaceRequest = 1 << 2, + kBoolean = 1 << 3, + kEnum = 1 << 4, + kHandle = 1 << 5, + kInterface = 1 << 6, + kInterfaceRequest = 1 << 7, + kMap = 1 << 8, // POD except boolean and enum. - POD = 1 << 9, - STRING = 1 << 10, - STRUCT = 1 << 11, - UNION = 1 << 12 + kPOD = 1 << 9, + kString = 1 << 10, + kStruct = 1 << 11, + kUnion = 1 << 12 }; inline constexpr MojomTypeCategory operator&(MojomTypeCategory x, @@ -216,7 +216,7 @@ using Data = T; using DataAsArrayElement = Data; - static const MojomTypeCategory category = MojomTypeCategory::POD; + static const MojomTypeCategory category = MojomTypeCategory::kPOD; }; template <typename T> @@ -224,7 +224,7 @@ using Data = Array_Data<typename MojomTypeTraits<T>::DataAsArrayElement>; using DataAsArrayElement = Pointer<Data>; - static const MojomTypeCategory category = MojomTypeCategory::ARRAY; + static const MojomTypeCategory category = MojomTypeCategory::kArray; }; template <typename T> @@ -233,7 +233,7 @@ using DataAsArrayElement = Data; static const MojomTypeCategory category = - MojomTypeCategory::ASSOCIATED_INTERFACE; + MojomTypeCategory::kAssociatedInterface; }; template <typename T> @@ -242,7 +242,7 @@ using DataAsArrayElement = Data; static const MojomTypeCategory category = - MojomTypeCategory::ASSOCIATED_INTERFACE_REQUEST; + MojomTypeCategory::kAssociatedInterfaceRequest; }; template <> @@ -250,7 +250,7 @@ using Data = bool; using DataAsArrayElement = Data; - static const MojomTypeCategory category = MojomTypeCategory::BOOLEAN; + static const MojomTypeCategory category = MojomTypeCategory::kBoolean; }; template <typename T> @@ -258,7 +258,7 @@ using Data = int32_t; using DataAsArrayElement = Data; - static const MojomTypeCategory category = MojomTypeCategory::ENUM; + static const MojomTypeCategory category = MojomTypeCategory::kEnum; }; template <typename T> @@ -266,7 +266,7 @@ using Data = Handle_Data; using DataAsArrayElement = Data; - static const MojomTypeCategory category = MojomTypeCategory::HANDLE; + static const MojomTypeCategory category = MojomTypeCategory::kHandle; }; template <typename T> @@ -274,7 +274,7 @@ using Data = Interface_Data; using DataAsArrayElement = Data; - static const MojomTypeCategory category = MojomTypeCategory::INTERFACE; + static const MojomTypeCategory category = MojomTypeCategory::kInterface; }; template <typename T> @@ -283,7 +283,7 @@ using DataAsArrayElement = Data; static const MojomTypeCategory category = - MojomTypeCategory::INTERFACE_REQUEST; + MojomTypeCategory::kInterfaceRequest; }; template <typename K, typename V> @@ -292,7 +292,7 @@ typename MojomTypeTraits<V>::DataAsArrayElement>; using DataAsArrayElement = Pointer<Data>; - static const MojomTypeCategory category = MojomTypeCategory::MAP; + static const MojomTypeCategory category = MojomTypeCategory::kMap; }; template <> @@ -300,7 +300,7 @@ using Data = String_Data; using DataAsArrayElement = Pointer<Data>; - static const MojomTypeCategory category = MojomTypeCategory::STRING; + static const MojomTypeCategory category = MojomTypeCategory::kString; }; template <typename T, MojomTypeCategory categories>
diff --git a/mojo/public/cpp/bindings/lib/serialization.h b/mojo/public/cpp/bindings/lib/serialization.h index 8ced91e..1f5d7de8 100644 --- a/mojo/public/cpp/bindings/lib/serialization.h +++ b/mojo/public/cpp/bindings/lib/serialization.h
@@ -35,7 +35,7 @@ struct MojomSerializationImplTraits< MojomType, typename std::enable_if< - BelongsTo<MojomType, MojomTypeCategory::STRUCT>::value>::type> { + BelongsTo<MojomType, MojomTypeCategory::kStruct>::value>::type> { template <typename MaybeConstUserType, typename WriterType> static void Serialize(MaybeConstUserType& input, Buffer* buffer, @@ -49,7 +49,7 @@ struct MojomSerializationImplTraits< MojomType, typename std::enable_if< - BelongsTo<MojomType, MojomTypeCategory::UNION>::value>::type> { + BelongsTo<MojomType, MojomTypeCategory::kUnion>::value>::type> { template <typename MaybeConstUserType, typename WriterType> static void Serialize(MaybeConstUserType& input, Buffer* buffer, @@ -73,8 +73,8 @@ template <typename MojomType, typename DataArrayType, typename UserType> DataArrayType SerializeImpl(UserType* input) { - static_assert(BelongsTo<MojomType, MojomTypeCategory::STRUCT>::value || - BelongsTo<MojomType, MojomTypeCategory::UNION>::value, + static_assert(BelongsTo<MojomType, MojomTypeCategory::kStruct>::value || + BelongsTo<MojomType, MojomTypeCategory::kUnion>::value, "Unexpected type."); Message message = SerializeAsMessageImpl<MojomType>(input); uint32_t size = message.payload_num_bytes(); @@ -90,8 +90,8 @@ std::vector<mojo::ScopedHandle> handles, UserType* output, bool (*validate_func)(const void*, ValidationContext*)) { - static_assert(BelongsTo<MojomType, MojomTypeCategory::STRUCT>::value || - BelongsTo<MojomType, MojomTypeCategory::UNION>::value, + static_assert(BelongsTo<MojomType, MojomTypeCategory::kStruct>::value || + BelongsTo<MojomType, MojomTypeCategory::kUnion>::value, "Unexpected type."); using DataType = typename MojomTypeTraits<MojomType>::Data;
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module-shared.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module-shared.h.tmpl index 994069a..e935bff 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/module-shared.h.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/module-shared.h.tmpl
@@ -12,10 +12,10 @@ using Data = {{kind|get_qualified_name_for_kind(internal=True)}}; {%- if kind|is_union_kind %} using DataAsArrayElement = Data; - static constexpr MojomTypeCategory category = MojomTypeCategory::UNION; + static constexpr MojomTypeCategory category = MojomTypeCategory::kUnion; {%- else %} using DataAsArrayElement = Pointer<Data>; - static constexpr MojomTypeCategory category = MojomTypeCategory::STRUCT; + static constexpr MojomTypeCategory category = MojomTypeCategory::kStruct; {%- endif %} }; {%- endmacro %}
diff --git a/net/BUILD.gn b/net/BUILD.gn index f5bc9a6..a27f002 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -1481,6 +1481,7 @@ "third_party/quiche/src/quic/core/frames/quic_streams_blocked_frame.h", "third_party/quiche/src/quic/core/frames/quic_window_update_frame.cc", "third_party/quiche/src/quic/core/frames/quic_window_update_frame.h", + "third_party/quiche/src/quic/core/http/http_constants.h", "third_party/quiche/src/quic/core/http/http_decoder.cc", "third_party/quiche/src/quic/core/http/http_decoder.h", "third_party/quiche/src/quic/core/http/http_encoder.cc", @@ -1549,6 +1550,9 @@ "third_party/quiche/src/quic/core/qpack/qpack_send_stream.h", "third_party/quiche/src/quic/core/qpack/qpack_static_table.cc", "third_party/quiche/src/quic/core/qpack/qpack_static_table.h", + "third_party/quiche/src/quic/core/qpack/qpack_stream_receiver.h", + "third_party/quiche/src/quic/core/qpack/qpack_stream_sender_delegate.h", + "third_party/quiche/src/quic/core/qpack/qpack_utils.h", "third_party/quiche/src/quic/core/qpack/value_splitting_header_list.cc", "third_party/quiche/src/quic/core/qpack/value_splitting_header_list.h", "third_party/quiche/src/quic/core/quic_ack_listener_interface.cc", @@ -1733,6 +1737,7 @@ "third_party/quiche/src/spdy/core/http2_frame_decoder_adapter.cc", "third_party/quiche/src/spdy/core/http2_frame_decoder_adapter.h", "third_party/quiche/src/spdy/core/http2_priority_write_scheduler.h", + "third_party/quiche/src/spdy/core/lifo_write_scheduler.h", "third_party/quiche/src/spdy/core/priority_write_scheduler.h", "third_party/quiche/src/spdy/core/spdy_alt_svc_wire_format.cc", "third_party/quiche/src/spdy/core/spdy_alt_svc_wire_format.h", @@ -5597,6 +5602,7 @@ "third_party/quiche/src/quic/platform/api/quic_mem_slice_storage_test.cc", "third_party/quiche/src/quic/platform/api/quic_mem_slice_test.cc", "third_party/quiche/src/quic/platform/api/quic_reference_counted_test.cc", + "third_party/quiche/src/quic/platform/api/quic_socket_address_test.cc", "third_party/quiche/src/quic/platform/api/quic_str_cat_test.cc", "third_party/quiche/src/quic/platform/api/quic_string_utils_test.cc", "third_party/quiche/src/quic/platform/api/quic_text_utils_test.cc", @@ -5621,6 +5627,7 @@ "third_party/quiche/src/spdy/core/hpack/hpack_round_trip_test.cc", "third_party/quiche/src/spdy/core/hpack/hpack_static_table_test.cc", "third_party/quiche/src/spdy/core/http2_priority_write_scheduler_test.cc", + "third_party/quiche/src/spdy/core/lifo_write_scheduler_test.cc", "third_party/quiche/src/spdy/core/mock_spdy_framer_visitor.cc", "third_party/quiche/src/spdy/core/mock_spdy_framer_visitor.h", "third_party/quiche/src/spdy/core/priority_write_scheduler_test.cc", @@ -5698,6 +5705,7 @@ "third_party/quiche/src/quic/quartc/quartc_interval_counter_test.cc", "third_party/quiche/src/quic/quartc/quartc_multiplexer.cc", "third_party/quiche/src/quic/quartc/quartc_multiplexer.h", + "third_party/quiche/src/quic/quartc/quartc_multiplexer_test.cc", "third_party/quiche/src/quic/quartc/quartc_packet_writer.cc", "third_party/quiche/src/quic/quartc/quartc_packet_writer.h", "third_party/quiche/src/quic/quartc/quartc_session.cc",
diff --git a/net/base/network_isolation_key.cc b/net/base/network_isolation_key.cc index 646d615c..cc2aa53 100644 --- a/net/base/network_isolation_key.cc +++ b/net/base/network_isolation_key.cc
@@ -2,9 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/base/network_isolation_key.h" +#include <string> + #include "base/feature_list.h" #include "net/base/features.h" +#include "net/base/network_isolation_key.h" +#include "url/gurl.h" namespace net { @@ -71,8 +74,75 @@ (use_frame_origin_ && frame_origin_->opaque()); } +bool NetworkIsolationKey::ToValue(base::Value* out_value) { + if (IsEmpty()) { + *out_value = base::Value(base::Value::Type::LIST); + return true; + } + + if (IsTransient()) + return false; + + *out_value = base::Value(base::Value::Type::LIST); + // Store origins GURLs, since GURL has validation logic that can be used when + // loading, while Origin only has DCHECKs. + out_value->GetList().emplace_back( + base::Value(top_frame_origin_->GetURL().spec())); + + if (use_frame_origin_) + out_value->GetList().emplace_back( + base::Value(frame_origin_->GetURL().spec())); + return true; +} + +bool NetworkIsolationKey::FromValue( + const base::Value& value, + NetworkIsolationKey* network_isolation_key) { + if (value.type() != base::Value::Type::LIST) + return false; + + const base::Value::ListStorage& list = value.GetList(); + if (list.empty()) { + *network_isolation_key = NetworkIsolationKey(); + return true; + } + + bool use_frame_origin = base::FeatureList::IsEnabled( + net::features::kAppendFrameOriginToNetworkIsolationKey); + if ((!use_frame_origin && list.size() != 1) || + (use_frame_origin && list.size() != 2)) { + return false; + } + + if (list[0].type() != base::Value::Type::STRING) + return false; + GURL top_frame_url(list[0].GetString()); + if (!top_frame_url.is_valid()) + return false; + url::Origin top_frame_origin = url::Origin::Create(top_frame_url); + if (!use_frame_origin) { + NetworkIsolationKey result_value(top_frame_origin, top_frame_origin); + if (result_value.IsTransient()) + return false; + *network_isolation_key = std::move(result_value); + return true; + } + + if (list[1].type() != base::Value::Type::STRING) + return false; + GURL frame_url(list[1].GetString()); + if (!frame_url.is_valid()) + return false; + url::Origin frame_origin = url::Origin::Create(frame_url); + NetworkIsolationKey result_value(top_frame_origin, frame_origin); + if (result_value.IsTransient()) + return false; + *network_isolation_key = std::move(result_value); + return true; +} + bool NetworkIsolationKey::IsEmpty() const { - return !top_frame_origin_.has_value(); + return !top_frame_origin_.has_value() && !frame_origin_.has_value(); } } // namespace net
diff --git a/net/base/network_isolation_key.h b/net/base/network_isolation_key.h index 82bfba0..be8f10d 100644 --- a/net/base/network_isolation_key.h +++ b/net/base/network_isolation_key.h
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "base/optional.h" +#include "base/values.h" #include "net/base/net_export.h" #include "url/origin.h" @@ -64,8 +65,9 @@ // Returns true if all parts of the key are non-empty. bool IsFullyPopulated() const; - // Returns true if this key's lifetime is short-lived. It may not make sense - // to persist state to disk related to it (e.g., disk cache). + // Returns true if this key's lifetime is short-lived, or if + // IsFullyPopulated() returns true. It may not make sense to persist state to + // disk related to it (e.g., disk cache). bool IsTransient() const; // APIs for serialization to and from the mojo structure. @@ -80,6 +82,19 @@ // Returns true if all parts of the key are empty. bool IsEmpty() const; + // Returns a representation of |this| as a base::Value. Returns false on + // failure. Succeeds if either IsEmpty() or !IsTransient(). + bool ToValue(base::Value* out_value) WARN_UNUSED_RESULT; + + // Inverse of ToValue(). Writes the result to |network_isolation_key|. Returns + // false on failure. Fails on values that could not have been produced by + // ToValue(), like transient origins. If the value of + // net::features::kAppendFrameOriginToNetworkIsolationKey has changed between + // saving and loading the data, fails. + static bool FromValue(const base::Value& value, + NetworkIsolationKey* out_network_isolation_key) + WARN_UNUSED_RESULT; + private: // Whether or not to use the |frame_origin_| as part of the key. bool use_frame_origin_;
diff --git a/net/base/network_isolation_key_unittest.cc b/net/base/network_isolation_key_unittest.cc index c3b52dc7..295c755 100644 --- a/net/base/network_isolation_key_unittest.cc +++ b/net/base/network_isolation_key_unittest.cc
@@ -6,6 +6,7 @@ #include "base/stl_util.h" #include "base/test/scoped_feature_list.h" +#include "base/values.h" #include "net/base/features.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -150,6 +151,143 @@ key2.ToDebugString()); } +TEST(NetworkIsolationKeyTest, ValueRoundTripEmpty) { + const url::Origin kJunkOrigin = + url::Origin::Create(GURL("data:text/html,junk")); + + // Convert empty key to value and back, expecting the same value. + NetworkIsolationKey no_frame_origin_key; + base::Value no_frame_origin_value; + ASSERT_TRUE(no_frame_origin_key.ToValue(&no_frame_origin_value)); + + // Fill initial value with junk data, to make sure it's overwritten. + NetworkIsolationKey out_key(kJunkOrigin, kJunkOrigin); + EXPECT_TRUE(NetworkIsolationKey::FromValue(no_frame_origin_value, &out_key)); + EXPECT_EQ(no_frame_origin_key, out_key); + + // Perform same checks when frame origins are enabled. + + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature( + net::features::kAppendFrameOriginToNetworkIsolationKey); + + NetworkIsolationKey frame_origin_key; + base::Value frame_origin_value; + ASSERT_TRUE(frame_origin_key.ToValue(&frame_origin_value)); + + // Fill initial value with junk data, to make sure it's overwritten. + out_key = NetworkIsolationKey(kJunkOrigin, kJunkOrigin); + EXPECT_TRUE(NetworkIsolationKey::FromValue(frame_origin_value, &out_key)); + EXPECT_EQ(frame_origin_key, out_key); + + // The Values should also be the same in both cases. + EXPECT_EQ(no_frame_origin_key, frame_origin_key); +} + +TEST(NetworkIsolationKeyTest, ValueRoundTripNoFrameOrigin) { + const url::Origin kJunkOrigin = + url::Origin::Create(GURL("data:text/html,junk")); + + NetworkIsolationKey key1(url::Origin::Create(GURL("https://foo.test/")), + kJunkOrigin); + base::Value value; + ASSERT_TRUE(key1.ToValue(&value)); + + // Fill initial value with junk data, to make sure it's overwritten. + NetworkIsolationKey key2(kJunkOrigin, kJunkOrigin); + EXPECT_TRUE(NetworkIsolationKey::FromValue(value, &key2)); + EXPECT_EQ(key1, key2); + + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature( + net::features::kAppendFrameOriginToNetworkIsolationKey); + + // Loading should fail when frame origins are enabled. + EXPECT_FALSE(NetworkIsolationKey::FromValue(value, &key2)); +} + +TEST(NetworkIsolationKeyTest, ValueRoundTripFrameOrigin) { + const url::Origin kJunkOrigin = + url::Origin::Create(GURL("data:text/html,junk")); + + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature( + net::features::kAppendFrameOriginToNetworkIsolationKey); + + NetworkIsolationKey key1(url::Origin::Create(GURL("https://foo.test/")), + url::Origin::Create(GURL("https://foo.test/"))); + base::Value value; + ASSERT_TRUE(key1.ToValue(&value)); + + // Fill initial value with junk data, to make sure it's overwritten. + NetworkIsolationKey key2(kJunkOrigin, kJunkOrigin); + EXPECT_TRUE(NetworkIsolationKey::FromValue(value, &key2)); + EXPECT_EQ(key1, key2); + + feature_list.Reset(); + + // Loading should fail when frame origins are disabled. + EXPECT_FALSE(NetworkIsolationKey::FromValue(value, &key2)); +} + +TEST(NetworkIsolationKeyTest, ToValueTransientOrigin) { + const url::Origin kTransientOrigin = + url::Origin::Create(GURL("data:text/html,transient")); + + for (bool use_frame_origins : {false, true}) { + SCOPED_TRACE(use_frame_origins); + base::test::ScopedFeatureList feature_list; + if (use_frame_origins) { + feature_list.InitAndEnableFeature( + net::features::kAppendFrameOriginToNetworkIsolationKey); + } + + NetworkIsolationKey key1(kTransientOrigin, kTransientOrigin); + EXPECT_TRUE(key1.IsTransient()); + base::Value value; + EXPECT_FALSE(key1.ToValue(&value)); + } +} + +TEST(NetworkIsolationKeyTest, FromValueBadData) { + // Can't create these inline, since vector initialization lists require a + // copy, and base::Value has no copy operator, only move. + base::Value::ListStorage not_a_url_list; + not_a_url_list.emplace_back(base::Value("not-a-url")); + + base::Value::ListStorage transient_origin_list; + transient_origin_list.emplace_back(base::Value("data:text/html,transient")); + + base::Value::ListStorage too_many_origins_list; + too_many_origins_list.emplace_back(base::Value("https://too/")); + too_many_origins_list.emplace_back(base::Value("https://many/")); + too_many_origins_list.emplace_back(base::Value("https://origins/")); + + const base::Value kTestCases[] = { + base::Value(base::Value::Type::STRING), + base::Value(base::Value::Type::DICTIONARY), + base::Value(std::move(not_a_url_list)), + base::Value(std::move(transient_origin_list)), + base::Value(std::move(too_many_origins_list)), + }; + + for (bool use_frame_origins : {false, true}) { + SCOPED_TRACE(use_frame_origins); + base::test::ScopedFeatureList feature_list; + if (use_frame_origins) { + feature_list.InitAndEnableFeature( + net::features::kAppendFrameOriginToNetworkIsolationKey); + } + + for (const auto& test_case : kTestCases) { + NetworkIsolationKey key; + // Write the value on failure. + EXPECT_FALSE(NetworkIsolationKey::FromValue(test_case, &key)) + << test_case; + } + } +} + class NetworkIsolationKeyWithFrameOriginTest : public testing::Test { public: NetworkIsolationKeyWithFrameOriginTest() {
diff --git a/net/base/url_util.cc b/net/base/url_util.cc index d8287fc8..9cd3c36 100644 --- a/net/base/url_util.cc +++ b/net/base/url_util.cc
@@ -356,27 +356,10 @@ } bool HostStringIsLocalhost(base::StringPiece host) { - if (IsLocalHostname(host, nullptr)) - return true; - IPAddress ip_address; - if (ip_address.AssignFromIPLiteral(host)) { - size_t size = ip_address.size(); - switch (size) { - case IPAddress::kIPv4AddressSize: { - const uint8_t prefix[] = {127}; - return IPAddressStartsWith(ip_address, prefix); - } - - case IPAddress::kIPv6AddressSize: - return ip_address == IPAddress::IPv6Localhost(); - - default: - NOTREACHED(); - } - } - - return false; + if (ip_address.AssignFromIPLiteral(host)) + return ip_address.IsLoopback(); + return IsLocalHostname(host, nullptr); } GURL SimplifyUrlForRequest(const GURL& url) {
diff --git a/net/cert/cert_verify_proc_blocklist.inc b/net/cert/cert_verify_proc_blocklist.inc index 99a9bcf..3d3b2c5 100644 --- a/net/cert/cert_verify_proc_blocklist.inc +++ b/net/cert/cert_verify_proc_blocklist.inc
@@ -47,6 +47,10 @@ {0x2c, 0x99, 0x8e, 0x76, 0x11, 0x60, 0xc3, 0xb0, 0x6d, 0x82, 0xfa, 0xa9, 0xfd, 0xc7, 0x54, 0x5d, 0x9b, 0xda, 0x9e, 0xb6, 0x03, 0x10, 0xf9, 0x92, 0xaa, 0x51, 0x0a, 0x62, 0x80, 0xb7, 0x42, 0x45}, + // 82a4cedbc7f61ce5cb04482aa27ea3145bb0cea58ab63ba1931a1654bfbdbb4f.pem + {0x2d, 0xc4, 0xcb, 0x59, 0x1f, 0x7e, 0xf0, 0x66, 0x34, 0x41, 0x64, + 0x6b, 0xcf, 0x5c, 0x0e, 0x9d, 0xbc, 0xde, 0xd7, 0x7c, 0xa0, 0x29, + 0x45, 0x19, 0x3c, 0xef, 0xc6, 0xed, 0xb1, 0x74, 0x06, 0x14}, // d0d672c2547d574ae055d9e78a993ddbcc74044c4253fbfaca573a67d368e1db.pem {0x30, 0xef, 0xe4, 0x13, 0x82, 0x47, 0x6c, 0x33, 0x80, 0xf0, 0x2f, 0x7e, 0x23, 0xe6, 0x6b, 0xa2, 0xf8, 0x67, 0xb0, 0x59, 0xee, 0x1e,
diff --git a/net/data/ssl/blocklist/82a4cedbc7f61ce5cb04482aa27ea3145bb0cea58ab63ba1931a1654bfbdbb4f.pem b/net/data/ssl/blocklist/82a4cedbc7f61ce5cb04482aa27ea3145bb0cea58ab63ba1931a1654bfbdbb4f.pem new file mode 100644 index 0000000..10fdcd8 --- /dev/null +++ b/net/data/ssl/blocklist/82a4cedbc7f61ce5cb04482aa27ea3145bb0cea58ab63ba1931a1654bfbdbb4f.pem
@@ -0,0 +1,140 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + fa:0c:43:ad:50:ca:d5:3d:88:c3:f0:4a:f7:7b:65:c6 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=TX, L=Houston, O=cPanel, Inc., CN=cPanel, Inc. Certification Authority + Validity + Not Before: Aug 5 00:00:00 2019 GMT + Not After : Nov 3 23:59:59 2019 GMT + Subject: CN=google.tg + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:df:f3:e5:4e:70:8c:0f:fb:ab:25:a7:c0:ee:a9: + c1:be:b4:56:01:06:b7:83:83:64:d9:6b:92:61:3c: + 9a:94:d2:b9:0a:66:82:2d:78:62:38:21:39:f5:5f: + be:04:52:d5:73:e6:32:32:8d:4d:94:44:19:bb:b2: + 92:07:32:4f:26:0c:53:5b:ad:af:cb:70:82:3a:ab: + d0:3d:5d:42:d3:b3:74:7c:41:64:b1:0f:02:a8:dd: + d4:73:63:87:aa:c3:de:6b:f5:1e:f1:9d:e8:8d:2c: + e0:8e:74:24:b0:87:cb:7b:8d:ff:e7:a8:c9:d0:d1: + 06:59:67:f3:c0:20:42:16:41:08:55:fe:9d:f0:71: + 2b:29:aa:d3:b9:98:b5:b6:19:db:dc:7d:7f:68:ac: + 8f:f9:f7:dc:64:de:fd:01:b1:c5:b8:47:97:6d:5f: + a3:3d:a0:df:cb:37:bd:b0:b0:d2:7a:84:0a:70:eb: + bb:60:34:4d:1b:ef:6f:2b:4c:f1:13:51:b7:c3:d2: + e4:d7:45:53:95:ae:cb:dc:b4:d3:82:e2:ea:91:60: + 1a:5c:e7:5b:ff:1b:5b:45:4c:d4:64:a4:8e:cf:5e: + 17:9e:0d:75:57:62:be:c4:0a:09:81:3b:24:c7:56: + 36:46:a6:2e:c1:1e:bc:cb:dc:1a:6f:a7:05:a9:b4: + 66:bf + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Authority Key Identifier: + keyid:7E:03:5A:65:41:6B:A7:7E:0A:E1:B8:9D:08:EA:1D:8E:1D:6A:C7:65 + + X509v3 Subject Key Identifier: + 38:BD:A3:F5:4D:B6:57:5F:11:16:B8:DD:54:8B:1D:0D:EF:08:D0:9C + X509v3 Key Usage: critical + Digital Signature, Key Encipherment + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Extended Key Usage: + TLS Web Server Authentication, TLS Web Client Authentication + X509v3 Certificate Policies: + Policy: 1.3.6.1.4.1.6449.1.2.2.52 + CPS: https://secure.comodo.com/CPS + Policy: 2.23.140.1.2.1 + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.comodoca.com/cPanelIncCertificationAuthority.crl + + Authority Information Access: + CA Issuers - URI:http://crt.comodoca.com/cPanelIncCertificationAuthority.crt + OCSP - URI:http://ocsp.comodoca.com + + X509v3 Subject Alternative Name: + DNS:google.tg, DNS:autodiscover.google.tg, DNS:cpanel.google.tg, DNS:google.leftyslivemusic.com, DNS:mail.google.tg, DNS:webdisk.google.tg, DNS:webmail.google.tg, DNS:www.google.leftyslivemusic.com, DNS:www.google.tg + CT Precertificate SCTs: + Signed Certificate Timestamp: + Version : v1(0) + Log ID : 63:F2:DB:CD:E8:3B:CC:2C:CF:0B:72:84:27:57:6B:33: + A4:8D:61:77:8F:BD:75:A6:38:B1:C7:68:54:4B:D8:8D + Timestamp : Aug 5 16:03:54.628 2019 GMT + Extensions: none + Signature : ecdsa-with-SHA256 + 30:44:02:20:11:15:25:95:E0:87:EE:1C:7F:22:EA:36: + B8:57:DE:C5:6A:DE:0A:50:DB:FF:BC:04:04:9B:01:24: + E0:BE:CC:84:02:20:72:3D:F2:10:8A:D5:F6:CF:31:17: + BA:E6:FF:30:CC:3E:C5:6D:BE:DE:DA:4C:16:AC:67:4B: + A0:DF:CC:CA:F6:C6 + Signed Certificate Timestamp: + Version : v1(0) + Log ID : 74:7E:DA:83:31:AD:33:10:91:21:9C:CE:25:4F:42:70: + C2:BF:FD:5E:42:20:08:C6:37:35:79:E6:10:7B:CC:56 + Timestamp : Aug 5 16:03:54.703 2019 GMT + Extensions: none + Signature : ecdsa-with-SHA256 + 30:46:02:21:00:FA:33:5E:17:CE:54:E0:31:9B:53:68: + 53:9F:17:C2:02:04:A6:2C:74:AD:F6:4F:4F:C7:87:14: + 63:3B:CB:3D:16:02:21:00:90:FA:4D:D9:0B:90:65:36: + A2:75:38:D6:17:06:F0:39:43:68:8A:21:F4:3E:F2:33: + 62:A1:55:DD:45:95:36:41 + Signature Algorithm: sha256WithRSAEncryption + 2b:33:7c:7f:68:fc:09:aa:b9:0b:89:e1:35:03:ae:b9:0e:c9: + fa:07:8b:59:c6:ab:dd:72:d1:dc:1b:0d:59:f5:a4:0c:be:92: + cd:d8:65:84:3c:68:8a:3d:2b:43:b7:8c:91:91:0e:93:05:a4: + 34:21:59:28:ba:33:ac:cb:bf:a1:e4:4f:a9:24:19:1b:63:80: + 4e:87:ba:ef:d4:f1:62:ad:da:cb:84:18:13:7a:70:81:e5:89: + 57:d4:aa:7b:cf:e2:a8:8b:53:0b:7b:56:ec:50:f4:72:ff:48: + a3:88:79:99:c2:4a:1f:ea:22:da:3b:79:b5:b0:3a:75:a6:a9: + 17:d8:67:ed:c8:45:74:47:9a:49:d0:14:be:9e:7b:e3:c3:df: + 71:6a:a4:18:ba:3e:f5:f5:69:d0:36:ac:ca:58:6d:c9:51:01: + a4:45:dc:34:11:d4:88:c3:5f:db:ea:a0:ec:88:ae:44:05:58: + a8:4e:b7:6b:33:8d:5f:8d:6a:f4:8d:39:bf:84:2b:4d:2b:3f: + 94:b5:d6:a2:fc:e7:2c:e4:26:77:6c:c5:84:3f:ba:2b:e4:ad: + 4f:4e:c6:a4:30:11:06:e4:53:71:3c:10:67:03:8f:52:f8:6c: + c6:b2:36:e2:5d:c2:d7:c8:4f:5f:36:dd:64:cc:5a:f7:42:b9: + db:f5:85:95 +-----BEGIN CERTIFICATE----- +MIIGfjCCBWagAwIBAgIRAPoMQ61QytU9iMPwSvd7ZcYwDQYJKoZIhvcNAQELBQAw +cjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlRYMRAwDgYDVQQHEwdIb3VzdG9uMRUw +EwYDVQQKEwxjUGFuZWwsIEluYy4xLTArBgNVBAMTJGNQYW5lbCwgSW5jLiBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xOTA4MDUwMDAwMDBaFw0xOTExMDMyMzU5 +NTlaMBQxEjAQBgNVBAMTCWdvb2dsZS50ZzCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAN/z5U5wjA/7qyWnwO6pwb60VgEGt4ODZNlrkmE8mpTSuQpmgi14 +YjghOfVfvgRS1XPmMjKNTZREGbuykgcyTyYMU1utr8twgjqr0D1dQtOzdHxBZLEP +Aqjd1HNjh6rD3mv1HvGd6I0s4I50JLCHy3uN/+eoydDRBlln88AgQhZBCFX+nfBx +Kymq07mYtbYZ29x9f2isj/n33GTe/QGxxbhHl21foz2g38s3vbCw0nqECnDru2A0 +TRvvbytM8RNRt8PS5NdFU5Wuy9y004Li6pFgGlznW/8bW0VM1GSkjs9eF54NdVdi +vsQKCYE7JMdWNkamLsEevMvcGm+nBam0Zr8CAwEAAaOCA2swggNnMB8GA1UdIwQY +MBaAFH4DWmVBa6d+CuG4nQjqHY4dasdlMB0GA1UdDgQWBBQ4vaP1TbZXXxEWuN1U +ix0N7wjQnDAOBgNVHQ8BAf8EBAMCBaAwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAU +BggrBgEFBQcDAQYIKwYBBQUHAwIwTwYDVR0gBEgwRjA6BgsrBgEEAbIxAQICNDAr +MCkGCCsGAQUFBwIBFh1odHRwczovL3NlY3VyZS5jb21vZG8uY29tL0NQUzAIBgZn +gQwBAgEwTAYDVR0fBEUwQzBBoD+gPYY7aHR0cDovL2NybC5jb21vZG9jYS5jb20v +Y1BhbmVsSW5jQ2VydGlmaWNhdGlvbkF1dGhvcml0eS5jcmwwfQYIKwYBBQUHAQEE +cTBvMEcGCCsGAQUFBzAChjtodHRwOi8vY3J0LmNvbW9kb2NhLmNvbS9jUGFuZWxJ +bmNDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNydDAkBggrBgEFBQcwAYYYaHR0cDov +L29jc3AuY29tb2RvY2EuY29tMIHBBgNVHREEgbkwgbaCCWdvb2dsZS50Z4IWYXV0 +b2Rpc2NvdmVyLmdvb2dsZS50Z4IQY3BhbmVsLmdvb2dsZS50Z4IaZ29vZ2xlLmxl +ZnR5c2xpdmVtdXNpYy5jb22CDm1haWwuZ29vZ2xlLnRnghF3ZWJkaXNrLmdvb2ds +ZS50Z4IRd2VibWFpbC5nb29nbGUudGeCHnd3dy5nb29nbGUubGVmdHlzbGl2ZW11 +c2ljLmNvbYINd3d3Lmdvb2dsZS50ZzCCAQQGCisGAQQB1nkCBAIEgfUEgfIA8AB1 +AGPy283oO8wszwtyhCdXazOkjWF3j711pjixx2hUS9iNAAABbGKF2IQAAAQDAEYw +RAIgERUlleCH7hx/Iuo2uFfexWreClDb/7wEBJsBJOC+zIQCIHI98hCK1fbPMRe6 +5v8wzD7Fbb7e2kwWrGdLoN/MyvbGAHcAdH7agzGtMxCRIZzOJU9CcMK//V5CIAjG +NzV55hB7zFYAAAFsYoXYzwAABAMASDBGAiEA+jNeF85U4DGbU2hTnxfCAgSmLHSt +9k9Px4cUYzvLPRYCIQCQ+k3ZC5BlNqJ1ONYXBvA5Q2iKIfQ+8jNioVXdRZU2QTAN +BgkqhkiG9w0BAQsFAAOCAQEAKzN8f2j8Caq5C4nhNQOuuQ7J+geLWcar3XLR3BsN +WfWkDL6SzdhlhDxoij0rQ7eMkZEOkwWkNCFZKLozrMu/oeRPqSQZG2OAToe679Tx +Yq3ay4QYE3pwgeWJV9Sqe8/iqItTC3tW7FD0cv9Io4h5mcJKH+oi2jt5tbA6daap +F9hn7chFdEeaSdAUvp5748PfcWqkGLo+9fVp0DasylhtyVEBpEXcNBHUiMNf2+qg +7IiuRAVYqE63azONX41q9I05v4QrTSs/lLXWovznLOQmd2zFhD+6K+StT07GpDAR +BuRTcTwQZwOPUvhsxrI24l3C18hPXzbdZMxa90K52/WFlQ== +-----END CERTIFICATE-----
diff --git a/net/data/ssl/blocklist/README.md b/net/data/ssl/blocklist/README.md index 5de614a0..237a84c 100644 --- a/net/data/ssl/blocklist/README.md +++ b/net/data/ssl/blocklist/README.md
@@ -1,11 +1,23 @@ # Certificate Blocklist This directory contains a number of certificates and public keys which are -considered blocked within Chromium-based products. +considered blocked within Chromium-based products. When applicable, additional information and the full certificate or key are included. +## Adding a New Entry + +Entries are recorded in [cert_verify_proc_blocklist.inc](../../../cert/cert_verify_proc_blocklist.inc). +The filename is the SHA-256 hash of the DER-encoded certificate, which can be +obtained via: + + openssl x509 -in path/to/cert.pem -outform DER | openssl dgst -sha256 + +The entries in the `cert_verify_proc_blocklist.inc` file can be generated via: + + openssl x509 -in path/to/cert.pem -noout -pubkey | openssl pkey -pubin -outform DER | openssl dgst -sha256 -c | awk '{print "0x" $2}' | sed 's/:/, 0x/g' + ## Compromises & Misissuances ### .bd @@ -107,6 +119,10 @@ * [c71f33c36d8efeefbed9d44e85e21cfe96b36fb0e132c52dca2415868492bf8a.pem](c71f33c36d8efeefbed9d44e85e21cfe96b36fb0e132c52dca2415868492bf8a.pem) * [fa5a828c9a7e732692682e60b14c634309cbb2bb79eb12aef44318d853ee97e3.pem](fa5a828c9a7e732692682e60b14c634309cbb2bb79eb12aef44318d853ee97e3.pem) +Another incident in August 2019. + + * [82a4cedbc7f61ce5cb04482aa27ea3145bb0cea58ab63ba1931a1654bfbdbb4f.pem](82a4cedbc7f61ce5cb04482aa27ea3145bb0cea58ab63ba1931a1654bfbdbb4f.pem) + ### Trustwave For details, see <https://www.trustwave.com/Resources/SpiderLabs-Blog/Clarifying-The-Trustwave-CA-Policy-Update/>
diff --git a/net/http/bidirectional_stream.cc b/net/http/bidirectional_stream.cc index 03a36f5..d4b199b5 100644 --- a/net/http/bidirectional_stream.cc +++ b/net/http/bidirectional_stream.cc
@@ -418,11 +418,8 @@ // BidirectionalStream doesn't support client auth. It ignores client auth // requests with null client cert and key. SSLConfig ssl_config = used_ssl_config; - ssl_config.send_client_cert = true; - ssl_config.client_cert = nullptr; - ssl_config.client_private_key = nullptr; - session_->ssl_client_auth_cache()->Add(cert_info->host_and_port, nullptr, - nullptr); + session_->ssl_client_context()->SetClientCertificate(cert_info->host_and_port, + nullptr, nullptr); stream_request_ = nullptr; StartRequest(ssl_config); }
diff --git a/net/http/bidirectional_stream_unittest.cc b/net/http/bidirectional_stream_unittest.cc index cb02bd3..4e2f167 100644 --- a/net/http/bidirectional_stream_unittest.cc +++ b/net/http/bidirectional_stream_unittest.cc
@@ -646,7 +646,7 @@ // Ensure the certificate was added to the client auth cache. scoped_refptr<X509Certificate> client_cert; scoped_refptr<SSLPrivateKey> client_private_key; - ASSERT_TRUE(http_session_->ssl_client_auth_cache()->Lookup( + ASSERT_TRUE(http_session_->ssl_client_context()->GetClientCertificate( host_port_pair_, &client_cert, &client_private_key)); ASSERT_FALSE(client_cert); ASSERT_FALSE(client_private_key);
diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h index af70598..75c7d13 100644 --- a/net/http/http_network_session.h +++ b/net/http/http_network_session.h
@@ -34,7 +34,6 @@ #include "net/socket/next_proto.h" #include "net/socket/websocket_endpoint_lock_manager.h" #include "net/spdy/spdy_session_pool.h" -#include "net/ssl/ssl_client_auth_cache.h" #include "net/ssl/ssl_client_session_cache.h" #include "net/third_party/quiche/src/spdy/core/spdy_protocol.h" @@ -195,9 +194,7 @@ ~HttpNetworkSession(); HttpAuthCache* http_auth_cache() { return &http_auth_cache_; } - SSLClientAuthCache* ssl_client_auth_cache() { - return &ssl_client_auth_cache_; - } + SSLClientContext* ssl_client_context() { return &ssl_client_context_; } void AddResponseDrainer(std::unique_ptr<HttpResponseBodyDrainer> drainer); @@ -312,7 +309,6 @@ SSLConfigService* const ssl_config_service_; HttpAuthCache http_auth_cache_; - SSLClientAuthCache ssl_client_auth_cache_; SSLClientSessionCache ssl_client_session_cache_; SSLClientContext ssl_client_context_; WebSocketEndpointLockManager websocket_endpoint_lock_manager_;
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index 00360b4f..c453a8d 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc
@@ -117,7 +117,7 @@ priority_(priority), headers_valid_(false), can_send_early_data_(false), - server_ssl_client_cert_was_cached_(false), + configured_client_cert_for_server_(false), request_headers_(), #if BUILDFLAG(ENABLE_REPORTING) network_error_logging_report_generated_(false), @@ -234,8 +234,8 @@ scoped_refptr<X509Certificate> client_cert, scoped_refptr<SSLPrivateKey> client_private_key, CompletionOnceCallback callback) { - // In HandleCertificateRequest(), we always tear down existing stream - // requests to force a new connection. So we shouldn't have one here. + // When we receive ERR_SSL_CLIENT_AUTH_CERT_NEEDED, we always tear down + // existing streams and stream requests to force a new connection. DCHECK(!stream_request_.get()); DCHECK(!stream_.get()); DCHECK_EQ(STATE_NONE, next_state_); @@ -243,14 +243,15 @@ if (!CheckMaxRestarts()) return ERR_TOO_MANY_RETRIES; - SSLConfig* ssl_config = response_.cert_request_info->is_proxy ? - &proxy_ssl_config_ : &server_ssl_config_; - ssl_config->send_client_cert = true; - ssl_config->client_cert = client_cert; - ssl_config->client_private_key = client_private_key; - session_->ssl_client_auth_cache()->Add( + // Add the credentials to the client auth cache. The next stream request will + // then pick them up. + session_->ssl_client_context()->SetClientCertificate( response_.cert_request_info->host_and_port, std::move(client_cert), std::move(client_private_key)); + + if (!response_.cert_request_info->is_proxy) + configured_client_cert_for_server_ = true; + // Reset the other member variables. // Note: this is necessary only with SSL renegotiation. ResetStateForRestart(); @@ -833,8 +834,6 @@ if (result == OK) { next_state_ = STATE_INIT_STREAM; DCHECK(stream_.get()); - } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { - result = HandleCertificateRequest(result); } else if (result == ERR_HTTP_1_1_REQUIRED || result == ERR_PROXY_HTTP_1_1_REQUIRED) { return HandleHttp11Required(result); @@ -1051,6 +1050,9 @@ // We don't handle a certificate error during SSL renegotiation, so we // have to return an error that's not in the certificate error range // (-2xx). + // + // TODO(davidben): Remove this error. This is impossible now that server + // certificates are forbidden from changing in renegotiation. LOG(ERROR) << "Got a server certificate with error " << result << " during SSL renegotiation"; result = ERR_CERT_ERROR_IN_SSL_RENEGOTIATION; @@ -1059,9 +1061,10 @@ DCHECK(IsSecureRequest()); response_.cert_request_info = base::MakeRefCounted<SSLCertRequestInfo>(); stream_->GetSSLCertRequestInfo(response_.cert_request_info.get()); - result = HandleCertificateRequest(result); - if (result == OK) - return result; + total_received_bytes_ += stream_->GetTotalReceivedBytes(); + total_sent_bytes_ += stream_->GetTotalSentBytes(); + stream_->Close(true); + CacheNetErrorDetailsAndResetStream(); } if (result == ERR_HTTP_1_1_REQUIRED || @@ -1441,76 +1444,6 @@ } #endif // BUILDFLAG(ENABLE_REPORTING) -int HttpNetworkTransaction::HandleCertificateRequest(int error) { - // There are two paths through which the server can request a certificate - // from us. The first is during the initial handshake, the second is - // during SSL renegotiation. - // - // In both cases, we want to close the connection before proceeding. - // We do this for two reasons: - // First, we don't want to keep the connection to the server hung for a - // long time while the user selects a certificate. - // Second, even if we did keep the connection open, NSS has a bug where - // restarting the handshake for ClientAuth is currently broken. - DCHECK_EQ(error, ERR_SSL_CLIENT_AUTH_CERT_NEEDED); - - if (stream_.get()) { - // Since we already have a stream, we're being called as part of SSL - // renegotiation. - DCHECK(!stream_request_.get()); - total_received_bytes_ += stream_->GetTotalReceivedBytes(); - total_sent_bytes_ += stream_->GetTotalSentBytes(); - stream_->Close(true); - CacheNetErrorDetailsAndResetStream(); - } - - // The server is asking for a client certificate during the initial - // handshake. - stream_request_.reset(); - - // If the user selected one of the certificates in client_certs or declined - // to provide one for this server before, use the past decision - // automatically. - scoped_refptr<X509Certificate> client_cert; - scoped_refptr<SSLPrivateKey> client_private_key; - bool found_cached_cert = session_->ssl_client_auth_cache()->Lookup( - response_.cert_request_info->host_and_port, &client_cert, - &client_private_key); - if (!found_cached_cert) - return error; - - // Check that the certificate selected is still a certificate the server - // is likely to accept, based on the criteria supplied in the - // CertificateRequest message. - if (client_cert.get()) { - const std::vector<std::string>& cert_authorities = - response_.cert_request_info->cert_authorities; - - bool cert_still_valid = cert_authorities.empty() || - client_cert->IsIssuedByEncoded(cert_authorities); - if (!cert_still_valid) - return error; - } - - if (!response_.cert_request_info->is_proxy) { - server_ssl_client_cert_was_cached_ = true; - } - - // TODO(davidben): Add a unit test which covers this path; we need to be - // able to send a legitimate certificate and also bypass/clear the - // SSL session cache. - SSLConfig* ssl_config = response_.cert_request_info->is_proxy ? - &proxy_ssl_config_ : &server_ssl_config_; - ssl_config->send_client_cert = true; - ssl_config->client_cert = client_cert; - ssl_config->client_private_key = client_private_key; - next_state_ = STATE_CREATE_STREAM; - // Reset the other member variables. - // Note: this is necessary only with SSL renegotiation. - ResetStateForRestart(); - return OK; -} - int HttpNetworkTransaction::HandleHttp11Required(int error) { DCHECK(error == ERR_HTTP_1_1_REQUIRED || error == ERR_PROXY_HTTP_1_1_REQUIRED); @@ -1525,50 +1458,45 @@ } int HttpNetworkTransaction::HandleSSLClientAuthError(int error) { - // Most client auth errors here come from the origin server, but they may come - // from the proxy if the request is not tunneled (i.e. the origin is HTTP, so - // there is no HTTPS connection) and the proxy does not report a bad client - // certificate until after the TLS handshake completes. The latter occurs in - // TLS 1.3 or TLS 1.2 with False Start (disabled for proxies). The error will - // then surface out of Read() rather than Connect() and ultimately surfaced - // out of DoReadHeadersComplete(). + // Client certificate errors may come from either the origin server or the + // proxy. + // + // Origin errors are handled here, while most proxy errors are handled in the + // HttpStreamFactory and below. However, if the request is not tunneled (i.e. + // the origin is HTTP, so there is no HTTPS connection) and the proxy does not + // report a bad client certificate until after the TLS handshake completes. + // The latter occurs in TLS 1.3 or TLS 1.2 with False Start (disabled for + // proxies). The error will then surface out of Read() rather than Connect() + // and ultimately surfaced out of DoReadHeadersComplete(). // // See https://crbug.com/828965. - bool is_server; - SSLConfig* ssl_config; - HostPortPair host_port_pair; - if (UsingHttpProxyWithoutTunnel()) { - is_server = false; - ssl_config = &proxy_ssl_config_; - host_port_pair = proxy_info_.proxy_server().host_port_pair(); - } else { - is_server = true; - ssl_config = &server_ssl_config_; - host_port_pair = HostPortPair::FromURL(request_->url); - } + bool is_server = !UsingHttpProxyWithoutTunnel(); + HostPortPair host_port_pair = + is_server ? HostPortPair::FromURL(request_->url) + : proxy_info_.proxy_server().host_port_pair(); - // Client certificate errors from the proxy are handled in the - // HttpStreamFactory and below. - if (ssl_config->send_client_cert && - (error == ERR_SSL_PROTOCOL_ERROR || IsClientCertificateError(error))) { + if (error == ERR_SSL_PROTOCOL_ERROR || IsClientCertificateError(error)) { DCHECK((is_server && IsSecureRequest()) || proxy_info_.is_https()); - session_->ssl_client_auth_cache()->Remove(host_port_pair); - - // The private key handle may have gone stale due to, e.g., the user - // unplugging their smartcard. Operating systems do not provide reliable - // notifications for this, so if the signature failed and the private key - // came from SSLClientAuthCache, retry to ask the user for a new one. - if (is_server && error == ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED && - server_ssl_client_cert_was_cached_ && !HasExceededMaxRetries()) { - server_ssl_client_cert_was_cached_ = false; - server_ssl_config_.send_client_cert = false; - server_ssl_config_.client_cert = nullptr; - server_ssl_config_.client_private_key = nullptr; - retry_attempts_++; - net_log_.AddEventWithNetErrorCode( - NetLogEventType::HTTP_TRANSACTION_RESTART_AFTER_ERROR, error); - ResetConnectionAndRequestForResend(); - return OK; + if (session_->ssl_client_context()->ClearClientCertificate( + host_port_pair)) { + // The private key handle may have gone stale due to, e.g., the user + // unplugging their smartcard. Operating systems do not provide reliable + // notifications for this, so if the signature failed and the user was + // not already prompted for certificate on this request, retry to ask + // the user for a new one. + // + // TODO(davidben): There is no corresponding feature for proxy client + // certificates. Ideally this would live at a lower level, common to both, + // but |configured_client_cert_for_server_| is not accessible below the + // socket pools. + if (is_server && error == ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED && + !configured_client_cert_for_server_ && !HasExceededMaxRetries()) { + retry_attempts_++; + net_log_.AddEventWithNetErrorCode( + NetLogEventType::HTTP_TRANSACTION_RESTART_AFTER_ERROR, error); + ResetConnectionAndRequestForResend(); + return OK; + } } } return error;
diff --git a/net/http/http_network_transaction.h b/net/http/http_network_transaction.h index fbb7bf6..f783e5e 100644 --- a/net/http/http_network_transaction.h +++ b/net/http/http_network_transaction.h
@@ -223,9 +223,6 @@ // response to a CONNECT request. void LogBlockedTunnelResponse(int response_code) const; - // Called to handle a client certificate request. - int HandleCertificateRequest(int error); - // Called wherever ERR_HTTP_1_1_REQUIRED or // ERR_PROXY_HTTP_1_1_REQUIRED has to be handled. int HandleHttp11Required(int error); @@ -339,9 +336,9 @@ // True if we can send the request over early data. bool can_send_early_data_; - // True if |server_ssl_config_.client_cert| was looked up from the - // SSLClientAuthCache, rather than provided externally by the caller. - bool server_ssl_client_cert_was_cached_; + // True if the client certificate for the server (rather than the proxy) was + // configured in this transaction. + bool configured_client_cert_for_server_; // SSL configuration used for the server and proxy, respectively. Note // |server_ssl_config_| may be updated from the HttpStreamFactory, which will
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index 72f9560..a70545f 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc
@@ -15142,7 +15142,7 @@ // allowing the connection to continue restarting. scoped_refptr<X509Certificate> client_cert; scoped_refptr<SSLPrivateKey> client_private_key; - ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup( + ASSERT_TRUE(session->ssl_client_context()->GetClientCertificate( HostPortPair("www.example.com", 443), &client_cert, &client_private_key)); ASSERT_FALSE(client_cert); @@ -15154,7 +15154,7 @@ // Ensure that the client certificate is removed from the cache on a // handshake failure. - ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup( + ASSERT_FALSE(session->ssl_client_context()->GetClientCertificate( HostPortPair("www.example.com", 443), &client_cert, &client_private_key)); } @@ -15260,7 +15260,7 @@ // allowing the connection to continue restarting. scoped_refptr<X509Certificate> client_cert; scoped_refptr<SSLPrivateKey> client_private_key; - ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup( + ASSERT_TRUE(session->ssl_client_context()->GetClientCertificate( HostPortPair("www.example.com", 443), &client_cert, &client_private_key)); ASSERT_FALSE(client_cert); @@ -15272,7 +15272,7 @@ // Ensure that the client certificate is removed from the cache on a // handshake failure. - ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup( + ASSERT_FALSE(session->ssl_client_context()->GetClientCertificate( HostPortPair("www.example.com", 443), &client_cert, &client_private_key)); } @@ -15397,12 +15397,12 @@ // allowing the connection to continue restarting. scoped_refptr<X509Certificate> client_cert; scoped_refptr<SSLPrivateKey> client_private_key; - ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup( + ASSERT_TRUE(session->ssl_client_context()->GetClientCertificate( HostPortPair("proxy", 70), &client_cert, &client_private_key)); ASSERT_FALSE(client_cert); // Ensure the certificate was NOT cached for the endpoint. This only // applies to HTTPS requests, but is fine to check for HTTP requests. - ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup( + ASSERT_FALSE(session->ssl_client_context()->GetClientCertificate( HostPortPair("www.example.com", 443), &client_cert, &client_private_key)); @@ -15414,9 +15414,9 @@ // Now that the new handshake has failed, ensure that the client // certificate was removed from the client auth cache. - ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup( + ASSERT_FALSE(session->ssl_client_context()->GetClientCertificate( HostPortPair("proxy", 70), &client_cert, &client_private_key)); - ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup( + ASSERT_FALSE(session->ssl_client_context()->GetClientCertificate( HostPortPair("www.example.com", 443), &client_cert, &client_private_key)); } @@ -15493,7 +15493,7 @@ // allowing the connection to continue restarting. scoped_refptr<X509Certificate> client_cert; scoped_refptr<SSLPrivateKey> client_private_key; - ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup( + ASSERT_TRUE(session->ssl_client_context()->GetClientCertificate( HostPortPair("www.example.com", 443), &client_cert, &client_private_key)); EXPECT_TRUE(client_cert->EqualsIncludingChain(identity->certificate())); @@ -15503,7 +15503,7 @@ EXPECT_EQ(200, trans.GetResponseInfo()->headers->response_code()); // The client certificate remains in the cache. - ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup( + ASSERT_TRUE(session->ssl_client_context()->GetClientCertificate( HostPortPair("www.example.com", 443), &client_cert, &client_private_key)); EXPECT_TRUE(client_cert->EqualsIncludingChain(identity->certificate())); } @@ -20240,6 +20240,17 @@ mock_reads3.emplace_back( "HTTP/1.1 200 OK\r\n" "Content-Length: 0\r\n\r\n"); + // The client makes another request. This should reuse the socket with all + // credentials cached. + mock_writes3.emplace_back( + "GET / HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Connection: keep-alive\r\n" + // Authenticate as user:pass. + "Authorization: Basic dXNlcjpwYXNz\r\n\r\n"); + mock_reads3.emplace_back( + "HTTP/1.1 200 OK\r\n" + "Content-Length: 0\r\n\r\n"); StaticSocketDataProvider data3(mock_reads3, mock_writes3); session_deps_.socket_factory->AddSocketDataProvider(&data3); session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy3); @@ -20298,6 +20309,14 @@ // The request completes. ASSERT_THAT(rv, IsOk()); EXPECT_EQ(200, trans->GetResponseInfo()->headers->response_code()); + + // Make a second request. This time all credentials are cached. + trans = + std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get()); + ASSERT_THAT(callback.GetResult(trans->Start(&request, callback.callback(), + NetLogWithSource())), + IsOk()); + EXPECT_EQ(200, trans->GetResponseInfo()->headers->response_code()); } // Test the proxy and origin server each requesting both TLS client certificates @@ -20447,6 +20466,38 @@ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy5); session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin5); + // The client makes a second request. This needs yet another connection, but + // all credentials are cached. + SSLSocketDataProvider ssl_proxy6(ASYNC, OK); + ssl_proxy6.expected_send_client_cert = true; + ssl_proxy6.expected_client_cert = identity_proxy->certificate(); + std::vector<MockWrite> mock_writes6; + std::vector<MockRead> mock_reads6; + mock_writes6.emplace_back( + "CONNECT www.example.org:443 HTTP/1.1\r\n" + "Host: www.example.org:443\r\n" + "Proxy-Connection: keep-alive\r\n" + // Authenticate as proxyuser:proxypass. + "Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n"); + mock_reads6.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n"); + SSLSocketDataProvider ssl_origin6(ASYNC, OK); + ssl_origin6.expected_send_client_cert = true; + ssl_origin6.expected_client_cert = identity_origin->certificate(); + mock_writes6.emplace_back( + "GET / HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Connection: keep-alive\r\n" + // Authenticate as user:pass. + "Authorization: Basic dXNlcjpwYXNz\r\n\r\n"); + mock_reads6.emplace_back( + "HTTP/1.1 200 OK\r\n" + "Connection: close\r\n" + "Content-Length: 0\r\n\r\n"); + StaticSocketDataProvider data6(mock_reads6, mock_writes6); + session_deps_.socket_factory->AddSocketDataProvider(&data6); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy6); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin6); + std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); // Start the request. @@ -20500,6 +20551,14 @@ // The request completes. ASSERT_THAT(rv, IsOk()); EXPECT_EQ(200, trans->GetResponseInfo()->headers->response_code()); + + // Make a second request. This time all credentials are cached. + trans = + std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get()); + ASSERT_THAT(callback.GetResult(trans->Start(&request, callback.callback(), + NetLogWithSource())), + IsOk()); + EXPECT_EQ(200, trans->GetResponseInfo()->headers->response_code()); } // Test the proxy requesting HTTP auth and the server requesting TLS client @@ -21555,4 +21614,295 @@ EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NETWORK_CHANGED)); } +// Test that HttpNetworkTransaction correctly handles existing sockets when the +// server requests a client certificate post-handshake (via a TLS +// renegotiation). This is a regression test for https://crbug.com/829184. +TEST_F(HttpNetworkTransactionTest, PostHandshakeClientCertWithSockets) { + const MutableNetworkTrafficAnnotationTag kTrafficAnnotation( + TRAFFIC_ANNOTATION_FOR_TESTS); + + auto cert_request_info = base::MakeRefCounted<SSLCertRequestInfo>(); + cert_request_info->host_and_port = HostPortPair("foo.test", 443); + + std::unique_ptr<FakeClientCertIdentity> identity = + FakeClientCertIdentity::CreateFromCertAndKeyFiles( + GetTestCertsDirectory(), "client_1.pem", "client_1.pk8"); + ASSERT_TRUE(identity); + + // This test will make several requests so that, when the client certificate + // request comes in, we have a socket in use, an idle socket, and a socket for + // an unrelated host. + // + // First, two long-lived requests which do not complete until after the client + // certificate request. This arranges for sockets to be in use during the + // request. They should not be interrupted. + HttpRequestInfo request_long_lived; + request_long_lived.method = "GET"; + request_long_lived.url = GURL("https://foo.test/long-lived"); + request_long_lived.traffic_annotation = kTrafficAnnotation; + + HttpRequestInfo request_long_lived_bar; + request_long_lived_bar.method = "GET"; + request_long_lived_bar.url = GURL("https://bar.test/long-lived"); + request_long_lived_bar.traffic_annotation = kTrafficAnnotation; + + // Next, make a request that needs client certificates. + HttpRequestInfo request_auth; + request_auth.method = "GET"; + request_auth.url = GURL("https://foo.test/auth"); + request_auth.traffic_annotation = kTrafficAnnotation; + + // Before responding to the challenge, make a request to an unauthenticated + // endpoint. This will result in an idle socket when the client certificate + // challenge is resolved. + HttpRequestInfo request_unauth; + request_unauth.method = "GET"; + request_unauth.url = GURL("https://foo.test/unauth"); + request_unauth.traffic_annotation = kTrafficAnnotation; + + // After all the preceding requests complete, end with two additional requests + // to ensure pre-authentication foo.test sockets are not used and bar.test + // sockets are unaffected. + HttpRequestInfo request_post_auth; + request_post_auth.method = "GET"; + request_post_auth.url = GURL("https://foo.test/post-auth"); + request_post_auth.traffic_annotation = kTrafficAnnotation; + + HttpRequestInfo request_post_auth_bar; + request_post_auth_bar.method = "GET"; + request_post_auth_bar.url = GURL("https://bar.test/post-auth"); + request_post_auth_bar.traffic_annotation = kTrafficAnnotation; + + // The sockets for /long-lived and /unauth complete their request but are + // not allocated for /post-auth or /retry because SSL state has since changed. + const MockWrite kLongLivedWrites[] = { + MockWrite(ASYNC, 0, + "GET /long-lived HTTP/1.1\r\n" + "Host: foo.test\r\n" + "Connection: keep-alive\r\n\r\n"), + }; + const MockRead kLongLivedReads[] = { + // Pause so /long-lived completes after the client presents client + // certificates. + MockRead(ASYNC, ERR_IO_PENDING, 1), + MockRead(ASYNC, 2, + "HTTP/1.1 200 OK\r\n" + "Connection: keep-alive\r\n" + "Content-Length: 10\r\n\r\n" + "long-lived"), + }; + SequencedSocketData data_long_lived(kLongLivedReads, kLongLivedWrites); + SSLSocketDataProvider ssl_long_lived(ASYNC, OK); + session_deps_.socket_factory->AddSocketDataProvider(&data_long_lived); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_long_lived); + + // Requests for bar.test should be unaffected by foo.test and get allocated + // a single socket. + const MockWrite kBarWrites[] = { + MockWrite(ASYNC, 0, + "GET /long-lived HTTP/1.1\r\n" + "Host: bar.test\r\n" + "Connection: keep-alive\r\n\r\n"), + MockWrite(ASYNC, 3, + "GET /post-auth HTTP/1.1\r\n" + "Host: bar.test\r\n" + "Connection: keep-alive\r\n\r\n"), + }; + const MockRead kBarReads[] = { + // Pause on /long-lived so it completes after foo.test's authentication. + MockRead(ASYNC, ERR_IO_PENDING, 1), + MockRead(ASYNC, 2, + "HTTP/1.1 200 OK\r\n" + "Connection: keep-alive\r\n" + "Content-Length: 10\r\n\r\n" + "long-lived"), + MockRead(ASYNC, 4, + "HTTP/1.1 200 OK\r\n" + "Connection: keep-alive\r\n" + "Content-Length: 9\r\n\r\n" + "post-auth"), + }; + SequencedSocketData data_bar(kBarReads, kBarWrites); + SSLSocketDataProvider ssl_bar(ASYNC, OK); + session_deps_.socket_factory->AddSocketDataProvider(&data_bar); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bar); + + // Requesting /auth results in a post-handshake client certificate challenge. + const MockWrite kAuthWrites[] = { + MockWrite(ASYNC, 0, + "GET /auth HTTP/1.1\r\n" + "Host: foo.test\r\n" + "Connection: keep-alive\r\n\r\n"), + }; + const MockRead kAuthReads[] = { + MockRead(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED, 1), + }; + SequencedSocketData data_auth(kAuthReads, kAuthWrites); + SSLSocketDataProvider ssl_auth(ASYNC, OK); + ssl_auth.cert_request_info = cert_request_info.get(); + session_deps_.socket_factory->AddSocketDataProvider(&data_auth); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_auth); + + // Requesting /unauth completes. + const MockWrite kUnauthWrites[] = { + MockWrite(ASYNC, 0, + "GET /unauth HTTP/1.1\r\n" + "Host: foo.test\r\n" + "Connection: keep-alive\r\n\r\n"), + }; + const MockRead kUnauthReads[] = { + MockRead(ASYNC, 1, + "HTTP/1.1 200 OK\r\n" + "Connection: keep-alive\r\n" + "Content-Length: 6\r\n\r\n" + "unauth"), + }; + SequencedSocketData data_unauth(kUnauthReads, kUnauthWrites); + SSLSocketDataProvider ssl_unauth(ASYNC, OK); + session_deps_.socket_factory->AddSocketDataProvider(&data_unauth); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_unauth); + + // When the client certificate is selected, /auth is retried on a new + // connection. In particular, it should not be retried on |data_unauth|, + // which would not honor the new client certificate configuration. + const MockWrite kRetryWrites[] = { + MockWrite(ASYNC, 0, + "GET /auth HTTP/1.1\r\n" + "Host: foo.test\r\n" + "Connection: keep-alive\r\n\r\n"), + }; + const MockRead kRetryReads[] = { + MockRead(ASYNC, 1, + "HTTP/1.1 200 OK\r\n" + // Close the connection so we test that /post-auth is not + // allocated to |data_unauth| or |data_long_lived|. + "Connection: close\r\n" + "Content-Length: 4\r\n\r\n" + "auth"), + }; + SequencedSocketData data_retry(kRetryReads, kRetryWrites); + SSLSocketDataProvider ssl_retry(ASYNC, OK); + ssl_retry.expected_send_client_cert = true; + ssl_retry.expected_client_cert = identity->certificate(); + session_deps_.socket_factory->AddSocketDataProvider(&data_retry); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_retry); + + // /post-auth gets its own socket. + const MockWrite kPostAuthWrites[] = { + MockWrite(ASYNC, 0, + "GET /post-auth HTTP/1.1\r\n" + "Host: foo.test\r\n" + "Connection: keep-alive\r\n\r\n"), + }; + const MockRead kPostAuthReads[] = { + MockRead(ASYNC, 1, + "HTTP/1.1 200 OK\r\n" + "Connection: keep-alive\r\n" + "Content-Length: 9\r\n\r\n" + "post-auth"), + }; + SequencedSocketData data_post_auth(kPostAuthReads, kPostAuthWrites); + SSLSocketDataProvider ssl_post_auth(ASYNC, OK); + ssl_post_auth.expected_send_client_cert = true; + ssl_post_auth.expected_client_cert = identity->certificate(); + session_deps_.socket_factory->AddSocketDataProvider(&data_post_auth); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_post_auth); + + std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_); + + // Start the two long-lived requests. + TestCompletionCallback callback_long_lived; + auto trans_long_lived = + std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get()); + int rv = trans_long_lived->Start( + &request_long_lived, callback_long_lived.callback(), NetLogWithSource()); + ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); + data_long_lived.RunUntilPaused(); + + TestCompletionCallback callback_long_lived_bar; + auto trans_long_lived_bar = + std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get()); + rv = trans_long_lived_bar->Start(&request_long_lived_bar, + callback_long_lived_bar.callback(), + NetLogWithSource()); + ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); + data_bar.RunUntilPaused(); + + // Request /auth. This gives a client certificate challenge. + TestCompletionCallback callback_auth; + auto trans_auth = + std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get()); + rv = trans_auth->Start(&request_auth, callback_auth.callback(), + NetLogWithSource()); + EXPECT_THAT(callback_auth.GetResult(rv), + IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED)); + + // Make an unauthenticated request. This completes. + TestCompletionCallback callback_unauth; + auto trans_unauth = + std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get()); + rv = trans_unauth->Start(&request_unauth, callback_unauth.callback(), + NetLogWithSource()); + EXPECT_THAT(callback_unauth.GetResult(rv), IsOk()); + std::string response_unauth; + EXPECT_THAT(ReadTransaction(trans_unauth.get(), &response_unauth), IsOk()); + EXPECT_EQ("unauth", response_unauth); + trans_unauth.reset(); + + // Complete the authenticated request. + rv = trans_auth->RestartWithCertificate(identity->certificate(), + identity->ssl_private_key(), + callback_auth.callback()); + EXPECT_THAT(callback_auth.GetResult(rv), IsOk()); + std::string response_auth; + EXPECT_THAT(ReadTransaction(trans_auth.get(), &response_auth), IsOk()); + EXPECT_EQ("auth", response_auth); + trans_auth.reset(); + + // Complete the long-lived requests. + data_long_lived.Resume(); + EXPECT_THAT(callback_long_lived.GetResult(ERR_IO_PENDING), IsOk()); + std::string response_long_lived; + EXPECT_THAT(ReadTransaction(trans_long_lived.get(), &response_long_lived), + IsOk()); + EXPECT_EQ("long-lived", response_long_lived); + trans_long_lived.reset(); + + data_bar.Resume(); + EXPECT_THAT(callback_long_lived_bar.GetResult(ERR_IO_PENDING), IsOk()); + std::string response_long_lived_bar; + EXPECT_THAT( + ReadTransaction(trans_long_lived_bar.get(), &response_long_lived_bar), + IsOk()); + EXPECT_EQ("long-lived", response_long_lived_bar); + trans_long_lived_bar.reset(); + + // Run the post-authentication requests. + TestCompletionCallback callback_post_auth; + auto trans_post_auth = + std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get()); + rv = trans_post_auth->Start(&request_post_auth, callback_post_auth.callback(), + NetLogWithSource()); + EXPECT_THAT(callback_post_auth.GetResult(rv), IsOk()); + std::string response_post_auth; + EXPECT_THAT(ReadTransaction(trans_post_auth.get(), &response_post_auth), + IsOk()); + EXPECT_EQ("post-auth", response_post_auth); + trans_post_auth.reset(); + + TestCompletionCallback callback_post_auth_bar; + auto trans_post_auth_bar = + std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get()); + rv = trans_post_auth_bar->Start(&request_post_auth_bar, + callback_post_auth_bar.callback(), + NetLogWithSource()); + EXPECT_THAT(callback_post_auth_bar.GetResult(rv), IsOk()); + std::string response_post_auth_bar; + EXPECT_THAT( + ReadTransaction(trans_post_auth_bar.get(), &response_post_auth_bar), + IsOk()); + EXPECT_EQ("post-auth", response_post_auth_bar); + trans_post_auth_bar.reset(); +} + } // namespace net
diff --git a/net/http/http_stream_factory_job_controller.cc b/net/http/http_stream_factory_job_controller.cc index ffe8aae..e280fc2 100644 --- a/net/http/http_stream_factory_job_controller.cc +++ b/net/http/http_stream_factory_job_controller.cc
@@ -1205,8 +1205,8 @@ if (request_info_.load_flags & LOAD_BYPASS_PROXY) return error; - if (proxy_info_.is_https() && proxy_ssl_config_.send_client_cert) { - session_->ssl_client_auth_cache()->Remove( + if (proxy_info_.is_https()) { + session_->ssl_client_context()->ClearClientCertificate( proxy_info_.proxy_server().host_port_pair()); }
diff --git a/net/quic/platform/impl/quic_text_utils_impl.h b/net/quic/platform/impl/quic_text_utils_impl.h index 06c1a0d..d9feafc 100644 --- a/net/quic/platform/impl/quic_text_utils_impl.h +++ b/net/quic/platform/impl/quic_text_utils_impl.h
@@ -125,10 +125,16 @@ return std::any_of(data.begin(), data.end(), base::IsAsciiUpper<char>); } + // Returns true if |data| contains only decimal digits. + static bool IsAllDigits(QuicStringPiece data) { + return std::all_of(data.begin(), data.end(), + base::IsAsciiDigit<QuicStringPiece::value_type>); + } + // Splits |data| into a vector of pieces delimited by |delim|. static std::vector<QuicStringPiece> Split(QuicStringPiece data, char delim) { return base::SplitStringPiece(data, QuicStringPiece(&delim, 1), - base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); + base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); } };
diff --git a/net/quic/quic_flags_list.h b/net/quic/quic_flags_list.h index fb98910e..3a22fdee 100644 --- a/net/quic/quic_flags_list.h +++ b/net/quic/quic_flags_list.h
@@ -363,3 +363,15 @@ QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_active_streams_never_negative, false) + +// If true and FIFO connection option is received, write_blocked_streams uses +// FIFO(stream with smallest ID has highest priority) write scheduler. +QUIC_FLAG(bool, + FLAGS_quic_reloadable_flag_quic_enable_fifo_write_scheduler, + false) + +// If true and LIFO connection option is received, write_blocked_streams uses +// LIFO(stream with largest ID has highest priority) write scheduler. +QUIC_FLAG(bool, + FLAGS_quic_reloadable_flag_quic_enable_lifo_write_scheduler, + false)
diff --git a/net/quic/quic_test_packet_maker.cc b/net/quic/quic_test_packet_maker.cc index 25ff01c..ba796c9 100644 --- a/net/quic/quic_test_packet_maker.cc +++ b/net/quic/quic_test_packet_maker.cc
@@ -7,6 +7,8 @@ #include <list> #include <utility> +#include "base/strings/strcat.h" +#include "base/strings/string_number_conversions.h" #include "net/quic/mock_crypto_client_stream.h" #include "net/quic/quic_chromium_client_session.h" #include "net/quic/quic_http_utils.h" @@ -516,7 +518,7 @@ quic::QuicConnectionCloseFrame close; close.quic_error_code = quic_error; - close.error_details = quic_error_details; + close.error_details = MaybePrependErrorCode(quic_error_details, quic_error); if (version_.transport_version == quic::QUIC_VERSION_99) { close.close_type = quic::IETF_QUIC_TRANSPORT_CONNECTION_CLOSE; } @@ -555,7 +557,7 @@ quic::QuicConnectionCloseFrame close; close.quic_error_code = quic_error; - close.error_details = quic_error_details; + close.error_details = MaybePrependErrorCode(quic_error_details, quic_error); if (version_.transport_version == quic::QUIC_VERSION_99) { close.close_type = quic::IETF_QUIC_TRANSPORT_CONNECTION_CLOSE; } @@ -576,7 +578,7 @@ quic::QuicConnectionCloseFrame close; close.quic_error_code = quic_error; - close.error_details = quic_error_details; + close.error_details = MaybePrependErrorCode(quic_error_details, quic_error); if (version_.transport_version == quic::QUIC_VERSION_99) { close.close_type = quic::IETF_QUIC_TRANSPORT_CONNECTION_CLOSE; } @@ -1525,6 +1527,18 @@ return include_version; } +std::string QuicTestPacketMaker::MaybePrependErrorCode( + const std::string& quic_error_details, + quic::QuicErrorCode quic_error_code) const { + if (!quic::VersionHasIetfQuicFrames(version_.transport_version) || + quic_error_code == quic::QUIC_IETF_GQUIC_ERROR_MISSING) { + // QUIC_IETF_GQUIC_ERROR_MISSING means not to encode the error value. + return quic_error_details; + } + return base::StrCat( + {base::NumberToString(quic_error_code), ":", quic_error_details}); +} + quic::QuicStreamFrame QuicTestPacketMaker::GenerateNextStreamFrame( quic::QuicStreamId stream_id, bool fin,
diff --git a/net/quic/quic_test_packet_maker.h b/net/quic/quic_test_packet_maker.h index 2aa34aa..4c1a4d1ee 100644 --- a/net/quic/quic_test_packet_maker.h +++ b/net/quic/quic_test_packet_maker.h
@@ -378,6 +378,11 @@ bool ShouldIncludeVersion(bool include_version) const; + // This mirrors quic_framer.cc::{anonymous namespace}::GenerateErrorString() + // behavior. + std::string MaybePrependErrorCode(const std::string& quic_error_details, + quic::QuicErrorCode quic_error_code) const; + quic::QuicStreamFrame GenerateNextStreamFrame(quic::QuicStreamId stream_id, bool fin, quic::QuicStringPiece data);
diff --git a/net/socket/client_socket_pool_base_unittest.cc b/net/socket/client_socket_pool_base_unittest.cc index 0f8df878..87bab386 100644 --- a/net/socket/client_socket_pool_base_unittest.cc +++ b/net/socket/client_socket_pool_base_unittest.cc
@@ -647,11 +647,13 @@ enable_backup_connect_jobs); } - void CreatePoolWithIdleTimeouts(int max_sockets, - int max_sockets_per_group, - base::TimeDelta unused_idle_socket_timeout, - base::TimeDelta used_idle_socket_timeout, - bool enable_backup_connect_jobs = false) { + void CreatePoolWithIdleTimeouts( + int max_sockets, + int max_sockets_per_group, + base::TimeDelta unused_idle_socket_timeout, + base::TimeDelta used_idle_socket_timeout, + bool enable_backup_connect_jobs = false, + ProxyServer proxy_server = ProxyServer::Direct()) { DCHECK(!pool_.get()); std::unique_ptr<TestConnectJobFactory> connect_job_factory = std::make_unique<TestConnectJobFactory>(&client_socket_factory_, @@ -659,7 +661,7 @@ connect_job_factory_ = connect_job_factory.get(); pool_ = TransportClientSocketPool::CreateForTesting( max_sockets, max_sockets_per_group, unused_idle_socket_timeout, - used_idle_socket_timeout, std::move(connect_job_factory), + used_idle_socket_timeout, proxy_server, std::move(connect_job_factory), nullptr /* ssl_config_service */, enable_backup_connect_jobs); } @@ -5527,9 +5529,63 @@ EXPECT_EQ(0, auth_helper4.auth_count()); } -TEST_F(ClientSocketPoolBaseTest, RefreshGroupCreatesNewConnectJobs) { - CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); - const ClientSocketPool::GroupId kGroupId = TestGroupId("a"); +enum class RefreshType { + kServer, + kProxy, +}; + +// Common base class to test RefreshGroup() when called from either +// OnSSLConfigForServerChanged() matching a specific group or the pool's proxy. +// +// Tests which test behavior specific to one or the other case should use +// ClientSocketPoolBaseTest directly. In particular, there is no "other group" +// when the pool's proxy matches. +class ClientSocketPoolBaseRefreshTest + : public ClientSocketPoolBaseTest, + public testing::WithParamInterface<RefreshType> { + public: + void CreatePoolForRefresh(int max_sockets, + int max_sockets_per_group, + bool enable_backup_connect_jobs = false) { + switch (GetParam()) { + case RefreshType::kServer: + CreatePool(max_sockets, max_sockets_per_group, + enable_backup_connect_jobs); + break; + case RefreshType::kProxy: + CreatePoolWithIdleTimeouts( + max_sockets, max_sockets_per_group, kUnusedIdleSocketTimeout, + ClientSocketPool::used_idle_socket_timeout(), + enable_backup_connect_jobs, + ProxyServer::FromPacString("HTTPS myproxy:70")); + break; + } + } + + static ClientSocketPool::GroupId GetGroupId() { + return TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl); + } + + void OnSSLConfigForServerChanged() { + switch (GetParam()) { + case RefreshType::kServer: + pool_->OnSSLConfigForServerChanged(HostPortPair("a", 443)); + break; + case RefreshType::kProxy: + pool_->OnSSLConfigForServerChanged(HostPortPair("myproxy", 70)); + break; + } + } +}; + +INSTANTIATE_TEST_SUITE_P(RefreshType, + ClientSocketPoolBaseRefreshTest, + ::testing::Values(RefreshType::kServer, + RefreshType::kProxy)); + +TEST_P(ClientSocketPoolBaseRefreshTest, RefreshGroupCreatesNewConnectJobs) { + CreatePoolForRefresh(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); + const ClientSocketPool::GroupId kGroupId = GetGroupId(); // First job will be waiting until it gets aborted. connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob); @@ -5547,7 +5603,7 @@ // success. connect_job_factory_->set_job_type(TestConnectJob::kMockJob); - pool_->RefreshGroupForTesting(kGroupId); + OnSSLConfigForServerChanged(); EXPECT_EQ(OK, callback.WaitForResult()); ASSERT_TRUE(handle.socket()); EXPECT_EQ(0, pool_->IdleSocketCount()); @@ -5557,9 +5613,9 @@ EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId)); } -TEST_F(ClientSocketPoolBaseTest, RefreshGroupClosesIdleConnectJobs) { - CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); - const ClientSocketPool::GroupId kGroupId = TestGroupId("a"); +TEST_P(ClientSocketPoolBaseRefreshTest, RefreshGroupClosesIdleConnectJobs) { + CreatePoolForRefresh(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); + const ClientSocketPool::GroupId kGroupId = GetGroupId(); pool_->RequestSockets(kGroupId, params_, base::nullopt, 2, NetLogWithSource()); @@ -5567,7 +5623,7 @@ EXPECT_EQ(2, pool_->IdleSocketCount()); EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kGroupId)); - pool_->RefreshGroupForTesting(kGroupId); + OnSSLConfigForServerChanged(); EXPECT_EQ(0, pool_->IdleSocketCount()); EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId)); } @@ -5575,8 +5631,10 @@ TEST_F(ClientSocketPoolBaseTest, RefreshGroupDoesNotCloseIdleConnectJobsInOtherGroup) { CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); - const ClientSocketPool::GroupId kGroupId = TestGroupId("a"); - const ClientSocketPool::GroupId kOtherGroupId = TestGroupId("b"); + const ClientSocketPool::GroupId kGroupId = + TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl); + const ClientSocketPool::GroupId kOtherGroupId = + TestGroupId("b", 443, ClientSocketPool::SocketType::kSsl); pool_->RequestSockets(kOtherGroupId, params_, base::nullopt, 2, NetLogWithSource()); @@ -5584,15 +5642,15 @@ EXPECT_EQ(2, pool_->IdleSocketCount()); EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kOtherGroupId)); - pool_->RefreshGroupForTesting(kGroupId); + pool_->OnSSLConfigForServerChanged(HostPortPair("a", 443)); ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId)); EXPECT_EQ(2, pool_->IdleSocketCount()); EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kOtherGroupId)); } -TEST_F(ClientSocketPoolBaseTest, RefreshGroupPreventsSocketReuse) { - CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); - const ClientSocketPool::GroupId kGroupId = TestGroupId("a"); +TEST_P(ClientSocketPoolBaseRefreshTest, RefreshGroupPreventsSocketReuse) { + CreatePoolForRefresh(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); + const ClientSocketPool::GroupId kGroupId = GetGroupId(); ClientSocketHandle handle; TestCompletionCallback callback; @@ -5605,7 +5663,7 @@ ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId)); EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId)); - pool_->RefreshGroupForTesting(kGroupId); + OnSSLConfigForServerChanged(); handle.Reset(); EXPECT_EQ(0, pool_->IdleSocketCount()); @@ -5615,8 +5673,10 @@ TEST_F(ClientSocketPoolBaseTest, RefreshGroupDoesNotPreventSocketReuseInOtherGroup) { CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); - const ClientSocketPool::GroupId kGroupId = TestGroupId("a"); - const ClientSocketPool::GroupId kOtherGroupId = TestGroupId("b"); + const ClientSocketPool::GroupId kGroupId = + TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl); + const ClientSocketPool::GroupId kOtherGroupId = + TestGroupId("b", 443, ClientSocketPool::SocketType::kSsl); ClientSocketHandle handle; TestCompletionCallback callback; @@ -5629,7 +5689,7 @@ ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId)); EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kOtherGroupId)); - pool_->RefreshGroupForTesting(kGroupId); + pool_->OnSSLConfigForServerChanged(HostPortPair("a", 443)); handle.Reset(); EXPECT_EQ(1, pool_->IdleSocketCount()); @@ -5637,9 +5697,10 @@ EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kOtherGroupId)); } -TEST_F(ClientSocketPoolBaseTest, RefreshGroupReplacesBoundConnectJobOnConnect) { - CreatePool(1, 1); - const ClientSocketPool::GroupId kGroupId = TestGroupId("a"); +TEST_P(ClientSocketPoolBaseRefreshTest, + RefreshGroupReplacesBoundConnectJobOnConnect) { + CreatePoolForRefresh(1, 1); + const ClientSocketPool::GroupId kGroupId = GetGroupId(); connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob); TestAuthHelper auth_helper; @@ -5651,7 +5712,7 @@ // This should update the generation, but not cancel the old ConnectJob - it's // not safe to do anything while waiting on the original ConnectJob. - pool_->RefreshGroupForTesting(kGroupId); + OnSSLConfigForServerChanged(); // Providing auth credentials and restarting the request with them will cause // the ConnectJob to complete successfully, but the result will be discarded @@ -5675,6 +5736,145 @@ EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId)); } +TEST_F(ClientSocketPoolBaseTest, RefreshProxyRefreshesAllGroups) { + CreatePoolWithIdleTimeouts(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup, + kUnusedIdleSocketTimeout, + ClientSocketPool::used_idle_socket_timeout(), + false /* no backup connect jobs */, + ProxyServer::FromPacString("HTTPS myproxy:70")); + + const ClientSocketPool::GroupId kGroupId1 = + TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl); + const ClientSocketPool::GroupId kGroupId2 = + TestGroupId("b", 443, ClientSocketPool::SocketType::kSsl); + const ClientSocketPool::GroupId kGroupId3 = + TestGroupId("c", 443, ClientSocketPool::SocketType::kSsl); + + // Make three sockets in three different groups. The third socket is released + // to the pool as idle. + ClientSocketHandle handle1, handle2, handle3; + TestCompletionCallback callback; + EXPECT_THAT( + handle1.Init(kGroupId1, params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource()), + IsOk()); + EXPECT_THAT( + handle2.Init(kGroupId2, params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource()), + IsOk()); + EXPECT_THAT( + handle3.Init(kGroupId3, params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource()), + IsOk()); + handle3.Reset(); + ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId1)); + EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId1)); + ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId2)); + EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId2)); + ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId3)); + EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId3)); + + // Changes to some other proxy do not affect the pool. The idle socket remains + // alive and closing |handle2| makes the socket available for the pool. + pool_->OnSSLConfigForServerChanged(HostPortPair("someotherproxy", 70)); + + ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId1)); + EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId1)); + ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId2)); + EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId2)); + ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId3)); + EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId3)); + + handle2.Reset(); + ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId2)); + EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId2)); + + // Changes to the matching proxy refreshes all groups. + pool_->OnSSLConfigForServerChanged(HostPortPair("myproxy", 70)); + + // Idle sockets are closed. + EXPECT_EQ(0, pool_->IdleSocketCount()); + EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId2)); + EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId3)); + + // The active socket, however, continues to be active. + ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId1)); + EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId1)); + + // Closing it does not make it available for the pool. + handle1.Reset(); + EXPECT_EQ(0, pool_->IdleSocketCount()); + EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId1)); +} + +TEST_F(ClientSocketPoolBaseTest, RefreshBothPrivacyAndNormalSockets) { + CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); + + const ClientSocketPool::GroupId kGroupId = + TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl, + PrivacyMode::PRIVACY_MODE_DISABLED); + const ClientSocketPool::GroupId kGroupIdPrivacy = + TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl, + PrivacyMode::PRIVACY_MODE_ENABLED); + const ClientSocketPool::GroupId kOtherGroupId = + TestGroupId("b", 443, ClientSocketPool::SocketType::kSsl); + + // Make a socket in each groups. + ClientSocketHandle handle1, handle2, handle3; + TestCompletionCallback callback; + EXPECT_THAT( + handle1.Init(kGroupId, params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource()), + IsOk()); + EXPECT_THAT( + handle2.Init(kGroupIdPrivacy, params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource()), + IsOk()); + EXPECT_THAT( + handle3.Init(kOtherGroupId, params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource()), + IsOk()); + ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId)); + EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId)); + ASSERT_TRUE(pool_->HasGroupForTesting(kGroupIdPrivacy)); + EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupIdPrivacy)); + ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId)); + EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kOtherGroupId)); + + pool_->OnSSLConfigForServerChanged(HostPortPair("a", 443)); + + // Active sockets continue to be active. + ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId)); + EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId)); + ASSERT_TRUE(pool_->HasGroupForTesting(kGroupIdPrivacy)); + EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupIdPrivacy)); + ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId)); + EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kOtherGroupId)); + + // Closing them leaves kOtherGroupId alone, but kGroupId and kGroupIdPrivacy + // are unusable. + handle1.Reset(); + handle2.Reset(); + handle3.Reset(); + EXPECT_EQ(1, pool_->IdleSocketCount()); + EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId)); + EXPECT_FALSE(pool_->HasGroupForTesting(kGroupIdPrivacy)); + EXPECT_TRUE(pool_->HasGroupForTesting(kOtherGroupId)); + EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kOtherGroupId)); +} + } // namespace } // namespace net
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc index 6fad42a7..85901884 100644 --- a/net/socket/socket_test_util.cc +++ b/net/socket/socket_test_util.cc
@@ -816,15 +816,20 @@ ssl_config.version_max_override.value_or(context->config().version_max)); if (next_ssl_data->expected_send_client_cert) { - EXPECT_EQ(*next_ssl_data->expected_send_client_cert, - ssl_config.send_client_cert); - DCHECK_EQ(*next_ssl_data->expected_send_client_cert, - next_ssl_data->expected_client_cert != nullptr); - if (next_ssl_data->expected_client_cert) { + // Client certificate preferences come from |context|. + scoped_refptr<X509Certificate> client_cert; + scoped_refptr<SSLPrivateKey> client_private_key; + bool send_client_cert = context->GetClientCertificate( + host_and_port, &client_cert, &client_private_key); + + EXPECT_EQ(*next_ssl_data->expected_send_client_cert, send_client_cert); + // Note |send_client_cert| may be true while |client_cert| is null if the + // socket is configured to continue without a certificate, as opposed to + // surfacing the certificate challenge. + EXPECT_EQ(!!next_ssl_data->expected_client_cert, !!client_cert); + if (next_ssl_data->expected_client_cert && client_cert) { EXPECT_TRUE(next_ssl_data->expected_client_cert->EqualsIncludingChain( - ssl_config.client_cert.get())); - } else { - EXPECT_FALSE(ssl_config.client_cert); + client_cert.get())); } } if (next_ssl_data->expected_host_and_port) {
diff --git a/net/socket/ssl_client_socket.cc b/net/socket/ssl_client_socket.cc index a32006d6..9f905dd 100644 --- a/net/socket/ssl_client_socket.cc +++ b/net/socket/ssl_client_socket.cc
@@ -86,6 +86,42 @@ host_and_port, ssl_config); } +bool SSLClientContext::GetClientCertificate( + const HostPortPair& server, + scoped_refptr<X509Certificate>* client_cert, + scoped_refptr<SSLPrivateKey>* private_key) { + return ssl_client_auth_cache_.Lookup(server, client_cert, private_key); +} + +void SSLClientContext::SetClientCertificate( + const HostPortPair& server, + scoped_refptr<X509Certificate> client_cert, + scoped_refptr<SSLPrivateKey> private_key) { + ssl_client_auth_cache_.Add(server, std::move(client_cert), + std::move(private_key)); + + if (ssl_client_session_cache_) { + // Session resumption bypasses client certificate negotiation, so flush all + // associated sessions when preferences change. + ssl_client_session_cache_->FlushForServer(server); + } + NotifySSLConfigForServerChanged(server); +} + +bool SSLClientContext::ClearClientCertificate(const HostPortPair& server) { + if (!ssl_client_auth_cache_.Remove(server)) { + return false; + } + + if (ssl_client_session_cache_) { + // Session resumption bypasses client certificate negotiation, so flush all + // associated sessions when preferences change. + ssl_client_session_cache_->FlushForServer(server); + } + NotifySSLConfigForServerChanged(server); + return true; +} + void SSLClientContext::AddObserver(Observer* observer) { observers_.AddObserver(observer); } @@ -104,6 +140,8 @@ } void SSLClientContext::OnCertDBChanged() { + // Both the trust store and client certificate store may have changed. + ssl_client_auth_cache_.Clear(); if (ssl_client_session_cache_) { ssl_client_session_cache_->Flush(); } @@ -116,4 +154,11 @@ } } +void SSLClientContext::NotifySSLConfigForServerChanged( + const HostPortPair& server) { + for (Observer& observer : observers_) { + observer.OnSSLConfigForServerChanged(server); + } +} + } // namespace net
diff --git a/net/socket/ssl_client_socket.h b/net/socket/ssl_client_socket.h index 4218fc5..705281a9 100644 --- a/net/socket/ssl_client_socket.h +++ b/net/socket/ssl_client_socket.h
@@ -16,6 +16,7 @@ #include "net/base/net_export.h" #include "net/cert/cert_database.h" #include "net/socket/ssl_socket.h" +#include "net/ssl/ssl_client_auth_cache.h" #include "net/ssl/ssl_config_service.h" namespace net { @@ -87,8 +88,13 @@ class NET_EXPORT Observer : public base::CheckedObserver { public: // Called when SSL configuration for all hosts changed. Newly-created - // SSLClientSockets will pick up the new configuration. + // SSLClientSockets will pick up the new configuration. Note that changes + // which only apply to one server will result in a call to + // OnSSLConfigForServerChanged() instead. virtual void OnSSLConfigChanged(bool is_cert_database_change) = 0; + // Called when SSL configuration for |server| changed. Newly-created + // SSLClientSockets to |server| will pick up the new configuration. + virtual void OnSSLConfigForServerChanged(const HostPortPair& server) = 0; }; // Creates a new SSLClientContext with the specified parameters. The @@ -127,6 +133,36 @@ const HostPortPair& host_and_port, const SSLConfig& ssl_config); + // Looks up the client certificate preference for |server|. If one is found, + // returns true and sets |client_cert| and |private_key| to the certificate + // and key. Note these may be null if the preference is to continue with no + // client certificate. Returns false if no preferences are configured, + // which means client certificate requests should be reported as + // ERR_SSL_CLIENT_AUTH_CERT_NEEDED. + bool GetClientCertificate(const HostPortPair& server, + scoped_refptr<X509Certificate>* client_cert, + scoped_refptr<SSLPrivateKey>* private_key); + + // Configures all subsequent connections to |server| to authenticate with + // |client_cert| and |private_key| when requested. If there is already a + // client certificate for |server|, it will be overwritten. |client_cert| and + // |private_key| may be null to indicate that no client certificate should be + // sent to |server|. + // + // Note this method will synchronously call OnSSLConfigForServerChanged() on + // observers. + void SetClientCertificate(const HostPortPair& server, + scoped_refptr<X509Certificate> client_cert, + scoped_refptr<SSLPrivateKey> private_key); + + // Clears a client certificate preference for |server| set by + // SetClientCertificate(). Returns true if one was removed and false + // otherwise. + // + // Note this method will synchronously call OnSSLConfigForServerChanged() on + // observers. + bool ClearClientCertificate(const HostPortPair& server); + // Add an observer to be notified when configuration has changed. // RemoveObserver() must be called before |observer| is destroyed. void AddObserver(Observer* observer); @@ -142,6 +178,7 @@ private: void NotifySSLConfigChanged(bool is_cert_database_change); + void NotifySSLConfigForServerChanged(const HostPortPair& server); SSLContextConfig config_; @@ -152,6 +189,8 @@ CTPolicyEnforcer* ct_policy_enforcer_; SSLClientSessionCache* ssl_client_session_cache_; + SSLClientAuthCache ssl_client_auth_cache_; + base::ObserverList<Observer, true /* check_empty */> observers_; DISALLOW_COPY_AND_ASSIGN(SSLClientContext);
diff --git a/net/socket/ssl_client_socket_impl.cc b/net/socket/ssl_client_socket_impl.cc index f01adac8..1a203fc 100644 --- a/net/socket/ssl_client_socket_impl.cc +++ b/net/socket/ssl_client_socket_impl.cc
@@ -617,8 +617,7 @@ server_cert_verify_result_.is_issued_by_known_root; ssl_info->pkp_bypassed = pkp_bypassed_; ssl_info->public_key_hashes = server_cert_verify_result_.public_key_hashes; - ssl_info->client_cert_sent = - ssl_config_.send_client_cert && ssl_config_.client_cert.get(); + ssl_info->client_cert_sent = send_client_cert_ && client_cert_.get(); ssl_info->pinning_failure_log = pinning_failure_log_; ssl_info->ocsp_result = server_cert_verify_result_.ocsp_result; ssl_info->is_fatal_cert_error = is_fatal_cert_error_; @@ -909,6 +908,12 @@ SSL_set_renegotiate_mode(ssl_.get(), ssl_renegotiate_freely); SSL_set_shed_handshake_config(ssl_.get(), 1); + + // TODO(https://crbug.com/775438), if |ssl_config_.privacy_mode| is enabled, + // this should always continue with no client certificate. + send_client_cert_ = context_->GetClientCertificate( + host_and_port_, &client_cert_, &client_private_key_); + return OK; } @@ -939,12 +944,11 @@ int net_error = OK; if (rv <= 0) { int ssl_error = SSL_get_error(ssl_.get(), rv); - if (ssl_error == SSL_ERROR_WANT_X509_LOOKUP && - !ssl_config_.send_client_cert) { + if (ssl_error == SSL_ERROR_WANT_X509_LOOKUP && !send_client_cert_) { return ERR_SSL_CLIENT_AUTH_CERT_NEEDED; } if (ssl_error == SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) { - DCHECK(ssl_config_.client_private_key); + DCHECK(client_private_key_); DCHECK_NE(kSSLClientSocketNoPendingResult, signature_result_); next_handshake_state_ = STATE_HANDSHAKE; return ERR_IO_PENDING; @@ -1371,11 +1375,11 @@ if (pending_read_ssl_error_ == SSL_ERROR_ZERO_RETURN) { pending_read_error_ = 0; } else if (pending_read_ssl_error_ == SSL_ERROR_WANT_X509_LOOKUP && - !ssl_config_.send_client_cert) { + !send_client_cert_) { pending_read_error_ = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; } else if (pending_read_ssl_error_ == SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) { - DCHECK(ssl_config_.client_private_key); + DCHECK(client_private_key_); DCHECK_NE(kSSLClientSocketNoPendingResult, signature_result_); pending_read_error_ = ERR_IO_PENDING; } else { @@ -1598,7 +1602,7 @@ // TODO(droger): Support client auth on iOS. See http://crbug.com/145954). LOG(WARNING) << "Client auth is not supported"; #else // !defined(OS_IOS) - if (!ssl_config_.send_client_cert) { + if (!send_client_cert_) { // First pass: we know that a client certificate is needed, but we do not // have one at hand. Suspend the handshake. SSL_get_error will return // SSL_ERROR_WANT_X509_LOOKUP. @@ -1606,8 +1610,8 @@ } // Second pass: a client certificate should have been selected. - if (ssl_config_.client_cert.get()) { - if (!ssl_config_.client_private_key) { + if (client_cert_.get()) { + if (!client_private_key_) { // The caller supplied a null private key. Fail the handshake and surface // an appropriate error to the caller. LOG(WARNING) << "Client cert found without private key"; @@ -1615,21 +1619,21 @@ return -1; } - if (!SetSSLChainAndKey(ssl_.get(), ssl_config_.client_cert.get(), nullptr, + if (!SetSSLChainAndKey(ssl_.get(), client_cert_.get(), nullptr, &SSLContext::kPrivateKeyMethod)) { OpenSSLPutNetError(FROM_HERE, ERR_SSL_CLIENT_AUTH_CERT_BAD_FORMAT); return -1; } std::vector<uint16_t> preferences = - ssl_config_.client_private_key->GetAlgorithmPreferences(); + client_private_key_->GetAlgorithmPreferences(); SSL_set_signing_algorithm_prefs(ssl_.get(), preferences.data(), preferences.size()); net_log_.AddEventWithIntParams( NetLogEventType::SSL_CLIENT_CERT_PROVIDED, "cert_count", - base::checked_cast<int>( - 1 + ssl_config_.client_cert->intermediate_buffers().size())); + base::checked_cast<int>(1 + + client_cert_->intermediate_buffers().size())); return 1; } #endif // defined(OS_IOS) @@ -1705,18 +1709,18 @@ size_t in_len) { DCHECK_EQ(kSSLClientSocketNoPendingResult, signature_result_); DCHECK(signature_.empty()); - DCHECK(ssl_config_.client_private_key); + DCHECK(client_private_key_); net_log_.BeginEvent(NetLogEventType::SSL_PRIVATE_KEY_OP, [&] { return NetLogPrivateKeyOperationParams( algorithm, // Pass the SSLPrivateKey pointer to avoid making copies of the // provider name in the common case with logging disabled. - ssl_config_.client_private_key.get()); + client_private_key_.get()); }); signature_result_ = ERR_IO_PENDING; - ssl_config_.client_private_key->Sign( + client_private_key_->Sign( algorithm, base::make_span(in, in_len), base::BindOnce(&SSLClientSocketImpl::OnPrivateKeyComplete, weak_factory_.GetWeakPtr())); @@ -1728,7 +1732,7 @@ size_t* out_len, size_t max_out) { DCHECK_NE(kSSLClientSocketNoPendingResult, signature_result_); - DCHECK(ssl_config_.client_private_key); + DCHECK(client_private_key_); if (signature_result_ == ERR_IO_PENDING) return ssl_private_key_retry; @@ -1751,7 +1755,7 @@ const std::vector<uint8_t>& signature) { DCHECK_EQ(ERR_IO_PENDING, signature_result_); DCHECK(signature_.empty()); - DCHECK(ssl_config_.client_private_key); + DCHECK(client_private_key_); net_log_.EndEventWithNetErrorCode(NetLogEventType::SSL_PRIVATE_KEY_OP, error); @@ -1816,8 +1820,7 @@ // certificate. See https://crbug.com/646567. if (ERR_GET_REASON(info->error_code) == SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE && - certificate_requested_ && ssl_config_.send_client_cert && - !ssl_config_.client_cert) { + certificate_requested_ && send_client_cert_ && !client_cert_) { net_error = ERR_BAD_SSL_CLIENT_AUTH_CERT; }
diff --git a/net/socket/ssl_client_socket_impl.h b/net/socket/ssl_client_socket_impl.h index a4ed759d..85f0ec7 100644 --- a/net/socket/ssl_client_socket_impl.h +++ b/net/socket/ssl_client_socket_impl.h
@@ -44,7 +44,9 @@ class SSLCertRequestInfo; class SSLInfo; +class SSLPrivateKey; class SSLKeyLogger; +class X509Certificate; class SSLClientSocketImpl : public SSLClientSocket, public SocketBIOAdapter::Delegate { @@ -274,6 +276,7 @@ bool disconnected_; NextProto negotiated_protocol_; + // Set to true if a CertificateRequest was received. bool certificate_requested_; @@ -292,6 +295,14 @@ // and false otherwise. bool is_fatal_cert_error_; + // True if the socket should respond to client certificate requests with + // |client_cert_| and |client_private_key_|, which may be null to continue + // with no certificate. If false, client certificate requests will result in + // ERR_SSL_CLIENT_AUTH_CERT_NEEDED. + bool send_client_cert_; + scoped_refptr<X509Certificate> client_cert_; + scoped_refptr<SSLPrivateKey> client_private_key_; + NetLogWithSource net_log_; base::WeakPtrFactory<SSLClientSocketImpl> weak_factory_{this};
diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc index 1ce80ba..9ed7f43 100644 --- a/net/socket/ssl_client_socket_unittest.cc +++ b/net/socket/ssl_client_socket_unittest.cc
@@ -1653,12 +1653,10 @@ // Our test server accepts certificate-less connections. // TODO(davidben): Add a test which requires them and verify the error. - SSLConfig ssl_config; - ssl_config.send_client_cert = true; - ssl_config.client_cert = nullptr; + context_->SetClientCertificate(host_port_pair(), nullptr, nullptr); int rv; - ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv)); + ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv)); EXPECT_THAT(rv, IsOk()); // We responded to the server's certificate request with a Certificate @@ -3663,13 +3661,10 @@ ASSERT_TRUE(StartTestServer(ssl_options)); - SSLConfig ssl_config; - ssl_config.send_client_cert = true; - ssl_config.client_cert = nullptr; - ssl_config.client_private_key = nullptr; + context_->SetClientCertificate(host_port_pair(), nullptr, nullptr); int rv; - ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv)); + ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv)); EXPECT_THAT(rv, IsOk()); EXPECT_TRUE(sock_->IsConnected()); @@ -3690,14 +3685,12 @@ ASSERT_TRUE(StartTestServer(ssl_options)); base::FilePath certs_dir = GetTestCertsDirectory(); - SSLConfig ssl_config; - ssl_config.send_client_cert = true; - ssl_config.client_cert = ImportCertFromFile(certs_dir, "client_1.pem"); - ssl_config.client_private_key = - key_util::LoadPrivateKeyOpenSSL(certs_dir.AppendASCII("client_1.key")); + context_->SetClientCertificate( + host_port_pair(), ImportCertFromFile(certs_dir, "client_1.pem"), + key_util::LoadPrivateKeyOpenSSL(certs_dir.AppendASCII("client_1.key"))); int rv; - ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv)); + ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv)); EXPECT_THAT(rv, IsOk()); EXPECT_TRUE(sock_->IsConnected()); @@ -3710,6 +3703,74 @@ EXPECT_FALSE(sock_->IsConnected()); } +// When client certificate preferences change, the session cache should be +// cleared so the client certificate preferences are applied. +TEST_F(SSLClientSocketTest, ClearSessionCacheOnClientCertChange) { + SSLServerConfig server_config; + // TLS 1.3 reports client certificate errors after the handshake, so test at + // TLS 1.2 for simplicity. + server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2; + server_config.client_cert_type = SSLServerConfig::REQUIRE_CLIENT_CERT; + ASSERT_TRUE( + StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config)); + + // Connecting without a client certificate will fail with + // ERR_SSL_CLIENT_AUTH_CERT_NEEDED. + int rv; + ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv)); + EXPECT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED)); + + // Configure a client certificate. + base::FilePath certs_dir = GetTestCertsDirectory(); + context_->SetClientCertificate( + host_port_pair(), ImportCertFromFile(certs_dir, "client_1.pem"), + key_util::LoadPrivateKeyOpenSSL(certs_dir.AppendASCII("client_1.key"))); + + // Now the connection succeeds. + ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv)); + EXPECT_THAT(rv, IsOk()); + EXPECT_TRUE(sock_->IsConnected()); + + SSLInfo ssl_info; + ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info)); + EXPECT_TRUE(ssl_info.client_cert_sent); + EXPECT_EQ(ssl_info.handshake_type, SSLInfo::HANDSHAKE_FULL); + + // Make a second connection. This should resume the session from the previous + // connection. + ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv)); + EXPECT_THAT(rv, IsOk()); + EXPECT_TRUE(sock_->IsConnected()); + + ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info)); + EXPECT_TRUE(ssl_info.client_cert_sent); + EXPECT_EQ(ssl_info.handshake_type, SSLInfo::HANDSHAKE_RESUME); + + // Clear the client certificate preference. + context_->ClearClientCertificate(host_port_pair()); + + // Connections return to failing, rather than resume the previous session. + ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv)); + EXPECT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED)); + + // Establish a new session with the correct client certificate. + context_->SetClientCertificate( + host_port_pair(), ImportCertFromFile(certs_dir, "client_1.pem"), + key_util::LoadPrivateKeyOpenSSL(certs_dir.AppendASCII("client_1.key"))); + ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv)); + EXPECT_THAT(rv, IsOk()); + ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info)); + EXPECT_TRUE(ssl_info.client_cert_sent); + EXPECT_EQ(ssl_info.handshake_type, SSLInfo::HANDSHAKE_FULL); + + // Switch to continuing without a client certificate. + context_->SetClientCertificate(host_port_pair(), nullptr, nullptr); + + // This also clears the session cache and the new preference is applied. + ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv)); + EXPECT_THAT(rv, IsError(ERR_BAD_SSL_CLIENT_AUTH_CERT)); +} + HashValueVector MakeHashValueVector(uint8_t value) { HashValueVector out; HashValue hash(HASH_VALUE_SHA256); @@ -4507,10 +4568,11 @@ ASSERT_THAT(rv, IsOk()); // Send no client certificate. - SSLConfig config; - config.send_client_cert = true; + context_->SetClientCertificate(spawned_test_server()->host_port_pair(), + nullptr, nullptr); std::unique_ptr<SSLClientSocket> sock(CreateSSLClientSocket( - std::move(transport), spawned_test_server()->host_port_pair(), config)); + std::move(transport), spawned_test_server()->host_port_pair(), + SSLConfig())); // Connect. Stop before the client processes ServerHello. raw_transport->BlockReadResult(); @@ -4557,13 +4619,13 @@ // Send a client certificate. base::FilePath certs_dir = GetTestCertsDirectory(); - SSLConfig config; - config.send_client_cert = true; - config.client_cert = ImportCertFromFile(certs_dir, "client_1.pem"); - config.client_private_key = - key_util::LoadPrivateKeyOpenSSL(certs_dir.AppendASCII("client_1.key")); + context_->SetClientCertificate( + spawned_test_server()->host_port_pair(), + ImportCertFromFile(certs_dir, "client_1.pem"), + key_util::LoadPrivateKeyOpenSSL(certs_dir.AppendASCII("client_1.key"))); std::unique_ptr<SSLClientSocket> sock(CreateSSLClientSocket( - std::move(transport), spawned_test_server()->host_port_pair(), config)); + std::move(transport), spawned_test_server()->host_port_pair(), + SSLConfig())); // Connect. Stop before the client processes ServerHello. raw_transport->BlockReadResult(); @@ -4653,13 +4715,13 @@ // Send a client certificate. base::FilePath certs_dir = GetTestCertsDirectory(); - SSLConfig config; - config.send_client_cert = true; - config.client_cert = ImportCertFromFile(certs_dir, "client_1.pem"); - config.client_private_key = - key_util::LoadPrivateKeyOpenSSL(certs_dir.AppendASCII("client_1.key")); + context_->SetClientCertificate( + spawned_test_server()->host_port_pair(), + ImportCertFromFile(certs_dir, "client_1.pem"), + key_util::LoadPrivateKeyOpenSSL(certs_dir.AppendASCII("client_1.key"))); std::unique_ptr<SSLClientSocket> sock(CreateSSLClientSocket( - std::move(transport), spawned_test_server()->host_port_pair(), config)); + std::move(transport), spawned_test_server()->host_port_pair(), + SSLConfig())); // Connect. Stop before the client processes ServerHello. raw_transport->BlockReadResult();
diff --git a/net/socket/ssl_server_socket_unittest.cc b/net/socket/ssl_server_socket_unittest.cc index 8323e80e..274ae98 100644 --- a/net/socket/ssl_server_socket_unittest.cc +++ b/net/socket/ssl_server_socket_unittest.cc
@@ -412,6 +412,8 @@ server_cert_.get(), server_ssl_private_key_, server_ssl_config_); } + static HostPortPair GetHostAndPort() { return HostPortPair("unittest", 0); } + void CreateSockets() { client_socket_.reset(); server_socket_.reset(); @@ -422,10 +424,8 @@ std::unique_ptr<StreamSocket> server_socket = std::make_unique<FakeSocket>(channel_2_.get(), channel_1_.get()); - HostPortPair host_and_pair("unittest", 0); - client_socket_ = client_context_->CreateSSLClientSocket( - std::move(client_connection), host_and_pair, client_ssl_config_); + std::move(client_connection), GetHostAndPort(), client_ssl_config_); ASSERT_TRUE(client_socket_); server_socket_ = @@ -435,17 +435,17 @@ void ConfigureClientCertsForClient(const char* cert_file_name, const char* private_key_file_name) { - client_ssl_config_.send_client_cert = true; - client_ssl_config_.client_cert = + scoped_refptr<X509Certificate> client_cert = ImportCertFromFile(GetTestCertsDirectory(), cert_file_name); - ASSERT_TRUE(client_ssl_config_.client_cert); + ASSERT_TRUE(client_cert); std::unique_ptr<crypto::RSAPrivateKey> key = ReadTestKey(private_key_file_name); ASSERT_TRUE(key); - client_ssl_config_.client_private_key = - WrapOpenSSLPrivateKey(bssl::UpRef(key->key())); + client_context_->SetClientCertificate( + GetHostAndPort(), std::move(client_cert), + WrapOpenSSLPrivateKey(bssl::UpRef(key->key()))); } void ConfigureClientCertsForServer() {
diff --git a/net/socket/transport_client_socket_pool.cc b/net/socket/transport_client_socket_pool.cc index dff85bcd..de40f29d 100644 --- a/net/socket/transport_client_socket_pool.cc +++ b/net/socket/transport_client_socket_pool.cc
@@ -145,6 +145,7 @@ max_sockets_per_group, unused_idle_socket_timeout, ClientSocketPool::used_idle_socket_timeout(), + proxy_server, std::make_unique<ConnectJobFactoryImpl>(proxy_server, is_for_websockets, common_connect_job_params), @@ -174,14 +175,16 @@ int max_sockets_per_group, base::TimeDelta unused_idle_socket_timeout, base::TimeDelta used_idle_socket_timeout, + const ProxyServer& proxy_server, std::unique_ptr<ConnectJobFactory> connect_job_factory, SSLClientContext* ssl_client_context, bool connect_backup_jobs_enabled) { return base::WrapUnique<TransportClientSocketPool>( new TransportClientSocketPool( max_sockets, max_sockets_per_group, unused_idle_socket_timeout, - used_idle_socket_timeout, std::move(connect_job_factory), - ssl_client_context, connect_backup_jobs_enabled)); + used_idle_socket_timeout, proxy_server, + std::move(connect_job_factory), ssl_client_context, + connect_backup_jobs_enabled)); } TransportClientSocketPool::CallbackResultPair::CallbackResultPair() @@ -762,6 +765,7 @@ int max_sockets_per_group, base::TimeDelta unused_idle_socket_timeout, base::TimeDelta used_idle_socket_timeout, + const ProxyServer& proxy_server, std::unique_ptr<ConnectJobFactory> connect_job_factory, SSLClientContext* ssl_client_context, bool connect_backup_jobs_enabled) @@ -772,6 +776,7 @@ max_sockets_per_group_(max_sockets_per_group), unused_idle_socket_timeout_(unused_idle_socket_timeout), used_idle_socket_timeout_(used_idle_socket_timeout), + proxy_server_(proxy_server), connect_job_factory_(std::move(connect_job_factory)), connect_backup_jobs_enabled_(connect_backup_jobs_enabled && g_connect_backup_jobs_enabled), @@ -793,6 +798,51 @@ : ERR_NETWORK_CHANGED); } +void TransportClientSocketPool::OnSSLConfigForServerChanged( + const HostPortPair& server) { + bool refreshed_any = false; + // Current time value. Retrieving it once at the function start rather than + // inside the inner loop, since it shouldn't change by any meaningful amount. + // + // TODO(davidben): This value is not actually needed because + // CleanupIdleSocketsInGroup() is called with |force| = true. Tidy up + // interfaces so the parameter is not necessary. + base::TimeTicks now = base::TimeTicks::Now(); + + if (proxy_server_.is_http_like() && !proxy_server_.is_http() && + proxy_server_.host_port_pair() == server) { + // If the proxy is |server| and uses SSL settings (HTTPS or QUIC), refresh + // every group. + refreshed_any = !group_map_.empty(); + for (auto it = group_map_.begin(); it != group_map_.end();) { + auto to_refresh = it++; + // Note this call may destroy the group and invalidate |to_refresh|. + RefreshGroup(to_refresh, now); + } + } else { + // Refresh the credentialed and uncredentialed pools for |server|. + for (auto privacy_mode : {PrivacyMode::PRIVACY_MODE_DISABLED, + PrivacyMode::PRIVACY_MODE_ENABLED}) { + auto it = + group_map_.find(GroupId(server, SocketType::kSsl, privacy_mode)); + if (it != group_map_.end()) { + refreshed_any = true; + // Note this call may destroy the group and invalidate |it|. + RefreshGroup(it, now); + } + } + } + + if (refreshed_any) { + // Check to see if any group can use the freed up socket slots. It would be + // more efficient to give the slots to the refreshed groups, if the still + // exists and need them, but this should be rare enough that it doesn't + // matter. This will also make sure the slots are given to the group with + // the highest priority request without an assigned ConnectJob. + CheckForStalledSocketGroups(); + } +} + bool TransportClientSocketPool::HasGroup(const GroupId& group_id) const { return base::Contains(group_map_, group_id); } @@ -878,11 +928,6 @@ group_map_.erase(it); } -void TransportClientSocketPool::RefreshGroupForTesting( - const GroupId& group_id) { - RefreshGroup(group_id); -} - // static bool TransportClientSocketPool::connect_backup_jobs_enabled() { return g_connect_backup_jobs_enabled; @@ -1323,31 +1368,21 @@ } } -void TransportClientSocketPool::RefreshGroup(const GroupId& group_id) { - auto group_it = group_map_.find(group_id); - if (group_it == group_map_.end()) - return; - Group* group = group_it->second; - - CleanupIdleSocketsInGroup(true /* force */, group, base::TimeTicks::Now()); +void TransportClientSocketPool::RefreshGroup(GroupMap::iterator it, + const base::TimeTicks& now) { + Group* group = it->second; + CleanupIdleSocketsInGroup(true /* force */, group, now); connecting_socket_count_ -= group->jobs().size(); group->RemoveAllUnboundJobs(); - if (group->IsEmpty()) { - // Remove group if it's now empty. - RemoveGroup(group_id); - } else { - // Otherwise, prevent reuse of existing sockets. - group->IncrementGeneration(); - } + // Otherwise, prevent reuse of existing sockets. + group->IncrementGeneration(); - // Check to see if any group (including |group_id|) can use the freed up - // socket slots. Would be more efficient to give the slots to |group|, if it - // still exists and needs them, but this should be rare enough that it doesn't - // matter. This will also make sure the slots are given to the group with the - // highest priority request without an assigned ConnectJob. - CheckForStalledSocketGroups(); + // Delete group if no longer needed. + if (group->IsEmpty()) { + RemoveGroup(it); + } } TransportClientSocketPool::Group::Group(
diff --git a/net/socket/transport_client_socket_pool.h b/net/socket/transport_client_socket_pool.h index ad1904f4..cdfa587 100644 --- a/net/socket/transport_client_socket_pool.h +++ b/net/socket/transport_client_socket_pool.h
@@ -31,6 +31,7 @@ #include "net/base/net_export.h" #include "net/base/network_change_notifier.h" #include "net/base/priority_queue.h" +#include "net/base/proxy_server.h" #include "net/base/request_priority.h" #include "net/log/net_log_with_source.h" #include "net/socket/client_socket_handle.h" @@ -51,7 +52,6 @@ struct CommonConnectJobParams; struct NetLogSource; -class ProxyServer; struct NetworkTrafficAnnotationTag; // TransportClientSocketPool establishes network connections through using @@ -175,6 +175,7 @@ int max_sockets_per_group, base::TimeDelta unused_idle_socket_timeout, base::TimeDelta used_idle_socket_timeout, + const ProxyServer& proxy_server, std::unique_ptr<ConnectJobFactory> connect_job_factory, SSLClientContext* ssl_client_context, bool connect_backup_jobs_enabled); @@ -258,14 +259,16 @@ return HasGroup(group_id); } - void RefreshGroupForTesting(const GroupId& group_id); - static bool connect_backup_jobs_enabled(); static bool set_connect_backup_jobs_enabled(bool enabled); // NetworkChangeNotifier::IPAddressObserver methods: void OnIPAddressChanged() override; + // SSLClientContext::Observer methods. + void OnSSLConfigChanged(bool is_cert_database_change) override; + void OnSSLConfigForServerChanged(const HostPortPair& server) override; + private: class ConnectJobFactoryImpl; @@ -596,13 +599,11 @@ int max_sockets_per_group, base::TimeDelta unused_idle_socket_timeout, base::TimeDelta used_idle_socket_timeout, + const ProxyServer& proxy_server, std::unique_ptr<ConnectJobFactory> connect_job_factory, SSLClientContext* ssl_client_context, bool connect_backup_jobs_enabled); - // SSLClientContext::Observer methods. - void OnSSLConfigChanged(bool is_cert_database_change) override; - base::TimeDelta ConnectRetryInterval() const { // TODO(mbelshe): Make this tuned dynamically based on measured RTT. // For now, just use the max retry interval. @@ -745,14 +746,18 @@ // this pool is stalled. void TryToCloseSocketsInLayeredPools(); - // If the specified group exists, closes all idle sockets and cancels all - // unbound ConnectJobs associated with the group. Also increments the group's - // generation number, ensuring any currently existing handed out socket will - // be siletly closed when its returned to the socket pool. Bound ConnectJobs - // will only be destroyed on once they compelete, as they may be waiting on - // user input. No request (including bound ones) will be failed as a result of - // this call - instead, new ConnectJobs will be created. - void RefreshGroup(const GroupId& group_id); + // Closes all idle sockets and cancels all unbound ConnectJobs associated with + // |it->second|. Also increments the group's generation number, ensuring any + // currently existing handed out socket will be silently closed when it is + // returned to the socket pool. Bound ConnectJobs will only be destroyed on + // once they complete, as they may be waiting on user input. No request + // (including bound ones) will be failed as a result of this call - instead, + // new ConnectJobs will be created. + // + // The group may be removed if this leaves the group empty. The caller must + // call CheckForStalledSocketGroups() after all applicable groups have been + // refreshed. + void RefreshGroup(GroupMap::iterator it, const base::TimeTicks& now); GroupMap group_map_; @@ -780,6 +785,8 @@ const base::TimeDelta unused_idle_socket_timeout_; const base::TimeDelta used_idle_socket_timeout_; + const ProxyServer proxy_server_; + const std::unique_ptr<ConnectJobFactory> connect_job_factory_; // TODO(vandebo) Remove when backup jobs move to TransportClientSocketPool
diff --git a/net/spdy/spdy_session_pool.cc b/net/spdy/spdy_session_pool.cc index a4ed404..8ffc3b7 100644 --- a/net/spdy/spdy_session_pool.cc +++ b/net/spdy/spdy_session_pool.cc
@@ -474,6 +474,24 @@ : ERR_NETWORK_CHANGED); } +void SpdySessionPool::OnSSLConfigForServerChanged(const HostPortPair& server) { + WeakSessionList current_sessions = GetCurrentSessions(); + for (base::WeakPtr<SpdySession>& session : current_sessions) { + if (!session) + continue; + + const ProxyServer& proxy_server = + session->spdy_session_key().proxy_server(); + if (session->host_port_pair() == server || + (proxy_server.is_http_like() && !proxy_server.is_http() && + proxy_server.host_port_pair() == server)) { + session->MakeUnavailable(); + session->MaybeFinishGoingAway(); + DCHECK(!IsSessionAvailable(session)); + } + } +} + void SpdySessionPool::RemoveRequestForSpdySession(SpdySessionRequest* request) { DCHECK_EQ(this, request->spdy_session_pool());
diff --git a/net/spdy/spdy_session_pool.h b/net/spdy/spdy_session_pool.h index 75417c59..e2ce4e7 100644 --- a/net/spdy/spdy_session_pool.h +++ b/net/spdy/spdy_session_pool.h
@@ -293,6 +293,11 @@ // We perform the same flushing as described above when SSL settings change. void OnSSLConfigChanged(bool is_cert_database_change) override; + // Makes all sessions using |server|'s SSL configuration unavailable, meaning + // they will not be used to service new streams. Does not close any existing + // streams. + void OnSSLConfigForServerChanged(const HostPortPair& server) override; + void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd, const std::string& parent_dump_absolute_name) const;
diff --git a/net/spdy/spdy_session_pool_unittest.cc b/net/spdy/spdy_session_pool_unittest.cc index 3013b53..7ab061bc2 100644 --- a/net/spdy/spdy_session_pool_unittest.cc +++ b/net/spdy/spdy_session_pool_unittest.cc
@@ -1408,4 +1408,158 @@ EXPECT_FALSE(request_deleted_callback3.invoked()); } +static const char kSSLServerTestHost[] = "config-changed.test"; + +static const struct { + const char* url; + const char* proxy_pac_string; + bool expect_invalidated; +} kSSLServerTests[] = { + // If the host and port match, the session should be invalidated. + {"https://config-changed.test", "DIRECT", true}, + // If host and port do not match, the session should not be invalidated. + {"https://mail.config-changed.test", "DIRECT", false}, + {"https://config-changed.test:444", "DIRECT", false}, + // If the proxy matches, the session should be invalidated independent of + // the host. + {"https://config-changed.test", "HTTPS config-changed.test:443", true}, + {"https://mail.config-changed.test", "HTTPS config-changed.test:443", true}, + // HTTP and SOCKS proxies do not have client certificates. + {"https://mail.config-changed.test", "PROXY config-changed.test:443", + false}, + {"https://mail.config-changed.test", "SOCKS5 config-changed.test:443", + false}, + // The proxy host and port must match. + {"https://mail.config-changed.test", "HTTPS mail.config-changed.test:443", + false}, + {"https://mail.config-changed.test", "HTTPS config-changed.test:444", + false}, +}; + +// Tests the OnSSLConfigForServerChanged() method when there are no streams +// active. +TEST_F(SpdySessionPoolTest, SSLConfigForServerChanged) { + const MockConnect connect_data(SYNCHRONOUS, OK); + const MockRead reads[] = { + MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. + }; + + std::vector<std::unique_ptr<StaticSocketDataProvider>> socket_data; + size_t num_tests = base::size(kSSLServerTests); + for (size_t i = 0; i < num_tests; i++) { + socket_data.push_back(std::make_unique<StaticSocketDataProvider>( + reads, base::span<MockWrite>())); + socket_data.back()->set_connect_data(connect_data); + session_deps_.socket_factory->AddSocketDataProvider( + socket_data.back().get()); + AddSSLSocketData(); + } + + CreateNetworkSession(); + + std::vector<base::WeakPtr<SpdySession>> sessions; + for (size_t i = 0; i < num_tests; i++) { + SpdySessionKey key( + HostPortPair::FromURL(GURL(kSSLServerTests[i].url)), + ProxyServer::FromPacString(kSSLServerTests[i].proxy_pac_string), + PRIVACY_MODE_DISABLED, SpdySessionKey::IsProxySession::kFalse, + SocketTag()); + sessions.push_back( + CreateSpdySession(http_session_.get(), key, NetLogWithSource())); + } + + // All sessions are available. + for (size_t i = 0; i < num_tests; i++) { + SCOPED_TRACE(i); + EXPECT_TRUE(sessions[i]->IsAvailable()); + } + + spdy_session_pool_->OnSSLConfigForServerChanged( + HostPortPair(kSSLServerTestHost, 443)); + base::RunLoop().RunUntilIdle(); + + // Sessions were inactive, so the unavailable sessions are closed. + for (size_t i = 0; i < num_tests; i++) { + SCOPED_TRACE(i); + if (kSSLServerTests[i].expect_invalidated) { + EXPECT_FALSE(sessions[i]); + } else { + ASSERT_TRUE(sessions[i]); + EXPECT_TRUE(sessions[i]->IsAvailable()); + } + } +} + +// Tests the OnSSLConfigForServerChanged() method when there are streams active. +TEST_F(SpdySessionPoolTest, SSLConfigForServerChangedWithStreams) { + const MockConnect connect_data(SYNCHRONOUS, OK); + const MockRead reads[] = { + MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. + }; + + std::vector<std::unique_ptr<StaticSocketDataProvider>> socket_data; + size_t num_tests = base::size(kSSLServerTests); + for (size_t i = 0; i < num_tests; i++) { + socket_data.push_back(std::make_unique<StaticSocketDataProvider>( + reads, base::span<MockWrite>())); + socket_data.back()->set_connect_data(connect_data); + session_deps_.socket_factory->AddSocketDataProvider( + socket_data.back().get()); + AddSSLSocketData(); + } + + CreateNetworkSession(); + + std::vector<base::WeakPtr<SpdySession>> sessions; + std::vector<base::WeakPtr<SpdyStream>> streams; + for (size_t i = 0; i < num_tests; i++) { + SCOPED_TRACE(i); + SpdySessionKey key( + HostPortPair::FromURL(GURL(kSSLServerTests[i].url)), + ProxyServer::FromPacString(kSSLServerTests[i].proxy_pac_string), + PRIVACY_MODE_DISABLED, SpdySessionKey::IsProxySession::kFalse, + SocketTag()); + sessions.push_back( + CreateSpdySession(http_session_.get(), key, NetLogWithSource())); + streams.push_back(CreateStreamSynchronously( + SPDY_BIDIRECTIONAL_STREAM, sessions.back(), + GURL(kSSLServerTests[i].url), MEDIUM, NetLogWithSource())); + ASSERT_TRUE(streams.back()); + } + + // All sessions are active and available. + for (size_t i = 0; i < num_tests; i++) { + SCOPED_TRACE(i); + EXPECT_TRUE(sessions[i]->is_active()); + EXPECT_TRUE(sessions[i]->IsAvailable()); + } + + spdy_session_pool_->OnSSLConfigForServerChanged( + HostPortPair(kSSLServerTestHost, 443)); + + // The sessions should continue to be active, but now some are unavailable. + for (size_t i = 0; i < num_tests; i++) { + SCOPED_TRACE(i); + ASSERT_TRUE(sessions[i]); + EXPECT_TRUE(sessions[i]->is_active()); + if (kSSLServerTests[i].expect_invalidated) { + EXPECT_FALSE(sessions[i]->IsAvailable()); + EXPECT_TRUE(sessions[i]->IsGoingAway()); + } else { + EXPECT_TRUE(sessions[i]->IsAvailable()); + EXPECT_FALSE(sessions[i]->IsGoingAway()); + } + } + + // Each stream is still around. Close them. + for (size_t i = 0; i < num_tests; i++) { + SCOPED_TRACE(i); + ASSERT_TRUE(streams[i]); + streams[i]->Close(); + } + + // TODO(https://crbug.com/982499): The invalidated sessions should be closed + // after a RunUntilIdle(), but they are not. +} + } // namespace net
diff --git a/net/ssl/ssl_client_auth_cache.cc b/net/ssl/ssl_client_auth_cache.cc index 4cd6aef7..e8c05fc9 100644 --- a/net/ssl/ssl_client_auth_cache.cc +++ b/net/ssl/ssl_client_auth_cache.cc
@@ -10,13 +10,9 @@ namespace net { -SSLClientAuthCache::SSLClientAuthCache() { - CertDatabase::GetInstance()->AddObserver(this); -} +SSLClientAuthCache::SSLClientAuthCache() {} -SSLClientAuthCache::~SSLClientAuthCache() { - CertDatabase::GetInstance()->RemoveObserver(this); -} +SSLClientAuthCache::~SSLClientAuthCache() {} bool SSLClientAuthCache::Lookup(const HostPortPair& server, scoped_refptr<X509Certificate>* certificate, @@ -41,11 +37,11 @@ // TODO(wtc): enforce a maximum number of entries. } -void SSLClientAuthCache::Remove(const HostPortPair& server) { - cache_.erase(server); +bool SSLClientAuthCache::Remove(const HostPortPair& server) { + return cache_.erase(server); } -void SSLClientAuthCache::OnCertDBChanged() { +void SSLClientAuthCache::Clear() { cache_.clear(); }
diff --git a/net/ssl/ssl_client_auth_cache.h b/net/ssl/ssl_client_auth_cache.h index 6486967..a380ea7 100644 --- a/net/ssl/ssl_client_auth_cache.h +++ b/net/ssl/ssl_client_auth_cache.h
@@ -13,7 +13,6 @@ #include "base/memory/ref_counted.h" #include "net/base/host_port_pair.h" #include "net/base/net_export.h" -#include "net/cert/cert_database.h" #include "net/ssl/ssl_private_key.h" namespace net { @@ -21,16 +20,12 @@ class X509Certificate; // The SSLClientAuthCache class is a simple cache structure to store SSL -// client certificates. Provides lookup, insertion, and deletion of entries. -// The parameter for doing lookups, insertions, and deletions is the server's -// host and port. -// -// TODO(wtc): This class is based on FtpAuthCache. We can extract the common -// code to a template class. -class NET_EXPORT_PRIVATE SSLClientAuthCache : public CertDatabase::Observer { +// client certificate decisions. Provides lookup, insertion, and deletion of +// entries based on a server's host and port. +class NET_EXPORT_PRIVATE SSLClientAuthCache { public: SSLClientAuthCache(); - ~SSLClientAuthCache() override; + ~SSLClientAuthCache(); // Checks for a client certificate preference for SSL server at |server|. // Returns true if a preference is found, and sets |*certificate| to the @@ -49,11 +44,12 @@ scoped_refptr<X509Certificate> client_cert, scoped_refptr<SSLPrivateKey> private_key); - // Remove the client certificate for |server| from the cache, if one exists. - void Remove(const HostPortPair& server); + // Remove cached client certificate decisions for |server| from the cache. + // Returns true if one was removed and false otherwise. + bool Remove(const HostPortPair& server); - // CertDatabase::Observer methods: - void OnCertDBChanged() override; + // Removes all cached client certificate decisions. + void Clear(); private: typedef HostPortPair AuthCacheKey;
diff --git a/net/ssl/ssl_client_auth_cache_unittest.cc b/net/ssl/ssl_client_auth_cache_unittest.cc index ff1b015..6d6bbf82 100644 --- a/net/ssl/ssl_client_auth_cache_unittest.cc +++ b/net/ssl/ssl_client_auth_cache_unittest.cc
@@ -154,8 +154,8 @@ EXPECT_EQ(nullptr, cached_cert.get()); } -// Check that the OnCertDBChanged() method removes all cache entries. -TEST(SSLClientAuthCacheTest, OnCertDBChanged) { +// Check that the Clear() method removes all cache entries. +TEST(SSLClientAuthCacheTest, Clear) { SSLClientAuthCache cache; HostPortPair server1("foo", 443); @@ -178,7 +178,7 @@ EXPECT_TRUE(cache.Lookup(server2, &cached_cert, &cached_pkey)); EXPECT_EQ(nullptr, cached_cert.get()); - cache.OnCertDBChanged(); + cache.Clear(); // Check that we no longer have entries for either server. EXPECT_FALSE(cache.Lookup(server1, &cached_cert, &cached_pkey));
diff --git a/net/ssl/ssl_client_session_cache.cc b/net/ssl/ssl_client_session_cache.cc index 10f1fb5..40ef3c3 100644 --- a/net/ssl/ssl_client_session_cache.cc +++ b/net/ssl/ssl_client_session_cache.cc
@@ -111,6 +111,17 @@ iter->second.Push(std::move(session)); } +void SSLClientSessionCache::FlushForServer(const HostPortPair& server) { + auto iter = cache_.begin(); + while (iter != cache_.end()) { + if (iter->first.server == server) { + iter = cache_.Erase(iter); + } else { + ++iter; + } + } +} + void SSLClientSessionCache::Flush() { cache_.Clear(); }
diff --git a/net/ssl/ssl_client_session_cache.h b/net/ssl/ssl_client_session_cache.h index d6af3e8..c674837 100644 --- a/net/ssl/ssl_client_session_cache.h +++ b/net/ssl/ssl_client_session_cache.h
@@ -77,6 +77,9 @@ // checked for stale entries. void Insert(const Key& cache_key, bssl::UniquePtr<SSL_SESSION> session); + // Removes all entries associated with |server|. + void FlushForServer(const HostPortPair& server); + // Removes all entries from the cache. void Flush();
diff --git a/net/ssl/ssl_client_session_cache_unittest.cc b/net/ssl/ssl_client_session_cache_unittest.cc index 8f0075f..32e7f30 100644 --- a/net/ssl/ssl_client_session_cache_unittest.cc +++ b/net/ssl/ssl_client_session_cache_unittest.cc
@@ -12,9 +12,11 @@ #include "base/trace_event/memory_allocator_dump.h" #include "base/trace_event/process_memory_dump.h" #include "base/trace_event/traced_value.h" +#include "net/base/network_isolation_key.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/boringssl/src/include/openssl/ssl.h" +#include "url/gurl.h" using testing::ByRef; using testing::Contains; @@ -409,6 +411,80 @@ EXPECT_EQ(0u, cache.size()); } +TEST_F(SSLClientSessionCacheTest, FlushForServer) { + SSLClientSessionCache::Config config; + SSLClientSessionCache cache(config); + + const url::Origin kOriginA = url::Origin::Create(GURL("https://a.test")); + const url::Origin kOriginB = url::Origin::Create(GURL("https://b.test")); + + // Insert a number of cache entries. + SSLClientSessionCache::Key key1; + key1.server = HostPortPair("a.test", 443); + auto session1 = NewSSLSession(); + cache.Insert(key1, bssl::UpRef(session1)); + + SSLClientSessionCache::Key key2; + key2.server = HostPortPair("a.test", 443); + key2.dest_ip_addr = IPAddress::IPv4Localhost(); + key2.network_isolation_key = NetworkIsolationKey(kOriginB, kOriginB); + key2.privacy_mode = PRIVACY_MODE_ENABLED; + auto session2 = NewSSLSession(); + cache.Insert(key2, bssl::UpRef(session2)); + + SSLClientSessionCache::Key key3; + key3.server = HostPortPair("a.test", 444); + auto session3 = NewSSLSession(); + cache.Insert(key3, bssl::UpRef(session3)); + + SSLClientSessionCache::Key key4; + key4.server = HostPortPair("b.test", 443); + auto session4 = NewSSLSession(); + cache.Insert(key4, bssl::UpRef(session4)); + + SSLClientSessionCache::Key key5; + key5.server = HostPortPair("b.test", 443); + key5.network_isolation_key = NetworkIsolationKey(kOriginA, kOriginA); + auto session5 = NewSSLSession(); + cache.Insert(key5, bssl::UpRef(session5)); + + // Flush an unrelated server. The cache should be unaffected. + cache.FlushForServer(HostPortPair("c.test", 443)); + EXPECT_EQ(5u, cache.size()); + EXPECT_EQ(session1.get(), cache.Lookup(key1).get()); + EXPECT_EQ(session2.get(), cache.Lookup(key2).get()); + EXPECT_EQ(session3.get(), cache.Lookup(key3).get()); + EXPECT_EQ(session4.get(), cache.Lookup(key4).get()); + EXPECT_EQ(session5.get(), cache.Lookup(key5).get()); + + // Flush a.test:443. |key1| and |key2| should match, but not the others. + cache.FlushForServer(HostPortPair("a.test", 443)); + EXPECT_EQ(3u, cache.size()); + EXPECT_EQ(nullptr, cache.Lookup(key1).get()); + EXPECT_EQ(nullptr, cache.Lookup(key2).get()); + EXPECT_EQ(session3.get(), cache.Lookup(key3).get()); + EXPECT_EQ(session4.get(), cache.Lookup(key4).get()); + EXPECT_EQ(session5.get(), cache.Lookup(key5).get()); + + // Flush b.test:443. |key4| and |key5| match, but not |key3|. + cache.FlushForServer(HostPortPair("b.test", 443)); + EXPECT_EQ(1u, cache.size()); + EXPECT_EQ(nullptr, cache.Lookup(key1).get()); + EXPECT_EQ(nullptr, cache.Lookup(key2).get()); + EXPECT_EQ(session3.get(), cache.Lookup(key3).get()); + EXPECT_EQ(nullptr, cache.Lookup(key4).get()); + EXPECT_EQ(nullptr, cache.Lookup(key5).get()); + + // Flush the last host, a.test:444. + cache.FlushForServer(HostPortPair("a.test", 444)); + EXPECT_EQ(0u, cache.size()); + EXPECT_EQ(nullptr, cache.Lookup(key1).get()); + EXPECT_EQ(nullptr, cache.Lookup(key2).get()); + EXPECT_EQ(nullptr, cache.Lookup(key3).get()); + EXPECT_EQ(nullptr, cache.Lookup(key4).get()); + EXPECT_EQ(nullptr, cache.Lookup(key5).get()); +} + class SSLClientSessionCacheMemoryDumpTest : public SSLClientSessionCacheTest, public testing::WithParamInterface<
diff --git a/net/ssl/ssl_config.cc b/net/ssl/ssl_config.cc index 3ffdf6c7..fbd71b01 100644 --- a/net/ssl/ssl_config.cc +++ b/net/ssl/ssl_config.cc
@@ -27,7 +27,6 @@ require_ecdhe(false), ignore_certificate_errors(false), disable_cert_verification_network_fetches(false), - send_client_cert(false), renego_allowed_default(false), privacy_mode(PRIVACY_MODE_DISABLED) {}
diff --git a/net/ssl/ssl_config.h b/net/ssl/ssl_config.h index 51c3e64..4be4323 100644 --- a/net/ssl/ssl_config.h +++ b/net/ssl/ssl_config.h
@@ -110,9 +110,6 @@ // deadlock. bool disable_cert_verification_network_fetches; - // True if we should send client_cert to the server. - bool send_client_cert; - // The list of application level protocols supported with ALPN (Application // Layer Protocol Negotiation), in decreasing order of preference. Protocols // will be advertised in this order during TLS handshake. @@ -125,9 +122,6 @@ // The list of application-level protocols to enable renegotiation for. NextProtoVector renego_allowed_for_protos; - scoped_refptr<X509Certificate> client_cert; - scoped_refptr<SSLPrivateKey> client_private_key; - // If the PartitionSSLSessionsByNetworkIsolationKey feature is enabled, the // session cache is partitioned by this value. NetworkIsolationKey network_isolation_key;
diff --git a/pdf/BUILD.gn b/pdf/BUILD.gn index c6989b1..ee72eea 100644 --- a/pdf/BUILD.gn +++ b/pdf/BUILD.gn
@@ -197,6 +197,7 @@ "pdfium/accessibility_unittest.cc", "pdfium/findtext_unittest.cc", "pdfium/pdfium_engine_exports_unittest.cc", + "pdfium/pdfium_permissions_unittest.cc", "pdfium/pdfium_print_unittest.cc", "pdfium/pdfium_test_base.cc", "pdfium/pdfium_test_base.h",
diff --git a/pdf/document_layout.cc b/pdf/document_layout.cc index 604a2e3f..813f1bae 100644 --- a/pdf/document_layout.cc +++ b/pdf/document_layout.cc
@@ -11,33 +11,60 @@ const draw_utils::PageInsetSizes DocumentLayout::kSingleViewInsets{ /*left=*/5, /*top=*/3, /*right=*/5, /*bottom=*/7}; -DocumentLayout::DocumentLayout() = default; +DocumentLayout::Options::Options() = default; -DocumentLayout::DocumentLayout(const DocumentLayout& other) = default; -DocumentLayout& DocumentLayout::operator=(const DocumentLayout& other) = - default; +DocumentLayout::Options::Options(const Options& other) = default; +DocumentLayout::Options& DocumentLayout::Options::operator=( + const Options& other) = default; -DocumentLayout::~DocumentLayout() = default; +DocumentLayout::Options::~Options() = default; -void DocumentLayout::RotatePagesClockwise() { +void DocumentLayout::Options::RotatePagesClockwise() { default_page_orientation_ = (default_page_orientation_ + 1) % 4; } -void DocumentLayout::RotatePagesCounterclockwise() { - default_page_orientation_ = (default_page_orientation_ - 1) % 4; +void DocumentLayout::Options::RotatePagesCounterclockwise() { + // Use the modular additive inverse of -1 to avoid negative values. + default_page_orientation_ = (default_page_orientation_ + 3) % 4; } -std::vector<pp::Rect> DocumentLayout::GetTwoUpViewLayout( - const std::vector<pp::Rect>& page_rects) { - std::vector<pp::Rect> formatted_rects(page_rects.size()); - // Reset the current layout's height for new two-up view layout. - size_.set_height(0); +DocumentLayout::DocumentLayout() = default; - for (size_t i = 0; i < page_rects.size(); ++i) { +DocumentLayout::~DocumentLayout() = default; + +// TODO(chinsenj): refactor to not rely on prior DocumentLayout state. +std::vector<pp::Rect> DocumentLayout::GetSingleViewLayout( + const std::vector<pp::Size>& page_sizes) { + std::vector<pp::Rect> formatted_rects(page_sizes.size()); + DCHECK_EQ(0, size_.height()); + + for (size_t i = 0; i < page_sizes.size(); ++i) { + if (i != 0) { + // Add space for bottom separator. + EnlargeHeight(kBottomSeparator); + } + + const pp::Size& page_size = page_sizes[i]; + formatted_rects[i] = + draw_utils::GetRectForSingleView(page_size, size_, kSingleViewInsets); + AppendPageRect(page_size); + } + + return formatted_rects; +} + +// TODO(chinsenj): refactor to not rely on prior DocumentLayout state. +std::vector<pp::Rect> DocumentLayout::GetTwoUpViewLayout( + const std::vector<pp::Size>& page_sizes) { + DCHECK_EQ(0, size_.height()); + + std::vector<pp::Rect> formatted_rects(page_sizes.size()); + + for (size_t i = 0; i < page_sizes.size(); ++i) { draw_utils::PageInsetSizes page_insets = draw_utils::GetPageInsetsForTwoUpView( - i, page_rects.size(), kSingleViewInsets, kHorizontalSeparator); - const pp::Size& page_size = page_rects[i].size(); + i, page_sizes.size(), kSingleViewInsets, kHorizontalSeparator); + const pp::Size& page_size = page_sizes[i]; if (i % 2 == 0) { formatted_rects[i] = draw_utils::GetLeftRectForTwoUpView( @@ -45,13 +72,12 @@ } else { formatted_rects[i] = draw_utils::GetRightRectForTwoUpView( page_size, {size_.width(), size_.height()}, page_insets); - EnlargeHeight( - std::max(page_size.height(), page_rects[i - 1].size().height())); + EnlargeHeight(std::max(page_size.height(), page_sizes[i - 1].height())); } } - if (page_rects.size() % 2 == 1) { - EnlargeHeight(page_rects.back().size().height()); + if (page_sizes.size() % 2 == 1) { + EnlargeHeight(page_sizes.back().height()); } return formatted_rects;
diff --git a/pdf/document_layout.h b/pdf/document_layout.h index 117d8a7..a558fbb7 100644 --- a/pdf/document_layout.h +++ b/pdf/document_layout.h
@@ -17,33 +17,57 @@ // (possibly rotated) in a non-overlapping vertical sequence. // // All layout units are pixels. +// +// The |Options| class controls the behavior of the layout, such as the default +// orientation of pages. class DocumentLayout final { public: + // Options controlling layout behavior. + class Options final { + public: + Options(); + + Options(const Options& other); + Options& operator=(const Options& other); + + ~Options(); + + // Returns the default page orientation, encoded as an integer from 0 to 3 + // (inclusive). + // + // A return value of 0 indicates the original page orientation, with each + // increment indicating clockwise rotation by an additional 90 degrees. + // + // TODO(kmoon): Return an enum (class) instead of an integer. + int default_page_orientation() const { return default_page_orientation_; } + + // Rotates default page orientation 90 degrees clockwise. + void RotatePagesClockwise(); + + // Rotates default page orientation 90 degrees counterclockwise. + void RotatePagesCounterclockwise(); + + private: + // Orientations are non-negative integers modulo 4. + int default_page_orientation_ = 0; + }; + static const draw_utils::PageInsetSizes kSingleViewInsets; static constexpr int32_t kBottomSeparator = 4; static constexpr int32_t kHorizontalSeparator = 1; DocumentLayout(); - DocumentLayout(const DocumentLayout& other); - DocumentLayout& operator=(const DocumentLayout& other); + DocumentLayout(const DocumentLayout& other) = delete; + DocumentLayout& operator=(const DocumentLayout& other) = delete; ~DocumentLayout(); - // Returns an integer from 0 to 3 (inclusive), encoding the default - // orientation of the document's pages. - // - // A return value of 0 indicates the original page orientation, with each - // increment indicating clockwise rotation by an additional 90 degrees. - // - // TODO(kmoon): Return an enum (class) instead of an integer. - int default_page_orientation() const { return default_page_orientation_; } + // Returns the layout options. + const Options& options() const { return options_; } - // Rotates all pages 90 degrees clockwise. Does not recompute layout. - void RotatePagesClockwise(); - - // Rotates all pages 90 degrees counterclockwise. Does not recompute layout. - void RotatePagesCounterclockwise(); + // Sets the layout options. + void set_options(const Options& options) { options_ = options; } // Returns the layout's total size. const pp::Size& size() const { return size_; } @@ -51,11 +75,19 @@ // Sets the layout's total size. void set_size(const pp::Size& size) { size_ = size; } - // Given |page_rects| and the layout's size is set to a single-view layout, - // return |page_rects| formatted for two-up view and update the layout's size - // to the size of the new two-up view layout. + // Given |page_sizes| and the layout's width set to the max width of the + // document's pages, return pp::Rects that represent |page_sizes| + // formatted for single view and update the layout's size to the size of the + // new single view layout. + std::vector<pp::Rect> GetSingleViewLayout( + const std::vector<pp::Size>& page_sizes); + + // Given |page_sizes| and the layout's width is set to the max page width of + // the document's pages, return pp::Rects that represent |page_sizes| + // formatted for two-up view and update the layout's size to the size of the + // new two-up view layout. std::vector<pp::Rect> GetTwoUpViewLayout( - const std::vector<pp::Rect>& page_rects); + const std::vector<pp::Size>& page_sizes); // Increases the layout's total height by |height|. void EnlargeHeight(int height); @@ -66,12 +98,7 @@ void AppendPageRect(const pp::Size& page_rect); private: - // Orientations are non-negative integers modulo 4. - // - // TODO(kmoon): Doesn't match return type of default_page_orientation(). - // Callers expect int, but internally, we want unsigned semantics. This will - // be cleaned up when we switch to an enum. - unsigned int default_page_orientation_ = 0; + Options options_; // Layout's total size. pp::Size size_;
diff --git a/pdf/document_layout_unittest.cc b/pdf/document_layout_unittest.cc index 1d7d0a8..02998b8 100644 --- a/pdf/document_layout_unittest.cc +++ b/pdf/document_layout_unittest.cc
@@ -11,6 +11,11 @@ namespace { +class DocumentLayoutOptionsTest : public testing::Test { + protected: + DocumentLayout::Options options_; +}; + class DocumentLayoutTest : public testing::Test { protected: DocumentLayout layout_; @@ -29,79 +34,73 @@ return lhs == rhs; } +TEST_F(DocumentLayoutOptionsTest, DefaultConstructor) { + EXPECT_EQ(options_.default_page_orientation(), 0); +} + +TEST_F(DocumentLayoutOptionsTest, CopyConstructor) { + options_.RotatePagesClockwise(); + + DocumentLayout::Options copy(options_); + EXPECT_EQ(copy.default_page_orientation(), 1); + + options_.RotatePagesClockwise(); + EXPECT_EQ(copy.default_page_orientation(), 1); +} + +TEST_F(DocumentLayoutOptionsTest, CopyAssignment) { + options_.RotatePagesClockwise(); + + DocumentLayout::Options copy; + EXPECT_EQ(copy.default_page_orientation(), 0); + copy = options_; + EXPECT_EQ(copy.default_page_orientation(), 1); + + options_.RotatePagesClockwise(); + EXPECT_EQ(copy.default_page_orientation(), 1); +} + +TEST_F(DocumentLayoutOptionsTest, RotatePagesClockwise) { + options_.RotatePagesClockwise(); + EXPECT_EQ(options_.default_page_orientation(), 1); + + options_.RotatePagesClockwise(); + EXPECT_EQ(options_.default_page_orientation(), 2); + + options_.RotatePagesClockwise(); + EXPECT_EQ(options_.default_page_orientation(), 3); + + options_.RotatePagesClockwise(); + EXPECT_EQ(options_.default_page_orientation(), 0); +} + +TEST_F(DocumentLayoutOptionsTest, RotatePagesCounterclockwise) { + options_.RotatePagesCounterclockwise(); + EXPECT_EQ(options_.default_page_orientation(), 3); + + options_.RotatePagesCounterclockwise(); + EXPECT_EQ(options_.default_page_orientation(), 2); + + options_.RotatePagesCounterclockwise(); + EXPECT_EQ(options_.default_page_orientation(), 1); + + options_.RotatePagesCounterclockwise(); + EXPECT_EQ(options_.default_page_orientation(), 0); +} + TEST_F(DocumentLayoutTest, DefaultConstructor) { - EXPECT_EQ(layout_.default_page_orientation(), 0); + EXPECT_EQ(layout_.options().default_page_orientation(), 0); EXPECT_PRED2(PpSizeEq, layout_.size(), pp::Size(0, 0)); } -TEST_F(DocumentLayoutTest, CopyConstructor) { - layout_.RotatePagesClockwise(); - layout_.EnlargeHeight(2); +TEST_F(DocumentLayoutTest, SetOptionsDoesNotRecomputeLayout) { + layout_.set_size(pp::Size(1, 2)); - DocumentLayout copy(layout_); - EXPECT_EQ(copy.default_page_orientation(), 1); - EXPECT_PRED2(PpSizeEq, copy.size(), pp::Size(0, 2)); - - layout_.RotatePagesClockwise(); - layout_.EnlargeHeight(5); - EXPECT_EQ(copy.default_page_orientation(), 1); - EXPECT_PRED2(PpSizeEq, copy.size(), pp::Size(0, 2)); -} - -TEST_F(DocumentLayoutTest, CopyAssignment) { - layout_.RotatePagesClockwise(); - layout_.EnlargeHeight(2); - - DocumentLayout copy; - EXPECT_EQ(copy.default_page_orientation(), 0); - EXPECT_PRED2(PpSizeEq, copy.size(), pp::Size(0, 0)); - - copy = layout_; - EXPECT_EQ(copy.default_page_orientation(), 1); - EXPECT_PRED2(PpSizeEq, copy.size(), pp::Size(0, 2)); - - layout_.RotatePagesClockwise(); - layout_.EnlargeHeight(5); - EXPECT_EQ(copy.default_page_orientation(), 1); - EXPECT_PRED2(PpSizeEq, copy.size(), pp::Size(0, 2)); -} - -TEST_F(DocumentLayoutTest, RotatePagesClockwise) { - layout_.RotatePagesClockwise(); - EXPECT_EQ(layout_.default_page_orientation(), 1); - - layout_.RotatePagesClockwise(); - EXPECT_EQ(layout_.default_page_orientation(), 2); - - layout_.RotatePagesClockwise(); - EXPECT_EQ(layout_.default_page_orientation(), 3); - - layout_.RotatePagesClockwise(); - EXPECT_EQ(layout_.default_page_orientation(), 0); -} - -TEST_F(DocumentLayoutTest, RotatePagesCounterclockwise) { - layout_.RotatePagesCounterclockwise(); - EXPECT_EQ(layout_.default_page_orientation(), 3); - - layout_.RotatePagesCounterclockwise(); - EXPECT_EQ(layout_.default_page_orientation(), 2); - - layout_.RotatePagesCounterclockwise(); - EXPECT_EQ(layout_.default_page_orientation(), 1); - - layout_.RotatePagesCounterclockwise(); - EXPECT_EQ(layout_.default_page_orientation(), 0); -} - -TEST_F(DocumentLayoutTest, RotatePagesDoesNotRecomputeLayout) { - layout_.EnlargeHeight(2); - - layout_.RotatePagesClockwise(); - EXPECT_PRED2(PpSizeEq, layout_.size(), pp::Size(0, 2)); - - layout_.RotatePagesCounterclockwise(); - EXPECT_PRED2(PpSizeEq, layout_.size(), pp::Size(0, 2)); + DocumentLayout::Options options; + options.RotatePagesClockwise(); + layout_.set_options(options); + EXPECT_EQ(layout_.options().default_page_orientation(), 1); + EXPECT_PRED2(PpSizeEq, layout_.size(), pp::Size(1, 2)); } TEST_F(DocumentLayoutTest, EnlargeHeight) { @@ -112,16 +111,40 @@ EXPECT_PRED2(PpSizeEq, layout_.size(), pp::Size(0, 16)); } +TEST_F(DocumentLayoutTest, GetSingleViewLayout) { + std::vector<pp::Rect> single_view_layout; + + std::vector<pp::Size> page_sizes{ + {300, 400}, {400, 500}, {300, 400}, {200, 300}}; + layout_.set_size({400, 0}); + single_view_layout = layout_.GetSingleViewLayout(page_sizes); + ASSERT_EQ(4u, single_view_layout.size()); + EXPECT_PRED2(PpRectEq, pp::Rect(55, 3, 290, 390), single_view_layout[0]); + EXPECT_PRED2(PpRectEq, pp::Rect(5, 407, 390, 490), single_view_layout[1]); + EXPECT_PRED2(PpRectEq, pp::Rect(55, 911, 290, 390), single_view_layout[2]); + EXPECT_PRED2(PpRectEq, pp::Rect(105, 1315, 190, 290), single_view_layout[3]); + EXPECT_PRED2(PpSizeEq, pp::Size(400, 1612), layout_.size()); + + page_sizes = {{240, 300}, {320, 400}, {250, 360}, {300, 600}, {270, 555}}; + layout_.set_size({320, 0}); + single_view_layout = layout_.GetSingleViewLayout(page_sizes); + ASSERT_EQ(5u, single_view_layout.size()); + EXPECT_PRED2(PpRectEq, pp::Rect(45, 3, 230, 290), single_view_layout[0]); + EXPECT_PRED2(PpRectEq, pp::Rect(5, 307, 310, 390), single_view_layout[1]); + EXPECT_PRED2(PpRectEq, pp::Rect(40, 711, 240, 350), single_view_layout[2]); + EXPECT_PRED2(PpRectEq, pp::Rect(15, 1075, 290, 590), single_view_layout[3]); + EXPECT_PRED2(PpRectEq, pp::Rect(30, 1679, 260, 545), single_view_layout[4]); + EXPECT_PRED2(PpSizeEq, pp::Size(320, 2231), layout_.size()); +} + TEST_F(DocumentLayoutTest, GetTwoUpViewLayout) { std::vector<pp::Rect> two_up_view_layout; // Test case where the widest page is on the right. - std::vector<pp::Rect> page_rects{{0, 10, 826, 1066}, - {0, 1076, 1066, 826}, - {0, 1902, 826, 1066}, - {0, 2968, 826, 900}}; + std::vector<pp::Size> page_sizes{ + {826, 1066}, {1066, 826}, {826, 1066}, {826, 900}}; layout_.set_size({1066, 0}); - two_up_view_layout = layout_.GetTwoUpViewLayout(page_rects); + two_up_view_layout = layout_.GetTwoUpViewLayout(page_sizes); ASSERT_EQ(4u, two_up_view_layout.size()); EXPECT_PRED2(PpRectEq, pp::Rect(245, 3, 820, 1056), two_up_view_layout[0]); EXPECT_PRED2(PpRectEq, pp::Rect(1067, 3, 1060, 816), two_up_view_layout[1]); @@ -130,12 +153,9 @@ EXPECT_PRED2(PpSizeEq, pp::Size(1066, 2132), layout_.size()); // Test case where the widest page is on the left. - page_rects = {{0, 5, 1066, 826}, - {0, 831, 820, 1056}, - {0, 1887, 820, 890}, - {0, 2777, 826, 1066}}; + page_sizes = {{1066, 826}, {820, 1056}, {820, 890}, {826, 1066}}; layout_.set_size({1066, 0}); - two_up_view_layout = layout_.GetTwoUpViewLayout(page_rects); + two_up_view_layout = layout_.GetTwoUpViewLayout(page_sizes); ASSERT_EQ(4u, two_up_view_layout.size()); EXPECT_PRED2(PpRectEq, pp::Rect(5, 3, 1060, 816), two_up_view_layout[0]); EXPECT_PRED2(PpRectEq, pp::Rect(1067, 3, 814, 1046), two_up_view_layout[1]); @@ -145,13 +165,9 @@ EXPECT_PRED2(PpSizeEq, pp::Size(1066, 2122), layout_.size()); // Test case where there's an odd # of pages. - page_rects = {{0, 5, 200, 300}, - {0, 305, 400, 200}, - {0, 505, 300, 600}, - {0, 1105, 250, 500}, - {0, 1605, 300, 400}}; + page_sizes = {{200, 300}, {400, 200}, {300, 600}, {250, 500}, {300, 400}}; layout_.set_size({400, 0}); - two_up_view_layout = layout_.GetTwoUpViewLayout(page_rects); + two_up_view_layout = layout_.GetTwoUpViewLayout(page_sizes); ASSERT_EQ(5u, two_up_view_layout.size()); EXPECT_PRED2(PpRectEq, pp::Rect(205, 3, 194, 290), two_up_view_layout[0]); EXPECT_PRED2(PpRectEq, pp::Rect(401, 3, 394, 190), two_up_view_layout[1]);
diff --git a/pdf/draw_utils/coordinates.cc b/pdf/draw_utils/coordinates.cc index cd3171e9..4a62020 100644 --- a/pdf/draw_utils/coordinates.cc +++ b/pdf/draw_utils/coordinates.cc
@@ -88,6 +88,17 @@ bottom_separator); } +pp::Rect GetRectForSingleView(const pp::Size& rect_size, + const pp::Size& document_size, + const PageInsetSizes& page_insets) { + pp::Rect page_rect({0, document_size.height()}, rect_size); + CenterRectHorizontally(document_size.width(), &page_rect); + page_rect.Inset(page_insets.left, page_insets.top, page_insets.right, + page_insets.bottom); + + return page_rect; +} + pp::Rect GetScreenRect(const pp::Rect& rect, const pp::Point& position, double zoom) {
diff --git a/pdf/draw_utils/coordinates.h b/pdf/draw_utils/coordinates.h index 5873197..1a77b49 100644 --- a/pdf/draw_utils/coordinates.h +++ b/pdf/draw_utils/coordinates.h
@@ -82,6 +82,13 @@ const PageInsetSizes& inset_sizes, int bottom_separator); +// Given |rect_size| and |document_size| create a horizontally centered +// pp::Rect placed at the bottom of the current document, and then inset it with +// |page_insets|. +pp::Rect GetRectForSingleView(const pp::Size& rect_size, + const pp::Size& document_size, + const PageInsetSizes& page_insets); + // Given |rect| in document coordinates, a |position| in screen coordinates, // and a |zoom| factor, returns the rectangle in screen coordinates (i.e. // 0,0 is top left corner of plugin area). An empty |rect| will always
diff --git a/pdf/draw_utils/coordinates_unittest.cc b/pdf/draw_utils/coordinates_unittest.cc index abb6747..ed221b8 100644 --- a/pdf/draw_utils/coordinates_unittest.cc +++ b/pdf/draw_utils/coordinates_unittest.cc
@@ -194,6 +194,20 @@ kBottomSeparator)); } +TEST(CoordinateTest, GetRectForSingleView) { + // Test portrait pages. + CompareRect({55, 503, 190, 390}, + GetRectForSingleView({200, 400}, {300, 500}, kSingleViewInsets)); + CompareRect({55, 603, 90, 330}, + GetRectForSingleView({100, 340}, {200, 600}, kSingleViewInsets)); + + // Test landscape pages. + CompareRect({5, 1003, 490, 440}, + GetRectForSingleView({500, 450}, {500, 1000}, kSingleViewInsets)); + CompareRect({30, 1503, 640, 190}, + GetRectForSingleView({650, 200}, {700, 1500}, kSingleViewInsets)); +} + TEST(CoordinateTest, GetScreenRect) { const pp::Rect rect(10, 20, 200, 300);
diff --git a/pdf/pdf_transform.cc b/pdf/pdf_transform.cc index 0acb36c4..c0e6f42 100644 --- a/pdf/pdf_transform.cc +++ b/pdf/pdf_transform.cc
@@ -105,8 +105,7 @@ source_clip_box.bottom; } -void CalculateNonScaledClipBoxOffset(const gfx::Rect& content_rect, - int rotation, +void CalculateNonScaledClipBoxOffset(int rotation, int page_width, int page_height, const PdfRectangle& source_clip_box,
diff --git a/pdf/pdf_transform.h b/pdf/pdf_transform.h index da506f1..5433ddc 100644 --- a/pdf/pdf_transform.h +++ b/pdf/pdf_transform.h
@@ -57,7 +57,7 @@ PdfRectangle CalculateClipBoxBoundary(const PdfRectangle& media_box, const PdfRectangle& crop_box); -// Scale |box| by |scale_factor|. +// Scale |rect| by |scale_factor|. void ScalePdfRectangle(double scale_factor, PdfRectangle* rect); // Calculate the clip box translation offset for a page that does need to be @@ -77,8 +77,6 @@ // Calculate the clip box offset for a page that does not need to be scaled. // All parameters are in points. // -// |content_rect| specifies the printable area of the destination page, with -// origin at left-bottom. // |rotation| specifies the source page rotation values which are N / 90 // degrees. // |page_width| specifies the screen destination page width. @@ -87,8 +85,7 @@ // at left-bottom. // |offset_x| and |offset_y| will contain the final translation offsets for the // source clip box, relative to origin at left-bottom. -void CalculateNonScaledClipBoxOffset(const gfx::Rect& content_rect, - int rotation, +void CalculateNonScaledClipBoxOffset(int rotation, int page_width, int page_height, const PdfRectangle& source_clip_box,
diff --git a/pdf/pdf_transform_unittest.cc b/pdf/pdf_transform_unittest.cc index faf424e..921e8b4 100644 --- a/pdf/pdf_transform_unittest.cc +++ b/pdf/pdf_transform_unittest.cc
@@ -210,26 +210,25 @@ TEST(PdfTransformTest, CalculateNonScaledClipBoxOffset) { int page_width = kDefaultWidth; int page_height = kDefaultHeight; - constexpr gfx::Rect rect(kDefaultWidth, kDefaultHeight); PdfRectangle clip_box; double offset_x; double offset_y; // |rect|, page size and |clip_box| are the same. InitializeBoxToDefaultPortraitValues(&clip_box); - CalculateNonScaledClipBoxOffset(rect, 0, page_width, page_height, clip_box, + CalculateNonScaledClipBoxOffset(0, page_width, page_height, clip_box, &offset_x, &offset_y); EXPECT_DOUBLE_EQ(0, offset_x); EXPECT_DOUBLE_EQ(0, offset_y); - CalculateNonScaledClipBoxOffset(rect, 1, page_width, page_height, clip_box, + CalculateNonScaledClipBoxOffset(1, page_width, page_height, clip_box, &offset_x, &offset_y); EXPECT_DOUBLE_EQ(0, offset_x); EXPECT_DOUBLE_EQ(0, offset_y); - CalculateNonScaledClipBoxOffset(rect, 2, page_width, page_height, clip_box, + CalculateNonScaledClipBoxOffset(2, page_width, page_height, clip_box, &offset_x, &offset_y); EXPECT_DOUBLE_EQ(0, offset_x); EXPECT_DOUBLE_EQ(0, offset_y); - CalculateNonScaledClipBoxOffset(rect, 3, page_width, page_height, clip_box, + CalculateNonScaledClipBoxOffset(3, page_width, page_height, clip_box, &offset_x, &offset_y); EXPECT_DOUBLE_EQ(180, offset_x); EXPECT_DOUBLE_EQ(-180, offset_y); @@ -237,19 +236,19 @@ // Smaller |clip_box|. clip_box.top /= 4; clip_box.right /= 2; - CalculateNonScaledClipBoxOffset(rect, 0, page_width, page_height, clip_box, + CalculateNonScaledClipBoxOffset(0, page_width, page_height, clip_box, &offset_x, &offset_y); EXPECT_DOUBLE_EQ(0, offset_x); EXPECT_DOUBLE_EQ(594, offset_y); - CalculateNonScaledClipBoxOffset(rect, 1, page_width, page_height, clip_box, + CalculateNonScaledClipBoxOffset(1, page_width, page_height, clip_box, &offset_x, &offset_y); EXPECT_DOUBLE_EQ(0, offset_x); EXPECT_DOUBLE_EQ(0, offset_y); - CalculateNonScaledClipBoxOffset(rect, 2, page_width, page_height, clip_box, + CalculateNonScaledClipBoxOffset(2, page_width, page_height, clip_box, &offset_x, &offset_y); EXPECT_DOUBLE_EQ(306, offset_x); EXPECT_DOUBLE_EQ(0, offset_y); - CalculateNonScaledClipBoxOffset(rect, 3, page_width, page_height, clip_box, + CalculateNonScaledClipBoxOffset(3, page_width, page_height, clip_box, &offset_x, &offset_y); EXPECT_DOUBLE_EQ(486, offset_x); EXPECT_DOUBLE_EQ(414, offset_y); @@ -258,19 +257,19 @@ InitializeBoxToDefaultPortraitValues(&clip_box); page_width += 10; page_height += 20; - CalculateNonScaledClipBoxOffset(rect, 0, page_width, page_height, clip_box, + CalculateNonScaledClipBoxOffset(0, page_width, page_height, clip_box, &offset_x, &offset_y); EXPECT_DOUBLE_EQ(0, offset_x); EXPECT_DOUBLE_EQ(20, offset_y); - CalculateNonScaledClipBoxOffset(rect, 1, page_width, page_height, clip_box, + CalculateNonScaledClipBoxOffset(1, page_width, page_height, clip_box, &offset_x, &offset_y); EXPECT_DOUBLE_EQ(0, offset_x); EXPECT_DOUBLE_EQ(0, offset_y); - CalculateNonScaledClipBoxOffset(rect, 2, page_width, page_height, clip_box, + CalculateNonScaledClipBoxOffset(2, page_width, page_height, clip_box, &offset_x, &offset_y); EXPECT_DOUBLE_EQ(10, offset_x); EXPECT_DOUBLE_EQ(0, offset_y); - CalculateNonScaledClipBoxOffset(rect, 3, page_width, page_height, clip_box, + CalculateNonScaledClipBoxOffset(3, page_width, page_height, clip_box, &offset_x, &offset_y); EXPECT_DOUBLE_EQ(200, offset_x); EXPECT_DOUBLE_EQ(-170, offset_y); @@ -296,8 +295,8 @@ EXPECT_DOUBLE_EQ(0, offset_x); EXPECT_DOUBLE_EQ(792, offset_y); - CalculateNonScaledClipBoxOffset(rect, 0, page_width, page_height, - media_box_b491160, &offset_x, &offset_y); + CalculateNonScaledClipBoxOffset(0, page_width, page_height, media_box_b491160, + &offset_x, &offset_y); EXPECT_DOUBLE_EQ(0, offset_x); EXPECT_DOUBLE_EQ(792, offset_y); @@ -311,7 +310,7 @@ EXPECT_DOUBLE_EQ(0, offset_x); EXPECT_DOUBLE_EQ(0, offset_y); - CalculateNonScaledClipBoxOffset(rect, 0, page_width, page_height, clip_box, + CalculateNonScaledClipBoxOffset(0, page_width, page_height, clip_box, &offset_x, &offset_y); EXPECT_DOUBLE_EQ(0, offset_x); EXPECT_DOUBLE_EQ(0, offset_y); @@ -326,7 +325,7 @@ EXPECT_DOUBLE_EQ(0, offset_x); EXPECT_DOUBLE_EQ(0, offset_y); - CalculateNonScaledClipBoxOffset(rect, 0, page_width, page_height, clip_box, + CalculateNonScaledClipBoxOffset(0, page_width, page_height, clip_box, &offset_x, &offset_y); EXPECT_DOUBLE_EQ(0, offset_x); EXPECT_DOUBLE_EQ(0, offset_y);
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc index 272d97c..f9cf6db 100644 --- a/pdf/pdfium/pdfium_engine.cc +++ b/pdf/pdfium/pdfium_engine.cc
@@ -973,8 +973,8 @@ *page_index = page; PDFiumPage::Area result = pages_[page]->GetCharIndex( - point_in_page, layout_.default_page_orientation(), char_index, form_type, - target); + point_in_page, layout_.options().default_page_orientation(), char_index, + form_type, target); return (client_->IsPrintPreview() && result == PDFiumPage::WEBLINK_AREA) ? PDFiumPage::NONSELECTABLE_AREA : result; @@ -1818,7 +1818,7 @@ // Use zoom of 1.0 since |visible_rect| is without zoom. const std::vector<pp::Rect>& rects = find_results_[current_find_index_.value()].GetScreenRects( - pp::Point(), 1.0, layout_.default_page_orientation()); + pp::Point(), 1.0, layout_.options().default_page_orientation()); for (const auto& rect : rects) bounding_rect = bounding_rect.Union(rect); if (!visible_rect.Contains(bounding_rect)) { @@ -1865,8 +1865,9 @@ std::vector<pp::Rect>* rect_vector) const { for (const auto& range : rect_range) { pp::Rect result_rect; - const std::vector<pp::Rect>& rects = range.GetScreenRects( - offset_point, current_zoom_, layout_.default_page_orientation()); + const std::vector<pp::Rect>& rects = + range.GetScreenRects(offset_point, current_zoom_, + layout_.options().default_page_orientation()); for (const auto& rect : rects) result_rect = result_rect.Union(rect); rect_vector->push_back(result_rect); @@ -1889,12 +1890,12 @@ } void PDFiumEngine::RotateClockwise() { - layout_.RotatePagesClockwise(); + desired_layout_options_.RotatePagesClockwise(); RotateInternal(); } void PDFiumEngine::RotateCounterclockwise() { - layout_.RotatePagesCounterclockwise(); + desired_layout_options_.RotatePagesCounterclockwise(); RotateInternal(); } @@ -2391,19 +2392,21 @@ } } -void PDFiumEngine::LoadPagesInSingleView(std::vector<pp::Rect> page_rects, +// TODO(chinsenj): Merge with LoadPagesInTwoUpView(). +void PDFiumEngine::LoadPagesInSingleView(std::vector<pp::Size> page_sizes, bool reload) { - for (size_t i = 0; i < page_rects.size(); ++i) { - draw_utils::CenterRectHorizontally(layout_.size().width(), &page_rects[i]); - InsetPage(i, page_rects.size(), /*multiplier=*/1, &page_rects[i]); - AppendPageRectToPages(page_rects[i], i, reload); + std::vector<pp::Rect> single_view_layout = + layout_.GetSingleViewLayout(page_sizes); + + for (size_t i = 0; i < single_view_layout.size(); ++i) { + AppendPageRectToPages(single_view_layout[i], i, reload); } } -void PDFiumEngine::LoadPagesInTwoUpView(std::vector<pp::Rect> page_rects, +void PDFiumEngine::LoadPagesInTwoUpView(std::vector<pp::Size> page_sizes, bool reload) { std::vector<pp::Rect> two_up_view_layout = - layout_.GetTwoUpViewLayout(page_rects); + layout_.GetTwoUpViewLayout(page_sizes); for (size_t i = 0; i < two_up_view_layout.size(); ++i) { AppendPageRectToPages(two_up_view_layout[i], i, reload); @@ -2418,18 +2421,13 @@ pending_pages_.clear(); pp::Size old_document_size = layout_.size(); layout_.set_size(pp::Size()); - std::vector<pp::Rect> page_rects; + std::vector<pp::Size> page_sizes; size_t new_page_count = FPDF_GetPageCount(doc()); bool doc_complete = doc_loader_->IsDocumentComplete(); bool is_linear = FPDFAvail_IsLinearized(fpdf_availability()) == PDF_LINEARIZED; for (size_t i = 0; i < new_page_count; ++i) { - if (i != 0) { - // Add space for bottom separator. - layout_.EnlargeHeight(DocumentLayout::kBottomSeparator); - } - // Get page availability. If |reload| == true and the page is not new, // then the page has been constructed already. Get page availability flag // from already existing PDFiumPage object. @@ -2449,16 +2447,15 @@ pp::Size size = page_available ? GetPageSize(i) : default_page_size_; EnlargePage(i, new_page_count, &size); - pp::Rect rect(pp::Point(0, layout_.size().height()), size); - page_rects.push_back(rect); + page_sizes.push_back(size); - layout_.AppendPageRect(size); + layout_.set_size({std::max(layout_.size().width(), size.width()), 0}); } if (two_up_view_) { - LoadPagesInTwoUpView(std::move(page_rects), reload); + LoadPagesInTwoUpView(std::move(page_sizes), reload); } else { - LoadPagesInSingleView(std::move(page_rects), reload); + LoadPagesInSingleView(std::move(page_sizes), reload); } // Remove pages that do not exist anymore. @@ -2635,7 +2632,7 @@ ConvertUnitDouble(width_in_points, kPointsPerInch, kPixelsPerInch)); int height_in_pixels = static_cast<int>( ConvertUnitDouble(height_in_points, kPointsPerInch, kPixelsPerInch)); - if (layout_.default_page_orientation() % 2 == 1) + if (layout_.options().default_page_orientation() % 2 == 1) std::swap(width_in_pixels, height_in_pixels); size = pp::Size(width_in_pixels, height_in_pixels); } @@ -2732,7 +2729,8 @@ 0xFFFFFFFF); rv = FPDF_RenderPageBitmap_Start( new_bitmap.get(), page, start_x, start_y, size_x, size_y, - layout_.default_page_orientation(), GetRenderingFlags(), this); + layout_.options().default_page_orientation(), GetRenderingFlags(), + this); progressive_paints_[progressive_index].SetBitmapAndImageData( std::move(new_bitmap), *image_data); } @@ -2759,7 +2757,7 @@ // Draw the forms. FPDF_FFLDraw(form(), bitmap, pages_[page_index]->GetPage(), start_x, start_y, - size_x, size_y, layout_.default_page_orientation(), + size_x, size_y, layout_.options().default_page_orientation(), GetRenderingFlags()); FillPageSides(progressive_index); @@ -2890,7 +2888,7 @@ const std::vector<pp::Rect>& rects = range.GetScreenRects(visible_rect.point(), current_zoom_, - layout_.default_page_orientation()); + layout_.options().default_page_orientation()); for (const auto& rect : rects) { pp::Rect visible_selection = rect.Intersect(dirty_in_screen); if (visible_selection.IsEmpty()) @@ -3111,9 +3109,9 @@ if (!engine_->IsPageVisible(range.page_index())) continue; - const std::vector<pp::Rect>& selection_rects = - range.GetScreenRects(visible_point, engine_->current_zoom_, - engine_->layout_.default_page_orientation()); + const std::vector<pp::Rect>& selection_rects = range.GetScreenRects( + visible_point, engine_->current_zoom_, + engine_->layout_.options().default_page_orientation()); rects.insert(rects.end(), selection_rects.begin(), selection_rects.end()); } return rects; @@ -3172,8 +3170,9 @@ pages_[page_index]->rect().y()); FPDF_BOOL ret = FPDF_DeviceToPage( pages_[page_index]->GetPage(), 0, 0, pages_[page_index]->rect().width(), - pages_[page_index]->rect().height(), layout_.default_page_orientation(), - temp_x, temp_y, page_x, page_y); + pages_[page_index]->rect().height(), + layout_.options().default_page_orientation(), temp_x, temp_y, page_x, + page_y); DCHECK(ret); } @@ -3281,7 +3280,7 @@ for (const auto& sel : selection_) { const std::vector<pp::Rect>& screen_rects = sel.GetScreenRects(GetVisibleRect().point(), current_zoom_, - layout_.default_page_orientation()); + layout_.options().default_page_orientation()); for (const auto& rect : screen_rects) { if (IsAboveOrDirectlyLeftOf(rect, left)) left = rect; @@ -3306,6 +3305,7 @@ // Save the current page. int most_visible_page = most_visible_page_; + layout_.set_options(desired_layout_options_); InvalidateAllPages(); // Restore find results.
diff --git a/pdf/pdfium/pdfium_engine.h b/pdf/pdfium/pdfium_engine.h index c45a3d5..7e4c1d4 100644 --- a/pdf/pdfium/pdfium_engine.h +++ b/pdf/pdfium/pdfium_engine.h
@@ -239,13 +239,13 @@ size_t page_index, bool reload); - // Formats the pages of |page_rects| for single-view and appends them to + // Formats the pages of |page_sizes| for single-view and appends them to // |pages_|. - void LoadPagesInSingleView(std::vector<pp::Rect> page_rects, bool reload); + void LoadPagesInSingleView(std::vector<pp::Size> page_sizes, bool reload); - // Formats the pages of |page_rects| for two-up view and appends them to + // Formats the pages of |page_sizes| for two-up view and appends them to // |pages_|. - void LoadPagesInTwoUpView(std::vector<pp::Rect> page_rects, bool reload); + void LoadPagesInTwoUpView(std::vector<pp::Size> page_sizes, bool reload); // Loads information about the pages in the document and calculate the // document size. @@ -529,6 +529,9 @@ // The current document layout. DocumentLayout layout_; + // The options for the desired document layout. + DocumentLayout::Options desired_layout_options_; + // The scroll position in screen coordinates. pp::Point position_; // The offset of the page into the viewport.
diff --git a/pdf/pdfium/pdfium_form_filler.cc b/pdf/pdfium/pdfium_form_filler.cc index 8483efd5..70022a81 100644 --- a/pdf/pdfium/pdfium_form_filler.cc +++ b/pdf/pdfium/pdfium_form_filler.cc
@@ -100,7 +100,7 @@ pp::Rect rect = engine->pages_[page_index]->PageToScreen( engine->GetVisibleRect().point(), engine->current_zoom_, left, top, right, - bottom, engine->layout_.default_page_orientation()); + bottom, engine->layout_.options().default_page_orientation()); engine->client_->Invalidate(rect); } @@ -119,7 +119,7 @@ } pp::Rect rect = engine->pages_[page_index]->PageToScreen( engine->GetVisibleRect().point(), engine->current_zoom_, left, top, right, - bottom, engine->layout_.default_page_orientation()); + bottom, engine->layout_.options().default_page_orientation()); if (rect.IsEmpty()) return;
diff --git a/pdf/pdfium/pdfium_permissions.cc b/pdf/pdfium/pdfium_permissions.cc index 08dba8a..71b32e4 100644 --- a/pdf/pdfium/pdfium_permissions.cc +++ b/pdf/pdfium/pdfium_permissions.cc
@@ -6,21 +6,22 @@ namespace chrome_pdf { -namespace { - -// See Table 3.20 in -// http://www.adobe.com/devnet/acrobat/pdfs/pdf_reference_1-7.pdf -constexpr uint32_t kPDFPermissionPrintLowQualityMask = 1 << 2; -constexpr uint32_t kPDFPermissionPrintHighQualityMask = 1 << 11; -constexpr uint32_t kPDFPermissionCopyMask = 1 << 4; -constexpr uint32_t kPDFPermissionCopyAccessibleMask = 1 << 9; - -} // namespace +// static +PDFiumPermissions PDFiumPermissions::CreateForTesting( + int permissions_handler_revision, + unsigned long permission_bits) { + return PDFiumPermissions(permissions_handler_revision, permission_bits); +} PDFiumPermissions::PDFiumPermissions(FPDF_DOCUMENT doc) : permissions_handler_revision_(FPDF_GetSecurityHandlerRevision(doc)), permission_bits_(FPDF_GetDocPermissions(doc)) {} +PDFiumPermissions::PDFiumPermissions(int permissions_handler_revision, + unsigned long permission_bits) + : permissions_handler_revision_(permissions_handler_revision), + permission_bits_(permission_bits) {} + bool PDFiumPermissions::HasPermission( PDFEngine::DocumentPermission permission) const { // PDF 1.7 spec, section 3.5.2 says: "If the revision number is 2 or greater,
diff --git a/pdf/pdfium/pdfium_permissions.h b/pdf/pdfium/pdfium_permissions.h index 19523ee4..137bbdd 100644 --- a/pdf/pdfium/pdfium_permissions.h +++ b/pdf/pdfium/pdfium_permissions.h
@@ -10,14 +10,28 @@ namespace chrome_pdf { +// See Table 3.20 in the PDF 1.7 spec for details on how to interpret permission +// bits. Exposed for use in testing. +constexpr uint32_t kPDFPermissionPrintLowQualityMask = 1 << 2; +constexpr uint32_t kPDFPermissionPrintHighQualityMask = 1 << 11; +constexpr uint32_t kPDFPermissionCopyMask = 1 << 4; +constexpr uint32_t kPDFPermissionCopyAccessibleMask = 1 << 9; + // The permissions for a given FPDF_DOCUMENT. class PDFiumPermissions final { public: + static PDFiumPermissions CreateForTesting(int permissions_handler_revision, + unsigned long permission_bits); + explicit PDFiumPermissions(FPDF_DOCUMENT doc); bool HasPermission(PDFEngine::DocumentPermission permission) const; private: + // For unit tests. + PDFiumPermissions(int permissions_handler_revision, + unsigned long permission_bits); + // Permissions security handler revision number. -1 for unknown. const int permissions_handler_revision_;
diff --git a/pdf/pdfium/pdfium_permissions_unittest.cc b/pdf/pdfium/pdfium_permissions_unittest.cc new file mode 100644 index 0000000..d1edd19 --- /dev/null +++ b/pdf/pdfium/pdfium_permissions_unittest.cc
@@ -0,0 +1,158 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "pdf/pdfium/pdfium_permissions.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace chrome_pdf { + +namespace { + +constexpr auto kPermCopy = PDFEngine::PERMISSION_COPY; +constexpr auto kPermCopya11y = PDFEngine::PERMISSION_COPY_ACCESSIBLE; +constexpr auto kPermPrintHigh = PDFEngine::PERMISSION_PRINT_HIGH_QUALITY; +constexpr auto kPermPrintLow = PDFEngine::PERMISSION_PRINT_LOW_QUALITY; + +constexpr uint32_t GeneratePermissions2(uint32_t permissions) { + constexpr uint32_t kBasePermissions = 0xffffffc0; + return kBasePermissions | permissions; +} + +constexpr uint32_t GeneratePermissions3(uint32_t permissions) { + constexpr uint32_t kBasePermissions = 0xfffff0c0; + return kBasePermissions | permissions; +} + +// Sanity check the permission constants are correct. +static_assert(kPDFPermissionCopyAccessibleMask == 0x200, "Wrong permission"); +static_assert(kPDFPermissionCopyMask == 0x10, "Wrong permission"); +static_assert(kPDFPermissionPrintHighQualityMask == 0x800, "Wrong permission"); +static_assert(kPDFPermissionPrintLowQualityMask == 0x4, "Wrong permission"); + +// Sanity check the permission generation functions above do the right thing. +static_assert(GeneratePermissions2(0) == 0xffffffc0, "Wrong permission"); +static_assert(GeneratePermissions2(kPDFPermissionCopyMask | + kPDFPermissionPrintLowQualityMask) == + 0xffffffd4, + "Wrong permission"); +static_assert(GeneratePermissions3(0) == 0xfffff0c0, "Wrong permission"); +static_assert(GeneratePermissions3(kPDFPermissionCopyAccessibleMask | + kPDFPermissionCopyMask | + kPDFPermissionPrintHighQualityMask | + kPDFPermissionPrintLowQualityMask) == + 0xfffffad4, + "Wrong permission"); + +TEST(PDFiumPermissionTest, InvalidSecurityHandler) { + constexpr int kPDFiumUnknownRevision = -1; + constexpr uint32_t kNoPermissions = 0; + auto unknown_perms = PDFiumPermissions::CreateForTesting( + kPDFiumUnknownRevision, kNoPermissions); + EXPECT_TRUE(unknown_perms.HasPermission(kPermCopy)); + EXPECT_TRUE(unknown_perms.HasPermission(kPermCopya11y)); + EXPECT_TRUE(unknown_perms.HasPermission(kPermPrintLow)); + EXPECT_TRUE(unknown_perms.HasPermission(kPermPrintHigh)); + + constexpr int kInvalidRevision = 1; + auto obsolete_perms = + PDFiumPermissions::CreateForTesting(kInvalidRevision, kNoPermissions); + EXPECT_TRUE(obsolete_perms.HasPermission(kPermCopy)); + EXPECT_TRUE(obsolete_perms.HasPermission(kPermCopya11y)); + EXPECT_TRUE(obsolete_perms.HasPermission(kPermPrintLow)); + EXPECT_TRUE(obsolete_perms.HasPermission(kPermPrintHigh)); +} + +TEST(PDFiumPermissionTest, Revision2SecurityHandler) { + uint32_t permissions = GeneratePermissions2(0); + auto no_perms = PDFiumPermissions::CreateForTesting(2, permissions); + EXPECT_FALSE(no_perms.HasPermission(kPermCopy)); + // TODO(crbug.com/989408) Should be the same as |PERMISSION_COPY|. + EXPECT_TRUE(no_perms.HasPermission(kPermCopya11y)); + EXPECT_FALSE(no_perms.HasPermission(kPermPrintLow)); + EXPECT_FALSE(no_perms.HasPermission(kPermPrintHigh)); + + permissions = GeneratePermissions2(kPDFPermissionCopyMask | + kPDFPermissionPrintLowQualityMask); + auto all_known_perms = PDFiumPermissions::CreateForTesting(2, permissions); + EXPECT_TRUE(all_known_perms.HasPermission(kPermCopy)); + EXPECT_TRUE(all_known_perms.HasPermission(kPermCopya11y)); + EXPECT_TRUE(all_known_perms.HasPermission(kPermPrintLow)); + EXPECT_TRUE(all_known_perms.HasPermission(kPermPrintHigh)); + + permissions = GeneratePermissions2(kPDFPermissionCopyMask); + auto no_print_perms = PDFiumPermissions::CreateForTesting(2, permissions); + EXPECT_TRUE(no_print_perms.HasPermission(kPermCopy)); + EXPECT_TRUE(no_print_perms.HasPermission(kPermCopya11y)); + EXPECT_FALSE(no_print_perms.HasPermission(kPermPrintLow)); + EXPECT_FALSE(no_print_perms.HasPermission(kPermPrintHigh)); + + permissions = GeneratePermissions2(kPDFPermissionPrintLowQualityMask); + auto no_copy_perms = PDFiumPermissions::CreateForTesting(2, permissions); + EXPECT_FALSE(no_copy_perms.HasPermission(kPermCopy)); + // TODO(crbug.com/989408) Should be the same as |PERMISSION_COPY|. + EXPECT_TRUE(no_copy_perms.HasPermission(kPermCopya11y)); + EXPECT_TRUE(no_copy_perms.HasPermission(kPermPrintLow)); + EXPECT_TRUE(no_copy_perms.HasPermission(kPermPrintHigh)); +} + +TEST(PDFiumPermissionTest, Revision3SecurityHandler) { + uint32_t permissions = GeneratePermissions3(0); + auto no_perms = PDFiumPermissions::CreateForTesting(3, permissions); + EXPECT_FALSE(no_perms.HasPermission(kPermCopy)); + EXPECT_FALSE(no_perms.HasPermission(kPermCopya11y)); + EXPECT_FALSE(no_perms.HasPermission(kPermPrintLow)); + EXPECT_FALSE(no_perms.HasPermission(kPermPrintHigh)); + + permissions = GeneratePermissions3( + kPDFPermissionCopyAccessibleMask | kPDFPermissionCopyMask | + kPDFPermissionPrintHighQualityMask | kPDFPermissionPrintLowQualityMask); + auto all_known_perms = PDFiumPermissions::CreateForTesting(3, permissions); + EXPECT_TRUE(all_known_perms.HasPermission(kPermCopy)); + EXPECT_TRUE(all_known_perms.HasPermission(kPermCopya11y)); + EXPECT_TRUE(all_known_perms.HasPermission(kPermPrintLow)); + EXPECT_TRUE(all_known_perms.HasPermission(kPermPrintHigh)); + + permissions = GeneratePermissions3(kPDFPermissionCopyAccessibleMask | + kPDFPermissionCopyMask); + auto copy_no_print_perms = + PDFiumPermissions::CreateForTesting(3, permissions); + EXPECT_TRUE(copy_no_print_perms.HasPermission(kPermCopy)); + EXPECT_TRUE(copy_no_print_perms.HasPermission(kPermCopya11y)); + EXPECT_FALSE(copy_no_print_perms.HasPermission(kPermPrintLow)); + EXPECT_FALSE(copy_no_print_perms.HasPermission(kPermPrintHigh)); + + permissions = GeneratePermissions3(kPDFPermissionCopyAccessibleMask | + kPDFPermissionCopyMask | + kPDFPermissionPrintLowQualityMask); + auto copy_low_print_perms = + PDFiumPermissions::CreateForTesting(3, permissions); + EXPECT_TRUE(copy_low_print_perms.HasPermission(kPermCopy)); + EXPECT_TRUE(copy_low_print_perms.HasPermission(kPermCopya11y)); + EXPECT_TRUE(copy_low_print_perms.HasPermission(kPermPrintLow)); + EXPECT_FALSE(copy_low_print_perms.HasPermission(kPermPrintHigh)); + + permissions = GeneratePermissions3(kPDFPermissionPrintHighQualityMask | + kPDFPermissionPrintLowQualityMask); + auto print_no_copy_perms = + PDFiumPermissions::CreateForTesting(3, permissions); + EXPECT_FALSE(print_no_copy_perms.HasPermission(kPermCopy)); + EXPECT_FALSE(print_no_copy_perms.HasPermission(kPermCopya11y)); + EXPECT_TRUE(print_no_copy_perms.HasPermission(kPermPrintLow)); + EXPECT_TRUE(print_no_copy_perms.HasPermission(kPermPrintHigh)); + + permissions = GeneratePermissions3(kPDFPermissionCopyAccessibleMask | + kPDFPermissionPrintHighQualityMask | + kPDFPermissionPrintLowQualityMask); + auto print_a11y_copy_perms = + PDFiumPermissions::CreateForTesting(3, permissions); + EXPECT_FALSE(print_a11y_copy_perms.HasPermission(kPermCopy)); + EXPECT_TRUE(print_a11y_copy_perms.HasPermission(kPermCopya11y)); + EXPECT_TRUE(print_a11y_copy_perms.HasPermission(kPermPrintLow)); + EXPECT_TRUE(print_a11y_copy_perms.HasPermission(kPermPrintHigh)); +} + +} // namespace + +} // namespace chrome_pdf
diff --git a/pdf/pdfium/pdfium_print.cc b/pdf/pdfium/pdfium_print.cc index 042bb20..9a185799 100644 --- a/pdf/pdfium/pdfium_print.cc +++ b/pdf/pdfium/pdfium_print.cc
@@ -118,9 +118,9 @@ CalculateScaledClipBoxOffset(gfx_content_rect, source_clip_box, &offset_x, &offset_y); } else { - CalculateNonScaledClipBoxOffset(gfx_content_rect, src_page_rotation, - actual_page_width, actual_page_height, - source_clip_box, &offset_x, &offset_y); + CalculateNonScaledClipBoxOffset(src_page_rotation, actual_page_width, + actual_page_height, source_clip_box, + &offset_x, &offset_y); } // Reset the media box and crop box. When the page has crop box and media box,
diff --git a/sandbox/win/src/broker_services.cc b/sandbox/win/src/broker_services.cc index ae7d15d..b39170c 100644 --- a/sandbox/win/src/broker_services.cc +++ b/sandbox/win/src/broker_services.cc
@@ -518,9 +518,4 @@ return SBOX_ALL_OK; } -bool BrokerServicesBase::IsActiveTarget(DWORD process_id) { - AutoLock lock(&lock_); - return child_process_ids_.find(process_id) != child_process_ids_.end(); -} - } // namespace sandbox
diff --git a/sandbox/win/src/broker_services.h b/sandbox/win/src/broker_services.h index bc9cb70..701d29a 100644 --- a/sandbox/win/src/broker_services.h +++ b/sandbox/win/src/broker_services.h
@@ -55,12 +55,6 @@ PROCESS_INFORMATION* target) override; ResultCode WaitForAllTargets() override; - // Checks if the supplied process ID matches one of the broker's active - // target processes - // Returns: - // true if there is an active target process for this ID, otherwise false. - bool IsActiveTarget(DWORD process_id); - private: // The routine that the worker thread executes. It is in charge of // notifications and cleanup-related tasks.
diff --git a/services/data_decoder/bundled_exchanges_parser.cc b/services/data_decoder/bundled_exchanges_parser.cc index 93c91b4..f3ea3b1 100644 --- a/services/data_decoder/bundled_exchanges_parser.cc +++ b/services/data_decoder/bundled_exchanges_parser.cc
@@ -542,7 +542,6 @@ weak_factory_.GetWeakPtr(), index_section_length)); } - // Step 1. of // https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html#index-section void ParseIndexSection(uint64_t expected_data_length, const base::Optional<std::vector<uint8_t>>& data) { @@ -562,170 +561,131 @@ RunErrorCallbackAndDestroy("Error parsing index section."); return; } - if (!index_section_value->is_array()) { - RunErrorCallbackAndDestroy("Index section must be an array."); + if (!index_section_value->is_map()) { + RunErrorCallbackAndDestroy("Index section must be a map."); return; } - // Read the header of the response section. + // Step 2. "Let requests be an initially-empty map ([INFRA]) from URLs to + // response descriptions, each of which is either a single + // location-in-stream value or a pair of a Variants header field value + // ([I-D.ietf-httpbis-variants]) and a map from that value's possible + // Variant-Keys to location-in-stream values, as described in Section 2.2." + base::flat_map<GURL, mojom::BundleIndexValuePtr> requests; + + // Step 3. "Let MakeRelativeToStream be a function that takes a + // location-in-responses value (offset, length) and returns a + // ResponseMetadata struct or error by running the following + // sub-steps:" + // The logic of MakeRelativeToStream is inlined at the callsite below. auto responses_section = section_offsets_.find(kResponsesSection); DCHECK(responses_section != section_offsets_.end()); const uint64_t responses_section_offset = responses_section->second.first; const uint64_t responses_section_length = responses_section->second.second; - const uint64_t length = - std::min(responses_section_length, kMaxCBORItemHeaderSize); - data_source_->Read( - responses_section_offset, length, - base::BindOnce(&MetadataParser::ParseResponsesSectionHeader, - weak_factory_.GetWeakPtr(), - std::move(*index_section_value), length)); - } + // Step 4. "For each (url, responses) entry in the index map:" + for (const auto& item : index_section_value->GetMap()) { + if (!item.first.is_string()) { + RunErrorCallbackAndDestroy("Index section: key must be a string."); + return; + } + if (!item.second.is_array()) { + RunErrorCallbackAndDestroy("Index section: value must be an array."); + return; + } + const std::string& url = item.first.GetString(); + const cbor::Value::ArrayValue& responses_array = item.second.GetArray(); - // Step 2- of - // https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html#index-section - void ParseResponsesSectionHeader( - cbor::Value index_section_value, - uint64_t expected_data_length, - const base::Optional<std::vector<uint8_t>>& data) { - const cbor::Value::ArrayValue& index_section_array = - index_section_value.GetArray(); - - // Step 2.1. "Seek to offset sectionOffsets["responses"].offset in stream. - // If this fails, return an error." - if (!data || data->size() != expected_data_length) { - RunErrorCallbackAndDestroy("Error reading responses section header."); - return; - } - InputReader input(*data); - - // Step 2.2. "Let (responsesType, numResponses) be the result of parsing the - // type and argument of a CBOR item from the stream (Section 3.5.3). If this - // returns an error, return that error." - auto num_responses = input.ReadCBORHeader(CBORType::kArray); - if (!num_responses) { - RunErrorCallbackAndDestroy( - "Cannot parse the number of elements of the responses section."); - return; - } - // Step 2.3. "If responsesType is not 4 (a CBOR array) or numResponses is - // not half of the length of index, return an error." - if (index_section_array.size() % 2 != 0 || - *num_responses != index_section_array.size() / 2) { - RunErrorCallbackAndDestroy( - "Wrong number of elements in the responses section."); - return; - } - - // Step 3. "Let currentOffset be the current offset within stream minus - // sectionOffsets["responses"].offset." - uint64_t current_offset = input.CurrentOffset(); - - // Step 4. "Let requests be an initially-empty map ([INFRA]) from HTTP - // requests ([FETCH]) to structs ([INFRA]) with items named "offset" and - // "length"." - - // Step 5. "For each (cbor-http-request, length) pair of adjacent elements - // in index:" - for (size_t i = 0; i < index_section_array.size(); i += 2) { - const cbor::Value& cbor_http_request_value = index_section_array[i]; - const cbor::Value& length_value = index_section_array[i + 1]; - - // Step 5.1. "Let (headers, pseudos) be the result of converting - // cbor-http-request to a header list and pseudoheaders using the - // algorithm in Section 3.6. If this returns an error, return that error." - auto parsed_headers = ConvertCBORValueToHeaders(cbor_http_request_value); - if (!parsed_headers) { + // Step 4.1. "Let parsedUrl be the result of parsing ([URL]) url with no + // base URL." + if (!base::IsStringUTF8(url)) { RunErrorCallbackAndDestroy( - "Cannot parse headers in the index section."); + "Index section: URL must be a valid UTF-8 string."); return; } + GURL parsed_url(url); - // Step 5.2. "If pseudos does not have keys named ':method' and - // ':url', or its size isn't 2, return an error." - const auto pseudo_method = parsed_headers->pseudos.find(":method"); - const auto pseudo_url = parsed_headers->pseudos.find(":url"); - if (parsed_headers->pseudos.size() != 2 || - pseudo_method == parsed_headers->pseudos.end() || - pseudo_url == parsed_headers->pseudos.end()) { - RunErrorCallbackAndDestroy( - "Request headers map must have exactly two pseudo-headers, :method " - "and :url."); - return; - } - - // Step 5.3. "If pseudos[':method'] is not 'GET', return an error." - if (pseudo_method->second != "GET") { - RunErrorCallbackAndDestroy("Request method must be GET."); - return; - } - - // Step 5.4. "Let parsedUrl be the result of parsing ([URL]) - // pseudos[':url'] with no base URL." - GURL parsed_url(pseudo_url->second); - - // Step 5.5. "If parsedUrl is a failure, its fragment is not null, or it + // Step 4.2. "If parsedUrl is a failure, its fragment is not null, or it // includes credentials, return an error." if (!parsed_url.is_valid() || parsed_url.has_ref() || parsed_url.has_username() || parsed_url.has_password()) { RunErrorCallbackAndDestroy( - ":url in header map must be a valid URL without fragment or " - "credentials."); + "Index section: exchange URL must be a valid URL without fragment " + "or credentials."); return; } - // Step 5.6. "Let http-request be a new request ([FETCH]) whose: - // - method is pseudos[':method'], - // - url is parsedUrl, - // - header list is headers, and - // - client is null." - mojom::BundleIndexItemPtr item = mojom::BundleIndexItem::New(); - item->request_method = pseudo_method->second; - item->request_url = std::move(parsed_url); - item->request_headers = std::move(parsed_headers->headers); - - // Step 5.7. "Let responseOffset be sectionOffsets["responses"].offset + - // currentOffset. This is relative to the start of the stream." - const uint64_t response_offset = - section_offsets_[kResponsesSection].first + current_offset; - - // Step 5.8. "If currentOffset + length is greater than - // sectionOffsets["responses"].length, return an error." - if (!length_value.is_unsigned()) { + // Step 4.3. "If the first element of responses is the empty string:" + if (responses_array.empty() || !responses_array[0].is_bytestring()) { RunErrorCallbackAndDestroy( - "Length value in the index section should be an unsigned."); + "Index section: the first element of responses array must be a " + "bytestring."); return; } - const uint64_t length = length_value.GetUnsigned(); - - uint64_t response_end; - if (!base::CheckAdd(current_offset, length) - .AssignIfValid(&response_end) || - response_end > section_offsets_[kResponsesSection].second) { - RunErrorCallbackAndDestroy( - "Index map is invalid: total length of responses exceeds the " - "length of the responses section."); - return; + base::StringPiece variants_value = + responses_array[0].GetBytestringAsString(); + if (variants_value.empty()) { + // Step 4.3.1. "If the length of responses is not 3 (i.e. there is more + // than one location-in-responses in responses), return an error." + if (responses_array.size() != 3) { + RunErrorCallbackAndDestroy( + "Index section: unexpected size of responses array."); + return; + } + } else { + // Step 4.4. "Otherwise:" + // TODO(crbug.com/969596): Parse variants_value to compute the number of + // variantKeys, and check that responses_array has + // (2 * #variantKeys + 1) elements. + if (responses_array.size() < 3 || responses_array.size() % 2 != 1) { + RunErrorCallbackAndDestroy( + "Index section: unexpected size of responses array."); + return; + } } + // Instead of constructing a map from Variant-Keys to location-in-stream, + // this implementation just returns the responses array's structure as + // a BundleIndexValue. + std::vector<mojom::BundleResponseLocationPtr> response_locations; + for (size_t i = 1; i < responses_array.size(); i += 2) { + if (!responses_array[i].is_unsigned() || + !responses_array[i + 1].is_unsigned()) { + RunErrorCallbackAndDestroy( + "Index section: offset and length values must be unsigned."); + return; + } + uint64_t offset = responses_array[i].GetUnsigned(); + uint64_t length = responses_array[i + 1].GetUnsigned(); - // Step 5.9. "If requests[http-request] exists, return an error. That is, - // duplicate requests are forbidden." + // MakeRelativeToStream (Step 3.) is inlined here. + // Step 3.1. "If offset + length is larger than + // sectionOffsets["responses"].length, return an error." + uint64_t response_end; + if (!base::CheckAdd(offset, length).AssignIfValid(&response_end) || + response_end > responses_section_length) { + RunErrorCallbackAndDestroy("Index section: response out of range."); + return; + } + // Step 3.2. "Otherwise, return a ResponseMetadata struct whose offset + // is sectionOffsets["responses"].offset + offset and whose length is + // length." - // TODO(crbug.com/966753): Implement this check. + // This doesn't wrap because (offset <= responses_section_length) and + // (responses_section_offset + responses_section_length) doesn't wrap. + uint64_t offset_within_stream = responses_section_offset + offset; - // Step 5.10. "Set requests[http-request] to a struct whose "offset" - // item is responseOffset and whose "length" item is length." - item->response_offset = response_offset; - item->response_length = length; - items_.push_back(std::move(item)); - - // Step 5.11. "Set currentOffset to currentOffset + length." - current_offset = response_end; + response_locations.push_back( + mojom::BundleResponseLocation::New(offset_within_stream, length)); + } + requests.insert(std::make_pair( + parsed_url, + mojom::BundleIndexValue::New(variants_value.as_string(), + std::move(response_locations)))); } // We're done. RunSuccessCallbackAndDestroy(mojom::BundleMetadata::New( - fallback_url_, std::move(items_), manifest_url_)); + fallback_url_, std::move(requests), manifest_url_)); } void RunSuccessCallbackAndDestroy(mojom::BundleMetadataPtr metadata) { @@ -756,7 +716,6 @@ GURL fallback_url_; // name -> (offset, length) std::map<std::string, std::pair<uint64_t, uint64_t>> section_offsets_; - std::vector<mojom::BundleIndexItemPtr> items_; GURL manifest_url_; base::WeakPtrFactory<MetadataParser> weak_factory_{this};
diff --git a/services/data_decoder/bundled_exchanges_parser_factory_unittest.cc b/services/data_decoder/bundled_exchanges_parser_factory_unittest.cc index d307fe4..814d210c 100644 --- a/services/data_decoder/bundled_exchanges_parser_factory_unittest.cc +++ b/services/data_decoder/bundled_exchanges_parser_factory_unittest.cc
@@ -167,35 +167,35 @@ run_loop.Run(); } ASSERT_TRUE(metadata); - ASSERT_EQ(metadata->index.size(), 4u); + ASSERT_EQ(metadata->requests.size(), 4u); - const auto& index = metadata->index; - - std::vector<mojom::BundleResponsePtr> responses; - for (size_t i = 0; i < index.size(); i++) { + std::map<std::string, mojom::BundleResponsePtr> responses; + for (const auto& item : metadata->requests) { + ASSERT_TRUE(item.second->variants_value.empty()); + ASSERT_EQ(item.second->response_locations.size(), 1u); base::RunLoop run_loop; - parser->ParseResponse( - index[i]->response_offset, index[i]->response_length, - base::BindLambdaForTesting( - [&responses, &run_loop](mojom::BundleResponsePtr response, - mojom::BundleResponseParseErrorPtr error) { - ASSERT_TRUE(response); - ASSERT_FALSE(error); - responses.push_back(std::move(response)); - run_loop.QuitClosure().Run(); - })); + parser->ParseResponse(item.second->response_locations[0]->offset, + item.second->response_locations[0]->length, + base::BindLambdaForTesting( + [&item, &responses, &run_loop]( + mojom::BundleResponsePtr response, + mojom::BundleResponseParseErrorPtr error) { + ASSERT_TRUE(response); + ASSERT_FALSE(error); + responses[item.first.spec()] = + std::move(response); + run_loop.QuitClosure().Run(); + })); run_loop.Run(); } - EXPECT_EQ(index[0]->request_url, "https://test.example.org/"); - EXPECT_EQ(index[0]->request_method, "GET"); - EXPECT_EQ(index[0]->request_headers.size(), 0u); - EXPECT_EQ(responses[0]->response_code, 200); - EXPECT_EQ(responses[0]->response_headers["content-type"], - "text/html; charset=utf-8"); - EXPECT_EQ(index[1]->request_url, "https://test.example.org/index.html"); - EXPECT_EQ(index[2]->request_url, - "https://test.example.org/manifest.webmanifest"); - EXPECT_EQ(index[3]->request_url, "https://test.example.org/script.js"); + ASSERT_TRUE(responses["https://test.example.org/"]); + EXPECT_EQ(responses["https://test.example.org/"]->response_code, 200); + EXPECT_EQ( + responses["https://test.example.org/"]->response_headers["content-type"], + "text/html; charset=utf-8"); + EXPECT_TRUE(responses["https://test.example.org/index.html"]); + EXPECT_TRUE(responses["https://test.example.org/manifest.webmanifest"]); + EXPECT_TRUE(responses["https://test.example.org/script.js"]); } } // namespace data_decoder
diff --git a/services/data_decoder/bundled_exchanges_parser_fuzzer.cc b/services/data_decoder/bundled_exchanges_parser_fuzzer.cc index 1ee19cb..c6f4b38 100644 --- a/services/data_decoder/bundled_exchanges_parser_fuzzer.cc +++ b/services/data_decoder/bundled_exchanges_parser_fuzzer.cc
@@ -76,19 +76,21 @@ std::move(quit_loop_).Run(); return; } - metadata_ = std::move(metadata); + for (const auto& item : metadata->requests) { + for (auto& resp_location : item.second->response_locations) + locations_.push_back(std::move(resp_location)); + } ParseResponses(0); } void ParseResponses(size_t index) { - if (index >= metadata_->index.size()) { + if (index >= locations_.size()) { std::move(quit_loop_).Run(); return; } parser_->ParseResponse( - metadata_->index[index]->response_offset, - metadata_->index[index]->response_length, + locations_[index]->offset, locations_[index]->length, base::Bind(&BundledExchangesParserFuzzer::OnParseResponse, base::Unretained(this), index)); } @@ -103,7 +105,7 @@ mojo::Remote<data_decoder::mojom::BundledExchangesParser> parser_; DataSource data_source_; base::Closure quit_loop_; - data_decoder::mojom::BundleMetadataPtr metadata_; + std::vector<data_decoder::mojom::BundleResponseLocationPtr> locations_; }; struct Environment {
diff --git a/services/data_decoder/bundled_exchanges_parser_unittest.cc b/services/data_decoder/bundled_exchanges_parser_unittest.cc index 24cb78b..c29edeea 100644 --- a/services/data_decoder/bundled_exchanges_parser_unittest.cc +++ b/services/data_decoder/bundled_exchanges_parser_unittest.cc
@@ -96,8 +96,26 @@ EXPECT_EQ(result.second->fallback_url, kFallbackUrl); } -mojom::BundleResponsePtr ParseResponse(TestDataSource* data_source, - const mojom::BundleIndexItemPtr& item) { +// Finds the only response for |url|. The index entry for |url| must not have +// variants-value. +mojom::BundleResponseLocationPtr FindResponse( + const mojom::BundleMetadataPtr& metadata, + const GURL& url) { + const auto item = metadata->requests.find(url); + if (item == metadata->requests.end()) + return nullptr; + + const mojom::BundleIndexValuePtr& index_value = item->second; + EXPECT_TRUE(index_value->variants_value.empty()); + EXPECT_EQ(index_value->response_locations.size(), 1u); + if (index_value->response_locations.empty()) + return nullptr; + return index_value->response_locations[0].Clone(); +} + +mojom::BundleResponsePtr ParseResponse( + TestDataSource* data_source, + const mojom::BundleResponseLocationPtr& location) { mojo::PendingRemote<mojom::BundleDataSource> source_remote; data_source->AddReceiver(source_remote.InitWithNewPipeAndPassReceiver()); @@ -109,7 +127,7 @@ base::RunLoop run_loop; mojom::BundleResponsePtr result; parser.ParseResponse( - item->response_offset, item->response_length, + location->offset, location->length, base::BindLambdaForTesting( [&result, &run_loop](mojom::BundleResponsePtr response, mojom::BundleResponseParseErrorPtr error) { @@ -123,23 +141,52 @@ class BundleBuilder { public: using Headers = std::vector<std::pair<std::string, std::string>>; + struct ResponseLocation { + // /components/cbor uses int64_t for integer types. + int64_t offset; + int64_t length; + }; explicit BundleBuilder(const std::string& fallback_url) : fallback_url_(fallback_url) { writer_config_.allow_invalid_utf8_for_testing = true; } - void AddExchange(const Headers& request_headers, + void AddExchange(base::StringPiece url, const Headers& response_headers, base::StringPiece payload) { + AddIndexEntry(url, "", {AddResponse(response_headers, payload)}); + } + + ResponseLocation AddResponse(const Headers& headers, + base::StringPiece payload) { + // We assume that the size of the CBOR header of the responses array is 1, + // which is true only if the responses array has no more than 23 elements. + EXPECT_LT(responses_.size(), 23u) + << "BundleBuilder cannot create bundles with more than 23 responses"; + cbor::Value::ArrayValue response_array; - response_array.emplace_back(Encode(CreateHeaderMap(response_headers))); + response_array.emplace_back(Encode(CreateHeaderMap(headers))); response_array.emplace_back(CreateByteString(payload)); cbor::Value response(response_array); - - index_.emplace_back(CreateHeaderMap(request_headers)); - index_.emplace_back(EncodedLength(response)); + int64_t response_length = EncodedLength(response); + ResponseLocation result = {current_responses_offset_, response_length}; + current_responses_offset_ += response_length; responses_.emplace_back(std::move(response)); + return result; + } + + void AddIndexEntry(base::StringPiece url, + base::StringPiece variants_value, + std::vector<ResponseLocation> response_locations) { + cbor::Value::ArrayValue index_value_array; + index_value_array.emplace_back(CreateByteString(variants_value)); + for (const auto& location : response_locations) { + index_value_array.emplace_back(location.offset); + index_value_array.emplace_back(location.length); + } + index_.insert({cbor::Value::InvalidUTF8StringValueForTesting(url), + cbor::Value(index_value_array)}); } void AddSection(base::StringPiece name, cbor::Value section) { @@ -192,8 +239,11 @@ std::string fallback_url_; cbor::Value::ArrayValue section_lengths_; cbor::Value::ArrayValue sections_; - cbor::Value::ArrayValue index_; + cbor::Value::MapValue index_; cbor::Value::ArrayValue responses_; + + // 1 for the CBOR header byte. See the comment at the top of AddResponse(). + int64_t current_responses_offset_ = 1; }; } // namespace @@ -209,9 +259,7 @@ mojom::BundleMetadataPtr metadata = ParseBundle(&data_source).first; ASSERT_TRUE(metadata); - const auto& index = metadata->index; - - ASSERT_EQ(index.size(), 0u); + ASSERT_EQ(metadata->requests.size(), 0u); } TEST_F(BundledExchangeParserTest, WrongMagic) { @@ -271,22 +319,18 @@ TEST_F(BundledExchangeParserTest, SingleEntry) { BundleBuilder builder(kFallbackUrl); - builder.AddExchange( - {{":method", "GET"}, {":url", "https://test.example.com/"}}, - {{":status", "200"}, {"content-type", "text/plain"}}, "payload"); + builder.AddExchange("https://test.example.com/", + {{":status", "200"}, {"content-type", "text/plain"}}, + "payload"); TestDataSource data_source(builder.CreateBundle()); mojom::BundleMetadataPtr metadata = ParseBundle(&data_source).first; ASSERT_TRUE(metadata); - const auto& index = metadata->index; - - ASSERT_EQ(index.size(), 1u); - auto response = ParseResponse(&data_source, index[0]); + ASSERT_EQ(metadata->requests.size(), 1u); + auto location = FindResponse(metadata, GURL("https://test.example.com/")); + ASSERT_TRUE(location); + auto response = ParseResponse(&data_source, location); ASSERT_TRUE(response); - - EXPECT_EQ(index[0]->request_url, "https://test.example.com/"); - EXPECT_EQ(index[0]->request_method, "GET"); - EXPECT_EQ(index[0]->request_headers.size(), 0u); EXPECT_EQ(response->response_code, 200); EXPECT_EQ(response->response_headers.size(), 1u); EXPECT_EQ(response->response_headers["content-type"], "text/plain"); @@ -295,7 +339,16 @@ TEST_F(BundledExchangeParserTest, InvalidRequestURL) { BundleBuilder builder(kFallbackUrl); - builder.AddExchange({{":method", "GET"}, {":url", ""}}, + builder.AddExchange("", {{":status", "200"}, {"content-type", "text/plain"}}, + "payload"); + TestDataSource data_source(builder.CreateBundle()); + + ExpectFormatErrorWithFallbackURL(ParseBundle(&data_source)); +} + +TEST_F(BundledExchangeParserTest, RequestURLIsNotUTF8) { + BundleBuilder builder(kFallbackUrl); + builder.AddExchange("https://test.example.com/\xcc", {{":status", "200"}, {"content-type", "text/plain"}}, "payload"); TestDataSource data_source(builder.CreateBundle()); @@ -305,9 +358,9 @@ TEST_F(BundledExchangeParserTest, RequestURLHasCredentials) { BundleBuilder builder(kFallbackUrl); - builder.AddExchange( - {{":method", "GET"}, {":url", "https://user:passwd@test.example.com/"}}, - {{":status", "200"}, {"content-type", "text/plain"}}, "payload"); + builder.AddExchange("https://user:passwd@test.example.com/", + {{":status", "200"}, {"content-type", "text/plain"}}, + "payload"); TestDataSource data_source(builder.CreateBundle()); ExpectFormatErrorWithFallbackURL(ParseBundle(&data_source)); @@ -315,39 +368,7 @@ TEST_F(BundledExchangeParserTest, RequestURLHasFragment) { BundleBuilder builder(kFallbackUrl); - builder.AddExchange( - {{":method", "GET"}, {":url", "https://test.example.com/#fragment"}}, - {{":status", "200"}, {"content-type", "text/plain"}}, "payload"); - TestDataSource data_source(builder.CreateBundle()); - - ExpectFormatErrorWithFallbackURL(ParseBundle(&data_source)); -} - -TEST_F(BundledExchangeParserTest, NoMethodInRequestHeaders) { - BundleBuilder builder(kFallbackUrl); - builder.AddExchange( - {{":url", "https://test.example.com/"}}, // ":method" is missing. - {{":status", "200"}, {"content-type", "text/plain"}}, "payload"); - TestDataSource data_source(builder.CreateBundle()); - - ExpectFormatErrorWithFallbackURL(ParseBundle(&data_source)); -} - -TEST_F(BundledExchangeParserTest, MethodIsNotGET) { - BundleBuilder builder(kFallbackUrl); - builder.AddExchange( - {{":method", "POST"}, {":url", "https://test.example.com/"}}, - {{":status", "200"}, {"content-type", "text/plain"}}, "payload"); - TestDataSource data_source(builder.CreateBundle()); - - ExpectFormatErrorWithFallbackURL(ParseBundle(&data_source)); -} - -TEST_F(BundledExchangeParserTest, ExtraPseudoInRequestHeaders) { - BundleBuilder builder(kFallbackUrl); - builder.AddExchange({{":method", "GET"}, - {":url", "https://test.example.com/"}, - {":scheme", "https"}}, + builder.AddExchange("https://test.example.com/#fragment", {{":status", "200"}, {"content-type", "text/plain"}}, "payload"); TestDataSource data_source(builder.CreateBundle()); @@ -357,73 +378,131 @@ TEST_F(BundledExchangeParserTest, NoStatusInResponseHeaders) { BundleBuilder builder(kFallbackUrl); - builder.AddExchange( - {{":method", "GET"}, {":url", "https://test.example.com/"}}, - {{"content-type", "text/plain"}}, "payload"); // ":status" is missing. + builder.AddExchange("https://test.example.com/", + {{"content-type", "text/plain"}}, + "payload"); // ":status" is missing. TestDataSource data_source(builder.CreateBundle()); mojom::BundleMetadataPtr metadata = ParseBundle(&data_source).first; ASSERT_TRUE(metadata); - ASSERT_EQ(metadata->index.size(), 1u); - - ASSERT_FALSE(ParseResponse(&data_source, metadata->index[0])); + auto location = FindResponse(metadata, GURL("https://test.example.com/")); + ASSERT_TRUE(location); + ASSERT_FALSE(ParseResponse(&data_source, location)); } TEST_F(BundledExchangeParserTest, InvalidResponseStatus) { BundleBuilder builder(kFallbackUrl); - builder.AddExchange( - {{":method", "GET"}, {":url", "https://test.example.com/"}}, - {{":status", "0200"}, {"content-type", "text/plain"}}, "payload"); + builder.AddExchange("https://test.example.com/", + {{":status", "0200"}, {"content-type", "text/plain"}}, + "payload"); TestDataSource data_source(builder.CreateBundle()); mojom::BundleMetadataPtr metadata = ParseBundle(&data_source).first; ASSERT_TRUE(metadata); - ASSERT_EQ(metadata->index.size(), 1u); - - ASSERT_FALSE(ParseResponse(&data_source, metadata->index[0])); + auto location = FindResponse(metadata, GURL("https://test.example.com/")); + ASSERT_TRUE(location); + ASSERT_FALSE(ParseResponse(&data_source, location)); } TEST_F(BundledExchangeParserTest, ExtraPseudoInResponseHeaders) { BundleBuilder builder(kFallbackUrl); builder.AddExchange( - {{":method", "GET"}, {":url", "https://test.example.com/"}}, + "https://test.example.com/", {{":status", "200"}, {":foo", ""}, {"content-type", "text/plain"}}, "payload"); TestDataSource data_source(builder.CreateBundle()); mojom::BundleMetadataPtr metadata = ParseBundle(&data_source).first; ASSERT_TRUE(metadata); - ASSERT_EQ(metadata->index.size(), 1u); - - ASSERT_FALSE(ParseResponse(&data_source, metadata->index[0])); + auto location = FindResponse(metadata, GURL("https://test.example.com/")); + ASSERT_TRUE(location); + ASSERT_FALSE(ParseResponse(&data_source, location)); } TEST_F(BundledExchangeParserTest, UpperCaseCharacterInHeaderName) { BundleBuilder builder(kFallbackUrl); - builder.AddExchange( - {{":method", "GET"}, {":url", "https://test.example.com/"}}, - {{":status", "200"}, {"Content-Type", "text/plain"}}, "payload"); + builder.AddExchange("https://test.example.com/", + {{":status", "200"}, {"Content-Type", "text/plain"}}, + "payload"); TestDataSource data_source(builder.CreateBundle()); mojom::BundleMetadataPtr metadata = ParseBundle(&data_source).first; ASSERT_TRUE(metadata); - ASSERT_EQ(metadata->index.size(), 1u); - - ASSERT_FALSE(ParseResponse(&data_source, metadata->index[0])); + auto location = FindResponse(metadata, GURL("https://test.example.com/")); + ASSERT_TRUE(location); + ASSERT_FALSE(ParseResponse(&data_source, location)); } TEST_F(BundledExchangeParserTest, InvalidHeaderValue) { BundleBuilder builder(kFallbackUrl); - builder.AddExchange( - {{":method", "GET"}, {":url", "https://test.example.com/"}}, - {{":status", "200"}, {"content-type", "\n"}}, "payload"); + builder.AddExchange("https://test.example.com/", + {{":status", "200"}, {"content-type", "\n"}}, "payload"); TestDataSource data_source(builder.CreateBundle()); mojom::BundleMetadataPtr metadata = ParseBundle(&data_source).first; ASSERT_TRUE(metadata); - ASSERT_EQ(metadata->index.size(), 1u); + auto location = FindResponse(metadata, GURL("https://test.example.com/")); + ASSERT_TRUE(location); + ASSERT_FALSE(ParseResponse(&data_source, location)); +} - ASSERT_FALSE(ParseResponse(&data_source, metadata->index[0])); +TEST_F(BundledExchangeParserTest, Variants) { + BundleBuilder builder(kFallbackUrl); + auto location1 = builder.AddResponse( + {{":status", "200"}, {"content-type", "text/html"}}, "payload1"); + auto location2 = builder.AddResponse( + {{":status", "200"}, {"content-type", "text/plain"}}, "payload2"); + builder.AddIndexEntry("https://test.example.com/", + "Accept;text/html;text/plain", {location1, location2}); + TestDataSource data_source(builder.CreateBundle()); + + mojom::BundleMetadataPtr metadata = ParseBundle(&data_source).first; + ASSERT_TRUE(metadata); + const auto& found = + metadata->requests.find(GURL("https://test.example.com/")); + ASSERT_NE(found, metadata->requests.end()); + const mojom::BundleIndexValuePtr& index_entry = found->second; + EXPECT_EQ(index_entry->variants_value, "Accept;text/html;text/plain"); + ASSERT_EQ(index_entry->response_locations.size(), 2u); + + auto response1 = + ParseResponse(&data_source, index_entry->response_locations[0]); + ASSERT_TRUE(response1); + EXPECT_EQ(data_source.GetPayload(response1), "payload1"); + auto response2 = + ParseResponse(&data_source, index_entry->response_locations[1]); + ASSERT_TRUE(response2); + EXPECT_EQ(data_source.GetPayload(response2), "payload2"); +} + +TEST_F(BundledExchangeParserTest, EmptyIndexEntry) { + BundleBuilder builder(kFallbackUrl); + builder.AddIndexEntry("https://test.example.com/", "", {}); + TestDataSource data_source(builder.CreateBundle()); + + ExpectFormatErrorWithFallbackURL(ParseBundle(&data_source)); +} + +TEST_F(BundledExchangeParserTest, EmptyIndexEntryWithVariants) { + BundleBuilder builder(kFallbackUrl); + builder.AddIndexEntry("https://test.example.com/", + "Accept;text/html;text/plain", {}); + TestDataSource data_source(builder.CreateBundle()); + + ExpectFormatErrorWithFallbackURL(ParseBundle(&data_source)); +} + +TEST_F(BundledExchangeParserTest, MultipleResponsesWithoutVariantsValue) { + BundleBuilder builder(kFallbackUrl); + auto location1 = builder.AddResponse( + {{":status", "200"}, {"content-type", "text/html"}}, "payload1"); + auto location2 = builder.AddResponse( + {{":status", "200"}, {"content-type", "text/plain"}}, "payload2"); + builder.AddIndexEntry("https://test.example.com/", "", + {location1, location2}); + TestDataSource data_source(builder.CreateBundle()); + + ExpectFormatErrorWithFallbackURL(ParseBundle(&data_source)); } TEST_F(BundledExchangeParserTest, ParseGoldenFile) { @@ -431,30 +510,32 @@ mojom::BundleMetadataPtr metadata = ParseBundle(&data_source).first; ASSERT_TRUE(metadata); - ASSERT_EQ(metadata->index.size(), 4u); + ASSERT_EQ(metadata->requests.size(), 4u); - const auto& index = metadata->index; - - std::vector<mojom::BundleResponsePtr> responses; - for (size_t i = 0; i < index.size(); i++) { - responses.push_back(ParseResponse(&data_source, index[i])); - ASSERT_TRUE(responses.back()); + std::map<std::string, mojom::BundleResponsePtr> responses; + for (const auto& item : metadata->requests) { + auto location = FindResponse(metadata, item.first); + ASSERT_TRUE(location); + auto resp = ParseResponse(&data_source, location); + ASSERT_TRUE(resp); + responses[item.first.spec()] = std::move(resp); } - EXPECT_EQ(index[0]->request_url, "https://test.example.org/"); - EXPECT_EQ(index[0]->request_method, "GET"); - EXPECT_EQ(index[0]->request_headers.size(), 0u); - EXPECT_EQ(responses[0]->response_code, 200); - EXPECT_EQ(responses[0]->response_headers["content-type"], - "text/html; charset=utf-8"); - EXPECT_EQ(data_source.GetPayload(responses[0]), + ASSERT_TRUE(responses["https://test.example.org/"]); + EXPECT_EQ(responses["https://test.example.org/"]->response_code, 200); + EXPECT_EQ( + responses["https://test.example.org/"]->response_headers["content-type"], + "text/html; charset=utf-8"); + EXPECT_EQ(data_source.GetPayload(responses["https://test.example.org/"]), GetTestFileContents( base::FilePath(FILE_PATH_LITERAL("hello/index.html")))); - EXPECT_EQ(index[1]->request_url, "https://test.example.org/index.html"); - EXPECT_EQ(index[2]->request_url, - "https://test.example.org/manifest.webmanifest"); - EXPECT_EQ(index[3]->request_url, "https://test.example.org/script.js"); + EXPECT_TRUE(responses["https://test.example.org/index.html"]); + EXPECT_TRUE(responses["https://test.example.org/manifest.webmanifest"]); + EXPECT_TRUE(responses["https://test.example.org/script.js"]); } +// TODO(crbug.com/969596): Add a test case that loads a wbn file with variants, +// once gen-bundle supports variants. + } // namespace data_decoder
diff --git a/services/data_decoder/public/cpp/safe_bundled_exchanges_parser_unittest.cc b/services/data_decoder/public/cpp/safe_bundled_exchanges_parser_unittest.cc index fc275b2..6446f20 100644 --- a/services/data_decoder/public/cpp/safe_bundled_exchanges_parser_unittest.cc +++ b/services/data_decoder/public/cpp/safe_bundled_exchanges_parser_unittest.cc
@@ -150,39 +150,38 @@ run_loop.Run(); } ASSERT_TRUE(metadata_result); - ASSERT_EQ(metadata_result->index.size(), 4u); - const auto& index = metadata_result->index; + const auto& requests = metadata_result->requests; + ASSERT_EQ(requests.size(), 4u); - std::vector<mojom::BundleResponsePtr> responses; - for (auto& entry : index) { + std::map<std::string, mojom::BundleResponsePtr> responses; + for (auto& entry : requests) { base::RunLoop run_loop; parser.ParseResponse( - entry->response_offset, entry->response_length, + entry.second->response_locations[0]->offset, + entry.second->response_locations[0]->length, base::BindOnce( - [](base::Closure quit_closure, - std::vector<mojom::BundleResponsePtr>* responses, + [](base::Closure quit_closure, const std::string url, + std::map<std::string, mojom::BundleResponsePtr>* responses, mojom::BundleResponsePtr response, mojom::BundleResponseParseErrorPtr error) { EXPECT_TRUE(response); EXPECT_FALSE(error); if (response) - responses->push_back(std::move(response)); + responses->insert({url, std::move(response)}); std::move(quit_closure).Run(); }, - run_loop.QuitClosure(), &responses)); + run_loop.QuitClosure(), entry.first.spec(), &responses)); run_loop.Run(); } - EXPECT_EQ(index[0]->request_url, "https://test.example.org/"); - EXPECT_EQ(index[0]->request_method, "GET"); - EXPECT_EQ(index[0]->request_headers.size(), 0u); - EXPECT_EQ(responses[0]->response_code, 200); - EXPECT_EQ(responses[0]->response_headers["content-type"], - "text/html; charset=utf-8"); - EXPECT_EQ(index[1]->request_url, "https://test.example.org/index.html"); - EXPECT_EQ(index[2]->request_url, - "https://test.example.org/manifest.webmanifest"); - EXPECT_EQ(index[3]->request_url, "https://test.example.org/script.js"); + ASSERT_TRUE(responses["https://test.example.org/"]); + EXPECT_EQ(responses["https://test.example.org/"]->response_code, 200); + EXPECT_EQ( + responses["https://test.example.org/"]->response_headers["content-type"], + "text/html; charset=utf-8"); + EXPECT_TRUE(responses["https://test.example.org/index.html"]); + EXPECT_TRUE(responses["https://test.example.org/manifest.webmanifest"]); + EXPECT_TRUE(responses["https://test.example.org/script.js"]); } TEST_F(SafeBundledExchangesParserTest, OpenInvalidFile) {
diff --git a/services/data_decoder/public/mojom/bundled_exchanges_parser.mojom b/services/data_decoder/public/mojom/bundled_exchanges_parser.mojom index 3356c8d..48c65e6 100644 --- a/services/data_decoder/public/mojom/bundled_exchanges_parser.mojom +++ b/services/data_decoder/public/mojom/bundled_exchanges_parser.mojom
@@ -58,18 +58,18 @@ // https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html#semantics-load-metadata struct BundleMetadata { url.mojom.Url primary_url; - array<BundleIndexItem> index; + map<url.mojom.Url, BundleIndexValue> requests; url.mojom.Url manifest_url; }; -struct BundleIndexItem { - url.mojom.Url request_url; - string request_method; - map<string, string> request_headers; +struct BundleIndexValue { + string variants_value; + array<BundleResponseLocation> response_locations; +}; - // Used as parameters to ParseResponse(). - uint64 response_offset; - uint64 response_length; +struct BundleResponseLocation { + uint64 offset; + uint64 length; }; struct BundleResponse {
diff --git a/services/device/serial/serial_device_enumerator.h b/services/device/serial/serial_device_enumerator.h index 91ed7c6..08fb4872 100644 --- a/services/device/serial/serial_device_enumerator.h +++ b/services/device/serial/serial_device_enumerator.h
@@ -31,7 +31,7 @@ virtual std::vector<mojom::SerialPortInfoPtr> GetDevices() = 0; - base::Optional<base::FilePath> GetPathFromToken( + virtual base::Optional<base::FilePath> GetPathFromToken( const base::UnguessableToken& token); protected:
diff --git a/services/device/serial/serial_device_enumerator_linux.cc b/services/device/serial/serial_device_enumerator_linux.cc index 41e515a..f1e59d3 100644 --- a/services/device/serial/serial_device_enumerator_linux.cc +++ b/services/device/serial/serial_device_enumerator_linux.cc
@@ -38,78 +38,107 @@ } SerialDeviceEnumeratorLinux::SerialDeviceEnumeratorLinux() { - udev_.reset(udev_new()); + DETACH_FROM_SEQUENCE(sequence_checker_); + + watcher_ = UdevWatcher::StartWatching(this); + watcher_->EnumerateExistingDevices(); } -SerialDeviceEnumeratorLinux::~SerialDeviceEnumeratorLinux() = default; +SerialDeviceEnumeratorLinux::~SerialDeviceEnumeratorLinux() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +} std::vector<mojom::SerialPortInfoPtr> SerialDeviceEnumeratorLinux::GetDevices() { + std::vector<mojom::SerialPortInfoPtr> ports; + ports.reserve(ports_.size()); + for (const auto& map_entry : ports_) + ports.push_back(map_entry.second->Clone()); + return ports; +} + +base::Optional<base::FilePath> SerialDeviceEnumeratorLinux::GetPathFromToken( + const base::UnguessableToken& token) { + auto it = ports_.find(token); + if (it == ports_.end()) + return base::nullopt; + return it->second->path; +} + +void SerialDeviceEnumeratorLinux::OnDeviceAdded(ScopedUdevDevicePtr device) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, base::BlockingType::MAY_BLOCK); - std::vector<mojom::SerialPortInfoPtr> devices; - ScopedUdevEnumeratePtr enumerate(udev_enumerate_new(udev_.get())); - if (!enumerate) { - LOG(ERROR) << "Serial device enumeration failed."; - return devices; - } - if (udev_enumerate_add_match_subsystem(enumerate.get(), kSerialSubsystem)) { - LOG(ERROR) << "Serial device enumeration failed."; - return devices; - } - if (udev_enumerate_scan_devices(enumerate.get())) { - LOG(ERROR) << "Serial device enumeration failed."; - return devices; + const char* subsystem = udev_device_get_subsystem(device.get()); + if (!subsystem || strcmp(subsystem, kSerialSubsystem) != 0) + return; + + const char* syspath = udev_device_get_syspath(device.get()); + if (!syspath) + return; + + const char* path = udev_device_get_property_value(device.get(), kHostPathKey); + if (!path) + return; + + // TODO(rockot): There may be a better way to filter serial devices here, + // but it's not clear what that would be. Udev will list lots of virtual + // devices with no real endpoint to back them anywhere. The presence of + // a bus identifier (e.g., "pci" or "usb") seems to be a good heuristic + // for detecting actual devices. + const char* bus = udev_device_get_property_value(device.get(), kHostBusKey); + if (!bus) { + const char* major = udev_device_get_property_value(device.get(), kMajorKey); + if (!major || strcmp(major, kRfcommMajor) != 0) + return; } - udev_list_entry* entry = udev_enumerate_get_list_entry(enumerate.get()); - for (; entry != NULL; entry = udev_list_entry_get_next(entry)) { - ScopedUdevDevicePtr device(udev_device_new_from_syspath( - udev_.get(), udev_list_entry_get_name(entry))); - // TODO(rockot): There may be a better way to filter serial devices here, - // but it's not clear what that would be. Udev will list lots of virtual - // devices with no real endpoint to back them anywhere. The presence of - // a bus identifier (e.g., "pci" or "usb") seems to be a good heuristic - // for detecting actual devices. - const char* path = - udev_device_get_property_value(device.get(), kHostPathKey); - if (!path) - continue; + auto token = base::UnguessableToken::Create(); + auto info = mojom::SerialPortInfo::New(); + info->path = base::FilePath(path); + info->token = token; - const char* bus = udev_device_get_property_value(device.get(), kHostBusKey); - if (!bus) { - const char* major = - udev_device_get_property_value(device.get(), kMajorKey); - if (!major || strcmp(major, kRfcommMajor) != 0) - continue; - } + const char* vendor_id = + udev_device_get_property_value(device.get(), kVendorIDKey); + const char* product_id = + udev_device_get_property_value(device.get(), kProductIDKey); + const char* product_name = + udev_device_get_property_value(device.get(), kProductNameKey); - auto info = mojom::SerialPortInfo::New(); - info->path = base::FilePath(path); - info->token = GetTokenFromPath(info->path); - - const char* vendor_id = - udev_device_get_property_value(device.get(), kVendorIDKey); - const char* product_id = - udev_device_get_property_value(device.get(), kProductIDKey); - const char* product_name = - udev_device_get_property_value(device.get(), kProductNameKey); - - uint32_t int_value; - if (vendor_id && base::HexStringToUInt(vendor_id, &int_value)) { - info->vendor_id = int_value; - info->has_vendor_id = true; - } - if (product_id && base::HexStringToUInt(product_id, &int_value)) { - info->product_id = int_value; - info->has_product_id = true; - } - if (product_name) - info->display_name.emplace(product_name); - devices.push_back(std::move(info)); + uint32_t int_value; + if (vendor_id && base::HexStringToUInt(vendor_id, &int_value)) { + info->vendor_id = int_value; + info->has_vendor_id = true; } - return devices; + if (product_id && base::HexStringToUInt(product_id, &int_value)) { + info->product_id = int_value; + info->has_product_id = true; + } + if (product_name) + info->display_name.emplace(product_name); + + ports_.insert(std::make_pair(token, std::move(info))); + paths_.insert(std::make_pair(syspath, token)); +} + +void SerialDeviceEnumeratorLinux::OnDeviceChanged(ScopedUdevDevicePtr device) {} + +void SerialDeviceEnumeratorLinux::OnDeviceRemoved(ScopedUdevDevicePtr device) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, + base::BlockingType::MAY_BLOCK); + + const char* syspath = udev_device_get_syspath(device.get()); + if (!syspath) + return; + + auto it = paths_.find(syspath); + if (it == paths_.end()) + return; + + ports_.erase(it->second); + paths_.erase(it); } } // namespace device
diff --git a/services/device/serial/serial_device_enumerator_linux.h b/services/device/serial/serial_device_enumerator_linux.h index d1ee7aa..d91f2ed 100644 --- a/services/device/serial/serial_device_enumerator_linux.h +++ b/services/device/serial/serial_device_enumerator_linux.h
@@ -5,25 +5,42 @@ #ifndef SERVICES_DEVICE_SERIAL_SERIAL_DEVICE_ENUMERATOR_LINUX_H_ #define SERVICES_DEVICE_SERIAL_SERIAL_DEVICE_ENUMERATOR_LINUX_H_ -#include <vector> +#include <map> +#include <memory> +#include <string> #include "base/macros.h" -#include "device/udev_linux/scoped_udev.h" +#include "base/sequence_checker.h" +#include "base/unguessable_token.h" +#include "device/udev_linux/udev_watcher.h" +#include "services/device/public/mojom/serial.mojom.h" #include "services/device/serial/serial_device_enumerator.h" namespace device { // Discovers and enumerates serial devices available to the host. -class SerialDeviceEnumeratorLinux : public SerialDeviceEnumerator { +class SerialDeviceEnumeratorLinux : public SerialDeviceEnumerator, + public UdevWatcher::Observer { public: SerialDeviceEnumeratorLinux(); ~SerialDeviceEnumeratorLinux() override; - // Implementation for SerialDeviceEnumerator. + // SerialDeviceEnumerator std::vector<mojom::SerialPortInfoPtr> GetDevices() override; + base::Optional<base::FilePath> GetPathFromToken( + const base::UnguessableToken& token) override; + + // UdevWatcher::Observer + void OnDeviceAdded(ScopedUdevDevicePtr device) override; + void OnDeviceChanged(ScopedUdevDevicePtr device) override; + void OnDeviceRemoved(ScopedUdevDevicePtr device) override; private: - ScopedUdevPtr udev_; + std::unique_ptr<UdevWatcher> watcher_; + std::map<base::UnguessableToken, mojom::SerialPortInfoPtr> ports_; + std::map<std::string, base::UnguessableToken> paths_; + + SEQUENCE_CHECKER(sequence_checker_); DISALLOW_COPY_AND_ASSIGN(SerialDeviceEnumeratorLinux); };
diff --git a/services/device/serial/serial_device_enumerator_unittest.cc b/services/device/serial/serial_device_enumerator_unittest.cc index 899f1c1..7db84f65 100644 --- a/services/device/serial/serial_device_enumerator_unittest.cc +++ b/services/device/serial/serial_device_enumerator_unittest.cc
@@ -4,14 +4,27 @@ #include "services/device/serial/serial_device_enumerator.h" -#include <memory> #include <vector> +#include "base/test/scoped_task_environment.h" #include "testing/gtest/include/gtest/gtest.h" namespace device { -TEST(SerialDeviceEnumeratorTest, GetDevices) { +namespace { + +class SerialDeviceEnumeratorTest : public testing::Test { + public: + SerialDeviceEnumeratorTest() + : scoped_task_environment_( + base::test::ScopedTaskEnvironment::MainThreadType::IO) {} + ~SerialDeviceEnumeratorTest() override = default; + + private: + base::test::ScopedTaskEnvironment scoped_task_environment_; +}; + +TEST_F(SerialDeviceEnumeratorTest, GetDevices) { // There is no guarantee that a test machine will have a serial device // available. The purpose of this test is to ensure that the process of // attempting to enumerate devices does not cause a crash. @@ -20,4 +33,6 @@ std::vector<mojom::SerialPortInfoPtr> devices = enumerator->GetDevices(); } +} // namespace + } // namespace device
diff --git a/services/network/cross_origin_read_blocking.cc b/services/network/cross_origin_read_blocking.cc index 18667282..74b183bf6 100644 --- a/services/network/cross_origin_read_blocking.cc +++ b/services/network/cross_origin_read_blocking.cc
@@ -236,7 +236,6 @@ "application/gzip", "application/x-gzip", "application/x-protobuf", - "application/x-www-form-urlencoded", "application/zip", // Block multipart responses because a protected type (e.g. JSON) can // become multipart if returned in a range request with multiple parts.
diff --git a/services/network/cross_origin_read_blocking_unittest.cc b/services/network/cross_origin_read_blocking_unittest.cc index e1c78e7..66d63ba 100644 --- a/services/network/cross_origin_read_blocking_unittest.cc +++ b/services/network/cross_origin_read_blocking_unittest.cc
@@ -2636,7 +2636,6 @@ {"application/gzip", MimeType::kNeverSniffed}, {"application/x-protobuf", MimeType::kNeverSniffed}, {"application/x-gzip", MimeType::kNeverSniffed}, - {"application/x-www-form-urlencoded", MimeType::kNeverSniffed}, {"application/zip", MimeType::kNeverSniffed}, {"multipart/byteranges", MimeType::kNeverSniffed}, {"text/event-stream", MimeType::kNeverSniffed},
diff --git a/services/network/proxy_resolving_client_socket_factory.cc b/services/network/proxy_resolving_client_socket_factory.cc index 45de7ee..514474f 100644 --- a/services/network/proxy_resolving_client_socket_factory.cc +++ b/services/network/proxy_resolving_client_socket_factory.cc
@@ -80,6 +80,14 @@ // might have since entered proxy credentials. Clear the http auth of // |network_session_| and copy over the data from |request_context|'s auth // cache. + // + // TODO(davidben): This does not share the SSLClientContext, so proxy client + // certificate credentials do not work. However, client certificates for both + // proxy and origin are handled at the socket layer, so doing so would pick up + // both sets. Depending on how these sockets are used, this may not be what we + // want. Toggling privacy mode (i.e. CORS uncredentialed mode) on the + // ConnectJob should give proxy auth without origin auth, but only after + // https://crbug.com/775438 is fixed. network_session_->http_auth_cache()->ClearAllEntries(); net::HttpAuthCache* other_auth_cache = request_context_->http_transaction_factory()
diff --git a/services/network/url_loader_unittest.cc b/services/network/url_loader_unittest.cc index bef9234b..1f922fb 100644 --- a/services/network/url_loader_unittest.cc +++ b/services/network/url_loader_unittest.cc
@@ -3392,7 +3392,6 @@ ASSERT_TRUE(identity); scoped_refptr<TestSSLPrivateKey> private_key = base::MakeRefCounted<TestSSLPrivateKey>(identity->ssl_private_key()); - TestSSLPrivateKey* private_key_ptr = private_key.get(); net::EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS); net::SSLServerConfig ssl_config; @@ -3407,7 +3406,7 @@ network_service_client.set_certificate_response( MockNetworkServiceClient::CertificateResponse:: VALID_CERTIFICATE_SIGNATURE); - network_service_client.set_private_key(std::move(private_key)); + network_service_client.set_private_key(private_key); scoped_refptr<net::X509Certificate> certificate = test_server.GetCertificate(); network_service_client.set_certificate(std::move(certificate)); @@ -3431,13 +3430,13 @@ ASSERT_TRUE(url_loader); EXPECT_EQ(0, network_service_client.on_certificate_requested_counter()); - EXPECT_EQ(0, private_key_ptr->sign_count()); + EXPECT_EQ(0, private_key->sign_count()); client()->RunUntilComplete(); EXPECT_EQ(1, network_service_client.on_certificate_requested_counter()); // The private key should have been used. - EXPECT_EQ(1, private_key_ptr->sign_count()); + EXPECT_EQ(1, private_key->sign_count()); } TEST_F(URLLoaderTest, ClientAuthCertificateWithInvalidSignature) { @@ -3448,7 +3447,6 @@ scoped_refptr<TestSSLPrivateKey> private_key = base::MakeRefCounted<TestSSLPrivateKey>(identity->ssl_private_key()); private_key->set_fail_signing(true); - TestSSLPrivateKey* private_key_ptr = private_key.get(); net::EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS); net::SSLServerConfig ssl_config; @@ -3463,7 +3461,7 @@ network_service_client.set_certificate_response( MockNetworkServiceClient::CertificateResponse:: VALID_CERTIFICATE_SIGNATURE); - network_service_client.set_private_key(std::move(private_key)); + network_service_client.set_private_key(private_key); scoped_refptr<net::X509Certificate> certificate = test_server.GetCertificate(); network_service_client.set_certificate(std::move(certificate)); @@ -3487,13 +3485,13 @@ ASSERT_TRUE(url_loader); EXPECT_EQ(0, network_service_client.on_certificate_requested_counter()); - EXPECT_EQ(0, private_key_ptr->sign_count()); + EXPECT_EQ(0, private_key->sign_count()); client()->RunUntilComplete(); EXPECT_EQ(1, network_service_client.on_certificate_requested_counter()); // The private key should have been used. - EXPECT_EQ(1, private_key_ptr->sign_count()); + EXPECT_EQ(1, private_key->sign_count()); EXPECT_EQ(net::ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED, client()->completion_status().error_code); }
diff --git a/services/service_manager/sandbox/fuchsia/sandbox_policy_fuchsia.cc b/services/service_manager/sandbox/fuchsia/sandbox_policy_fuchsia.cc index 35b86fe..433eda5d 100644 --- a/services/service_manager/sandbox/fuchsia/sandbox_policy_fuchsia.cc +++ b/services/service_manager/sandbox/fuchsia/sandbox_policy_fuchsia.cc
@@ -80,7 +80,6 @@ { SANDBOX_TYPE_NETWORK, base::make_span((const char* const[]){ - fuchsia::net::SocketProvider::Name_, fuchsia::net::NameLookup::Name_, fuchsia::netstack::Netstack::Name_, "fuchsia.posix.socket.Provider"}), kProvideSslConfig,
diff --git a/services/test/data/bundled_exchanges/hello.wbn b/services/test/data/bundled_exchanges/hello.wbn index a1f9221..75bb0b0 100644 --- a/services/test/data/bundled_exchanges/hello.wbn +++ b/services/test/data/bundled_exchanges/hello.wbn Binary files differ
diff --git a/services/tracing/perfetto/privacy_filtered_fields-inl.h b/services/tracing/perfetto/privacy_filtered_fields-inl.h index bc2cb16e..1b446fa 100644 --- a/services/tracing/perfetto/privacy_filtered_fields-inl.h +++ b/services/tracing/perfetto/privacy_filtered_fields-inl.h
@@ -84,8 +84,8 @@ kInternedDataComplexMessages}; // Proto Message: BufferStats -constexpr int kBufferStatsIndices[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, -1}; +constexpr int kBufferStatsIndices[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, -1}; constexpr MessageInfo kBufferStats = {kBufferStatsIndices, nullptr}; // Proto Message: TraceStats
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 4f0df1e..1f05e4b 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -1163,7 +1163,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ], "hard_timeout": 900, @@ -1187,7 +1187,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ], "hard_timeout": 900 @@ -1214,7 +1214,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ], "hard_timeout": 900, @@ -8103,6 +8103,92 @@ } ] }, + "linux-bfcache-rel": { + "gtest_tests": [ + { + "args": [ + "--enable-features=BackForwardCache", + "--test-launcher-filter-file=../../testing/buildbot/filters/bfcache.browser_tests.filter" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "bf_cache_browser_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-16.04" + } + ], + "shards": 10 + }, + "test": "browser_tests" + }, + { + "args": [ + "--enable-features=BackForwardCache", + "--test-launcher-filter-file=../../testing/buildbot/filters/bfcache.content_browsertests.filter" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "bf_cache_content_browsertests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-16.04" + } + ], + "shards": 10 + }, + "test": "content_browsertests" + }, + { + "args": [ + "--enable-features=BackForwardCache", + "--test-launcher-filter-file=../../testing/buildbot/filters/bfcache.content_unittests.filter" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "bf_cache_content_unittests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-16.04" + } + ] + }, + "test": "content_unittests" + }, + { + "args": [ + "--enable-features=BackForwardCache", + "--test-launcher-filter-file=../../testing/buildbot/filters/bfcache.unit_tests.filter" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "bf_cache_unit_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-16.04" + } + ] + }, + "test": "unit_tests" + } + ] + }, "linux-blink-animation-use-time-delta": { "additional_compile_targets": [ "all" @@ -21713,27 +21799,6 @@ "gtest_tests": [ { "args": [ - "--enable-features=BackForwardCache", - "--test-launcher-filter-file=../../testing/buildbot/filters/bfcache.browser_tests.filter" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "bf_cache_browser_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ], - "shards": 10 - }, - "test": "browser_tests" - }, - { - "args": [ "--disable-field-trial-config" ], "merge": { @@ -21751,67 +21816,6 @@ "shards": 10 }, "test": "browser_tests" - }, - { - "args": [ - "--enable-features=BackForwardCache", - "--test-launcher-filter-file=../../testing/buildbot/filters/bfcache.content_browsertests.filter" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "bf_cache_content_browsertests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ], - "shards": 10 - }, - "test": "content_browsertests" - }, - { - "args": [ - "--enable-features=BackForwardCache", - "--test-launcher-filter-file=../../testing/buildbot/filters/bfcache.content_unittests.filter" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "bf_cache_content_unittests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "content_unittests" - }, - { - "args": [ - "--enable-features=BackForwardCache", - "--test-launcher-filter-file=../../testing/buildbot/filters/bfcache.unit_tests.filter" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "bf_cache_unit_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "unit_tests" } ] },
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index 6f319415..694e35f 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -10283,6 +10283,551 @@ } ] }, + "Linux FYI SkiaRenderer Vulkan (Intel HD 630)": { + "gtest_tests": [ + { + "args": [ + "--use-gpu-in-tests", + "--test-launcher-retry-limit=0" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "intel-hd-630-ubuntu-stable", + "os": "linux-intel-stable", + "pool": "Chrome-GPU" + } + ], + "shards": 4 + }, + "test": "angle_end2end_tests" + }, + { + "args": [ + "--use-gpu-in-tests", + "--test-launcher-retry-limit=0", + "--no-xvfb" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "intel-hd-630-ubuntu-stable", + "os": "linux-intel-stable", + "pool": "Chrome-GPU" + } + ] + }, + "test": "angle_unittests" + }, + { + "args": [ + "--test-launcher-retry-limit=0" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "intel-hd-630-ubuntu-stable", + "os": "linux-intel-stable", + "pool": "Chrome-GPU" + } + ] + }, + "test": "angle_white_box_tests" + }, + { + "args": [ + "--enable-gpu", + "--test-launcher-bot-mode", + "--test-launcher-jobs=1", + "--test-launcher-filter-file=../../testing/buildbot/filters/vulkan.content_browsertests.filter", + "--enable-features=VizDisplayCompositor,UseSkiaRenderer,UiGpuRasterization", + "--use-vulkan=native", + "--enable-oop-rasterization", + "--enable-gpu-rasterization", + "--force-gpu-rasterization", + "--disable-software-compositing-fallback", + "--disable-vulkan-fallback-to-gl-for-testing", + "--disable-headless-mode", + "--no-xvfb" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "vulkan_content_browsertests", + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "intel-hd-630-ubuntu-stable", + "os": "linux-intel-stable", + "pool": "Chrome-GPU" + } + ] + }, + "test": "content_browsertests" + }, + { + "args": [ + "--use-gpu-in-tests", + "--use-cmd-decoder=validating" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "intel-hd-630-ubuntu-stable", + "os": "linux-intel-stable", + "pool": "Chrome-GPU" + } + ] + }, + "test": "gl_tests" + }, + { + "args": [ + "--use-gpu-in-tests", + "--no-xvfb" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "intel-hd-630-ubuntu-stable", + "os": "linux-intel-stable", + "pool": "Chrome-GPU" + } + ] + }, + "test": "gl_unittests" + }, + { + "args": [ + "--use-gpu-in-tests" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "intel-hd-630-ubuntu-stable", + "os": "linux-intel-stable", + "pool": "Chrome-GPU" + } + ] + }, + "test": "gles2_conform_test" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "intel-hd-630-ubuntu-stable", + "os": "linux-intel-stable", + "pool": "Chrome-GPU" + } + ] + }, + "test": "swiftshader_unittests" + } + ], + "isolated_scripts": [ + { + "args": [ + "context_lost", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "context_lost_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "intel-hd-630-ubuntu-stable", + "os": "linux-intel-stable", + "pool": "Chrome-GPU" + } + ], + "idempotent": false + } + }, + { + "args": [ + "depth_capture", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "depth_capture_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "intel-hd-630-ubuntu-stable", + "os": "linux-intel-stable", + "pool": "Chrome-GPU" + } + ], + "idempotent": false + } + }, + { + "args": [ + "gpu_process", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "gpu_process_launch_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "intel-hd-630-ubuntu-stable", + "os": "linux-intel-stable", + "pool": "Chrome-GPU" + } + ], + "idempotent": false + } + }, + { + "args": [ + "hardware_accelerated_feature", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "hardware_accelerated_feature_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "intel-hd-630-ubuntu-stable", + "os": "linux-intel-stable", + "pool": "Chrome-GPU" + } + ], + "idempotent": false + } + }, + { + "args": [ + "maps", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer", + "--dont-restore-color-profile-after-test", + "--os-type", + "linux", + "--build-revision", + "${got_revision}", + "--test-machine-name", + "${buildername}" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "maps_pixel_test", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "intel-hd-630-ubuntu-stable", + "os": "linux-intel-stable", + "pool": "Chrome-GPU" + } + ], + "idempotent": false + } + }, + { + "args": [ + "screenshot_sync", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer", + "--dont-restore-color-profile-after-test" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "screenshot_sync_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "intel-hd-630-ubuntu-stable", + "os": "linux-intel-stable", + "pool": "Chrome-GPU" + } + ], + "idempotent": false + } + }, + { + "args": [ + "--num-retries=3", + "--additional-driver-flag=--enable-features=VizDisplayCompositor,UseSkiaRenderer", + "--additional-driver-flag=--use-gl=any", + "--additional-driver-flag=--enable-gpu-rasterization", + "--additional-driver-flag=--force-gpu-rasterization", + "--additional-driver-flag=--enable-oop-rasterization", + "--additional-driver-flag=--disable-software-compositing-fallback", + "--additional-driver-flag=--disable-headless-mode", + "--no-xvfb", + "--fuzzy-diff", + "--skipped=always", + "--test-list=../../testing/buildbot/filters/gpu.skiarenderer_vulkan_blink_web_tests.filter", + "--additional-expectations=../../third_party/blink/web_tests/FlagExpectations/enable-features=UseSkiaRenderer", + "--additional-expectations=../../third_party/blink/web_tests/FlagExpectations/enable-gpu-rasterization" + ], + "isolate_name": "blink_web_tests_exparchive", + "merge": { + "args": [ + "--verbose" + ], + "script": "//third_party/blink/tools/merge_web_test_results.py" + }, + "name": "skia_renderer_gl_blink_web_tests", + "results_handler": "layout tests", + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "intel-hd-630-ubuntu-stable", + "os": "linux-intel-stable", + "pool": "Chrome-GPU" + } + ] + } + }, + { + "args": [ + "pixel", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --enable-features=VizDisplayCompositor,UseSkiaRenderer", + "--dont-restore-color-profile-after-test", + "--os-type", + "linux", + "--build-revision", + "${got_revision}", + "--test-machine-name", + "${buildername}" + ], + "experiment_percentage": 100, + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "skia_renderer_pixel_skia_gold_test", + "precommit_args": [ + "--review-patch-issue", + "${patch_issue}", + "--review-patch-set", + "${patch_set}", + "--buildbucket-build-id", + "${buildbucket_build_id}" + ], + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "intel-hd-630-ubuntu-stable", + "os": "linux-intel-stable", + "pool": "Chrome-GPU" + } + ], + "idempotent": false, + "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com" + } + }, + { + "args": [ + "--num-retries=3", + "--additional-driver-flag=--enable-features=VizDisplayCompositor,UseSkiaRenderer", + "--additional-driver-flag=--use-gl=any", + "--additional-driver-flag=--enable-gpu-rasterization", + "--additional-driver-flag=--force-gpu-rasterization", + "--additional-driver-flag=--enable-oop-rasterization", + "--additional-driver-flag=--disable-software-compositing-fallback", + "--additional-driver-flag=--use-vulkan=native", + "--additional-driver-flag=--disable-vulkan-fallback-to-gl-for-testing", + "--additional-driver-flag=--disable-headless-mode", + "--no-xvfb", + "--fuzzy-diff", + "--skipped=always", + "--driver-logging", + "--test-list=../../testing/buildbot/filters/gpu.skiarenderer_vulkan_blink_web_tests.filter", + "--additional-expectations=../../third_party/blink/web_tests/FlagExpectations/enable-features=UseSkiaRenderer", + "--additional-expectations=../../third_party/blink/web_tests/FlagExpectations/use-vulkan=native" + ], + "isolate_name": "blink_web_tests_exparchive", + "merge": { + "args": [ + "--verbose" + ], + "script": "//third_party/blink/tools/merge_web_test_results.py" + }, + "name": "vulkan_native_blink_web_tests", + "results_handler": "layout tests", + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "intel-hd-630-ubuntu-stable", + "os": "linux-intel-stable", + "pool": "Chrome-GPU" + } + ] + } + }, + { + "args": [ + "pixel", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc \"--use-vulkan=native --disable-vulkan-fallback-to-gl-for-testing --enable-features=UseSkiaRenderer --disable-software-compositing-fallback\"", + "--dont-restore-color-profile-after-test", + "--os-type", + "linux", + "--build-revision", + "${got_revision}", + "--test-machine-name", + "${buildername}" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "vulkan_pixel_skia_gold_test", + "precommit_args": [ + "--review-patch-issue", + "${patch_issue}", + "--review-patch-set", + "${patch_set}", + "--buildbucket-build-id", + "${buildbucket_build_id}" + ], + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "intel-hd-630-ubuntu-stable", + "os": "linux-intel-stable", + "pool": "Chrome-GPU" + } + ], + "idempotent": false, + "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com" + } + } + ] + }, "Linux FYI SkiaRenderer Vulkan (NVIDIA)": { "gtest_tests": [ { @@ -27249,6 +27794,7 @@ "pool": "Chrome-GPU" } ], + "expiration": 10800, "shards": 4 }, "test": "angle_end2end_tests" @@ -27270,7 +27816,8 @@ "os": "Windows-10", "pool": "Chrome-GPU" } - ] + ], + "expiration": 10800 }, "test": "angle_gles1_conformance_tests" }, @@ -27293,7 +27840,8 @@ "os": "Windows-10", "pool": "Chrome-GPU" } - ] + ], + "expiration": 10800 }, "test": "angle_unittests" }, @@ -27315,7 +27863,8 @@ "os": "Windows-10", "pool": "Chrome-GPU" } - ] + ], + "expiration": 10800 }, "test": "angle_white_box_tests" }, @@ -27340,7 +27889,8 @@ "os": "Windows-10", "pool": "Chrome-GPU" } - ] + ], + "expiration": 10800 }, "test": "browser_tests" }, @@ -27362,7 +27912,8 @@ "os": "Windows-10", "pool": "Chrome-GPU" } - ] + ], + "expiration": 10800 }, "test": "gl_tests" }, @@ -27385,7 +27936,8 @@ "os": "Windows-10", "pool": "Chrome-GPU" } - ] + ], + "expiration": 10800 }, "test": "gl_tests" }, @@ -27406,7 +27958,8 @@ "os": "Windows-10", "pool": "Chrome-GPU" } - ] + ], + "expiration": 10800 }, "test": "gl_unittests" }, @@ -27427,7 +27980,8 @@ "os": "Windows-10", "pool": "Chrome-GPU" } - ] + ], + "expiration": 10800 }, "test": "gles2_conform_test" }, @@ -27450,7 +28004,8 @@ "os": "Windows-10", "pool": "Chrome-GPU" } - ] + ], + "expiration": 10800 }, "test": "gles2_conform_test" }, @@ -27474,7 +28029,8 @@ "os": "Windows-10", "pool": "Chrome-GPU" } - ] + ], + "expiration": 10800 }, "test": "gles2_conform_test" }, @@ -27492,7 +28048,8 @@ "os": "Windows-10", "pool": "Chrome-GPU" } - ] + ], + "expiration": 10800 }, "test": "gpu_unittests" }, @@ -27510,7 +28067,8 @@ "os": "Windows-10", "pool": "Chrome-GPU" } - ] + ], + "expiration": 10800 }, "test": "swiftshader_unittests" }, @@ -27534,7 +28092,8 @@ "os": "Windows-10", "pool": "Chrome-GPU" } - ] + ], + "expiration": 10800 }, "test": "video_decode_accelerator_unittest" }, @@ -27558,7 +28117,8 @@ "os": "Windows-10", "pool": "Chrome-GPU" } - ] + ], + "expiration": 10800 }, "test": "video_decode_accelerator_unittest" }, @@ -27580,7 +28140,8 @@ "os": "Windows-10", "pool": "Chrome-GPU" } - ] + ], + "expiration": 10800 }, "test": "xr_browser_tests" } @@ -27609,7 +28170,8 @@ "os": "Windows-10", "pool": "Chrome-GPU" } - ] + ], + "expiration": 10800 } }, { @@ -27638,6 +28200,7 @@ "pool": "Chrome-GPU" } ], + "expiration": 10800, "idempotent": false } }, @@ -27667,6 +28230,7 @@ "pool": "Chrome-GPU" } ], + "expiration": 10800, "idempotent": false } }, @@ -27696,6 +28260,7 @@ "pool": "Chrome-GPU" } ], + "expiration": 10800, "idempotent": false } }, @@ -27725,6 +28290,7 @@ "pool": "Chrome-GPU" } ], + "expiration": 10800, "idempotent": false } }, @@ -27758,6 +28324,7 @@ "pool": "Chrome-GPU" } ], + "expiration": 10800, "idempotent": false } }, @@ -27794,6 +28361,7 @@ "pool": "Chrome-GPU" } ], + "expiration": 10800, "idempotent": false } }, @@ -27838,6 +28406,7 @@ "pool": "Chrome-GPU" } ], + "expiration": 10800, "idempotent": false, "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com" } @@ -27868,6 +28437,7 @@ "pool": "Chrome-GPU" } ], + "expiration": 10800, "idempotent": false } }, @@ -27892,7 +28462,8 @@ "os": "Windows-10", "pool": "Chrome-GPU" } - ] + ], + "expiration": 10800 } }, { @@ -27922,6 +28493,7 @@ "pool": "Chrome-GPU" } ], + "expiration": 10800, "idempotent": false } }, @@ -27951,6 +28523,7 @@ "pool": "Chrome-GPU" } ], + "expiration": 10800, "idempotent": false } }, @@ -27982,6 +28555,7 @@ "pool": "Chrome-GPU" } ], + "expiration": 10800, "idempotent": false, "shards": 20 } @@ -28014,6 +28588,7 @@ "pool": "Chrome-GPU" } ], + "expiration": 10800, "idempotent": false, "shards": 20 } @@ -28046,6 +28621,7 @@ "pool": "Chrome-GPU" } ], + "expiration": 10800, "idempotent": false, "shards": 20 } @@ -28076,6 +28652,7 @@ "pool": "Chrome-GPU" } ], + "expiration": 10800, "idempotent": false, "shards": 2 } @@ -28106,6 +28683,7 @@ "pool": "Chrome-GPU" } ], + "expiration": 10800, "idempotent": false, "shards": 2 } @@ -28136,6 +28714,7 @@ "pool": "Chrome-GPU" } ], + "expiration": 10800, "idempotent": false, "shards": 2 } @@ -28166,6 +28745,7 @@ "pool": "Chrome-GPU" } ], + "expiration": 10800, "idempotent": false, "shards": 2 }
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json index 5db6f906..d1498e4d 100644 --- a/testing/buildbot/chromium.linux.json +++ b/testing/buildbot/chromium.linux.json
@@ -2044,6 +2044,25 @@ "test": "ui_base_unittests" }, { + "args": [ + "--child-arg=--ozone-platform=headless" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-16.04" + } + ] + }, + "test": "viz_unittests" + }, + { "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl index 53f7ed9..5ee6810 100644 --- a/testing/buildbot/mixins.pyl +++ b/testing/buildbot/mixins.pyl
@@ -599,6 +599,12 @@ 'os': 'Windows-10', 'pool': 'Chrome-GPU', }, + # ~50% of the WebGL2 conformance tests time out with the default + # 1 hour expiration, so use 3 times that until more devices are + # available. + # TODO(https://crbug.com/986939): Remove this when more devices + # are added. + 'expiration': 10800, }, }, 'win10_nvidia_geforce_gtx_1660': {
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 59da224..d60ceb0 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -1420,6 +1420,7 @@ 'Linux FYI Experimental Release (Intel HD 630)', 'Linux FYI Release (Intel HD 630)', 'Linux FYI Release (NVIDIA)', + 'Linux FYI SkiaRenderer Vulkan (Intel HD 630)', 'Linux FYI SkiaRenderer Vulkan (NVIDIA)', 'Linux Release (NVIDIA)', 'Linux Release Code Coverage (NVIDIA)', @@ -1625,8 +1626,6 @@ 'remove_from': [ # chromium.win 'Win10 Tests x64', - # chromium.linux - 'Fuchsia x64', # https://crbug.com/961455 ], }, 'vr_android_unittests': {
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 7207fad5..0b899f8 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -190,6 +190,43 @@ 'wm_unittests': {}, }, + 'bfcache_gtests': { + 'bf_cache_content_unittests': { + 'args': [ + '--enable-features=BackForwardCache', + '--test-launcher-filter-file=../../testing/buildbot/filters/bfcache.content_unittests.filter' + ], + 'test': 'content_unittests', + }, + 'bf_cache_unit_tests': { + 'args': [ + '--enable-features=BackForwardCache', + '--test-launcher-filter-file=../../testing/buildbot/filters/bfcache.unit_tests.filter' + ], + 'test': 'unit_tests', + }, + 'bf_cache_content_browsertests': { + 'args': [ + '--enable-features=BackForwardCache', + '--test-launcher-filter-file=../../testing/buildbot/filters/bfcache.content_browsertests.filter' + ], + 'swarming': { + 'shards': 10, + }, + 'test': 'content_browsertests', + }, + 'bf_cache_browser_tests': { + 'args': [ + '--enable-features=BackForwardCache', + '--test-launcher-filter-file=../../testing/buildbot/filters/bfcache.browser_tests.filter' + ], + 'swarming': { + 'shards': 10, + }, + 'test': 'browser_tests', + }, + }, + 'cast_audio_specific_chromium_gtests': { 'cast_audio_backend_unittests': {}, 'cast_base_unittests': {}, @@ -2681,7 +2718,7 @@ 'blink_python_tests': {}, }, - 'fieldtrial_gtests': { + 'fieldtrial_browser_tests': { 'no_fieldtrial_browser_tests': { 'args': [ '--disable-field-trial-config', @@ -2691,40 +2728,6 @@ }, 'test': 'browser_tests', }, - 'bf_cache_content_unittests': { - 'args': [ - '--enable-features=BackForwardCache', - '--test-launcher-filter-file=../../testing/buildbot/filters/bfcache.content_unittests.filter' - ], - 'test': 'content_unittests', - }, - 'bf_cache_unit_tests': { - 'args': [ - '--enable-features=BackForwardCache', - '--test-launcher-filter-file=../../testing/buildbot/filters/bfcache.unit_tests.filter' - ], - 'test': 'unit_tests', - }, - 'bf_cache_content_browsertests': { - 'args': [ - '--enable-features=BackForwardCache', - '--test-launcher-filter-file=../../testing/buildbot/filters/bfcache.content_browsertests.filter' - ], - 'swarming': { - 'shards': 10, - }, - 'test': 'content_browsertests', - }, - 'bf_cache_browser_tests': { - 'args': [ - '--enable-features=BackForwardCache', - '--test-launcher-filter-file=../../testing/buildbot/filters/bfcache.browser_tests.filter' - ], - 'swarming': { - 'shards': 10, - }, - 'test': 'browser_tests', - }, }, 'fuchsia_gtests': {
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index d5657095..2611a588 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -1471,14 +1471,9 @@ }, 'WebKit Linux composite_after_paint Dummy Builder': { 'mixins': [ - 'linux-trusty', + 'linux-xenial', ], 'swarming': { - 'dimension_sets': [ - { - 'os': 'Ubuntu-14.04', - }, - ], 'hard_timeout': 900, }, 'test_suites': { @@ -1487,14 +1482,9 @@ }, 'WebKit Linux layout_ng Dummy Builder': { 'mixins': [ - 'linux-trusty', + 'linux-xenial', ], 'swarming': { - 'dimension_sets': [ - { - 'os': 'Ubuntu-14.04', - }, - ], 'hard_timeout': 900, }, 'test_suites': { @@ -1724,6 +1714,14 @@ 'scripts': 'test_traffic_annotation_auditor_script', } }, + 'linux-bfcache-rel': { + 'mixins': [ + 'linux-xenial', + ], + 'test_suites': { + 'gtest_tests': 'bfcache_gtests', + }, + }, 'linux-blink-animation-use-time-delta': { 'mixins': [ 'linux-xenial', @@ -1833,7 +1831,7 @@ 'linux-xenial', ], 'test_suites': { - 'gtest_tests': 'fieldtrial_gtests', + 'gtest_tests': 'fieldtrial_browser_tests', }, }, 'linux-wpt-fyi-rel': { @@ -2650,7 +2648,19 @@ 'gpu_telemetry_tests': 'gpu_fyi_linux_intel_and_nvidia_release_telemetry_tests', }, }, - 'Linux FYI SkiaRenderer Vulkan (NVIDIA)': { + 'Linux FYI SkiaRenderer Vulkan (Intel HD 630)': { + 'os_type': 'linux', + 'browser_config': 'release', + 'mixins': [ + 'linux_intel_hd_630', + ], + 'test_suites': { + 'gtest_tests': 'gpu_fyi_linux_release_gtests', + 'isolated_scripts': 'gpu_blink_web_tests', + 'gpu_telemetry_tests': 'gpu_skia_renderer_telemetry_tests', + }, + }, + 'Linux FYI SkiaRenderer Vulkan (NVIDIA)': { 'os_type': 'linux', 'browser_config': 'release', 'mixins': [
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 863fb48..2116cb6 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -4519,7 +4519,7 @@ { "name": "Enabled", "params": { - "ad_popup_trigger_quota": "5" + "ad_popup_trigger_quota": "10" }, "enable_features": [ "SafeBrowsingAdPopupTrigger" @@ -4541,7 +4541,7 @@ { "name": "Enabled", "params": { - "ad_redirect_trigger_quota": "5" + "ad_redirect_trigger_quota": "10" }, "enable_features": [ "SafeBrowsingAdRedirectTrigger"
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index e9424e0..f57ee22 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -363,7 +363,7 @@ "BlinkHeapConcurrentMarking", base::FEATURE_DISABLED_BY_DEFAULT}; // Enables concurrently sweeping Blink's heap. const base::Feature kBlinkHeapConcurrentSweeping{ - "BlinkHeapConcurrentSweeping", base::FEATURE_DISABLED_BY_DEFAULT}; + "BlinkHeapConcurrentSweeping", base::FEATURE_ENABLED_BY_DEFAULT}; // Enables incrementally marking Blink's heap. const base::Feature kBlinkHeapIncrementalMarking{ "BlinkHeapIncrementalMarking", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index 15db3d0..fc844272 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -156,7 +156,6 @@ "platform/modules/mediastream/web_media_stream_video_renderer.h", "platform/modules/mediastream/web_platform_media_stream_source.h", "platform/modules/mediastream/web_platform_media_stream_track.h", - "platform/modules/mediastream/webaudio_media_stream_source.h", "platform/modules/mediastream/webrtc_uma_histograms.h", "platform/modules/remoteplayback/web_remote_playback_client.h", "platform/modules/service_worker/web_service_worker_error.h", @@ -370,10 +369,8 @@ "web/mac/web_substring_util.h", "web/modules/autofill/web_form_element_observer.h", "web/modules/media/webmediaplayer_util.h", - "web/modules/mediastream/local_media_stream_audio_source.h", "web/modules/mediastream/media_stream_constraints_util.h", "web/modules/mediastream/media_stream_constraints_util_sets.h", - "web/modules/mediastream/media_stream_constraints_util_video_content.h", "web/modules/mediastream/media_stream_video_capturer_source.h", "web/modules/mediastream/media_stream_video_sink.h", "web/modules/mediastream/media_stream_video_source.h", @@ -451,6 +448,7 @@ "web/web_local_frame_client.h", "web/web_manifest_manager.h", "web/web_meaningful_layout.h", + "web/web_media_inspector.h", "web/web_media_player_action.h", "web/web_memory_statistics.h", "web/web_menu_item_info.h",
diff --git a/third_party/blink/public/mojom/choosers/color_chooser.mojom b/third_party/blink/public/mojom/choosers/color_chooser.mojom index c2525a2..e9c3d3b2 100644 --- a/third_party/blink/public/mojom/choosers/color_chooser.mojom +++ b/third_party/blink/public/mojom/choosers/color_chooser.mojom
@@ -12,8 +12,8 @@ // A ColorChooser window is shown for <input type="color">. interface ColorChooserFactory { OpenColorChooser( - ColorChooser& chooser, - ColorChooserClient client, + pending_receiver<ColorChooser> chooser, + pending_remote<ColorChooserClient> client, uint32 color, array<ColorSuggestion> suggestions); };
diff --git a/third_party/blink/public/mojom/indexeddb/indexeddb.mojom b/third_party/blink/public/mojom/indexeddb/indexeddb.mojom index 60f3876..286d9381 100644 --- a/third_party/blink/public/mojom/indexeddb/indexeddb.mojom +++ b/third_party/blink/public/mojom/indexeddb/indexeddb.mojom
@@ -33,8 +33,6 @@ }; // In order of the least to the highest precedent in terms of sort order. -// These values are written to logs. New enum values can be added, but -// existing enums must never be renumbered or deleted and reused. enum IDBKeyType { // Invalid is used in blink bindings code. When converting a V8 value that // is not a valid key, key of this type is returned. Outside of testing
diff --git a/third_party/blink/public/mojom/permissions/permission.mojom b/third_party/blink/public/mojom/permissions/permission.mojom index dd220391..0dcfed5 100644 --- a/third_party/blink/public/mojom/permissions/permission.mojom +++ b/third_party/blink/public/mojom/permissions/permission.mojom
@@ -80,5 +80,5 @@ // access to |permission|. Closing the pipe will cancel the subscription. AddPermissionObserver(PermissionDescriptor permission, PermissionStatus last_known_status, - PermissionObserver observer); + pending_remote<PermissionObserver> observer); };
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h index f999e6f..ef920b66 100644 --- a/third_party/blink/public/platform/web_runtime_features.h +++ b/third_party/blink/public/platform/web_runtime_features.h
@@ -123,7 +123,6 @@ bool); BLINK_PLATFORM_EXPORT static void EnableNavigatorContentUtils(bool); BLINK_PLATFORM_EXPORT static void EnableNetInfoDownlinkMax(bool); - BLINK_PLATFORM_EXPORT static void EnableNetworkService(bool); BLINK_PLATFORM_EXPORT static void EnableUpdateHoverAtBeginFrame(bool); BLINK_PLATFORM_EXPORT static void EnableNotificationConstructor(bool); BLINK_PLATFORM_EXPORT static void EnableNotificationContentImage(bool);
diff --git a/third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_video_content.h b/third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_video_content.h deleted file mode 100644 index 9b49b8e..0000000 --- a/third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_video_content.h +++ /dev/null
@@ -1,36 +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 THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_VIDEO_CONTENT_H_ -#define THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_VIDEO_CONTENT_H_ - -#include "third_party/blink/public/common/mediastream/media_stream_request.h" -#include "third_party/blink/public/platform/web_common.h" -#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h" - -namespace blink { - -class WebMediaConstraints; - -// TODO(crbug.com/704136): Move these helpers out of the Blink exposed API -// when all users of it have been Onion souped. -BLINK_MODULES_EXPORT extern const int kMinScreenCastDimension; -BLINK_MODULES_EXPORT extern const int kMaxScreenCastDimension; -BLINK_MODULES_EXPORT extern const int kDefaultScreenCastWidth; -BLINK_MODULES_EXPORT extern const int kDefaultScreenCastHeight; - -BLINK_MODULES_EXPORT extern const double kMaxScreenCastFrameRate; -BLINK_MODULES_EXPORT extern const double kDefaultScreenCastFrameRate; - -// This function performs source, source-settings and track-settings selection -// for content video capture based on the given |constraints|. -VideoCaptureSettings BLINK_MODULES_EXPORT -SelectSettingsVideoContentCapture(const blink::WebMediaConstraints& constraints, - blink::mojom::MediaStreamType stream_type, - int screen_width, - int screen_height); - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_VIDEO_CONTENT_H_
diff --git a/third_party/blink/public/web/web_local_frame.h b/third_party/blink/public/web/web_local_frame.h index 0bfaf0fe..a781a44 100644 --- a/third_party/blink/public/web/web_local_frame.h +++ b/third_party/blink/public/web/web_local_frame.h
@@ -767,6 +767,12 @@ virtual void WasHidden() = 0; virtual void WasShown() = 0; + // Grants ability to lookup a named frame via the FindFrame + // WebLocalFrameClient API. Enhanced binding security checks that check the + // agent cluster will be enabled for windows that do not have this permission. + // This should only be used for extensions and the webview tag. + virtual void SetAllowsCrossBrowsingInstanceFrameLookup() = 0; + protected: explicit WebLocalFrame(WebTreeScopeType scope) : WebFrame(scope) {}
diff --git a/third_party/blink/public/web/web_media_inspector.h b/third_party/blink/public/web/web_media_inspector.h new file mode 100644 index 0000000..8aae3cbc --- /dev/null +++ b/third_party/blink/public/web/web_media_inspector.h
@@ -0,0 +1,43 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_MEDIA_INSPECTOR_H_ +#define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_MEDIA_INSPECTOR_H_ + +#include "base/time/time.h" +#include "third_party/blink/public/platform/web_string.h" +#include "third_party/blink/public/platform/web_vector.h" + +namespace blink { + +// These types should look exactly like the types defined in +// browser_protocol.pdl and should eventually replace the types in +// //src/media/base +struct InspectorPlayerProperty { + WebString name; + base::Optional<WebString> value; +}; +using InspectorPlayerProperties = WebVector<InspectorPlayerProperty>; + +struct InspectorPlayerEvent { + enum InspectorPlayerEventType { PLAYBACK_EVENT, SYSTEM_EVENT, MESSAGE_EVENT }; + InspectorPlayerEventType type; + base::TimeTicks timestamp; + WebString key; + WebString value; +}; +using InspectorPlayerEvents = WebVector<InspectorPlayerEvent>; + +class MediaInspectorContext { + public: + virtual WebString CreatePlayer() = 0; + + // These methods DCHECK if the player id is invalid. + virtual void NotifyPlayerEvents(WebString, InspectorPlayerEvents) = 0; + virtual void SetPlayerProperties(WebString, InspectorPlayerProperties) = 0; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_MEDIA_INSPECTOR_H_
diff --git a/third_party/blink/renderer/bindings/modules/BUILD.gn b/third_party/blink/renderer/bindings/modules/BUILD.gn index 11fccb2..0f17d1f 100644 --- a/third_party/blink/renderer/bindings/modules/BUILD.gn +++ b/third_party/blink/renderer/bindings/modules/BUILD.gn
@@ -33,6 +33,8 @@ "//third_party/blink/renderer/modules/gamepad/gamepad_axis_event.idl", "//third_party/blink/renderer/modules/gamepad/gamepad_button_event.idl", "//third_party/blink/renderer/modules/gamepad/gamepad_event.idl", + "//third_party/blink/renderer/modules/hid/hid_connection_event.idl", + "//third_party/blink/renderer/modules/hid/hid_input_report_event.idl", "//third_party/blink/renderer/modules/indexeddb/idb_version_change_event.idl", "//third_party/blink/renderer/modules/mediarecorder/blob_event.idl", "//third_party/blink/renderer/modules/mediastream/media_stream_event.idl",
diff --git a/third_party/blink/renderer/bindings/scripts/generate_web_idl_database.py b/third_party/blink/renderer/bindings/scripts/generate_web_idl_database.py deleted file mode 100755 index 773130b..0000000 --- a/third_party/blink/renderer/bindings/scripts/generate_web_idl_database.py +++ /dev/null
@@ -1,41 +0,0 @@ -#!/usr/bin/python -# -# 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. - -"""Generates a data collection of IDL information per component. -This scripts parses IDL files and stores the result ASTs in a pickle file. -The output file may contain information about component, too. -""" - -import optparse -import utilities -from web_idl.idl_compiler import IdlCompiler -from web_idl import ir_builder -from web_idl.identifier_ir_map import IdentifierIRMap - - -def parse_options(): - parser = optparse.OptionParser() - parser.add_option('--output', type='string', - help='pickle file to write down') - options, args = parser.parse_args() - - if options.output is None: - parser.error('Must specify a pickle file to output using --output.') - - return options, args - - -def main(): - options, filepaths = parse_options() - ir_map = IdentifierIRMap() - ir_builder.load_and_register_idl_definitions(filepaths, ir_map) - idl_compiler = IdlCompiler(ir_map) - idl_database = idl_compiler.build_database() - utilities.write_pickle_file(options.output, idl_database) - - -if __name__ == '__main__': - main()
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/attribute.py b/third_party/blink/renderer/bindings/scripts/web_idl/attribute.py index 22f6e3b..ad703dd 100644 --- a/third_party/blink/renderer/bindings/scripts/web_idl/attribute.py +++ b/third_party/blink/renderer/bindings/scripts/web_idl/attribute.py
@@ -2,23 +2,21 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import exceptions - from .composition_parts import WithCodeGeneratorInfo from .composition_parts import WithComponent from .composition_parts import WithDebugInfo -from .composition_parts import WithExposure from .composition_parts import WithExtendedAttributes from .composition_parts import WithIdentifier -from .idl_member import IdlMember +from .composition_parts import WithOwner from .idl_type import IdlType -class Attribute(IdlMember): +class Attribute(WithIdentifier, WithExtendedAttributes, WithCodeGeneratorInfo, + WithOwner, WithComponent, WithDebugInfo): """https://heycam.github.io/webidl/#idl-attributes""" - class IR(WithIdentifier, WithExtendedAttributes, WithExposure, - WithCodeGeneratorInfo, WithComponent, WithDebugInfo): + class IR(WithIdentifier, WithExtendedAttributes, WithCodeGeneratorInfo, + WithComponent, WithDebugInfo): def __init__(self, identifier, idl_type, @@ -26,7 +24,6 @@ is_readonly=False, does_inherit_getter=False, extended_attributes=None, - exposures=None, code_generator_info=None, component=None, components=None, @@ -38,7 +35,6 @@ WithIdentifier.__init__(self, identifier) WithExtendedAttributes.__init__(self, extended_attributes) - WithExposure.__init__(self, exposures) WithCodeGeneratorInfo.__init__(self, code_generator_info) WithComponent.__init__( self, component=component, components=components) @@ -61,35 +57,42 @@ components=self.components, debug_info=self.debug_info.make_copy()) + def __init__(self, ir, owner): + assert isinstance(ir, Attribute.IR) + + WithIdentifier.__init__(self, ir.identifier) + WithExtendedAttributes.__init__(self, + ir.extended_attributes.make_copy()) + WithCodeGeneratorInfo.__init__(self, + ir.code_generator_info.make_copy()) + WithOwner.__init__(self, owner) + WithComponent.__init__(self, components=ir.components) + WithDebugInfo.__init__(self, ir.debug_info.make_copy()) + + self._idl_type = ir.idl_type + self._is_static = ir.is_static + self._is_readonly = ir.is_readonly + self._does_inherit_getter = ir.does_inherit_getter + @property def idl_type(self): - """ - Returns type of this attribute. - @return IdlType - """ - raise exceptions.NotImplementedError() + """Returns the type.""" + return self._idl_type @property def is_static(self): - """ - Returns True if this attriute is static. - @return bool - """ - raise exceptions.NotImplementedError() + """Returns True if this attriute is static.""" + return self._is_static @property def is_readonly(self): - """ - Returns True if this attribute is read only. - @return bool - """ - raise exceptions.NotImplementedError() + """Returns True if this attribute is read only.""" + return self._is_readonly @property def does_inherit_getter(self): """ - Returns True if |self| inherits its getter. + Returns True if this attribute inherits its getter. https://heycam.github.io/webidl/#dfn-inherit-getter - @return bool """ - raise exceptions.NotImplementedError() + return self._does_inherit_getter
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/composition_parts.py b/third_party/blink/renderer/bindings/scripts/web_idl/composition_parts.py index f13f4c6..d2a7b8eb 100644 --- a/third_party/blink/renderer/bindings/scripts/web_idl/composition_parts.py +++ b/third_party/blink/renderer/bindings/scripts/web_idl/composition_parts.py
@@ -61,14 +61,8 @@ """Implements |exposures| as a readonly attribute.""" def __init__(self, exposures=None): - assert (exposures is None - or (isinstance(exposures, (list, tuple)) and all( - isinstance(exposure, Exposure) for exposure in exposures))) - self._exposures = tuple(exposures or ()) - - @property - def exposures(self): - return self._exposures + # TODO(peria): Design Exposure and this class. + pass class Component(str):
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/constant.py b/third_party/blink/renderer/bindings/scripts/web_idl/constant.py index 5238854..f93addbd 100644 --- a/third_party/blink/renderer/bindings/scripts/web_idl/constant.py +++ b/third_party/blink/renderer/bindings/scripts/web_idl/constant.py
@@ -6,64 +6,71 @@ from .composition_parts import WithComponent from .composition_parts import WithDebugInfo from .composition_parts import WithExtendedAttributes -from .composition_parts import WithExposure from .composition_parts import WithIdentifier -from .idl_member import IdlMember +from .composition_parts import WithOwner from .idl_type import IdlType from .values import ConstantValue -class Constant(IdlMember): +class Constant(WithIdentifier, WithExtendedAttributes, WithCodeGeneratorInfo, + WithOwner, WithComponent, WithDebugInfo): """https://heycam.github.io/webidl/#idl-constants""" - class IR(WithIdentifier, WithExtendedAttributes, WithExposure, - WithCodeGeneratorInfo, WithComponent, WithDebugInfo): + class IR(WithIdentifier, WithExtendedAttributes, WithCodeGeneratorInfo, + WithComponent, WithDebugInfo): def __init__(self, identifier, - value, idl_type, + value, extended_attributes=None, - exposures=None, code_generator_info=None, component=None, components=None, debug_info=None): - assert isinstance(value, ConstantValue) assert isinstance(idl_type, IdlType) + assert isinstance(value, ConstantValue) WithIdentifier.__init__(self, identifier) WithExtendedAttributes.__init__(self, extended_attributes) - WithExposure.__init__(self, exposures) WithCodeGeneratorInfo.__init__(self, code_generator_info) WithComponent.__init__( self, component=component, components=components) WithDebugInfo.__init__(self, debug_info) - self.value = value self.idl_type = idl_type + self.value = value def make_copy(self): return Constant.IR( identifier=self.identifier, - value=self.value, idl_type=self.idl_type, + value=self.value, extended_attributes=self.extended_attributes.make_copy(), code_generator_info=self.code_generator_info.make_copy(), components=self.components, debug_info=self.debug_info.make_copy()) + def __init__(self, ir, owner): + assert isinstance(ir, Constant.IR) + + WithIdentifier.__init__(self, ir.identifier) + WithExtendedAttributes.__init__(self, + ir.extended_attributes.make_copy()) + WithCodeGeneratorInfo.__init__(self, + ir.code_generator_info.make_copy()) + WithOwner.__init__(self, owner) + WithComponent.__init__(self, components=ir.components) + WithDebugInfo.__init__(self, ir.debug_info.make_copy()) + + self._idl_type = ir.idl_type + self._value = ir.value + @property def idl_type(self): - """ - Returns the type of this constant. - @return IdlType - """ - assert False, 'To be implemented' + """Returns the type""" + return self._idl_type @property def value(self): - """ - Returns the constant value. - @return ConstantValue - """ - assert False, 'To be implemented' + """Returns the value.""" + return self._value
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/idl_compiler.py b/third_party/blink/renderer/bindings/scripts/web_idl/idl_compiler.py index aea5100..86875bac 100644 --- a/third_party/blink/renderer/bindings/scripts/web_idl/idl_compiler.py +++ b/third_party/blink/renderer/bindings/scripts/web_idl/idl_compiler.py
@@ -8,9 +8,11 @@ from .dictionary import Dictionary from .identifier_ir_map import IdentifierIRMap from .idl_type import IdlTypeFactory +from .interface import Interface from .reference import RefByIdFactory from .typedef import Typedef from .union import Union +from .user_defined_type import StubUserDefinedType from .user_defined_type import UserDefinedType @@ -189,6 +191,11 @@ def _create_public_objects(self): """Creates public representations of compiled objects.""" + interface_irs = self._ir_map.find_by_kind( + IdentifierIRMap.IR.Kind.INTERFACE) + for ir in interface_irs.itervalues(): + self._db.register(DatabaseBody.Kind.INTERFACE, Interface(ir)) + dictionary_irs = self._ir_map.find_by_kind( IdentifierIRMap.IR.Kind.DICTIONARY) for ir in dictionary_irs.itervalues(): @@ -206,7 +213,7 @@ except KeyError: self._report_error("{}: Unresolved reference to {}".format( ref.ref_own_debug_info.location, ref.identifier)) - idl_def = UserDefinedType(ref.identifier) # dummy stub + idl_def = StubUserDefinedType(ref.identifier) ref.set_target_object(idl_def) self._ref_to_idl_def_factory.for_each(resolve) @@ -218,7 +225,7 @@ except KeyError: self._report_error("{}: Unresolved reference to {}".format( ref.ref_own_debug_info.location, ref.identifier)) - idl_def = UserDefinedType(ref.identifier) # dummy stub + idl_def = StubUserDefinedType(ref.identifier) if isinstance(idl_def, UserDefinedType): idl_type = self._idl_type_factory.definition_type( user_defined_type=idl_def)
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/idl_member.py b/third_party/blink/renderer/bindings/scripts/web_idl/idl_member.py index 22491d0b..f4ff13e5 100644 --- a/third_party/blink/renderer/bindings/scripts/web_idl/idl_member.py +++ b/third_party/blink/renderer/bindings/scripts/web_idl/idl_member.py
@@ -5,13 +5,12 @@ from .composition_parts import WithCodeGeneratorInfo from .composition_parts import WithComponent from .composition_parts import WithDebugInfo -from .composition_parts import WithExposure from .composition_parts import WithExtendedAttributes from .composition_parts import WithIdentifier from .composition_parts import WithOwner class IdlMember(WithIdentifier, WithExtendedAttributes, WithCodeGeneratorInfo, - WithExposure, WithOwner, WithComponent, WithDebugInfo): + WithOwner, WithComponent, WithDebugInfo): """IdlMember provides common APIs for IDL members; attributes, operations, constants, dictionary members, etc."""
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/idl_type.py b/third_party/blink/renderer/bindings/scripts/web_idl/idl_type.py index 804e0b14..e26806e 100644 --- a/third_party/blink/renderer/bindings/scripts/web_idl/idl_type.py +++ b/third_party/blink/renderer/bindings/scripts/web_idl/idl_type.py
@@ -166,6 +166,17 @@ """ raise exceptions.NotImplementedError() + def apply_to_all_composing_elements(self, callback): + """ + Applies |callback| to all instances of IdlType of which this IdlType + consists, including |self|. + + In case of x.apply_to_all_composing_elements(callback), |callback| will + be recursively called back on x, x.inner_type, x.element_type, + x.result_type.original_type, etc. if any. + """ + callback(self) + @property def does_include_nullable_type(self): """ @@ -368,6 +379,16 @@ """Returns the inner type of type IdlType if |is_nullable|.""" return None + @property + def type_definition_object(self): + """ + Returns an object that represents a spec-author-defined type or None. + + Note that a returned object is not an IdlType. In case of interface, + a returned object is an instance of Interface. + """ + return None + def _format_syntactic_form(self, syntactic_form_inner): """Helper function to implement |syntactic_form|.""" optional_form = 'optional ' if self.is_optional else '' @@ -533,7 +554,7 @@ debug_info=debug_info, pass_key=pass_key) WithIdentifier.__init__(self, user_defined_type.identifier) - self._definition = user_defined_type + self._type_definition_object = user_defined_type def __eq__(self, other): return (IdlType.__eq__(self, other) @@ -557,23 +578,27 @@ @property def is_interface(self): - return self._definition.is_interface + return self.type_definition_object.is_interface @property def is_callback_interface(self): - return self._definition.is_callback_interface + return self.type_definition_object.is_callback_interface @property def is_dictionary(self): - return self._definition.is_dictionary + return self.type_definition_object.is_dictionary @property def is_enumeration(self): - return self._definition.is_enumeration + return self.type_definition_object.is_enumeration @property def is_callback_function(self): - return self._definition.is_callback_function + return self.type_definition_object.is_callback_function + + @property + def type_definition_object(self): + return self._type_definition_object class TypedefType(IdlType, WithIdentifier): @@ -621,6 +646,10 @@ assert not self.is_optional return self.original_type.type_name + def apply_to_all_composing_elements(self, callback): + callback(self) + self.original_type.apply_to_all_composing_elements(callback) + @property def does_include_nullable_type(self): return self.original_type.does_include_nullable_type @@ -660,6 +689,10 @@ return hash((self.__class__, self.element_type)) # IdlType overrides + def apply_to_all_composing_elements(self, callback): + callback(self) + self.element_type.apply_to_all_composing_elements(callback) + @property def element_type(self): return self._element_type @@ -810,6 +843,11 @@ return self._format_type_name('{}{}Record'.format( self.key_type.type_name, self.value_type.type_name)) + def apply_to_all_composing_elements(self, callback): + callback(self) + self.key_type.apply_to_all_composing_elements(callback) + self.value_type.apply_to_all_composing_elements(callback) + @property def is_record(self): return True @@ -861,6 +899,10 @@ return self._format_type_name('{}Promise'.format( self.result_type.type_name)) + def apply_to_all_composing_elements(self, callback): + callback(self) + self.result_type.apply_to_all_composing_elements(callback) + @property def is_promise(self): return True @@ -926,6 +968,11 @@ return self._format_type_name('Or'.join( [member.type_name for member in self.member_types])) + def apply_to_all_composing_elements(self, callback): + callback(self) + for member_type in self.member_types: + member_type.apply_to_all_composing_elements(callback) + @property def does_include_nullable_type(self): return any( @@ -1003,6 +1050,10 @@ sep_index = len(name) - len(ext_attrs) return '{}OrNull{}'.format(name[0:sep_index], name[sep_index:]) + def apply_to_all_composing_elements(self, callback): + callback(self) + self.inner_type.apply_to_all_composing_elements(callback) + @property def does_include_nullable_type(self): return True
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/interface.py b/third_party/blink/renderer/bindings/scripts/web_idl/interface.py index 7f57781..547d66c9 100644 --- a/third_party/blink/renderer/bindings/scripts/web_idl/interface.py +++ b/third_party/blink/renderer/bindings/scripts/web_idl/interface.py
@@ -2,13 +2,10 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import exceptions - from .attribute import Attribute from .composition_parts import WithCodeGeneratorInfo from .composition_parts import WithComponent from .composition_parts import WithDebugInfo -from .composition_parts import WithExposure from .composition_parts import WithExtendedAttributes from .constant import Constant from .identifier_ir_map import IdentifierIRMap @@ -19,18 +16,12 @@ from .user_defined_type import UserDefinedType -class Interface(UserDefinedType, WithExtendedAttributes, WithExposure, - WithCodeGeneratorInfo, WithComponent, WithDebugInfo): - """A summarized interface definition in IDL. +class Interface(UserDefinedType, WithExtendedAttributes, WithCodeGeneratorInfo, + WithComponent, WithDebugInfo): + """https://heycam.github.io/webidl/#idl-interfaces""" - Interface provides information about an interface, partial interfaces, - interface mixins, and partial interface mixins, as if they were all - gathered in an interface. - https://heycam.github.io/webidl/#idl-interfaces - """ - - class IR(IdentifierIRMap.IR, WithExtendedAttributes, WithExposure, - WithCodeGeneratorInfo, WithComponent, WithDebugInfo): + class IR(IdentifierIRMap.IR, WithExtendedAttributes, WithCodeGeneratorInfo, + WithComponent, WithDebugInfo): def __init__(self, identifier, is_partial, @@ -43,7 +34,6 @@ maplike=None, setlike=None, extended_attributes=None, - exposures=None, code_generator_info=None, component=None, components=None, @@ -83,7 +73,6 @@ kind = IdentifierIRMap.IR.Kind.INTERFACE IdentifierIRMap.IR.__init__(self, identifier=identifier, kind=kind) WithExtendedAttributes.__init__(self, extended_attributes) - WithExposure.__init__(self, exposures) WithCodeGeneratorInfo.__init__(self, code_generator_info) WithComponent.__init__( self, component=component, components=components) @@ -116,67 +105,81 @@ components=self.components, debug_info=self.debug_info.make_copy()) + def __init__(self, ir): + assert isinstance(ir, Interface.IR) + assert not ir.is_partial + + UserDefinedType.__init__(self, ir.identifier) + WithExtendedAttributes.__init__(self, + ir.extended_attributes.make_copy()) + WithCodeGeneratorInfo.__init__(self, + ir.code_generator_info.make_copy()) + WithComponent.__init__(self, components=ir.components) + WithDebugInfo.__init__(self, ir.debug_info.make_copy()) + + self._is_mixin = ir.is_mixin + self._inherited = ir.inherited + self._attributes = tuple([ + Attribute(attribute_ir, owner=self) + for attribute_ir in ir.attributes + ]) + self._constants = tuple([ + Constant(constant_ir, owner=self) for constant_ir in ir.constants + ]) + self._iterable = ir.iterable + self._maplike = ir.maplike + self._setlike = ir.setlike + + @property + def is_mixin(self): + """Returns True if this is a mixin interface.""" + return self._is_mixin @property def inherited_interface(self): - """ - Returns an Interface from which this interface inherits. If this - interface does not inherit, returns None. - @return Interface? - """ - raise exceptions.NotImplementedError() + """Returns the inherited interface or None.""" + return self._inherited.target_object if self._inherited else None @property def attributes(self): """ - Returns a tuple of attributes including [Unforgeable] attributes in - ancestors. - @return tuple(Attribute) + Returns attributes, including [Unforgeable] attributes in ancestors. """ - raise exceptions.NotImplementedError() + return self._attributes @property def operation_groups(self): """ - Returns a tuple of OperationGroup. Each OperationGroup has operation(s) - defined in this interface and [Unforgeable] operations in ancestors. - @return tuple(OperationGroup) + Returns groups of operations, including [Unforgeable] operations in + ancestors. Operation groups are sorted by their identifier. + + All operations are grouped by their identifier in OperationGroup's, + even when there exists a single operation with that identifier. """ - raise exceptions.NotImplementedError() + assert False, "Not implemented yet." @property def constants(self): - """ - Returns a tuple of constants defined in this interface. - @return tuple(Constant) - """ - raise exceptions.NotImplementedError() + """Returns constants.""" + return self._constants @property def constructors(self): - """ - Returns ConstructorGroup instance for this interface. - @return tuple(ConstructorGroup) - """ - raise exceptions.NotImplementedError() + """Returns a constructor group.""" + assert False, "Not implemented yet." @property def named_constructor(self): - """ - Returns a named constructor, if this interface has it. Otherwise, returns - None. - @return NamedConstructor? - """ - raise exceptions.NotImplementedError() + """Returns a named constructor or None.""" + assert False, "Not implemented yet." @property def exposed_interfaces(self): """ - Returns a tuple of Interfaces that are exposed to |self|. If |self| is - not a global interface, returns an empty tuple. - @return tuple(Interface) + Returns a tuple of interfaces that are exposed to this interface, if + this is a global interface. Returns None otherwise. """ - raise exceptions.NotImplementedError() + assert False, "Not implemented yet." # Special operations @property @@ -187,7 +190,7 @@ @return IndexedPropertyHandler? """ # TODO: Include anonymous handlers of ancestors. https://crbug.com/695972 - raise exceptions.NotImplementedError() + assert False, "Not implemented yet." @property def named_property_handler(self): @@ -197,7 +200,7 @@ @return NamedPropertyHandler? """ # TODO: Include anonymous handlers of ancestors. https://crbug.com/695972 - raise exceptions.NotImplementedError() + assert False, "Not implemented yet." @property def stringifier(self): @@ -205,31 +208,22 @@ Returns stringifier if it is defined. Returns None otherwise. @return TBD? """ - raise exceptions.NotImplementedError() + assert False, "Not implemented yet." @property def iterable(self): - """ - Returns iterable if it is defined. Returns None otherwise. - @return Iterable? - """ - raise exceptions.NotImplementedError() + """Returns an Iterable or None.""" + return self._iterable @property def maplike(self): - """ - Returns maplike if it is defined. Returns None otherwise. - @return Maplike? - """ - raise exceptions.NotImplementedError() + """Returns a Maplike or None.""" + return self._maplike @property def setlike(self): - """ - Returns setlike if it is defined. Returns None otherwise. - @return Setlike? - """ - raise exceptions.NotImplementedError() + """Returns a Setlike or None.""" + return self._setlike # UserDefinedType overrides @property @@ -261,18 +255,12 @@ @property def key_type(self): - """ - Returns the key type or None. - @return IdlType? - """ + """Returns the key type or None.""" return self._key_type @property def value_type(self): - """ - Returns the value type. - @return IdlType - """ + """Returns the value type.""" return self._value_type @@ -362,7 +350,7 @@ Returns an Operation for indexed property getter. @return Operation? """ - raise exceptions.NotImplementedError() + assert False, "Not implemented yet." @property def setter(self): @@ -370,7 +358,7 @@ Returns an Operation for indexed property setter. @return Operation? """ - raise exceptions.NotImplementedError() + assert False, "Not implemented yet." @property def deleter(self): @@ -378,7 +366,7 @@ Returns an Operation for indexed property deleter. @return Operation? """ - raise exceptions.NotImplementedError() + assert False, "Not implemented yet." class NamedPropertyHandler(IdlMember): @@ -388,7 +376,7 @@ Returns an Operation for named property getter. @return Operation? """ - raise exceptions.NotImplementedError() + assert False, "Not implemented yet." @property def setter(self): @@ -396,7 +384,7 @@ Returns an Operation for named property setter. @return Operation? """ - raise exceptions.NotImplementedError() + assert False, "Not implemented yet." @property def deleter(self): @@ -404,4 +392,4 @@ Returns an Operation for named property deleter. @return Operation? """ - raise exceptions.NotImplementedError() + assert False, "Not implemented yet."
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/ir_builder.py b/third_party/blink/renderer/bindings/scripts/web_idl/ir_builder.py index 7eb14e7..d65b8d99 100644 --- a/third_party/blink/renderer/bindings/scripts/web_idl/ir_builder.py +++ b/third_party/blink/renderer/bindings/scripts/web_idl/ir_builder.py
@@ -179,8 +179,8 @@ idl_type = self._build_type_internal(child_nodes) return Constant.IR( identifier=Identifier(node.GetName()), - value=value, idl_type=idl_type, + value=value, extended_attributes=extended_attributes, component=self._component, debug_info=self._build_debug_info(node))
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/namespace.py b/third_party/blink/renderer/bindings/scripts/web_idl/namespace.py index 9762b102..20a8998 100644 --- a/third_party/blink/renderer/bindings/scripts/web_idl/namespace.py +++ b/third_party/blink/renderer/bindings/scripts/web_idl/namespace.py
@@ -7,23 +7,21 @@ from .composition_parts import WithCodeGeneratorInfo from .composition_parts import WithComponent from .composition_parts import WithDebugInfo -from .composition_parts import WithExposure from .composition_parts import WithExtendedAttributes from .composition_parts import WithIdentifier from .identifier_ir_map import IdentifierIRMap -class Namespace(WithIdentifier, WithExtendedAttributes, WithExposure, - WithCodeGeneratorInfo, WithComponent, WithDebugInfo): +class Namespace(WithIdentifier, WithExtendedAttributes, WithCodeGeneratorInfo, + WithComponent, WithDebugInfo): """https://heycam.github.io/webidl/#idl-namespaces""" - class IR(IdentifierIRMap.IR, WithExtendedAttributes, WithExposure, - WithCodeGeneratorInfo, WithComponent, WithDebugInfo): + class IR(IdentifierIRMap.IR, WithExtendedAttributes, WithCodeGeneratorInfo, + WithComponent, WithDebugInfo): def __init__(self, identifier, is_partial, extended_attributes=None, - exposures=None, code_generator_info=None, component=None, debug_info=None): @@ -31,7 +29,6 @@ if is_partial else IdentifierIRMap.IR.Kind.NAMESPACE) IdentifierIRMap.IR.__init__(self, identifier=identifier, kind=kind) WithExtendedAttributes.__init__(self, extended_attributes) - WithExposure.__init__(self, exposures) WithCodeGeneratorInfo.__init__(self, code_generator_info) WithComponent.__init__(self, component) WithDebugInfo.__init__(self, debug_info)
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/operation.py b/third_party/blink/renderer/bindings/scripts/web_idl/operation.py index 008c1e3..692eef91 100644 --- a/third_party/blink/renderer/bindings/scripts/web_idl/operation.py +++ b/third_party/blink/renderer/bindings/scripts/web_idl/operation.py
@@ -8,7 +8,6 @@ from .composition_parts import WithCodeGeneratorInfo from .composition_parts import WithComponent from .composition_parts import WithDebugInfo -from .composition_parts import WithExposure from .composition_parts import WithExtendedAttributes from .composition_parts import WithIdentifier from .composition_parts import WithOwner @@ -20,15 +19,14 @@ """https://heycam.github.io/webidl/#idl-operations https://www.w3.org/TR/WebIDL-1/#idl-special-operations""" - class IR(WithIdentifier, WithExtendedAttributes, WithExposure, - WithCodeGeneratorInfo, WithComponent, WithDebugInfo): + class IR(WithIdentifier, WithExtendedAttributes, WithCodeGeneratorInfo, + WithComponent, WithDebugInfo): def __init__(self, identifier, arguments, return_type, is_static=False, extended_attributes=None, - exposures=None, code_generator_info=None, component=None, components=None, @@ -40,7 +38,6 @@ WithIdentifier.__init__(self, identifier) WithExtendedAttributes.__init__(self, extended_attributes) - WithExposure.__init__(self, exposures) WithCodeGeneratorInfo.__init__(self, code_generator_info) WithComponent.__init__( self, component=component, components=components)
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/union.py b/third_party/blink/renderer/bindings/scripts/web_idl/union.py index c28677b6..b25a69a 100644 --- a/third_party/blink/renderer/bindings/scripts/web_idl/union.py +++ b/third_party/blink/renderer/bindings/scripts/web_idl/union.py
@@ -62,10 +62,19 @@ sort_key = lambda x: x.syntactic_form + components = set() + + def collect_components(idl_type): + user_defined_type = idl_type.type_definition_object + if user_defined_type: + components.update(user_defined_type.components) + + for idl_type in flattened_members: + idl_type.apply_to_all_composing_elements(collect_components) + WithIdentifier.__init__(self, identifier) WithCodeGeneratorInfo.__init__(self) - # TODO(yukishiino): Set components to the components of member types. - WithComponent.__init__(self, components=[]) + WithComponent.__init__(self, components=sorted(components)) WithDebugInfo.__init__(self) # Sort improves reproducibility.
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/user_defined_type.py b/third_party/blink/renderer/bindings/scripts/web_idl/user_defined_type.py index eee2887..434c3b78 100644 --- a/third_party/blink/renderer/bindings/scripts/web_idl/user_defined_type.py +++ b/third_party/blink/renderer/bindings/scripts/web_idl/user_defined_type.py
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +from .composition_parts import WithComponent from .composition_parts import WithIdentifier @@ -55,3 +56,9 @@ @return bool """ return False + + +class StubUserDefinedType(UserDefinedType, WithComponent): + def __init__(self, identifier): + UserDefinedType.__init__(self, identifier) + WithComponent.__init__(self, components=[])
diff --git a/third_party/blink/renderer/core/animation/BUILD.gn b/third_party/blink/renderer/core/animation/BUILD.gn index 24ab67be..13544228b 100644 --- a/third_party/blink/renderer/core/animation/BUILD.gn +++ b/third_party/blink/renderer/core/animation/BUILD.gn
@@ -45,6 +45,8 @@ "css/css_animations.h", "css/css_timing_data.cc", "css/css_timing_data.h", + "css/css_transition.cc", + "css/css_transition.h", "css/css_transition_data.cc", "css/css_transition_data.h", "css_angle_interpolation_type.cc",
diff --git a/third_party/blink/renderer/core/animation/css/css_animation.cc b/third_party/blink/renderer/core/animation/css/css_animation.cc index b5bde1f..07e7b2ca 100644 --- a/third_party/blink/renderer/core/animation/css/css_animation.cc +++ b/third_party/blink/renderer/core/animation/css/css_animation.cc
@@ -8,16 +8,8 @@ CSSAnimation* CSSAnimation::Create(AnimationEffect* effect, AnimationTimeline* timeline, - String animation_name, - ExceptionState& exception_state) { - DCHECK(timeline); - if (!timeline->IsDocumentTimeline()) { - exception_state.ThrowDOMException( - DOMExceptionCode::kNotSupportedError, - "Invalid timeline. CSSAnimation requires a DocumentTimeline"); - return nullptr; - } - DCHECK(timeline->IsDocumentTimeline()); + const String& animation_name) { + DCHECK(timeline && timeline->IsDocumentTimeline()); return MakeGarbageCollected<CSSAnimation>( timeline->GetDocument()->ContextDocument(), timeline, effect, @@ -27,13 +19,13 @@ CSSAnimation::CSSAnimation(ExecutionContext* execution_context, AnimationTimeline* timeline, AnimationEffect* content, - String animation_name) + const String& animation_name) : Animation(execution_context, timeline, content), animation_name_(animation_name) { setId(animation_name); } -String CSSAnimation::animationName() { +const String& CSSAnimation::animationName() const { return animation_name_; }
diff --git a/third_party/blink/renderer/core/animation/css/css_animation.h b/third_party/blink/renderer/core/animation/css/css_animation.h index 2b01fee..7fa0885 100644 --- a/third_party/blink/renderer/core/animation/css/css_animation.h +++ b/third_party/blink/renderer/core/animation/css/css_animation.h
@@ -17,15 +17,14 @@ public: static CSSAnimation* Create(AnimationEffect*, AnimationTimeline*, - String animation_name, - ExceptionState& = ASSERT_NO_EXCEPTION); + const String& animation_name); CSSAnimation(ExecutionContext*, AnimationTimeline*, AnimationEffect*, - String animation_name); + const String& animation_name); - String animationName(); + const String& animationName() const; private: String animation_name_;
diff --git a/third_party/blink/renderer/core/animation/css/css_animations.cc b/third_party/blink/renderer/core/animation/css/css_animations.cc index e68db18..14a3788e 100644 --- a/third_party/blink/renderer/core/animation/css/css_animations.cc +++ b/third_party/blink/renderer/core/animation/css/css_animations.cc
@@ -38,6 +38,7 @@ #include "third_party/blink/renderer/core/animation/compositor_animations.h" #include "third_party/blink/renderer/core/animation/css/compositor_keyframe_value_factory.h" #include "third_party/blink/renderer/core/animation/css/css_animation.h" +#include "third_party/blink/renderer/core/animation/css/css_transition.h" #include "third_party/blink/renderer/core/animation/css_interpolation_types_map.h" #include "third_party/blink/renderer/core/animation/document_timeline.h" #include "third_party/blink/renderer/core/animation/element_animations.h" @@ -605,15 +606,13 @@ KeyframeEffectModelBase* model = inert_animation->Model(); - auto* transition = MakeGarbageCollected<KeyframeEffect>( + auto* transition_effect = MakeGarbageCollected<KeyframeEffect>( element, model, inert_animation->SpecifiedTiming(), KeyframeEffect::kTransitionPriority, event_delegate); - Animation* animation = element->GetDocument().Timeline().Play(transition); - if (property.IsCSSCustomProperty()) { - animation->setId(property.CustomPropertyName()); - } else { - animation->setId(property.GetCSSProperty().GetPropertyName()); - } + Animation* animation = CSSTransition::Create( + transition_effect, &(element->GetDocument().Timeline()), property); + animation->play(); + // Set the current time as the start time for retargeted transitions if (retargeted_compositor_transitions.Contains(property)) { animation->setStartTime(element->GetDocument().Timeline().currentTime(),
diff --git a/third_party/blink/renderer/core/animation/css/css_transition.cc b/third_party/blink/renderer/core/animation/css/css_transition.cc new file mode 100644 index 0000000..f726ebd --- /dev/null +++ b/third_party/blink/renderer/core/animation/css/css_transition.cc
@@ -0,0 +1,30 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/animation/css/css_transition.h" + +namespace blink { + +CSSTransition* CSSTransition::Create(AnimationEffect* effect, + AnimationTimeline* timeline, + const PropertyHandle& property) { + DCHECK(timeline && timeline->IsDocumentTimeline()); + return MakeGarbageCollected<CSSTransition>( + timeline->GetDocument()->ContextDocument(), timeline, effect, property); +} + +CSSTransition::CSSTransition(ExecutionContext* execution_context, + AnimationTimeline* timeline, + AnimationEffect* content, + const PropertyHandle& transition_property) + : Animation(execution_context, timeline, content), + transition_property_(transition_property) { + setId(transitionProperty()); +} + +AtomicString CSSTransition::transitionProperty() const { + return transition_property_.GetCSSPropertyName().ToAtomicString(); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/animation/css/css_transition.h b/third_party/blink/renderer/core/animation/css/css_transition.h new file mode 100644 index 0000000..82dced9d --- /dev/null +++ b/third_party/blink/renderer/core/animation/css/css_transition.h
@@ -0,0 +1,34 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_CSS_TRANSITION_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_CSS_TRANSITION_H_ + +#include "third_party/blink/renderer/core/animation/animation.h" +#include "third_party/blink/renderer/core/core_export.h" + +namespace blink { + +class CORE_EXPORT CSSTransition : public Animation { + DEFINE_WRAPPERTYPEINFO(); + + public: + static CSSTransition* Create(AnimationEffect*, + AnimationTimeline*, + const PropertyHandle&); + + CSSTransition(ExecutionContext*, + AnimationTimeline*, + AnimationEffect*, + const PropertyHandle& transition_property); + + AtomicString transitionProperty() const; + + private: + PropertyHandle transition_property_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_CSS_TRANSITION_H_
diff --git a/third_party/blink/renderer/core/animation/css/css_transition.idl b/third_party/blink/renderer/core/animation/css/css_transition.idl new file mode 100644 index 0000000..7d9fec2 --- /dev/null +++ b/third_party/blink/renderer/core/animation/css/css_transition.idl
@@ -0,0 +1,10 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://drafts.csswg.org/css-transitions-2/#the-CSSTransition-interface + +[Exposed=Window, RuntimeEnabled=WebAnimationsAPI] +interface CSSTransition : Animation { + readonly attribute CSSOMString transitionProperty; +};
diff --git a/third_party/blink/renderer/core/core_idl_files.gni b/third_party/blink/renderer/core/core_idl_files.gni index 11eb39e..dc63b64 100644 --- a/third_party/blink/renderer/core/core_idl_files.gni +++ b/third_party/blink/renderer/core/core_idl_files.gni
@@ -43,6 +43,7 @@ "animation/animation_effect.idl", "animation/animation_timeline.idl", "animation/css/css_animation.idl", + "animation/css/css_transition.idl", "animation/document_timeline.idl", "animation/keyframe_effect.idl", "animation/scroll_timeline.idl",
diff --git a/third_party/blink/renderer/core/css/cssom/paint_worklet_deferred_image.cc b/third_party/blink/renderer/core/css/cssom/paint_worklet_deferred_image.cc index 573b37e7..9828aa2 100644 --- a/third_party/blink/renderer/core/css/cssom/paint_worklet_deferred_image.cc +++ b/third_party/blink/renderer/core/css/cssom/paint_worklet_deferred_image.cc
@@ -46,4 +46,21 @@ kClampImageToSourceRect, input_); } +sk_sp<PaintShader> PaintWorkletDeferredImage::CreateShader( + const FloatRect& tile_rect, + const SkMatrix* pattern_matrix, + const FloatRect& src_rect) { + PaintImage image = PaintImageBuilder::WithDefault() + .set_paint_worklet_input(std::move(input_)) + .set_id(PaintImage::GetNextId()) + .TakePaintImage(); + + SkRect tile = SkRect::MakeXYWH(tile_rect.X(), tile_rect.Y(), + tile_rect.Width(), tile_rect.Height()); + sk_sp<PaintShader> shader = PaintShader::MakeImage( + image, SkTileMode::kRepeat, SkTileMode::kRepeat, pattern_matrix, &tile); + + return shader; +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/css/cssom/paint_worklet_deferred_image.h b/third_party/blink/renderer/core/css/cssom/paint_worklet_deferred_image.h index f5fb9cd..9ef8f71 100644 --- a/third_party/blink/renderer/core/css/cssom/paint_worklet_deferred_image.h +++ b/third_party/blink/renderer/core/css/cssom/paint_worklet_deferred_image.h
@@ -39,6 +39,9 @@ ImageClampingMode, ImageDecodingMode) override; void DrawTile(GraphicsContext&, const FloatRect&) override; + sk_sp<cc::PaintShader> CreateShader(const FloatRect& tile_rect, + const SkMatrix* pattern_matrix, + const FloatRect& src_rect) final; private: PaintWorkletDeferredImage(scoped_refptr<PaintWorkletInput> input,
diff --git a/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.cc b/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.cc index 30c6493..99b710d 100644 --- a/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.cc +++ b/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.cc
@@ -414,6 +414,17 @@ return nullptr; } +CSSPrimitiveValue* ConsumeAlphaValue(CSSParserTokenRange& range) { + if (CSSPrimitiveValue* value = ConsumeNumber(range, kValueRangeAll)) { + return value; + } + if (CSSPrimitiveValue* value = ConsumePercent(range, kValueRangeAll)) { + return CSSNumericLiteralValue::Create(value->GetDoubleValue() / 100.0, + CSSPrimitiveValue::UnitType::kNumber); + } + return nullptr; +} + bool CanConsumeCalcValue(CalculationCategory category, CSSParserMode css_parser_mode) { if (category == kCalcLength || category == kCalcPercent ||
diff --git a/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h b/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h index 8e0193c..550758a5 100644 --- a/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h +++ b/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h
@@ -59,6 +59,7 @@ ValueRange, UnitlessQuirk = UnitlessQuirk::kForbid); CSSPrimitiveValue* ConsumePercent(CSSParserTokenRange&, ValueRange); +CSSPrimitiveValue* ConsumeAlphaValue(CSSParserTokenRange&); CSSPrimitiveValue* ConsumeLengthOrPercent( CSSParserTokenRange&, CSSParserMode,
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 23cedc2..e2e4cb0f 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
@@ -2302,7 +2302,7 @@ CSSParserTokenRange& range, const CSSParserContext& context, const CSSParserLocalContext&) const { - return css_property_parser_helpers::ConsumeNumber(range, kValueRangeAll); + return css_property_parser_helpers::ConsumeAlphaValue(range); } const CSSValue* FillOpacity::CSSValueFromComputedStyleInternal( @@ -2444,7 +2444,7 @@ CSSParserTokenRange& range, const CSSParserContext& context, const CSSParserLocalContext&) const { - return css_property_parser_helpers::ConsumeNumber(range, kValueRangeAll); + return css_property_parser_helpers::ConsumeAlphaValue(range); } const CSSValue* FloodOpacity::CSSValueFromComputedStyleInternal( @@ -4211,7 +4211,7 @@ const CSSValue* Opacity::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, const CSSParserLocalContext&) const { - return css_property_parser_helpers::ConsumeNumber(range, kValueRangeAll); + return css_property_parser_helpers::ConsumeAlphaValue(range); } const CSSValue* Opacity::CSSValueFromComputedStyleInternal( @@ -5353,7 +5353,7 @@ CSSParserTokenRange& range, const CSSParserContext& context, const CSSParserLocalContext&) const { - return css_property_parser_helpers::ConsumeNumber(range, kValueRangeAll); + return css_property_parser_helpers::ConsumeAlphaValue(range); } const CSSValue* ShapeImageThreshold::CSSValueFromComputedStyleInternal( @@ -5596,7 +5596,7 @@ CSSParserTokenRange& range, const CSSParserContext& context, const CSSParserLocalContext&) const { - return css_property_parser_helpers::ConsumeNumber(range, kValueRangeAll); + return css_property_parser_helpers::ConsumeAlphaValue(range); } const CSSValue* StopOpacity::CSSValueFromComputedStyleInternal( @@ -5709,7 +5709,7 @@ CSSParserTokenRange& range, const CSSParserContext& context, const CSSParserLocalContext&) const { - return css_property_parser_helpers::ConsumeNumber(range, kValueRangeAll); + return css_property_parser_helpers::ConsumeAlphaValue(range); } const CSSValue* StrokeOpacity::CSSValueFromComputedStyleInternal(
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/third_party/blink/renderer/core/css/resolver/style_resolver.cc index fea9526..583152f 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -38,6 +38,7 @@ #include "third_party/blink/renderer/core/animation/invalidatable_interpolation.h" #include "third_party/blink/renderer/core/animation/keyframe_effect.h" #include "third_party/blink/renderer/core/animation/transition_interpolation.h" +#include "third_party/blink/renderer/core/css/css_color_value.h" #include "third_party/blink/renderer/core/css/css_custom_ident_value.h" #include "third_party/blink/renderer/core/css/css_default_style_sheets.h" #include "third_party/blink/renderer/core/css/css_font_selector.h" @@ -53,6 +54,7 @@ #include "third_party/blink/renderer/core/css/css_selector_watch.h" #include "third_party/blink/renderer/core/css/css_style_declaration.h" #include "third_party/blink/renderer/core/css/css_style_rule.h" +#include "third_party/blink/renderer/core/css/css_unset_value.h" #include "third_party/blink/renderer/core/css/css_value_list.h" #include "third_party/blink/renderer/core/css/element_rule_collector.h" #include "third_party/blink/renderer/core/css/font_face.h" @@ -539,8 +541,7 @@ // If the system is in forced colors mode, match rules from the forced colors // style sheet. - if (blink::RuntimeEnabledFeatures::ForcedColorsEnabled() && - GetDocument().GetSettings()->GetForcedColors() != ForcedColors::kNone) + if (IsForcedColorsModeEnabled()) MatchRuleSet(collector, default_style_sheets.DefaultForcedColorStyle()); collector.FinishAddingUARules(); @@ -1557,7 +1558,8 @@ bool inherited_only, NeedsApplyPass& needs_apply_pass, ValidPropertyFilter valid_property_filter, - unsigned apply_mask) { + unsigned apply_mask, + ForcedColorFilter forced_colors) { unsigned property_count = properties->PropertyCount(); for (unsigned i = 0; i < property_count; ++i) { CSSPropertyValueSet::PropertyReference current = properties->PropertyAt(i); @@ -1586,6 +1588,9 @@ GetDocument())) continue; + if (!CSSPropertyPriorityData<priority>::PropertyHasPriority(property_id)) + continue; + if (inherited_only && !current.IsInherited()) { // If the property value is explicitly inherited, we need to apply further // non-inherited properties as they might override the value inherited @@ -1598,8 +1603,11 @@ continue; } - if (!CSSPropertyPriorityData<priority>::PropertyHasPriority(property_id)) + if (IsForcedColorsModeEnabled() && + forced_colors == ForcedColorFilter::kEnabled && + !current.Property().IsAffectedByForcedColors()) { continue; + } ApplyProperty<priority>(current, state, apply_mask); } @@ -1625,7 +1633,8 @@ const MatchedPropertiesRange& range, bool is_important, bool inherited_only, - NeedsApplyPass& needs_apply_pass) { + NeedsApplyPass& needs_apply_pass, + ForcedColorFilter forced_colors) { if (range.IsEmpty()) return; @@ -1640,7 +1649,7 @@ inherited_only, needs_apply_pass, static_cast<ValidPropertyFilter>( matched_properties.types_.valid_property_filter), - apply_mask); + apply_mask, forced_colors); } } @@ -1665,6 +1674,48 @@ was_viewport_resized_ = false; } +template <CSSPropertyPriority priority> +void StyleResolver::ApplyForcedColors(StyleResolverState& state, + const MatchResult& match_result, + bool apply_inherited_only, + NeedsApplyPass& needs_apply_pass) { + if (!IsForcedColorsModeEnabled()) + return; + if (state.Style()->ForcedColorAdjust() == EForcedColorAdjust::kNone) + return; + + const CSSValue* unset = cssvalue::CSSUnsetValue::Create(); + unsigned apply_mask = kApplyMaskRegular | kApplyMaskVisited; + + // This simulates 'revert !important' in the user origin. + // https://drafts.csswg.org/css-color-adjust-1/#forced-colors-properties + if (priority == kHighPropertyPriority) { + ApplyProperty(GetCSSPropertyColor(), state, *unset, apply_mask); + } else { + DCHECK(priority == kLowPropertyPriority); + ApplyProperty(GetCSSPropertyBackgroundColor(), state, *unset, apply_mask); + ApplyProperty(GetCSSPropertyBorderBottomColor(), state, *unset, apply_mask); + ApplyProperty(GetCSSPropertyBorderLeftColor(), state, *unset, apply_mask); + ApplyProperty(GetCSSPropertyBorderRightColor(), state, *unset, apply_mask); + ApplyProperty(GetCSSPropertyBorderTopColor(), state, *unset, apply_mask); + ApplyProperty(GetCSSPropertyBoxShadow(), state, *unset, apply_mask); + ApplyProperty(GetCSSPropertyOutlineColor(), state, *unset, apply_mask); + ApplyProperty(GetCSSPropertyTextShadow(), state, *unset, apply_mask); + ApplyProperty(GetCSSPropertyColumnRuleColor(), state, *unset, apply_mask); + ApplyProperty(GetCSSPropertyWebkitTapHighlightColor(), state, *unset, + apply_mask); + ApplyProperty(GetCSSPropertyOutlineColor(), state, *unset, apply_mask); + } + + auto force_colors = ForcedColorFilter::kEnabled; + ApplyMatchedProperties<priority, kCheckNeedsApplyPass>( + state, match_result.UaRules(), false, apply_inherited_only, + needs_apply_pass, force_colors); + ApplyMatchedProperties<priority, kCheckNeedsApplyPass>( + state, match_result.UaRules(), true, apply_inherited_only, + needs_apply_pass, force_colors); +} + StyleResolver::CacheSuccess StyleResolver::ApplyMatchedCache( StyleResolverState& state, const MatchResult& match_result) { @@ -1815,6 +1866,12 @@ state, match_result.UaRules(), true, apply_inherited_only, needs_apply_pass); + if (IsForcedColorsModeEnabled() && + state.Style()->ForcedColorAdjust() != EForcedColorAdjust::kNone) { + ApplyForcedColors<kHighPropertyPriority>( + state, match_result, apply_inherited_only, needs_apply_pass); + } + if (cache_success.cached_matched_properties && cache_success.cached_matched_properties->computed_style ->EffectiveZoom() != state.Style()->EffectiveZoom()) { @@ -1868,6 +1925,12 @@ state, match_result.UaRules(), true, apply_inherited_only, needs_apply_pass); + if (IsForcedColorsModeEnabled() && + state.Style()->ForcedColorAdjust() != EForcedColorAdjust::kNone) { + ApplyForcedColors<kLowPropertyPriority>( + state, match_result, apply_inherited_only, needs_apply_pass); + } + if (state.Style()->HasAppearance() && !apply_inherited_only) { // Check whether the final border and background differs from the cached UA // ones. When there is a partial match in the MatchedPropertiesCache, these @@ -2223,4 +2286,9 @@ visitor->Trace(tracker_); } +bool StyleResolver::IsForcedColorsModeEnabled() const { + return RuntimeEnabledFeatures::ForcedColorsEnabled() && + GetDocument().GetSettings()->GetForcedColors() != ForcedColors::kNone; +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.h b/third_party/blink/renderer/core/css/resolver/style_resolver.h index 31ff3a5..8809350e 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver.h +++ b/third_party/blink/renderer/core/css/resolver/style_resolver.h
@@ -215,6 +215,8 @@ bool flags_[kPropertyPriorityCount * 2] = {0}; }; + enum class ForcedColorFilter { kEnabled, kDisabled }; + enum ShouldUpdateNeedsApplyPass { kCheckNeedsApplyPass = false, kUpdateNeedsApplyPass = true, @@ -240,6 +242,11 @@ bool& apply_inherited_only, NeedsApplyPass&); void ApplyMatchedProperties(StyleResolverState&, const MatchResult&); + template <CSSPropertyPriority priority> + void ApplyForcedColors(StyleResolverState& state, + const MatchResult& match_result, + bool apply_inherited_only, + NeedsApplyPass& needs_apply_pass); void CascadeAndApplyMatchedProperties(StyleResolverState&, const MatchResult&); @@ -263,19 +270,23 @@ void ApplyCallbackSelectors(StyleResolverState&); template <CSSPropertyPriority priority, ShouldUpdateNeedsApplyPass> - void ApplyMatchedProperties(StyleResolverState&, - const MatchedPropertiesRange&, - bool important, - bool inherited_only, - NeedsApplyPass&); + void ApplyMatchedProperties( + StyleResolverState&, + const MatchedPropertiesRange&, + bool important, + bool inherited_only, + NeedsApplyPass&, + ForcedColorFilter forced_colors = ForcedColorFilter::kDisabled); template <CSSPropertyPriority priority, ShouldUpdateNeedsApplyPass> - void ApplyProperties(StyleResolverState&, - const CSSPropertyValueSet* properties, - bool is_important, - bool inherited_only, - NeedsApplyPass&, - ValidPropertyFilter, - unsigned apply_mask); + void ApplyProperties( + StyleResolverState&, + const CSSPropertyValueSet* properties, + bool is_important, + bool inherited_only, + NeedsApplyPass&, + ValidPropertyFilter, + unsigned apply_mask, + ForcedColorFilter forced_colors = ForcedColorFilter::kDisabled); template <CSSPropertyPriority priority> void ApplyAnimatedStandardProperties(StyleResolverState&, const ActiveInterpolationsMap&); @@ -294,6 +305,8 @@ Document& GetDocument() const { return *document_; } bool WasViewportResized() const { return was_viewport_resized_; } + bool IsForcedColorsModeEnabled() const; + MatchedPropertiesCache matched_properties_cache_; Member<Document> document_; SelectorFilter selector_filter_;
diff --git a/third_party/blink/renderer/core/css/style_engine_test.cc b/third_party/blink/renderer/core/css/style_engine_test.cc index e8f2022c..f9fad92 100644 --- a/third_party/blink/renderer/core/css/style_engine_test.cc +++ b/third_party/blink/renderer/core/css/style_engine_test.cc
@@ -1564,6 +1564,9 @@ ScopedForcedColorsForTest scoped_feature(true); GetDocument().body()->SetInnerHTMLFromString(R"HTML( <style> + body { + forced-color-adjust: none; + } @media (forced-colors: none) { body { color: red } } @@ -1590,6 +1593,9 @@ ScopedForcedColorsForTest scoped_feature(true); GetDocument().body()->SetInnerHTMLFromString(R"HTML( <style> + body { + forced-color-adjust: none; + } @media (forced-colors: none) and (prefers-color-scheme: light) { body { color: red } }
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 62a79dd..0240e3e 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -5888,7 +5888,8 @@ if (!http_last_modified.IsEmpty()) { double date_value = ParseDate(http_last_modified); if (!std::isnan(date_value)) { - date.SetMillisecondsSinceEpochForDateTime(ConvertToLocalTime(date_value)); + date.SetMillisecondsSinceEpochForDateTimeLocal( + ConvertToLocalTime(date_value)); found_date = true; } } @@ -5896,7 +5897,7 @@ // specificiation tells us to read the last modification date from the file // system. if (!found_date) { - date.SetMillisecondsSinceEpochForDateTime( + date.SetMillisecondsSinceEpochForDateTimeLocal( ConvertToLocalTime(base::Time::Now().ToDoubleT() * 1000.0)); } return String::Format("%02d/%02d/%04d %02d:%02d:%02d", date.Month() + 1, @@ -8417,19 +8418,15 @@ GetOriginTrialContext()) { if (feature == WebFeature::kHTMLImports && origin_trial_context->IsFeatureEnabled( - OriginTrialFeature::kHTMLImports) && - !RuntimeEnabledFeatures::HTMLImportsEnabledByRuntimeFlag()) { + OriginTrialFeature::kHTMLImports)) { CountUse(WebFeature::kHTMLImportsOnReverseOriginTrials); } else if (feature == WebFeature::kElementCreateShadowRoot && origin_trial_context->IsFeatureEnabled( - OriginTrialFeature::kShadowDOMV0) && - !RuntimeEnabledFeatures::ShadowDOMV0EnabledByRuntimeFlag()) { + OriginTrialFeature::kShadowDOMV0)) { CountUse(WebFeature::kElementCreateShadowRootOnReverseOriginTrials); } else if (feature == WebFeature::kDocumentRegisterElement && origin_trial_context->IsFeatureEnabled( - OriginTrialFeature::kCustomElementsV0) && - !RuntimeEnabledFeatures:: - CustomElementsV0EnabledByRuntimeFlag()) { + OriginTrialFeature::kCustomElementsV0)) { CountUse(WebFeature::kDocumentRegisterElementOnReverseOriginTrials); } }
diff --git a/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc b/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc index 633f611..b57ad9f 100644 --- a/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc +++ b/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc
@@ -69,6 +69,7 @@ #include "third_party/blink/renderer/core/inspector/inspector_io_agent.h" #include "third_party/blink/renderer/core/inspector/inspector_layer_tree_agent.h" #include "third_party/blink/renderer/core/inspector/inspector_log_agent.h" +#include "third_party/blink/renderer/core/inspector/inspector_media_agent.h" #include "third_party/blink/renderer/core/inspector/inspector_memory_agent.h" #include "third_party/blink/renderer/core/inspector/inspector_network_agent.h" #include "third_party/blink/renderer/core/inspector/inspector_overlay_agent.h" @@ -292,6 +293,8 @@ session->Append(MakeGarbageCollected<InspectorAuditsAgent>(network_agent)); + session->Append(MakeGarbageCollected<InspectorMediaAgent>(inspected_frames)); + // TODO(dgozman): we should actually pass the view instead of frame, but // during remote->local transition we cannot access mainFrameImpl() yet, so // we have to store the frame which will become the main frame later.
diff --git a/third_party/blink/renderer/core/frame/csp/DEPS b/third_party/blink/renderer/core/frame/csp/DEPS new file mode 100644 index 0000000..4f0cae7a --- /dev/null +++ b/third_party/blink/renderer/core/frame/csp/DEPS
@@ -0,0 +1,3 @@ +include_rules = [ + "+testing/libfuzzer", +]
diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy_fuzzer.cc b/third_party/blink/renderer/core/frame/csp/content_security_policy_fuzzer.cc index 1f962e2..bafc925c 100644 --- a/third_party/blink/renderer/core/frame/csp/content_security_policy_fuzzer.cc +++ b/third_party/blink/renderer/core/frame/csp/content_security_policy_fuzzer.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" +#include "testing/libfuzzer/libfuzzer_exports.h" #include "third_party/blink/renderer/core/testing/dummy_page_holder.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/thread_state.h"
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc index 9701a9a2..fc42401f3 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -2676,4 +2676,17 @@ frame_->WasShown(); } +void WebLocalFrameImpl::SetAllowsCrossBrowsingInstanceFrameLookup() { + DCHECK(GetFrame()); + + // Allow the frame's security origin to access other SecurityOrigins + // that match everything except the agent cluster check. This is needed + // for embedders that hand out frame references outside of a browsing + // instance, for example extensions and webview tag. + GetFrame() + ->GetDocument() + ->GetMutableSecurityOrigin() + ->GrantCrossAgentClusterAccess(); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/third_party/blink/renderer/core/frame/web_local_frame_impl.h index 6fadecb..be86395 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.h +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
@@ -459,6 +459,8 @@ virtual void Trace(blink::Visitor*); + void SetAllowsCrossBrowsingInstanceFrameLookup() override; + private: friend LocalFrameClientImpl;
diff --git a/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.cc b/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.cc index bf0f558..8d8cca0 100644 --- a/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.cc +++ b/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.cc
@@ -37,7 +37,7 @@ ColorChooserUIController::ColorChooserUIController( LocalFrame* frame, blink::ColorChooserClient* client) - : client_(client), frame_(frame), binding_(this) {} + : client_(client), frame_(frame) {} ColorChooserUIController::~ColorChooserUIController() {} @@ -48,7 +48,7 @@ } void ColorChooserUIController::Dispose() { - binding_.Close(); + receiver_.reset(); } void ColorChooserUIController::OpenUI() { @@ -76,14 +76,14 @@ void ColorChooserUIController::OpenColorChooser() { DCHECK(!chooser_); - frame_->GetInterfaceProvider().GetInterface(&color_chooser_factory_); - mojom::blink::ColorChooserClientPtr mojo_client; - binding_.Bind(mojo::MakeRequest(&mojo_client)); - binding_.set_connection_error_handler(WTF::Bind( - &ColorChooserUIController::EndChooser, WrapWeakPersistent(this))); + frame_->GetInterfaceProvider().GetInterface( + color_chooser_factory_.BindNewPipeAndPassReceiver()); color_chooser_factory_->OpenColorChooser( - mojo::MakeRequest(&chooser_), std::move(mojo_client), - client_->CurrentColor().Rgb(), client_->Suggestions()); + chooser_.BindNewPipeAndPassReceiver(), + receiver_.BindNewPipeAndPassRemote(), client_->CurrentColor().Rgb(), + client_->Suggestions()); + receiver_.set_disconnect_handler(WTF::Bind( + &ColorChooserUIController::EndChooser, WrapWeakPersistent(this))); } } // namespace blink
diff --git a/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.h b/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.h index 59d1030..7cca96c 100644 --- a/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.h +++ b/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.h
@@ -27,7 +27,8 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_COLOR_CHOOSER_UI_CONTROLLER_H_ #include <memory> -#include "mojo/public/cpp/bindings/binding.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/choosers/color_chooser.mojom-blink.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/html/forms/color_chooser.h" @@ -65,14 +66,14 @@ protected: void OpenColorChooser(); - mojom::blink::ColorChooserPtr chooser_; + mojo::Remote<mojom::blink::ColorChooser> chooser_; Member<blink::ColorChooserClient> client_; Member<LocalFrame> frame_; private: - mojom::blink::ColorChooserFactoryPtr color_chooser_factory_; - mojo::Binding<mojom::blink::ColorChooserClient> binding_; + mojo::Remote<mojom::blink::ColorChooserFactory> color_chooser_factory_; + mojo::Receiver<mojom::blink::ColorChooserClient> receiver_{this}; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/inspector/BUILD.gn b/third_party/blink/renderer/core/inspector/BUILD.gn index c5bb02a..8ed729ad 100644 --- a/third_party/blink/renderer/core/inspector/BUILD.gn +++ b/third_party/blink/renderer/core/inspector/BUILD.gn
@@ -62,6 +62,10 @@ "inspector_layer_tree_agent.h", "inspector_log_agent.cc", "inspector_log_agent.h", + "inspector_media_agent.cc", + "inspector_media_agent.h", + "inspector_media_context_impl.cc", + "inspector_media_context_impl.h", "inspector_memory_agent.cc", "inspector_memory_agent.h", "inspector_network_agent.cc", @@ -158,6 +162,8 @@ "inspector/protocol/LayerTree.h", "inspector/protocol/Log.cpp", "inspector/protocol/Log.h", + "inspector/protocol/Media.cpp", + "inspector/protocol/Media.h", "inspector/protocol/Memory.cpp", "inspector/protocol/Memory.h", "inspector/protocol/Network.cpp",
diff --git a/third_party/blink/renderer/core/inspector/browser_protocol.pdl b/third_party/blink/renderer/core/inspector/browser_protocol.pdl index 69900726..50b851ab 100644 --- a/third_party/blink/renderer/core/inspector/browser_protocol.pdl +++ b/third_party/blink/renderer/core/inspector/browser_protocol.pdl
@@ -5048,7 +5048,7 @@ type Frame extends object properties # Frame unique identifier. - string id + FrameId id # Parent frame identifier. optional string parentId # Identifier of the loader associated with this frame. @@ -7166,3 +7166,60 @@ parameters AuthenticatorId authenticatorId boolean isUserVerified + +# This domain allows detailed inspection of media elements +experimental domain Media + + # Players will get an ID that is unique within the agent context. + type PlayerId extends string + + type Timestamp extends number + + # Player Property type + type PlayerProperty extends object + properties + string name + optional string value + + # Break out events into different types + type PlayerEventType extends string + enum + playbackEvent + systemEvent + messageEvent + + type PlayerEvent extends object + properties + PlayerEventType type + # Events are timestamped relative to the start of the player creation + # not relative to the start of playback. + Timestamp timestamp + string name + string value + + # This can be called multiple times, and can be used to set / override / + # remove player properties. A null propValue indicates removal. + event playerPropertiesChanged + parameters + PlayerId playerId + array of PlayerProperty properties + + # Send events as a list, allowing them to be batched on the browser for less + # congestion. If batched, events must ALWAYS be in chronological order. + event playerEventsAdded + parameters + PlayerId playerId + array of PlayerEvent events + + # Called whenever a player is created, or when a new agent joins and recieves + # a list of active players. If an agent is restored, it will recieve the full + # list of player ids and all events again. + event playersCreated + parameters + array of PlayerId players + + # Enables the Media domain + command enable + + # Disables the Media domain. + command disable
diff --git a/third_party/blink/renderer/core/inspector/inspector_media_agent.cc b/third_party/blink/renderer/core/inspector/inspector_media_agent.cc new file mode 100644 index 0000000..9b1cdc9 --- /dev/null +++ b/third_party/blink/renderer/core/inspector/inspector_media_agent.cc
@@ -0,0 +1,125 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/inspector/inspector_media_agent.h" +#include "third_party/blink/renderer/core/inspector/inspector_media_context_impl.h" + +#include <utility> + +#include "third_party/blink/renderer/core/page/page.h" + +namespace blink { + +namespace { + +std::unique_ptr<protocol::Media::PlayerEvent> ConvertInspectorPlayerEvent( + const InspectorPlayerEvent& event) { + protocol::Media::PlayerEventType event_type; + switch (event.type) { + case InspectorPlayerEvent::PLAYBACK_EVENT: + event_type = protocol::Media::PlayerEventTypeEnum::PlaybackEvent; + break; + case InspectorPlayerEvent::SYSTEM_EVENT: + event_type = protocol::Media::PlayerEventTypeEnum::SystemEvent; + break; + case InspectorPlayerEvent::MESSAGE_EVENT: + event_type = protocol::Media::PlayerEventTypeEnum::MessageEvent; + break; + } + return protocol::Media::PlayerEvent::create() + .setType(event_type) + .setTimestamp(event.timestamp.since_origin().InSecondsF()) + .setName(event.key) + .setValue(event.value) + .build(); +} + +std::unique_ptr<protocol::Media::PlayerProperty> ConvertInspectorPlayerProperty( + const InspectorPlayerProperty& property) { + auto builder = std::move( + protocol::Media::PlayerProperty::create().setName(property.name)); + if (property.value.has_value()) + builder.setValue(property.value.value()); + return builder.build(); +} + +} // namespace + +InspectorMediaAgent::InspectorMediaAgent(InspectedFrames* inspected_frames) + : local_frame_(inspected_frames->Root()), + enabled_(&agent_state_, /*default_value = */ false) {} + +InspectorMediaAgent::~InspectorMediaAgent() = default; + +void InspectorMediaAgent::Restore() { + if (!enabled_.Get()) + return; + RegisterAgent(); +} + +void InspectorMediaAgent::RegisterAgent() { + instrumenting_agents_->AddInspectorMediaAgent(this); + auto* cache = MediaInspectorContextImpl::FromLocalFrame(local_frame_); + Vector<WebString> players = cache->GetAllPlayerIds(); + PlayersCreated(players); + for (const auto& player_id : players) { + auto props_events = cache->GetPropertiesAndEvents(player_id); + PlayerPropertiesChanged(player_id, props_events.first); + PlayerEventsAdded(player_id, props_events.second); + } +} + +protocol::Response InspectorMediaAgent::enable() { + if (enabled_.Get()) + return protocol::Response::OK(); + enabled_.Set(true); + RegisterAgent(); + return protocol::Response::OK(); +} + +protocol::Response InspectorMediaAgent::disable() { + if (!enabled_.Get()) + return protocol::Response::OK(); + enabled_.Clear(); + instrumenting_agents_->RemoveInspectorMediaAgent(this); + return protocol::Response::OK(); +} + +void InspectorMediaAgent::PlayerPropertiesChanged( + const WebString& playerId, + const Vector<InspectorPlayerProperty>& properties) { + auto protocol_props = + std::make_unique<protocol::Array<protocol::Media::PlayerProperty>>(); + protocol_props->reserve(properties.size()); + for (const auto& property : properties) + protocol_props->push_back(ConvertInspectorPlayerProperty(property)); + GetFrontend()->playerPropertiesChanged(playerId, std::move(protocol_props)); +} + +void InspectorMediaAgent::PlayerEventsAdded( + const WebString& playerId, + const Vector<InspectorPlayerEvent>& events) { + auto protocol_events = + std::make_unique<protocol::Array<protocol::Media::PlayerEvent>>(); + protocol_events->reserve(events.size()); + for (const auto& event : events) + protocol_events->push_back(ConvertInspectorPlayerEvent(event)); + GetFrontend()->playerEventsAdded(playerId, std::move(protocol_events)); +} + +void InspectorMediaAgent::PlayersCreated(const Vector<WebString>& player_ids) { + auto protocol_players = + std::make_unique<protocol::Array<protocol::Media::PlayerId>>(); + protocol_players->reserve(player_ids.size()); + for (const auto& player_id : player_ids) + protocol_players->push_back(player_id); + GetFrontend()->playersCreated(std::move(protocol_players)); +} + +void InspectorMediaAgent::Trace(blink::Visitor* visitor) { + visitor->Trace(local_frame_); + InspectorBaseAgent::Trace(visitor); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/inspector/inspector_media_agent.h b/third_party/blink/renderer/core/inspector/inspector_media_agent.h new file mode 100644 index 0000000..493f5d7e --- /dev/null +++ b/third_party/blink/renderer/core/inspector/inspector_media_agent.h
@@ -0,0 +1,51 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECTOR_MEDIA_AGENT_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECTOR_MEDIA_AGENT_H_ + +#include <memory> +#include <vector> + +#include "third_party/blink/public/web/web_media_inspector.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" +#include "third_party/blink/renderer/core/inspector/inspected_frames.h" +#include "third_party/blink/renderer/core/inspector/inspector_base_agent.h" +#include "third_party/blink/renderer/core/inspector/protocol/Media.h" + +namespace blink { + +class CORE_EXPORT InspectorMediaAgent final + : public InspectorBaseAgent<protocol::Media::Metainfo> { + public: + explicit InspectorMediaAgent(InspectedFrames*); + ~InspectorMediaAgent() override; + + // BaseAgent methods. + void Restore() override; + + // Protocol receive messages. + protocol::Response enable() override; + protocol::Response disable() override; + + // Protocol send messages. + void PlayerPropertiesChanged(const WebString&, + const Vector<InspectorPlayerProperty>&); + void PlayerEventsAdded(const WebString&, const Vector<InspectorPlayerEvent>&); + void PlayersCreated(const Vector<WebString>&); + + // blink-gc methods. + void Trace(blink::Visitor*) override; + + private: + void RegisterAgent(); + + Member<LocalFrame> local_frame_; + InspectorAgentState::Boolean enabled_; + DISALLOW_COPY_AND_ASSIGN(InspectorMediaAgent); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECTOR_MEDIA_AGENT_H_
diff --git a/third_party/blink/renderer/core/inspector/inspector_media_context_impl.cc b/third_party/blink/renderer/core/inspector/inspector_media_context_impl.cc new file mode 100644 index 0000000..c721cf9 --- /dev/null +++ b/third_party/blink/renderer/core/inspector/inspector_media_context_impl.cc
@@ -0,0 +1,123 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/inspector/inspector_media_context_impl.h" + +#include <unordered_set> +#include <utility> + +#include "base/atomic_sequence_num.h" +#include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/html/media/html_media_element.h" +#include "third_party/blink/renderer/core/inspector/inspected_frames.h" +#include "third_party/blink/renderer/core/probe/core_probes.h" + +namespace blink { + +const char MediaInspectorContextImpl::kSupplementName[] = + "MediaInspectorContextImpl"; + +base::AtomicSequenceNumber player_id_generator_; + +// static +void MediaInspectorContextImpl::ProvideToLocalFrame(LocalFrame& frame) { + frame.ProvideSupplement( + MakeGarbageCollected<MediaInspectorContextImpl>(frame)); +} + +// static +MediaInspectorContextImpl* MediaInspectorContextImpl::FromLocalFrame( + LocalFrame* frame) { + return Supplement<LocalFrame>::From<MediaInspectorContextImpl>(frame); +} + +// static +MediaInspectorContextImpl* MediaInspectorContextImpl::FromDocument( + const Document& document) { + return MediaInspectorContextImpl::FromLocalFrame(document.GetFrame()); +} + +// static +MediaInspectorContextImpl* MediaInspectorContextImpl::FromHtmlMediaElement( + const HTMLMediaElement& element) { + return MediaInspectorContextImpl::FromDocument(element.GetDocument()); +} + +MediaInspectorContextImpl::MediaInspectorContextImpl(LocalFrame& frame) + : Supplement<LocalFrame>(frame) { + // 0 is an invalid key in a HashMap, so our keys should be 1-indexed. + (void)player_id_generator_.GetNext(); +} + +// Garbage collection method. +void MediaInspectorContextImpl::Trace(blink::Visitor* visitor) { + Supplement<LocalFrame>::Trace(visitor); + visitor->Trace(players_); +} + +Vector<WebString> MediaInspectorContextImpl::GetAllPlayerIds() { + Vector<WebString> existing_players; + existing_players.ReserveCapacity(players_.size()); + for (const auto& player_id : players_.Keys()) + existing_players.push_back(player_id); + return existing_players; +} + +std::pair<Vector<InspectorPlayerProperty>, Vector<InspectorPlayerEvent>> +MediaInspectorContextImpl::GetPropertiesAndEvents(const WebString& player_id) { + Vector<InspectorPlayerProperty> to_send_properties; + Vector<InspectorPlayerEvent> to_send_events; + + const auto& player_search = players_.find(player_id); + if (player_search != players_.end()) { + to_send_properties.ReserveCapacity(player_search->value->properties.size()); + for (const auto& prop : player_search->value->properties.Values()) + to_send_properties.push_back(prop); + to_send_events.ReserveCapacity(player_search->value->events.size()); + for (const auto& event : player_search->value->events) + to_send_events.insert(to_send_events.size(), event); + } + + return {std::move(to_send_properties), std::move(to_send_events)}; +} + +WebString MediaInspectorContextImpl::CreatePlayer() { + String next_player_id = String::Number(player_id_generator_.GetNext()); + players_.insert(next_player_id, MakeGarbageCollected<MediaPlayer>()); + probe::PlayersCreated(GetSupplementable(), {next_player_id}); + return next_player_id; +} + +// Convert public version of event to protocol version, and send it. +void MediaInspectorContextImpl::NotifyPlayerEvents( + WebString playerId, + InspectorPlayerEvents events) { + const auto& player_search = players_.find(playerId); + if (player_search == players_.end()) + DCHECK(false); + Vector<InspectorPlayerEvent> to_send; + to_send.ReserveCapacity(events.size()); + for (const auto& event : events) { + player_search->value->events.emplace_back(event); + to_send.push_back(event); + } + probe::PlayerEventsAdded(GetSupplementable(), playerId, to_send); +} + +void MediaInspectorContextImpl::SetPlayerProperties( + WebString playerId, + InspectorPlayerProperties props) { + const auto& player_search = players_.find(playerId); + if (player_search == players_.end()) + DCHECK(false); + Vector<InspectorPlayerProperty> to_send; + to_send.ReserveCapacity(props.size()); + for (const auto& property : props) { + to_send.push_back(property); + player_search->value->properties.insert(property.name, property); + } + probe::PlayerPropertiesChanged(GetSupplementable(), playerId, to_send); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/inspector/inspector_media_context_impl.h b/third_party/blink/renderer/core/inspector/inspector_media_context_impl.h new file mode 100644 index 0000000..dbf5bb4 --- /dev/null +++ b/third_party/blink/renderer/core/inspector/inspector_media_context_impl.h
@@ -0,0 +1,70 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECTOR_MEDIA_CONTEXT_IMPL_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECTOR_MEDIA_CONTEXT_IMPL_H_ + +#include <map> +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#include "third_party/blink/public/web/web_media_inspector.h" +#include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" +#include "third_party/blink/renderer/platform/supplementable.h" + +namespace blink { + +class Document; +class HTMLMediaElement; + +struct MediaPlayer final : public GarbageCollectedFinalized<MediaPlayer> { + void Trace(blink::Visitor*) {} + + WebString player_id; + InspectorPlayerEvents events; + HashMap<String, InspectorPlayerProperty> properties; +}; + +class CORE_EXPORT MediaInspectorContextImpl final + : public GarbageCollectedFinalized<MediaInspectorContextImpl>, + public Supplement<LocalFrame>, + public MediaInspectorContext { + USING_GARBAGE_COLLECTED_MIXIN(MediaInspectorContextImpl); + + public: + static const char kSupplementName[]; + static void ProvideToLocalFrame(LocalFrame&); + + // Different ways of getting the singleton instance of + // MediaInspectorContextImpl depending on what things are easily in scope + // caller side. + static MediaInspectorContextImpl* FromLocalFrame(LocalFrame*); + static MediaInspectorContextImpl* FromDocument(const Document&); + static MediaInspectorContextImpl* FromHtmlMediaElement( + const HTMLMediaElement&); + + explicit MediaInspectorContextImpl(LocalFrame&); + + // MediaInspectorContext methods. + WebString CreatePlayer() override; + void NotifyPlayerEvents(WebString, InspectorPlayerEvents) override; + void SetPlayerProperties(WebString, InspectorPlayerProperties) override; + + // GarbageCollectedFinalized methods. + void Trace(blink::Visitor*) override; + + Vector<WebString> GetAllPlayerIds(); + std::pair<Vector<InspectorPlayerProperty>, Vector<InspectorPlayerEvent>> + GetPropertiesAndEvents(const WebString&); + + private: + HeapHashMap<String, Member<MediaPlayer>> players_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECTOR_MEDIA_CONTEXT_IMPL_H_
diff --git a/third_party/blink/renderer/core/inspector/inspector_protocol_config.json b/third_party/blink/renderer/core/inspector/inspector_protocol_config.json index a66e4c4..2e53fa2 100644 --- a/third_party/blink/renderer/core/inspector/inspector_protocol_config.json +++ b/third_party/blink/renderer/core/inspector/inspector_protocol_config.json
@@ -97,6 +97,9 @@ }, { "domain": "WebAudio" + }, + { + "domain": "Media" } ] },
diff --git a/third_party/blink/renderer/core/layout/layout_counter.cc b/third_party/blink/renderer/core/layout/layout_counter.cc index 32d2333..b7f4bd4 100644 --- a/third_party/blink/renderer/core/layout/layout_counter.cc +++ b/third_party/blink/renderer/core/layout/layout_counter.cc
@@ -191,7 +191,7 @@ return true; } if (IsHTMLUListElement(*e) || IsHTMLMenuElement(*e) || - IsHTMLDirectoryElement(*e)) { + IsA<HTMLDirectoryElement>(*e)) { value = 0; is_reset = true; return true;
diff --git a/third_party/blink/renderer/core/layout/layout_text.cc b/third_party/blink/renderer/core/layout/layout_text.cc index bc79f62..caddb451 100644 --- a/third_party/blink/renderer/core/layout/layout_text.cc +++ b/third_party/blink/renderer/core/layout/layout_text.cc
@@ -1652,8 +1652,9 @@ FirstTextBox()->ManuallySetStartLenAndLogicalWidth( offset, text->length(), LayoutUnit(text_width)); SetFirstTextBoxLogicalLeft(text_width); - const bool avoid_layout_and_only_paint = true; - ForceSetText(std::move(text), avoid_layout_and_only_paint); + SetTextInternal(std::move(text)); + SetShouldDoFullPaintInvalidation(); + TextDidChangeWithoutInvalidation(); lines_dirty_ = false; valid_ng_items_ = false; return; @@ -1780,7 +1781,11 @@ void LayoutText::SetTextInternal(scoped_refptr<StringImpl> text) { DCHECK(text); text_ = String(std::move(text)); + DCHECK(text_); + DCHECK(!IsBR() || (TextLength() == 1 && text_[0] == kNewlineCharacter)); +} +void LayoutText::ApplyTextTransform() { if (const ComputedStyle* style = Style()) { style->ApplyTextTransform(&text_, PreviousCharacter()); @@ -1799,9 +1804,6 @@ SecureText(kBlackSquareCharacter); } } - - DCHECK(text_); - DCHECK(!IsBR() || (TextLength() == 1 && text_[0] == kNewlineCharacter)); } void LayoutText::SecureText(UChar mask) { @@ -1837,22 +1839,26 @@ ForceSetText(std::move(text)); } -void LayoutText::ForceSetText(scoped_refptr<StringImpl> text, - bool avoid_layout_and_only_paint) { +void LayoutText::ForceSetText(scoped_refptr<StringImpl> text) { DCHECK(text); SetTextInternal(std::move(text)); + TextDidChange(); +} + +void LayoutText::TextDidChange() { // If preferredLogicalWidthsDirty() of an orphan child is true, // LayoutObjectChildList::insertChildNode() fails to set true to owner. // To avoid that, we call setNeedsLayoutAndPrefWidthsRecalc() only if this // LayoutText has parent. if (Parent()) { - if (avoid_layout_and_only_paint) { - SetShouldDoFullPaintInvalidation(); - } else { - SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( - layout_invalidation_reason::kTextChanged); - } + SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( + layout_invalidation_reason::kTextChanged); } + TextDidChangeWithoutInvalidation(); +} + +void LayoutText::TextDidChangeWithoutInvalidation() { + ApplyTextTransform(); known_to_have_no_overflow_and_no_fallback_fonts_ = false; if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache())
diff --git a/third_party/blink/renderer/core/layout/layout_text.h b/third_party/blink/renderer/core/layout/layout_text.h index 19d94d9..5683ebd 100644 --- a/third_party/blink/renderer/core/layout/layout_text.h +++ b/third_party/blink/renderer/core/layout/layout_text.h
@@ -188,8 +188,7 @@ PhysicalOffset FirstLineBoxTopLeft() const; void SetTextIfNeeded(scoped_refptr<StringImpl>); - virtual void ForceSetText(scoped_refptr<StringImpl>, - bool avoid_layout_and_only_paint = false); + void ForceSetText(scoped_refptr<StringImpl>); void SetTextWithOffset(scoped_refptr<StringImpl>, unsigned offset, unsigned len); @@ -335,7 +334,8 @@ void InLayoutNGInlineFormattingContextWillChange(bool) final; - virtual void SetTextInternal(scoped_refptr<StringImpl>); + void SetTextInternal(scoped_refptr<StringImpl>); + virtual void TextDidChange(); virtual InlineTextBox* CreateTextBox(int start, uint16_t length); // Subclassed by SVG. @@ -347,6 +347,8 @@ private: InlineTextBoxList& MutableTextBoxes(); + void TextDidChangeWithoutInvalidation(); + // PhysicalRectCollector should be like a function: // void (const PhysicalRect&). template <typename PhysicalRectCollector> @@ -386,6 +388,7 @@ FloatRect* glyph_bounds_accumulation, float expansion = 0) const; + void ApplyTextTransform(); void SecureText(UChar mask); bool IsText() const =
diff --git a/third_party/blink/renderer/core/layout/layout_text_combine.cc b/third_party/blink/renderer/core/layout/layout_text_combine.cc index a35e759..62c1971 100644 --- a/third_party/blink/renderer/core/layout/layout_text_combine.cc +++ b/third_party/blink/renderer/core/layout/layout_text_combine.cc
@@ -46,8 +46,8 @@ UpdateFontStyleForCombinedText(); } -void LayoutTextCombine::SetTextInternal(scoped_refptr<StringImpl> text) { - LayoutText::SetTextInternal(std::move(text)); +void LayoutTextCombine::TextDidChange() { + LayoutText::TextDidChange(); bool was_combined = IsCombined(); UpdateIsCombined();
diff --git a/third_party/blink/renderer/core/layout/layout_text_combine.h b/third_party/blink/renderer/core/layout/layout_text_combine.h index d356152..9459fe91 100644 --- a/third_party/blink/renderer/core/layout/layout_text_combine.h +++ b/third_party/blink/renderer/core/layout/layout_text_combine.h
@@ -58,7 +58,7 @@ FloatRect* glyph_bounds = nullptr, float expansion = 0) const override; void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override; - void SetTextInternal(scoped_refptr<StringImpl>) override; + void TextDidChange() override; void UpdateIsCombined(); void UpdateFontStyleForCombinedText();
diff --git a/third_party/blink/renderer/core/layout/layout_text_fragment.cc b/third_party/blink/renderer/core/layout/layout_text_fragment.cc index fa7ee60..a3a975f0 100644 --- a/third_party/blink/renderer/core/layout/layout_text_fragment.cc +++ b/third_party/blink/renderer/core/layout/layout_text_fragment.cc
@@ -104,9 +104,8 @@ return result->Substring(Start(), FragmentLength()); } -void LayoutTextFragment::ForceSetText(scoped_refptr<StringImpl> text, - bool avoid_layout_and_only_paint) { - LayoutText::ForceSetText(std::move(text), avoid_layout_and_only_paint); +void LayoutTextFragment::TextDidChange() { + LayoutText::TextDidChange(); start_ = 0; fragment_length_ = TextLength(); @@ -125,22 +124,26 @@ void LayoutTextFragment::SetTextFragment(scoped_refptr<StringImpl> text, unsigned start, unsigned length) { - // Note, we have to call |LayoutText::ForceSetText()| here because, if we + // Note, we have to call |LayoutText::TextDidChange()| here because, if we // use our version we will, potentially, screw up the first-letter settings // where we only use portions of the string. - if (!Equal(GetText().Impl(), text.get())) - LayoutText::ForceSetText(std::move(text)); + if (!Equal(GetText().Impl(), text.get())) { + SetTextInternal(std::move(text)); + LayoutText::TextDidChange(); + } start_ = start; fragment_length_ = length; } void LayoutTextFragment::TransformText() { - // Note, we have to call LayoutText::ForceSetText()| here because, if we use + // Note, we have to call LayoutText::TextDidChange()| here because, if we use // our version we will, potentially, screw up the first-letter settings where // we only use portions of the string. - if (scoped_refptr<StringImpl> text_to_transform = OriginalText()) - LayoutText::ForceSetText(std::move(text_to_transform)); + if (scoped_refptr<StringImpl> text_to_transform = OriginalText()) { + SetTextInternal(std::move(text_to_transform)); + LayoutText::TextDidChange(); + } } UChar LayoutTextFragment::PreviousCharacter() const {
diff --git a/third_party/blink/renderer/core/layout/layout_text_fragment.h b/third_party/blink/renderer/core/layout/layout_text_fragment.h index 538fbdd..9dfed8a 100644 --- a/third_party/blink/renderer/core/layout/layout_text_fragment.h +++ b/third_party/blink/renderer/core/layout/layout_text_fragment.h
@@ -74,8 +74,6 @@ scoped_refptr<StringImpl> OriginalText() const override; - void ForceSetText(scoped_refptr<StringImpl>, - bool avoid_layout_and_only_paint = false) override; void SetTextFragment(scoped_refptr<StringImpl>, unsigned start, unsigned length); @@ -109,6 +107,7 @@ private: LayoutBlock* BlockForAccompanyingFirstLetter() const; UChar PreviousCharacter() const override; + void TextDidChange() override; void UpdateHitTestResult(HitTestResult&, const PhysicalOffset&) const override;
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 08b53cf..fe2e38c 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
@@ -983,10 +983,12 @@ // block offset. bfc_offset_already_resolved = true; child_bfc_offset_estimate = *ConstraintSpace().ForcedBfcBlockOffset(); - // We require that the BFC block offset be the one we'd get with either - // margins adjoining or margins separated. Anything else is a bug. + // We require that the BFC block offset be the one we'd get with margins + // adjoining, margins separated, or if clearance was applied to either of + // these. Anything else is a bug. DCHECK(child_bfc_offset_estimate == adjoining_bfc_offset_estimate || - child_bfc_offset_estimate == non_adjoining_bfc_offset_estimate); + child_bfc_offset_estimate == non_adjoining_bfc_offset_estimate || + child_bfc_offset_estimate == ConstraintSpace().ClearanceOffset()); // Figure out if the child margin has already got separated from the // margin strut or not. child_margin_got_separated =
diff --git a/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc index 7fc7d45..b35bc4c 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc
@@ -61,7 +61,6 @@ } void NGFlexLayoutAlgorithm::ConstructAndAppendFlexItems() { - const bool is_horizontal_flow = algorithm_->IsHorizontalFlow(); for (NGLayoutInputNode generic_child = Node().FirstChild(); generic_child; generic_child = generic_child.NextSibling()) { auto child = To<NGBlockNode>(generic_child); @@ -92,11 +91,11 @@ border_scrollbar_padding_in_child_writing_mode.ConvertToPhysical( child_style.GetWritingMode(), child_style.Direction())); LayoutUnit main_axis_border_scrollbar_padding = - is_horizontal_flow ? physical_border_padding.HorizontalSum() - : physical_border_padding.VerticalSum(); + is_horizontal_flow_ ? physical_border_padding.HorizontalSum() + : physical_border_padding.VerticalSum(); LayoutUnit main_axis_border_and_padding = main_axis_border_scrollbar_padding - - (is_horizontal_flow + (is_horizontal_flow_ ? child.GetLayoutBox()->VerticalScrollbarWidth() : child.GetLayoutBox()->HorizontalScrollbarHeight()); @@ -114,7 +113,7 @@ LayoutUnit flex_base_border_box; const Length& specified_length_in_main_axis = - is_horizontal_flow ? child_style.Width() : child_style.Height(); + is_horizontal_flow_ ? child_style.Width() : child_style.Height(); const Length& flex_basis = child_style.FlexBasis(); // TODO(dgrogan): Generalize IsAuto: See the <'width'> section of // https://drafts.csswg.org/css-flexbox/#valdef-flex-flex-basis @@ -157,13 +156,13 @@ NGPhysicalBoxStrut physical_child_margins = ComputePhysicalMargins(child_space, child_style); - LayoutUnit main_axis_margin = is_horizontal_flow + LayoutUnit main_axis_margin = is_horizontal_flow_ ? physical_child_margins.HorizontalSum() : physical_child_margins.VerticalSum(); MinMaxSize min_max_sizes_in_main_axis_direction{LayoutUnit(), LayoutUnit::Max()}; - const Length& max_property_in_main_axis = is_horizontal_flow + const Length& max_property_in_main_axis = is_horizontal_flow_ ? child.Style().MaxWidth() : child.Style().MaxHeight(); if (MainAxisIsInlineAxis(child)) { @@ -180,8 +179,8 @@ LengthResolvePhase::kLayout); } - const Length& min = is_horizontal_flow ? child.Style().MinWidth() - : child.Style().MinHeight(); + const Length& min = is_horizontal_flow_ ? child.Style().MinWidth() + : child.Style().MinHeight(); if (min.IsAuto()) { if (algorithm_->ShouldApplyMinSizeAutoForChild(*child.GetLayoutBox())) { // TODO(dgrogan): Do the aspect ratio parts of @@ -264,7 +263,7 @@ const LayoutUnit line_break_length = MainAxisContentExtent(LayoutUnit::Max()); algorithm_.emplace(&Style(), line_break_length); - const bool is_horizontal_flow = algorithm_->IsHorizontalFlow(); + is_horizontal_flow_ = algorithm_->IsHorizontalFlow(); ConstructAndAppendFlexItems(); @@ -313,7 +312,7 @@ flex_item.layout_result = flex_item.ng_input_node.Layout(child_space, nullptr /*break token*/); flex_item.cross_axis_size = - is_horizontal_flow + is_horizontal_flow_ ? flex_item.layout_result->PhysicalFragment().Size().height : flex_item.layout_result->PhysicalFragment().Size().width; }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.h index f33c5e0d..349f412 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.h +++ b/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.h
@@ -46,9 +46,10 @@ const bool is_column_; LogicalSize border_box_size_; LogicalSize content_box_size_; - // This is populated at the top of Layout(), so isn't available in + // These are populated at the top of Layout(), so aren't available in // ComputeMinMaxSize() or anything it calls. base::Optional<FlexLayoutAlgorithm> algorithm_; + bool is_horizontal_flow_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.cc index b5da4ce..5a08932 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.cc +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.cc
@@ -56,8 +56,9 @@ : LayoutText(n, NormalizeWhitespace(std::move(string))), scaling_factor_(1) {} -void LayoutSVGInlineText::SetTextInternal(scoped_refptr<StringImpl> text) { - LayoutText::SetTextInternal(NormalizeWhitespace(std::move(text))); +void LayoutSVGInlineText::TextDidChange() { + SetTextInternal(NormalizeWhitespace(GetText().Impl())); + LayoutText::TextDidChange(); if (LayoutSVGText* text_layout_object = LayoutSVGText::LocateLayoutSVGTextAncestor(this)) text_layout_object->SubtreeTextDidChange();
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.h b/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.h index 8714fa3..20ca818 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.h +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.h
@@ -56,7 +56,7 @@ const char* GetName() const override { return "LayoutSVGInlineText"; } private: - void SetTextInternal(scoped_refptr<StringImpl>) override; + void TextDidChange() override; void StyleDidChange(StyleDifference, const ComputedStyle*) override; void AddMetricsFromRun(const TextRun&, bool& last_character_was_white_space);
diff --git a/third_party/blink/renderer/core/page/frame_tree.cc b/third_party/blink/renderer/core/page/frame_tree.cc index b35e797e..aa41f83 100644 --- a/third_party/blink/renderer/core/page/frame_tree.cc +++ b/third_party/blink/renderer/core/page/frame_tree.cc
@@ -22,6 +22,7 @@ #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/frame/frame_client.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame_client.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" @@ -289,7 +290,15 @@ } // Ask the embedder as a fallback. - return To<LocalFrame>(this_frame_.Get())->Client()->FindFrame(name); + LocalFrame* local_frame = To<LocalFrame>(this_frame_.Get()); + Frame* named_frame = local_frame->Client()->FindFrame(name); + // The embedder can return a frame from another agent cluster. Make sure + // that the returned frame, if any, has explicitly allowed cross-agent + // cluster access. + DCHECK(!named_frame || local_frame->GetDocument() + ->GetSecurityOrigin() + ->IsGrantedCrossAgentClusterAccess()); + return named_frame; } bool FrameTree::IsDescendantOf(const Frame* ancestor) const {
diff --git a/third_party/blink/renderer/core/probe/core_probes.json5 b/third_party/blink/renderer/core/probe/core_probes.json5 index 769141b..7324fab 100644 --- a/third_party/blink/renderer/core/probe/core_probes.json5 +++ b/third_party/blink/renderer/core/probe/core_probes.json5
@@ -13,6 +13,7 @@ "third_party/blink/renderer/core/loader/frame_loader_types.h", "third_party/blink/renderer/core/page/chrome_client.h", "third_party/blink/renderer/core/probe/core_probes.h", + "third_party/blink/public/web/web_media_inspector.h", ], }, observers: { @@ -116,6 +117,13 @@ "ConsoleMessageAdded", ] }, + InspectorMediaAgent: { + probes: [ + "PlayerEventsAdded", + "PlayerPropertiesChanged", + "PlayersCreated" + ] + }, InspectorNetworkAgent: { probes: [ "DidBlockRequest",
diff --git a/third_party/blink/renderer/core/probe/core_probes.pidl b/third_party/blink/renderer/core/probe/core_probes.pidl index 940ae51..37b7945 100644 --- a/third_party/blink/renderer/core/probe/core_probes.pidl +++ b/third_party/blink/renderer/core/probe/core_probes.pidl
@@ -168,4 +168,8 @@ void ProduceCompilationCache(LocalFrame*, const ScriptSourceCode& source, v8::Local<v8::Script> script); void ConsumeCompilationCache(ExecutionContext*, const ScriptSourceCode& source, v8::ScriptCompiler::CachedData** cached_data); void NodeCreated([Keep] Node* node); + + void PlayerEventsAdded(LocalFrame* frame, String player_id, const Vector<InspectorPlayerEvent>& events); + void PlayerPropertiesChanged(LocalFrame* frame, String player_id, const Vector<InspectorPlayerProperty>& properties); + void PlayersCreated(LocalFrame* frame, const Vector<WebString>& players); }
diff --git a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc index f8ec1679..ad6d6d4 100644 --- a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc +++ b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
@@ -1013,6 +1013,8 @@ double active_time = std::max(elapsed - interval_.begin.Value(), 0.0); SMILTime repeating_duration = RepeatingDuration(); if (elapsed >= interval_.end || active_time > repeating_duration) { + if (!repeating_duration.IsFinite()) + return 0; unsigned repeat = static_cast<unsigned>(repeating_duration.Value() / simple_duration.Value()); if (!fmod(repeating_duration.Value(), simple_duration.Value()))
diff --git a/third_party/blink/renderer/modules/BUILD.gn b/third_party/blink/renderer/modules/BUILD.gn index 4fd5171..6efa997 100644 --- a/third_party/blink/renderer/modules/BUILD.gn +++ b/third_party/blink/renderer/modules/BUILD.gn
@@ -456,6 +456,7 @@ "//third_party/blink/public:blink_headers", "//third_party/blink/renderer/core", "//third_party/blink/renderer/modules/gamepad:unit_tests", + "//third_party/blink/renderer/modules/hid:unit_tests", "//third_party/blink/renderer/modules/storage:unit_tests", "//third_party/blink/renderer/platform", "//third_party/blink/renderer/platform/wtf",
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc index ebebce8..404d0b5 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -29,6 +29,7 @@ #include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h" #include "base/memory/scoped_refptr.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h" #include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink.h" #include "third_party/blink/public/platform/task_type.h" @@ -113,8 +114,7 @@ modification_count_(0), validation_message_axid_(0), relation_cache_(std::make_unique<AXRelationCache>(this)), - accessibility_event_permission_(mojom::PermissionStatus::ASK), - permission_observer_binding_(this) { + accessibility_event_permission_(mojom::PermissionStatus::ASK) { if (document_->LoadEventFinished()) AddPermissionStatusListener(); documents_.insert(&document); @@ -1718,14 +1718,17 @@ return; } + if (permission_service_.is_bound()) + permission_service_.reset(); + ConnectToPermissionService(document_->GetExecutionContext(), - mojo::MakeRequest(&permission_service_)); + permission_service_.BindNewPipeAndPassReceiver()); - if (permission_observer_binding_.is_bound()) - permission_observer_binding_.Close(); + if (permission_observer_receiver_.is_bound()) + permission_observer_receiver_.reset(); - mojom::blink::PermissionObserverPtr observer; - permission_observer_binding_.Bind(mojo::MakeRequest(&observer)); + mojo::PendingRemote<mojom::blink::PermissionObserver> observer; + permission_observer_receiver_.Bind(observer.InitWithNewPipeAndPassReceiver()); permission_service_->AddPermissionObserver( CreatePermissionDescriptor( mojom::blink::PermissionName::ACCESSIBILITY_EVENTS), @@ -1768,7 +1771,7 @@ void AXObjectCacheImpl::ContextDestroyed(ExecutionContext*) { permission_service_.reset(); - permission_observer_binding_.Close(); + permission_observer_receiver_.reset(); } void AXObjectCacheImpl::Trace(blink::Visitor* visitor) {
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h index a889a12..0c4ceb5 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h +++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
@@ -33,7 +33,8 @@ #include <utility> #include "base/macros.h" -#include "mojo/public/cpp/bindings/binding.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h" #include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink.h" #include "third_party/blink/renderer/core/accessibility/ax_object_cache_base.h" @@ -374,8 +375,9 @@ mojom::PermissionStatus accessibility_event_permission_; // The permission service, enabling us to check for event listener // permission. - mojom::blink::PermissionServicePtr permission_service_; - mojo::Binding<mojom::blink::PermissionObserver> permission_observer_binding_; + mojo::Remote<mojom::blink::PermissionService> permission_service_; + mojo::Receiver<mojom::blink::PermissionObserver> + permission_observer_receiver_{this}; // The main document, plus any page popups. HeapHashSet<WeakMember<Document>> documents_;
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc index a694aaf..fbc9ea2 100644 --- a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc +++ b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
@@ -263,8 +263,9 @@ PermissionService* ClipboardPromise::GetPermissionService() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!permission_service_) { - ConnectToPermissionService(ExecutionContext::From(script_state_), - mojo::MakeRequest(&permission_service_)); + ConnectToPermissionService( + ExecutionContext::From(script_state_), + permission_service_.BindNewPipeAndPassReceiver()); } return permission_service_.get(); }
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_promise.h b/third_party/blink/renderer/modules/clipboard/clipboard_promise.h index ab4c4b76..9867510 100644 --- a/third_party/blink/renderer/modules/clipboard/clipboard_promise.h +++ b/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "base/sequence_checker.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" @@ -74,7 +75,7 @@ std::unique_ptr<ClipboardWriter> clipboard_writer_; // Checks for Read and Write permission. - mojom::blink::PermissionServicePtr permission_service_; + mojo::Remote<mojom::blink::PermissionService> permission_service_; // Only for use in writeText(). String plain_text_;
diff --git a/third_party/blink/renderer/modules/hid/BUILD.gn b/third_party/blink/renderer/modules/hid/BUILD.gn index 300f53c..67e6cfec 100644 --- a/third_party/blink/renderer/modules/hid/BUILD.gn +++ b/third_party/blink/renderer/modules/hid/BUILD.gn
@@ -24,3 +24,23 @@ "navigator_hid.h", ] } + +jumbo_source_set("unit_tests") { + testonly = true + sources = [ + "hid_report_item_test.cc", + ] + + configs += [ + "//third_party/blink/renderer:config", + "//third_party/blink/renderer:inside_blink", + "//third_party/blink/renderer/core:blink_core_pch", + ] + + deps = [ + "//testing/gtest", + "//third_party/blink/renderer/modules", + "//third_party/blink/renderer/platform", + "//third_party/blink/renderer/platform/wtf", + ] +}
diff --git a/third_party/blink/renderer/modules/hid/hid.cc b/third_party/blink/renderer/modules/hid/hid.cc index 3af6698..a0691d8 100644 --- a/third_party/blink/renderer/modules/hid/hid.cc +++ b/third_party/blink/renderer/modules/hid/hid.cc
@@ -175,12 +175,19 @@ return promise; } +void HID::Connect(const String& device_guid, + device::mojom::blink::HidConnectionClientPtr client, + device::mojom::blink::HidManager::ConnectCallback callback) { + EnsureServiceConnection(); + service_->Connect(device_guid, std::move(client), std::move(callback)); +} + HIDDevice* HID::GetOrCreateDevice(device::mojom::blink::HidDeviceInfoPtr info) { const String guid = info->guid; HIDDevice* device = device_cache_.at(guid); if (!device) { - device = - MakeGarbageCollected<HIDDevice>(std::move(info), GetExecutionContext()); + device = MakeGarbageCollected<HIDDevice>(this, std::move(info), + GetExecutionContext()); device_cache_.insert(guid, device); } return device;
diff --git a/third_party/blink/renderer/modules/hid/hid.h b/third_party/blink/renderer/modules/hid/hid.h index 213a121..3895e5f0 100644 --- a/third_party/blink/renderer/modules/hid/hid.h +++ b/third_party/blink/renderer/modules/hid/hid.h
@@ -39,6 +39,10 @@ ScriptPromise getDevices(ScriptState*); ScriptPromise requestDevice(ScriptState*, const HIDDeviceRequestOptions*); + void Connect(const String& device_guid, + device::mojom::blink::HidConnectionClientPtr connection_client, + device::mojom::blink::HidManager::ConnectCallback callback); + void Trace(blink::Visitor*) override; protected:
diff --git a/third_party/blink/renderer/modules/hid/hid_collection_info.cc b/third_party/blink/renderer/modules/hid/hid_collection_info.cc index fcfac53..c95e753 100644 --- a/third_party/blink/renderer/modules/hid/hid_collection_info.cc +++ b/third_party/blink/renderer/modules/hid/hid_collection_info.cc
@@ -9,16 +9,28 @@ namespace blink { HIDCollectionInfo::HIDCollectionInfo( - const device::mojom::blink::HidCollectionInfo& info) {} + const device::mojom::blink::HidCollectionInfo& info) + : usage_page_(info.usage->usage_page), + usage_(info.usage->usage), + collection_type_(info.collection_type) { + for (const auto& child : info.children) + children_.push_back(MakeGarbageCollected<HIDCollectionInfo>(*child)); + for (const auto& report : info.input_reports) + input_reports_.push_back(MakeGarbageCollected<HIDReportInfo>(*report)); + for (const auto& report : info.output_reports) + output_reports_.push_back(MakeGarbageCollected<HIDReportInfo>(*report)); + for (const auto& report : info.feature_reports) + feature_reports_.push_back(MakeGarbageCollected<HIDReportInfo>(*report)); +} HIDCollectionInfo::~HIDCollectionInfo() = default; uint16_t HIDCollectionInfo::usagePage() const { - return 0; + return usage_page_; } uint16_t HIDCollectionInfo::usage() const { - return 0; + return usage_; } const HeapVector<Member<HIDCollectionInfo>>& HIDCollectionInfo::children() @@ -42,7 +54,7 @@ } uint32_t HIDCollectionInfo::collectionType() const { - return 0; + return collection_type_; } void HIDCollectionInfo::Trace(blink::Visitor* visitor) {
diff --git a/third_party/blink/renderer/modules/hid/hid_collection_info.h b/third_party/blink/renderer/modules/hid/hid_collection_info.h index 33950571..5883758 100644 --- a/third_party/blink/renderer/modules/hid/hid_collection_info.h +++ b/third_party/blink/renderer/modules/hid/hid_collection_info.h
@@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_COLLECTION_INFO_H_ #include "services/device/public/mojom/hid.mojom-blink.h" +#include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -13,7 +14,7 @@ class HIDReportInfo; -class HIDCollectionInfo : public ScriptWrappable { +class MODULES_EXPORT HIDCollectionInfo : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: @@ -32,6 +33,9 @@ void Trace(blink::Visitor* visitor) override; private: + uint16_t usage_page_; + uint16_t usage_; + uint32_t collection_type_; HeapVector<Member<HIDCollectionInfo>> children_; HeapVector<Member<HIDReportInfo>> input_reports_; HeapVector<Member<HIDReportInfo>> output_reports_;
diff --git a/third_party/blink/renderer/modules/hid/hid_device.cc b/third_party/blink/renderer/modules/hid/hid_device.cc index 73bde94..259a09e 100644 --- a/third_party/blink/renderer/modules/hid/hid_device.cc +++ b/third_party/blink/renderer/modules/hid/hid_device.cc
@@ -7,17 +7,101 @@ #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" +#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h" +#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h" +#include "third_party/blink/renderer/core/typed_arrays/dom_data_view.h" #include "third_party/blink/renderer/modules/event_target_modules.h" +#include "third_party/blink/renderer/modules/hid/hid.h" #include "third_party/blink/renderer/modules/hid/hid_collection_info.h" +#include "third_party/blink/renderer/modules/hid/hid_input_report_event.h" #include "third_party/blink/renderer/platform/heap/heap.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" namespace blink { -HIDDevice::HIDDevice(device::mojom::blink::HidDeviceInfoPtr info, - ExecutionContext* context) - : ContextLifecycleObserver(context) {} +namespace { -HIDDevice::~HIDDevice() = default; +const char kDeviceStateChangeInProgress[] = + "An operation that changes the device state is in progress."; +const char kOpenRequired[] = "The device must be opened first."; +const char kOpenFailed[] = "Failed to open the device."; +const char kSendReportFailed[] = "Failed to write the report."; +const char kSendFeatureReportFailed[] = "Failed to write the feature report."; +const char kReceiveFeatureReportFailed[] = + "Failed to receive the feature report."; +const char kUnexpectedClose[] = "The device was closed unexpectedly."; + +Vector<uint8_t> ConvertBufferSource( + const ArrayBufferOrArrayBufferView& buffer) { + DCHECK(!buffer.IsNull()); + Vector<uint8_t> vector; + if (buffer.IsArrayBuffer()) { + vector.Append(static_cast<uint8_t*>(buffer.GetAsArrayBuffer()->Data()), + buffer.GetAsArrayBuffer()->ByteLength()); + } else { + vector.Append(static_cast<uint8_t*>( + buffer.GetAsArrayBufferView().View()->BaseAddress()), + buffer.GetAsArrayBufferView().View()->byteLength()); + } + return vector; +} + +bool IsProtected( + const device::mojom::blink::HidUsageAndPage& hid_usage_and_page) { + const uint16_t usage = hid_usage_and_page.usage; + const uint16_t usage_page = hid_usage_and_page.usage_page; + + if (usage_page == device::mojom::blink::kPageFido) + return true; + + if (usage_page == device::mojom::blink::kPageKeyboard) + return true; + + if (usage_page != device::mojom::blink::kPageGenericDesktop) + return false; + + if (usage == device::mojom::blink::kGenericDesktopPointer || + usage == device::mojom::blink::kGenericDesktopMouse || + usage == device::mojom::blink::kGenericDesktopKeyboard || + usage == device::mojom::blink::kGenericDesktopKeypad) { + return true; + } + + if (usage >= device::mojom::blink::kGenericDesktopSystemControl && + usage <= device::mojom::blink::kGenericDesktopSystemWarmRestart) { + return true; + } + + if (usage >= device::mojom::blink::kGenericDesktopSystemDock && + usage <= device::mojom::blink::kGenericDesktopSystemDisplaySwap) { + return true; + } + + return false; +} + +} // namespace + +HIDDevice::HIDDevice(HID* parent, + device::mojom::blink::HidDeviceInfoPtr info, + ExecutionContext* context) + : ContextLifecycleObserver(context), + parent_(parent), + device_info_(std::move(info)), + binding_(this) { + DCHECK(device_info_); + for (const auto& collection : device_info_->collections) { + // Omit information about top-level collections with protected usages. + if (!IsProtected(*collection->usage)) { + collections_.push_back( + MakeGarbageCollected<HIDCollectionInfo>(*collection)); + } + } +} + +HIDDevice::~HIDDevice() { + DCHECK(device_requests_.IsEmpty()); +} ExecutionContext* HIDDevice::GetExecutionContext() const { return ContextLifecycleObserver::GetExecutionContext(); @@ -27,20 +111,26 @@ return event_target_names::kHIDDevice; } +void HIDDevice::OnInputReport(uint8_t report_id, + const Vector<uint8_t>& buffer) { + DispatchEvent(*MakeGarbageCollected<HIDInputReportEvent>( + event_type_names::kInputreport, this, report_id, buffer)); +} + bool HIDDevice::opened() const { - return false; + return connection_.is_bound(); } uint16_t HIDDevice::vendorId() const { - return 0; + return device_info_->vendor_id; } uint16_t HIDDevice::productId() const { - return 0; + return device_info_->product_id; } String HIDDevice::productName() const { - return String(); + return device_info_->product_name; } const HeapVector<Member<HIDCollectionInfo>>& HIDDevice::collections() const { @@ -48,57 +138,214 @@ } ScriptPromise HIDDevice::open(ScriptState* script_state) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotSupportedError, - "Not supported.")); + ScriptPromiseResolver* resolver = + MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); + if (!EnsureNoDeviceChangeInProgress(resolver)) + return promise; + + if (opened()) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError, "The device is already open.")); + return promise; + } + + device::mojom::blink::HidConnectionClientPtr client; + binding_.Bind(mojo::MakeRequest(&client)); + + device_state_change_in_progress_ = true; + device_requests_.insert(resolver); + parent_->Connect(device_info_->guid, std::move(client), + WTF::Bind(&HIDDevice::FinishOpen, WrapPersistent(this), + WrapPersistent(resolver))); + return promise; } ScriptPromise HIDDevice::close(ScriptState* script_state) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotSupportedError, - "Not supported.")); + ScriptPromiseResolver* resolver = + MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); + if (!EnsureNoDeviceChangeInProgress(resolver)) + return promise; + + connection_.reset(); + resolver->Resolve(); + return promise; } ScriptPromise HIDDevice::sendReport(ScriptState* script_state, uint8_t report_id, const ArrayBufferOrArrayBufferView& data) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotSupportedError, - "Not supported.")); + ScriptPromiseResolver* resolver = + MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); + if (!EnsureNoDeviceChangeInProgress(resolver)) + return promise; + + if (!opened()) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError, kOpenRequired)); + return promise; + } + + device_requests_.insert(resolver); + connection_->Write(report_id, ConvertBufferSource(data), + WTF::Bind(&HIDDevice::FinishSendReport, + WrapPersistent(this), WrapPersistent(resolver))); + return promise; } ScriptPromise HIDDevice::sendFeatureReport( ScriptState* script_state, uint8_t report_id, const ArrayBufferOrArrayBufferView& data) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotSupportedError, - "Not supported.")); + ScriptPromiseResolver* resolver = + MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); + if (!EnsureNoDeviceChangeInProgress(resolver)) + return promise; + + if (!opened()) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError, kOpenRequired)); + return promise; + } + + device_requests_.insert(resolver); + connection_->SendFeatureReport( + report_id, ConvertBufferSource(data), + WTF::Bind(&HIDDevice::FinishSendFeatureReport, WrapPersistent(this), + WrapPersistent(resolver))); + return promise; } ScriptPromise HIDDevice::receiveFeatureReport(ScriptState* script_state, uint8_t report_id) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotSupportedError, - "Not supported.")); + ScriptPromiseResolver* resolver = + MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); + if (!EnsureNoDeviceChangeInProgress(resolver)) + return promise; + + if (!opened()) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError, kOpenRequired)); + return promise; + } + + device_requests_.insert(resolver); + connection_->GetFeatureReport( + report_id, WTF::Bind(&HIDDevice::FinishReceiveFeatureReport, + WrapPersistent(this), WrapPersistent(resolver))); + return promise; } -void HIDDevice::AddedEventListener(const AtomicString& event_type, - RegisteredEventListener& listener) { - EventTargetWithInlineData::AddedEventListener(event_type, listener); - // TODO(mattreynolds): Open a HID connection and register for input report - // events. +void HIDDevice::ContextDestroyed(ExecutionContext*) { + connection_.reset(); + device_requests_.clear(); + if (binding_) + binding_.Close(); } void HIDDevice::Trace(blink::Visitor* visitor) { + visitor->Trace(parent_); + visitor->Trace(device_requests_); + visitor->Trace(collections_); + EventTargetWithInlineData::Trace(visitor); ScriptWrappable::Trace(visitor); ContextLifecycleObserver::Trace(visitor); - visitor->Trace(collections_); +} + +void HIDDevice::Dispose() { + // The connection client binding holds a raw pointer to this object which must + // be released when it becomes garbage. + if (binding_) + binding_.Close(); +} + +bool HIDDevice::EnsureNoDeviceChangeInProgress( + ScriptPromiseResolver* resolver) const { + if (device_state_change_in_progress_) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError, kDeviceStateChangeInProgress)); + return false; + } + return true; +} + +void HIDDevice::FinishOpen(ScriptPromiseResolver* resolver, + device::mojom::blink::HidConnectionPtr connection) { + MarkRequestComplete(resolver); + device_state_change_in_progress_ = false; + + if (connection) { + connection_ = std::move(connection); + connection_.set_connection_error_handler(WTF::Bind( + &HIDDevice::OnServiceConnectionError, WrapWeakPersistent(this))); + resolver->Resolve(); + } else { + // If the connection is null, the open failed. + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kNotAllowedError, kOpenFailed)); + } +} + +void HIDDevice::OnServiceConnectionError() { + for (auto& resolver : device_requests_) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError, kUnexpectedClose)); + } + device_requests_.clear(); +} + +void HIDDevice::FinishClose(ScriptPromiseResolver* resolver) { + MarkRequestComplete(resolver); + connection_.reset(); + resolver->Resolve(); +} + +void HIDDevice::FinishSendReport(ScriptPromiseResolver* resolver, + bool success) { + MarkRequestComplete(resolver); + if (success) { + resolver->Resolve(); + } else { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kNotAllowedError, kSendReportFailed)); + } +} + +void HIDDevice::FinishSendFeatureReport(ScriptPromiseResolver* resolver, + bool success) { + MarkRequestComplete(resolver); + if (success) { + resolver->Resolve(); + } else { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kNotAllowedError, kSendFeatureReportFailed)); + } +} + +void HIDDevice::FinishReceiveFeatureReport( + ScriptPromiseResolver* resolver, + bool success, + const base::Optional<Vector<uint8_t>>& data) { + MarkRequestComplete(resolver); + if (success && data) { + DOMArrayBuffer* dom_buffer = + DOMArrayBuffer::Create(data->data(), data->size()); + DOMDataView* data_view = DOMDataView::Create(dom_buffer, 0, data->size()); + resolver->Resolve(data_view); + } else { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kNotAllowedError, kReceiveFeatureReportFailed)); + } +} + +void HIDDevice::MarkRequestComplete(ScriptPromiseResolver* resolver) { + auto find_result = device_requests_.find(resolver); + DCHECK_NE(device_requests_.end(), find_result); + device_requests_.erase(find_result); } } // namespace blink
diff --git a/third_party/blink/renderer/modules/hid/hid_device.h b/third_party/blink/renderer/modules/hid/hid_device.h index 62ee906..5d25ca1 100644 --- a/third_party/blink/renderer/modules/hid/hid_device.h +++ b/third_party/blink/renderer/modules/hid/hid_device.h
@@ -5,34 +5,50 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_DEVICE_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_DEVICE_H_ +#include "mojo/public/cpp/bindings/binding.h" #include "services/device/public/mojom/hid.mojom-blink.h" +#include "third_party/blink/public/mojom/hid/hid.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/core/dom/events/event_target.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" +#include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" -#include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/heap/heap_allocator.h" +#include "third_party/blink/renderer/platform/heap/member.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "third_party/blink/renderer/platform/wtf/vector.h" namespace blink { class ExecutionContext; +class HID; class HIDCollectionInfo; +class ScriptPromiseResolver; +class ScriptState; -class HIDDevice : public EventTargetWithInlineData, - public ContextLifecycleObserver { +class MODULES_EXPORT HIDDevice + : public EventTargetWithInlineData, + public ContextLifecycleObserver, + public device::mojom::blink::HidConnectionClient { DEFINE_WRAPPERTYPEINFO(); USING_GARBAGE_COLLECTED_MIXIN(HIDDevice); + USING_PRE_FINALIZER(HIDDevice, Dispose); public: - HIDDevice(device::mojom::blink::HidDeviceInfoPtr info, + HIDDevice(HID* parent, + device::mojom::blink::HidDeviceInfoPtr info, ExecutionContext* execution_context); ~HIDDevice() override; - // EventTarget overrides. + // EventTarget: ExecutionContext* GetExecutionContext() const override; const AtomicString& InterfaceName() const override; - // hid_device.idl + // device::mojom::blink::HidConnectionClient: + void OnInputReport(uint8_t report_id, const Vector<uint8_t>& buffer) override; + + // Web-exposed interfaces: DEFINE_ATTRIBUTE_EVENT_LISTENER(inputreport, kInputreport) bool opened() const; @@ -51,15 +67,39 @@ const ArrayBufferOrArrayBufferView& data); ScriptPromise receiveFeatureReport(ScriptState*, uint8_t report_id); - void Trace(blink::Visitor*) override; + // ContextLifecycleObserver: + void ContextDestroyed(ExecutionContext*) override; - protected: - // EventTarget protected overrides. - void AddedEventListener(const AtomicString& event_type, - RegisteredEventListener& listener) override; + void Trace(Visitor*) override; + void Dispose(); private: + bool EnsureNoDeviceChangeInProgress(ScriptPromiseResolver* resolver) const; + + void OnServiceConnectionError(); + + void FinishOpen(ScriptPromiseResolver*, + device::mojom::blink::HidConnectionPtr); + void FinishClose(ScriptPromiseResolver*); + void FinishSendReport(ScriptPromiseResolver*, bool success); + void FinishReceiveReport(ScriptPromiseResolver*, + bool success, + uint8_t report_id, + const base::Optional<Vector<uint8_t>>&); + void FinishSendFeatureReport(ScriptPromiseResolver*, bool success); + void FinishReceiveFeatureReport(ScriptPromiseResolver*, + bool success, + const base::Optional<Vector<uint8_t>>&); + + void MarkRequestComplete(ScriptPromiseResolver*); + + Member<HID> parent_; + device::mojom::blink::HidDeviceInfoPtr device_info_; + device::mojom::blink::HidConnectionPtr connection_; + mojo::Binding<device::mojom::blink::HidConnectionClient> binding_; + HeapHashSet<Member<ScriptPromiseResolver>> device_requests_; HeapVector<Member<HIDCollectionInfo>> collections_; + bool device_state_change_in_progress_ = false; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/hid/hid_input_report_event.cc b/third_party/blink/renderer/modules/hid/hid_input_report_event.cc index 3436ab1efd..f28f06b 100644 --- a/third_party/blink/renderer/modules/hid/hid_input_report_event.cc +++ b/third_party/blink/renderer/modules/hid/hid_input_report_event.cc
@@ -4,37 +4,32 @@ #include "third_party/blink/renderer/modules/hid/hid_input_report_event.h" +#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h" #include "third_party/blink/renderer/core/typed_arrays/dom_data_view.h" -#include "third_party/blink/renderer/modules/hid/hid_input_report_event_init.h" +#include "third_party/blink/renderer/modules/hid/hid_device.h" namespace blink { -HIDInputReportEvent* HIDInputReportEvent::Create( - const AtomicString& type, - const HIDInputReportEventInit* initializer) { - return MakeGarbageCollected<HIDInputReportEvent>(type, initializer); -} - -HIDInputReportEvent* HIDInputReportEvent::Create(const AtomicString& type, - HIDDevice* device, - uint8_t report_id, - const Vector<uint8_t>& data) { - return MakeGarbageCollected<HIDInputReportEvent>(type, device, report_id, - data); -} - -HIDInputReportEvent::HIDInputReportEvent( - const AtomicString& type, - const HIDInputReportEventInit* initializer) - : Event(type, initializer) {} - HIDInputReportEvent::HIDInputReportEvent(const AtomicString& type, HIDDevice* device, uint8_t report_id, const Vector<uint8_t>& data) - : Event(type, Bubbles::kNo, Cancelable::kNo) {} + : Event(type, Bubbles::kNo, Cancelable::kNo), + device_(device), + report_id_(report_id) { + DOMArrayBuffer* dom_buffer = DOMArrayBuffer::Create(data.data(), data.size()); + data_ = DOMDataView::Create(dom_buffer, 0, data.size()); +} + +HIDInputReportEvent::~HIDInputReportEvent() = default; + +const AtomicString& HIDInputReportEvent::InterfaceName() const { + return event_interface_names::kHIDInputReportEvent; +} void HIDInputReportEvent::Trace(blink::Visitor* visitor) { + visitor->Trace(device_); + visitor->Trace(data_); Event::Trace(visitor); }
diff --git a/third_party/blink/renderer/modules/hid/hid_input_report_event.h b/third_party/blink/renderer/modules/hid/hid_input_report_event.h index 466c063..57c9950 100644 --- a/third_party/blink/renderer/modules/hid/hid_input_report_event.h +++ b/third_party/blink/renderer/modules/hid/hid_input_report_event.h
@@ -11,31 +11,30 @@ namespace blink { class DOMDataView; -class HIDInputReportEventInit; class HIDDevice; class HIDInputReportEvent final : public Event { DEFINE_WRAPPERTYPEINFO(); public: - static HIDInputReportEvent* Create(const AtomicString& type, - const HIDInputReportEventInit*); - static HIDInputReportEvent* Create(const AtomicString& type, - HIDDevice*, - uint8_t report_id, - const Vector<uint8_t>& data); - - HIDInputReportEvent(const AtomicString& type, const HIDInputReportEventInit*); HIDInputReportEvent(const AtomicString& type, HIDDevice* device, uint8_t report_id, const Vector<uint8_t>& data); + ~HIDInputReportEvent() override; - HIDDevice* device() const { return nullptr; } - uint8_t reportId() const { return 0; } - DOMDataView* data() const { return nullptr; } + HIDDevice* device() const { return device_; } + uint8_t reportId() const { return report_id_; } + DOMDataView* data() const { return data_; } + // Event: + const AtomicString& InterfaceName() const override; void Trace(blink::Visitor*) override; + + private: + Member<HIDDevice> device_; + uint8_t report_id_; + Member<DOMDataView> data_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/hid/hid_input_report_event.idl b/third_party/blink/renderer/modules/hid/hid_input_report_event.idl index 7285fc5c..615a014 100644 --- a/third_party/blink/renderer/modules/hid/hid_input_report_event.idl +++ b/third_party/blink/renderer/modules/hid/hid_input_report_event.idl
@@ -6,7 +6,6 @@ // https://wicg.github.io/webhid/index.html#events [ - Constructor(DOMString type, HIDInputReportEventInit eventInitDict), Exposed(Window WebHID), SecureContext ] interface HIDInputReportEvent : Event {
diff --git a/third_party/blink/renderer/modules/hid/hid_input_report_event_init.idl b/third_party/blink/renderer/modules/hid/hid_input_report_event_init.idl deleted file mode 100644 index fc54c26..0000000 --- a/third_party/blink/renderer/modules/hid/hid_input_report_event_init.idl +++ /dev/null
@@ -1,12 +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. - -// EventInit initializer dictionary for HIDInputReportEvent. -// https://wicg.github.io/webhid/index.html#events - -dictionary HIDInputReportEventInit : EventInit { - required HIDDevice device; - required octet reportId; - required DataView data; -};
diff --git a/third_party/blink/renderer/modules/hid/hid_report_info.cc b/third_party/blink/renderer/modules/hid/hid_report_info.cc index 3edf508e..a10eb44 100644 --- a/third_party/blink/renderer/modules/hid/hid_report_info.cc +++ b/third_party/blink/renderer/modules/hid/hid_report_info.cc
@@ -9,12 +9,16 @@ namespace blink { HIDReportInfo::HIDReportInfo( - const device::mojom::blink::HidReportDescription& report) {} + const device::mojom::blink::HidReportDescription& report) + : report_id_(report.report_id) { + for (const auto& item : report.items) + items_.push_back(MakeGarbageCollected<HIDReportItem>(*item)); +} HIDReportInfo::~HIDReportInfo() {} uint8_t HIDReportInfo::reportId() const { - return 0; + return report_id_; } const HeapVector<Member<HIDReportItem>>& HIDReportInfo::items() const {
diff --git a/third_party/blink/renderer/modules/hid/hid_report_info.h b/third_party/blink/renderer/modules/hid/hid_report_info.h index 43cb8e1..e7b0d3ca 100644 --- a/third_party/blink/renderer/modules/hid/hid_report_info.h +++ b/third_party/blink/renderer/modules/hid/hid_report_info.h
@@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_REPORT_INFO_H_ #include "services/device/public/mojom/hid.mojom-blink.h" +#include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -13,7 +14,7 @@ class HIDReportItem; -class HIDReportInfo : public ScriptWrappable { +class MODULES_EXPORT HIDReportInfo : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: @@ -27,6 +28,7 @@ void Trace(blink::Visitor* visitor) override; private: + uint8_t report_id_; HeapVector<Member<HIDReportItem>> items_; };
diff --git a/third_party/blink/renderer/modules/hid/hid_report_item.cc b/third_party/blink/renderer/modules/hid/hid_report_item.cc index 2696841f..a8e98ee3 100644 --- a/third_party/blink/renderer/modules/hid/hid_report_item.cc +++ b/third_party/blink/renderer/modules/hid/hid_report_item.cc
@@ -6,8 +6,116 @@ namespace blink { -HIDReportItem::HIDReportItem(const device::mojom::blink::HidReportItem& item) {} +namespace { -HIDReportItem::~HIDReportItem() {} +// The HID specification defines four canonical unit systems. Each unit system +// corresponds to a set of units for length, mass, time, temperature, current, +// and luminous intensity. The vendor-defined unit system can be used for +// devices which produce measurements that cannot be adequately described by +// these unit systems. +// +// See the Units table in section 6.2.2.7 of the Device Class Definition for +// HID v1.11. +// https://www.usb.org/document-library/device-class-definition-hid-111 +enum HidUnitSystem { + // none: No unit system + kUnitSystemNone = 0x00, + // si-linear: Centimeter, Gram, Seconds, Kelvin, Ampere, Candela + kUnitSystemSILinear = 0x01, + // si-rotation: Radians, Gram, Seconds, Kelvin, Ampere, Candela + kUnitSystemSIRotation = 0x02, + // english-linear: Inch, Slug, Seconds, Fahrenheit, Ampere, Candela + kUnitSystemEnglishLinear = 0x03, + // english-linear: Degrees, Slug, Seconds, Fahrenheit, Ampere, Candela + kUnitSystemEnglishRotation = 0x04, + // vendor-defined unit system + kUnitSystemVendorDefined = 0x0f, +}; + +uint32_t ConvertHidUsageAndPageToUint32( + const device::mojom::blink::HidUsageAndPage& usage) { + return (usage.usage_page) << 16 | usage.usage; +} + +String UnitSystemToString(uint8_t unit) { + DCHECK_LE(unit, 0x0f); + switch (unit) { + case kUnitSystemNone: + return "none"; + case kUnitSystemSILinear: + return "si-linear"; + case kUnitSystemSIRotation: + return "si-rotation"; + case kUnitSystemEnglishLinear: + return "english-linear"; + case kUnitSystemEnglishRotation: + return "english-rotation"; + case kUnitSystemVendorDefined: + return "vendor-defined"; + default: + break; + } + // Values other than those defined in HidUnitSystem are reserved by the spec. + return "reserved"; +} + +// Convert |unit_factor_exponent| from its coded representation to a signed +// integer type. +int8_t UnitFactorExponentToInt(uint8_t unit_factor_exponent) { + DCHECK_LE(unit_factor_exponent, 0x0f); + // Values from 0x08 to 0x0f encode negative exponents. + if (unit_factor_exponent > 0x08) + return int8_t{unit_factor_exponent} - 16; + return unit_factor_exponent; +} + +// Unpack the 32-bit unit definition value |unit| into each of its components. +// The unit definition value includes the unit system as well as unit factor +// exponents for each of the 6 units defined by the unit system. +void UnpackUnitValues(uint32_t unit, + String& unit_system, + int8_t& length_exponent, + int8_t& mass_exponent, + int8_t& time_exponent, + int8_t& temperature_exponent, + int8_t& current_exponent, + int8_t& luminous_intensity_exponent) { + unit_system = UnitSystemToString(unit & 0x0f); + length_exponent = UnitFactorExponentToInt((unit >> 4) & 0x0f); + mass_exponent = UnitFactorExponentToInt((unit >> 8) & 0x0f); + time_exponent = UnitFactorExponentToInt((unit >> 12) & 0x0f); + temperature_exponent = UnitFactorExponentToInt((unit >> 16) & 0x0f); + current_exponent = UnitFactorExponentToInt((unit >> 20) & 0x0f); + luminous_intensity_exponent = UnitFactorExponentToInt((unit >> 24) & 0x0f); +} + +} // namespace + +HIDReportItem::HIDReportItem(const device::mojom::blink::HidReportItem& item) + : is_absolute_(!item.is_relative), + is_array_(!item.is_variable), + is_range_(item.is_range), + has_null_(item.has_null_position), + report_size_(item.report_size), + report_count_(item.report_count), + unit_exponent_(UnitFactorExponentToInt(item.unit_exponent & 0x0f)), + logical_minimum_(item.logical_minimum), + logical_maximum_(item.logical_maximum), + physical_minimum_(item.physical_minimum), + physical_maximum_(item.physical_maximum) { + for (const auto& usage : item.usages) + usages_.push_back(ConvertHidUsageAndPageToUint32(*usage)); + usage_minimum_ = ConvertHidUsageAndPageToUint32(*item.usage_minimum); + usage_maximum_ = ConvertHidUsageAndPageToUint32(*item.usage_maximum); + UnpackUnitValues(item.unit, unit_system_, unit_factor_length_exponent_, + unit_factor_mass_exponent_, unit_factor_time_exponent_, + unit_factor_temperature_exponent_, + unit_factor_current_exponent_, + unit_factor_luminous_intensity_exponent_); + + // TODO(mattreynolds): Set |strings_|. +} + +HIDReportItem::~HIDReportItem() = default; } // namespace blink
diff --git a/third_party/blink/renderer/modules/hid/hid_report_item.h b/third_party/blink/renderer/modules/hid/hid_report_item.h index a791350..63085652 100644 --- a/third_party/blink/renderer/modules/hid/hid_report_item.h +++ b/third_party/blink/renderer/modules/hid/hid_report_item.h
@@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_REPORT_ITEM_H_ #include "services/device/public/mojom/hid.mojom-blink.h" +#include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/heap_allocator.h" #include "third_party/blink/renderer/platform/heap/member.h" @@ -14,39 +15,67 @@ namespace blink { -class HIDReportItem : public ScriptWrappable { +class MODULES_EXPORT HIDReportItem : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: explicit HIDReportItem(const device::mojom::blink::HidReportItem& item); ~HIDReportItem() override; - bool isAbsolute() const { return false; } - bool isArray() const { return false; } - bool isRange() const { return false; } - bool hasNull() const { return false; } + bool isAbsolute() const { return is_absolute_; } + bool isArray() const { return is_array_; } + bool isRange() const { return is_range_; } + bool hasNull() const { return has_null_; } const Vector<uint32_t>& usages() const { return usages_; } - uint32_t usageMinimum() const { return 0; } - uint32_t usageMaximum() const { return 0; } + uint32_t usageMinimum() const { return usage_minimum_; } + uint32_t usageMaximum() const { return usage_maximum_; } const Vector<String>& strings() const { return strings_; } - uint16_t reportSize() const { return 0; } - uint16_t reportCount() const { return 0; } - uint32_t unitExponent() const { return 0; } - String unitSystem() const { return String(); } - int8_t unitFactorLengthExponent() const { return 0; } - int8_t unitFactorMassExponent() const { return 0; } - int8_t unitFactorTimeExponent() const { return 0; } - int8_t unitFactorTemperatureExponent() const { return 0; } - int8_t unitFactorCurrentExponent() const { return 0; } - int8_t unitFactorLuminousIntensityExponent() const { return 0; } - int32_t logicalMinimum() const { return 0; } - int32_t logicalMaximum() const { return 0; } - int32_t physicalMinimum() const { return 0; } - int32_t physicalMaximum() const { return 0; } + uint16_t reportSize() const { return report_size_; } + uint16_t reportCount() const { return report_count_; } + int8_t unitExponent() const { return unit_exponent_; } + String unitSystem() const { return unit_system_; } + int8_t unitFactorLengthExponent() const { + return unit_factor_length_exponent_; + } + int8_t unitFactorMassExponent() const { return unit_factor_mass_exponent_; } + int8_t unitFactorTimeExponent() const { return unit_factor_time_exponent_; } + int8_t unitFactorTemperatureExponent() const { + return unit_factor_temperature_exponent_; + } + int8_t unitFactorCurrentExponent() const { + return unit_factor_current_exponent_; + } + int8_t unitFactorLuminousIntensityExponent() const { + return unit_factor_luminous_intensity_exponent_; + } + int32_t logicalMinimum() const { return logical_minimum_; } + int32_t logicalMaximum() const { return logical_maximum_; } + int32_t physicalMinimum() const { return physical_minimum_; } + int32_t physicalMaximum() const { return physical_maximum_; } private: + bool is_absolute_; + bool is_array_; + bool is_range_; + bool has_null_; Vector<uint32_t> usages_; Vector<String> strings_; + uint32_t usage_minimum_; + uint32_t usage_maximum_; + uint16_t report_size_; + uint16_t report_count_; + int8_t unit_exponent_; + String unit_system_; + int8_t unit_factor_length_exponent_; + int8_t unit_factor_mass_exponent_; + int8_t unit_factor_time_exponent_; + int8_t unit_factor_temperature_exponent_; + int8_t unit_factor_current_exponent_; + int8_t unit_factor_luminous_intensity_exponent_; + int32_t logical_minimum_; + int32_t logical_maximum_; + int32_t physical_minimum_; + int32_t physical_maximum_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/hid/hid_report_item.idl b/third_party/blink/renderer/modules/hid/hid_report_item.idl index b682bf80..eed37327 100644 --- a/third_party/blink/renderer/modules/hid/hid_report_item.idl +++ b/third_party/blink/renderer/modules/hid/hid_report_item.idl
@@ -70,7 +70,7 @@ // The base 10 exponent of the units for this report item. For instance, for // kilograms |unitExponent| would be 3 and for micrograms it would be -6. - readonly attribute unsigned long unitExponent; + readonly attribute byte unitExponent; // The unit system determines which units are used for length, mass, time, // temperature, current, and luminous intensity. May be "none" if the values
diff --git a/third_party/blink/renderer/modules/hid/hid_report_item_test.cc b/third_party/blink/renderer/modules/hid/hid_report_item_test.cc new file mode 100644 index 0000000..6902ab2a --- /dev/null +++ b/third_party/blink/renderer/modules/hid/hid_report_item_test.cc
@@ -0,0 +1,162 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/hid/hid_report_item.h" + +#include "services/device/public/mojom/hid.mojom-blink.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { + +namespace { + +// Construct and return a sample HID report item. +device::mojom::blink::HidReportItemPtr MakeReportItem() { + auto item = device::mojom::blink::HidReportItem::New(); + item->is_range = false; // Usages for this item are defined by |usages|. + + // Configure the report item with reasonable values for a button-like input. + item->is_constant = false; // Data. + item->is_variable = true; // Variable. + item->is_relative = false; // Absolute. + item->wrap = false; // No wrap. + item->is_non_linear = false; // Linear. + item->no_preferred_state = false; // Preferred State. + item->has_null_position = false; // No Null position. + item->is_volatile = false; // Non Volatile. + item->is_buffered_bytes = false; // Bit Field. + + // Assign the primary button usage to this item. + item->usages.push_back(device::mojom::blink::HidUsageAndPage::New( + 0x01, device::mojom::blink::kPageButton)); + // |usage_minimum| and |usage_maximum| are unused. + item->usage_minimum = device::mojom::blink::HidUsageAndPage::New(0, 0); + item->usage_maximum = device::mojom::blink::HidUsageAndPage::New(0, 0); + + // Set the designator index and string index extents to zero. This indicates + // that no physical designators or strings are associated with this item. + item->designator_minimum = 0; + item->designator_minimum = 0; + item->string_minimum = 0; + item->string_maximum = 0; + + // The report field described by this item can only hold the logical values 0 + // and 1. + item->logical_minimum = 0; + item->logical_maximum = 1; + item->physical_minimum = 0; + item->physical_maximum = 1; + + // Values reported in this field are unitless. + item->unit_exponent = 0; + item->unit = 0; + + // This item defines a single report field, 8 bits wide. + item->report_size = 8; // 1 byte. + item->report_count = 1; + + return item; +} + +} // namespace + +TEST(HIDReportItemTest, singleUsageItem) { + device::mojom::blink::HidReportItemPtr mojo_item = MakeReportItem(); + HIDReportItem item(*mojo_item); + + // Check that all item properties are correctly converted for the sample + // report item. + EXPECT_TRUE(item.isAbsolute()); + EXPECT_FALSE(item.isArray()); + EXPECT_FALSE(item.isRange()); + EXPECT_FALSE(item.hasNull()); + EXPECT_EQ(1U, item.usages().size()); + EXPECT_EQ(0x00090001U, item.usages()[0]); + EXPECT_EQ(0U, item.usageMinimum()); + EXPECT_EQ(0U, item.usageMaximum()); + EXPECT_TRUE(item.strings().IsEmpty()); + EXPECT_EQ(8U, item.reportSize()); + EXPECT_EQ(1U, item.reportCount()); + EXPECT_EQ(0, item.unitExponent()); + EXPECT_EQ("none", item.unitSystem()); + EXPECT_EQ(0, item.unitFactorLengthExponent()); + EXPECT_EQ(0, item.unitFactorMassExponent()); + EXPECT_EQ(0, item.unitFactorTimeExponent()); + EXPECT_EQ(0, item.unitFactorTemperatureExponent()); + EXPECT_EQ(0, item.unitFactorCurrentExponent()); + EXPECT_EQ(0, item.unitFactorLuminousIntensityExponent()); + EXPECT_EQ(0, item.logicalMinimum()); + EXPECT_EQ(1, item.logicalMaximum()); + EXPECT_EQ(0, item.physicalMinimum()); + EXPECT_EQ(1, item.physicalMaximum()); +} + +TEST(HIDReportItemTest, multiUsageItem) { + device::mojom::blink::HidReportItemPtr mojo_item = MakeReportItem(); + + // Configure the item to use 8 non-consecutive usages. + mojo_item->usages.clear(); + for (int i = 1; i < 9; ++i) { + mojo_item->usages.push_back(device::mojom::blink::HidUsageAndPage::New( + 2 * i, device::mojom::blink::kPageButton)); + } + mojo_item->report_size = 1; // 1 bit. + mojo_item->report_count = 8; + HIDReportItem item(*mojo_item); + + EXPECT_EQ(8U, item.usages().size()); + EXPECT_EQ(0x00090002U, item.usages()[0]); + EXPECT_EQ(0x00090004U, item.usages()[1]); + EXPECT_EQ(0x00090006U, item.usages()[2]); + EXPECT_EQ(0x00090008U, item.usages()[3]); + EXPECT_EQ(0x0009000aU, item.usages()[4]); + EXPECT_EQ(0x0009000cU, item.usages()[5]); + EXPECT_EQ(0x0009000eU, item.usages()[6]); + EXPECT_EQ(0x00090010U, item.usages()[7]); + EXPECT_EQ(1U, item.reportSize()); + EXPECT_EQ(8U, item.reportCount()); +} + +TEST(HIDReportItemTest, usageRangeItem) { + device::mojom::blink::HidReportItemPtr mojo_item = MakeReportItem(); + + // Configure the item to use a usage range. The item defines eight fields, + // each 1-bit wide, with consecutive usages from the Button usage page. + mojo_item->is_range = true; + mojo_item->usages.clear(); + mojo_item->usage_minimum->usage_page = device::mojom::blink::kPageButton; + mojo_item->usage_minimum->usage = 0x01; // 1st button usage (primary). + mojo_item->usage_maximum->usage_page = device::mojom::blink::kPageButton; + mojo_item->usage_maximum->usage = 0x08; // 8th button usage. + mojo_item->report_size = 1; // 1 bit. + mojo_item->report_count = 8; + HIDReportItem item(*mojo_item); + + EXPECT_TRUE(item.usages().IsEmpty()); + EXPECT_EQ(0x00090001U, item.usageMinimum()); + EXPECT_EQ(0x00090008U, item.usageMaximum()); + EXPECT_EQ(1U, item.reportSize()); + EXPECT_EQ(8U, item.reportCount()); +} + +TEST(HIDReportItemTest, unitDefinition) { + device::mojom::blink::HidReportItemPtr mojo_item = MakeReportItem(); + + // Add a unit definition and check that the unit properties are correctly + // converted. + mojo_item->unit_exponent = 0x0C; // 10^-4 + mojo_item->unit = 0x0000E111; // g*cm/s^2 + HIDReportItem item(*mojo_item); + + EXPECT_EQ("si-linear", item.unitSystem()); + EXPECT_EQ(-4, item.unitExponent()); + EXPECT_EQ(1, item.unitFactorLengthExponent()); + EXPECT_EQ(1, item.unitFactorMassExponent()); + EXPECT_EQ(-2, item.unitFactorTimeExponent()); + EXPECT_EQ(0, item.unitFactorTemperatureExponent()); + EXPECT_EQ(0, item.unitFactorCurrentExponent()); + EXPECT_EQ(0, item.unitFactorLuminousIntensityExponent()); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_database.cc b/third_party/blink/renderer/modules/indexeddb/idb_database.cc index 70774d4b..9d1a3bfe 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_database.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_database.cc
@@ -49,7 +49,6 @@ #include "third_party/blink/renderer/modules/indexeddb/web_idb_database_callbacks_impl.h" #include "third_party/blink/renderer/modules/indexeddb/web_idb_transaction_impl.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" -#include "third_party/blink/renderer/platform/instrumentation/histogram.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_factory.cc b/third_party/blink/renderer/modules/indexeddb/idb_factory.cc index f8363a4..9085fff 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_factory.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_factory.cc
@@ -60,7 +60,6 @@ #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/heap/persistent.h" -#include "third_party/blink/renderer/platform/instrumentation/histogram.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc b/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc index 92794d0..2ca5a70 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc
@@ -308,11 +308,6 @@ if (!index_key) return Vector<std::unique_ptr<IDBKey>>(); - DEFINE_THREAD_SAFE_STATIC_LOCAL( - EnumerationHistogram, key_type_histogram, - ("WebCore.IndexedDB.ObjectStore.IndexEntry.KeyType", - static_cast<int>(mojom::IDBKeyType::kMaxValue))); - if (!index_metadata.multi_entry || index_key->GetType() != mojom::IDBKeyType::Array) { if (!index_key->IsValid()) @@ -321,15 +316,12 @@ Vector<std::unique_ptr<IDBKey>> index_keys; index_keys.ReserveInitialCapacity(1); index_keys.emplace_back(std::move(index_key)); - key_type_histogram.Count(static_cast<int>(index_keys[0]->GetType())); return index_keys; } else { DCHECK(index_metadata.multi_entry); DCHECK_EQ(index_key->GetType(), mojom::IDBKeyType::Array); Vector<std::unique_ptr<IDBKey>> index_keys = IDBKey::ToMultiEntryArray(std::move(index_key)); - for (std::unique_ptr<IDBKey>& key : index_keys) - key_type_histogram.Count(static_cast<int>(key->GetType())); return index_keys; } } @@ -542,14 +534,6 @@ return nullptr; } - if (key && uses_in_line_keys) { - DEFINE_THREAD_SAFE_STATIC_LOCAL( - EnumerationHistogram, key_type_histogram, - ("WebCore.IndexedDB.ObjectStore.Record.KeyType", - static_cast<int>(mojom::IDBKeyType::kMaxValue))); - key_type_histogram.Count(static_cast<int>(key->GetType())); - } - Vector<IDBIndexKeys> index_keys; index_keys.ReserveInitialCapacity(Metadata().indexes.size()); for (const auto& it : Metadata().indexes) {
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_request.cc b/third_party/blink/renderer/modules/indexeddb/idb_request.cc index 35c4912..2ad0d5eb 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_request.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_request.cc
@@ -52,7 +52,6 @@ #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/heap.h" -#include "third_party/blink/renderer/platform/instrumentation/histogram.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
diff --git a/third_party/blink/renderer/modules/mediastream/BUILD.gn b/third_party/blink/renderer/modules/mediastream/BUILD.gn index 2607dc2..2f01074e 100644 --- a/third_party/blink/renderer/modules/mediastream/BUILD.gn +++ b/third_party/blink/renderer/modules/mediastream/BUILD.gn
@@ -15,6 +15,7 @@ "input_device_info.cc", "input_device_info.h", "local_media_stream_audio_source.cc", + "local_media_stream_audio_source.h", "media_constraints_impl.cc", "media_constraints_impl.h", "media_device_info.cc", @@ -30,6 +31,7 @@ "media_stream_constraints_util_audio.h", "media_stream_constraints_util_sets.cc", "media_stream_constraints_util_video_content.cc", + "media_stream_constraints_util_video_content.h", "media_stream_constraints_util_video_device.cc", "media_stream_constraints_util_video_device.h", "media_stream_device_observer.cc",
diff --git a/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.cc b/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.cc index 4a082f8..0908f84c 100644 --- a/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.cc +++ b/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.cc
@@ -14,10 +14,10 @@ #include "third_party/blink/public/platform/web_media_stream_source.h" #include "third_party/blink/public/platform/web_media_stream_track.h" #include "third_party/blink/public/platform/web_string.h" -#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_video_content.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h" #include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio.h" +#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.h" #include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
diff --git a/third_party/blink/renderer/modules/mediastream/local_media_stream_audio_source.cc b/third_party/blink/renderer/modules/mediastream/local_media_stream_audio_source.cc index 82ee81f..de235d0 100644 --- a/third_party/blink/renderer/modules/mediastream/local_media_stream_audio_source.cc +++ b/third_party/blink/renderer/modules/mediastream/local_media_stream_audio_source.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/public/web/modules/mediastream/local_media_stream_audio_source.h" +#include "third_party/blink/renderer/modules/mediastream/local_media_stream_audio_source.h" #include <utility> @@ -13,12 +13,11 @@ #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame.h" -#include "third_party/blink/renderer/modules/mediastream/media_stream_local_frame_wrapper.h" namespace blink { LocalMediaStreamAudioSource::LocalMediaStreamAudioSource( - WebLocalFrame* web_frame, + LocalFrame* consumer_frame, const MediaStreamDevice& device, const int* requested_buffer_size, bool disable_local_echo, @@ -27,8 +26,7 @@ : MediaStreamAudioSource(std::move(task_runner), true /* is_local_source */, disable_local_echo), - internal_consumer_frame_( - std::make_unique<MediaStreamInternalFrameWrapper>(web_frame)), + consumer_frame_(consumer_frame), started_callback_(std::move(started_callback)) { DVLOG(1) << "LocalMediaStreamAudioSource::LocalMediaStreamAudioSource()"; SetDevice(device); @@ -79,16 +77,17 @@ // Sanity-check that the consuming WebLocalFrame still exists. // This is required by AudioDeviceFactory. - if (!internal_consumer_frame_->web_frame()) + if (!consumer_frame_) return false; VLOG(1) << "Starting local audio input device (session_id=" << device().session_id() << ") with audio parameters={" << GetAudioParameters().AsHumanReadableString() << "}."; + auto* web_frame = + static_cast<WebLocalFrame*>(WebFrame::FromFrame(consumer_frame_)); source_ = Platform::Current()->NewAudioCapturerSource( - internal_consumer_frame_->web_frame(), - media::AudioSourceParameters(device().session_id())); + web_frame, media::AudioSourceParameters(device().session_id())); source_->Initialize(GetAudioParameters(), this); source_->Start(); return true;
diff --git a/third_party/blink/public/web/modules/mediastream/local_media_stream_audio_source.h b/third_party/blink/renderer/modules/mediastream/local_media_stream_audio_source.h similarity index 73% rename from third_party/blink/public/web/modules/mediastream/local_media_stream_audio_source.h rename to third_party/blink/renderer/modules/mediastream/local_media_stream_audio_source.h index d37c860..9ea0c5a 100644 --- a/third_party/blink/public/web/modules/mediastream/local_media_stream_audio_source.h +++ b/third_party/blink/renderer/modules/mediastream/local_media_stream_audio_source.h
@@ -2,37 +2,36 @@ // 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_WEB_MODULES_MEDIASTREAM_LOCAL_MEDIA_STREAM_AUDIO_SOURCE_H_ -#define THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_LOCAL_MEDIA_STREAM_AUDIO_SOURCE_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_LOCAL_MEDIA_STREAM_AUDIO_SOURCE_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_LOCAL_MEDIA_STREAM_AUDIO_SOURCE_H_ #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h" #include <string> #include "media/base/audio_capturer_source.h" -#include "third_party/blink/public/platform/web_common.h" +#include "third_party/blink/renderer/modules/modules_export.h" namespace blink { -class MediaStreamInternalFrameWrapper; -class WebLocalFrame; +class LocalFrame; // Represents a local source of audio data generated by an AudioInputDevice. // Uses content::AudioDeviceFactory (indirectly through -// blink::Platform::NewAudioRendererSink) to auto-create the AudioInputDevice, +// Platform::NewAudioRendererSink) to auto-create the AudioInputDevice, // using the parameters and session ID found in MediaStreamDevice, just before // the first track is connected. Audio data is transported directly to the // tracks (i.e., there is no audio processing). -class BLINK_MODULES_EXPORT LocalMediaStreamAudioSource +class MODULES_EXPORT LocalMediaStreamAudioSource : public MediaStreamAudioSource, public media::AudioCapturerSource::CaptureCallback { public: - // |consumer_render_frame_id| references the RenderFrame that will consume the + // |consumer_frame| references the RenderFrame that will consume the // audio data. Audio parameters and (optionally) a pre-existing audio session // ID are read from |device_info|. |requested_buffer_size| is the desired // buffer size for the audio hardware, a nullptr means to use the default. LocalMediaStreamAudioSource( - WebLocalFrame* web_frame, + LocalFrame* consumer_frame, const MediaStreamDevice& device, const int* requested_buffer_size, bool disable_local_echo, @@ -44,8 +43,8 @@ // MediaStreamAudioSource implementation. void ChangeSourceImpl(const MediaStreamDevice& new_device) final; - base::Optional<blink::AudioProcessingProperties> - GetAudioProcessingProperties() const final; + base::Optional<AudioProcessingProperties> GetAudioProcessingProperties() + const final; private: // MediaStreamAudioSource implementation. @@ -61,10 +60,13 @@ void OnCaptureError(const std::string& message) final; void OnCaptureMuted(bool is_muted) final; - // The WebLocalFrame that will consume the audio data. Used when creating + // The LocalFrame that will consume the audio data. Used when creating // AudioInputDevices via the AudioDeviceFactory (indirectly through - // blink::Platform). - std::unique_ptr<MediaStreamInternalFrameWrapper> internal_consumer_frame_; + // Platform). + // + // TODO(crbug.com/704136): Consider moving LocalMediaStreamAudioSource to + // Oilpan and use Member<> here. + WeakPersistent<LocalFrame> consumer_frame_; // The device created by the AudioDeviceFactory in EnsureSourceIsStarted(). scoped_refptr<media::AudioCapturerSource> source_; @@ -81,4 +83,4 @@ } // namespace blink -#endif // THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_LOCAL_MEDIA_STREAM_AUDIO_SOURCE_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_LOCAL_MEDIA_STREAM_AUDIO_SOURCE_H_
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio_test.cc b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio_test.cc index 6ceab1f..9324b54 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio_test.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio_test.cc
@@ -21,10 +21,10 @@ #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" #include "third_party/blink/public/platform/web_media_constraints.h" #include "third_party/blink/public/platform/web_string.h" -#include "third_party/blink/public/web/modules/mediastream/local_media_stream_audio_source.h" #include "third_party/blink/public/web/modules/mediastream/mock_constraint_factory.h" #include "third_party/blink/public/web/modules/mediastream/processed_local_audio_source.h" #include "third_party/blink/public/web/modules/webrtc/webrtc_audio_device_impl.h" +#include "third_party/blink/renderer/modules/mediastream/local_media_stream_audio_source.h" #include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h" #include "third_party/webrtc/rtc_base/ref_counted_object.h"
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.cc b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.cc index 02d5a0a..812992b5 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_video_content.h" +#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.h" #include <algorithm> #include <cmath> @@ -12,6 +12,7 @@ #include "third_party/blink/public/common/mediastream/media_stream_controls.h" #include "third_party/blink/public/platform/web_media_constraints.h" #include "third_party/blink/public/platform/web_string.h" +#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_sets.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h" @@ -34,16 +35,15 @@ const double kMaxScreenCastFrameRate = 120.0; const double kDefaultScreenCastFrameRate = - blink::MediaStreamVideoSource::kDefaultFrameRate; + MediaStreamVideoSource::kDefaultFrameRate; namespace { -using blink::VideoCaptureSettings; -using ResolutionSet = blink::media_constraints::ResolutionSet; +using ResolutionSet = media_constraints::ResolutionSet; using Point = ResolutionSet::Point; -using StringSet = blink::media_constraints::DiscreteSet<std::string>; -using BoolSet = blink::media_constraints::DiscreteSet<bool>; -using DoubleRangeSet = blink::media_constraints::NumericRangeSet<double>; +using StringSet = media_constraints::DiscreteSet<std::string>; +using BoolSet = media_constraints::DiscreteSet<bool>; +using DoubleRangeSet = media_constraints::NumericRangeSet<double>; constexpr double kMinScreenCastAspectRatio = static_cast<double>(kMinScreenCastDimension) / @@ -57,7 +57,7 @@ VideoContentCaptureCandidates() : has_explicit_max_height_(false), has_explicit_max_width_(false) {} explicit VideoContentCaptureCandidates( - const blink::WebMediaTrackConstraintSet& constraint_set) + const WebMediaTrackConstraintSet& constraint_set) : resolution_set_(ResolutionSet::FromConstraintSet(constraint_set)), has_explicit_max_height_(ConstraintHasMax(constraint_set.height) && ConstraintMax(constraint_set.height) <= @@ -69,11 +69,11 @@ DoubleRangeSet::FromConstraint(constraint_set.frame_rate, 0.0, kMaxScreenCastFrameRate)), - device_id_set_(blink::media_constraints::StringSetFromConstraint( + device_id_set_(media_constraints::StringSetFromConstraint( constraint_set.device_id)), - noise_reduction_set_(blink::media_constraints::BoolSetFromConstraint( + noise_reduction_set_(media_constraints::BoolSetFromConstraint( constraint_set.goog_noise_reduction)), - rescale_set_(blink::media_constraints::RescaleSetFromConstraint( + rescale_set_(media_constraints::RescaleSetFromConstraint( constraint_set.resize_mode)) {} VideoContentCaptureCandidates(VideoContentCaptureCandidates&& other) = @@ -174,7 +174,7 @@ double SelectFrameRateFromCandidates( const DoubleRangeSet& candidate_set, - const blink::WebMediaTrackConstraintSet& basic_constraint_set, + const WebMediaTrackConstraintSet& basic_constraint_set, double default_frame_rate) { double frame_rate = basic_constraint_set.frame_rate.HasIdeal() ? basic_constraint_set.frame_rate.Ideal() @@ -189,7 +189,7 @@ media::VideoCaptureParams SelectVideoCaptureParamsFromCandidates( const VideoContentCaptureCandidates& candidates, - const blink::WebMediaTrackConstraintSet& basic_constraint_set, + const WebMediaTrackConstraintSet& basic_constraint_set, int default_height, int default_width, double default_frame_rate, @@ -213,7 +213,7 @@ std::string SelectDeviceIDFromCandidates( const StringSet& candidates, - const blink::WebMediaTrackConstraintSet& basic_constraint_set) { + const WebMediaTrackConstraintSet& basic_constraint_set) { DCHECK(!candidates.IsEmpty()); if (basic_constraint_set.device_id.HasIdeal()) { // If there are multiple elements specified by ideal, break ties by choosing @@ -239,7 +239,7 @@ base::Optional<bool> SelectNoiseReductionFromCandidates( const BoolSet& candidates, - const blink::WebMediaTrackConstraintSet& basic_constraint_set) { + const WebMediaTrackConstraintSet& basic_constraint_set) { DCHECK(!candidates.IsEmpty()); if (basic_constraint_set.goog_noise_reduction.HasIdeal() && candidates.Contains(basic_constraint_set.goog_noise_reduction.Ideal())) { @@ -256,16 +256,16 @@ bool SelectRescaleFromCandidates( const BoolSet& candidates, - const blink::WebMediaTrackConstraintSet& basic_constraint_set) { + const WebMediaTrackConstraintSet& basic_constraint_set) { DCHECK(!candidates.IsEmpty()); if (basic_constraint_set.resize_mode.HasIdeal()) { for (const auto& ideal_resize_value : basic_constraint_set.resize_mode.Ideal()) { - if (ideal_resize_value == blink::WebMediaStreamTrack::kResizeModeNone && + if (ideal_resize_value == WebMediaStreamTrack::kResizeModeNone && candidates.Contains(false)) { return false; } else if (ideal_resize_value == - blink::WebMediaStreamTrack::kResizeModeRescale && + WebMediaStreamTrack::kResizeModeRescale && candidates.Contains(true)) { return true; } @@ -288,8 +288,8 @@ VideoCaptureSettings SelectResultFromCandidates( const VideoContentCaptureCandidates& candidates, - const blink::WebMediaTrackConstraintSet& basic_constraint_set, - blink::mojom::MediaStreamType stream_type, + const WebMediaTrackConstraintSet& basic_constraint_set, + mojom::MediaStreamType stream_type, int screen_width, int screen_height) { std::string device_id = SelectDeviceIDFromCandidates( @@ -329,7 +329,7 @@ // This default comes from the old algorithm. media::ResolutionChangePolicy default_resolution_policy = - stream_type == blink::mojom::MediaStreamType::GUM_TAB_VIDEO_CAPTURE + stream_type == mojom::MediaStreamType::GUM_TAB_VIDEO_CAPTURE ? media::ResolutionChangePolicy::FIXED_RESOLUTION : media::ResolutionChangePolicy::ANY_WITHIN_LIMIT; @@ -357,7 +357,7 @@ VideoCaptureSettings UnsatisfiedConstraintsResult( const VideoContentCaptureCandidates& candidates, - const blink::WebMediaTrackConstraintSet& constraint_set) { + const WebMediaTrackConstraintSet& constraint_set) { DCHECK(candidates.IsEmpty()); if (candidates.resolution_set().IsHeightEmpty()) { return VideoCaptureSettings(constraint_set.height.GetName()); @@ -380,8 +380,8 @@ } // namespace VideoCaptureSettings SelectSettingsVideoContentCapture( - const blink::WebMediaConstraints& constraints, - blink::mojom::MediaStreamType stream_type, + const WebMediaConstraints& constraints, + mojom::MediaStreamType stream_type, int screen_width, int screen_height) { VideoContentCaptureCandidates candidates;
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.h b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.h new file mode 100644 index 0000000..96f7c0d --- /dev/null +++ b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.h
@@ -0,0 +1,34 @@ +// 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 THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_VIDEO_CONTENT_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_VIDEO_CONTENT_H_ + +#include "third_party/blink/public/common/mediastream/media_stream_request.h" +#include "third_party/blink/renderer/modules/modules_export.h" + +namespace blink { + +class WebMediaConstraints; +class VideoCaptureSettings; + +MODULES_EXPORT extern const int kMinScreenCastDimension; +MODULES_EXPORT extern const int kMaxScreenCastDimension; +MODULES_EXPORT extern const int kDefaultScreenCastWidth; +MODULES_EXPORT extern const int kDefaultScreenCastHeight; + +MODULES_EXPORT extern const double kMaxScreenCastFrameRate; +MODULES_EXPORT extern const double kDefaultScreenCastFrameRate; + +// This function performs source, source-settings and track-settings selection +// for content video capture based on the given |constraints|. +VideoCaptureSettings MODULES_EXPORT +SelectSettingsVideoContentCapture(const WebMediaConstraints& constraints, + mojom::MediaStreamType stream_type, + int screen_width, + int screen_height); + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_VIDEO_CONTENT_H_
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content_test.cc b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content_test.cc index b378cd4..50ee2e16 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content_test.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content_test.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_video_content.h" +#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.h" #include <cmath> #include <string> @@ -11,6 +11,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h" #include "third_party/blink/public/platform/web_media_constraints.h" +#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h" #include "third_party/blink/public/web/modules/mediastream/mock_constraint_factory.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_utils.cc b/third_party/blink/renderer/modules/mediastream/media_stream_utils.cc index b508d848..d7da867 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_utils.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_utils.cc
@@ -6,11 +6,11 @@ #include "base/single_thread_task_runner.h" #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h" -#include "third_party/blink/public/platform/modules/mediastream/webaudio_media_stream_source.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h" +#include "third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.h" #include "third_party/blink/renderer/platform/scheduler/public/thread.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/mediastream/user_media_client_impl_test.cc b/third_party/blink/renderer/modules/mediastream/user_media_client_impl_test.cc index bfc1b5a..086cbb9 100644 --- a/third_party/blink/renderer/modules/mediastream/user_media_client_impl_test.cc +++ b/third_party/blink/renderer/modules/mediastream/user_media_client_impl_test.cc
@@ -31,12 +31,12 @@ #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_vector.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h" -#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_video_content.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h" #include "third_party/blink/public/web/modules/mediastream/mock_constraint_factory.h" #include "third_party/blink/public/web/modules/mediastream/mock_media_stream_video_source.h" #include "third_party/blink/public/web/modules/mediastream/web_media_stream_device_observer.h" #include "third_party/blink/public/web/web_heap.h" +#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.h" #include "third_party/blink/renderer/modules/mediastream/mock_mojo_media_stream_dispatcher_host.h" #include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
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 66641e85..3423c49 100644 --- a/third_party/blink/renderer/modules/mediastream/user_media_processor.cc +++ b/third_party/blink/renderer/modules/mediastream/user_media_processor.cc
@@ -29,9 +29,7 @@ #include "third_party/blink/public/platform/web_media_stream_track.h" #include "third_party/blink/public/platform/web_screen_info.h" #include "third_party/blink/public/platform/web_string.h" -#include "third_party/blink/public/web/modules/mediastream/local_media_stream_audio_source.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h" -#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_video_content.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_video_capturer_source.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h" #include "third_party/blink/public/web/modules/mediastream/processed_local_audio_source.h" @@ -39,7 +37,9 @@ #include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/page/chrome_client.h" +#include "third_party/blink/renderer/modules/mediastream/local_media_stream_audio_source.h" #include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio.h" +#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.h" #include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.h" #include "third_party/blink/renderer/modules/mediastream/user_media_client_impl.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_processor.h" @@ -1133,13 +1133,6 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(current_request_info_); - // TODO(crbug.com/c/704136): Convert both LocalMediaStreamAudioSource and - // ProcessedLocalAudioSource ctors to operate over LocalFrame instead of - // WebLocalFrame. - WebLocalFrame* web_frame = - frame_ ? static_cast<WebLocalFrame*>(WebFrame::FromFrame(frame_)) - : nullptr; - StreamControls* stream_controls = current_request_info_->stream_controls(); // If the audio device is a loopback device (for screen capture), or if the // constraints/effects parameters indicate no audio processing is needed, @@ -1151,7 +1144,7 @@ !blink::MediaStreamAudioProcessor::WouldModifyAudio( audio_processing_properties)) { return std::make_unique<blink::LocalMediaStreamAudioSource>( - web_frame, device, + frame_, device, base::OptionalOrNullptr(current_request_info_->audio_capture_settings() .requested_buffer_size()), stream_controls->disable_local_echo, std::move(source_ready), @@ -1160,6 +1153,12 @@ // The audio device is not associated with screen capture and also requires // processing. + // + // TODO(crbug.com/c/704136): Convert ProcessedLocalAudioSource ctor to + // operate over LocalFrame instead of WebLocalFrame. + WebLocalFrame* web_frame = + frame_ ? static_cast<WebLocalFrame*>(WebFrame::FromFrame(frame_)) + : nullptr; return std::make_unique<blink::ProcessedLocalAudioSource>( web_frame, device, stream_controls->disable_local_echo, audio_processing_properties, std::move(source_ready), task_runner_);
diff --git a/third_party/blink/renderer/modules/modules_idl_files.gni b/third_party/blink/renderer/modules/modules_idl_files.gni index c6bc7c78..960bbec 100644 --- a/third_party/blink/renderer/modules/modules_idl_files.gni +++ b/third_party/blink/renderer/modules/modules_idl_files.gni
@@ -624,7 +624,6 @@ "hid/hid_connection_event_init.idl", "hid/hid_device_filter.idl", "hid/hid_device_request_options.idl", - "hid/hid_input_report_event_init.idl", "idle/idle_options.idl", "imagecapture/constrain_point_2d_parameters.idl", "imagecapture/photo_settings.idl",
diff --git a/third_party/blink/renderer/modules/modules_initializer.cc b/third_party/blink/renderer/modules/modules_initializer.cc index 2d28825..ed6e4041 100644 --- a/third_party/blink/renderer/modules/modules_initializer.cc +++ b/third_party/blink/renderer/modules/modules_initializer.cc
@@ -24,6 +24,7 @@ #include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h" #include "third_party/blink/renderer/core/html/media/html_media_element.h" #include "third_party/blink/renderer/core/inspector/devtools_session.h" +#include "third_party/blink/renderer/core/inspector/inspector_media_context_impl.h" #include "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h" #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/page.h" @@ -195,6 +196,7 @@ // Only main frame has ImageDownloader service. ImageDownloaderImpl::ProvideTo(frame); } + MediaInspectorContextImpl::ProvideToLocalFrame(frame); } void ModulesInitializer::ProvideLocalFileSystemToWorker(
diff --git a/third_party/blink/renderer/modules/notifications/notification_manager.cc b/third_party/blink/renderer/modules/notifications/notification_manager.cc index f5265ac..4b20812 100644 --- a/third_party/blink/renderer/modules/notifications/notification_manager.cc +++ b/third_party/blink/renderer/modules/notifications/notification_manager.cc
@@ -76,8 +76,8 @@ context->GetTaskRunner(TaskType::kMiscPlatformAPI); ConnectToPermissionService( context, - mojo::MakeRequest(&permission_service_, std::move(task_runner))); - permission_service_.set_connection_error_handler( + permission_service_.BindNewPipeAndPassReceiver(std::move(task_runner))); + permission_service_.set_disconnect_handler( WTF::Bind(&NotificationManager::OnPermissionServiceConnectionError, WrapWeakPersistent(this))); }
diff --git a/third_party/blink/renderer/modules/notifications/notification_manager.h b/third_party/blink/renderer/modules/notifications/notification_manager.h index abea5e77..f43f45ac 100644 --- a/third_party/blink/renderer/modules/notifications/notification_manager.h +++ b/third_party/blink/renderer/modules/notifications/notification_manager.h
@@ -106,7 +106,7 @@ void OnPermissionServiceConnectionError(); mojo::Remote<mojom::blink::NotificationService> notification_service_; - mojom::blink::PermissionServicePtr permission_service_; + mojo::Remote<mojom::blink::PermissionService> permission_service_; DISALLOW_COPY_AND_ASSIGN(NotificationManager); };
diff --git a/third_party/blink/renderer/modules/payments/payment_instruments.cc b/third_party/blink/renderer/modules/payments/payment_instruments.cc index 915b933..5003acb 100644 --- a/third_party/blink/renderer/modules/payments/payment_instruments.cc +++ b/third_party/blink/renderer/modules/payments/payment_instruments.cc
@@ -286,8 +286,9 @@ mojom::blink::PermissionService* PaymentInstruments::GetPermissionService( ScriptState* script_state) { if (!permission_service_) { - ConnectToPermissionService(ExecutionContext::From(script_state), - mojo::MakeRequest(&permission_service_)); + ConnectToPermissionService( + ExecutionContext::From(script_state), + permission_service_.BindNewPipeAndPassReceiver()); } return permission_service_.get(); }
diff --git a/third_party/blink/renderer/modules/payments/payment_instruments.h b/third_party/blink/renderer/modules/payments/payment_instruments.h index 487c451..363cea0 100644 --- a/third_party/blink/renderer/modules/payments/payment_instruments.h +++ b/third_party/blink/renderer/modules/payments/payment_instruments.h
@@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_INSTRUMENTS_H_ #include "base/macros.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/payments/payment_app.mojom-blink.h" #include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h" #include "third_party/blink/renderer/modules/modules_export.h" @@ -62,7 +63,7 @@ const payments::mojom::blink::PaymentManagerPtr& manager_; - mojom::blink::PermissionServicePtr permission_service_; + mojo::Remote<mojom::blink::PermissionService> permission_service_; DISALLOW_COPY_AND_ASSIGN(PaymentInstruments); };
diff --git a/third_party/blink/renderer/modules/permissions/permission_status.cc b/third_party/blink/renderer/modules/permissions/permission_status.cc index 0807b24..a39645f 100644 --- a/third_party/blink/renderer/modules/permissions/permission_status.cc +++ b/third_party/blink/renderer/modules/permissions/permission_status.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/permissions/permission_status.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/document.h" @@ -38,8 +39,7 @@ MojoPermissionDescriptor descriptor) : ContextLifecycleStateObserver(execution_context), status_(status), - descriptor_(std::move(descriptor)), - binding_(this) {} + descriptor_(std::move(descriptor)) {} PermissionStatus::~PermissionStatus() = default; @@ -56,7 +56,7 @@ } bool PermissionStatus::HasPendingActivity() const { - return binding_.is_bound(); + return receiver_.is_bound(); } void PermissionStatus::ContextLifecycleStateChanged( @@ -76,21 +76,21 @@ } void PermissionStatus::StartListening() { - DCHECK(!binding_.is_bound()); - mojom::blink::PermissionObserverPtr observer; + DCHECK(!receiver_.is_bound()); + mojo::PendingRemote<mojom::blink::PermissionObserver> observer; scoped_refptr<base::SingleThreadTaskRunner> task_runner = GetExecutionContext()->GetTaskRunner(TaskType::kPermission); - binding_.Bind(mojo::MakeRequest(&observer, task_runner), task_runner); + receiver_.Bind(observer.InitWithNewPipeAndPassReceiver(), task_runner); - mojom::blink::PermissionServicePtr service; + mojo::Remote<mojom::blink::PermissionService> service; ConnectToPermissionService(GetExecutionContext(), - mojo::MakeRequest(&service, task_runner)); + service.BindNewPipeAndPassReceiver(task_runner)); service->AddPermissionObserver(descriptor_->Clone(), status_, std::move(observer)); } void PermissionStatus::StopListening() { - binding_.Close(); + receiver_.reset(); } void PermissionStatus::OnPermissionStatusChange(MojoPermissionStatus status) {
diff --git a/third_party/blink/renderer/modules/permissions/permission_status.h b/third_party/blink/renderer/modules/permissions/permission_status.h index 055803e5a..6a12afad 100644 --- a/third_party/blink/renderer/modules/permissions/permission_status.h +++ b/third_party/blink/renderer/modules/permissions/permission_status.h
@@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PERMISSIONS_PERMISSION_STATUS_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PERMISSIONS_PERMISSION_STATUS_H_ -#include "mojo/public/cpp/bindings/binding.h" +#include "mojo/public/cpp/bindings/receiver.h" #include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/core/dom/events/event_target.h" @@ -72,7 +72,7 @@ MojoPermissionStatus status_; MojoPermissionDescriptor descriptor_; - mojo::Binding<mojom::blink::PermissionObserver> binding_; + mojo::Receiver<mojom::blink::PermissionObserver> receiver_{this}; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/permissions/permission_utils.cc b/third_party/blink/renderer/modules/permissions/permission_utils.cc index f14b0be..c61535b 100644 --- a/third_party/blink/renderer/modules/permissions/permission_utils.cc +++ b/third_party/blink/renderer/modules/permissions/permission_utils.cc
@@ -24,9 +24,9 @@ void ConnectToPermissionService( ExecutionContext* execution_context, - mojom::blink::PermissionServiceRequest request) { + mojo::PendingReceiver<mojom::blink::PermissionService> receiver) { if (auto* interface_provider = execution_context->GetInterfaceProvider()) - interface_provider->GetInterface(std::move(request)); + interface_provider->GetInterface(std::move(receiver)); } String PermissionStatusToString(mojom::blink::PermissionStatus status) {
diff --git a/third_party/blink/renderer/modules/permissions/permission_utils.h b/third_party/blink/renderer/modules/permissions/permission_utils.h index 688e2de..5a52edb7 100644 --- a/third_party/blink/renderer/modules/permissions/permission_utils.h +++ b/third_party/blink/renderer/modules/permissions/permission_utils.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PERMISSIONS_PERMISSION_UTILS_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PERMISSIONS_PERMISSION_UTILS_H_ +#include "mojo/public/cpp/bindings/pending_receiver.h" #include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h" #include "third_party/blink/renderer/platform/wtf/forward.h" @@ -12,8 +13,9 @@ class ExecutionContext; -void ConnectToPermissionService(ExecutionContext*, - mojom::blink::PermissionServiceRequest); +void ConnectToPermissionService( + ExecutionContext*, + mojo::PendingReceiver<mojom::blink::PermissionService>); String PermissionStatusToString(mojom::blink::PermissionStatus);
diff --git a/third_party/blink/renderer/modules/permissions/permissions.cc b/third_party/blink/renderer/modules/permissions/permissions.cc index 383fdcc..5927e03 100644 --- a/third_party/blink/renderer/modules/permissions/permissions.cc +++ b/third_party/blink/renderer/modules/permissions/permissions.cc
@@ -196,10 +196,10 @@ // likely be "prompt". PermissionDescriptorPtr descriptor_copy = descriptor->Clone(); GetService(ExecutionContext::From(script_state)) - .HasPermission(std::move(descriptor), - WTF::Bind(&Permissions::TaskComplete, WrapPersistent(this), - WrapPersistent(resolver), - WTF::Passed(std::move(descriptor_copy)))); + ->HasPermission(std::move(descriptor), + WTF::Bind(&Permissions::TaskComplete, + WrapPersistent(this), WrapPersistent(resolver), + WTF::Passed(std::move(descriptor_copy)))); return promise; } @@ -220,7 +220,7 @@ Document* doc = DynamicTo<Document>(context); LocalFrame* frame = doc ? doc->GetFrame() : nullptr; GetService(ExecutionContext::From(script_state)) - .RequestPermission( + ->RequestPermission( std::move(descriptor), LocalFrame::HasTransientUserActivation( frame, true /* check_if_main_thread */), @@ -243,7 +243,7 @@ PermissionDescriptorPtr descriptor_copy = descriptor->Clone(); GetService(ExecutionContext::From(script_state)) - .RevokePermission( + ->RevokePermission( std::move(descriptor), WTF::Bind(&Permissions::TaskComplete, WrapPersistent(this), WrapPersistent(resolver), @@ -295,7 +295,7 @@ Document* doc = DynamicTo<Document>(context); LocalFrame* frame = doc ? doc->GetFrame() : nullptr; GetService(ExecutionContext::From(script_state)) - .RequestPermissions( + ->RequestPermissions( std::move(internal_permissions), LocalFrame::HasTransientUserActivation( frame, true /* check_if_main_thread */), @@ -306,17 +306,17 @@ return promise; } -PermissionService& Permissions::GetService( +PermissionService* Permissions::GetService( ExecutionContext* execution_context) { if (!service_) { ConnectToPermissionService( execution_context, - mojo::MakeRequest(&service_, execution_context->GetTaskRunner( - TaskType::kPermission))); - service_.set_connection_error_handler(WTF::Bind( + service_.BindNewPipeAndPassReceiver( + execution_context->GetTaskRunner(TaskType::kPermission))); + service_.set_disconnect_handler(WTF::Bind( &Permissions::ServiceConnectionError, WrapWeakPersistent(this))); } - return *service_; + return service_.get(); } void Permissions::ServiceConnectionError() {
diff --git a/third_party/blink/renderer/modules/permissions/permissions.h b/third_party/blink/renderer/modules/permissions/permissions.h index c91c9be..d17ffd9 100644 --- a/third_party/blink/renderer/modules/permissions/permissions.h +++ b/third_party/blink/renderer/modules/permissions/permissions.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PERMISSIONS_PERMISSIONS_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PERMISSIONS_PERMISSIONS_H_ +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" @@ -29,7 +30,7 @@ ExceptionState&); private: - mojom::blink::PermissionService& GetService(ExecutionContext*); + mojom::blink::PermissionService* GetService(ExecutionContext*); void ServiceConnectionError(); void TaskComplete(ScriptPromiseResolver*, mojom::blink::PermissionDescriptorPtr, @@ -39,7 +40,7 @@ Vector<int>, const Vector<mojom::blink::PermissionStatus>&); - mojom::blink::PermissionServicePtr service_; + mojo::Remote<mojom::blink::PermissionService> service_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.cc b/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.cc index d2abfad..ae69d791 100644 --- a/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.cc +++ b/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.cc
@@ -52,8 +52,8 @@ const PushSubscriptionOptionsInit* options) { ExecutionContext* context = ExecutionContext::From(script_state); if (!permission_service_) { - ConnectToPermissionService(context, - mojo::MakeRequest(&permission_service_)); + ConnectToPermissionService( + context, permission_service_.BindNewPipeAndPassReceiver()); } auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
diff --git a/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.h b/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.h index 28d375eb..af26f9e 100644 --- a/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.h +++ b/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.h
@@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PUSH_MESSAGING_PUSH_MESSAGING_BRIDGE_H_ #include "base/macros.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h" #include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink.h" #include "third_party/blink/renderer/modules/service_worker/service_worker_registration.h" @@ -46,7 +47,7 @@ void DidGetPermissionState(ScriptPromiseResolver* resolver, mojom::blink::PermissionStatus status); - mojom::blink::PermissionServicePtr permission_service_; + mojo::Remote<mojom::blink::PermissionService> permission_service_; DISALLOW_COPY_AND_ASSIGN(PushMessagingBridge); };
diff --git a/third_party/blink/renderer/modules/quota/storage_manager.cc b/third_party/blink/renderer/modules/quota/storage_manager.cc index 7b427b07..8b2e76d 100644 --- a/third_party/blink/renderer/modules/quota/storage_manager.cc +++ b/third_party/blink/renderer/modules/quota/storage_manager.cc
@@ -97,7 +97,7 @@ Document* doc = To<Document>(execution_context); GetPermissionService(ExecutionContext::From(script_state)) - .RequestPermission( + ->RequestPermission( CreatePermissionDescriptor(PermissionName::DURABLE_STORAGE), LocalFrame::HasTransientUserActivation(doc->GetFrame()), WTF::Bind(&StorageManager::PermissionRequestComplete, @@ -120,7 +120,7 @@ } GetPermissionService(ExecutionContext::From(script_state)) - .HasPermission( + ->HasPermission( CreatePermissionDescriptor(PermissionName::DURABLE_STORAGE), WTF::Bind(&StorageManager::PermissionRequestComplete, WrapPersistent(this), WrapPersistent(resolver))); @@ -151,18 +151,18 @@ return promise; } -PermissionService& StorageManager::GetPermissionService( +PermissionService* StorageManager::GetPermissionService( ExecutionContext* execution_context) { if (!permission_service_) { ConnectToPermissionService( - execution_context, mojo::MakeRequest(&permission_service_, - execution_context->GetTaskRunner( - TaskType::kMiscPlatformAPI))); - permission_service_.set_connection_error_handler( + execution_context, + permission_service_.BindNewPipeAndPassReceiver( + execution_context->GetTaskRunner(TaskType::kMiscPlatformAPI))); + permission_service_.set_disconnect_handler( WTF::Bind(&StorageManager::PermissionServiceConnectionError, WrapWeakPersistent(this))); } - return *permission_service_; + return permission_service_.get(); } void StorageManager::PermissionServiceConnectionError() {
diff --git a/third_party/blink/renderer/modules/quota/storage_manager.h b/third_party/blink/renderer/modules/quota/storage_manager.h index 3ec770d..1ebee48 100644 --- a/third_party/blink/renderer/modules/quota/storage_manager.h +++ b/third_party/blink/renderer/modules/quota/storage_manager.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_QUOTA_STORAGE_MANAGER_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_QUOTA_STORAGE_MANAGER_H_ +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h" #include "third_party/blink/public/mojom/quota/quota_dispatcher_host.mojom-blink.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" @@ -27,7 +28,7 @@ ScriptPromise estimate(ScriptState*); private: - mojom::blink::PermissionService& GetPermissionService(ExecutionContext*); + mojom::blink::PermissionService* GetPermissionService(ExecutionContext*); void PermissionServiceConnectionError(); void PermissionRequestComplete(ScriptPromiseResolver*, mojom::blink::PermissionStatus); @@ -36,7 +37,7 @@ // provider, and returns it, mojom::blink::QuotaDispatcherHost& GetQuotaHost(ExecutionContext*); - mojom::blink::PermissionServicePtr permission_service_; + mojo::Remote<mojom::blink::PermissionService> permission_service_; mojom::blink::QuotaDispatcherHostPtr quota_host_; };
diff --git a/third_party/blink/renderer/modules/wake_lock/wake_lock_controller.cc b/third_party/blink/renderer/modules/wake_lock/wake_lock_controller.cc index 33c5d0b..6c87877 100644 --- a/third_party/blink/renderer/modules/wake_lock/wake_lock_controller.cc +++ b/third_party/blink/renderer/modules/wake_lock/wake_lock_controller.cc
@@ -216,18 +216,19 @@ ? To<Document>(GetExecutionContext())->GetFrame() : nullptr; - GetPermissionService().RequestPermission( + GetPermissionService()->RequestPermission( CreateWakeLockPermissionDescriptor( static_cast<mojom::blink::WakeLockType>(type)), LocalFrame::HasTransientUserActivation(local_frame), std::move(callback)); } -PermissionService& WakeLockController::GetPermissionService() { +PermissionService* WakeLockController::GetPermissionService() { if (!permission_service_) { - ConnectToPermissionService(GetExecutionContext(), - mojo::MakeRequest(&permission_service_)); + ConnectToPermissionService( + GetExecutionContext(), + permission_service_.BindNewPipeAndPassReceiver()); } - return *permission_service_; + return permission_service_.get(); } } // namespace blink
diff --git a/third_party/blink/renderer/modules/wake_lock/wake_lock_controller.h b/third_party/blink/renderer/modules/wake_lock/wake_lock_controller.h index 65fb629..4688fdd 100644 --- a/third_party/blink/renderer/modules/wake_lock/wake_lock_controller.h +++ b/third_party/blink/renderer/modules/wake_lock/wake_lock_controller.h
@@ -7,6 +7,7 @@ #include "base/callback.h" #include "base/gtest_prod_util.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" @@ -68,9 +69,9 @@ void ObtainPermission( WakeLockType type, base::OnceCallback<void(mojom::blink::PermissionStatus)> callback); - mojom::blink::PermissionService& GetPermissionService(); + mojom::blink::PermissionService* GetPermissionService(); - mojom::blink::PermissionServicePtr permission_service_; + mojo::Remote<mojom::blink::PermissionService> permission_service_; // https://w3c.github.io/wake-lock/#concepts-and-state-record // Each platform wake lock (one per wake lock type) has an associated state
diff --git a/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.cc b/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.cc index 79f20dc..d614a46 100644 --- a/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.cc +++ b/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.cc
@@ -7,7 +7,9 @@ #include <utility> #include "base/logging.h" +#include "base/macros.h" #include "base/run_loop.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/renderer/bindings/core/v8/script_function.h" #include "third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h" @@ -147,9 +149,10 @@ MockPermissionService::~MockPermissionService() = default; void MockPermissionService::BindRequest(mojo::ScopedMessagePipeHandle handle) { - DCHECK(!binding_.is_bound()); - binding_.Bind(mojom::blink::PermissionServiceRequest(std::move(handle))); - binding_.set_connection_error_handler(WTF::Bind( + DCHECK(!receiver_.is_bound()); + receiver_.Bind(mojo::PendingReceiver<mojom::blink::PermissionService>( + std::move(handle))); + receiver_.set_disconnect_handler(WTF::Bind( &MockPermissionService::OnConnectionError, WTF::Unretained(this))); } @@ -161,7 +164,7 @@ } void MockPermissionService::OnConnectionError() { - binding_.Unbind(); + ignore_result(receiver_.Unbind()); } bool MockPermissionService::GetWakeLockTypeFromDescriptor( @@ -235,7 +238,7 @@ void MockPermissionService::AddPermissionObserver( PermissionDescriptorPtr permission, PermissionStatus last_known_status, - mojom::blink::PermissionObserverPtr) { + mojo::PendingRemote<mojom::blink::PermissionObserver>) { NOTREACHED(); }
diff --git a/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.h b/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.h index ce01a8b6..1446b10 100644 --- a/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.h +++ b/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.h
@@ -7,8 +7,9 @@ #include "base/callback.h" #include "base/optional.h" -#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding_set.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/receiver.h" #include "services/device/public/mojom/wake_lock.mojom-blink.h" #include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h" #include "third_party/blink/public/mojom/wake_lock/wake_lock.mojom-blink.h" @@ -115,13 +116,14 @@ RequestPermissionsCallback) override; void RevokePermission(mojom::blink::PermissionDescriptorPtr permission, RevokePermissionCallback) override; - void AddPermissionObserver(mojom::blink::PermissionDescriptorPtr permission, - mojom::blink::PermissionStatus last_known_status, - mojom::blink::PermissionObserverPtr) override; + void AddPermissionObserver( + mojom::blink::PermissionDescriptorPtr permission, + mojom::blink::PermissionStatus last_known_status, + mojo::PendingRemote<mojom::blink::PermissionObserver>) override; void OnConnectionError(); - mojo::Binding<mojom::blink::PermissionService> binding_{this}; + mojo::Receiver<mojom::blink::PermissionService> receiver_{this}; base::Optional<mojom::blink::PermissionStatus> permission_responses_[kWakeLockTypeCount];
diff --git a/third_party/blink/renderer/modules/webaudio/audio_context.cc b/third_party/blink/renderer/modules/webaudio/audio_context.cc index a94b4f1..a3d7a030 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_context.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_context.cc
@@ -55,6 +55,13 @@ ExceptionState& exception_state) { DCHECK(IsMainThread()); + if (document.IsDetached()) { + exception_state.ThrowDOMException( + DOMExceptionCode::kNotSupportedError, + "Cannot create AudioContext on a detached document."); + return nullptr; + } + document.CountUseOnlyInCrossOriginIframe( WebFeature::kAudioContextCrossOriginIframe);
diff --git a/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc b/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc index d5e89b6..8c42f49a 100644 --- a/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc +++ b/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc
@@ -58,6 +58,13 @@ return nullptr; } + if (document->IsDetached()) { + exception_state.ThrowDOMException( + DOMExceptionCode::kNotSupportedError, + "Cannot create OfflineAudioContext on a detached document."); + return nullptr; + } + if (!number_of_frames) { exception_state.ThrowDOMException( DOMExceptionCode::kNotSupportedError,
diff --git a/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc b/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc index 9d58695..4c19f27 100644 --- a/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc +++ b/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc
@@ -78,20 +78,14 @@ } void RealtimeAnalyser::WriteInput(AudioBus* bus, uint32_t frames_to_process) { - bool is_bus_good = bus && bus->NumberOfChannels() > 0 && - bus->Channel(0)->length() >= frames_to_process; - DCHECK(is_bus_good); - if (!is_bus_good) - return; + DCHECK(bus); + DCHECK_GT(bus->NumberOfChannels(), 0u); + DCHECK_GE(bus->Channel(0)->length(), frames_to_process); unsigned write_index = GetWriteIndex(); // FIXME : allow to work with non-FFTSize divisible chunking - bool is_destination_good = - write_index < input_buffer_.size() && - write_index + frames_to_process <= input_buffer_.size(); - DCHECK(is_destination_good); - if (!is_destination_good) - return; + DCHECK_LT(write_index, input_buffer_.size()); + DCHECK_LE(write_index + frames_to_process, input_buffer_.size()); // Perform real-time analysis float* dest = input_buffer_.Data() + write_index; @@ -281,11 +275,8 @@ unsigned fft_size = this->FftSize(); size_t len = std::min(fft_size, destination_array->length()); if (len > 0) { - bool is_input_buffer_good = input_buffer_.size() == kInputBufferSize && - input_buffer_.size() > fft_size; - DCHECK(is_input_buffer_good); - if (!is_input_buffer_good) - return; + DCHECK_EQ(input_buffer_.size(), kInputBufferSize); + DCHECK_GT(input_buffer_.size(), fft_size); float* input_buffer = input_buffer_.Data(); float* destination = destination_array->Data(); @@ -310,11 +301,8 @@ unsigned fft_size = this->FftSize(); size_t len = std::min(fft_size, destination_array->length()); if (len > 0) { - bool is_input_buffer_good = input_buffer_.size() == kInputBufferSize && - input_buffer_.size() > fft_size; - DCHECK(is_input_buffer_good); - if (!is_input_buffer_good) - return; + DCHECK_EQ(input_buffer_.size(), kInputBufferSize); + DCHECK_GT(input_buffer_.size(), fft_size); float* input_buffer = input_buffer_.Data(); unsigned char* destination = destination_array->Data();
diff --git a/third_party/blink/renderer/modules/webaudio/script_processor_node.cc b/third_party/blink/renderer/modules/webaudio/script_processor_node.cc index 4b7d5b1..ee72d2c 100644 --- a/third_party/blink/renderer/modules/webaudio/script_processor_node.cc +++ b/third_party/blink/renderer/modules/webaudio/script_processor_node.cc
@@ -125,13 +125,9 @@ // Get input and output buffers. We double-buffer both the input and output // sides. uint32_t double_buffer_index = this->DoubleBufferIndex(); - bool is_double_buffer_index_good = - double_buffer_index < 2 && - double_buffer_index < shared_input_buffers_.size() && - double_buffer_index < shared_output_buffers_.size(); - DCHECK(is_double_buffer_index_good); - if (!is_double_buffer_index_good) - return; + DCHECK_LT(double_buffer_index, 2u); + DCHECK_LT(double_buffer_index, shared_input_buffers_.size()); + DCHECK_LT(double_buffer_index, shared_output_buffers_.size()); SharedAudioBuffer* shared_input_buffer = shared_input_buffers_.at(double_buffer_index).get(); @@ -156,21 +152,14 @@ // We assume that bufferSize() is evenly divisible by framesToProcess - should // always be true, but we should still check. - bool is_frames_to_process_good = frames_to_process && - BufferSize() >= frames_to_process && - !(BufferSize() % frames_to_process); - DCHECK(is_frames_to_process_good); - if (!is_frames_to_process_good) - return; + DCHECK_GT(frames_to_process, 0u); + DCHECK_GE(BufferSize(), frames_to_process); + DCHECK_EQ(BufferSize() % frames_to_process, 0u); uint32_t number_of_output_channels = output_bus->NumberOfChannels(); - bool channels_are_good = - (number_of_input_channels == number_of_input_channels_) && - (number_of_output_channels == number_of_output_channels_); - DCHECK(channels_are_good); - if (!channels_are_good) - return; + DCHECK_EQ(number_of_input_channels, number_of_input_channels_); + DCHECK_EQ(number_of_output_channels, number_of_output_channels_); for (uint32_t i = 0; i < number_of_input_channels; ++i) internal_input_bus_->SetChannelMemory( @@ -248,8 +237,6 @@ return; DCHECK_LT(double_buffer_index, 2u); - if (double_buffer_index > 1) - return; // Avoid firing the event if the document has already gone away. if (GetNode()) {
diff --git a/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.cc b/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.cc index ee76705..e8bd42a 100644 --- a/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.cc +++ b/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.cc
@@ -143,10 +143,7 @@ void WaveShaperDSPKernel::ProcessCurve2x(const float* source, float* destination, uint32_t frames_to_process) { - bool is_safe = frames_to_process == audio_utilities::kRenderQuantumFrames; - DCHECK(is_safe); - if (!is_safe) - return; + DCHECK_EQ(frames_to_process, audio_utilities::kRenderQuantumFrames); float* temp_p = temp_buffer_->Data(); @@ -161,10 +158,7 @@ void WaveShaperDSPKernel::ProcessCurve4x(const float* source, float* destination, uint32_t frames_to_process) { - bool is_safe = frames_to_process == audio_utilities::kRenderQuantumFrames; - DCHECK(is_safe); - if (!is_safe) - return; + DCHECK_EQ(frames_to_process, audio_utilities::kRenderQuantumFrames); float* temp_p = temp_buffer_->Data(); float* temp_p2 = temp_buffer2_->Data();
diff --git a/third_party/blink/renderer/modules/webaudio/wave_shaper_processor.cc b/third_party/blink/renderer/modules/webaudio/wave_shaper_processor.cc index 6c3e83b..76eefdfc 100644 --- a/third_party/blink/renderer/modules/webaudio/wave_shaper_processor.cc +++ b/third_party/blink/renderer/modules/webaudio/wave_shaper_processor.cc
@@ -97,12 +97,8 @@ return; } - bool channel_count_matches = - source->NumberOfChannels() == destination->NumberOfChannels() && - source->NumberOfChannels() == kernels_.size(); - DCHECK(channel_count_matches); - if (!channel_count_matches) - return; + DCHECK_EQ(source->NumberOfChannels(), destination->NumberOfChannels()); + DCHECK_EQ(source->NumberOfChannels(), kernels_.size()); // The audio thread can't block on this lock, so we call tryLock() instead. MutexTryLocker try_locker(process_lock_);
diff --git a/third_party/blink/renderer/modules/webmidi/midi_access_initializer.cc b/third_party/blink/renderer/modules/webmidi/midi_access_initializer.cc index a9c30c9..e76ba15 100644 --- a/third_party/blink/renderer/modules/webmidi/midi_access_initializer.cc +++ b/third_party/blink/renderer/modules/webmidi/midi_access_initializer.cc
@@ -54,7 +54,7 @@ ConnectToPermissionService( GetExecutionContext(), - mojo::MakeRequest(&permission_service_, std::move(task_runner))); + permission_service_.BindNewPipeAndPassReceiver(std::move(task_runner))); Document& doc = To<Document>(*GetExecutionContext()); permission_service_->RequestPermission(
diff --git a/third_party/blink/renderer/modules/webmidi/midi_access_initializer.h b/third_party/blink/renderer/modules/webmidi/midi_access_initializer.h index 777886e..e347e49 100644 --- a/third_party/blink/renderer/modules/webmidi/midi_access_initializer.h +++ b/third_party/blink/renderer/modules/webmidi/midi_access_initializer.h
@@ -7,6 +7,7 @@ #include <memory> #include "media/midi/midi_service.mojom-blink.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h" #include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" @@ -100,7 +101,7 @@ Vector<PortDescriptor> port_descriptors_; Member<const MIDIOptions> options_; - mojom::blink::PermissionServicePtr permission_service_; + mojo::Remote<mojom::blink::PermissionService> permission_service_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/xr/OWNERS b/third_party/blink/renderer/modules/xr/OWNERS index 04300e66..d35fcbdb 100644 --- a/third_party/blink/renderer/modules/xr/OWNERS +++ b/third_party/blink/renderer/modules/xr/OWNERS
@@ -1,5 +1,6 @@ alcooper@chromium.org bajones@chromium.org +jacde@chromium.org klausw@chromium.org # TEAM: xr-dev@chromium.org
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index 3e647ed..5896806c 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -479,7 +479,6 @@ "exported/mediastream/web_media_element_source_utils.cc", "exported/mediastream/web_platform_media_stream_source.cc", "exported/mediastream/web_platform_media_stream_track.cc", - "exported/mediastream/webaudio_media_stream_source.cc", "exported/mediastream/webrtc_uma_histograms.cc", "exported/platform.cc", "exported/service_registry.cc", @@ -1202,6 +1201,8 @@ "mediastream/media_stream_source.h", "mediastream/media_stream_web_audio_source.cc", "mediastream/media_stream_web_audio_source.h", + "mediastream/webaudio_media_stream_source.cc", + "mediastream/webaudio_media_stream_source.h", "mhtml/archive_resource.cc", "mhtml/archive_resource.h", "mhtml/mhtml_archive.cc",
diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc index 03e6e27..bd957f9f 100644 --- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc +++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -272,10 +272,6 @@ RuntimeEnabledFeatures::SetNetInfoDownlinkMaxEnabled(enable); } -void WebRuntimeFeatures::EnableNetworkService(bool enable) { - RuntimeEnabledFeatures::SetNetworkServiceEnabled(enable); -} - void WebRuntimeFeatures::EnableOnDeviceChange(bool enable) { RuntimeEnabledFeatures::SetOnDeviceChangeEnabled(enable); }
diff --git a/third_party/blink/renderer/platform/graphics/generated_image.cc b/third_party/blink/renderer/platform/graphics/generated_image.cc index 0fc64ec3..6efb7a029 100644 --- a/third_party/blink/renderer/platform/graphics/generated_image.cc +++ b/third_party/blink/renderer/platform/graphics/generated_image.cc
@@ -48,19 +48,12 @@ FloatRect tile_rect = src_rect; tile_rect.Expand(repeat_spacing); - auto paint_controller = std::make_unique<PaintController>(); - GraphicsContext context(*paint_controller); - context.BeginRecording(tile_rect); - DrawTile(context, src_rect); - sk_sp<PaintRecord> record = context.EndRecording(); - SkMatrix pattern_matrix = SkMatrix::MakeTrans(phase.X(), phase.Y()); pattern_matrix.preScale(scale.Width(), scale.Height()); pattern_matrix.preTranslate(tile_rect.X(), tile_rect.Y()); - sk_sp<PaintShader> tile_shader = PaintShader::MakePaintRecord( - std::move(record), tile_rect, SkTileMode::kRepeat, SkTileMode::kRepeat, - &pattern_matrix); + sk_sp<PaintShader> tile_shader = + CreateShader(tile_rect, &pattern_matrix, src_rect); PaintFlags fill_flags = dest_context.FillFlags(); fill_flags.setShader(std::move(tile_shader)); @@ -70,6 +63,20 @@ dest_context.DrawRect(dest_rect, fill_flags); } +sk_sp<PaintShader> GeneratedImage::CreateShader(const FloatRect& tile_rect, + const SkMatrix* pattern_matrix, + const FloatRect& src_rect) { + auto paint_controller = std::make_unique<PaintController>(); + GraphicsContext context(*paint_controller); + context.BeginRecording(tile_rect); + DrawTile(context, src_rect); + sk_sp<PaintRecord> record = context.EndRecording(); + + return PaintShader::MakePaintRecord(std::move(record), tile_rect, + SkTileMode::kRepeat, SkTileMode::kRepeat, + pattern_matrix); +} + PaintImage GeneratedImage::PaintImageForCurrentFrame() { return PaintImage(); }
diff --git a/third_party/blink/renderer/platform/graphics/generated_image.h b/third_party/blink/renderer/platform/graphics/generated_image.h index f9c629e..21d225cf 100644 --- a/third_party/blink/renderer/platform/graphics/generated_image.h +++ b/third_party/blink/renderer/platform/graphics/generated_image.h
@@ -53,6 +53,9 @@ SkBlendMode, const FloatRect&, const FloatSize& repeat_spacing) final; + virtual sk_sp<cc::PaintShader> CreateShader(const FloatRect& tile_rect, + const SkMatrix* pattern_matrix, + const FloatRect& src_rect); // FIXME: Implement this to be less conservative. bool CurrentFrameKnownToBeOpaque() override { return false; }
diff --git a/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.cc b/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.cc index a6b7e6a2..6450da3e 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.cc
@@ -289,8 +289,13 @@ // Create a texture backed by the shared buffer image. DCHECK(!shared_buffer_texture_id_); - shared_buffer_texture_id_ = - gl->CreateAndConsumeTextureCHROMIUM(buffer_mailbox_holder.mailbox.name); + DCHECK(buffer_mailbox_holder.mailbox.IsSharedImage()); + shared_buffer_texture_id_ = gl->CreateAndTexStorage2DSharedImageCHROMIUM( + buffer_mailbox_holder.mailbox.name); + + gl->BeginSharedImageAccessDirectCHROMIUM( + shared_buffer_texture_id_, + GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM); if (WantExplicitResolve()) { // Bind the shared texture to the destination framebuffer of @@ -353,8 +358,10 @@ // rendering now. gl->BindFramebuffer(GL_FRAMEBUFFER, 0); - // Done with the texture created by CreateAndConsumeTexture, delete it. + // Done with the texture created by CreateAndTexStorage2DSharedImageCHROMIUM + // finish accessing and delete it. DCHECK(shared_buffer_texture_id_); + gl->EndSharedImageAccessDirectCHROMIUM(shared_buffer_texture_id_); gl->DeleteTextures(1, &shared_buffer_texture_id_); shared_buffer_texture_id_ = 0;
diff --git a/third_party/blink/renderer/platform/heap/handle.h b/third_party/blink/renderer/platform/heap/handle.h index 1447743..9df15cc4 100644 --- a/third_party/blink/renderer/platform/heap/handle.h +++ b/third_party/blink/renderer/platform/heap/handle.h
@@ -37,47 +37,9 @@ #include "third_party/blink/renderer/platform/heap/heap_traits.h" #include "third_party/blink/renderer/platform/heap/member.h" #include "third_party/blink/renderer/platform/heap/thread_state.h" +#include "third_party/blink/renderer/platform/heap/thread_state_scopes.h" #include "third_party/blink/renderer/platform/heap/trace_traits.h" #include "third_party/blink/renderer/platform/heap/visitor.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" -#if defined(LEAK_SANITIZER) -#include "third_party/blink/renderer/platform/wtf/leak_annotations.h" -#endif - -namespace blink { - -// LEAK_SANITIZER_DISABLED_SCOPE: all allocations made in the current scope -// will be exempted from LSan consideration. -// -// TODO(sof): move this to wtf/LeakAnnotations.h (LeakSanitizer.h?) once -// wtf/ can freely call upon Oilpan functionality. -#if defined(LEAK_SANITIZER) -class LeakSanitizerDisableScope { - STACK_ALLOCATED(); - - public: - LeakSanitizerDisableScope() { - __lsan_disable(); - if (ThreadState::Current()) - ThreadState::Current()->enterStaticReferenceRegistrationDisabledScope(); - } - - ~LeakSanitizerDisableScope() { - __lsan_enable(); - if (ThreadState::Current()) - ThreadState::Current()->leaveStaticReferenceRegistrationDisabledScope(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(LeakSanitizerDisableScope); -}; -#define LEAK_SANITIZER_DISABLED_SCOPE \ - LeakSanitizerDisableScope lsanDisabledScope -#else -#define LEAK_SANITIZER_DISABLED_SCOPE -#endif - -} // namespace blink - -#endif +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HANDLE_H_
diff --git a/third_party/blink/renderer/platform/heap/heap.cc b/third_party/blink/renderer/platform/heap/heap.cc index eb535ede..470f967f73 100644 --- a/third_party/blink/renderer/platform/heap/heap.cc +++ b/third_party/blink/renderer/platform/heap/heap.cc
@@ -37,6 +37,7 @@ #include "base/trace_event/process_memory_dump.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h" +#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h" #include "third_party/blink/renderer/platform/heap/address_cache.h" #include "third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h" #include "third_party/blink/renderer/platform/heap/heap_compact.h" @@ -45,6 +46,7 @@ #include "third_party/blink/renderer/platform/heap/page_memory.h" #include "third_party/blink/renderer/platform/heap/page_pool.h" #include "third_party/blink/renderer/platform/heap/thread_state_scopes.h" +#include "third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.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/web_memory_allocator_dump.h" @@ -101,6 +103,7 @@ movable_reference_worklist_(nullptr), weak_table_worklist_(nullptr), backing_store_callback_worklist_(nullptr), + v8_references_worklist_(nullptr), vector_backing_arena_index_(BlinkGC::kVector1ArenaIndex), current_arena_ages_(0) { if (ThreadState::Current()->IsMainThread()) @@ -161,6 +164,7 @@ movable_reference_worklist_.reset(new MovableReferenceWorklist()); weak_table_worklist_.reset(new WeakTableWorklist); backing_store_callback_worklist_.reset(new BackingStoreCallbackWorklist()); + v8_references_worklist_.reset(new V8ReferencesWorklist()); DCHECK(ephemeron_callbacks_.IsEmpty()); } @@ -169,6 +173,7 @@ previously_not_fully_constructed_worklist_.reset(nullptr); weak_callback_worklist_.reset(nullptr); weak_table_worklist_.reset(); + v8_references_worklist_.reset(); ephemeron_callbacks_.clear(); // The fixed point iteration may have found not-fully-constructed objects. @@ -300,6 +305,8 @@ bool ThreadHeap::AdvanceMarking(MarkingVisitor* visitor, base::TimeTicks deadline) { + FlushV8References(visitor); + bool finished; // Ephemeron fixed point loop. do { @@ -335,6 +342,12 @@ // Rerun loop if ephemeron processing queued more objects for tracing. } while (!marking_worklist_->IsGlobalEmpty()); + + // In case we reached here, we might not enter these method again for a + // while. Flush all V8 references before returning so we don't get left with + /// unflushed references. + FlushV8References(visitor); + return true; } @@ -614,6 +627,32 @@ } } +// TODO(omerkatz): Temporary solution until concurrent marking is ready. see +// https://crrev.com/c/1730054 for details. Eventually this will be removed. +void ThreadHeap::FlushV8References(MarkingVisitor* visitor) { + if (!thread_state_->IsUnifiedGCMarkingInProgress()) + return; + + UnifiedHeapMarkingVisitor* unified_visitor = + reinterpret_cast<UnifiedHeapMarkingVisitor*>(visitor); + + DCHECK(unified_visitor->is_concurrent_marking_enabled() || + v8_references_worklist_->IsGlobalEmpty()); + + // TODO(omerkatz): In concurrent marking, this should flush all visitors + unified_visitor->FlushV8References(); + + V8ReferencesWorklist::View v8_references(v8_references_worklist_.get(), + WorklistTaskId::MainThread); + V8Reference reference; + v8::EmbedderHeapTracer* controller = + reinterpret_cast<v8::EmbedderHeapTracer*>( + thread_state_->unified_heap_controller()); + while (v8_references.Pop(&reference)) { + controller->RegisterEmbedderReference(reference->Get()); + } +} + ThreadHeap* ThreadHeap::main_thread_heap_ = nullptr; } // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/heap.h b/third_party/blink/renderer/platform/heap/heap.h index 36fee957..595456c7 100644 --- a/third_party/blink/renderer/platform/heap/heap.h +++ b/third_party/blink/renderer/platform/heap/heap.h
@@ -75,6 +75,8 @@ void* callback_data; }; +using V8Reference = const TraceWrapperV8Reference<v8::Value>*; + // Segment size of 512 entries necessary to avoid throughput regressions. Since // the work list is currently a temporary object this is not a problem. using MarkingWorklist = Worklist<MarkingItem, 512 /* local entries */>; @@ -89,6 +91,7 @@ using WeakTableWorklist = Worklist<WeakTableItem, 16 /* local entries */>; using BackingStoreCallbackWorklist = Worklist<BackingStoreCallbackItem, 16 /* local entries */>; +using V8ReferencesWorklist = Worklist<V8Reference, 16 /* local entries */>; class PLATFORM_EXPORT HeapAllocHooks { STATIC_ONLY(HeapAllocHooks); @@ -239,6 +242,10 @@ return backing_store_callback_worklist_.get(); } + V8ReferencesWorklist* GetV8ReferencesWorklist() const { + return v8_references_worklist_.get(); + } + // Register an ephemeron table for fixed-point iteration. void RegisterWeakTable(void* container_object, EphemeronCallback); @@ -414,6 +421,8 @@ void InvokeEphemeronCallbacks(MarkingVisitor*); + void FlushV8References(MarkingVisitor*); + ThreadState* thread_state_; std::unique_ptr<ThreadHeapStatsCollector> heap_stats_collector_; std::unique_ptr<RegionTree> region_tree_; @@ -456,6 +465,10 @@ std::unique_ptr<BackingStoreCallbackWorklist> backing_store_callback_worklist_; + // Worklist for storing the V8 references until ThreadHeap can flush them + // to V8. + std::unique_ptr<V8ReferencesWorklist> v8_references_worklist_; + // No duplicates allowed for ephemeron callbacks. Hence, we use a hashmap // with the key being the HashTable. WTF::HashMap<void*, EphemeronCallback> ephemeron_callbacks_;
diff --git a/third_party/blink/renderer/platform/heap/thread_state.cc b/third_party/blink/renderer/platform/heap/thread_state.cc index 570f1a7..3fe7946 100644 --- a/third_party/blink/renderer/platform/heap/thread_state.cc +++ b/third_party/blink/renderer/platform/heap/thread_state.cc
@@ -137,9 +137,6 @@ #if defined(ADDRESS_SANITIZER) asan_fake_stack_(__asan_get_current_fake_stack()), #endif -#if defined(LEAK_SANITIZER) - disabled_static_persistent_registration_(0), -#endif reported_memory_to_v8_(0), sweeper_scheduler_(base::MakeRefCounted<WorkerPoolTaskRunner>()) { DCHECK(CheckThread()); @@ -1164,13 +1161,20 @@ reported_memory_to_v8_ = current_heap_size; } +void ThreadState::EnterStaticReferenceRegistrationDisabledScope() { + static_persistent_registration_disabled_count_++; +} + +void ThreadState::LeaveStaticReferenceRegistrationDisabledScope() { + DCHECK(static_persistent_registration_disabled_count_); + static_persistent_registration_disabled_count_--; +} + void ThreadState::RegisterStaticPersistentNode( PersistentNode* node, PersistentClearCallback callback) { -#if defined(LEAK_SANITIZER) - if (disabled_static_persistent_registration_) + if (static_persistent_registration_disabled_count_) return; -#endif DCHECK(!static_persistents_.Contains(node)); static_persistents_.insert(node, callback); @@ -1198,17 +1202,6 @@ DCHECK(!static_persistents_.Contains(persistent_node)); } -#if defined(LEAK_SANITIZER) -void ThreadState::enterStaticReferenceRegistrationDisabledScope() { - disabled_static_persistent_registration_++; -} - -void ThreadState::leaveStaticReferenceRegistrationDisabledScope() { - DCHECK(disabled_static_persistent_registration_); - disabled_static_persistent_registration_--; -} -#endif - void ThreadState::InvokePreFinalizers() { DCHECK(CheckThread()); DCHECK(!SweepForbidden());
diff --git a/third_party/blink/renderer/platform/heap/thread_state.h b/third_party/blink/renderer/platform/heap/thread_state.h index 13dc93fb..69bb0a65 100644 --- a/third_party/blink/renderer/platform/heap/thread_state.h +++ b/third_party/blink/renderer/platform/heap/thread_state.h
@@ -178,6 +178,7 @@ class AtomicPauseScope; class GCForbiddenScope; + class LsanDisabledScope; class MainThreadGCForbiddenScope; class NoAllocationScope; class SweepForbiddenScope; @@ -377,11 +378,6 @@ void RegisterStaticPersistentNode(PersistentNode*, PersistentClearCallback); void ReleaseStaticPersistentNodes(); -#if defined(LEAK_SANITIZER) - void enterStaticReferenceRegistrationDisabledScope(); - void leaveStaticReferenceRegistrationDisabledScope(); -#endif - v8::Isolate* GetIsolate() const { return isolate_; } // Use CollectAllGarbageForTesting below for testing! @@ -478,6 +474,9 @@ gc_forbidden_count_--; } + void EnterStaticReferenceRegistrationDisabledScope(); + void LeaveStaticReferenceRegistrationDisabledScope(); + // The following methods are used to compose RunAtomicPause. Public users // should use the CollectGarbage entrypoint. Internal users should use these // methods to compose a full garbage collection. @@ -586,6 +585,7 @@ bool should_optimize_for_load_time_ = false; size_t no_allocation_count_ = 0; size_t gc_forbidden_count_ = 0; + size_t static_persistent_registration_disabled_count_ = 0; base::TimeDelta next_incremental_marking_step_duration_; base::TimeDelta previous_incremental_marking_time_left_; @@ -620,11 +620,6 @@ // have to clear before initiating LSan's leak detection. HashMap<PersistentNode*, PersistentClearCallback> static_persistents_; -#if defined(LEAK_SANITIZER) - // Count that controls scoped disabling of persistent registration. - size_t disabled_static_persistent_registration_; -#endif - size_t reported_memory_to_v8_; int gc_age_ = 0;
diff --git a/third_party/blink/renderer/platform/heap/thread_state_scopes.h b/third_party/blink/renderer/platform/heap/thread_state_scopes.h index 961db852..eaf06b8 100644 --- a/third_party/blink/renderer/platform/heap/thread_state_scopes.h +++ b/third_party/blink/renderer/platform/heap/thread_state_scopes.h
@@ -7,6 +7,10 @@ #include "third_party/blink/renderer/platform/heap/thread_state.h" +#if defined(LEAK_SANITIZER) +#include "third_party/blink/renderer/platform/wtf/leak_annotations.h" +#endif + namespace blink { // The NoAllocationScope class is used in debug mode to catch unwanted @@ -87,6 +91,35 @@ GCForbiddenScope gc_forbidden_scope; }; +#if defined(LEAK_SANITIZER) +class ThreadState::LsanDisabledScope final { + STACK_ALLOCATED(); + DISALLOW_COPY_AND_ASSIGN(LsanDisabledScope); + + public: + explicit LsanDisabledScope(ThreadState* thread_state) + : thread_state_(thread_state) { + __lsan_disable(); + if (thread_state_) + thread_state_->EnterStaticReferenceRegistrationDisabledScope(); + } + + ~LsanDisabledScope() { + __lsan_enable(); + if (thread_state_) + thread_state_->LeaveStaticReferenceRegistrationDisabledScope(); + } + + private: + ThreadState* const thread_state_; +}; + +#define LEAK_SANITIZER_DISABLED_SCOPE \ + ThreadState::LsanDisabledScope lsan_disabled_scope(ThreadState::Current()) +#else +#define LEAK_SANITIZER_DISABLED_SCOPE +#endif + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_THREAD_STATE_SCOPES_H_
diff --git a/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.cc b/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.cc index c5d20e6..e75eefe 100644 --- a/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.cc +++ b/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.cc
@@ -21,7 +21,9 @@ isolate_(isolate), controller_(thread_state->unified_heap_controller()), is_concurrent_marking_enabled_(base::FeatureList::IsEnabled( - blink::features::kBlinkHeapConcurrentMarking)) { + blink::features::kBlinkHeapConcurrentMarking)), + v8_references_worklist_(Heap().GetV8ReferencesWorklist(), + WorklistTaskId::MainThread) { DCHECK(controller_); } @@ -30,11 +32,22 @@ if (v8_reference.Get().IsEmpty()) return; DCHECK(isolate_); - // TODO(mlippautz): Do not call into controller directly but rather use a - // Worklist or similar as temporary storage. + if (is_concurrent_marking_enabled_) { + // This is a temporary solution. Pushing directly from concurrent threads + // to V8 marking worklist will currently result in data races. This + // solution guarantees correctness until we implement a long-term solution + // (i.e. allowing Oilpan concurrent threads concurrent-safe access to V8 + // marking worklist without data-races) + v8_references_worklist_.Push(&v8_reference); + return; + } controller_->RegisterEmbedderReference(v8_reference.Get()); } +void UnifiedHeapMarkingVisitorBase::FlushV8References() { + v8_references_worklist_.FlushToGlobal(); +} + UnifiedHeapMarkingVisitor::UnifiedHeapMarkingVisitor(ThreadState* thread_state, MarkingMode mode, v8::Isolate* isolate)
diff --git a/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h b/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h index 62d6547..61b6a2c 100644 --- a/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h +++ b/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h
@@ -31,6 +31,9 @@ return is_concurrent_marking_enabled_; } + // Flush all V8 references in the private segments to the global pool. + void FlushV8References(); + protected: UnifiedHeapMarkingVisitorBase(ThreadState*, MarkingMode, v8::Isolate*); @@ -41,6 +44,7 @@ private: bool is_concurrent_marking_enabled_; + V8ReferencesWorklist::View v8_references_worklist_; }; // Same as the base visitor with the difference that it is bound to main thread.
diff --git a/third_party/blink/renderer/platform/exported/mediastream/webaudio_media_stream_source.cc b/third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.cc similarity index 97% rename from third_party/blink/renderer/platform/exported/mediastream/webaudio_media_stream_source.cc rename to third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.cc index 7e66eb77..8d294a3 100644 --- a/third_party/blink/renderer/platform/exported/mediastream/webaudio_media_stream_source.cc +++ b/third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/public/platform/modules/mediastream/webaudio_media_stream_source.h" +#include "third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.h" #include <utility>
diff --git a/third_party/blink/public/platform/modules/mediastream/webaudio_media_stream_source.h b/third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.h similarity index 88% rename from third_party/blink/public/platform/modules/mediastream/webaudio_media_stream_source.h rename to third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.h index ace9be0..522f342 100644 --- a/third_party/blink/public/platform/modules/mediastream/webaudio_media_stream_source.h +++ b/third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.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 THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIASTREAM_WEBAUDIO_MEDIA_STREAM_SOURCE_H_ -#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIASTREAM_WEBAUDIO_MEDIA_STREAM_SOURCE_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_WEBAUDIO_MEDIA_STREAM_SOURCE_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_WEBAUDIO_MEDIA_STREAM_SOURCE_H_ #include <memory> @@ -12,9 +12,9 @@ #include "media/base/audio_push_fifo.h" #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h" #include "third_party/blink/public/platform/web_audio_destination_consumer.h" -#include "third_party/blink/public/platform/web_common.h" #include "third_party/blink/public/platform/web_media_stream_source.h" #include "third_party/blink/public/platform/web_vector.h" +#include "third_party/blink/renderer/platform/platform_export.h" namespace blink { @@ -22,7 +22,7 @@ // audio data (i.e., the output from a graph of WebAudio nodes) to one or more // MediaStreamAudioTracks. Audio data is transported directly to the tracks in // 10 ms chunks. -class BLINK_PLATFORM_EXPORT WebAudioMediaStreamSource final +class PLATFORM_EXPORT WebAudioMediaStreamSource final : public MediaStreamAudioSource, public WebAudioDestinationConsumer { public: @@ -82,4 +82,4 @@ } // namespace blink -#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIASTREAM_WEBAUDIO_MEDIA_STREAM_SOURCE_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_WEBAUDIO_MEDIA_STREAM_SOURCE_H_
diff --git a/third_party/blink/renderer/platform/mojo/kurl.typemap b/third_party/blink/renderer/platform/mojo/kurl.typemap index 5d155c4..8a25d18 100644 --- a/third_party/blink/renderer/platform/mojo/kurl.typemap +++ b/third_party/blink/renderer/platform/mojo/kurl.typemap
@@ -3,7 +3,10 @@ # found in the LICENSE file. mojom = "//url/mojom/url.mojom" -public_headers = [ "//third_party/blink/renderer/platform/weborigin/kurl.h" ] +public_headers = [ + "//third_party/blink/renderer/platform/weborigin/kurl.h", + "//third_party/blink/renderer/platform/weborigin/kurl_hash.h", +] traits_headers = [ "//third_party/blink/renderer/platform/mojo/kurl_mojom_traits.h" ]
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index f261ce3d..9774f32 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1036,9 +1036,6 @@ // Only Android, ChromeOS support NetInfo downlinkMax, type and ontypechange now status: {"Android": "stable", "ChromeOS": "stable"}, }, - { - name: "NetworkService", - }, // Not a web exposed feature, enabled from the command line. { name: "NewRemotePlaybackPipeline",
diff --git a/third_party/blink/renderer/platform/text/date_components.cc b/third_party/blink/renderer/platform/text/date_components.cc index 512348d..f44343e 100644 --- a/third_party/blink/renderer/platform/text/date_components.cc +++ b/third_party/blink/renderer/platform/text/date_components.cc
@@ -44,8 +44,8 @@ // HTML5 specification defines maximum week of year is 53. const int DateComponents::kMaximumWeekNumber = 53; -static const int kMaximumMonthInMaximumYear = - 8; // This is September, since months are 0 based. +// This is September, since months are 0 based. +static const int kMaximumMonthInMaximumYear = 8; static const int kMaximumDayInMaximumMonth = 13; static const int kMaximumWeekInMaximumYear = 37; // The week of 275760-09-13 @@ -178,163 +178,10 @@ if (month_day > kMaximumDayInMaximumMonth) return false; // (year, month, monthDay) = - // (maximumYear, maximumMonthInMaximumYear, maximumDayInMaximumMonth) + // (MaximumYear, kMaximumMonthInMaximumYear, kMaximumDayInMaximumMonth) return !hour && !minute && !second && !millisecond; } -bool DateComponents::AddDay(int day_diff) { - DCHECK(month_day_); - - int day = month_day_ + day_diff; - if (day > MaxDayOfMonth(year_, month_)) { - day = month_day_; - int year = year_; - int month = month_; - int max_day = MaxDayOfMonth(year, month); - for (; day_diff > 0; --day_diff) { - ++day; - if (day > max_day) { - day = 1; - ++month; - if (month >= 12) { // month is 0-origin. - month = 0; - ++year; - } - max_day = MaxDayOfMonth(year, month); - } - } - if (!WithinHTMLDateLimits(year, month, day)) - return false; - year_ = year; - month_ = month; - } else if (day < 1) { - int month = month_; - int year = year_; - day = month_day_; - for (; day_diff < 0; ++day_diff) { - --day; - if (day < 1) { - --month; - if (month < 0) { - month = 11; - --year; - } - day = MaxDayOfMonth(year, month); - } - } - if (!WithinHTMLDateLimits(year, month, day)) - return false; - year_ = year; - month_ = month; - } else { - if (!WithinHTMLDateLimits(year_, month_, day)) - return false; - } - month_day_ = day; - return true; -} - -bool DateComponents::AddMinute(int minute) { - // This function is used to adjust timezone offset. So m_year, m_month, - // m_monthDay have values between the lower and higher limits. - DCHECK(WithinHTMLDateLimits(year_, month_, month_day_)); - - int carry; - // minute can be negative or greater than 59. - minute += minute_; - if (minute > 59) { - carry = minute / 60; - minute = minute % 60; - } else if (minute < 0) { - carry = (59 - minute) / 60; - minute += carry * 60; - carry = -carry; - DCHECK_GE(minute, 0); - DCHECK_LE(minute, 59); - } else { - if (!WithinHTMLDateLimits(year_, month_, month_day_, hour_, minute, second_, - millisecond_)) - return false; - minute_ = minute; - return true; - } - - int hour = hour_ + carry; - if (hour > 23) { - carry = hour / 24; - hour = hour % 24; - } else if (hour < 0) { - carry = (23 - hour) / 24; - hour += carry * 24; - carry = -carry; - DCHECK_GE(hour, 0); - DCHECK_LE(hour, 23); - } else { - if (!WithinHTMLDateLimits(year_, month_, month_day_, hour, minute, second_, - millisecond_)) - return false; - minute_ = minute; - hour_ = hour; - return true; - } - if (!AddDay(carry)) - return false; - if (!WithinHTMLDateLimits(year_, month_, month_day_, hour, minute, second_, - millisecond_)) - return false; - minute_ = minute; - hour_ = hour; - return true; -} - -// Parses a timezone part, and adjust year, month, monthDay, hour, minute, -// second, millisecond. -bool DateComponents::ParseTimeZone(const String& src, - unsigned start, - unsigned& end) { - if (start >= src.length()) - return false; - unsigned index = start; - if (src[index] == 'Z') { - end = index + 1; - return true; - } - - bool minus; - if (src[index] == '+') - minus = false; - else if (src[index] == '-') - minus = true; - else - return false; - ++index; - - int hour; - int minute; - if (!ToInt(src, index, 2, hour) || hour < 0 || hour > 23) - return false; - index += 2; - - if (index >= src.length() || src[index] != ':') - return false; - ++index; - - if (!ToInt(src, index, 2, minute) || minute < 0 || minute > 59) - return false; - index += 2; - - if (minus) { - hour = -hour; - minute = -minute; - } - - // Subtract the timezone offset. - if (!AddMinute(-(hour * 60 + minute))) - return false; - end = index; - return true; -} - bool DateComponents::ParseMonth(const String& src, unsigned start, unsigned& end) { @@ -451,7 +298,7 @@ millisecond *= 10; } else if (digits_length == 3) { ok = ToInt(src, index, 3, millisecond); - } else { // digitsLength >= 4 + } else { // digits_length >= 4 return false; } DCHECK(ok); @@ -525,7 +372,7 @@ return true; } -bool DateComponents::SetMillisecondsSinceEpochForDateTime(double ms) { +bool DateComponents::SetMillisecondsSinceEpochForDateTimeLocal(double ms) { type_ = kInvalid; if (!std::isfinite(ms)) return false; @@ -536,15 +383,6 @@ if (!WithinHTMLDateLimits(year_, month_, month_day_, hour_, minute_, second_, millisecond_)) return false; - type_ = kDateTime; - return true; -} - -bool DateComponents::SetMillisecondsSinceEpochForDateTimeLocal(double ms) { - // Internal representation of DateTimeLocal is the same as DateTime except - // m_type. - if (!SetMillisecondsSinceEpochForDateTime(ms)) - return false; type_ = kDateTimeLocal; return true; } @@ -642,7 +480,7 @@ } double DateComponents::MillisecondsSinceEpochForTime() const { - DCHECK(type_ == kTime || type_ == kDateTime || type_ == kDateTimeLocal); + DCHECK(type_ == kTime || type_ == kDateTimeLocal); return ((hour_ * kMinutesPerHour + minute_) * kSecondsPerMinute + second_) * kMsPerSecond + millisecond_; @@ -652,7 +490,6 @@ switch (type_) { case kDate: return DateToDaysFrom1970(year_, month_, month_day_) * kMsPerDay; - case kDateTime: case kDateTimeLocal: return DateToDaysFrom1970(year_, month_, month_day_) * kMsPerDay + MillisecondsSinceEpochForTime(); @@ -677,7 +514,7 @@ } String DateComponents::ToStringForTime(SecondFormat format) const { - DCHECK(type_ == kDateTime || type_ == kDateTimeLocal || type_ == kTime); + DCHECK(type_ == kDateTimeLocal || type_ == kTime); SecondFormat effective_format = format; if (millisecond_) effective_format = kMillisecond; @@ -702,9 +539,6 @@ switch (type_) { case kDate: return String::Format("%04d-%02d-%02d", year_, month_ + 1, month_day_); - case kDateTime: - return String::Format("%04d-%02d-%02dT", year_, month_ + 1, month_day_) + - ToStringForTime(format) + String("Z"); case kDateTimeLocal: return String::Format("%04d-%02d-%02dT", year_, month_ + 1, month_day_) + ToStringForTime(format);
diff --git a/third_party/blink/renderer/platform/text/date_components.h b/third_party/blink/renderer/platform/text/date_components.h index 6923c88..cbd05d3d 100644 --- a/third_party/blink/renderer/platform/text/date_components.h +++ b/third_party/blink/renderer/platform/text/date_components.h
@@ -41,11 +41,11 @@ // A DateComponents instance represents one of the following date and time // combinations: -// * Month type: year-month -// * Date type: year-month-day -// * Week type: year-week -// * Time type: hour-minute-second-millisecond -// * DateTime or DateTimeLocal type: +// * kMonth type: year-month +// * kDate type: year-month-day +// * kWeek type: year-week +// * kTime type: hour-minute-second-millisecond +// * kDateTime or kDateTimeLocal type: // year-month-day hour-minute-second-millisecond class PLATFORM_EXPORT DateComponents { DISALLOW_NEW(); @@ -65,7 +65,6 @@ enum Type { kInvalid, kDate, - kDateTime, kDateTimeLocal, kMonth, kTime, @@ -91,99 +90,90 @@ }; // Returns an ISO 8601 representation for this instance. - // The format argument is valid for DateTime, DateTimeLocal, and Time types. + // The format argument is valid for kDateTime, kDateTimeLocal, and + // kTime types. String ToString(SecondFormat format = kNone) const; - // parse*() and setMillisecondsSince*() functions are initializers for an + // Parse*() and SetMillisecondsSince*() functions are initializers for an // DateComponents instance. If these functions return false, the instance // might be invalid. - // The following six functions parse the input 'src' whose length is - // 'length', and updates some fields of this instance. The parsing starts at - // src[start] and examines characters before src[length]. - // 'src' must be non-null. The 'src' string doesn't need to be - // null-terminated. + // The following five functions parse the input 'src', and updates some + // fields of this instance. The parsing starts at src[start]. // The functions return true if the parsing succeeds, and set 'end' to the // next index after the last consumed. Extra leading characters cause parse // failures, and the trailing extra characters don't cause parse failures. - // Sets year and month. - bool ParseMonth(const String&, unsigned start, unsigned& end); - // Sets year, month and monthDay. - bool ParseDate(const String&, unsigned start, unsigned& end); - // Sets year and week. - bool ParseWeek(const String&, unsigned start, unsigned& end); - // Sets hour, minute, second and millisecond. - bool ParseTime(const String&, unsigned start, unsigned& end); - // Sets year, month, monthDay, hour, minute, second and millisecond. + // Sets FullYear and Month. + bool ParseMonth(const String& src, unsigned start, unsigned& end); + // Sets FullYear, Month and MonthDay. + bool ParseDate(const String& src, unsigned start, unsigned& end); + // Sets FullYear and Week. + bool ParseWeek(const String& src, unsigned start, unsigned& end); + // Sets Hour, Minute, Second and Millisecond. + bool ParseTime(const String& src, unsigned start, unsigned& end); + // Sets FullYear, Month, MonthDay, Hour, Minute, Second and Millisecond. bool ParseDateTimeLocal(const String&, unsigned start, unsigned& end); - // The following setMillisecondsSinceEpochFor*() functions take + // The following SetMillisecondsSinceEpochFor*() functions take // the number of milliseconds since 1970-01-01 00:00:00.000 UTC as // the argument, and update all fields for the corresponding // DateComponents type. The functions return true if it succeeds, and // false if they fail. - // For Date type. Updates m_year, m_month and m_monthDay. + // For kDate type. Updates FullYear, Month and MonthDay. bool SetMillisecondsSinceEpochForDate(double ms); - // For DateTime type. Updates m_year, m_month, m_monthDay, m_hour, m_minute, - // m_second and m_millisecond. - bool SetMillisecondsSinceEpochForDateTime(double ms); - // For DateTimeLocal type. Updates m_year, m_month, m_monthDay, m_hour, - // m_minute, m_second and m_millisecond. + // For kDateTimeLocal type. Updates FullYear, Month, MonthDay, Hour, + // Minute, Second and Millisecond. bool SetMillisecondsSinceEpochForDateTimeLocal(double ms); - // For Month type. Updates m_year and m_month. + // For kMonth type. Updates FullYear and Month. bool SetMillisecondsSinceEpochForMonth(double ms); - // For Week type. Updates m_year and m_week. + // For kWeek type. Updates FullYear and Week. bool SetMillisecondsSinceEpochForWeek(double ms); - // For Time type. Updates m_hour, m_minute, m_second and m_millisecond. + // For kTime type. Updates Hour, Minute, Second and Millisecond. bool SetMillisecondsSinceMidnight(double ms); - // Another initializer for Month type. Updates m_year and m_month. + // Another initializer for kMonth type. Updates FullYear and Month. bool SetMonthsSinceEpoch(double months); - // Another initializer for Week type. Updates m_year and m_week. + // Another initializer for kWeek type. Updates FullYear and Week. bool SetWeek(int year, int week_number); // Returns the number of milliseconds from 1970-01-01 00:00:00 UTC. - // For a DateComponents initialized with parseDateTimeLocal(), - // millisecondsSinceEpoch() returns a value for UTC timezone. + // For a DateComponents initialized with ParseDateTimeLocal(), + // MillisecondsSinceEpoch() returns a value for UTC timezone. double MillisecondsSinceEpoch() const; // Returns the number of months from 1970-01. - // Do not call this for types other than Month. + // Do not call this for types other than kMonth. double MonthsSinceEpoch() const; + static inline double InvalidMilliseconds() { return std::numeric_limits<double>::quiet_NaN(); } - // Minimum and maxmimum limits for setMillisecondsSince*(), - // setMonthsSinceEpoch(), millisecondsSinceEpoch(), and monthsSinceEpoch(). - static inline double MinimumDate() { - return -62135596800000.0; - } // 0001-01-01T00:00Z - static inline double MinimumDateTime() { - return -62135596800000.0; - } // ditto. - static inline double MinimumMonth() { - return (1 - 1970) * 12.0 + 1 - 1; - } // 0001-01 - static inline double MinimumTime() { return 0; } // 00:00:00.000 - static inline double MinimumWeek() { - return -62135596800000.0; - } // 0001-01-01, the first Monday of 0001. - static inline double MaximumDate() { - return 8640000000000000.0; - } // 275760-09-13T00:00Z - static inline double MaximumDateTime() { - return 8640000000000000.0; - } // ditto. - static inline double MaximumMonth() { - return (275760 - 1970) * 12.0 + 9 - 1; - } // 275760-09 - static inline double MaximumTime() { return 86399999; } // 23:59:59.999 - static inline double MaximumWeek() { - return 8639999568000000.0; - } // 275760-09-08, the Monday of the week including 275760-09-13. + // Minimum and maxmimum limits for SetMillisecondsSince*(), + // SetMonthsSinceEpoch(), MillisecondsSinceEpoch(), and MonthsSinceEpoch(). + + // 0001-01-01T00:00Z + static inline double MinimumDate() { return -62135596800000.0; } + // Ditto. + static inline double MinimumDateTime() { return -62135596800000.0; } + // 0001-01 + static inline double MinimumMonth() { return (1 - 1970) * 12.0 + 1 - 1; } + // 00:00:00.000 + static inline double MinimumTime() { return 0; } + // 0001-01-01, the first Monday of 0001. + static inline double MinimumWeek() { return -62135596800000.0; } + // 275760-09-13T00:00Z + static inline double MaximumDate() { return 8640000000000000.0; } + // Ditto. + static inline double MaximumDateTime() { return 8640000000000000.0; } + // 275760-09 + static inline double MaximumMonth() { return (275760 - 1970) * 12.0 + 9 - 1; } + // 23:59:59.999 + static inline double MaximumTime() { return 86399999; } + // 275760-09-08, the Monday of the week including 275760-09-13. + static inline double MaximumWeek() { return 8639999568000000.0; } // HTML5 uses ISO-8601 format with year >= 1. Gregorian calendar started in // 1582. However, we need to support 0001-01-01 in Gregorian calendar rule. @@ -199,15 +189,12 @@ // The result is either of 52 and 53. int MaxWeekNumberInYear() const; bool ParseYear(const String&, unsigned start, unsigned& end); - bool AddDay(int); - bool AddMinute(int); - bool ParseTimeZone(const String&, unsigned start, unsigned& end); - // Helper for millisecondsSinceEpoch(). + // Helper for MillisecondsSinceEpoch(). double MillisecondsSinceEpochForTime() const; - // Helpers for setMillisecondsSinceEpochFor*(). + // Helpers for SetMillisecondsSinceEpochFor*(). bool SetMillisecondsSinceEpochForDateInternal(double ms); void SetMillisecondsSinceMidnightInternal(double ms); - // Helper for toString(). + // Helper for ToString(). String ToStringForTime(SecondFormat) const; // m_weekDay values @@ -227,7 +214,7 @@ int hour_; int month_day_; // 1 - 31 int month_; // 0:January - 11:December - int year_; // 1582 - + int year_; // 1 - 275760 int week_; // 1 - 53 Type type_;
diff --git a/third_party/blink/renderer/platform/text/platform_locale.cc b/third_party/blink/renderer/platform/text/platform_locale.cc index acefb47..0ce0b3a 100644 --- a/third_party/blink/renderer/platform/text/platform_locale.cc +++ b/third_party/blink/renderer/platform/text/platform_locale.cc
@@ -473,7 +473,6 @@ case DateComponents::kWeek: builder.Build(WeekFormatInLDML()); break; - case DateComponents::kDateTime: case DateComponents::kDateTimeLocal: builder.Build(format_type == kFormatTypeShort ? DateTimeFormatWithoutSeconds()
diff --git a/third_party/blink/renderer/platform/weborigin/security_origin.cc b/third_party/blink/renderer/platform/weborigin/security_origin.cc index 006236a5..aac0c777 100644 --- a/third_party/blink/renderer/platform/weborigin/security_origin.cc +++ b/third_party/blink/renderer/platform/weborigin/security_origin.cc
@@ -173,6 +173,7 @@ other->block_local_access_from_local_origin_), is_opaque_origin_potentially_trustworthy_( other->is_opaque_origin_potentially_trustworthy_), + cross_agent_cluster_access_(other->cross_agent_cluster_access_), precursor_origin_(other->precursor_origin_ ? other->precursor_origin_->IsolatedCopy() : nullptr) {} @@ -486,6 +487,10 @@ universal_access_ = true; } +void SecurityOrigin::GrantCrossAgentClusterAccess() { + cross_agent_cluster_access_ = true; +} + void SecurityOrigin::BlockLocalAccessFromLocalOrigin() { DCHECK(IsLocal()); block_local_access_from_local_origin_ = true;
diff --git a/third_party/blink/renderer/platform/weborigin/security_origin.h b/third_party/blink/renderer/platform/weborigin/security_origin.h index 03066f35e..1db1177 100644 --- a/third_party/blink/renderer/platform/weborigin/security_origin.h +++ b/third_party/blink/renderer/platform/weborigin/security_origin.h
@@ -210,6 +210,13 @@ void GrantUniversalAccess(); bool IsGrantedUniversalAccess() const { return universal_access_; } + // Whether this origin has ability to access another SecurityOrigin + // if everything but the agent clusters do not match. + void GrantCrossAgentClusterAccess(); + bool IsGrantedCrossAgentClusterAccess() const { + return cross_agent_cluster_access_; + } + bool CanAccessDatabase() const { return !IsOpaque(); } bool CanAccessLocalStorage() const { return !IsOpaque(); } bool CanAccessSharedWorkers() const { return !IsOpaque(); } @@ -359,6 +366,7 @@ bool can_load_local_resources_ = false; bool block_local_access_from_local_origin_ = false; bool is_opaque_origin_potentially_trustworthy_ = false; + bool cross_agent_cluster_access_ = false; // For opaque origins, tracks the non-opaque origin from which the opaque // origin is derived.
diff --git a/third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.h b/third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.h index 8846639..69ddc164 100644 --- a/third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.h +++ b/third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.h
@@ -20,9 +20,6 @@ namespace blink { -// TODO(crbug.com/704136): Move the classes below out of the Blink exposed -// API when all users of it have been Onion souped. - // PeerConnectionRemoteAudioTrack is a WebRTC specific implementation of an // audio track whose data is sourced from a PeerConnection. class PLATFORM_EXPORT PeerConnectionRemoteAudioTrack final @@ -57,7 +54,7 @@ }; // Represents the audio provided by the receiving end of a PeerConnection. -class BLINK_PLATFORM_EXPORT PeerConnectionRemoteAudioSource final +class PLATFORM_EXPORT PeerConnectionRemoteAudioSource final : public MediaStreamAudioSource, protected webrtc::AudioTrackSinkInterface { public:
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 00c9188..7bb1906 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
@@ -219,6 +219,7 @@ # cc painting types. 'cc::PaintCanvas', 'cc::PaintFlags', + 'cc::PaintShader', 'cc::PaintWorkletInput', 'cc::NodeId', @@ -678,6 +679,7 @@ 'cc::VideoLayer', 'gpu::gles2::GLES2Interface', 'libyuv::.+', + 'media_constraints::.+', "rtc::RefCountedObject", 'viz::.+', "webrtc::AudioProcessorInterface",
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests index 8b1e215..853e56b6 100644 --- a/third_party/blink/web_tests/NeverFixTests +++ b/third_party/blink/web_tests/NeverFixTests
@@ -2198,8 +2198,8 @@ Bug(none) external/wpt/html/browsers/history/the-location-interface/location-prototype-setting-same-origin-domain.sub.html [ WontFix ] Bug(none) external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects-on-new-window.html [ WontFix ] Bug(none) external/wpt/html/browsers/the-windowproxy-exotic-object/windowproxy-prototype-setting-same-origin-domain.sub.html [ WontFix ] -Bug(none) external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-success.sub.html [ WontFix ] -Bug(none) external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-similar-but-cross-origin-success.sub.html [ WontFix ] +Bug(none) external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-success.https.sub.html [ WontFix ] +Bug(none) external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-similar-but-cross-origin-success.https.sub.html [ WontFix ] Bug(none) external/wpt/wasm/serialization/module/window-domain-success.sub.html [ WontFix ] Bug(none) external/wpt/wasm/serialization/module/window-similar-but-cross-origin-success.sub.html [ WontFix ] # -------------------- origin-vs-url in console messages -----------------
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 4fe3a777..a53f925 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -259,6 +259,8 @@ # virtual-scroller failures crbug.com/986574 wpt_internal/virtual-scroller/ [ Failure ] +# Skip tests for rendersubtree for now. +crbug.com/991095 wpt_internal/display-lock/rendersubtree/ [ Skip ] # Sheriff 2018/05/25 crbug.com/846747 http/tests/navigation/navigation-interrupted-by-fragment.html [ Pass Timeout ] @@ -2764,10 +2766,6 @@ ####crbug.com/613672 [ Mac ] virtual/scroll_customization/fast/events/touch/gesture/touch-gesture-scroll-input-field.html [ Skip ] ####crbug.com/613672 [ Mac ] virtual/scroll_customization/fast/events/touch/gesture/touch-gesture-scroll-listbox.html [ Skip ] -crbug.com/802067 [ Mac ] external/wpt/pointerlock/movementX_Y_basic.html [ Failure ] -crbug.com/802067 [ Mac ] external/wpt/pointerevents/pointerlock/pointerevent_movementxy.html [ Failure ] -crbug.com/802067 [ Mac ] external/wpt/pointerevents/pointerlock/pointerevent_movementxy_with_pointerlock.html [ Failure ] - # Since there is no compositor thread when running tests then there is no main thread event queue. Hence the # logic for this test will be skipped when running Layout tests. crbug.com/770028 external/wpt/pointerevents/extension/pointerevent_pointerrawupdate_in_pointerlock-manual.html [ Skip ] @@ -3292,7 +3290,37 @@ crbug.com/785230 external/wpt/css/css-text-decor/text-decoration-thickness-underline-001.html [ Failure ] crbug.com/785230 external/wpt/css/css-text-decor/text-decoration-thickness-vertical-002.html [ Failure ] +# Flaky because of timestamps in error messages. +crbug.com/991295 external/wpt/web-animations/timing-model/timelines/document-timelines.html [ Pass Failure ] + # ====== New tests from wpt-importer added here ====== +crbug.com/626703 [ Win7 ] virtual/omt-worker-fetch/external/wpt/referrer-policy/unsafe-url/attr-referrer/same-origin/http-http/img-tag/keep-origin-redirect/generic.http.html [ Timeout ] +crbug.com/626703 external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-015.html [ Failure ] +crbug.com/626703 external/wpt/css/css-text/line-break/line-break-anywhere-002.html [ Failure ] +crbug.com/626703 external/wpt/css/css-text/white-space/trailing-other-space-separators-002.html [ Failure ] +crbug.com/626703 [ Win7 ] external/wpt/IndexedDB/structured-clone.any.html [ Timeout ] +crbug.com/626703 external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-004.html [ Failure ] +crbug.com/626703 external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-011.html [ Failure ] +crbug.com/626703 external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-007.html [ Failure ] +crbug.com/626703 [ Win7 ] virtual/not-omt-sw-fetch/external/wpt/referrer-policy/unsafe-url/attr-referrer/same-origin/http-http/img-tag/no-redirect/generic.http.html [ Timeout ] +crbug.com/626703 [ Win7 ] virtual/omt-worker-fetch/external/wpt/referrer-policy/unset-referrer-policy/attr-referrer/cross-origin/http-http/img-tag/no-redirect/insecure-protocol.http.html [ Timeout ] +crbug.com/626703 [ Win7 ] virtual/not-omt-sw-fetch/external/wpt/referrer-policy/unsafe-url/http-rp/same-origin/http-http/img-tag/swap-origin-redirect/generic.http.html [ Timeout ] +crbug.com/626703 [ Win7 ] virtual/omt-worker-fetch/external/wpt/referrer-policy/unset-referrer-policy/attr-referrer/cross-origin/http-http/img-tag/keep-origin-redirect/insecure-protocol.http.html [ Timeout ] +crbug.com/626703 external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-012.html [ Failure ] +crbug.com/626703 external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-010.html [ Failure ] +crbug.com/626703 [ Win7 ] virtual/not-omt-sw-fetch/external/wpt/referrer-policy/strict-origin-when-cross-origin/attr-referrer/same-origin/http-http/img-tag/no-redirect/same-insecure.http.html [ Timeout ] +crbug.com/626703 [ Win7 ] virtual/blink-cors/external/wpt/referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/img-tag/keep-origin-redirect/generic.http.html [ Timeout ] +crbug.com/626703 external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-006.html [ Failure ] +crbug.com/626703 external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-014.html [ Failure ] +crbug.com/626703 external/wpt/css/css-text/white-space/trailing-other-space-separators-001.html [ Failure ] +crbug.com/626703 external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-002.html [ Failure ] +crbug.com/626703 external/wpt/css/css-text/white-space/trailing-other-space-separators-004.html [ Failure ] +crbug.com/626703 external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-008.html [ Failure ] +crbug.com/626703 external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-001.html [ Failure ] +crbug.com/626703 external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-003.html [ Failure ] +crbug.com/626703 external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-005.html [ Failure ] +crbug.com/626703 [ Win7 ] virtual/blink-cors/external/wpt/referrer-policy/unsafe-url/attr-referrer/same-origin/http-http/img-tag/swap-origin-redirect/generic.http.html [ Timeout ] +crbug.com/626703 external/wpt/css/css-text/white-space/trailing-other-space-separators-003.html [ Failure ] crbug.com/626703 virtual/layout_ng_experimental/external/wpt/css/css-multicol/multicol-rule-nested-balancing-002.html [ Failure ] crbug.com/626703 external/wpt/css/css-multicol/multicol-breaking-000.html [ Failure ] crbug.com/626703 external/wpt/css/css-multicol/multicol-breaking-001.html [ Failure ] @@ -4636,8 +4664,6 @@ crbug.com/626703 [ Win ] external/wpt/css/css-writing-modes/box-offsets-rel-pos-vrl-004.xht [ Failure ] # Failure due to on-going off-thread paint worklet project. -crbug.com/957457 virtual/threaded/external/wpt/css/css-paint-api/background-image-tiled.https.html [ Crash ] -crbug.com/957457 virtual/threaded/external/wpt/css/css-paint-api/geometry-background-image-tiled-001.https.html [ Crash ] crbug.com/957457 virtual/threaded/external/wpt/css/css-paint-api/invalid-image-pending-script.https.html [ Crash ] crbug.com/982116 http/tests/devtools/elements/styles-4/styles-new-API.js [ Pass Timeout ] @@ -4949,7 +4975,7 @@ crbug.com/705490 external/wpt/fetch/api/basic/error-after-response.html [ Timeout Pass ] crbug.com/820334 external/wpt/fetch/api/request/request-cache-default-conditional.html [ Timeout Pass ] -crbug.com/716320 external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success-and-failure.html [ Failure Timeout ] +crbug.com/716320 external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success-and-failure.https.html [ Failure Timeout ] crbug.com/874302 external/wpt/wasm/serialization/module/broadcastchannel-success-and-failure.html [ Timeout ] crbug.com/874302 external/wpt/wasm/serialization/module/broadcastchannel-success.html [ Timeout ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 9e6a9188..582cdaf 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -1139,6 +1139,11 @@ "args": ["--enable-blink-features=ForcedColors"] }, { + "prefix": "forced-colors", + "base": "fast/css/forced-colors-mode", + "args": ["--force-high-contrast", "--enable-blink-features=ForcedColors"] + }, + { "prefix": "force-defer-script", "base": "defer-script", "args": ["--enable-blink-features=ForceDeferScriptIntervention"]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json index c6d305a9..0ffc1e3 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
@@ -40045,6 +40045,42 @@ {} ] ], + "css/css-contain/contain-size-replaced-004.html": [ + [ + "css/css-contain/contain-size-replaced-004.html", + [ + [ + "/css/css-contain/contain-size-replaced-004-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-contain/contain-size-replaced-005.html": [ + [ + "css/css-contain/contain-size-replaced-005.html", + [ + [ + "/css/css-contain/contain-size-replaced-005-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-contain/contain-size-replaced-006.html": [ + [ + "css/css-contain/contain-size-replaced-006.html", + [ + [ + "/css/css-contain/contain-size-replaced-006-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-contain/contain-size-scrollbars-001.html": [ [ "css/css-contain/contain-size-scrollbars-001.html", @@ -46189,6 +46225,18 @@ {} ] ], + "css/css-flexbox/percentage-heights-006.html": [ + [ + "css/css-flexbox/percentage-heights-006.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], "css/css-flexbox/percentage-size-subitems-001.html": [ [ "css/css-flexbox/percentage-size-subitems-001.html", @@ -58667,6 +58715,18 @@ {} ] ], + "css/css-paint-api/background-repeat-x.https.html": [ + [ + "css/css-paint-api/background-repeat-x.https.html", + [ + [ + "/css/css-paint-api/background-repeat-x-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-paint-api/geometry-background-image-001.https.html": [ [ "css/css-paint-api/geometry-background-image-001.https.html", @@ -72927,6 +72987,234 @@ {} ] ], + "css/css-text/white-space/trailing-other-space-separators-001.html": [ + [ + "css/css-text/white-space/trailing-other-space-separators-001.html", + [ + [ + "/css/css-text/white-space/reference/trailing-other-space-separators-001-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/trailing-other-space-separators-002.html": [ + [ + "css/css-text/white-space/trailing-other-space-separators-002.html", + [ + [ + "/css/css-text/white-space/reference/trailing-other-space-separators-002-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/trailing-other-space-separators-003.html": [ + [ + "css/css-text/white-space/trailing-other-space-separators-003.html", + [ + [ + "/css/css-text/white-space/reference/trailing-other-space-separators-001-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/trailing-other-space-separators-004.html": [ + [ + "css/css-text/white-space/trailing-other-space-separators-004.html", + [ + [ + "/css/css-text/white-space/reference/trailing-other-space-separators-001-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-001.html": [ + [ + "css/css-text/white-space/trailing-other-space-separators-break-spaces-001.html", + [ + [ + "/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-001-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-002.html": [ + [ + "css/css-text/white-space/trailing-other-space-separators-break-spaces-002.html", + [ + [ + "/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-002-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-003.html": [ + [ + "css/css-text/white-space/trailing-other-space-separators-break-spaces-003.html", + [ + [ + "/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-003-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-004.html": [ + [ + "css/css-text/white-space/trailing-other-space-separators-break-spaces-004.html", + [ + [ + "/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-004-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-005.html": [ + [ + "css/css-text/white-space/trailing-other-space-separators-break-spaces-005.html", + [ + [ + "/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-005-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-006.html": [ + [ + "css/css-text/white-space/trailing-other-space-separators-break-spaces-006.html", + [ + [ + "/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-006-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-007.html": [ + [ + "css/css-text/white-space/trailing-other-space-separators-break-spaces-007.html", + [ + [ + "/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-007-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-008.html": [ + [ + "css/css-text/white-space/trailing-other-space-separators-break-spaces-008.html", + [ + [ + "/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-008-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-009.html": [ + [ + "css/css-text/white-space/trailing-other-space-separators-break-spaces-009.html", + [ + [ + "/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-009-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-010.html": [ + [ + "css/css-text/white-space/trailing-other-space-separators-break-spaces-010.html", + [ + [ + "/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-010-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-011.html": [ + [ + "css/css-text/white-space/trailing-other-space-separators-break-spaces-011.html", + [ + [ + "/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-011-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-012.html": [ + [ + "css/css-text/white-space/trailing-other-space-separators-break-spaces-012.html", + [ + [ + "/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-012-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-013.html": [ + [ + "css/css-text/white-space/trailing-other-space-separators-break-spaces-013.html", + [ + [ + "/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-013-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-014.html": [ + [ + "css/css-text/white-space/trailing-other-space-separators-break-spaces-014.html", + [ + [ + "/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-014-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-015.html": [ + [ + "css/css-text/white-space/trailing-other-space-separators-break-spaces-015.html", + [ + [ + "/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-015-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-text/white-space/trailing-space-align-start.tentative.html": [ [ "css/css-text/white-space/trailing-space-align-start.tentative.html", @@ -101533,6 +101821,18 @@ {} ] ], + "css/motion/animation/reftests/offset-path-with-transforms-001.html": [ + [ + "css/motion/animation/reftests/offset-path-with-transforms-001.html", + [ + [ + "/css/motion/animation/reftests/offset-path-with-transforms-ref.html", + "==" + ] + ], + {} + ] + ], "css/motion/animation/reftests/offset-rotate-interpolation-001.html": [ [ "css/motion/animation/reftests/offset-rotate-interpolation-001.html", @@ -131830,9 +132130,6 @@ "css/css-color/lab-007-ref.html": [ [] ], - "css/css-color/parsing/opacity-valid-expected.txt": [ - [] - ], "css/css-color/rebeccapurple-ref.html": [ [] ], @@ -132016,6 +132313,15 @@ "css/css-contain/contain-size-replaced-003-ref.html": [ [] ], + "css/css-contain/contain-size-replaced-004-ref.html": [ + [] + ], + "css/css-contain/contain-size-replaced-005-ref.html": [ + [] + ], + "css/css-contain/contain-size-replaced-006-ref.html": [ + [] + ], "css/css-contain/contain-style-counters-ref.html": [ [] ], @@ -140278,6 +140584,9 @@ "css/css-paint-api/background-image-tiled-ref.html": [ [] ], + "css/css-paint-api/background-repeat-x-ref.html": [ + [] + ], "css/css-paint-api/geometry-background-image-001-ref.html": [ [] ], @@ -140830,12 +141139,6 @@ "css/css-shapes/OWNERS": [ [] ], - "css/css-shapes/parsing/shape-image-threshold-computed-expected.txt": [ - [] - ], - "css/css-shapes/parsing/shape-image-threshold-valid-expected.txt": [ - [] - ], "css/css-shapes/parsing/shape-outside-computed-expected.txt": [ [] ], @@ -143452,6 +143755,57 @@ "css/css-text/white-space/reference/trailing-ideographic-space-alt-003-ref.html": [ [] ], + "css/css-text/white-space/reference/trailing-other-space-separators-001-ref.html": [ + [] + ], + "css/css-text/white-space/reference/trailing-other-space-separators-002-ref.html": [ + [] + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-001-ref.html": [ + [] + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-002-ref.html": [ + [] + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-003-ref.html": [ + [] + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-004-ref.html": [ + [] + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-005-ref.html": [ + [] + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-006-ref.html": [ + [] + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-007-ref.html": [ + [] + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-008-ref.html": [ + [] + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-009-ref.html": [ + [] + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-010-ref.html": [ + [] + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-011-ref.html": [ + [] + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-012-ref.html": [ + [] + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-013-ref.html": [ + [] + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-014-ref.html": [ + [] + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-015-ref.html": [ + [] + ], "css/css-text/white-space/reference/trailing-space-align-start-ref.html": [ [] ], @@ -144538,12 +144892,6 @@ "css/css-transitions/CSSTransition-canceling.tentative-expected.txt": [ [] ], - "css/css-transitions/CSSTransition-effect.tentative-expected.txt": [ - [] - ], - "css/css-transitions/CSSTransition-transitionProperty.tentative-expected.txt": [ - [] - ], "css/css-transitions/Document-getAnimations.tentative-expected.txt": [ [] ], @@ -147877,9 +148225,15 @@ "css/cssom-view/scrollIntoView-horizontal-tb-writing-mode-and-rtl-direction-expected.txt": [ [] ], + "css/cssom-view/scrollIntoView-sideways-lr-writing-mode-and-rtl-direction-expected.txt": [ + [] + ], "css/cssom-view/scrollIntoView-sideways-lr-writing-mode-expected.txt": [ [] ], + "css/cssom-view/scrollIntoView-sideways-rl-writing-mode-and-rtl-direction-expected.txt": [ + [] + ], "css/cssom-view/scrollIntoView-sideways-rl-writing-mode-expected.txt": [ [] ], @@ -148492,12 +148846,6 @@ "css/filter-effects/interfaces.any-expected.txt": [ [] ], - "css/filter-effects/parsing/flood-opacity-computed-expected.txt": [ - [] - ], - "css/filter-effects/parsing/flood-opacity-valid-expected.txt": [ - [] - ], "css/filter-effects/reference/filters-opacity-001-ref.html": [ [] ], @@ -148663,9 +149011,6 @@ "css/geometry/DOMMatrix2DInit-validate-fixup-expected.txt": [ [] ], - "css/geometry/DOMQuad-001-expected.txt": [ - [] - ], "css/geometry/META.yml": [ [] ], @@ -148717,6 +149062,9 @@ "css/motion/animation/reftests/offset-path-path-interpolation-ref.html": [ [] ], + "css/motion/animation/reftests/offset-path-with-transforms-ref.html": [ + [] + ], "css/motion/offset-anchor-transform-box-fill-box-ref.html": [ [] ], @@ -148732,6 +149080,9 @@ "css/motion/offset-rotate-ref.html": [ [] ], + "css/motion/offset-supports-calc-expected.txt": [ + [] + ], "css/motion/parsing/offset-path-parsing-valid-expected.txt": [ [] ], @@ -153799,25 +154150,25 @@ "fonts/math/fraction-denominatordisplaystylegapmin5000-rulethickness1000.woff": [ [] ], - "fonts/math/fraction-denominatordisplaystyleshiftdown6000-rulethickness1000.woff": [ + "fonts/math/fraction-denominatordisplaystyleshiftdown6000-axisheight1000-rulethickness1000.woff": [ [] ], "fonts/math/fraction-denominatorgapmin4000-rulethickness1000.woff": [ [] ], - "fonts/math/fraction-denominatorshiftdown3000-rulethickness1000.woff": [ + "fonts/math/fraction-denominatorshiftdown3000-axisheight1000-rulethickness1000.woff": [ [] ], "fonts/math/fraction-numeratordisplaystylegapmin8000-rulethickness1000.woff": [ [] ], - "fonts/math/fraction-numeratordisplaystyleshiftup2000-rulethickness1000.woff": [ + "fonts/math/fraction-numeratordisplaystyleshiftup2000-axisheight1000-rulethickness1000.woff": [ [] ], "fonts/math/fraction-numeratorgapmin9000-rulethickness1000.woff": [ [] ], - "fonts/math/fraction-numeratorshiftup11000-rulethickness1000.woff": [ + "fonts/math/fraction-numeratorshiftup11000-axisheight1000-rulethickness1000.woff": [ [] ], "fonts/math/fraction-rulethickness10000.woff": [ @@ -153961,10 +154312,10 @@ "fonts/math/stack-axisheight7000.woff": [ [] ], - "fonts/math/stack-bottomdisplaystyleshiftdown5000.woff": [ + "fonts/math/stack-bottomdisplaystyleshiftdown5000-axisheight1000.woff": [ [] ], - "fonts/math/stack-bottomshiftdown6000.woff": [ + "fonts/math/stack-bottomshiftdown6000-axisheight1000.woff": [ [] ], "fonts/math/stack-displaystylegapmin4000.woff": [ @@ -153973,10 +154324,10 @@ "fonts/math/stack-gapmin8000.woff": [ [] ], - "fonts/math/stack-topdisplaystyleshiftup3000.woff": [ + "fonts/math/stack-topdisplaystyleshiftup3000-axisheight1000.woff": [ [] ], - "fonts/math/stack-topshiftup9000.woff": [ + "fonts/math/stack-topshiftup9000-axisheight1000.woff": [ [] ], "fonts/math/stretchstack-bottomshiftdown3000.woff": [ @@ -158113,18 +158464,48 @@ "html/infrastructure/safe-passing-of-structured-data/resources/echo-iframe.html": [ [] ], + "html/infrastructure/safe-passing-of-structured-data/resources/echo-iframe.html.headers": [ + [] + ], "html/infrastructure/safe-passing-of-structured-data/resources/echo-worker.js": [ [] ], + "html/infrastructure/safe-passing-of-structured-data/resources/echo-worker.js.headers": [ + [] + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success-and-failure.https.html.headers": [ + [] + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success.https.html.headers": [ [] ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/identity-not-preserved.https.html.headers": [ + [] + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https-expected.txt": [ + [] + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https.html.headers": [ + [] + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success-sharedworker-expected.txt": [ [] ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.any.sharedworker-expected.txt": [ [] ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.https.html.headers": [ + [] + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any-expected.txt": [ + [] + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.worker-expected.txt": [ + [] + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-transferring.https.html.headers": [ + [] + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/blank.html": [ [] ], @@ -158137,54 +158518,126 @@ "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-sharedworker.js": [ [] ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-sharedworker.js.headers": [ + [] + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-worker.js": [ [] ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-worker.js.headers": [ + [] + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe-domain.sub.html": [ [] ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe-domain.sub.html.headers": [ + [] + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe-messagechannel.html": [ [] ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe-messagechannel.html.headers": [ + [] + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe.html": [ [] ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe.html.headers": [ + [] + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-popup.html": [ [] ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-popup.html.headers": [ + [] + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker-with-channel.js": [ [] ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker-with-channel.js.headers": [ + [] + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker.js": [ [] ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker.js.headers": [ + [] + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-1.html": [ [] ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-1.html.headers": [ + [] + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-2.html": [ [] ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-2.html.headers": [ + [] + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-3.html": [ [] ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-3.html.headers": [ + [] + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-4-incrementer.html": [ [] ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-4-incrementer.html.headers": [ + [] + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js": [ + [] + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js.headers": [ + [] + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/serviceworker-failure.js": [ [] ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/serviceworker-failure.js.headers": [ + [] + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/sharedworker-failure.js": [ [] ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/sharedworker-failure.js.headers": [ + [] + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/test-incrementer.js": [ [] ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/test-sab.js": [ [] ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-history.https.html.headers": [ + [] + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-success.https.sub.html.headers": [ + [] + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel-success.https.html.headers": [ + [] + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-messagechannel-success.https.html.headers": [ + [] + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-serviceworker-failure.https-expected.txt": [ [] ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-serviceworker-failure.https.html.headers": [ + [] + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-sharedworker-failure.https.html.headers": [ + [] + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-similar-but-cross-origin-success.https.sub.html.headers": [ + [] + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-simple-success.https.html.headers": [ + [] + ], "html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window-expected.txt": [ [] ], @@ -166510,6 +166963,9 @@ "resources/OWNERS": [ [] ], + "resources/SVGAnimationTestCase-testharness.js": [ + [] + ], "resources/check-layout-th.js": [ [] ], @@ -169528,12 +169984,6 @@ "svg/painting/marker-008-ref.svg": [ [] ], - "svg/painting/parsing/fill-opacity-computed-expected.txt": [ - [] - ], - "svg/painting/parsing/fill-opacity-valid-expected.txt": [ - [] - ], "svg/painting/parsing/fill-valid-expected.txt": [ [] ], @@ -169549,12 +169999,6 @@ "svg/painting/parsing/stroke-linejoin-valid-expected.txt": [ [] ], - "svg/painting/parsing/stroke-opacity-computed-expected.txt": [ - [] - ], - "svg/painting/parsing/stroke-opacity-valid-expected.txt": [ - [] - ], "svg/painting/parsing/stroke-valid-expected.txt": [ [] ], @@ -169606,12 +170050,6 @@ "svg/path/property/resources/interpolation-test-common.js": [ [] ], - "svg/pservers/parsing/stop-opacity-computed-expected.txt": [ - [] - ], - "svg/pservers/parsing/stop-opacity-valid-expected.txt": [ - [] - ], "svg/pservers/reftests/meshgradient-basic-001-ref.png": [ [] ], @@ -169981,9 +170419,18 @@ "tools/docker/Dockerfile": [ [] ], + "tools/docker/__init__.py": [ + [] + ], + "tools/docker/commands.json": [ + [] + ], "tools/docker/documentation/Dockerfile": [ [] ], + "tools/docker/frontend.py": [ + [] + ], "tools/docker/github/Dockerfile": [ [] ], @@ -174331,6 +174778,9 @@ "web-animations/resources/keyframe-utils.js": [ [] ], + "web-animations/resources/timing-override.js": [ + [] + ], "web-animations/resources/timing-tests.js": [ [] ], @@ -199269,6 +199719,12 @@ {} ] ], + "css/CSS2/floats-clear/adjoining-float-new-fc-crash.html": [ + [ + "css/CSS2/floats-clear/adjoining-float-new-fc-crash.html", + {} + ] + ], "css/CSS2/floats/computed-float-position-absolute.html": [ [ "css/CSS2/floats/computed-float-position-absolute.html", @@ -204861,18 +205317,6 @@ {} ] ], - "css/css-lists/list-and-margin-collapse-003.html": [ - [ - "css/css-lists/list-and-margin-collapse-003.html", - {} - ] - ], - "css/css-lists/list-and-margin-collapse-004.html": [ - [ - "css/css-lists/list-and-margin-collapse-004.html", - {} - ] - ], "css/css-lists/list-and-writing-mode-001.html": [ [ "css/css-lists/list-and-writing-mode-001.html", @@ -214091,6 +214535,12 @@ {} ] ], + "css/css-writing-modes/bidi-line-break-001.html": [ + [ + "css/css-writing-modes/bidi-line-break-001.html", + {} + ] + ], "css/css-writing-modes/inheritance.html": [ [ "css/css-writing-modes/inheritance.html", @@ -237929,9 +238379,9 @@ {} ] ], - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success-and-failure.html": [ + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success-and-failure.https.html": [ [ - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success-and-failure.html", + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success-and-failure.https.html", {} ] ], @@ -237941,53 +238391,43 @@ {} ] ], - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/identity-not-preserved.html": [ + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/identity-not-preserved.https.html": [ [ - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/identity-not-preserved.html", + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/identity-not-preserved.https.html", {} ] ], - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.any.js": [ + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https.html": [ [ - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.any.sharedworker.html", - { - "script_metadata": [ - [ - "global", - "!default,dedicatedworker,sharedworker" - ], - [ - "script", - "resources/test-incrementer.js" - ] - ] - } + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https.html", + {} + ] + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.https.html": [ + [ + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.https.html", + {} + ] + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.js": [ + [ + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.html", + {} ], [ - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.any.worker.html", - { - "script_metadata": [ - [ - "global", - "!default,dedicatedworker,sharedworker" - ], - [ - "script", - "resources/test-incrementer.js" - ] - ] - } - ] - ], - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-transferring.html": [ - [ - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-transferring.html", + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.worker.html", {} ] ], - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-history.html": [ + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-transferring.https.html": [ [ - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-history.html", + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-transferring.https.html", + {} + ] + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-history.https.html": [ + [ + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-history.https.html", {} ] ], @@ -238025,21 +238465,21 @@ {} ] ], - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-success.sub.html": [ + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-success.https.sub.html": [ [ - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-success.sub.html", + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-success.https.sub.html", {} ] ], - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel-success.html": [ + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel-success.https.html": [ [ - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel-success.html", + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel-success.https.html", {} ] ], - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-messagechannel-success.html": [ + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-messagechannel-success.https.html": [ [ - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-messagechannel-success.html", + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-messagechannel-success.https.html", {} ] ], @@ -238049,21 +238489,21 @@ {} ] ], - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-sharedworker-failure.html": [ + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-sharedworker-failure.https.html": [ [ - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-sharedworker-failure.html", + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-sharedworker-failure.https.html", {} ] ], - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-similar-but-cross-origin-success.sub.html": [ + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-similar-but-cross-origin-success.https.sub.html": [ [ - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-similar-but-cross-origin-success.sub.html", + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-similar-but-cross-origin-success.https.sub.html", {} ] ], - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-simple-success.html": [ + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-simple-success.https.html": [ [ - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-simple-success.html", + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-simple-success.https.html", {} ] ], @@ -250886,6 +251326,12 @@ {} ] ], + "mathml/relations/css-styling/not-participating-to-parent-layout.html": [ + [ + "mathml/relations/css-styling/not-participating-to-parent-layout.html", + {} + ] + ], "mathml/relations/css-styling/padding-border-margin/border-001.html": [ [ "mathml/relations/css-styling/padding-border-margin/border-001.html", @@ -250958,6 +251404,18 @@ {} ] ], + "mathml/relations/html5-tree/clipboard-event-handlers.tentative.html": [ + [ + "mathml/relations/html5-tree/clipboard-event-handlers.tentative.html", + {} + ] + ], + "mathml/relations/html5-tree/css-inline-style-interface.tentative.html": [ + [ + "mathml/relations/html5-tree/css-inline-style-interface.tentative.html", + {} + ] + ], "mathml/relations/html5-tree/display-1.html": [ [ "mathml/relations/html5-tree/display-1.html", @@ -250972,12 +251430,24 @@ } ] ], + "mathml/relations/html5-tree/html-or-foreign-element-interfaces.tentative.html": [ + [ + "mathml/relations/html5-tree/html-or-foreign-element-interfaces.tentative.html", + {} + ] + ], "mathml/relations/html5-tree/integration-point-4.html": [ [ "mathml/relations/html5-tree/integration-point-4.html", {} ] ], + "mathml/relations/html5-tree/math-global-event-handlers.tentative.html": [ + [ + "mathml/relations/html5-tree/math-global-event-handlers.tentative.html", + {} + ] + ], "mathml/relations/html5-tree/unique-identifier-2.html": [ [ "mathml/relations/html5-tree/unique-identifier-2.html", @@ -286990,6 +287460,368 @@ {} ] ], + "svg/animations/svgenum-animation-3.html": [ + [ + "svg/animations/svgenum-animation-3.html", + {} + ] + ], + "svg/animations/svgenum-animation-4.html": [ + [ + "svg/animations/svgenum-animation-4.html", + {} + ] + ], + "svg/animations/svgenum-animation-5.html": [ + [ + "svg/animations/svgenum-animation-5.html", + {} + ] + ], + "svg/animations/svgenum-animation-6.html": [ + [ + "svg/animations/svgenum-animation-6.html", + {} + ] + ], + "svg/animations/svgenum-animation-7.html": [ + [ + "svg/animations/svgenum-animation-7.html", + {} + ] + ], + "svg/animations/svgenum-animation-8.html": [ + [ + "svg/animations/svgenum-animation-8.html", + {} + ] + ], + "svg/animations/svgenum-animation-9.html": [ + [ + "svg/animations/svgenum-animation-9.html", + {} + ] + ], + "svg/animations/svginteger-animation-1.html": [ + [ + "svg/animations/svginteger-animation-1.html", + {} + ] + ], + "svg/animations/svginteger-animation-2.html": [ + [ + "svg/animations/svginteger-animation-2.html", + {} + ] + ], + "svg/animations/svglength-additive-by-1.html": [ + [ + "svg/animations/svglength-additive-by-1.html", + {} + ] + ], + "svg/animations/svglength-additive-by-2.html": [ + [ + "svg/animations/svglength-additive-by-2.html", + {} + ] + ], + "svg/animations/svglength-additive-by-3.html": [ + [ + "svg/animations/svglength-additive-by-3.html", + {} + ] + ], + "svg/animations/svglength-additive-by-4.html": [ + [ + "svg/animations/svglength-additive-by-4.html", + {} + ] + ], + "svg/animations/svglength-additive-by-6.html": [ + [ + "svg/animations/svglength-additive-by-6.html", + {} + ] + ], + "svg/animations/svglength-additive-by-7.html": [ + [ + "svg/animations/svglength-additive-by-7.html", + {} + ] + ], + "svg/animations/svglength-additive-by-8.html": [ + [ + "svg/animations/svglength-additive-by-8.html", + {} + ] + ], + "svg/animations/svglength-additive-from-by-1.html": [ + [ + "svg/animations/svglength-additive-from-by-1.html", + {} + ] + ], + "svg/animations/svglength-additive-from-by-2.html": [ + [ + "svg/animations/svglength-additive-from-by-2.html", + {} + ] + ], + "svg/animations/svglength-additive-from-by-3.html": [ + [ + "svg/animations/svglength-additive-from-by-3.html", + {} + ] + ], + "svg/animations/svglength-additive-from-by-4.html": [ + [ + "svg/animations/svglength-additive-from-by-4.html", + {} + ] + ], + "svg/animations/svglength-animation-LengthModeHeight.html": [ + [ + "svg/animations/svglength-animation-LengthModeHeight.html", + {} + ] + ], + "svg/animations/svglength-animation-LengthModeOther.html": [ + [ + "svg/animations/svglength-animation-LengthModeOther.html", + {} + ] + ], + "svg/animations/svglength-animation-LengthModeWidth.html": [ + [ + "svg/animations/svglength-animation-LengthModeWidth.html", + {} + ] + ], + "svg/animations/svglength-animation-invalid-value-1.html": [ + [ + "svg/animations/svglength-animation-invalid-value-1.html", + {} + ] + ], + "svg/animations/svglength-animation-invalid-value-2.html": [ + [ + "svg/animations/svglength-animation-invalid-value-2.html", + {} + ] + ], + "svg/animations/svglength-animation-invalid-value-3.html": [ + [ + "svg/animations/svglength-animation-invalid-value-3.html", + {} + ] + ], + "svg/animations/svglength-animation-number-to-number.html": [ + [ + "svg/animations/svglength-animation-number-to-number.html", + {} + ] + ], + "svg/animations/svglength-animation-px-to-cm.html": [ + [ + "svg/animations/svglength-animation-px-to-cm.html", + {} + ] + ], + "svg/animations/svglength-animation-px-to-ems.html": [ + [ + "svg/animations/svglength-animation-px-to-ems.html", + {} + ] + ], + "svg/animations/svglength-animation-px-to-in.html": [ + [ + "svg/animations/svglength-animation-px-to-in.html", + {} + ] + ], + "svg/animations/svglength-animation-px-to-number.html": [ + [ + "svg/animations/svglength-animation-px-to-number.html", + {} + ] + ], + "svg/animations/svglength-animation-px-to-pc.html": [ + [ + "svg/animations/svglength-animation-px-to-pc.html", + {} + ] + ], + "svg/animations/svglength-animation-px-to-pt.html": [ + [ + "svg/animations/svglength-animation-px-to-pt.html", + {} + ] + ], + "svg/animations/svglength-animation-px-to-px.html": [ + [ + "svg/animations/svglength-animation-px-to-px.html", + {} + ] + ], + "svg/animations/svglength-animation-unitType.html": [ + [ + "svg/animations/svglength-animation-unitType.html", + {} + ] + ], + "svg/animations/svglength-animation-values.html": [ + [ + "svg/animations/svglength-animation-values.html", + {} + ] + ], + "svg/animations/svglengthlist-animation-1.html": [ + [ + "svg/animations/svglengthlist-animation-1.html", + {} + ] + ], + "svg/animations/svglengthlist-animation-2.html": [ + [ + "svg/animations/svglengthlist-animation-2.html", + {} + ] + ], + "svg/animations/svglengthlist-animation-3.html": [ + [ + "svg/animations/svglengthlist-animation-3.html", + { + "timeout": "long" + } + ] + ], + "svg/animations/svglengthlist-animation-4.html": [ + [ + "svg/animations/svglengthlist-animation-4.html", + {} + ] + ], + "svg/animations/svglengthlist-animation-5.html": [ + [ + "svg/animations/svglengthlist-animation-5.html", + {} + ] + ], + "svg/animations/svgnumber-animation-1.html": [ + [ + "svg/animations/svgnumber-animation-1.html", + {} + ] + ], + "svg/animations/svgnumber-animation-2.html": [ + [ + "svg/animations/svgnumber-animation-2.html", + {} + ] + ], + "svg/animations/svgnumber-animation-3.html": [ + [ + "svg/animations/svgnumber-animation-3.html", + {} + ] + ], + "svg/animations/svgnumber-animation-4.html": [ + [ + "svg/animations/svgnumber-animation-4.html", + {} + ] + ], + "svg/animations/svgnumberlist-animation-1.html": [ + [ + "svg/animations/svgnumberlist-animation-1.html", + {} + ] + ], + "svg/animations/svgnumberlist-animation-2.html": [ + [ + "svg/animations/svgnumberlist-animation-2.html", + {} + ] + ], + "svg/animations/svgnumberoptionalnumber-animation-1.html": [ + [ + "svg/animations/svgnumberoptionalnumber-animation-1.html", + {} + ] + ], + "svg/animations/svgnumberoptionalnumber-animation-2.html": [ + [ + "svg/animations/svgnumberoptionalnumber-animation-2.html", + {} + ] + ], + "svg/animations/svgnumberoptionalnumber-animation-3.html": [ + [ + "svg/animations/svgnumberoptionalnumber-animation-3.html", + {} + ] + ], + "svg/animations/svgnumberoptionalnumber-animation-4.html": [ + [ + "svg/animations/svgnumberoptionalnumber-animation-4.html", + {} + ] + ], + "svg/animations/svgpath-animation-1.html": [ + [ + "svg/animations/svgpath-animation-1.html", + {} + ] + ], + "svg/animations/svgpointlist-animation-1.html": [ + [ + "svg/animations/svgpointlist-animation-1.html", + {} + ] + ], + "svg/animations/svgpointlist-animation-2.html": [ + [ + "svg/animations/svgpointlist-animation-2.html", + {} + ] + ], + "svg/animations/svgrect-animation-1.html": [ + [ + "svg/animations/svgrect-animation-1.html", + {} + ] + ], + "svg/animations/svgrect-animation-2.html": [ + [ + "svg/animations/svgrect-animation-2.html", + {} + ] + ], + "svg/animations/svgstring-animation-1.html": [ + [ + "svg/animations/svgstring-animation-1.html", + {} + ] + ], + "svg/animations/svgstring-animation-fallback-to-discrete.html": [ + [ + "svg/animations/svgstring-animation-fallback-to-discrete.html", + {} + ] + ], + "svg/animations/svgtransform-animation-1.html": [ + [ + "svg/animations/svgtransform-animation-1.html", + {} + ] + ], + "svg/animations/svgtransform-animation-discrete.html": [ + [ + "svg/animations/svgtransform-animation-discrete.html", + {} + ] + ], "svg/coordinate-systems/outer-svg-intrinsic-size-001.html": [ [ "svg/coordinate-systems/outer-svg-intrinsic-size-001.html", @@ -294021,6 +294853,12 @@ {} ] ], + "webaudio/the-audio-api/the-audioparam-interface/set-target-conv.html": [ + [ + "webaudio/the-audio-api/the-audioparam-interface/set-target-conv.html", + {} + ] + ], "webaudio/the-audio-api/the-audioparam-interface/setTargetAtTime-after-event-within-block.html": [ [ "webaudio/the-audio-api/the-audioparam-interface/setTargetAtTime-after-event-within-block.html", @@ -295887,9 +296725,9 @@ {} ] ], - "webrtc/RTCPeerConnection-onicecandidateerror.html": [ + "webrtc/RTCPeerConnection-onicecandidateerror.https.html": [ [ - "webrtc/RTCPeerConnection-onicecandidateerror.html", + "webrtc/RTCPeerConnection-onicecandidateerror.https.html", {} ] ], @@ -329246,6 +330084,10 @@ "426b47537bf1069121c82dbbb8d4d034ff437244", "reftest" ], + "css/CSS2/floats-clear/adjoining-float-new-fc-crash.html": [ + "b220a48422f45ce0d5a03099142c5052cc31bb7e", + "testharness" + ], "css/CSS2/floats-clear/adjoining-float-new-fc.html": [ "587bbf51b7da9a1d620f35e0b2ece720ddd4ee1e", "reftest" @@ -348154,10 +348996,6 @@ "1bcf4c5b64b07dd0f2097329631cff92c92dd292", "testharness" ], - "css/css-color/parsing/opacity-valid-expected.txt": [ - "46291416765c4f2d9f474a50c4e07f0e3a416d9d", - "support" - ], "css/css-color/parsing/opacity-valid.html": [ "daa8d8647f17ec48a1c648dfaea48bc8373c20ea", "testharness" @@ -349482,6 +350320,30 @@ "8cb8a8f28a1ea5c9abc0fb0bbb5d7b5805aa3b87", "reftest" ], + "css/css-contain/contain-size-replaced-004-ref.html": [ + "eba5e8cb9a81b14895af3e6a9b5b2f425e23d74a", + "support" + ], + "css/css-contain/contain-size-replaced-004.html": [ + "511edadc4f8f1130802b2c179448bad6e7552593", + "reftest" + ], + "css/css-contain/contain-size-replaced-005-ref.html": [ + "a5328c79ac60e24fc05f8c8027247ad9fb8d619c", + "support" + ], + "css/css-contain/contain-size-replaced-005.html": [ + "e889dcc903cc47f4fc59cd65ab313912b8d6e72c", + "reftest" + ], + "css/css-contain/contain-size-replaced-006-ref.html": [ + "2f638d7fe428efe8f326a1ba34337853243d6937", + "support" + ], + "css/css-contain/contain-size-replaced-006.html": [ + "dccb799ea87433e0442539e11c3a5934e4b59e2e", + "reftest" + ], "css/css-contain/contain-size-scrollbars-001.html": [ "26f0d81da8ceac6df92325bf33d15d01c0d3d432", "reftest" @@ -353638,6 +354500,10 @@ "5f3cfeec7e026ed3100c6af37ccc12ad9a5c5258", "reftest" ], + "css/css-flexbox/percentage-heights-006.html": [ + "5633dba3bdb63188d5ce10112d22b69bb5eb21a3", + "reftest" + ], "css/css-flexbox/percentage-size-subitems-001.html": [ "70f3953052a3a770c6cd15ee169607a00fc452b0", "reftest" @@ -363743,11 +364609,11 @@ "reftest" ], "css/css-grid/animation/grid-template-columns-interpolation-expected.txt": [ - "b0a28bcdeda2793917b95b55650315aa6d6d612c", + "9b5f81d129f7cde2694843a47aac0b2d389ac9e3", "support" ], "css/css-grid/animation/grid-template-columns-interpolation.html": [ - "e42a4243543dc43a876724ce1f74a2c1d496c077", + "5da3dea6cca6fba44717efc4dcafb4a258f97679", "testharness" ], "css/css-grid/animation/grid-template-rows-001-ref.html": [ @@ -363759,11 +364625,11 @@ "reftest" ], "css/css-grid/animation/grid-template-rows-interpolation-expected.txt": [ - "02f20e7c811dbb704fcbf08420794dd621911d91", + "c5f662ca9d73969937256ef5799140e457754f39", "support" ], "css/css-grid/animation/grid-template-rows-interpolation.html": [ - "3c650395df082f0240b88f5868fc10ec04960d53", + "c1ff70c49ec1e77ba0e794c7537ae90cd503498e", "testharness" ], "css/css-grid/grid-definition/fr-unit-with-percentage.html": [ @@ -366186,14 +367052,6 @@ "ef110ca17ce04b458100ca9c7b61f71cbc7b3b67", "testharness" ], - "css/css-lists/list-and-margin-collapse-003.html": [ - "78dcbc6cd4503c2dac6122809f498fbd772c3bc1", - "testharness" - ], - "css/css-lists/list-and-margin-collapse-004.html": [ - "4a92f8becf204f03e865218b9d82060f83a8cf7e", - "testharness" - ], "css/css-lists/list-and-writing-mode-001.html": [ "df54e8fb0df8146f896c2abd136d63d930d92d1c", "testharness" @@ -370111,7 +370969,7 @@ "support" ], "css/css-overscroll-behavior/inheritance.html": [ - "e49fa49bc4e26572a68ad947e8e82a63ee46d4e2", + "823d6239471a819dfb4e33bdeb646f7fbbfa220f", "testharness" ], "css/css-overscroll-behavior/overscroll-behavior-logical.html": [ @@ -370166,6 +371024,14 @@ "11647c9228c8fb2f10bf5e3aeb25967b40478c45", "reftest" ], + "css/css-paint-api/background-repeat-x-ref.html": [ + "3df0c5417d7be47e22bd6145be9d13b9e5fbc9b8", + "support" + ], + "css/css-paint-api/background-repeat-x.https.html": [ + "2eccfd2a7d0b6e894a66f1afedc6969090f8ad9c", + "reftest" + ], "css/css-paint-api/geometry-background-image-001-ref.html": [ "83edae100ee4ecd02315147ddf96ef61f34e875d", "support" @@ -372930,10 +373796,6 @@ "490775dd8ce24721046f89234237d8f7c200623c", "testharness" ], - "css/css-shapes/parsing/shape-image-threshold-computed-expected.txt": [ - "8a246fca5bbb8077ddf3a9a0cb9c989b9540eb59", - "support" - ], "css/css-shapes/parsing/shape-image-threshold-computed.html": [ "81bc0ccb8453109ca99fed496ef607ee99e95035", "testharness" @@ -372942,10 +373804,6 @@ "c0cac033fb6d10a00275fcce6bb5e27ed4514984", "testharness" ], - "css/css-shapes/parsing/shape-image-threshold-valid-expected.txt": [ - "b6e14a08a5931acc9a4c701ec12c845edde1ba2a", - "support" - ], "css/css-shapes/parsing/shape-image-threshold-valid.html": [ "4ed1fb9fbaf1bd4aed1cdb89753d4f15c6a72fd9", "testharness" @@ -376855,1103 +377713,1103 @@ "support" ], "css/css-text/i18n/css3-text-line-break-baspglwj-001.html": [ - "2d927eae085ed301f9450da4f77538fc1481201a", + "63677ae05537f74277d69c8a9e4c003b767dd5e8", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-002.html": [ - "e6928a511ee323b8eee956df888f43f6e6483b52", + "80bc4a6093e5ba51d5fc05e0312c880cf8d87034", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-003.html": [ - "ab3de2cdfe4dc5e668188daed0e4ef9f3eabcea5", + "09fabc68885bc020ec9121d04cd6b7ab87d81b17", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-004.html": [ - "6ed1680b444b0cbb9a8ce86f3c610e96c6d04dc0", + "0caffeebaeee628697c8129c3e58464a508c11f7", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-005.html": [ - "2b2385ee9247ff8cc64868e5cb5944b7acb2591b", + "9d17bdaa1cc1e5a99d499cb3fc0886573e182595", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-006.html": [ - "4789681de5328a826f981953f48e256951652e8a", + "0c34ed53f8bc893597cdaa1e40e80f6b5b917898", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-007.html": [ - "c9f9775857307b6b67a0d733d36b3a530dac37bf", + "b4f6d2f9b441bcc6c888ab1a1e097343c69b47e8", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-008.html": [ - "d19991a006d605ea293f9511154f9fa64fe12b55", + "77dc7194ce2c6e955078bf12cdf1ffc3c8255730", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-009.html": [ - "6f3b4eb5344f6e6e5421b9f3dd72afb5f6597c6a", + "f25a575983e1e68be85b5b9a3b375b90cdc2ef92", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-010.html": [ - "00b53566a369aeaeccdce1556ba892a3577ecde9", + "28eb4c41001032d2440a71ac90214b87f103d297", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-011.html": [ - "821d44f6cf9c83d3e1e0b33f56a34c304b090850", + "3d2144c0744fa285c4af18df1bc529d88363437a", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-012.html": [ - "6c3b7e4a51fbb7c6dc9e820de354cfc2b87e1d3b", + "a7579397175114560d99ab32798e171f10479100", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-014.html": [ - "8400e6b14a8950496c5cc35bb3e32b70c1d87773", + "4f67b1ac6d5a6863806bd0ff06a8cb37a1b16c46", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-015.html": [ - "7ea20f5a94a755a17ef03d8add17791bb96d560e", + "734d237c8903fefc31d6be5c1f4b744b31be2433", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-016.html": [ - "20fa39a5bec7df2a7c668ccd6b420a7f3dc02a26", + "93df63bac603822d9ae589c47732a3088f388982", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-017.html": [ - "36373081d1c4f19907b801e79c1638722a1fbbb3", + "3edb77e708437364f38dbd224f6f8557f69dc3a4", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-018.html": [ - "bf14c3247fcda8ca50207f6fbe3a2aba88407746", + "bf0f9eb2dc0adeec155c64fbf7a148653ea82cc1", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-019.html": [ - "c4981c2f0da72641784821549ad10245da62b2a0", + "3a80da037787470a70c93b196ef05e0b122d72d4", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-020.html": [ - "207b5faad06bcf65c80a3729b3661839d84b0ed1", + "26e8d14abecef52e584454e1343e512fb2475860", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-021.html": [ - "8638739f979415e094b95f2ab2efc111ffd24a11", + "42fa5c32eb4dd9fb4401fc3d59935dcb314a1b6a", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-022.html": [ - "e19905ed2b4e560a493f6ede281d3ccac44747bd", + "f5f2c4a83fca09f44af7828442fc278e7ff3e6c3", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-023.html": [ - "a55feb4015bd657a142084eed0af7e1724d6d07f", + "051dfa9403998a9f3700d30cb73bd72c7a051e20", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-024.html": [ - "af8f1340c36b6a463a7a2e54c79fecf3cd33fc01", + "09221092c53d28b8578917fe954d18a7e0a7e770", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-025.html": [ - "9bb029516f6c507c946bceb59b7aab3847d7a410", + "dd9823074cac4890f886260fc7579a5b44ea65e2", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-026-expected.txt": [ - "3fb8385ec3411117e089630e8967aec30e0148bb", + "b3d3fc34d5c2622d011b6c3286c34eb930a33f75", "support" ], "css/css-text/i18n/css3-text-line-break-baspglwj-026.html": [ - "cca4ed843daa8f7cdb6dd2a26520ce7df2a96bea", + "8292d41a7e39d71d83b0bb06b6d813aa7f8085f3", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-030.html": [ - "ac870677e82469c5b66084e62c0c8b85571ab938", + "d688ad383ae6512c1a4c1eee2f2a93a4c67dbebf", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-031.html": [ - "c9c6a3ba02a830237e16ead6de2a543e07e978af", + "d021f965816e55b171b114e336adef50199e22ea", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-032.html": [ - "b760eae93f69753ab115e72f3af4fd6e8a152dff", + "39e7d69715150cc6e99626bbca4bc764cd228c24", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-033.html": [ - "09a600175b549bda0979210fafe3ea9eba220004", + "95873aaa94eff3b3e4f5fa30da10012f2eb291e7", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-034.html": [ - "f67b5504cd34092d58c2d28fcadc3fb2cbf055f4", + "4d93ef0a71b48473593d8853100c3c7b67bccbb2", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-035.html": [ - "e44c44d7871c7c16f63d617094ce65580656a6f3", + "34f30306fa93f1c2634342e4d17689f2df1e305f", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-036.html": [ - "ac358fe01975ac6ffc028bc037e3d5c66af7665f", + "e8a670e7b8ec7933a7679cdb9a2117200d7009c5", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-037.html": [ - "360b64876a39f0b4140a1613a2eacf74ebbf9142", + "3afe27f19dec48e39d6f5de63212489357c4b751", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-038.html": [ - "0fa6ee03ba17a2324184f092529e165302f271ea", + "fc8c6fd8eff7f14dbce09848353f42d4d9277f35", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-039.html": [ - "e575ab402d92accaaff3a26740fd492d067f8b95", + "31c4d4e9829c7e380248ca0bc473a6e7008473a4", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-040.html": [ - "c249c6fd043693a5cfc753040b1c662217a81db2", + "4892ae556bb8acb8d13b204f46d3f2726fbba03d", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-041.html": [ - "5b245ed458fbbca2a4134fc9e3b6df28d8dbcae9", + "ac7a71cf2ba4fc39808ab895f73c09fb65d08c9f", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-042.html": [ - "980046142f3b8ea79b2152558036fc85dc459d7d", + "39130cecb874c6dc1ae43672c0a11613c7fd0b8e", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-043.html": [ - "e0c8bec970290718499b1d2ba55e941fcd33f893", + "8b0fcec1c34060e00d0ff2225731554f2b300fe0", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-044.html": [ - "4598f55dc374af80835c6cadcde4a2deb58c0b77", + "c538fb88b0cf4590f8ff56f20ad723518f97f19c", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-045.html": [ - "1086d07257e61d956d74176a2c6818845e8798e4", + "696ec803d225bbd30833948126a7970ea1c359e2", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-046.html": [ - "3588a938cb9d4b8886353dbf6bae7562f7873dc3", + "29bd1988912abcde51641252ada0d77727732a0c", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-047.html": [ - "053651eedc2dafbbfc6b3ba8ae0c8ddfa25b3820", + "d4b675b5b34c70e30a6facfc8e377d62d54eb33f", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-048.html": [ - "b6ce6541989949ac8188c7ed918f5b48042792fa", + "649a20c791d7402a8e931ab665db5d2f6cd9ac85", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-049.html": [ - "41a1f32338556778fcf4c39e49988aa0fe012299", + "d7c54f1c44c5c1f916ac53240f6aaa553259a7ff", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-050.html": [ - "bb056c3c4c942fa6a7eff2739a0dc75817561fac", + "e88e3cc9b3de927f1cd27b2f9431cff2d9d78375", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-051.html": [ - "4a26ea23a1bdf6688eff1523215959efb8f322d2", + "95129f9051213ec5e74a6703aea54666a2f11060", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-052.html": [ - "f9cbe6ae1739150f1a41d14cc2e2ed2c985a9d29", + "458d0542a69eb713f662090ee9f05f18cfd3ef50", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-060.html": [ - "2caab43c81e1d7381c603cb660282b8881247fd2", + "44fa928e8428f25e7bbc1e37f403ecce9f5ebcb3", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-061.html": [ - "46452ff9567348cb44cc7c3e3b51c663418e7a92", + "ef037bb3087656ef6135f4646ca436056671940d", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-062.html": [ - "5dc418bc58e70f0475583814ba2e8c7affbe803c", + "f74603693fea8aa6acb6e8eb602ece0e9edcc2eb", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-063.html": [ - "bfd96756faecc3f13bf81d4cb5d817b844c7981e", + "50c26922b9c0542405acf1bee0d61a64c81a90f6", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-064.html": [ - "818489ef37d6523fc729f761160fa763cae6c12b", + "04aa14f45cfdb95b414c9c5c5506287cdc45fcc5", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-065.html": [ - "eb926342e8e49902bcb63f43e712f24f2bbc4ba7", + "44349fedcd4f28c5046900334ca7a7ffad286bb3", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-066.html": [ - "4a53923bd5a9dbc8ec3768fe94e1b2ae1ebd2581", + "42fe1a0c4a0864be9a5d59b7f7bf128f25d29af9", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-067.html": [ - "fdc4bf297ceae3e233a88f102dc8bbddbdeac5e1", + "bd3b06de97a2fc28808112b4253ca34504d087d1", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-068.html": [ - "37846df0b83debb5315fa4cd4d11524531cb95c6", + "66fa67e286583ff0ed386e0ab14f78b2edd14a5b", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-069.html": [ - "07375fe27ab7ea0ddc0a054bd6994cc2258464f4", + "869d8e1dc233134eb20e3bd291443b3082aadcfe", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-070.html": [ - "0ec87931003a89cf8c73c6b477106efa05543bbd", + "8b398da350618d3154b0b3e1eab8beb92e1e583f", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-071.html": [ - "20bbf56a81bc9238dc77c57fc93e0ca242bd9104", + "d4d44ca336c15193a89851c0ecb755a3786c5783", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-072.html": [ - "f08cdfdd321e5d6169dd7d23b4b6acb65b7d379e", + "b6beaeb8016413e0d44bac7237adb8b7ff9f627e", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-073.html": [ - "e87d141feda2699cd3bf16aeeaab4834a6b31435", + "e32b43466b2b3c6298c9317584f90db7ebe4203d", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-074.html": [ - "db5e2bc1e9ea8da8b76aea3fd3e929ebf31b7b0d", + "57b083fc45dacb73927dcd5e4a354afbf102ac57", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-075.html": [ - "67456e183897473d2ad115cdaec669b7fdfbe134", + "31e374a98d548a0175db922e1274adc7a4f6fb15", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-076.html": [ - "85a2eabbce987e4f0713b7f8230900dde2157e3c", + "22cc6f28d607723bf86f7b28a6f5ea8511d724e1", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-077.html": [ - "3612b0337882bad67ad1022a5f468d40db7f9c41", + "786f52077c94440b3b9ac9a5f8f0e946edef3cd9", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-078.html": [ - "cd75ea46f45aa75eb7dc2e0a0ff4b406e9e0c620", + "a123d1bfc9f121af3edd06553e93d3011e90ec2e", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-080.html": [ - "35ed5789e851052b287703d63667217d94c0dc4c", + "ee4224a9f6adc962b71eae0eb927d53c357a1251", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-081.html": [ - "71972f04c53bb7a000743f087b8081d83ccae37b", + "a23a41d1b5098f86bd4e47b7a2cf1acef3c29a99", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-082.html": [ - "cc659314d3d69e26f1e91901b6359c891494274f", + "2e95a95f1b3bbc581f0aa075f34c7df763910f05", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-083-expected.txt": [ - "3fb8385ec3411117e089630e8967aec30e0148bb", + "b3d3fc34d5c2622d011b6c3286c34eb930a33f75", "support" ], "css/css-text/i18n/css3-text-line-break-baspglwj-083.html": [ - "a831d4ffcf826bdcddcec996853910414b0d2d3b", + "5d389995d2ad5fea63b3bca726a154be3120a8ed", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-084.html": [ - "d03f82893bae67a3b79aac47f811b3749a03069a", + "4cc59af4bac033c320d607cdd214803867a65457", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-085.html": [ - "bc4767d8f44fa6e6ac756bfb28bb65bf212d4322", + "81c59385f2bdcbd23b8915cf195925f61be5caf9", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-086.html": [ - "bc4767d8f44fa6e6ac756bfb28bb65bf212d4322", + "81c59385f2bdcbd23b8915cf195925f61be5caf9", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-090.html": [ - "ccf0ddcd3883ec283aae4046965aca04335b55d8", + "42ee8908a230910fa2a3845e0178cf1fff4cdb2e", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-091.html": [ - "bffa293eeaeaa79e71f4431a98bcbdd4857c16a0", + "cc52c803199aa305b699f86e075bcca47d93da70", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-092.html": [ - "c7ffd753f007587186f278071cefdd0f54746ec0", + "1dfa041d112e2e71bba5de25d25ac396c83c5bad", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-093.html": [ - "de78a700772710131d689e9d593b6e072d6b7491", + "a7c70c559978881a3c713a74e3f3ca4acef2e575", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-094-expected.txt": [ - "3fb8385ec3411117e089630e8967aec30e0148bb", + "b3d3fc34d5c2622d011b6c3286c34eb930a33f75", "support" ], "css/css-text/i18n/css3-text-line-break-baspglwj-094.html": [ - "c710eaf9b963a5237c4a78c32c33301229060fb5", + "a38ad72667d0423ba609be4c8f286a149ac4fcff", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-095.html": [ - "1562b02ef90d245ac3f72ddb5bc6e8a31b54c13b", + "e0fcf33c5dd8621ac20b6b7ad2e5f9fa273918a7", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-096.html": [ - "7e621b81f220e8c4ebbbe20a7305148ae3306acd", + "b5a96dbb230b4c5401d47d6a67cc7b8376d320ba", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-097.html": [ - "cdb3be3a4749fdc602e415901c60da576a079fec", + "cb031c6befb1d9dc2f7a820a8c36a8f608a5c1c1", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-098.html": [ - "4760c1d3d18d2d168a70a50b961ffd08c2a75a1b", + "44135cf1eebd46b3c3eb6817c7e8c21560427db3", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-099.html": [ - "d88d96caf6955fd149a127c3cb684094139c01a5", + "53880470f0d949e1c31b92cfd9b1f05fd92e0ad0", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-100.html": [ - "d88d96caf6955fd149a127c3cb684094139c01a5", + "53880470f0d949e1c31b92cfd9b1f05fd92e0ad0", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-101.html": [ - "430a56d2d9109ddbf5a9299423438b65b88c0cb2", + "f5f5117fb50fa6988408f124223ce05450a17f02", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-102.html": [ - "716810d73b4709506b70cd12303f5f95ba2fbe74", + "7481591acff4e9c8bd5fd2f59862b21547482790", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-103.html": [ - "c17e1717a8532f9e880099eebcfac41dc256df93", + "3b9db361e5361a29a73be147a78a3f750dd52962", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-104.html": [ - "ae853d3f75e91865cd23d9fc9473d3368e1b9a8d", + "ec575ebc8109d60c9f0eb7a9d7357cf881d4a812", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-105.html": [ - "4c43f66c5a7da32f079a858417eb7b91837f2122", + "af3a8887fd7b8f239a59f0b7e2061efc4a26357c", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-106.html": [ - "8907e57987f9138b76495f737d497bf55faaa691", + "e5203073e707b200c310649e335a28a94577cf9a", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-107.html": [ - "9d23188e64c35d4ad151d5122eefda048b7bf3d0", + "eb3f70b70d1ef847972f2c80c751fb4d433fec02", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-108.html": [ - "dc9f94ce9fff74cd3d06d79d8361f1f1b8aa25f4", + "f977eaa10bd117087c0f9cd6a6438ec069b255c3", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-109.html": [ - "ef37b91db161e220918ed274d9f1dd2ee90598d8", + "1ba489e3bd7f1255ac1b5086ebd569d7d40c6bc9", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-110.html": [ - "43c44fc67d7722905cd1d65046205691da65e9ed", + "fe5cfd0c59018945099eb5042f9c5deeef6ac909", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-111.html": [ - "1db4aef642bcefae001f9804566cc14220ee80c3", + "20e214b63c4f70067370aabdf6d820a405991557", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-112.html": [ - "f6af70906b1d4b2794d7f10cc6958df18ab8710a", + "3e2c4af3c838aec5a98ea81bb2caa931ffd7ce59", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-113.html": [ - "66e03e25bba473a0d2350cf5e25a7f64dba6c4b3", + "ac308ecb92cb9a59c9476ea726cac61e592f43b9", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-114.html": [ - "fc0c64f78f59773f0a0feb9b344b6d51e8a2bbaf", + "ced3533c04c3c202db5c2e500cd3f28d611703d4", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-115.html": [ - "98c6f296f3fd542d37117e5519d9fc3182dcfdf9", + "95c7bee5cad217fbe9547e2ef74ddafbe3b611a1", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-116.html": [ - "e8159844e062a635bf2e79f40b102831a62edc01", + "ebbfd912f2a2ee08172a2a5d358fc1a8d1138537", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-117.html": [ - "c61c766cbc71bbb777fbd3bd83be679dfcba4621", + "ee25a94c73d552e5c0341dd92ae291541c7cb89a", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-118.html": [ - "a32f7768ac15f72b38f5007e201715d4da60dfac", + "6a9736cbb0d6d74a295ee50a592591566351af0b", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-120.html": [ - "b57a54d9e2a43b5e9c3f479207c856a3fceafd81", + "affee69bb6b0eab49ce639fedcf814e778cb006d", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-121.html": [ - "aca8565a3df686be9ffd2e98f5d4cc5c10eb0914", + "589e981b09b69ddf5cf1cc96a61910a69a96e10f", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-122.html": [ - "a2e4df0dac1abd02272e6806321c507e01ebc3fc", + "59bbe8b4356a9b8e45c5c480d2b1a0edc00fc4cd", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-123.html": [ - "5be9df538ef67d3cc1a796b86b69c4a822793def", + "bf98f931322c8d00a4b74a00e93355c83f84ae7f", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-124.html": [ - "cadbbf1992b6005d781bc36d0ac809cd369006a6", + "5ac0df9777c82eec78ede5c0a0ed23f963745f97", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-125.html": [ - "13b5712b7b734d9079ad601c25031d8c2c70c4d8", + "d38479fdde2c9ca8fc7d4cf5c296b77895faf99a", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-126.html": [ - "322a9ecd33715a97b6f11108c939955174b9b023", + "c14899d77888240f94908640b20f5d4360276aba", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-127.html": [ - "f880cb023a99672a67a0a7c40bb57cfe5ff24da2", + "dfa0a8e33e6a3a21fa085b344a864b09b0050788", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-128.html": [ - "302b44710f57af8f1039c22071eeafc2b66e4574", + "b4009bd76f78ddc58c18bcd3372b31105a878e25", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-130.html": [ - "7d16c3baf4151608914e7791f36a836df52181e6", + "b9a9e48e79f3607069256eb3a0d18b7f550b0e48", "testharness" ], "css/css-text/i18n/css3-text-line-break-baspglwj-131.html": [ - "528accad10eaabb699841906fc7070203b93e367", + "93bf8d156b187dd2fa22a53da7d0393bf5606c72", "testharness" ], "css/css-text/i18n/css3-text-line-break-opclns-001.html": [ - "65d7327208284f099a499f816801e41977845ec6", + "e150523327a19157e8eca75b37c0f29db41c2569", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-002.html": [ - "ca03be545534b21e54ab25ee56206d6f63d66c6d", + "12e6589545d2ca71b644b966c0c82ca1a1643d78", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-003.html": [ - "ec0b661415cb20fe2afee6681f206a3824b89ad8", + "984c2ba6c89449f45f6608ff6f2f01be01cf8d34", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-004.html": [ - "686f380bc54f1e2d4c994d8770b08e57b22e780a", + "48d7b8e9a48f31a23ece001e364451367472582f", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-005.html": [ - "78b50f18b67f9ef06e0d1dcbfcd40628cf0848d2", + "0d7913280085da818813089388d31dd0a245e24e", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-006.html": [ - "36cfeba87e248243cae37eee00b452f5470c1ee7", + "185cf59c892d8e120617e35a22d029d6438fbd8b", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-007.html": [ - "aa520e1dad168d2b3f8be4a6c1dd8a5172e47757", + "c67e866bc43cb746879463b11f178713c3804ab7", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-008.html": [ - "ebc4b90b0e46029b86450743394535a0c0d70c9d", + "7a22a9e50f6fdf378552f7f6029065fff14014b5", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-009.html": [ - "d0bcd7ffcc410efcac8d8eb86e746a198db23424", + "1312f5b77d2a32bf040b896969177c7a9170be1d", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-010.html": [ - "89c8f3f0f8d3f61067f348efcc703a90a93cc12d", + "c914a2449953913300260d541aa2cefb81deba11", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-011.html": [ - "9a338aec12da1a9dfcb5fc53a08362b221097307", + "acdef96554196940ad2d58a1269afa0f845e41ba", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-012.html": [ - "9d6ea3d5e5e00a63617db56433189059a1413e0b", + "68e77aaa66bde8815cc7fd6c306b0b3dfb3f6472", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-014.html": [ - "5a25666097347675b36003eb48dd2c22094424b9", + "6fdaee9739ad2e1164bb0c3cf2835ac1ffcc4ad4", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-015.html": [ - "1408381d7262446397c007a0bd42919a4267f787", + "7f6858f53d15eb9bc93eae92fbaec6789a9f7f44", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-016.html": [ - "ff9f5a797193bb5f30abbb35ea28afe188cba4fe", + "9b3717483eb55279aa318f24828c064dd08b5529", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-017.html": [ - "f1aceca3946cbb9c5102ba36237ffc23ffc8ee1a", + "32e4925ac7b11148e48458d898b7510b64551fde", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-018.html": [ - "be8cd0cfe8a173430c7c4f948691a5c734a3f4a7", + "6d8556cd3cf0cf0e6194bd26c647c776191f1791", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-019.html": [ - "15ef881c905aeb53b54c4969ce00220f5a691093", + "977efda0a35a7ea601e63a7f1ce0d77969ed5c16", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-020.html": [ - "0d972121dea2eccd97bdd84ed9ea8081245ebad9", + "9006b8dda651ddd0a1c865ee3aca76def86c48f2", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-021.html": [ - "8ad6f6017fb2e78a3af042fd5c3c7528203143f2", + "ac2c7ff09ce3a2e9c699897ab0f967ad654cd8a2", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-022.html": [ - "8d0c58f73916fb974c73274f55d7ada460972e59", + "7bfaeeb629a156b2b8a7e7a3c27579eaa4e468fb", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-023.html": [ - "14e03e79172105ef6188d3d6eb107dce6a96e4f7", + "3e36d8ab06bbbb73561aed7d552e18cd0daacfa4", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-024.html": [ - "d54eccfd7d68f3462eeb1227713634ded7ff63e0", + "d7b5ee4771636f645dd4f2c00be8560f1bb7f32c", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-025.html": [ - "fca5eab90368aed41cbe420aa4ccaf6c127be392", + "fe049b3d8de10dd7173d88d9606663422f4dc4fe", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-026.html": [ - "a7f87a2babb2598e7236f0adfecb21936c61cea5", + "9fa262ec8235ee93b6d2550ceab923a41114ea85", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-027.html": [ - "2f00731ac29b995afa237ff0f9af062c130b7921", + "0cba8cc740a506fc2a2f336ae5821c60e6ae404c", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-028.html": [ - "62a4f29cb2be03af65e5b03706c7829bf7263d40", + "05d34171c25a19b247393c223d9dbc089656e79a", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-029.html": [ - "003beb5b32b1be0acf7e73e28e3db08792181562", + "6d79c20b476642582479440aa3147ff8ee2f23d4", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-030.html": [ - "74a3f3d0ceb39f0cf711f6b859697a3147094c22", + "1494c06909b67314174b0dc55df7c0863ca1e7b8", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-031.html": [ - "c1744316c03a3581c39401b2133b13847d88e1b9", + "62807dd3e227490b0268dde3e771fdbf9fb80121", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-032.html": [ - "20094b347c698cdb0f08d5d37b40d24c1cdbcaf1", + "a40de11be4b8f3e80f5f6b0a51eeffb577fd9966", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-033.html": [ - "ae72cbcc01d01702d42b6ee5f23fa55662dcd32a", + "aefca35e6546c177c484f2f5b7825e4df6e7f55a", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-034.html": [ - "37bc76b040102cef8ebfa9b503d977e9ba49c800", + "ba4918304ead2d3f655c5bbc2329696a120e31f8", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-035.html": [ - "dcaa88003dc2a5498b70e3f6ef7bf3956834efb1", + "ea8303462fc93ce8173867f2aa6c81b0420365bd", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-036.html": [ - "ac62455f39c56ec6be68947f15335dba3912605d", + "71d8e146666912d6a6820f4314af561f06d7c032", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-037.html": [ - "e684869c4d76b5fde0aecbaea50ef0b9a16cfdf0", + "d14fe3572c39ca4af94ccc3b54e0884634edf788", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-038.html": [ - "02386366ef3a046113ab23766531f4582dfe3c08", + "28202c9329f3ff4fe8ac8a8dfa5a08e575dbe98a", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-039.html": [ - "1cc30a03ebdc2e1372545642d56c9d5cdf6cd158", + "724fd85fb870015371254a62748e6ec2c9068eb6", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-040.html": [ - "2478f1b9faaaf6e81020a5c0b995d862eae8ceee", + "1f626eb1ae4be81a085576793f88c6d4e725de32", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-041.html": [ - "a56e4de2edbb324796fa4b04b5f144652adee638", + "2b8e5cc6d219ed147becab14582c5759145c5557", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-042.html": [ - "37b9d380935a83139bf869d6efb23fa784553108", + "4d2d5fef8ca4ad3ca3432d6d70c6b61f2d3f6ed9", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-043.html": [ - "70aaa8954404511a01fa75527fff433a5188016b", + "59622cda079fee1a7a32b3ed7652be1a672dd876", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-044.html": [ - "4801e3093124482978eabc8f949397de64ab031e", + "37675c1ec7f114463e6e3658a027169cc4835fce", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-045.html": [ - "ab03da2bb4bdc7132c133bd710afbb8fde87059e", + "94a568224db89d8e58bcb8baf3c13f557a227d78", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-046.html": [ - "65cd6027a576c2c6b041d53abe3853fe4b66b424", + "9710c36831f95cf8fb0f2966ceff472864e00506", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-047.html": [ - "bf392784582c7553e29cbd0b828c0f1e41dc3bd1", + "c112ac87664b321432af0e07ae1a420841ffb59b", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-049.html": [ - "8c9a86c051dc240e6165f90da4e9d3d6535a0850", + "2e3e088c9a03a4edfee2415e57965c247a9b9580", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-050.html": [ - "6b3d4973e5a3b504c1b2eb077f899596fb716190", + "f85f3deb1999913ee53c7ca4d4b159fbf220d1a0", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-051.html": [ - "c028e0b1364c595149041754021ffe89d921ffd0", + "55f558e0b187dbde4284e4251572a70211df244d", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-052.html": [ - "73ad09601166bf28079eecb8e1290ad50993c15f", + "a8e094d6f7200653b63a4167f32c522581160f03", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-053.html": [ - "be5dd30d34b62a88f70fc9540cfd073523c6fa45", + "33df08dd39a8b8e420854652f693f6702b98e4a8", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-054.html": [ - "2c22489c4d78715ea1570a20fda11a6dd592dda0", + "02e8c797f18c1a92c9c554cfe026978a34b76df0", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-055.html": [ - "2546535678c8cfd86887b138b8cbec6829a90087", + "d0aeaa609ec7a725b4d9ce0e410b16bc1b91d65e", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-056.html": [ - "102cf4d28239a093633e1263664abc9238698cb9", + "4c4be0f221aecd2bfea74caa7eae7e7ac2e7254d", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-057.html": [ - "49ccc36e73c26ff3af05fd5c70c75f841db80583", + "e97b355b6949fcb02d289c8f7ef01c65e085c7b8", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-058.html": [ - "429384952c1d786f03b4cae696ef846bf8bd8109", + "6fa1bd617d5fd08df03b2d65e3163cde8d276e0e", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-059.html": [ - "65b95b4f7fd8d809cd4f9c4d11472044e9f10ef9", + "190de2cd75468b113d8b3292a5507be39702a60f", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-060.html": [ - "98a0423ab293e9a9a4b97d428a2fc41fa0e2d9ab", + "48c7a771a756b9b6f51c35abea03de7bbdc6484d", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-061.html": [ - "e351406ad258ad11010b8f3aa2bb114cb666c61c", + "4b7cfdeb6108d3c7e9c28475023308fe7221eeaf", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-062.html": [ - "af9b75e70a8b3fe19cd3eb3beb8b8ea4a3dc78ee", + "08818309e4591cff61d31ea7ebb8090c34167b31", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-063.html": [ - "fb4dee8c84aeef51d48edb45b39d661e1f135337", + "cde3bcd06e182948db46ed9ec1f1483a2d3224d0", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-064.html": [ - "1efb48b716e38f9df5d2e18d089a4bd469b452c9", + "b9416640d1495a6ab0abea206f1e44df627cb58f", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-065.html": [ - "c0a17ecac078867beebc34c009c4a1ba99701fe9", + "2856ae5727afb72b94506d96617e32380efa0aa0", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-100.html": [ - "d97591c1c66d76203170cc14c18fed328be25202", + "75216619a97b0a3958b3f11202bbb5c3fe0ac7b6", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-101.html": [ - "125ea52c2ff1ef7b379ade08e3a8c5e038c716fc", + "def939a906354a1c6d0507bad015b4b11e1b9509", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-102.html": [ - "f3e68798b3cb4139e160e6df873cb6fe4a72cb0c", + "bc437fc93f50dc2375f234ef5e2d72cc42ce2249", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-103.html": [ - "5a5fd934f05ea4dcce02a8b22ee1910e19819938", + "a8b9140479783d47bcd6c17f0c06eac329fce33a", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-104.html": [ - "e35c82aacb39d4a4179790f5f7d5273cd6d87141", + "0700d7b98b48c813d7f71a206941e34a2d1c0cf9", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-105.html": [ - "d8baaf03d44e28317ab7d46b2b9914ffd4f789e1", + "9d3a28f1b0016c69e55ff5d6e84a44640f538683", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-106.html": [ - "200ff0c0423659080e76b38a38b194a15b5365e4", + "eebf1095317b0de2a2f31f3a7e089aa46718b91b", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-107.html": [ - "b76f797dd7fe591498fc180f9942059f52f8683c", + "cbf46fc6ab4edcf2ef38f573e956d3426385a3fa", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-108.html": [ - "d33e85c9b5b2099014398a24e393911214feaccd", + "6711fa8295e8745ae6a24790c07e34b78d66e30e", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-109.html": [ - "89dd7bb2d3975fef253ddbf854cc4671d36b5881", + "302ce10aeb122ba2194cb94864f76f6877166ab0", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-110.html": [ - "e89c12b55f644065926826ebda7c361c97910fa2", + "14fc9f25712466d867ba72f02300f455f56a9606", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-111.html": [ - "db0a27628df9c65c9973ef9808368ab73ef50d1d", + "e369d5d50cb3c45fb0c1d4b67f4c5e1352a14918", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-112.html": [ - "01e7faa39d1275e566d1356bcfa9fe3f7a5eaa40", + "4bff4133723ebf29297851b64c529da492c07a03", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-113.html": [ - "314674d170f9cdd1d4bc6807070d6e81f5b2e7ef", + "d9cda3ab80d63048718f2d2223fab66f59198d3d", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-114.html": [ - "2a9c9f281d411f5c157674c0c292528a01c15af7", + "daf95af40b8fb47c353aadc424345dd77ee3b2cf", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-115.html": [ - "eb5cbe0dcc67afe192fda3c04002711fa7cc0064", + "76a0d1f3905fd507a40e367fa85a42ae68e03136", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-116.html": [ - "21ddae596f713fb25c49eec583f574b5ffb661ff", + "904aeb3706f7d601741b8950cd624932aa9b1398", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-117.html": [ - "7fa697affdda9f7e7702bc97c53d4ec5d42a1aa1", + "f9958c9a4ad6800b1b6aa229a08fe642a60057c6", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-119.html": [ - "d6ae58832d7220f209a31fcb9c5edf6caf4ac893", + "36a3f1dfcc324ca0f12098e26c87cb8e870a34d0", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-120.html": [ - "147d62491b01bf7d27ef4745f9ecb4902015d168", + "741452d30f089f2f6b3094b46f88732be9b76c59", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-121.html": [ - "20e7abc3555c881dd44c99de957ee07a4a7187a7", + "121dcd74573414192079ef5f40dc34ca4dcda353", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-122.html": [ - "13ad23e934f8cb9e917e6986416e2449640877a7", + "c1bc044dae8c22fe450e05452719e1051ba181b6", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-123.html": [ - "d0f81dcbab242f80865889361fb5b42c0218ca59", + "beb12b06fc9bba945606cda4cb4a095980025942", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-124.html": [ - "2c4aa74555498cebbd5a0d947c7a5c8083ac571b", + "d596efa2b89d39403534d4e197615c071d03125b", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-125.html": [ - "de99e5c347d52a72b9f9d19896997c9a1d853cad", + "db73766b2c4fa58ed6a99922378b13894bd68d16", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-126.html": [ - "8e5a501da0f0089ec999eaa4335306ec966ab671", + "aed75f9bd6256de664882313e07395b07328489b", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-127.html": [ - "4901e9115027ed7c8acb1bfb2fdacb6f54bea4f2", + "945a1976b16d45f741c7a25be44aea43792c3ae4", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-128.html": [ - "a7362c1f918c71e4001c6145fb130afb4827bb83", + "b15858df13ca34da8d60d4c899f92d8369a08f1d", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-129.html": [ - "de172e28e452dcf5749969eed1dbd62d1e0c9802", + "2add59f6b7b0d7a88d1fde8c87ff878c623fec67", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-130.html": [ - "3fdc7b13cfdc4e0aae8c8938ea5bafa52ca3245a", + "63fde2f34a25447a477cbc4c6e4adc4388b8edd8", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-131.html": [ - "93b7063650c9e92da4ca93c308d5f5eec25a34f0", + "bf58dce9be753532de66016f5d1956057f1b26a1", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-132.html": [ - "8c83a80f66213ed74c60e1690a15405336152b8b", + "8392f21fabf0f37bff34abc35d2478213e106fbe", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-133.html": [ - "352169196b76cd6fcaacc871c5f2cd982a92f268", + "aad6470e234895ba71ca5075c37346aee9b60860", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-134.html": [ - "6a102664e502d3786063a704610c00f5d3b0c81c", + "50830b12efdfa3e3b5cc676816a721823b135986", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-135.html": [ - "1f91909b436e155e4559296df96bdf090287d233", + "62fee7708e7ccb99bef7ee820f95271e191f4cd1", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-136.html": [ - "6b0cddccaefe19016d0563707b6aa1e7459526dd", + "b09f104bab1fdb8064fdd24b7f7fd4eea4546afe", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-137.html": [ - "f6578dcf6ccb7968887d3f7fc78f5b325d85e150", + "912d8d6214914ed6d6e9b4aab40124f1a3a20321", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-138.html": [ - "6fe9782683fde886c4b7f6743f6b3de6c1013829", + "5138aeb325168fae9d6bb052e516aa0a4aa922fd", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-139.html": [ - "9b9cb61e259001e74e26c6c84747d9d3e4510fd0", + "473ea17678c47baad163c97cc590a3f8a44e46bc", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-140.html": [ - "676eed0ca9999ff27ec6f305372cf127895fb06c", + "fe0060adaba1a514e824ba2a3489b505b0313fda", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-141.html": [ - "6b6d021db31b6feda6312f7ae652d3c64e121de8", + "073ea05ee088f567ae44018343f7d7637ed57ef6", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-142.html": [ - "95ddc3557f4abb480e5df8045cc09770853790bb", + "994a4a88e709a07084f8f75a51e7305b65de2e17", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-143.html": [ - "d3338c22b64766f1c9cea76bb8d0a5ea9b078ec2", + "a61cc5647f0d400798a84595d04263f6fc0b106d", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-144.html": [ - "397cee69bb49a42a6d334614e30d8ff62b8ca4f1", + "5905185924d33625ddeb525982f47cc20402de1f", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-145.html": [ - "f3c75980ec0ed8b165f4ee60e25fbab610f18e58", + "7c6cddb1eb6d1d9dd243ca86bc090ec73a9f27e1", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-146.html": [ - "21570bbd0c6ac5a66350edb162770e9bdb8a1423", + "37fd024865ea6e2aa1355bbbf7b9afacfe3a93cb", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-147.html": [ - "3f20bcf5dd46b889ed59492294baaf3a43e2864d", + "678d1b9af3624da5eb182df56ea46c63619936f9", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-148.html": [ - "562812754e722c30e040ff6916b924a3dedfe6e3", + "e9945f0b986be18e0564bfedcd0f374990fd3836", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-149.html": [ - "cc2a953961837d9e3d8199bce12484c6706bce8e", + "11907a406fd82aa095380c829b6d632681fca46f", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-150.html": [ - "380893faf1f5f1f4eb38aae3404eaec4eccf8d7a", + "2653652d0dc6b549853384801b6038702410e6b2", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-151.html": [ - "87c1db2e4416d52629ab3c9af5fa66d1e609ad8a", + "af7656910c9f49e2429c2a50e060111546dfe2a5", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-152.html": [ - "6f6767c714ef3b235a5a13dbc63513c3679f45b1", + "8090119899e65c2641f762b66c1128fb540cec3e", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-153.html": [ - "bf0381aa5601ef1e211a15bb1f4e954aac8cc9a8", + "31ca266ba94495dbec416f5c58ae85736361e32f", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-155.html": [ - "c1a26be6b283607056b2a7ceb3aabf7e1661b774", + "ecdf8c1487aeb3e11375c4b03b3fb5129efe08c2", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-156.html": [ - "d34641778366f7afbb7f085695ed4dd271a0b664", + "52982127a1c2a87682211afea602d5cc063c0ce1", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-157.html": [ - "808bb91a3d904bfcd503d5316999a78b1e6d78c2", + "08297c9388ca569c671c7942c3ad62bb363dd7e8", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-158.html": [ - "d5d030916e0d939c92bbc6aeda61c04a2024883f", + "7a155bb9527e198c4d33490c351bc9c6e7882e52", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-159.html": [ - "296673a155523c0413fdf4aa07ba45287ef82b00", + "ada16da9f5e85f1d3c5541d0545c4bad3352c272", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-160.html": [ - "1b7419fb06f3c87b232483f9741fcd879616c6c0", + "65a8260450d3878214065e140884b2ea71f5f8d2", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-161.html": [ - "11de841f66bd7549f7f8dc693364758ea97fd028", + "847202a71e5d8db61795cfd7948bf6e80c1888b7", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-162.html": [ - "1e373b5824e7a720bb76b5b32eccbe2fac221b2b", + "73daa10ed997ab535c0f81ab391848fb17a3220f", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-163.html": [ - "53deaaa0f5243ac1b7ed3bacb66e0a68fb1bc9e9", + "62073afabe506bceb9cda6e978a2986b31a3da19", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-164.html": [ - "5a59c950a3b6fd2ae010c2a04ab379c2cef861f2", + "e23308ccc3e6ceb06947efdb13680f02acc89c9f", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-165.html": [ - "48b071f38a24d11b18321e125b27dda0dae6d73c", + "3f467d11977577db8fb6f4275ba8e004e427d23f", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-166.html": [ - "a8d357ce2ed58ed1d80fbf14b8925a569b94d201", + "8f9b4192ccb0472213eb8a0445a6d9aae5e189a6", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-167.html": [ - "c37ca171fd7dee717e5faa8ec2c522344c707c7e", + "80f96fa31b768391380822388200c1c1e22020da", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-168.html": [ - "eb43c6394be58c95103891b067ac29de161f78ff", + "23477b04ef920da76bdee481a5d01682f38b56de", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-169.html": [ - "bb65486f42703d645b70912c1468f502b7b7de75", + "1a619b1d93fecd072753d388673a7cdc3c15d892", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-170.html": [ - "a67d271c096135bd20fcb87e06190bb640517671", + "bd3ce8eb8ed32e8e630c046443645d5f4a3ad0c1", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-171.html": [ - "1e931fae83be94fb64d1f670ca02744044477fe0", + "382736c9d0a1ae560cdb69769a0216ca57e23c86", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-200.html": [ - "57460aa67be9af8f67cbb406b9d6f6ee93478681", + "298ee680239ae4ca9959dce658b80317ec93b71c", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-201.html": [ - "09ccb28f3a8e5ca08caaad95deedc8f690eaa05d", + "6c95bb130876f79230aafb46a2aebbbd661e08e4", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-202.html": [ - "70280cee9633756cd19134044a00adca93c8979f", + "4d288b1f5310b724547e455352e6b712c75e9acd", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-203.html": [ - "21228668c494b017da1310f2c43459be4f53cb81", + "2ad9d56577872299fc3e0b62afb3373d7cf0b36a", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-204.html": [ - "d85601c7afcdef4bd787b478243f1861623302ac", + "69416d3f5e6fbc245b5feff1b730a8a1e20060ed", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-205.html": [ - "64eba30bde1a3e2f87dc91718a8a7de4bef73f16", + "2f3297ed10021c09dbee71acd4b41708caf4259e", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-206.html": [ - "0d26e5e00fd0083313baf765c7813100a6b26155", + "d584f0a187236b377792f5164febdca2e93983a0", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-207.html": [ - "e98aeee072bf01d09584381ab0d21e426674f35e", + "2a3d8ee06ab5fa80b15ad2df1acf40cf9271b564", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-208.html": [ - "86128f866c30c8eefa26d9f615a350b9a61932ec", + "a7f0ff0fa77dcff705f705a12b2c6975f061b0b5", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-209.html": [ - "1b8da919a6b71df1e34b7e87e78b32ed90c65c3e", + "044a435241dc2d667dfcc0eef8e1820e66f8ff27", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-210.html": [ - "72740027ebc4b297a61139252352263060f0865e", + "076a06823ea82a2490ff627e41f119e0c66e66fa", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-211.html": [ - "22268f4ae45630aac6079355714fee8b823bf98b", + "254211af4028785e985c5bf341bafd3ffa2af5bc", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-212.html": [ - "536811086d51a065f9d07c285a8e8c6b7ffd81da", + "1ce5478116ebe2711b68b183c387caf14559bde2", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-213.html": [ - "37f6b154a165de4a6f23c42991f2bcfa45f39961", + "c8464baf0ce66b02deaca6f96f0d0d6bbc818a87", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-214.html": [ - "12951207c7fb07660f0b2962a1f36bc8755f668f", + "20db61d453171b0d842e2c6a9dabddd7591b10dd", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-215.html": [ - "ec7b51fec9c0de2f37b76836bc7e83a68f631197", + "8a603a570ef4bd26fd145d0546b9dc5cc6e5a3b3", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-217.html": [ - "fdd4a3b263dc5462120b3dd230df8d188365a9b5", + "f975564d9338ef5ce39a65753613bdb37c07ac32", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-218.html": [ - "c10d0d61a7ff917d707ef5e62c1d08f7cfe76a95", + "e7c4c0a3667c3fdcbb80ffa65c33437e9be92ba8", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-219.html": [ - "1d991ab3119264e675daf9523a98ad81de95bcc8", + "77b82ab0cc409e620a4ac74fe5c6c223d57488c5", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-220.html": [ - "eabf2c9b501b7a0bbd36d10c81fd586792d76265", + "5bd4f80333ed8f8e0cd9626e58f9648c1b4b7f9c", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-221.html": [ - "5fdf1d5410b5ba4399a1e589fe0a4a583015bf5d", + "7919aa72e4c531509724ca0c599bcb1bbdd1ae6f", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-222.html": [ - "ad07476663da8c8579dd7a7795088559daca7a62", + "0fd1093a61f0d58d030671daf131425d715f7aab", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-223.html": [ - "e15641543ce71d3b52954024e79072a4656cd0de", + "ae076ca4401168e49b3b8149401455a3097d86d7", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-225.html": [ - "1bd5a3adcbd68754a559644501619eb438492bb0", + "3e3061976aef3d221755b4a4db8030354a3c0360", "reftest" ], "css/css-text/i18n/css3-text-line-break-opclns-226.html": [ - "70c1c6d8331bab29aa4aaf8a33728f57048a8560", + "fef8bd58dc31a0bd5fd72a7e5974ffc16b60b55e", "reftest" ], "css/css-text/i18n/ja/css-text-line-break-ja-cj-loose.html": [ @@ -379123,7 +379981,7 @@ "support" ], "css/css-text/line-break/line-break-anywhere-001.html": [ - "a031765b3245aa8b4efe303b5d4cd6019b6aa4a0", + "6ae60eadb9e59021736da5a25c685230cd36d0eb", "reftest" ], "css/css-text/line-break/line-break-anywhere-002.html": [ @@ -379311,7 +380169,7 @@ "reftest" ], "css/css-text/line-break/reference/line-break-anywhere-001-ref.html": [ - "ff74b3bce2d5ece698b404ecd30b53538c0eb420", + "daf17c9c0aa310ec26ea0d2510add74675f6216c", "support" ], "css/css-text/line-break/reference/line-break-anywhere-003-ref.html": [ @@ -382594,6 +383452,74 @@ "9f579f29e0c897c744e1b06d5d2d60e85612f823", "support" ], + "css/css-text/white-space/reference/trailing-other-space-separators-001-ref.html": [ + "34e60ff0721d9197b9d39bf98d3682deb6ac7aba", + "support" + ], + "css/css-text/white-space/reference/trailing-other-space-separators-002-ref.html": [ + "3939dabe5d5e77d19cb528598604c4073b8c1774", + "support" + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-001-ref.html": [ + "738bd55b0b7eb6be016e047537ebd8e370c65dc4", + "support" + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-002-ref.html": [ + "f3abfe4627183bfe24746d394bf779dd70023ddf", + "support" + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-003-ref.html": [ + "a1681bfb607eaf92dbbb9479013f08f136eadac6", + "support" + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-004-ref.html": [ + "2201f7d067803a660f251c004c31e3e3d1099413", + "support" + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-005-ref.html": [ + "9174a0984aab7a735b0a42f0c7a9b07e4e1f5670", + "support" + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-006-ref.html": [ + "35261a8010c18d362d29afbfe5061af0028e12e5", + "support" + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-007-ref.html": [ + "8e8163ca1675ed34e6259461a1ca5d08ba046994", + "support" + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-008-ref.html": [ + "fb2ee58aaff4f4490d629a1265ea16d1172a980a", + "support" + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-009-ref.html": [ + "005c5055196006d2deb51c64692618a53abcb6b9", + "support" + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-010-ref.html": [ + "5f4c11409f0582673bdd6c348020b92ec5563fb1", + "support" + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-011-ref.html": [ + "f7770741dc97abd8cd31f555f134a70c1e88ef3a", + "support" + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-012-ref.html": [ + "6b00177f2962912d7f8d150c1205c07355b3aa47", + "support" + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-013-ref.html": [ + "6deaef07f1bd3a15f3204d969c7a07e2f88c86bf", + "support" + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-014-ref.html": [ + "1eed539eab6ebd141c3b1719a9eccfb971a51a8e", + "support" + ], + "css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-015-ref.html": [ + "c60d25401b358332e73da4e0dd3c16c496779230", + "support" + ], "css/css-text/white-space/reference/trailing-space-align-start-ref.html": [ "b65a8fe75479c0119a8ecc156b9a5d5f318d66d0", "support" @@ -382830,6 +383756,82 @@ "af3187ae8d3d955dcb23a02de7ecc6b0b4db9479", "reftest" ], + "css/css-text/white-space/trailing-other-space-separators-001.html": [ + "6b693f08494734678af27db97ac9022e13e28190", + "reftest" + ], + "css/css-text/white-space/trailing-other-space-separators-002.html": [ + "269b691b615418d2e6ea44d5a803753d4bef848e", + "reftest" + ], + "css/css-text/white-space/trailing-other-space-separators-003.html": [ + "549c731f44d356212cf3e1cf93a65eb1b33a008e", + "reftest" + ], + "css/css-text/white-space/trailing-other-space-separators-004.html": [ + "90a568a8c9d49154db4157fde3b93ed50cdefb76", + "reftest" + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-001.html": [ + "896afe6019df6f02a946ecbfa0d7445d8b07c973", + "reftest" + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-002.html": [ + "f795b3173ffef4f235a538e89a220807440c3168", + "reftest" + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-003.html": [ + "f5e2fd82d7648f742fe8d1b8c09a49fc52939781", + "reftest" + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-004.html": [ + "99308eb82dc3586d7e5f5043314bcf12c539ac65", + "reftest" + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-005.html": [ + "9323e810926376e1b6a8bc31647c19ab5c1dee92", + "reftest" + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-006.html": [ + "d4c24ad009ec0f1555955958c09fae9e939181a3", + "reftest" + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-007.html": [ + "e9ebbacae491d5a2bf03908b817a0a732e0a5d7a", + "reftest" + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-008.html": [ + "7d399e2efebe111b16a5b0f599d47dd394e1c655", + "reftest" + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-009.html": [ + "3d2d9d900c16332bccea310a5cb7fb49b778335a", + "reftest" + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-010.html": [ + "1d75558b3522bf167967239dcb87dbf5f394a150", + "reftest" + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-011.html": [ + "f0be5d586a7db4f29a9b2b50bd2b5090c8d0b972", + "reftest" + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-012.html": [ + "ffb018ec54c21dd55133dafbdde7728d2dba8b48", + "reftest" + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-013.html": [ + "067ad06f4cfa95848b7f8cb3498f2976982e1f98", + "reftest" + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-014.html": [ + "36cc5aed59d45c28315e83c7c861c04c50589b84", + "reftest" + ], + "css/css-text/white-space/trailing-other-space-separators-break-spaces-015.html": [ + "cbb7e7c31b2ee05161b502d66c8c8339fb163436", + "reftest" + ], "css/css-text/white-space/trailing-space-align-start.tentative.html": [ "7908de12adff86e96df50a30a9ae57e2db9cd7f5", "reftest" @@ -388938,10 +389940,6 @@ "4c7a7a4891636a7201f07b671ff605dca3ddcc2b", "testharness" ], - "css/css-transitions/CSSTransition-effect.tentative-expected.txt": [ - "065f2d4229e82516c9dbdc22aac1b8b7c88c2db9", - "support" - ], "css/css-transitions/CSSTransition-effect.tentative.html": [ "a6153b33171daee1dc0e9cb5b98c2ff89059fbae", "testharness" @@ -388958,10 +389956,6 @@ "b6482f8047422f6d5abf6e1ae5a14b8fdc9a41f8", "testharness" ], - "css/css-transitions/CSSTransition-transitionProperty.tentative-expected.txt": [ - "414a6e1657db8c63a204e56691321ccda3de04c6", - "support" - ], "css/css-transitions/CSSTransition-transitionProperty.tentative.html": [ "8eb284107d350fb2a5da1b176aa213f807cd212f", "testharness" @@ -388975,7 +389969,7 @@ "testharness" ], "css/css-transitions/Element-getAnimations.tentative-expected.txt": [ - "67df4ecaecda5e6ce8f19e7f1babce484e406459", + "8878ef0b1b6752fc2ea0af3ab09f2d36ea0ad4d1", "support" ], "css/css-transitions/Element-getAnimations.tentative.html": [ @@ -389027,7 +390021,7 @@ "testharness" ], "css/css-transitions/event-dispatch.tentative-expected.txt": [ - "4a1fd79bfb4c30445f5442f3f96d471ec2292abf", + "3216888a9ef85e95c6ad59c8ca1454dfa3668f33", "support" ], "css/css-transitions/event-dispatch.tentative.html": [ @@ -396686,6 +397680,10 @@ "2e93f34363748585836a28ac86581dbcd8863d7e", "reftest" ], + "css/css-writing-modes/bidi-line-break-001.html": [ + "f46b56b76cc011126055bd7327edb4ec4963f9ad", + "testharness" + ], "css/css-writing-modes/bidi-normal-001.html": [ "59479c538ce2114bfdec8bf3a6b91af8be2b8735", "reftest" @@ -402099,7 +403097,7 @@ "testharness" ], "css/cssom-view/scrollIntoView-horizontal-tb-writing-mode-and-rtl-direction-expected.txt": [ - "1ee45e2e10c2b83122b35b7baf10622f3853e6a6", + "e6c667c584c1847913ee81a0c1bddcc2bf41f773", "support" ], "css/cssom-view/scrollIntoView-horizontal-tb-writing-mode-and-rtl-direction.html": [ @@ -402122,6 +403120,10 @@ "eb1bce37d2cdc09640eb1aa20951f75d2a8aa36f", "testharness" ], + "css/cssom-view/scrollIntoView-sideways-lr-writing-mode-and-rtl-direction-expected.txt": [ + "8ed2baa631ddcbe568cd5fb32505c2e61b2b3c6c", + "support" + ], "css/cssom-view/scrollIntoView-sideways-lr-writing-mode-and-rtl-direction.html": [ "8d435407f68e42e026c22b563f639e885d1feb84", "testharness" @@ -402134,6 +403136,10 @@ "0659dec8c1a7e226e2e22c7ae16119f204c5d892", "testharness" ], + "css/cssom-view/scrollIntoView-sideways-rl-writing-mode-and-rtl-direction-expected.txt": [ + "410a1757236c986cfa8141c17653d3ed13dd3d37", + "support" + ], "css/cssom-view/scrollIntoView-sideways-rl-writing-mode-and-rtl-direction.html": [ "82e43eb4859d9cbd5cea64e105adfae9df629f21", "testharness" @@ -402155,7 +403161,7 @@ "testharness" ], "css/cssom-view/scrollIntoView-vertical-lr-writing-mode-and-rtl-direction-expected.txt": [ - "e65551778c1ee55e7774157c8634d8f1e372f14d", + "9c4115c5977f0a98f10cc19f6dc34240348204ec", "support" ], "css/cssom-view/scrollIntoView-vertical-lr-writing-mode-and-rtl-direction.html": [ @@ -403914,10 +404920,6 @@ "5fb4a266e6c0b3cd8eab37864ce53b4cff5686e4", "testharness" ], - "css/filter-effects/parsing/flood-opacity-computed-expected.txt": [ - "4da55addf44ed4ec73b630942edfbd4a69b56200", - "support" - ], "css/filter-effects/parsing/flood-opacity-computed.svg": [ "a395eda22e377757afc1583016e8d14da13268cc", "testharness" @@ -403926,10 +404928,6 @@ "ac21f8d8fbd593c266bc34bab15e94e857564f44", "testharness" ], - "css/filter-effects/parsing/flood-opacity-valid-expected.txt": [ - "01b8a62475bdf78c1d150d89331815574cd90075", - "support" - ], "css/filter-effects/parsing/flood-opacity-valid.svg": [ "67eb37fad5ec15e01f9f54ea016e74606dec9f03", "testharness" @@ -404366,10 +405364,6 @@ "b7f5a911772b21272265bfbc6fdebdee62bce0a8", "testharness" ], - "css/geometry/DOMQuad-001-expected.txt": [ - "140c19bb54a4063f597aa6649b72daf22a21fe7d", - "support" - ], "css/geometry/DOMQuad-001.html": [ "38c54285d94b516c9be6f904be2542956b81c53e", "testharness" @@ -404627,7 +405621,7 @@ "support" ], "css/motion/animation/offset-anchor-interpolation.html": [ - "7ad9482a2b4b65eda290a9ed33f3db24acd7bce9", + "75f855a2c8aff046c2817201197b3eb345327a4a", "testharness" ], "css/motion/animation/offset-distance-interpolation.html": [ @@ -404674,6 +405668,14 @@ "9bc2409061d0ca3df287d33fdfb84bdecf522d01", "support" ], + "css/motion/animation/reftests/offset-path-with-transforms-001.html": [ + "c554264032737899f8ff5e3e6816085ba5a90a29", + "reftest" + ], + "css/motion/animation/reftests/offset-path-with-transforms-ref.html": [ + "413369e0effe0b2cf0236be14c419f2cfeaaf5f3", + "support" + ], "css/motion/animation/reftests/offset-rotate-interpolation-001.html": [ "360caeea68242cc80cbdb131884c633a6f3f7b47", "reftest" @@ -404782,8 +405784,12 @@ "ec22768e96a1cd1efab206781b985cec8f006686", "support" ], + "css/motion/offset-supports-calc-expected.txt": [ + "c7772419a5144fddb7316cd9413e20d352352324", + "support" + ], "css/motion/offset-supports-calc.html": [ - "9ec737e6a87198e390b4adc0c0cc5a349dc1bc43", + "907694f7fc32ebb1c44787fcfbf5980627d2919e", "testharness" ], "css/motion/parsing/offset-anchor-parsing-invalid.html": [ @@ -404791,7 +405797,7 @@ "testharness" ], "css/motion/parsing/offset-anchor-parsing-valid.html": [ - "a69a5ce9f8117262db576430ea9c840b958a14fa", + "6cb4d44117fa6361fc87efdee22e79bc6df749b5", "testharness" ], "css/motion/parsing/offset-distance-parsing-invalid.html": [ @@ -420019,7 +421025,7 @@ "testharness" ], "fetch/corb/script-resource-with-nonsniffable-types.tentative.sub.html": [ - "bf42d0eaf685d2d1bcdb3b9a0276daf2aae2268f", + "4cbdd7b99e6b4bae045951733d61a794c476571c", "testharness" ], "fetch/corb/style-css-mislabeled-as-html-nosniff.sub.html": [ @@ -420966,32 +421972,32 @@ "e4d381edaf259a15b24c55a0100ce9cd05444967", "support" ], - "fonts/math/fraction-denominatordisplaystyleshiftdown6000-rulethickness1000.woff": [ - "3d90e64302a7d0d9708329ef41ae62d441c53e04", + "fonts/math/fraction-denominatordisplaystyleshiftdown6000-axisheight1000-rulethickness1000.woff": [ + "28e41f5cfb39a864dde00ca1e5ba9100786d062b", "support" ], "fonts/math/fraction-denominatorgapmin4000-rulethickness1000.woff": [ "ab648f5eb66369415831d25d7eedc7305205b351", "support" ], - "fonts/math/fraction-denominatorshiftdown3000-rulethickness1000.woff": [ - "0b7efbaf70647351f336fa5bc416fed4dc856593", + "fonts/math/fraction-denominatorshiftdown3000-axisheight1000-rulethickness1000.woff": [ + "f0e0d5cbc2befa80d41c48ad9794e4aa431736b9", "support" ], "fonts/math/fraction-numeratordisplaystylegapmin8000-rulethickness1000.woff": [ "2e910bbf42147fa041e79f80a12e3bd1b375ecff", "support" ], - "fonts/math/fraction-numeratordisplaystyleshiftup2000-rulethickness1000.woff": [ - "920c81eb1bf7bf82a613c4aa27972a09765f2ee5", + "fonts/math/fraction-numeratordisplaystyleshiftup2000-axisheight1000-rulethickness1000.woff": [ + "d6f530d8e104b880d83973817c137a9c69d0264c", "support" ], "fonts/math/fraction-numeratorgapmin9000-rulethickness1000.woff": [ "1b5d60bb14457cf9ee639f7d248ae57268ec0b44", "support" ], - "fonts/math/fraction-numeratorshiftup11000-rulethickness1000.woff": [ - "3e70cd29a344d195edf4ded1cc67ced91a23d2e1", + "fonts/math/fraction-numeratorshiftup11000-axisheight1000-rulethickness1000.woff": [ + "d26853979607b2772597b8b9d5df28d3f45dc957", "support" ], "fonts/math/fraction-rulethickness10000.woff": [ @@ -421182,12 +422188,12 @@ "7a9dc5d4cb1bbc758d2ecf34641e331e9ac7acb0", "support" ], - "fonts/math/stack-bottomdisplaystyleshiftdown5000.woff": [ - "8761585484b83e3dad6488e99340825bcdb872d1", + "fonts/math/stack-bottomdisplaystyleshiftdown5000-axisheight1000.woff": [ + "d8f8ae48a6d4c24ba17ed9185b769a8956418002", "support" ], - "fonts/math/stack-bottomshiftdown6000.woff": [ - "96ebce2da516621dae35145f49245bc490deb8e4", + "fonts/math/stack-bottomshiftdown6000-axisheight1000.woff": [ + "a3a491dbaf1f066ee4d564468c6107d324d9a988", "support" ], "fonts/math/stack-displaystylegapmin4000.woff": [ @@ -421198,12 +422204,12 @@ "a4428d1d49bdfccce2ae95b417ae2c902edb86d8", "support" ], - "fonts/math/stack-topdisplaystyleshiftup3000.woff": [ - "556226f12265581701190efd0bd198586ee55139", + "fonts/math/stack-topdisplaystyleshiftup3000-axisheight1000.woff": [ + "bb286182e47cc5ba7142b78425c5652fb74d6dcc", "support" ], - "fonts/math/stack-topshiftup9000.woff": [ - "d036e893087cef4dc4ad62681b968f9ef75be9c8", + "fonts/math/stack-topshiftup9000-axisheight1000.woff": [ + "52bc04458caae71c2ef71250e4c0fd9ac4290726", "support" ], "fonts/math/stretchstack-bottomshiftdown3000.woff": [ @@ -429778,14 +430784,26 @@ "c4fd5824a1c617c21fe8b92483b388d586edf06e", "support" ], + "html/infrastructure/safe-passing-of-structured-data/resources/echo-iframe.html.headers": [ + "6604450991a122e3e241e40b1b9e0516c525389d", + "support" + ], "html/infrastructure/safe-passing-of-structured-data/resources/echo-worker.js": [ "cbbde8a73c8c2a63cc97cbe2b6cd7c6d81585b5c", "support" ], - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success-and-failure.html": [ + "html/infrastructure/safe-passing-of-structured-data/resources/echo-worker.js.headers": [ + "6604450991a122e3e241e40b1b9e0516c525389d", + "support" + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success-and-failure.https.html": [ "8902de49cfb10293ddb6246dc834268621e0dcad", "testharness" ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success-and-failure.https.html.headers": [ + "63b60e490f47f4db77d33d7a4ca2f5b9a4181de8", + "support" + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success.https.html": [ "d3e9956368a5ce538ff6e57d6f1febcf8d882a59", "testharness" @@ -429794,26 +430812,62 @@ "63b60e490f47f4db77d33d7a4ca2f5b9a4181de8", "support" ], - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/identity-not-preserved.html": [ + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/identity-not-preserved.https.html": [ "869f49043e9736bf62c2ec60257019175d2961f6", "testharness" ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/identity-not-preserved.https.html.headers": [ + "63b60e490f47f4db77d33d7a4ca2f5b9a4181de8", + "support" + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https-expected.txt": [ + "7b70ea298989ba1aeafd5cadeff2dd50b97c56e2", + "support" + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https.html": [ + "dd221502b6f6c31d56852df2519ec1f162352135", + "testharness" + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https.html.headers": [ + "63b60e490f47f4db77d33d7a4ca2f5b9a4181de8", + "support" + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success-sharedworker-expected.txt": [ "7b70ea298989ba1aeafd5cadeff2dd50b97c56e2", "support" ], - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.any.js": [ - "5388ebcc39b22946957250004577a1966c264a5a", - "testharness" - ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.any.sharedworker-expected.txt": [ "7b70ea298989ba1aeafd5cadeff2dd50b97c56e2", "support" ], - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-transferring.html": [ + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.https.html": [ + "aeee3705aea4bf54d2073392451df2d238045627", + "testharness" + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.https.html.headers": [ + "63b60e490f47f4db77d33d7a4ca2f5b9a4181de8", + "support" + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any-expected.txt": [ + "03e29e361a979b99ae058233eededfdc13bfa7d7", + "support" + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.js": [ + "96276d747047fc72d02a22055edf2986ab2163b9", + "testharness" + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.worker-expected.txt": [ + "660041682dcbd8f3e1c7b839d86c49530fe8b20f", + "support" + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-transferring.https.html": [ "b39e37fd4966440dc01c2efab42ea99f30574f68", "testharness" ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-transferring.https.html.headers": [ + "63b60e490f47f4db77d33d7a4ca2f5b9a4181de8", + "support" + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/blank.html": [ "eec1b2cc8e36c3fb130563ec9545b1084fa84426", "support" @@ -429823,65 +430877,129 @@ "support" ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-iframe.html.headers": [ - "6604450991a122e3e241e40b1b9e0516c525389d", + "1528bf05e6368b00600b23c23042bf0d61985917", "support" ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-sharedworker.js": [ "310e0e9358446acaec0f13d8e2fb4437316953c2", "support" ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-sharedworker.js.headers": [ + "6604450991a122e3e241e40b1b9e0516c525389d", + "support" + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-worker.js": [ "36369cde5004b40b079f00377cc54b83c52941ee", "support" ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-worker.js.headers": [ + "6604450991a122e3e241e40b1b9e0516c525389d", + "support" + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe-domain.sub.html": [ "a6dd70177584c9115c24beb281e7681110c07624", "support" ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe-domain.sub.html.headers": [ + "56d0ac342824434c621fb50f9351e2e74aa077cb", + "support" + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe-messagechannel.html": [ "6f3f284ae24b1d5c1ea432766bed2cb2445a9a42", "support" ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe-messagechannel.html.headers": [ + "1528bf05e6368b00600b23c23042bf0d61985917", + "support" + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe.html": [ "6f27ad7d5becee543f00093b47fbe65fa46614dd", "support" ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe.html.headers": [ + "1528bf05e6368b00600b23c23042bf0d61985917", + "support" + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-popup.html": [ "e583b5c4161be811b30f6ae2ebdc93215beb3fe0", "support" ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-popup.html.headers": [ + "63b60e490f47f4db77d33d7a4ca2f5b9a4181de8", + "support" + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker-with-channel.js": [ "c74fd26d3fd6e85a48c147f771ed4689eea5e9ac", "support" ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker-with-channel.js.headers": [ + "6604450991a122e3e241e40b1b9e0516c525389d", + "support" + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker.js": [ "5801bd2b97c8b5b7e300a24a9e729c40c5355eed", "support" ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker.js.headers": [ + "6604450991a122e3e241e40b1b9e0516c525389d", + "support" + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-1.html": [ "fe93cc0c4b0fe5b86bf1a12de84fb3fc48ea08a5", "support" ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-1.html.headers": [ + "1528bf05e6368b00600b23c23042bf0d61985917", + "support" + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-2.html": [ "fad52ce9de3977c077b5a22e72ee7b23837ea302", "support" ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-2.html.headers": [ + "1528bf05e6368b00600b23c23042bf0d61985917", + "support" + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-3.html": [ "7971022b2cdc315d598761a3694838494c2884a8", "support" ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-3.html.headers": [ + "1528bf05e6368b00600b23c23042bf0d61985917", + "support" + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-4-incrementer.html": [ "d374515bdc736658432c92da42d7bc0765daf09e", "support" ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-4-incrementer.html.headers": [ + "1528bf05e6368b00600b23c23042bf0d61985917", + "support" + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js": [ + "9befc9006e706853d9fab259e631a39f3193c095", + "support" + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js.headers": [ + "6604450991a122e3e241e40b1b9e0516c525389d", + "support" + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/serviceworker-failure.js": [ "c6f2046878cce32fdc01596ca369930b71e13938", "support" ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/serviceworker-failure.js.headers": [ + "6604450991a122e3e241e40b1b9e0516c525389d", + "support" + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/sharedworker-failure.js": [ "8472318abd53207ec56b3f5988fb0a49d0c006a4", "support" ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/sharedworker-failure.js.headers": [ + "6604450991a122e3e241e40b1b9e0516c525389d", + "support" + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/test-incrementer.js": [ "2bdd2bae66e178680c2604826ed27d6818c47334", "support" @@ -429890,10 +431008,14 @@ "6d6efda00db263f7ba86f80ad94744a0777f6ea9", "support" ], - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-history.html": [ + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-history.https.html": [ "49d341f47f9bfebe37a78876ae1367766793c5c2", "testharness" ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-history.https.html.headers": [ + "63b60e490f47f4db77d33d7a4ca2f5b9a4181de8", + "support" + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-idb.any.js": [ "4eb25eb85467fd3e9b9a41b251a8df825608838b", "testharness" @@ -429902,18 +431024,30 @@ "2c3fb7be034b0c315c4add66790bcfed30bcecc7", "testharness" ], - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-success.sub.html": [ + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-success.https.sub.html": [ "9205d01df26e3274692f48aa76d7ffceba9e51ac", "testharness" ], - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel-success.html": [ + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-success.https.sub.html.headers": [ + "63b60e490f47f4db77d33d7a4ca2f5b9a4181de8", + "support" + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel-success.https.html": [ "98145310f610f0ca88af938872e9ea2103de600c", "testharness" ], - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-messagechannel-success.html": [ + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel-success.https.html.headers": [ + "63b60e490f47f4db77d33d7a4ca2f5b9a4181de8", + "support" + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-messagechannel-success.https.html": [ "cd67e5b2c9553a9172959c1ba7df5b96b7091a33", "testharness" ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-messagechannel-success.https.html.headers": [ + "63b60e490f47f4db77d33d7a4ca2f5b9a4181de8", + "support" + ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-serviceworker-failure.https-expected.txt": [ "8ddfd2537eae9cba1f7a8d505ec5dd8df3b2bd7f", "support" @@ -429922,18 +431056,34 @@ "ff7449a931775116d51f0d016194c14b84ecc466", "testharness" ], - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-sharedworker-failure.html": [ + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-serviceworker-failure.https.html.headers": [ + "63b60e490f47f4db77d33d7a4ca2f5b9a4181de8", + "support" + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-sharedworker-failure.https.html": [ "023cb5acdef1c144dbad4ebefd0af23fc6c17d79", "testharness" ], - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-similar-but-cross-origin-success.sub.html": [ + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-sharedworker-failure.https.html.headers": [ + "63b60e490f47f4db77d33d7a4ca2f5b9a4181de8", + "support" + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-similar-but-cross-origin-success.https.sub.html": [ "e25fc9002d02d3c1177447012fcfc9f77381bda7", "testharness" ], - "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-simple-success.html": [ + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-similar-but-cross-origin-success.https.sub.html.headers": [ + "63b60e490f47f4db77d33d7a4ca2f5b9a4181de8", + "support" + ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-simple-success.https.html": [ "4b86f9befa6a04c03211a7f30e9cb2d1a63ad06d", "testharness" ], + "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-simple-success.https.html.headers": [ + "63b60e490f47f4db77d33d7a4ca2f5b9a4181de8", + "support" + ], "html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window-expected.txt": [ "d86c1db7d01d34ca2bc784ea7afafcee08508890", "support" @@ -443219,7 +444369,7 @@ "support" ], "interfaces/speech-api.idl": [ - "6278d171cd4e619df14e6b04cbc9499f41835ba4", + "2ed9c2ce8b81756091267843bbe55708c6ecc86c", "support" ], "interfaces/storage.idl": [ @@ -443275,7 +444425,7 @@ "support" ], "interfaces/web-nfc.idl": [ - "13afc27663da2f3deb9c939032836073d49f83e9", + "f082a1e8952cbe6cad0e7e67fa8e7486135f90ba", "support" ], "interfaces/web-share.idl": [ @@ -443327,7 +444477,7 @@ "support" ], "interfaces/webxr.idl": [ - "2c9eac510672513e611f565fc31d2c7d8a3820da", + "ec4b76d9ba819527257e251fd52777dfa7cc415a", "support" ], "interfaces/worklets.idl": [ @@ -444295,11 +445445,11 @@ "reftest" ], "mathml/presentation-markup/fractions/frac-parameters-1.html": [ - "b8bc405107bd643519fef9e0fb0dba1ba0a66762", + "ba47897c111b33f439fe9fde2e2ecb707c7b5585", "testharness" ], "mathml/presentation-markup/fractions/frac-parameters-2.html": [ - "ce2d299f281b639c1e4026caa9354a8bc8c5298d", + "9c363866de08ab15202cab10e014a25fdd7e2f0d", "testharness" ], "mathml/presentation-markup/fractions/frac-parameters-gap-001-ref.html": [ @@ -444770,6 +445920,10 @@ "fa8bea41f470bbe83441bdea2693cd16b9b01320", "reftest" ], + "mathml/relations/css-styling/not-participating-to-parent-layout.html": [ + "89389fc668234cc46bb58e33a099b2c04cc675b5", + "testharness" + ], "mathml/relations/css-styling/padding-border-margin/border-001.html": [ "784491cf2e1bf60ea7c9edc951b9252d903d592f", "testharness" @@ -444866,6 +446020,10 @@ "8d6515af9f97279e6c0ab036409f7f5a31757e8a", "testharness" ], + "mathml/relations/html5-tree/clipboard-event-handlers.tentative.html": [ + "d293b1500c77dd289381619d658ad5761316b9cf", + "testharness" + ], "mathml/relations/html5-tree/color-attributes-1-ref.html": [ "71ee8cea9db15b3c6359788aa95efd6b825def81", "support" @@ -444874,6 +446032,10 @@ "585aebaf393d85187b644a97f6e7f28535fa9095", "reftest" ], + "mathml/relations/html5-tree/css-inline-style-interface.tentative.html": [ + "708926413f2aff21c4972a3f0ab19c692b81bbc7", + "testharness" + ], "mathml/relations/html5-tree/display-1.html": [ "9ecd45f9a4087e41a98546d1afb6faca9d396403", "testharness" @@ -444906,6 +446068,10 @@ "a8475ea3ff801dfdb6f4d6d5a7e049a6eafe7c00", "testharness" ], + "mathml/relations/html5-tree/html-or-foreign-element-interfaces.tentative.html": [ + "1fcaf6c40167a5eeb55dcc62de14e50224998994", + "testharness" + ], "mathml/relations/html5-tree/integration-point-1-ref.html": [ "49877549670ae9fdd81e24801c74756465c4c595", "support" @@ -444934,6 +446100,10 @@ "7121db645b2761f999c9492a44601d54531d6170", "testharness" ], + "mathml/relations/html5-tree/math-global-event-handlers.tentative.html": [ + "92e18639dff0d10949143bba2c7c403e48fdbe1c", + "testharness" + ], "mathml/relations/html5-tree/required-extensions-2-ref.html": [ "dcc5b2b7d337e769299df17a0eacafddc92665c6", "support" @@ -444983,7 +446153,7 @@ "support" ], "mathml/support/box-comparison.js": [ - "77d145b36324d1ac4f06b97a49f8609d6202c9bc", + "c46808f7fee6f72ec9e7ffd4946239d9dcaad25b", "support" ], "mathml/support/feature-detection.js": [ @@ -444991,11 +446161,11 @@ "support" ], "mathml/support/layout-comparison.js": [ - "b1a68995178410d3d0181b9981a0a2ab602ff3b2", + "f9111d02ee31871f68e2793c684258b826fd4e3d", "support" ], "mathml/support/mathml-fragments.js": [ - "013171cf8c2af515d69d60d58795dedcd75780bd", + "7c7b003e9e683a2770520eeb82a42a0dd1307c9f", "support" ], "mathml/tools/axisheight.py": [ @@ -445003,7 +446173,7 @@ "support" ], "mathml/tools/fractions.py": [ - "8652806b2971b90293e5586c3f40b12d79a70fb2", + "42cfe468219ce658cfe3943cd78e38ce70a9cdc7", "support" ], "mathml/tools/largeop.py": [ @@ -445035,7 +446205,7 @@ "support" ], "mathml/tools/stacks.py": [ - "81f79befb69082fd0a4a26ebc9ed9283662c11b9", + "18626291336352157b8b450dfaac77caf37cfd89", "support" ], "mathml/tools/stretchstacks.py": [ @@ -457275,7 +458445,7 @@ "testharness" ], "pointerevents/pointerevent_sequence_at_implicit_release_on_drag.html": [ - "9b1de2270e4eb7e35d1ff1054a0a5dddf677da5b", + "52f9e439a4b7d1529456ba47d5905656afa245d7", "testharness" ], "pointerevents/pointerevent_setpointercapture_disconnected.html": [ @@ -457311,7 +458481,7 @@ "testharness" ], "pointerevents/pointerevent_touch-action-auto-css_touch.html": [ - "e995ccd5d6e1d4c23a3df075208d794f2b66edbe", + "c486d77c1119128d7ad87c5c83aea43ebfe379e7", "testharness" ], "pointerevents/pointerevent_touch-action-button-none-test_touch.html": [ @@ -457327,11 +458497,11 @@ "testharness" ], "pointerevents/pointerevent_touch-action-inherit_child-none_touch.html": [ - "4f9e75d3ce5524e6251b29876b801eb9fd132034", + "dc234cbef3d87373ad0bf4277b94f6f021f9a9e6", "testharness" ], "pointerevents/pointerevent_touch-action-inherit_child-pan-x-child-pan-x_touch.html": [ - "62fc8c22c0712135235c3d3a5e6c9e1c73ed3641", + "c2f4bd35aebbb67194f4cc17d3d52709d63f732a", "testharness" ], "pointerevents/pointerevent_touch-action-inherit_child-pan-x-child-pan-y_touch.html": [ @@ -457339,11 +458509,11 @@ "testharness" ], "pointerevents/pointerevent_touch-action-inherit_highest-parent-none_touch.html": [ - "a1fefe16982316546b2cb0a7bf14362fe21f7145", + "3ec5998b54d1677dee7dc15b6a6c5cec1750a55d", "testharness" ], "pointerevents/pointerevent_touch-action-inherit_parent-none_touch.html": [ - "d525fe6ccd16c9ff1de275b845441617d0b3a3fc", + "04db243676fd2f454421d10b6a7e6a1cef4e3e04", "testharness" ], "pointerevents/pointerevent_touch-action-keyboard.html": [ @@ -457355,23 +458525,23 @@ "manual" ], "pointerevents/pointerevent_touch-action-none-css_touch.html": [ - "5e963abfe0ff9519dea3286012374c1721c9acbc", + "2ff161a915c95d1c14916fede40ca76439813cc9", "testharness" ], "pointerevents/pointerevent_touch-action-pan-x-css_touch.html": [ - "ebdc180792ce7b529ae7c168679d53c909b5e817", + "d2b147da0a0157bb29c50b32185d51b65be23c45", "testharness" ], "pointerevents/pointerevent_touch-action-pan-x-pan-y-pan-y_touch.html": [ - "ef59c9951cdfd7ffcde73ebe223a8d35f5893da4", + "e081cacbe427524d915083dbfb124f197ab551c8", "testharness" ], "pointerevents/pointerevent_touch-action-pan-x-pan-y_touch.html": [ - "0c88054379538b4287c9157124f68b9cbff82234", + "b80035c98dfb84d568a913a75872419c1fe9e6a6", "testharness" ], "pointerevents/pointerevent_touch-action-pan-y-css_touch.html": [ - "b6444ede33472509421e9e55f06eb0f9c6284bb8", + "adf502f1d8e0b3d856ea34f968b75e70428efca7", "testharness" ], "pointerevents/pointerevent_touch-action-rotated-divs_touch-manual.html": [ @@ -457399,7 +458569,7 @@ "testharness" ], "pointerevents/pointerlock/pointerevent_movementxy.html": [ - "2d6147dae562af7efadacee9dfb44cc080005742", + "260ef4829cba212e77ad487f8e82d69d9e9e8e73", "testharness" ], "pointerevents/pointerlock/pointerevent_movementxy_with_pointerlock.html": [ @@ -457471,7 +458641,7 @@ "testharness" ], "pointerlock/movementX_Y_basic.html": [ - "b09d896ecfb90eea17c294c77582ba53b07283da", + "a317130190ae46a59b89d63ac2c9717c12a8fbc5", "testharness" ], "pointerlock/movementX_Y_no-jumps-manual.html": [ @@ -467946,6 +469116,10 @@ "82c8165c34f3df1366bf49099aa5d75b79c59e7e", "support" ], + "resources/SVGAnimationTestCase-testharness.js": [ + "59febda86d63f3109e74901620d1c1562554c754", + "support" + ], "resources/check-layout-th.js": [ "928b0cf2a1041ecb831fadb44943e8907a29b872", "support" @@ -472111,11 +473285,11 @@ "testharness" ], "service-workers/service-worker/worker-interception.https-expected.txt": [ - "f123296d75fdc547132e9e6808403d427d4425fd", + "4619031b155e7823885850da9c8b0b195e6af136", "support" ], "service-workers/service-worker/worker-interception.https.html": [ - "302a214ac619400c38f7564c065a5e0be47ac6df", + "204638a44afffda47c39d1e0fed7d9a3cf3972fc", "testharness" ], "service-workers/service-worker/xhr-response-url.https.html": [ @@ -474466,6 +475640,246 @@ "86a0a40fa2de116c5b2076641180b24688d56f9b", "testharness" ], + "svg/animations/svgenum-animation-3.html": [ + "5ed9f5aa8819510f8a7701e5edb7d00fb716aa70", + "testharness" + ], + "svg/animations/svgenum-animation-4.html": [ + "652e49655e1027ce7a6a8c3d6ad29d76eb6fc85b", + "testharness" + ], + "svg/animations/svgenum-animation-5.html": [ + "1487918bde23a642fd5a49de844b5e880d662f27", + "testharness" + ], + "svg/animations/svgenum-animation-6.html": [ + "e60c93bbbf67cbfbe0bfe7a7f655ac3cb2feb44e", + "testharness" + ], + "svg/animations/svgenum-animation-7.html": [ + "4e2d27e581c687106d3056f825ad11b2efaefdd4", + "testharness" + ], + "svg/animations/svgenum-animation-8.html": [ + "cd00e46d56d7133b565adebad45aa4efe341313f", + "testharness" + ], + "svg/animations/svgenum-animation-9.html": [ + "8aa9d6a761803b726c4de7f8a6eee1df31c2a55c", + "testharness" + ], + "svg/animations/svginteger-animation-1.html": [ + "7803541691858ddf64f63c7486ad369254572220", + "testharness" + ], + "svg/animations/svginteger-animation-2.html": [ + "25ef7ff08effb49c9953981756d482846b590aaf", + "testharness" + ], + "svg/animations/svglength-additive-by-1.html": [ + "67549890cff56769c3df9973266b76e128f90c6d", + "testharness" + ], + "svg/animations/svglength-additive-by-2.html": [ + "e08c99cb63eebf462bcd037ad0219145b291aa9f", + "testharness" + ], + "svg/animations/svglength-additive-by-3.html": [ + "b5ac7a033ec2524e9bd8119227dcc88f63924254", + "testharness" + ], + "svg/animations/svglength-additive-by-4.html": [ + "10e8bd7b491a9083141dd4d260db951046096fe2", + "testharness" + ], + "svg/animations/svglength-additive-by-6.html": [ + "43beafe220e4c02d312da9fe4a653054d40d3d0d", + "testharness" + ], + "svg/animations/svglength-additive-by-7.html": [ + "7c1dde4a7c6262d64130ef84e4fa0b05b360b154", + "testharness" + ], + "svg/animations/svglength-additive-by-8.html": [ + "c61cb65ebd923f82d3c44ae00328e4712d214019", + "testharness" + ], + "svg/animations/svglength-additive-from-by-1.html": [ + "ce458e0266c68665a68adab94aa706ed4ccb4a84", + "testharness" + ], + "svg/animations/svglength-additive-from-by-2.html": [ + "1ac7eed4e1b3d03b5b44dde6fad6209f21ab0aa4", + "testharness" + ], + "svg/animations/svglength-additive-from-by-3.html": [ + "1c22f351da43b6723a360706c23ed6f351844e70", + "testharness" + ], + "svg/animations/svglength-additive-from-by-4.html": [ + "998c37458f98538333395d74e1f89a21ac7f0548", + "testharness" + ], + "svg/animations/svglength-animation-LengthModeHeight.html": [ + "2bb409e8e10ea7ba72fdf882e8c7a300e822c1ce", + "testharness" + ], + "svg/animations/svglength-animation-LengthModeOther.html": [ + "1fd9e0a3b9b0f2093f35769dc91a1badea5b4a86", + "testharness" + ], + "svg/animations/svglength-animation-LengthModeWidth.html": [ + "9481d434b9a11f8f2753497924a762a5c1e95662", + "testharness" + ], + "svg/animations/svglength-animation-invalid-value-1.html": [ + "9b45c5a8ca0dd1fec4aad07c02e6bbc7caad0a3a", + "testharness" + ], + "svg/animations/svglength-animation-invalid-value-2.html": [ + "64d5884df44bc1334da2750b0c23ce52e0ad5028", + "testharness" + ], + "svg/animations/svglength-animation-invalid-value-3.html": [ + "0fb1794eaa2c738e17ba42a63c478d877e52de29", + "testharness" + ], + "svg/animations/svglength-animation-number-to-number.html": [ + "0b4fca52ec0f878023ce6ba62fcde0e7426bbc8d", + "testharness" + ], + "svg/animations/svglength-animation-px-to-cm.html": [ + "f51beed02b3df9382df78d5ba211c9555bfd5d87", + "testharness" + ], + "svg/animations/svglength-animation-px-to-ems.html": [ + "e65125303e10d3572cc53abef54d8cad4a781df2", + "testharness" + ], + "svg/animations/svglength-animation-px-to-in.html": [ + "a55b357187aa01dc9eaace04a89eb17cd2ad6557", + "testharness" + ], + "svg/animations/svglength-animation-px-to-number.html": [ + "8eab444caa3eda56eda3f5600f5f031d68b8d60e", + "testharness" + ], + "svg/animations/svglength-animation-px-to-pc.html": [ + "62d9d9964f1dc9a1952cf45417572fc6a13a99cc", + "testharness" + ], + "svg/animations/svglength-animation-px-to-pt.html": [ + "d86e09075788d37c05f418252686fe3d8c56b87a", + "testharness" + ], + "svg/animations/svglength-animation-px-to-px.html": [ + "fdeb773375a290d6f925d42be90dd0401222947f", + "testharness" + ], + "svg/animations/svglength-animation-unitType.html": [ + "4cd6d2d3af5e94e259195cc1d5599132dd8a69b6", + "testharness" + ], + "svg/animations/svglength-animation-values.html": [ + "a3e485320b0e76b9e6cc5c176c4e114d939f56bb", + "testharness" + ], + "svg/animations/svglengthlist-animation-1.html": [ + "198fc8a6fef879ea9397f6668b38a10a9b4d755a", + "testharness" + ], + "svg/animations/svglengthlist-animation-2.html": [ + "c1c91b83f0f652d3d04e277c3a13d116af291147", + "testharness" + ], + "svg/animations/svglengthlist-animation-3.html": [ + "d26e67a8a05a049378bda86cc15ff2e5dbedc2fa", + "testharness" + ], + "svg/animations/svglengthlist-animation-4.html": [ + "0e890ab5f5a16e53ce10a3f7c68e99a25e764989", + "testharness" + ], + "svg/animations/svglengthlist-animation-5.html": [ + "5d0bc2b4836fcc934b4676eb1d79e23e15b5e148", + "testharness" + ], + "svg/animations/svgnumber-animation-1.html": [ + "72c2d736771868b615d723958324307a6f96be66", + "testharness" + ], + "svg/animations/svgnumber-animation-2.html": [ + "1654480ffced7d79bf28595664bc6dc8d524ba07", + "testharness" + ], + "svg/animations/svgnumber-animation-3.html": [ + "255eeb0a94c66f6337af8079f6eef8e6416586e4", + "testharness" + ], + "svg/animations/svgnumber-animation-4.html": [ + "758138d6678a2afa778c766b9072e47307e5341d", + "testharness" + ], + "svg/animations/svgnumberlist-animation-1.html": [ + "aabb7d7daa159409706ad2ff59e54220218f25a2", + "testharness" + ], + "svg/animations/svgnumberlist-animation-2.html": [ + "e62bbf68602dbe439b2659aac3727f8f6c40e2d0", + "testharness" + ], + "svg/animations/svgnumberoptionalnumber-animation-1.html": [ + "b20855140ffcd398778d3375aa9ac395aa221776", + "testharness" + ], + "svg/animations/svgnumberoptionalnumber-animation-2.html": [ + "db2576533ce22a0a4aa68d8113ae858bf1cf17aa", + "testharness" + ], + "svg/animations/svgnumberoptionalnumber-animation-3.html": [ + "974c1d7034a86e585c84cf9576fb231db7601fc3", + "testharness" + ], + "svg/animations/svgnumberoptionalnumber-animation-4.html": [ + "4c734b5373762e9844511f5ac7b550743a50f0b2", + "testharness" + ], + "svg/animations/svgpath-animation-1.html": [ + "220130532e9fbd223e0ed8b02e1771a06229e3bf", + "testharness" + ], + "svg/animations/svgpointlist-animation-1.html": [ + "a3340ba83a2a0f6846d0a9e7faa1c27dd49a1383", + "testharness" + ], + "svg/animations/svgpointlist-animation-2.html": [ + "e0819cd519c7e0a6a05bdd8e6cfa0991433f0f99", + "testharness" + ], + "svg/animations/svgrect-animation-1.html": [ + "d13ccff418ff36c3f928e45aa14766a0d041e988", + "testharness" + ], + "svg/animations/svgrect-animation-2.html": [ + "86f5368a3adfa4e40e84327f9170a74c231d0b03", + "testharness" + ], + "svg/animations/svgstring-animation-1.html": [ + "259dfbd27a0a1f203dd3faf6feaad106d782a2b0", + "testharness" + ], + "svg/animations/svgstring-animation-fallback-to-discrete.html": [ + "8cf6c34af0d4af11e4fa89a9d495936bda0cbfa9", + "testharness" + ], + "svg/animations/svgtransform-animation-1.html": [ + "618ba9a31c00bf2ff56bf842ad1ec40fdbfc73fa", + "testharness" + ], + "svg/animations/svgtransform-animation-discrete.html": [ + "17b78a2787d0becf64b90136fcf0f6f966404baa", + "testharness" + ], "svg/coordinate-systems/abspos.html": [ "fb37bbe7f3ae4a61d1c216970c8a263673aed0dc", "reftest" @@ -475054,10 +476468,6 @@ "1feb867c3ab9e83f96e0566b53c75aa3dccb0653", "testharness" ], - "svg/painting/parsing/fill-opacity-computed-expected.txt": [ - "aaf3a6e7b141b355f8c97eda6c80e385f542fa0f", - "support" - ], "svg/painting/parsing/fill-opacity-computed.svg": [ "16843bcceecbbd1833a8c70ad35ee3a33903d4ae", "testharness" @@ -475066,10 +476476,6 @@ "86726c6ad088a52e7f80f19cb11c9ab04571764f", "testharness" ], - "svg/painting/parsing/fill-opacity-valid-expected.txt": [ - "a93f1ba9f39e09ab59a0972c392cb46d3adb9aae", - "support" - ], "svg/painting/parsing/fill-opacity-valid.svg": [ "90d2732b1854785585f2edbb61de1195054c0b7a", "testharness" @@ -475262,10 +476668,6 @@ "36fd81d29cdf22ca8be540f7d58ac9d4273b1177", "testharness" ], - "svg/painting/parsing/stroke-opacity-computed-expected.txt": [ - "ebc7606d4f8fe580c9ab0d521c9680600789823c", - "support" - ], "svg/painting/parsing/stroke-opacity-computed.svg": [ "df58a213ff50835181f1e74eb608aa5aabcbeacb", "testharness" @@ -475274,10 +476676,6 @@ "af1a954b47491b53fb84881da0dd40e0b40b047d", "testharness" ], - "svg/painting/parsing/stroke-opacity-valid-expected.txt": [ - "21f5a3f85517ddfc633ea41e800c98a0f8a5c44a", - "support" - ], "svg/painting/parsing/stroke-opacity-valid.svg": [ "a333363e3834ab594a3b7cb7a6839d230f327ba2", "testharness" @@ -475482,10 +476880,6 @@ "b05a69f10b9e3614f7a588998ea06879df437da7", "testharness" ], - "svg/pservers/parsing/stop-opacity-computed-expected.txt": [ - "7cc6d1c0d3acb0a94c40c7e4eef4e25c3c3cb2a1", - "support" - ], "svg/pservers/parsing/stop-opacity-computed.svg": [ "1ad1e98c5a84ebad5e0129164e0d5616b72e36fc", "testharness" @@ -475494,10 +476888,6 @@ "eae9343d1472c215dc237f1dbd1c8e15bc50708b", "testharness" ], - "svg/pservers/parsing/stop-opacity-valid-expected.txt": [ - "b8e8d535f06ade29aec919ff70bfc97838112d1d", - "support" - ], "svg/pservers/parsing/stop-opacity-valid.svg": [ "28b60038a4d5707ae45b5e6e7dbc7f806717eaf9", "testharness" @@ -476602,10 +477992,22 @@ "e60b4ea6a3a1c909c715fb7248a6f1b0cc6e9d4e", "support" ], + "tools/docker/__init__.py": [ + "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + "support" + ], + "tools/docker/commands.json": [ + "15182cc9e6531d5a5ba3d42c9f00821946c5e8a3", + "support" + ], "tools/docker/documentation/Dockerfile": [ "e01f98e4d4df0e7f7501bb5d7057d1d528221bde", "support" ], + "tools/docker/frontend.py": [ + "c4a207345820d534df5cc092c8b46838a5b8ce1f", + "support" + ], "tools/docker/github/Dockerfile": [ "22d47f3e5fa9032e5f016f6f15720fa98e1ba625", "support" @@ -476615,7 +478017,7 @@ "support" ], "tools/docker/start.sh": [ - "b1ff4a7faa5ef7a3519fb8797a02557432de2c34", + "dbeeed41c149398cb12202a9e10b71e745d06d90", "support" ], "tools/gitignore/__init__.py": [ @@ -476711,7 +478113,7 @@ "support" ], "tools/pytest.ini": [ - "b52e465598ab97faa6b718859617f2194141fbb4", + "6bdb4d563f6dd5086ed3e09715187e549edf255a", "support" ], "tools/pywebsocket/CONTRIBUTING": [ @@ -480851,7 +482253,7 @@ "support" ], "tools/wpt/browser.py": [ - "6036b3dc37756fde4b8725e45525367179e9469d", + "0943ee9f3d74fa1e7542712682563f0badfea54d", "support" ], "tools/wpt/commands.json": [ @@ -480863,7 +482265,7 @@ "support" ], "tools/wpt/install.py": [ - "b107752d81b6fd6ae6bd70bc330e8575aa3d7822", + "8215dfe09161ad49ba3975e1eacc927c61715acf", "support" ], "tools/wpt/markdown.py": [ @@ -480871,7 +482273,7 @@ "support" ], "tools/wpt/paths": [ - "4528222fbf56e40ac8db2342553bf889fe7e4a53", + "093a71568920a944b0b8361165f5ea5fa002ee14", "support" ], "tools/wpt/requirements.txt": [ @@ -480879,7 +482281,7 @@ "support" ], "tools/wpt/run.py": [ - "ae33d1b0223ffa5ae0ca305d7156bbc48c1cc39e", + "617ea7282b893fc17e8a794191f3223911d63dde", "support" ], "tools/wpt/testfiles.py": [ @@ -481003,7 +482405,7 @@ "support" ], "tools/wptrunner/wptrunner/browsers/chrome_android.py": [ - "b7d553c78a2af4826fced07d3bf420609339cd4d", + "b8ebedef0487d267c0da59b488d159c776319316", "support" ], "tools/wptrunner/wptrunner/browsers/chrome_ios.py": [ @@ -481371,7 +482773,7 @@ "support" ], "tools/wptserve/README.md": [ - "30a7dccc93ef197d51e3ce99eb78c2e114d1653e", + "6821dee38a498a472cf71861ac25a8cda12e17aa", "support" ], "tools/wptserve/setup.py": [ @@ -482459,7 +483861,7 @@ "support" ], "url/resources/setters_tests.json": [ - "db23d9247328009772b3cdc9eb161f9787304857", + "0b4f6b67387c22879b1f2a03ed4d5d3c1d440d26", "support" ], "url/resources/toascii.json": [ @@ -483647,7 +485049,7 @@ "testharness" ], "web-animations/interfaces/DocumentTimeline/constructor.html": [ - "e4714be02f8e31aa3663f372ab04c8a466226058", + "ca0997ac8f9012b7d019760be97e09fa0f837179", "testharness" ], "web-animations/interfaces/DocumentTimeline/idlharness.window.js": [ @@ -483738,6 +485140,10 @@ "971e82ed81d6fef46a65f11ec66331a9f1954dfc", "support" ], + "web-animations/resources/timing-override.js": [ + "a1d65030f02ba6973efaf4d73839e86803291f47", + "support" + ], "web-animations/resources/timing-tests.js": [ "4b0f021f74e09f6cbde5e27fc7cb8240b7bd9788", "support" @@ -483783,7 +485189,7 @@ "testharness" ], "web-animations/timing-model/animations/finishing-an-animation.html": [ - "cb824ae30ed16ef92138fee23a9939e2b3013832", + "779bee184b8dbde227db6ae72dc7ff83a79c4176", "testharness" ], "web-animations/timing-model/animations/pausing-an-animation-expected.txt": [ @@ -483827,7 +485233,7 @@ "support" ], "web-animations/timing-model/animations/setting-the-start-time-of-an-animation.html": [ - "454a294239aa61130dc56af910fe1aa8faf4900b", + "a1727994bdb9b8da10bfdd36baa3d8e0ccc4ef1d", "testharness" ], "web-animations/timing-model/animations/setting-the-target-effect-of-an-animation-expected.txt": [ @@ -483847,7 +485253,7 @@ "testharness" ], "web-animations/timing-model/animations/the-current-time-of-an-animation.html": [ - "a0e1a111fd433761afc25486fe4fb23c0ef1164b", + "77a6b716d22062998529b58382e0205e6f017980", "testharness" ], "web-animations/timing-model/animations/updating-the-finished-state.html": [ @@ -483859,7 +485265,7 @@ "testharness" ], "web-animations/timing-model/timelines/document-timelines.html": [ - "4023bba55612b689d98a9773c9c6fafe11408e2b", + "f45865ac7c0e37abeddee73ad5435dcc8acd6e89", "testharness" ], "web-animations/timing-model/timelines/timelines.html": [ @@ -484674,6 +486080,10 @@ "bbda190f099e4e08c686bb7d2b063e753ba0f606", "support" ], + "webaudio/the-audio-api/the-audioparam-interface/set-target-conv.html": [ + "2ed076cccf758caaec1c381e89254b10ff7cd7d5", + "testharness" + ], "webaudio/the-audio-api/the-audioparam-interface/setTargetAtTime-after-event-within-block.html": [ "827aeeabd47962ca52ff187f770cce3deb58d077", "testharness" @@ -487126,8 +488536,8 @@ "2fd33ca541148ca6a7be5f5624e303795c7c458d", "testharness" ], - "webrtc/RTCPeerConnection-onicecandidateerror.html": [ - "e06c219483eee479d3b4afe8c470c8d63953132c", + "webrtc/RTCPeerConnection-onicecandidateerror.https.html": [ + "1bbb30bd575794ea5bb12bc192262a4127a6c308", "testharness" ], "webrtc/RTCPeerConnection-onnegotiationneeded.html": [ @@ -492235,7 +493645,7 @@ "testharness" ], "webxr/idlharness.https.window-expected.txt": [ - "b4ff722b1266759a41ff67988007d745067989cc", + "e95d78844f2ec8abf33d21ba172881556b9d45e9", "support" ], "webxr/idlharness.https.window.js": [
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/adjoining-float-new-fc-crash.html b/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/adjoining-float-new-fc-crash.html new file mode 100644 index 0000000..b220a484 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/adjoining-float-new-fc-crash.html
@@ -0,0 +1,16 @@ +<!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=987004"> +<meta name="assert" content="The renderer should not crash."> +<div style="width: 100px; overflow: hidden;"> + <div style="float: left; width: 100%; height: 20px; background: hotpink;"></div> + <div style="clear: both;"> + <span style="position: absolute; width: 10px; height: 10px; background: orange;"></span> + <div style="height: 10px; background: green; overflow: hidden;"></div> + </div> +</div> +<script> +test(() => { +}, 'Test passes if the renderer does not crash.'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/opacity-valid-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/opacity-valid-expected.txt deleted file mode 100644 index 46291416..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/opacity-valid-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -This is a testharness.js-based test. -PASS e.style['opacity'] = "1" should set the property value -PASS e.style['opacity'] = "0.5" should set the property value -PASS e.style['opacity'] = "0" should set the property value -PASS e.style['opacity'] = "-2" should set the property value -PASS e.style['opacity'] = "3" should set the property value -FAIL e.style['opacity'] = "-100%" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['opacity'] = "50%" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['opacity'] = "300%" 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-grid/animation/grid-template-columns-interpolation-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-grid/animation/grid-template-columns-interpolation-expected.txt index b0a28bc..9b5f81d1 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/animation/grid-template-columns-interpolation-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/animation/grid-template-columns-interpolation-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 119 tests; 87 PASS, 32 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 119 tests; 91 PASS, 28 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS "1fr 1fr 1fr" and "2fr 2fr" are valid grid-template-columns values PASS Animation between "1fr 1fr 1fr" and "2fr 2fr" at progress -1 PASS Animation between "1fr 1fr 1fr" and "2fr 2fr" at progress 0 @@ -85,12 +85,12 @@ PASS Animation between "1fr repeat(2, 2fr 30px) 1fr" and "2fr repeat(3, 3fr 40px) 2fr" at progress 1 PASS Animation between "1fr repeat(2, 2fr 30px) 1fr" and "2fr repeat(3, 3fr 40px) 2fr" at progress 2 PASS "repeat(2, 2fr 30px)" and "repeat(4, 40px)" are valid grid-template-columns values -FAIL Animation between "repeat(2, 2fr 30px)" and "repeat(4, 40px)" at progress -1 assert_equals: expected "2fr 20px 2fr 20px" but got "2fr 30px 2fr 30px" +PASS Animation between "repeat(2, 2fr 30px)" and "repeat(4, 40px)" at progress -1 PASS Animation between "repeat(2, 2fr 30px)" and "repeat(4, 40px)" at progress 0 -FAIL Animation between "repeat(2, 2fr 30px)" and "repeat(4, 40px)" at progress 0.4 assert_equals: expected "2fr 34px 2fr 34px" but got "2fr 30px 2fr 30px" -FAIL Animation between "repeat(2, 2fr 30px)" and "repeat(4, 40px)" at progress 0.6 assert_equals: expected "40px 36px 40px 36px" but got "40px 40px 40px 40px" +PASS Animation between "repeat(2, 2fr 30px)" and "repeat(4, 40px)" at progress 0.4 +PASS Animation between "repeat(2, 2fr 30px)" and "repeat(4, 40px)" at progress 0.6 PASS Animation between "repeat(2, 2fr 30px)" and "repeat(4, 40px)" at progress 1 -FAIL Animation between "repeat(2, 2fr 30px)" and "repeat(4, 40px)" at progress 2 assert_equals: expected "40px 50px 40px 50px" but got "40px 40px 40px 40px" +PASS Animation between "repeat(2, 2fr 30px)" and "repeat(4, 40px)" at progress 2 PASS "1fr repeat(2, 2fr auto 30px) 1fr" and "2fr repeat(2, 3fr 30px 40px) 2fr" are valid grid-template-columns values FAIL Animation between "1fr repeat(2, 2fr auto 30px) 1fr" and "2fr repeat(2, 3fr 30px 40px) 2fr" at progress -1 assert_equals: expected "0fr 1fr auto 20px 1fr auto 20px 0fr" but got "1fr 2fr auto 30px 2fr auto 30px 1fr" PASS Animation between "1fr repeat(2, 2fr auto 30px) 1fr" and "2fr repeat(2, 3fr 30px 40px) 2fr" at progress 0
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/animation/grid-template-columns-interpolation.html b/third_party/blink/web_tests/external/wpt/css/css-grid/animation/grid-template-columns-interpolation.html index e42a424..5da3dea 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/animation/grid-template-columns-interpolation.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/animation/grid-template-columns-interpolation.html
@@ -118,6 +118,7 @@ ]); // Exercise <track-list> (with <track-repeat>) + // https://drafts.csswg.org/css-grid/#repeat-interpolation test_no_interpolation({ property: 'grid-template-columns', from: "1fr repeat(2, 2fr 30px) 1fr", @@ -130,18 +131,11 @@ to: "2fr repeat(3, 3fr 40px) 2fr" }); - test_interpolation({ + test_no_interpolation({ property: 'grid-template-columns', from: "repeat(2, 2fr 30px)", to: "repeat(4, 40px)" - }, [ - {at: -1, expect: "2fr 20px 2fr 20px"}, - {at: 0, expect: "repeat(2, 2fr 30px)"}, - {at: 0.4, expect: "2fr 34px 2fr 34px"}, - {at: 0.6, expect: "40px 36px 40px 36px"}, - {at: 1, expect: "repeat(4, 40px)"}, - {at: 2, expect: "40px 50px 40px 50px"} - ]); + }); test_interpolation({ property: 'grid-template-columns',
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/animation/grid-template-rows-interpolation-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-grid/animation/grid-template-rows-interpolation-expected.txt index 02f20e7c..c5f662c 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/animation/grid-template-rows-interpolation-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/animation/grid-template-rows-interpolation-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 119 tests; 87 PASS, 32 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 119 tests; 91 PASS, 28 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS "1fr 1fr 1fr" and "2fr 2fr" are valid grid-template-rows values PASS Animation between "1fr 1fr 1fr" and "2fr 2fr" at progress -1 PASS Animation between "1fr 1fr 1fr" and "2fr 2fr" at progress 0 @@ -85,12 +85,12 @@ PASS Animation between "1fr repeat(2, 2fr 30px) 1fr" and "2fr repeat(3, 3fr 40px) 2fr" at progress 1 PASS Animation between "1fr repeat(2, 2fr 30px) 1fr" and "2fr repeat(3, 3fr 40px) 2fr" at progress 2 PASS "repeat(2, 2fr 30px)" and "repeat(4, 40px)" are valid grid-template-rows values -FAIL Animation between "repeat(2, 2fr 30px)" and "repeat(4, 40px)" at progress -1 assert_equals: expected "2fr 20px 2fr 20px" but got "2fr 30px 2fr 30px" +PASS Animation between "repeat(2, 2fr 30px)" and "repeat(4, 40px)" at progress -1 PASS Animation between "repeat(2, 2fr 30px)" and "repeat(4, 40px)" at progress 0 -FAIL Animation between "repeat(2, 2fr 30px)" and "repeat(4, 40px)" at progress 0.4 assert_equals: expected "2fr 34px 2fr 34px" but got "2fr 30px 2fr 30px" -FAIL Animation between "repeat(2, 2fr 30px)" and "repeat(4, 40px)" at progress 0.6 assert_equals: expected "40px 36px 40px 36px" but got "40px 40px 40px 40px" +PASS Animation between "repeat(2, 2fr 30px)" and "repeat(4, 40px)" at progress 0.4 +PASS Animation between "repeat(2, 2fr 30px)" and "repeat(4, 40px)" at progress 0.6 PASS Animation between "repeat(2, 2fr 30px)" and "repeat(4, 40px)" at progress 1 -FAIL Animation between "repeat(2, 2fr 30px)" and "repeat(4, 40px)" at progress 2 assert_equals: expected "40px 50px 40px 50px" but got "40px 40px 40px 40px" +PASS Animation between "repeat(2, 2fr 30px)" and "repeat(4, 40px)" at progress 2 PASS "1fr repeat(2, 2fr auto 30px) 1fr" and "2fr repeat(2, 3fr 30px 40px) 2fr" are valid grid-template-rows values FAIL Animation between "1fr repeat(2, 2fr auto 30px) 1fr" and "2fr repeat(2, 3fr 30px 40px) 2fr" at progress -1 assert_equals: expected "0fr 1fr auto 20px 1fr auto 20px 0fr" but got "1fr 2fr auto 30px 2fr auto 30px 1fr" PASS Animation between "1fr repeat(2, 2fr auto 30px) 1fr" and "2fr repeat(2, 3fr 30px 40px) 2fr" at progress 0
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/animation/grid-template-rows-interpolation.html b/third_party/blink/web_tests/external/wpt/css/css-grid/animation/grid-template-rows-interpolation.html index 3c650395..c1ff70c4 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/animation/grid-template-rows-interpolation.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/animation/grid-template-rows-interpolation.html
@@ -118,6 +118,7 @@ ]); // Exercise <track-list> (with <track-repeat>) + // https://drafts.csswg.org/css-grid/#repeat-interpolation test_no_interpolation({ property: 'grid-template-rows', from: "1fr repeat(2, 2fr 30px) 1fr", @@ -130,18 +131,12 @@ to: "2fr repeat(3, 3fr 40px) 2fr" }); - test_interpolation({ + // See https://github.com/w3c/csswg-drafts/issues/3503 + test_no_interpolation({ property: 'grid-template-rows', from: "repeat(2, 2fr 30px)", to: "repeat(4, 40px)" - }, [ - {at: -1, expect: "2fr 20px 2fr 20px"}, - {at: 0, expect: "repeat(2, 2fr 30px)"}, - {at: 0.4, expect: "2fr 34px 2fr 34px"}, - {at: 0.6, expect: "40px 36px 40px 36px"}, - {at: 1, expect: "repeat(4, 40px)"}, - {at: 2, expect: "40px 50px 40px 50px"} - ]); + }); test_interpolation({ property: 'grid-template-rows',
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/background-repeat-x-ref.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/background-repeat-x-ref.html new file mode 100644 index 0000000..3df0c54 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/background-repeat-x-ref.html
@@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html> +<body> +<canvas id ="canvas" width="200" height="200"></canvas> +<script> +var ctx = document.getElementById('canvas').getContext('2d'); +ctx.fillStyle = 'green'; +ctx.fillRect(0, 0, 50, 50); +ctx.fillRect(100, 0, 50, 50); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/background-repeat-x.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/background-repeat-x.https.html new file mode 100644 index 0000000..2eccfd2 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/background-repeat-x.https.html
@@ -0,0 +1,32 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<link rel="help" href="https://drafts.css-houdini.org/css-paint-api/"> +<link rel="match" href="background-repeat-x-ref.html"> +<style> +.container { + width: 200px; + height: 200px; +} +#foo { + background: paint(foo) top left/50% 50% repeat-x; +} +</style> +<script src="/common/reftest-wait.js"></script> +<script src="/common/worklet-reftest.js"></script> +<body> +<div id="foo" class="container"></div> + +<script id="code" type="text/worklet"> +registerPaint('foo', class { + paint(ctx, geom) { + ctx.fillStyle = 'green'; + ctx.fillRect(0, 0, 50, 50); + } +}); +</script> + +<script> + importWorkletAndTerminateTestAfterAsyncPaint(CSS.paintWorklet, document.getElementById('code').textContent); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-shapes/parsing/shape-image-threshold-computed-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-shapes/parsing/shape-image-threshold-computed-expected.txt deleted file mode 100644 index 8a246fc..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-shapes/parsing/shape-image-threshold-computed-expected.txt +++ /dev/null
@@ -1,9 +0,0 @@ -This is a testharness.js-based test. -PASS Property shape-image-threshold value '-7' computes to '0' -PASS Property shape-image-threshold value '0.5' computes to '0.5' -PASS Property shape-image-threshold value '12.5' computes to '1' -PASS Property shape-image-threshold value '-100%' computes to '0' -FAIL Property shape-image-threshold value '50%' computes to '0.5' assert_equals: expected "0.5" but got "0" -FAIL Property shape-image-threshold value '300%' computes to '1' assert_equals: expected "1" but got "0" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/css/css-shapes/parsing/shape-image-threshold-valid-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-shapes/parsing/shape-image-threshold-valid-expected.txt deleted file mode 100644 index b6e14a0..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-shapes/parsing/shape-image-threshold-valid-expected.txt +++ /dev/null
@@ -1,8 +0,0 @@ -This is a testharness.js-based test. -PASS e.style['shape-image-threshold'] = "12.5" should set the property value -PASS e.style['shape-image-threshold'] = "-7" should set the property value -FAIL e.style['shape-image-threshold'] = "-100%" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['shape-image-threshold'] = "50%" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['shape-image-threshold'] = "300%" 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-text/i18n/css3-text-line-break-baspglwj-001.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-001.html index 2d927ea..63677ae 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-001.html
@@ -10,13 +10,10 @@ <meta name='flags' content='dom'> <meta name="assert" content="When white-space allows wrapping, line breaking behavior defined for the WJ, ZW, and GL line-breaking classes in [UAX14] must be honored."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-002.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-002.html index e6928a51..80bc4a6 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-002.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-002.html
@@ -10,13 +10,10 @@ <meta name='flags' content='dom'> <meta name="assert" content="When white-space allows wrapping, line breaking behavior defined for the WJ, ZW, and GL line-breaking classes in [UAX14] must be honored."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa​bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa​bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa​bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa​bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa​bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-003.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-003.html index ab3de2c..09fabc6 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-003.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-003.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after each of the BA breaking space characters."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-004.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-004.html index 6ed1680b..0caffee 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-004.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-004.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after each of the BA breaking space characters."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-005.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-005.html index 2b2385ee..9d17bdaa 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-005.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-005.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after each of the BA breaking space characters."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-006.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-006.html index 4789681..0c34ed5 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-006.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-006.html
@@ -7,25 +7,24 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after each of the BA breaking space characters."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> - <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +34,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-007.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-007.html index c9f9775..b4f6d2f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-007.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-007.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after each of the BA breaking space characters."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-008.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-008.html index d19991a0..77dc7194 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-008.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-008.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after each of the BA breaking space characters."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-009.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-009.html index 6f3b4eb5..f25a575 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-009.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-009.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after each of the BA breaking space characters."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-010.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-010.html index 00b5356..28eb4c4 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-010.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-010.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after each of the BA breaking space characters."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-011.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-011.html index 821d44f..3d2144c0 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-011.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-011.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after each of the BA breaking space characters."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-012.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-012.html index 6c3b7e4..a7579397 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-012.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-012.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after each of the BA breaking space characters."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-014.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-014.html index 8400e6b..4f67b1ac 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-014.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-014.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after each of the BA breaking space characters."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-015.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-015.html index 7ea20f5a..734d237c 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-015.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-015.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after each of the BA breaking space characters."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-016.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-016.html index 20fa39a5..93df63b 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-016.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-016.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after each of the BA breaking hyphen characters."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa֊bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa֊bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa֊bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa֊bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa֊bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-017.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-017.html index 3637308..3edb77e 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-017.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-017.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after each of the BA breaking hyphen characters."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa‐bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa‐bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa‐bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa‐bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa‐bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-018.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-018.html index bf14c324..bf0f9eb2 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-018.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-018.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after each of the BA breaking hyphen characters."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa‒bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa‒bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa‒bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa‒bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa‒bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-019.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-019.html index c4981c2..3a80da0 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-019.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-019.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after each of the BA breaking hyphen characters."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa–bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa–bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa–bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa–bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa–bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-020.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-020.html index 207b5fa..26e8d14a 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-020.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-020.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-break-details'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after each of the BA visible word divider characters."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa־bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa־bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa־bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa־bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa־bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-021.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-021.html index 8638739..42fa5c32e 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-021.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-021.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-break-details'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after each of the BA visible word divider characters."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa་bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa་bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa་bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa་bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa་bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-022.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-022.html index e19905ed2..f5f2c4a 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-022.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-022.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-break-details'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after each of the BA visible word divider characters."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa፡bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa፡bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa፡bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa፡bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa፡bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-023.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-023.html index a55feb40..051dfa9 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-023.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-023.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-break-details'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after each of the BA visible word divider characters."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa៘bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa៘bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa៘bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa៘bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa៘bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-024.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-024.html index af8f134..09221092 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-024.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-024.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-break-details'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after each of the BA visible word divider characters."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa៚bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa៚bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa៚bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa៚bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa៚bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-025.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-025.html index 9bb0295..dd98230 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-025.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-025.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-break-details'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after each of the BA visible word divider characters."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa‧bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa‧bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa‧bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa‧bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa‧bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-026-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-026-expected.txt index 3fb8385..b3d3fc34 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-026-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-026-expected.txt
@@ -1,4 +1,7 @@ This is a testharness.js-based test. -FAIL assert_true: expected true got false +FAIL white-space:normal assert_true: expected true got false +FAIL white-space:pre-line assert_true: expected true got false +FAIL white-space:pre-wrap assert_true: expected true got false +FAIL white-space:break-spaces assert_true: expected true got false Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-026.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-026.html index cca4ed8..8292d41 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-026.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-026.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-break-details'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after each of the BA visible word divider characters."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-030.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-030.html index ac87067..d688ad3 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-030.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-030.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA historic word separator property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᛫bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᛫bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᛫bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᛫bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᛫bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-031.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-031.html index c9c6a3ba..d021f96 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-031.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-031.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA historic word separator property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᛬bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᛬bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᛬bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᛬bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᛬bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-032.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-032.html index b760eae..39e7d697 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-032.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-032.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA historic word separator property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᛭bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᛭bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᛭bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᛭bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᛭bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-033.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-033.html index 09a60017..95873aa 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-033.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-033.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA historic word separator property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁖bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁖bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁖bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁖bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁖bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-034.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-034.html index f67b550..4d93ef0 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-034.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-034.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA historic word separator property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁘bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁘bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁘bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁘bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁘bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-035.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-035.html index e44c44d..34f3030 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-035.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-035.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA historic word separator property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁙bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁙bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁙bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁙bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁙bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-036.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-036.html index ac358fe..e8a670e 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-036.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-036.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA historic word separator property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁚bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁚bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁚bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁚bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁚bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-037.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-037.html index 360b648..3afe27f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-037.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-037.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA historic word separator property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁛bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁛bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁛bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁛bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁛bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-038.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-038.html index 0fa6ee03..fc8c6fd8 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-038.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-038.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA historic word separator property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁝bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁝bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁝bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁝bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁝bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-039.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-039.html index e575ab4..31c4d4e 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-039.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-039.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA historic word separator property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁞bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁞bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁞bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁞bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁞bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-040.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-040.html index c249c6f..4892ae5 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-040.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-040.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA historic word separator property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸙bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸙bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸙bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸙bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸙bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-041.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-041.html index 5b245ed4..ac7a71c 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-041.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-041.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA historic word separator property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸪bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸪bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸪bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸪bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸪bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-042.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-042.html index 98004614..39130ce 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-042.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-042.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA historic word separator property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸫bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸫bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸫bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸫bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸫bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-043.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-043.html index e0c8bec..8b0fcec1 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-043.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-043.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA historic word separator property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸬bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸬bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸬bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸬bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸬bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-044.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-044.html index 4598f55..c538fb8 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-044.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-044.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA historic word separator property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸭bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸭bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸭bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸭bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸭bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-045.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-045.html index 1086d07..696ec803 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-045.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-045.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA historic word separator property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸰bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸰bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸰bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸰bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸰bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-046.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-046.html index 3588a93..29bd198 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-046.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-046.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA historic word separator property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐄀bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐄀bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐄀bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐄀bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐄀bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-047.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-047.html index 053651e..d4b675b 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-047.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-047.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA historic word separator property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐄁bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐄁bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐄁bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐄁bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐄁bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-048.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-048.html index b6ce654..649a20c 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-048.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-048.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA historic word separator property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐄂bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐄂bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐄂bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐄂bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐄂bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-049.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-049.html index 41a1f32..d7c54f1c4 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-049.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-049.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA historic word separator property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐎟bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐎟bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐎟bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐎟bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐎟bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-050.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-050.html index bb056c3..e88e3cc 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-050.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-050.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA historic word separator property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐏐bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐏐bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐏐bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐏐bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐏐bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-051.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-051.html index 4a26ea2..95129f9 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-051.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-051.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA historic word separator property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐤟bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐤟bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐤟bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐤟bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐤟bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-052.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-052.html index f9cbe6a..458d054 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-052.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-052.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA historic word separator property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𒑰bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𒑰bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𒑰bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𒑰bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𒑰bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-060.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-060.html index 2caab43c..44fa928 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-060.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-060.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA danda property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa।bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa।bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa।bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa।bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa।bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-061.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-061.html index 46452ff9..ef037bb3 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-061.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-061.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA danda property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa॥bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa॥bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa॥bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa॥bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa॥bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-062.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-062.html index 5dc418b..f746036 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-062.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-062.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA danda property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa๚bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa๚bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa๚bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa๚bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa๚bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-063.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-063.html index bfd9675..50c2692 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-063.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-063.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA danda property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa๛bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa๛bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa๛bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa๛bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa๛bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-064.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-064.html index 818489e..04aa14f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-064.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-064.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA danda property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa၊bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa၊bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa၊bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa၊bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa၊bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-065.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-065.html index eb92634..44349fed 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-065.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-065.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA danda property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa။bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa။bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa။bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa။bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa။bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-066.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-066.html index 4a53923..42fe1a0 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-066.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-066.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA danda property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᜵bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᜵bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᜵bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᜵bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᜵bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-067.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-067.html index fdc4bf2..bd3b06d 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-067.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-067.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA danda property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᜶bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᜶bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᜶bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᜶bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᜶bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-068.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-068.html index 37846df0..66fa67e28 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-068.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-068.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA danda property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa។bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa។bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa។bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa។bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa។bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-069.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-069.html index 07375fe27..869d8e1 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-069.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-069.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA danda property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa៕bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa៕bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa៕bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa៕bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa៕bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-070.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-070.html index 0ec8793..8b398da3 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-070.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-070.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA danda property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭞bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭞bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭞bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭞bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭞bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-071.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-071.html index 20bbf56..d4d44ca 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-071.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-071.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA danda property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭟bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭟bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭟bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭟bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭟bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-072.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-072.html index f08cdfd..b6beaeb 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-072.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-072.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA danda property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꣎bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꣎bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꣎bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꣎bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꣎bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-073.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-073.html index e87d141..e32b4346 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-073.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-073.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA danda property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꣏bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꣏bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꣏bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꣏bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꣏bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-074.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-074.html index db5e2bc..57b083f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-074.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-074.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA danda property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꩝bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꩝bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꩝bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꩝bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꩝bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-075.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-075.html index 67456e18..31e374a 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-075.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-075.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA danda property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꩞bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꩞bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꩞bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꩞bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꩞bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-076.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-076.html index 85a2eab..22cc6f2 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-076.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-076.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA danda property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꩟bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꩟bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꩟bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꩟bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꩟bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-077.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-077.html index 3612b03..786f520 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-077.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-077.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA danda property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩖bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩖bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩖bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩖bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩖bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-078.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-078.html index cd75ea46..a123d1b 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-078.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-078.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA danda property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩗bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩗bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩗bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩗bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩗bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-080.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-080.html index 35ed5789..ee4224a9 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-080.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-080.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The UA will break a line of text after any Unicode character with the BA tibetan property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa྅bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa྅bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa྅bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa྅bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa྅bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-081.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-081.html index 71972f0..a23a41d 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-081.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-081.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The UA will break a line of text after any Unicode character with the BA tibetan property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa༴bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa༴bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa༴bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa༴bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa༴bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-082.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-082.html index cc659314..2e95a95 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-082.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-082.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The UA will break a line of text after any Unicode character with the BA tibetan property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaཿbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaཿbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaཿbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaཿbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaཿbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-083-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-083-expected.txt index 3fb8385..b3d3fc34 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-083-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-083-expected.txt
@@ -1,4 +1,7 @@ This is a testharness.js-based test. -FAIL assert_true: expected true got false +FAIL white-space:normal assert_true: expected true got false +FAIL white-space:pre-line assert_true: expected true got false +FAIL white-space:pre-wrap assert_true: expected true got false +FAIL white-space:break-spaces assert_true: expected true got false Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-083.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-083.html index a831d4f..5d389995 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-083.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-083.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The UA will break a line of text after any Unicode character with the BA tibetan property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa޾bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa޾bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa޾bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa޾bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa޾bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-084.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-084.html index d03f82893..4cc59af 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-084.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-084.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The UA will break a line of text after any Unicode character with the BA tibetan property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa྿bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa྿bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa྿bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa྿bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa྿bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-085.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-085.html index bc4767d..81c5938 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-085.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-085.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The UA will break a line of text after any Unicode character with the BA tibetan property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa࿒bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa࿒bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa࿒bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa࿒bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa࿒bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-086.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-086.html index bc4767d..81c5938 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-086.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-086.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The UA will break a line of text after any Unicode character with the BA tibetan property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa࿒bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa࿒bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa࿒bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa࿒bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa࿒bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-090.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-090.html index ccf0ddc..42ee890 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-090.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-090.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᠄bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᠄bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᠄bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᠄bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᠄bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-091.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-091.html index bffa293e..cc52c80 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-091.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-091.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᠅bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᠅bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᠅bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᠅bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᠅bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-092.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-092.html index c7ffd75..1dfa041 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-092.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-092.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭚bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭚bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭚bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭚bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭚bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-093.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-093.html index de78a700..a7c70c559 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-093.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-093.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭛bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭛bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭛bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭛bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭛bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-094-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-094-expected.txt index 3fb8385..b3d3fc34 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-094-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-094-expected.txt
@@ -1,4 +1,7 @@ This is a testharness.js-based test. -FAIL assert_true: expected true got false +FAIL white-space:normal assert_true: expected true got false +FAIL white-space:pre-line assert_true: expected true got false +FAIL white-space:pre-wrap assert_true: expected true got false +FAIL white-space:break-spaces assert_true: expected true got false Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-094.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-094.html index c710eaf9b..a38ad72 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-094.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-094.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭜bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭜bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭜bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭜bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭜bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-095.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-095.html index 1562b02e..e0fcf33 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-095.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-095.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭝bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭝bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭝bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭝bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭝bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-096.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-096.html index 7e621b8..b5a96dbb 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-096.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-096.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭠bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭠bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭠bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭠bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᭠bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-097.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-097.html index cdb3be3..cb031c6 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-097.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-097.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᰻bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᰻bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᰻bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᰻bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᰻bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-098.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-098.html index 4760c1d..44135cf1 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-098.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-098.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᰼bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᰼bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᰼bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᰼bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᰼bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-099.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-099.html index d88d96c..5388047 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-099.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-099.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᰾bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᰾bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᰾bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᰾bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᰾bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-100.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-100.html index d88d96c..5388047 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-100.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-100.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᰾bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᰾bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᰾bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᰾bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᰾bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-101.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-101.html index 430a56d..f5f5117f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-101.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-101.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᰿bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᰿bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᰿bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᰿bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᰿bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-102.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-102.html index 716810d..7481591 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-102.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-102.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᱾bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᱾bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᱾bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᱾bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᱾bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-103.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-103.html index c17e171..3b9db36 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-103.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-103.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᱿bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᱿bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᱿bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᱿bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᱿bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-104.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-104.html index ae853d3..ec575eb 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-104.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-104.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⳺bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⳺bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⳺bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⳺bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⳺bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-105.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-105.html index 4c43f66..af3a8887 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-105.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-105.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⳻bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⳻bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⳻bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⳻bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⳻bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-106.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-106.html index 8907e579..e5203073 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-106.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-106.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⳼bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⳼bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⳼bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⳼bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⳼bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-107.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-107.html index 9d23188..eb3f70b 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-107.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-107.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⳿bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⳿bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⳿bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⳿bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⳿bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-108.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-108.html index dc9f94ce..f977eaa 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-108.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-108.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸗bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸗bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸗bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸗bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⸗bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-109.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-109.html index ef37b91..1ba489e 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-109.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-109.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꘍bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꘍bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꘍bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꘍bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꘍bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-110.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-110.html index 43c44fc..fe5cfd0 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-110.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-110.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꘏bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꘏bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꘏bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꘏bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꘏bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-111.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-111.html index 1db4aef..20e214b 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-111.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-111.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꤮bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꤮bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꤮bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꤮bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꤮bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-112.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-112.html index f6af709..3e2c4af 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-112.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-112.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꤯bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꤯bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꤯bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꤯bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa꤯bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-113.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-113.html index 66e03e25..ac308ecb 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-113.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-113.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩐bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩐bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩐bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩐bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩐bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-114.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-114.html index fc0c64f..ced3533c 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-114.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-114.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩑bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩑bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩑bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩑bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩑bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-115.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-115.html index 98c6f29..95c7bee5 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-115.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-115.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩒bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩒bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩒bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩒bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩒bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-116.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-116.html index e815984..ebbfd91 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-116.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-116.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩓bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩓bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩓bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩓bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩓bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-117.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-117.html index c61c766..ee25a94 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-117.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-117.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩔bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩔bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩔bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩔bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩔bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-118.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-118.html index a32f7768ac..6a9736c 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-118.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-118.html
@@ -7,16 +7,13 @@ <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<meta name='flags' content='dom'> +<meta name='flags' content='should dom'> <meta name="assert" content="[Exploratory] The browser will break a line of text after any Unicode character with the BA Other Terminating Punctuation property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩕bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩕bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩕bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩕bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa𐩕bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight > 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight > 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight > 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight > 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight > 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-120.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-120.html index b57a54d..affee69 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-120.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-120.html
@@ -10,13 +10,10 @@ <meta name='flags' content='dom'> <meta name="assert" content="[Exploratory] The browser will NOT break a line of text containing any Unicode character with the GL non-breaking property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight < 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight < 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight < 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight < 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight < 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-121.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-121.html index aca8565a..589e981 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-121.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-121.html
@@ -10,22 +10,20 @@ <meta name='flags' content='dom'> <meta name="assert" content="[Exploratory] The browser will NOT break a line of text containing any Unicode character with the GL non-breaking property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> - - <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +33,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight < 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight < 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight < 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight < 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight < 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-122.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-122.html index a2e4df0..59bbe8b 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-122.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-122.html
@@ -10,13 +10,10 @@ <meta name='flags' content='dom'> <meta name="assert" content="[Exploratory] The browser will NOT break a line of text containing any Unicode character with the GL non-breaking property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᠎bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᠎bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᠎bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᠎bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa᠎bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight < 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight < 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight < 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight < 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight < 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-123.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-123.html index 5be9df5..bf98f931 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-123.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-123.html
@@ -10,13 +10,10 @@ <meta name='flags' content='dom'> <meta name="assert" content="[Exploratory] The browser will NOT break a line of text containing any Unicode character with the GL non-breaking property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa͏bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa͏bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa͏bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa͏bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa͏bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight < 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight < 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight < 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight < 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight < 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-124.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-124.html index cadbbf1..5ac0df9 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-124.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-124.html
@@ -10,13 +10,10 @@ <meta name='flags' content='dom'> <meta name="assert" content="[Exploratory] The browser will NOT break a line of text containing any Unicode character with the GL non-breaking property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight < 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight < 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight < 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight < 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight < 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-125.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-125.html index 13b5712b..d38479f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-125.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-125.html
@@ -10,13 +10,10 @@ <meta name='flags' content='dom'> <meta name="assert" content="[Exploratory] The browser will NOT break a line of text containing any Unicode character with the GL non-breaking property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa‑bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa‑bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa‑bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa‑bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa‑bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight < 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight < 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight < 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight < 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight < 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-126.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-126.html index 322a9ec..c14899d7 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-126.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-126.html
@@ -10,13 +10,10 @@ <meta name='flags' content='dom'> <meta name="assert" content="[Exploratory] The browser will NOT break a line of text containing any Unicode character with the GL non-breaking property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa༈bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa༈bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa༈bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa༈bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa༈bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight < 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight < 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight < 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight < 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight < 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-127.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-127.html index f880cb02..dfa0a8e 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-127.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-127.html
@@ -10,13 +10,10 @@ <meta name='flags' content='dom'> <meta name="assert" content="[Exploratory] The browser will NOT break a line of text containing any Unicode character with the GL non-breaking property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa༌bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa༌bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa༌bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa༌bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa༌bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight < 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight < 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight < 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight < 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight < 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-128.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-128.html index 302b4471..b4009bd 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-128.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-128.html
@@ -10,13 +10,10 @@ <meta name='flags' content='dom'> <meta name="assert" content="[Exploratory] The browser will NOT break a line of text containing any Unicode character with the GL non-breaking property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa༒bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa༒bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa༒bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa༒bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa༒bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight < 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight < 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight < 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight < 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight < 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-130.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-130.html index 7d16c3ba..b9a9e48e 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-130.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-130.html
@@ -10,13 +10,10 @@ <meta name='flags' content='dom'> <meta name="assert" content="[Exploratory] The browser will NOT break a line of text containing any Unicode character with the WJ Word Joiner property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁠bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁠bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁠bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁠bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa⁠bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight < 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight < 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight < 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight < 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight < 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-131.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-131.html index 528acca..93bf8d1 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-131.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-baspglwj-131.html
@@ -10,13 +10,10 @@ <meta name='flags' content='dom'> <meta name="assert" content="[Exploratory] The browser will NOT break a line of text containing any Unicode character with the WJ Word Joiner property."> <style type='text/css'> -@font-face { - font-family: 'csstest_ascii'; - src: url('support/csstest-ascii-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; - } -#breakable { font-family: csstest_ascii; font-size: 25px; width: 800px; line-height: 30px; } +.test > div { font-family: monospace; font-size: 25px; width: 50ch; line-height: 30px; } +#breakable2 { white-space: pre-line; } +#breakable3 { white-space: pre-wrap; } +#breakable4 { white-space: break-spaces; } </style> </head> <body> @@ -24,8 +21,11 @@ <div class="test"> - <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> - </div> + <div id="breakable">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable3">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> + <div id="breakable4">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div> +</div> <!--Notes: @@ -35,8 +35,17 @@ --> <script> test(function() { -assert_true(document.getElementById('breakable').offsetHeight < 35); -}, " "); + assert_true(document.getElementById('breakable').offsetHeight < 35); +}, "white-space:normal"); +test(function() { + assert_true(document.getElementById('breakable2').offsetHeight < 35); +}, "white-space:pre-line"); +test(function() { + assert_true(document.getElementById('breakable3').offsetHeight < 35); +}, "white-space:pre-wrap"); +test(function() { + assert_true(document.getElementById('breakable4').offsetHeight < 35); +}, "white-space:break-spaces"); </script> <div id='log'></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-001.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-001.html index 65d7327..e150523 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-001.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-001-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 0028 LEFT PARENTHESIS at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-002.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-002.html index ca03be54..12e6589 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-002.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-002.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-002-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 005B LEFT SQUARE BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-003.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-003.html index ec0b661..984c2ba 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-003.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-003.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-003-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 007B LEFT CURLY BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-004.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-004.html index 686f380..48d7b8e 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-004.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-004.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-004-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 0F3A TIBETAN MARK GUG RTAGS GYON at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-005.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-005.html index 78b50f18b..0d791328 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-005.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-005.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-005-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 0F3C TIBETAN MARK ANG KHANG GYON at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-006.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-006.html index 36cfeba..185cf59 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-006.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-006.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-006-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 169B OGHAM FEATHER MARK at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-007.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-007.html index aa520e1d..c67e866 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-007.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-007.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-007-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 201A SINGLE LOW-9 QUOTATION MARK at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-008.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-008.html index ebc4b90..7a22a9e5 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-008.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-008.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-008-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 201E DOUBLE LOW-9 QUOTATION MARK at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-009.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-009.html index d0bcd7f..1312f5b7 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-009.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-009.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-009-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 2045 LEFT SQUARE BRACKET WITH QUILL at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-010.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-010.html index 89c8f3f..c914a24 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-010.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-010.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-010-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 207D SUPERSCRIPT LEFT PARENTHESIS at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-011.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-011.html index 9a338ae..acdef96 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-011.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-011.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-011-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 208D SUBSCRIPT LEFT PARENTHESIS at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-012.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-012.html index 9d6ea3d..68e77aa 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-012.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-012.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-012-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 2329 LEFT-POINTING ANGLE BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-014.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-014.html index 5a25666..6fdaee9 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-014.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-014.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-014-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 2768 MEDIUM LEFT PARENTHESIS ORNAMENT at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-015.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-015.html index 1408381d7..7f6858f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-015.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-015.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-015-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 276A MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-016.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-016.html index ff9f5a79..9b37174 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-016.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-016.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-016-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 276C MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-017.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-017.html index f1aceca3..32e4925 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-017.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-017.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-017-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 276E HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-018.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-018.html index be8cd0c..6d8556c 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-018.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-018.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-018-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 2770 HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-019.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-019.html index 15ef881c..977efda 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-019.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-019.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-019-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 2772 LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-020.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-020.html index 0d972121..9006b8dd 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-020.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-020.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-020-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 2774 MEDIUM LEFT CURLY BRACKET ORNAMENT at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-021.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-021.html index 8ad6f601..ac2c7ff 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-021.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-021.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-021-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 27E6 MATHEMATICAL LEFT WHITE SQUARE BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-022.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-022.html index 8d0c58f..7bfaeeb6 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-022.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-022.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-022-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 27E8 MATHEMATICAL LEFT ANGLE BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-023.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-023.html index 14e03e79..3e36d8a 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-023.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-023.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-023-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 27EA MATHEMATICAL LEFT DOUBLE ANGLE BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-024.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-024.html index d54eccfd..d7b5ee4 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-024.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-024.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-024-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 2983 LEFT WHITE CURLY BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-025.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-025.html index fca5eab..fe049b3 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-025.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-025.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-025-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 2985 LEFT WHITE PARENTHESIS at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-026.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-026.html index a7f87a2..9fa262ec8 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-026.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-026.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-026-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 2987 Z NOTATION LEFT IMAGE BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-027.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-027.html index 2f00731..0cba8cc7 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-027.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-027.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-027-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 2989 Z NOTATION LEFT BINDING BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-028.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-028.html index 62a4f29c..05d34171 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-028.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-028.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-028-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 298B LEFT SQUARE BRACKET WITH UNDERBAR at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-029.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-029.html index 003beb5..6d79c20b 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-029.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-029.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-029-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 298D LEFT SQUARE BRACKET WITH TICK IN TOP CORNER at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-030.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-030.html index 74a3f3d0..1494c0690 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-030.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-030.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-030-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 298F LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-031.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-031.html index c1744316..62807dd 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-031.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-031.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-031-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 2991 LEFT ANGLE BRACKET WITH DOT at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-032.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-032.html index 20094b3..a40de11b 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-032.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-032.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-032-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 2993 LEFT ARC LESS-THAN BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-033.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-033.html index ae72cbcc..aefca35 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-033.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-033.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-033-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 2995 DOUBLE LEFT ARC GREATER-THAN BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-034.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-034.html index 37bc76b..ba49183 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-034.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-034.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-034-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 2997 LEFT BLACK TORTOISE SHELL BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-035.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-035.html index dcaa880..ea830346 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-035.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-035.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-035-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 29D8 LEFT WIGGLY FENCE at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-036.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-036.html index ac62455f..71d8e14 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-036.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-036.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-036-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 29DA LEFT DOUBLE WIGGLY FENCE at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-037.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-037.html index e684869c..d14fe35 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-037.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-037.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-037-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 29FC LEFT-POINTING CURVED ANGLE BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-038.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-038.html index 0238636..28202c9 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-038.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-038.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-038-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 3008 LEFT ANGLE BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-039.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-039.html index 1cc30a0..724fd85f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-039.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-039.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-039-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 300A LEFT DOUBLE ANGLE BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-040.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-040.html index 2478f1b..1f626eb 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-040.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-040.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-040-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 300C LEFT CORNER BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-041.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-041.html index a56e4de..2b8e5cc 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-041.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-041.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-041-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 300E LEFT WHITE CORNER BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-042.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-042.html index 37b9d38..4d2d5fef 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-042.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-042.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-042-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 3010 LEFT BLACK LENTICULAR BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-043.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-043.html index 70aaa89..59622cda 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-043.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-043.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-043-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 3014 LEFT TORTOISE SHELL BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-044.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-044.html index 4801e30..37675c1 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-044.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-044.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-044-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 3016 LEFT WHITE LENTICULAR BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-045.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-045.html index ab03da2b..94a5682 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-045.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-045.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-045-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 3018 LEFT WHITE TORTOISE SHELL BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-046.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-046.html index 65cd602..9710c36 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-046.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-046.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-046-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 301A LEFT WHITE SQUARE BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-047.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-047.html index bf39278..c112ac8 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-047.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-047.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-047-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 301D REVERSED DOUBLE PRIME QUOTATION MARK at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-049.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-049.html index 8c9a86c..2e3e088 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-049.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-049.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-049-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave FE35 PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-050.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-050.html index 6b3d4973..f85f3deb 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-050.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-050.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-050-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave FE37 PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-051.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-051.html index c028e0b..55f558e 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-051.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-051.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-051-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave FE39 PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-052.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-052.html index 73ad096..a8e094d 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-052.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-052.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-052-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave FE3B PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-053.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-053.html index be5dd30d..33df08d 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-053.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-053.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-053-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave FE3D PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-054.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-054.html index 2c22489c..02e8c797 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-054.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-054.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-054-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave FE3F PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-055.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-055.html index 2546535..d0aeaa60 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-055.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-055.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-055-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave FE41 PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-056.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-056.html index 102cf4d2..4c4be0f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-056.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-056.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-056-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave FE43 PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-057.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-057.html index 49ccc36e..e97b355 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-057.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-057.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-057-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave FE47 PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-058.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-058.html index 42938495..6fa1bd61 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-058.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-058.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-058-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave FE59 SMALL LEFT PARENTHESIS at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-059.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-059.html index 65b95b4..190de2c 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-059.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-059.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-059-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave FE5B SMALL LEFT CURLY BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-060.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-060.html index 98a0423a..48c7a77 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-060.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-060.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-060-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave FE5D SMALL LEFT TORTOISE SHELL BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-061.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-061.html index e351406..4b7cfde 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-061.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-061.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-061-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave FF08 FULLWIDTH LEFT PARENTHESIS at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-062.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-062.html index af9b75e..0881830 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-062.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-062.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-062-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave FF3B FULLWIDTH LEFT SQUARE BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-063.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-063.html index fb4dee8..cde3bcd0 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-063.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-063.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-063-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave FF5B FULLWIDTH LEFT CURLY BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-064.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-064.html index 1efb48b7..b941664 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-064.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-064.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-064-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave FF5F FULLWIDTH LEFT WHITE PARENTHESIS at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-065.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-065.html index c0a17ec..2856ae57 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-065.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-065.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-065-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave FF62 HALFWIDTH LEFT CORNER BRACKET at the end of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-100.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-100.html index d97591c..7521661 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-100.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-100.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-100-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 3001 IDEOGRAPHIC COMMA at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-101.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-101.html index 125ea52c2..def939a 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-101.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-101.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-101-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 3002 IDEOGRAPHIC FULL STOP at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-102.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-102.html index f3e6879..bc437fc9 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-102.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-102.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-102-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave FE50 SMALL COMMA at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-103.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-103.html index 5a5fd93..a8b9140 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-103.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-103.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-103-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave FE52 SMALL FULL STOP at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-104.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-104.html index e35c82a..0700d7b9 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-104.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-104.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-104-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave FF0C FULLWIDTH COMMA at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-105.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-105.html index d8baaf0..9d3a28f1 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-105.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-105.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-105-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave FF0E FULLWIDTH FULL STOP at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-106.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-106.html index 200ff0c0..eebf109 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-106.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-106.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-106-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave FF61 HALFWIDTH IDEOGRAPHIC FULL STOP at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-107.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-107.html index b76f797..cbf46fc 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-107.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-107.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-107-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave FF64 HALFWIDTH IDEOGRAPHIC COMMA at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-108.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-108.html index d33e85c..6711fa8 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-108.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-108.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-108-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 0029 RIGHT PARENTHESIS at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-109.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-109.html index 89dd7bb..302ce10a 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-109.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-109.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-109-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 005D RIGHT SQUARE BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-110.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-110.html index e89c12b5..14fc9f2 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-110.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-110.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-110-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 007D RIGHT CURLY BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-111.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-111.html index db0a276..e369d5d 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-111.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-111.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-111-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 0F3B TIBETAN MARK GUG RTAGS GYAS at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-112.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-112.html index 01e7faa..4bff413 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-112.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-112.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-112-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 0F3D TIBETAN MARK ANG KHANG GYAS at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-113.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-113.html index 314674d..d9cda3ab 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-113.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-113.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-113-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 169C OGHAM REVERSED FEATHER MARK at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-114.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-114.html index 2a9c9f2..daf95af 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-114.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-114.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-114-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 2046 RIGHT SQUARE BRACKET WITH QUILL at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-115.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-115.html index eb5cbe0d..76a0d1f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-115.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-115.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-115-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 207E SUPERSCRIPT RIGHT PARENTHESIS at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-116.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-116.html index 21ddae5..904aeb3 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-116.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-116.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-116-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 208E SUBSCRIPT RIGHT PARENTHESIS at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-117.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-117.html index 7fa697a..f9958c9 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-117.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-117.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-117-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 232A RIGHT-POINTING ANGLE BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-119.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-119.html index d6ae588..36a3f1d 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-119.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-119.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-119-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 2769 MEDIUM RIGHT PARENTHESIS ORNAMENT at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-120.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-120.html index 147d624..741452d3 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-120.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-120.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-120-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 276B MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-121.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-121.html index 20e7abc..121dcd74 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-121.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-121.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-121-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 276D MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-122.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-122.html index 13ad23e..c1bc044d 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-122.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-122.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-122-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 276F HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-123.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-123.html index d0f81dcb..beb12b06 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-123.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-123.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-123-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 2771 HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-124.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-124.html index 2c4aa745..d596efa 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-124.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-124.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-124-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 2773 LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-125.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-125.html index de99e5c..db73766b 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-125.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-125.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-125-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 2775 MEDIUM RIGHT CURLY BRACKET ORNAMENT at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-126.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-126.html index 8e5a501d..aed75f9 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-126.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-126.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-126-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 27E7 MATHEMATICAL RIGHT WHITE SQUARE BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-127.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-127.html index 4901e91..945a1976 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-127.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-127.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-127-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 27E9 MATHEMATICAL RIGHT ANGLE BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-128.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-128.html index a7362c1..b15858df 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-128.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-128.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-128-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 27EB MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-129.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-129.html index de172e28..2add59f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-129.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-129.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-129-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 2984 RIGHT WHITE CURLY BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-130.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-130.html index 3fdc7b1..63fde2f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-130.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-130.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-130-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 2986 RIGHT WHITE PARENTHESIS at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-131.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-131.html index 93b70636..bf58dce 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-131.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-131.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-131-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 2988 Z NOTATION RIGHT IMAGE BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-132.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-132.html index 8c83a80f..8392f21 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-132.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-132.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-132-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 298A Z NOTATION RIGHT BINDING BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-133.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-133.html index 35216919..aad6470 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-133.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-133.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-133-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 298C RIGHT SQUARE BRACKET WITH UNDERBAR at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-134.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-134.html index 6a10266..50830b12ef 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-134.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-134.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-134-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 298E RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-135.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-135.html index 1f91909b..62fee77 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-135.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-135.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-135-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 2990 RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-136.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-136.html index 6b0cddc..b09f104 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-136.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-136.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-136-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 2992 RIGHT ANGLE BRACKET WITH DOT at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-137.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-137.html index f6578dc..912d8d6 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-137.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-137.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-137-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 2994 RIGHT ARC GREATER-THAN BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-138.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-138.html index 6fe9782..5138aeb 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-138.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-138.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-138-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 2996 DOUBLE RIGHT ARC LESS-THAN BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-139.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-139.html index 9b9cb61e..473ea176 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-139.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-139.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-139-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 2998 RIGHT BLACK TORTOISE SHELL BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-140.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-140.html index 676eed0c..fe0060a 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-140.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-140.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-140-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 29D9 RIGHT WIGGLY FENCE at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-141.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-141.html index 6b6d021d..073ea05 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-141.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-141.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-141-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 29DB RIGHT DOUBLE WIGGLY FENCE at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-142.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-142.html index 95ddc35..994a4a8 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-142.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-142.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-142-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 29FD RIGHT-POINTING CURVED ANGLE BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-143.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-143.html index d3338c2..a61cc56 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-143.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-143.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-143-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 3009 RIGHT ANGLE BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-144.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-144.html index 397cee69..5905185 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-144.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-144.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-144-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 300B RIGHT DOUBLE ANGLE BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-145.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-145.html index f3c7598..7c6cddb 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-145.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-145.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-145-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 300D RIGHT CORNER BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-146.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-146.html index 21570bb..37fd0248 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-146.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-146.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-146-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 300F RIGHT WHITE CORNER BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-147.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-147.html index 3f20bcf..678d1b9 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-147.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-147.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-147-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 3011 RIGHT BLACK LENTICULAR BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-148.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-148.html index 5628127..e9945f0b 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-148.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-148.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-148-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 3015 RIGHT TORTOISE SHELL BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-149.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-149.html index cc2a9539..11907a40 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-149.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-149.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-149-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 3017 RIGHT WHITE LENTICULAR BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-150.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-150.html index 380893f..2653652d 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-150.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-150.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-150-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 3019 RIGHT WHITE TORTOISE SHELL BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-151.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-151.html index 87c1db2..af76569 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-151.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-151.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-151-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 301B RIGHT WHITE SQUARE BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-152.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-152.html index 6f6767c7..8090119 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-152.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-152.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-152-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 301E DOUBLE PRIME QUOTATION MARK at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-153.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-153.html index bf0381a..31ca266 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-153.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-153.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-153-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 301F LOW DOUBLE PRIME QUOTATION MARK at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-155.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-155.html index c1a26be..ecdf8c1 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-155.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-155.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-155-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave FE36 PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-156.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-156.html index d346417..5298212 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-156.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-156.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-156-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave FE38 PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-157.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-157.html index 808bb91..08297c9 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-157.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-157.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-157-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave FE3A PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-158.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-158.html index d5d0309..7a155bb 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-158.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-158.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-158-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave FE3C PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-159.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-159.html index 296673a1..ada16da 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-159.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-159.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-159-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave FE3E PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-160.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-160.html index 1b7419f..65a8260 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-160.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-160.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-160-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave FE40 PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-161.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-161.html index 11de841..847202a 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-161.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-161.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-161-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave FE42 PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-162.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-162.html index 1e373b5..73daa10 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-162.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-162.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-162-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave FE44 PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-163.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-163.html index 53deaaa0..62073afa 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-163.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-163.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-163-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave FE48 PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-164.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-164.html index 5a59c95..e23308c 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-164.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-164.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-164-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave FE5A SMALL RIGHT PARENTHESIS at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-165.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-165.html index 48b071f3..3f467d1 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-165.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-165.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-165-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave FE5C SMALL RIGHT CURLY BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-166.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-166.html index a8d357ce..8f9b419 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-166.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-166.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-166-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave FE5E SMALL RIGHT TORTOISE SHELL BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-167.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-167.html index c37ca17..80f96fa 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-167.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-167.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-167-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave FF09 FULLWIDTH RIGHT PARENTHESIS at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-168.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-168.html index eb43c63..23477b0 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-168.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-168.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-168-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave FF3D FULLWIDTH RIGHT SQUARE BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-169.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-169.html index bb65486..1a619b1 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-169.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-169.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-169-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave FF5D FULLWIDTH RIGHT CURLY BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-170.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-170.html index a67d271c..bd3ce8e 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-170.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-170.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-170-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave FF60 FULLWIDTH RIGHT WHITE PARENTHESIS at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-171.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-171.html index 1e931fae..382736c 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-171.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-171.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-171-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave FF63 HALFWIDTH RIGHT CORNER BRACKET at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-200.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-200.html index 57460aa..298ee680 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-200.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-200.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-200-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has an NS Non-Starter property, the browser will not leave 0E5A THAI CHARACTER ANGKHANKHU at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-201.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-201.html index 09ccb28f..6c95bb1 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-201.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-201.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-201-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has an NS Non-Starter property, the browser will not leave 0E5B THAI CHARACTER KHOMUT at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-202.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-202.html index 70280cee..4d288b1f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-202.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-202.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-202-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has an NS Non-Starter property, the browser will not leave 17D4 KHMER SIGN KHAN at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-203.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-203.html index 21228668..2ad9d56 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-203.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-203.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-203-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has an NS Non-Starter property, the browser will not leave 17D6 KHMER SIGN CAMNUC PII KUUH at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-204.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-204.html index d85601c..69416d3f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-204.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-204.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-204-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has an NS Non-Starter property, the browser will not leave 17DA KHMER SIGN KOOMUUT at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-205.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-205.html index 64eba30..2f3297e 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-205.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-205.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-205-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has an NS Non-Starter property, the browser will not leave 203C DOUBLE EXCLAMATION MARK at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-206.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-206.html index 0d26e5e0..d584f0a 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-206.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-206.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-206-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has an NS Non-Starter property, the browser will not leave 3005 IDEOGRAPHIC ITERATION MARK at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-207.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-207.html index e98aeee..2a3d8ee 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-207.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-207.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-207-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has an NS Non-Starter property, the browser will not leave 301C WAVE DASH at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-208.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-208.html index 86128f8..a7f0ff0 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-208.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-208.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-208-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has an NS Non-Starter property, the browser will not leave 303C MASU MARK at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-209.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-209.html index 1b8da91..044a435 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-209.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-209.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-209-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has an NS Non-Starter property, the browser will not leave 303B VERTICAL IDEOGRAPHIC ITERATION MARK at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-210.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-210.html index 7274002..076a068 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-210.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-210.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-210-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has an NS Non-Starter property, the browser will not leave 309B KATAKANA-HIRAGANA VOICED SOUND MARK at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-211.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-211.html index 22268f4..254211a 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-211.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-211.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-211-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has an NS Non-Starter property, the browser will not leave 309C KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-212.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-212.html index 5368110..1ce5478 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-212.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-212.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-212-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has an NS Non-Starter property, the browser will not leave 309D HIRAGANA ITERATION MARK at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-213.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-213.html index 37f6b15..c8464ba 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-213.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-213.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-213-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has an NS Non-Starter property, the browser will not leave 309E HIRAGANA VOICED ITERATION MARK at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-214.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-214.html index 1295120..20db61d 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-214.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-214.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-214-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has an NS Non-Starter property, the browser will not leave 30A0 KATAKANA-HIRAGANA DOUBLE HYPHEN at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-215.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-215.html index ec7b51fe..8a603a57 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-215.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-215.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-215-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has an NS Non-Starter property, the browser will not leave 30FB KATAKANA MIDDLE DOT at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-217.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-217.html index fdd4a3b2..f975564 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-217.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-217.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-217-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has an NS Non-Starter property, the browser will not leave 30FD KATAKANA ITERATION MARK at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-218.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-218.html index c10d0d61..e7c4c0a 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-218.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-218.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-218-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has an NS Non-Starter property, the browser will not leave 30FE KATAKANA VOICED ITERATION MARK at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-219.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-219.html index 1d991ab..77b82ab 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-219.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-219.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-219-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has an NS Non-Starter property, the browser will not leave FE54 SMALL SEMICOLON at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-220.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-220.html index eabf2c9..5bd4f80 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-220.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-220.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-220-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has an NS Non-Starter property, the browser will not leave FE55 SMALL COLON at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-221.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-221.html index 5fdf1d54..7919aa7 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-221.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-221.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-221-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has an NS Non-Starter property, the browser will not leave FF1A FULLWIDTH COLON at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-222.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-222.html index ad07476..0fd1093 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-222.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-222.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-222-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has an NS Non-Starter property, the browser will not leave FF1B FULLWIDTH SEMICOLON at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-223.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-223.html index e156415..ae076ca4 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-223.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-223.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-223-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has an NS Non-Starter property, the browser will not leave FF65 HALFWIDTH KATAKANA MIDDLE DOT at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-225.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-225.html index 1bd5a3a..3e30619 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-225.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-225.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-225-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has an NS Non-Starter property, the browser will not leave FF9E HALFWIDTH KATAKANA VOICED SOUND MARK at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-226.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-226.html index 70c1c6d8..fef8bd5 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-226.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-226.html
@@ -6,7 +6,7 @@ <link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'> <link rel='help' href='https://drafts.csswg.org/css-text-3/#line-breaking'> <link rel="match" href="reference/css3-text-line-break-opclns-226-ref.html"> -<meta name='flags' content=''> +<meta name='flags' content='should '> <meta name="assert" content="Because it has an NS Non-Starter property, the browser will not leave FF9F HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK at the beginning of a line."> <style type='text/css'> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/line-break/line-break-anywhere-001.html b/third_party/blink/web_tests/external/wpt/css/css-text/line-break/line-break-anywhere-001.html index a031765..6ae60ead 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/line-break/line-break-anywhere-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/line-break/line-break-anywhere-001.html
@@ -16,7 +16,7 @@ background: green; font-family: monospace; width: 1ch; - height: 20em; + height: 19em; } #test { width: 1ch; @@ -25,9 +25,12 @@ font-family: monospace; line-break: anywhere; } +span { + background: red; +} </style> <p>Test passes if there is a green rectangle below and no red.</p> <div id=green></div> <!-- with line breaks everywhere, none of the following characters should stick out from under the green div --> -<div id=test>aa-a.a)a,a)a aa⁠a‍a・a</div> +<div id=test>aa-a.a)a,a)a<span> </span>aa⁠a‍a・a</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/line-break/reference/line-break-anywhere-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/line-break/reference/line-break-anywhere-001-ref.html index ff74b3bce..daf17c9c 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/line-break/reference/line-break-anywhere-001-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/line-break/reference/line-break-anywhere-001-ref.html
@@ -1,4 +1,4 @@ -<!DOCTYPE html> +<!DOCTYPE html> <html lang=en> <meta charset="utf-8"> <title>CSS Text Test Reference</title> @@ -9,7 +9,7 @@ background: green; font-family: monospace; width: 1ch; - height: 20em; + height: 19em; } </style>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-001-ref.html new file mode 100644 index 0000000..34e60ff --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-001-ref.html
@@ -0,0 +1,26 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test reference</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<style> +div { font-family: monospace; } +</style> + +<p>Test passes if there are two columns of "x" characters below and no red. + +<div>xx<br>xx</div> +<div>xx<br>xx</div> +<div>xx<br>xx</div> +<div>xx<br>xx</div> +<div>xx<br>xx</div> +<div>xx<br>xx</div> +<div>xx<br>xx</div> +<div>xx<br>xx</div> +<div>xx<br>xx</div> +<div>xx<br>xx</div> +<div>xx<br>xx</div> +<div>xx<br>xx</div> +<div>xx<br>xx</div> +<div>xx<br>xx</div> +<div>xx<br>xx</div> +<div>xx<br>xx</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-002-ref.html new file mode 100644 index 0000000..3939dab --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-002-ref.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test reference</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: pre-wrap; + font-family: Ahem; + font-size: 10px; + line-height: 1; + color: green; +} +</style> + +<p>Test passes if there are two green tall boxes below and no red. + +<div>x x<br>x x</div> +<div>x x<br>x x</div> +<div>x x<br>x x</div> +<div>x x<br>x x</div> +<div>x x<br>x x</div> +<div>x x<br>x x</div> +<div>x x<br>x x</div> +<div>x x<br>x x</div> +<div>x x<br>x x</div> +<div>x x<br>x x</div> +<div>x x<br>x x</div> +<div>x x<br>x x</div> +<div>x x<br>x x</div> +<div>x x<br>x x</div> +<div>x x<br>x x</div> +<div>x x<br>x x</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-001-ref.html new file mode 100644 index 0000000..738bd55 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-001-ref.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test reference</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: pre; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-002-ref.html new file mode 100644 index 0000000..f3abfe46 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-002-ref.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Reference</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: pre; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-003-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-003-ref.html new file mode 100644 index 0000000..a1681bfb --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-003-ref.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Reference</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: pre; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-004-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-004-ref.html new file mode 100644 index 0000000..2201f7d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-004-ref.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Reference</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: pre; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-005-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-005-ref.html new file mode 100644 index 0000000..9174a09 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-005-ref.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Reference</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: pre; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-006-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-006-ref.html new file mode 100644 index 0000000..35261a8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-006-ref.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Reference</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: pre; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-007-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-007-ref.html new file mode 100644 index 0000000..8e8163ca1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-007-ref.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Reference</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: pre; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-008-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-008-ref.html new file mode 100644 index 0000000..fb2ee58 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-008-ref.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Reference</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: pre; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-009-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-009-ref.html new file mode 100644 index 0000000..005c505 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-009-ref.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Reference</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: pre; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<section class=ref> + <div>xx あ<br>あ あ<br>あ xx</div><!--XB/XA, non tailorable--> +</section> +<section> + <div>xx あ<br>あ あ<br>あ xx</div><!--XB/XA, non tailorable--> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-010-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-010-ref.html new file mode 100644 index 0000000..5f4c1140 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-010-ref.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Reference</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: pre; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-011-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-011-ref.html new file mode 100644 index 0000000..f7770741 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-011-ref.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Reference</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: pre; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-012-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-012-ref.html new file mode 100644 index 0000000..6b00177f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-012-ref.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Reference</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: pre; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-013-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-013-ref.html new file mode 100644 index 0000000..6deaef0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-013-ref.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Reference</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: pre; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<section class=ref> + <div>xx あ<br>あ あ<br>あ xx</div><!--XB/XA, non-tailorable--> +</section> +<section> + <div>xx あ<br>あ あ<br>あ xx</div><!--XB/XA, non-tailorable--> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-014-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-014-ref.html new file mode 100644 index 0000000..1eed539 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-014-ref.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Reference</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: pre; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-015-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-015-ref.html new file mode 100644 index 0000000..c60d2540 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/trailing-other-space-separators-break-spaces-015-ref.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test Reference</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: pre; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-001.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-001.html new file mode 100644 index 0000000..6b693f08 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-001.html
@@ -0,0 +1,30 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: sequence of spaces and other space separators at the end of line must be removed</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="match" href="reference/trailing-other-space-separators-001-ref.html"> +<meta name="assert" content="An sequence of regular spaces and other space separators at the end of the line must be removed."> +<style> +div { font-family: monospace; width: 2ch; } +span { background: red; } /* If the space hangs instead of being removed, there will be red */ +</style> + +<p>Test passes if there are two columns of "x" characters below and no red. + +<div>xx<span>                    </span>xx</div> +<div>xx<span> </span>xx</div> +<div>xx<span> </span>xx</div> +<div>xx<span> </span>xx</div> +<div>xx<span> </span>xx</div> +<div>xx<span> </span>xx</div> +<div>xx<span> </span>xx</div> +<div>xx<span> </span>xx</div> +<div>xx<span> </span>xx</div> +<div>xx<span> </span><wbr>xx</div> +<div>xx<span> </span>xx</div> +<div>xx<span> </span>xx</div> +<div>xx<span> </span>xx</div> +<div>xx<span> </span><wbr>xx</div> +<div>xx<span> </span>xx</div> +<div>xx<span> </span>xx</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-002.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-002.html new file mode 100644 index 0000000..269b691b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-002.html
@@ -0,0 +1,65 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: sequence of spaces and other space separators at the end of line with white-space:pre-wrap</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="match" href="reference/trailing-other-space-separators-002-ref.html"> +<meta name="assert" content="An sequence of regular spaces and other space separators at the end of the line must hang if white-space is pre-wrap."> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: pre-wrap; + font-family: Ahem; + font-size: 10px; + line-height: 1; + width: 3ch; + color: green; +} +.red { + position: absolute; + z-index: -1; +} +.red div { + color: red; +} +span { color: transparent; } /* because ogham space is otherwise visible*/ +</style> + +<p>Test passes if there are two green tall boxes below and no red. + +<section class=red> + <div>x x<br>x x</div> + <div>x x<br>x x</div> + <div>x x<br>x x</div> + <div>x x<br>x x</div> + <div>x x<br>x x</div> + <div>x x<br>x x</div> + <div>x x<br>x x</div> + <div>x x<br>x x</div> + <div>x x<br>x x</div> + <div>x x<br>x x</div> + <div>x x<br>x x</div> + <div>x x<br>x x</div> + <div>x x<br>x x</div> + <div>x x<br>x x</div> + <div>x x<br>x x</div> + <div>x x<br>x x</div> +</section> +<section> + <div>x x<span> </span>                   x x</div> + <div>x x<span> </span>x x</div> + <div>x x x x</div> + <div>x x x x</div> + <div>x x x x</div> + <div>x x x x</div> + <div>x x x x</div> + <div>x x x x</div> + <div>x x x x</div> + <div>x x <wbr>x x</div> + <div>x x x x</div> + <div>x x x x</div> + <div>x x x x</div> + <div>x x <wbr>x x</div> + <div>x x x x</div> + <div>x x x x</div> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-003.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-003.html new file mode 100644 index 0000000..549c731 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-003.html
@@ -0,0 +1,30 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: sequence of spaces and other space separators at the end of line, white-space:pre-line</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="match" href="reference/trailing-other-space-separators-001-ref.html"> +<meta name="assert" content="An sequence of regular spaces and other space separators at the end of the line must be removed, with white-space:pre-line."> +<style> +div { font-family: monospace; width: 2ch; white-space: pre-line; } +span { background: red; } /* If the space hangs instead of being removed, there will be red */ +</style> + +<p>Test passes if there are two columns of "x" characters below and no red. + +<div>xx<span>                    </span>xx</div> +<div>xx<span> </span>xx</div> +<div>xx<span> </span>xx</div> +<div>xx<span> </span>xx</div> +<div>xx<span> </span>xx</div> +<div>xx<span> </span>xx</div> +<div>xx<span> </span>xx</div> +<div>xx<span> </span>xx</div> +<div>xx<span> </span>xx</div> +<div>xx<span> </span><wbr>xx</div> +<div>xx<span> </span>xx</div> +<div>xx<span> </span>xx</div> +<div>xx<span> </span>xx</div> +<div>xx<span> </span><wbr>xx</div> +<div>xx<span> </span>xx</div> +<div>xx<span> </span>xx</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-004.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-004.html new file mode 100644 index 0000000..90a568a8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-004.html
@@ -0,0 +1,30 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: sequence of spaces and other space separators at the end of line, white-space:nowrap</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="match" href="reference/trailing-other-space-separators-001-ref.html"> +<meta name="assert" content="An sequence of regular spaces and other space separators at the end of the line must be removed, with white-space:nowrap."> +<style> +div { font-family: monospace; width: 2ch; white-space: nowrap; } +span { background: red; } /* If the space hangs instead of being removed, there will be red */ +</style> + +<p>Test passes if there are two columns of "x" characters below and no red. + +<div>xx<span>                    </span><br>xx</div> +<div>xx<span> </span><br>xx</div> +<div>xx<span> </span><br>xx</div> +<div>xx<span> </span><br>xx</div> +<div>xx<span> </span><br>xx</div> +<div>xx<span> </span><br>xx</div> +<div>xx<span> </span><br>xx</div> +<div>xx<span> </span><br>xx</div> +<div>xx<span> </span><br>xx</div> +<div>xx<span> </span><br>xx</div> +<div>xx<span> </span><br>xx</div> +<div>xx<span> </span><br>xx</div> +<div>xx<span> </span><br>xx</div> +<div>xx<span> </span><br>xx</div> +<div>xx<span> </span><br>xx</div> +<div>xx<span> </span><br>xx</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-001.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-001.html new file mode 100644 index 0000000..896afe6 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-001.html
@@ -0,0 +1,49 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: U+1680 at the end of line with white-space:break-spaces</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="match" href="reference/trailing-other-space-separators-break-spaces-001-ref.html"> +<meta name="assert" content="U+1680 at the end of the line must not hang or be discarded if white-space is break-spaces. It thus keeps its usual line breaking properties, as defined in UAX14."> +<meta name="flags" content="should"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: break-spaces; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +.ref div { + white-space: pre; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<!-- + * no line breaking opportunity is after an "x" + unless the next character provides one, + and none of the other space separators do. + * no line breaking opportunity is before an "x" + unless the previous character provides one (A). + * a line breaking opportunity is expected after "あ", + unless suppressed by the next character (XB). + * a line breaking opportunity is expected before "あ", + unless suppressed by the previous character (XA). +--> +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx ああ ああ xx</div> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-002.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-002.html new file mode 100644 index 0000000..f795b31 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-002.html
@@ -0,0 +1,49 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: U+2000 at the end of line with white-space:break-spaces</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="match" href="reference/trailing-other-space-separators-break-spaces-002-ref.html"> +<meta name="assert" content="U+2000 at the end of the line must not hang or be discarded if white-space is break-spaces. It thus keeps its usual line breaking properties, as defined in UAX14."> +<meta name="flags" content="should"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: break-spaces; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +.ref div { + white-space: pre; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<!-- + * no line breaking opportunity is after an "x" + unless the next character provides one, + and none of the other space separators do. + * no line breaking opportunity is before an "x" + unless the previous character provides one (A). + * a line breaking opportunity is expected after "あ", + unless suppressed by the next character (XB). + * a line breaking opportunity is expected before "あ", + unless suppressed by the previous character (XA). +--> +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx ああ ああ xx</div> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-003.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-003.html new file mode 100644 index 0000000..f5e2fd8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-003.html
@@ -0,0 +1,49 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: U+2001 at the end of line with white-space:break-spaces</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="match" href="reference/trailing-other-space-separators-break-spaces-003-ref.html"> +<meta name="assert" content="U+2001 at the end of the line must not hang or be discarded if white-space is break-spaces. It thus keeps its usual line breaking properties, as defined in UAX14."> +<meta name="flags" content="should"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: break-spaces; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +.ref div { + white-space: pre; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<!-- + * no line breaking opportunity is after an "x" + unless the next character provides one, + and none of the other space separators do. + * no line breaking opportunity is before an "x" + unless the previous character provides one (A). + * a line breaking opportunity is expected after "あ", + unless suppressed by the next character (XB). + * a line breaking opportunity is expected before "あ", + unless suppressed by the previous character (XA). +--> +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx ああ ああ xx</div> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-004.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-004.html new file mode 100644 index 0000000..99308eb8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-004.html
@@ -0,0 +1,49 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: U+2002 at the end of line with white-space:break-spaces</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="match" href="reference/trailing-other-space-separators-break-spaces-004-ref.html"> +<meta name="assert" content="U+2002 at the end of the line must not hang or be discarded if white-space is break-spaces. It thus keeps its usual line breaking properties, as defined in UAX14."> +<meta name="flags" content="should"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: break-spaces; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +.ref div { + white-space: pre; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<!-- + * no line breaking opportunity is after an "x" + unless the next character provides one, + and none of the other space separators do. + * no line breaking opportunity is before an "x" + unless the previous character provides one (A). + * a line breaking opportunity is expected after "あ", + unless suppressed by the next character (XB). + * a line breaking opportunity is expected before "あ", + unless suppressed by the previous character (XA). +--> +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx ああ ああ xx</div> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-005.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-005.html new file mode 100644 index 0000000..9323e81 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-005.html
@@ -0,0 +1,49 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: U+2003 at the end of line with white-space:break-spaces</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="match" href="reference/trailing-other-space-separators-break-spaces-005-ref.html"> +<meta name="assert" content="U+2003 at the end of the line must not hang or be discarded if white-space is break-spaces. It thus keeps its usual line breaking properties, as defined in UAX14."> +<meta name="flags" content="should"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: break-spaces; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +.ref div { + white-space: pre; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<!-- + * no line breaking opportunity is after an "x" + unless the next character provides one, + and none of the other space separators do. + * no line breaking opportunity is before an "x" + unless the previous character provides one (A). + * a line breaking opportunity is expected after "あ", + unless suppressed by the next character (XB). + * a line breaking opportunity is expected before "あ", + unless suppressed by the previous character (XA). +--> +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx ああ ああ xx</div> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-006.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-006.html new file mode 100644 index 0000000..d4c24ad --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-006.html
@@ -0,0 +1,49 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: U+2004 at the end of line with white-space:break-spaces</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="match" href="reference/trailing-other-space-separators-break-spaces-006-ref.html"> +<meta name="assert" content="U+2004 at the end of the line must not hang or be discarded if white-space is break-spaces. It thus keeps its usual line breaking properties, as defined in UAX14."> +<meta name="flags" content="should"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: break-spaces; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +.ref div { + white-space: pre; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<!-- + * no line breaking opportunity is after an "x" + unless the next character provides one, + and none of the other space separators do. + * no line breaking opportunity is before an "x" + unless the previous character provides one (A). + * a line breaking opportunity is expected after "あ", + unless suppressed by the next character (XB). + * a line breaking opportunity is expected before "あ", + unless suppressed by the previous character (XA). +--> +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx ああ ああ xx</div> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-007.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-007.html new file mode 100644 index 0000000..e9ebbaca --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-007.html
@@ -0,0 +1,49 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: U+2005 at the end of line with white-space:break-spaces</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="match" href="reference/trailing-other-space-separators-break-spaces-007-ref.html"> +<meta name="assert" content="U+2005 at the end of the line must not hang or be discarded if white-space is break-spaces. It thus keeps its usual line breaking properties, as defined in UAX14."> +<meta name="flags" content="should"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: break-spaces; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +.ref div { + white-space: pre; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<!-- + * no line breaking opportunity is after an "x" + unless the next character provides one, + and none of the other space separators do. + * no line breaking opportunity is before an "x" + unless the previous character provides one (A). + * a line breaking opportunity is expected after "あ", + unless suppressed by the next character (XB). + * a line breaking opportunity is expected before "あ", + unless suppressed by the previous character (XA). +--> +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx ああ ああ xx</div> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-008.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-008.html new file mode 100644 index 0000000..7d399e2 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-008.html
@@ -0,0 +1,49 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: U+2006 at the end of line with white-space:break-spaces</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="match" href="reference/trailing-other-space-separators-break-spaces-008-ref.html"> +<meta name="assert" content="U+2006 at the end of the line must not hang or be discarded if white-space is break-spaces. It thus keeps its usual line breaking properties, as defined in UAX14."> +<meta name="flags" content="should"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: break-spaces; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +.ref div { + white-space: pre; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<!-- + * no line breaking opportunity is after an "x" + unless the next character provides one, + and none of the other space separators do. + * no line breaking opportunity is before an "x" + unless the previous character provides one (A). + * a line breaking opportunity is expected after "あ", + unless suppressed by the next character (XB). + * a line breaking opportunity is expected before "あ", + unless suppressed by the previous character (XA). +--> +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx ああ ああ xx</div> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-009.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-009.html new file mode 100644 index 0000000..3d2d9d9 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-009.html
@@ -0,0 +1,48 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: U+2007 at the end of line with white-space:break-spaces</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="match" href="reference/trailing-other-space-separators-break-spaces-009-ref.html"> +<meta name="assert" content="U+2007 at the end of the line must not hang or be discarded if white-space is break-spaces. It thus keeps its usual line breaking properties, as defined in UAX14."> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: break-spaces; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +.ref div { + white-space: pre; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<!-- + * no line breaking opportunity is after an "x" + unless the next character provides one, + and none of the other space separators do. + * no line breaking opportunity is before an "x" + unless the previous character provides one (A). + * a line breaking opportunity is expected after "あ", + unless suppressed by the next character (XB). + * a line breaking opportunity is expected before "あ", + unless suppressed by the previous character (XA). +--> +<section class=ref> + <div>xx あ<br>あ あ<br>あ xx</div><!--XB/XA, non tailorable--> +</section> +<section> + <div>xx ああ ああ xx</div> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-010.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-010.html new file mode 100644 index 0000000..1d75558 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-010.html
@@ -0,0 +1,49 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: U+2008 at the end of line with white-space:break-spaces</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="match" href="reference/trailing-other-space-separators-break-spaces-010-ref.html"> +<meta name="assert" content="U+2008 at the end of the line must not hang or be discarded if white-space is break-spaces. It thus keeps its usual line breaking properties, as defined in UAX14."> +<meta name="flags" content="should"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: break-spaces; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +.ref div { + white-space: pre; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<!-- + * no line breaking opportunity is after an "x" + unless the next character provides one, + and none of the other space separators do. + * no line breaking opportunity is before an "x" + unless the previous character provides one (A). + * a line breaking opportunity is expected after "あ", + unless suppressed by the next character (XB). + * a line breaking opportunity is expected before "あ", + unless suppressed by the previous character (XA). +--> +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx ああ ああ xx</div> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-011.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-011.html new file mode 100644 index 0000000..f0be5d5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-011.html
@@ -0,0 +1,49 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: U+2009 at the end of line with white-space:break-spaces</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="match" href="reference/trailing-other-space-separators-break-spaces-011-ref.html"> +<meta name="assert" content="U+2009 at the end of the line must not hang or be discarded if white-space is break-spaces. It thus keeps its usual line breaking properties, as defined in UAX14."> +<meta name="flags" content="should"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: break-spaces; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +.ref div { + white-space: pre; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<!-- + * no line breaking opportunity is after an "x" + unless the next character provides one, + and none of the other space separators do. + * no line breaking opportunity is before an "x" + unless the previous character provides one (A). + * a line breaking opportunity is expected after "あ", + unless suppressed by the next character (XB). + * a line breaking opportunity is expected before "あ", + unless suppressed by the previous character (XA). +--> +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx ああ ああ xx</div> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-012.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-012.html new file mode 100644 index 0000000..ffb018e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-012.html
@@ -0,0 +1,49 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: U+200A at the end of line with white-space:break-spaces</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="match" href="reference/trailing-other-space-separators-break-spaces-012-ref.html"> +<meta name="assert" content="U+200A at the end of the line must not hang or be discarded if white-space is break-spaces. It thus keeps its usual line breaking properties, as defined in UAX14."> +<meta name="flags" content="should"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: break-spaces; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +.ref div { + white-space: pre; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<!-- + * no line breaking opportunity is after an "x" + unless the next character provides one, + and none of the other space separators do. + * no line breaking opportunity is before an "x" + unless the previous character provides one (A). + * a line breaking opportunity is expected after "あ", + unless suppressed by the next character (XB). + * a line breaking opportunity is expected before "あ", + unless suppressed by the previous character (XA). +--> +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx ああ ああ xx</div> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-013.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-013.html new file mode 100644 index 0000000..067ad06 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-013.html
@@ -0,0 +1,48 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: U+200F at the end of line with white-space:break-spaces</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="match" href="reference/trailing-other-space-separators-break-spaces-013-ref.html"> +<meta name="assert" content="U+200F at the end of the line must not hang or be discarded if white-space is break-spaces. It thus keeps its usual line breaking properties, as defined in UAX14."> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: break-spaces; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +.ref div { + white-space: pre; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<!-- + * no line breaking opportunity is after an "x" + unless the next character provides one, + and none of the other space separators do. + * no line breaking opportunity is before an "x" + unless the previous character provides one (A). + * a line breaking opportunity is expected after "あ", + unless suppressed by the next character (XB). + * a line breaking opportunity is expected before "あ", + unless suppressed by the previous character (XA). +--> +<section class=ref> + <div>xx あ<br>あ あ<br>あ xx</div><!--XB/XA, non-tailorable--> +</section> +<section> + <div>xx ああ ああ xx</div> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-014.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-014.html new file mode 100644 index 0000000..36cc5ae --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-014.html
@@ -0,0 +1,49 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: U+205F at the end of line with white-space:break-spaces</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="match" href="reference/trailing-other-space-separators-break-spaces-014-ref.html"> +<meta name="assert" content="U+205F at the end of the line must not hang or be discarded if white-space is break-spaces. It thus keeps its usual line breaking properties, as defined in UAX14."> +<meta name="flags" content="should"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: break-spaces; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +.ref div { + white-space: pre; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<!-- + * no line breaking opportunity is after an "x" + unless the next character provides one, + and none of the other space separators do. + * no line breaking opportunity is before an "x" + unless the previous character provides one (A). + * a line breaking opportunity is expected after "あ", + unless suppressed by the next character (XB). + * a line breaking opportunity is expected before "あ", + unless suppressed by the previous character (XA). +--> +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx ああ ああ xx</div> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-015.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-015.html new file mode 100644 index 0000000..cbb7e7c3 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-other-space-separators-break-spaces-015.html
@@ -0,0 +1,49 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: U+3000 at the end of line with white-space:break-spaces</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="match" href="reference/trailing-other-space-separators-break-spaces-015-ref.html"> +<meta name="assert" content="U+3000 at the end of the line must not hang or be discarded if white-space is break-spaces. It thus keeps its usual line breaking properties, as defined in UAX14."> +<meta name="flags" content="should"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + white-space: break-spaces; + font-size: 10px; + line-height: 1; + width: 2em; +} +section { + font-family: Ahem; + float: left; + margin: 0 1em; + color: blue; +} +.ref { + color: orange; +} +.ref div { + white-space: pre; +} +</style> + +<p>Test passes if the orange and blue parts of this page are identical. + +<!-- + * no line breaking opportunity is after an "x" + unless the next character provides one, + and none of the other space separators do. + * no line breaking opportunity is before an "x" + unless the previous character provides one (A). + * a line breaking opportunity is expected after "あ", + unless suppressed by the next character (XB). + * a line breaking opportunity is expected before "あ", + unless suppressed by the previous character (XA). +--> +<section class=ref> + <div>xx <br>ああ<br> あ<br>あ <br>xx</div><!-- A, tailorable --> +</section> +<section> + <div>xx ああ ああ xx</div> +</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transitions/CSSTransition-effect.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-transitions/CSSTransition-effect.tentative-expected.txt deleted file mode 100644 index 065f2d42..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-transitions/CSSTransition-effect.tentative-expected.txt +++ /dev/null
@@ -1,10 +0,0 @@ -This is a testharness.js-based test. -FAIL After setting a transition's effect to null, it still reports the original transition property assert_equals: expected (string) "left" but got (undefined) undefined -PASS After setting a transition's effect to null, it becomes finished -PASS After setting a transition's effect to null, style is updated -PASS After setting a transition's effect to null, a new transition can be started -PASS After setting a new keyframe effect with a shorter duration, the transition becomes finished -FAIL After setting a new keyframe effect targeting different properties, the transition continues to report the original transition property assert_equals: expected (string) "left" but got (undefined) undefined -FAIL After setting a new keyframe effect on a play-pending transition, the transition remains pending assert_equals: expected (string) "left" but got (undefined) undefined -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transitions/CSSTransition-transitionProperty.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-transitions/CSSTransition-transitionProperty.tentative-expected.txt deleted file mode 100644 index 414a6e1..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-transitions/CSSTransition-transitionProperty.tentative-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL CSSTransition.transitionProperty assert_equals: The transitionProperty for the returned transition corresponds to the specific property being transitioned expected (string) "left" but got (undefined) undefined -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transitions/Element-getAnimations.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-transitions/Element-getAnimations.tentative-expected.txt index 67df4eca..8878ef0 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-transitions/Element-getAnimations.tentative-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-transitions/Element-getAnimations.tentative-expected.txt
@@ -1,10 +1,10 @@ This is a testharness.js-based test. PASS getAnimations returns one Animation per transitioning property -FAIL getAnimations returns CSSTransition objects for CSS Transitions assert_equals: Interface of returned animation is CSSTransition expected "[object CSSTransition]" but got "[object Animation]" +PASS getAnimations returns CSSTransition objects for CSS Transitions PASS getAnimations does not return finished CSS Transitions PASS getAnimations does not return a transition for a non-animatable property PASS getAnimations does not return a transition for an unsupposed property -FAIL getAnimations sorts simultaneous transitions by name assert_equals: expected (string) "border-bottom-width" but got (undefined) undefined -FAIL getAnimations sorts transitions by when they were generated assert_equals: expected (string) "transform" but got (undefined) undefined +FAIL getAnimations sorts simultaneous transitions by name assert_equals: expected "border-bottom-width" but got "opacity" +PASS getAnimations sorts transitions by when they were generated Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transitions/event-dispatch.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-transitions/event-dispatch.tentative-expected.txt index 4a1fd79..3216888a 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-transitions/event-dispatch.tentative-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-transitions/event-dispatch.tentative-expected.txt
@@ -4,15 +4,15 @@ PASS Idle or Pending -> Active PASS Idle or Pending -> After PASS Before -> Idle (display: none) -FAIL Before -> Idle (Animation.timeline = null) promise_test: Unhandled rejection with value: object "TypeError: Cannot assign to read only property 'timeline' of object '#<Animation>'" +FAIL Before -> Idle (Animation.timeline = null) promise_test: Unhandled rejection with value: object "TypeError: Cannot assign to read only property 'timeline' of object '#<CSSTransition>'" PASS Before -> Active PASS Before -> After PASS Active -> Idle, no delay (display: none) -FAIL Active -> Idle, no delay (Animation.timeline = null) promise_test: Unhandled rejection with value: object "TypeError: Cannot assign to read only property 'timeline' of object '#<Animation>'" +FAIL Active -> Idle, no delay (Animation.timeline = null) promise_test: Unhandled rejection with value: object "TypeError: Cannot assign to read only property 'timeline' of object '#<CSSTransition>'" PASS Active -> Idle, with positive delay (display: none) -FAIL Active -> Idle, with positive delay (Animation.timeline = null) promise_test: Unhandled rejection with value: object "TypeError: Cannot assign to read only property 'timeline' of object '#<Animation>'" +FAIL Active -> Idle, with positive delay (Animation.timeline = null) promise_test: Unhandled rejection with value: object "TypeError: Cannot assign to read only property 'timeline' of object '#<CSSTransition>'" PASS Active -> Idle, with negative delay (display: none) -FAIL Active -> Idle, with negative delay (Animation.timeline = null) promise_test: Unhandled rejection with value: object "TypeError: Cannot assign to read only property 'timeline' of object '#<Animation>'" +FAIL Active -> Idle, with negative delay (Animation.timeline = null) promise_test: Unhandled rejection with value: object "TypeError: Cannot assign to read only property 'timeline' of object '#<CSSTransition>'" PASS Active -> Before PASS Active -> After PASS After -> Before @@ -22,7 +22,7 @@ PASS Call Animation.cancel after canceling transition. FAIL Restart transition after canceling transition immediately assert_true: Timed out waiting for transitioncancel, transitionrun expected true got false PASS Call Animation.cancel after restarting transition immediately -FAIL Set timeline and play transition after clear the timeline promise_test: Unhandled rejection with value: object "TypeError: Cannot assign to read only property 'timeline' of object '#<Animation>'" +FAIL Set timeline and play transition after clear the timeline promise_test: Unhandled rejection with value: object "TypeError: Cannot assign to read only property 'timeline' of object '#<CSSTransition>'" PASS Set null target effect after canceling the transition FAIL Cancel the transition after clearing the target effect assert_true: Timed out waiting for transitionend expected true got false Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/parsing/flood-opacity-computed-expected.txt b/third_party/blink/web_tests/external/wpt/css/filter-effects/parsing/flood-opacity-computed-expected.txt deleted file mode 100644 index 4da55ad..0000000 --- a/third_party/blink/web_tests/external/wpt/css/filter-effects/parsing/flood-opacity-computed-expected.txt +++ /dev/null
@@ -1,9 +0,0 @@ -This is a testharness.js-based test. -PASS Property flood-opacity value '-1' computes to '0' -PASS Property flood-opacity value '0.5' computes to '0.5' -PASS Property flood-opacity value '3' computes to '1' -FAIL Property flood-opacity value '-100%' computes to '0' assert_equals: expected "0" but got "1" -FAIL Property flood-opacity value '50%' computes to '0.5' assert_equals: expected "0.5" but got "1" -PASS Property flood-opacity value '300%' computes to '1' -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/parsing/flood-opacity-valid-expected.txt b/third_party/blink/web_tests/external/wpt/css/filter-effects/parsing/flood-opacity-valid-expected.txt deleted file mode 100644 index 01b8a624..0000000 --- a/third_party/blink/web_tests/external/wpt/css/filter-effects/parsing/flood-opacity-valid-expected.txt +++ /dev/null
@@ -1,9 +0,0 @@ -This is a testharness.js-based test. -PASS e.style['flood-opacity'] = "-1" should set the property value -PASS e.style['flood-opacity'] = "0.5" should set the property value -PASS e.style['flood-opacity'] = "3" should set the property value -FAIL e.style['flood-opacity'] = "-100%" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['flood-opacity'] = "50%" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['flood-opacity'] = "300%" 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/motion/animation/offset-anchor-interpolation.html b/third_party/blink/web_tests/external/wpt/css/motion/animation/offset-anchor-interpolation.html index 7ad9482..75f855a 100644 --- a/third_party/blink/web_tests/external/wpt/css/motion/animation/offset-anchor-interpolation.html +++ b/third_party/blink/web_tests/external/wpt/css/motion/animation/offset-anchor-interpolation.html
@@ -42,7 +42,7 @@ to: 'right -140% bottom -60%', }, [ {at: -1, expect: 'calc(960px - 240%) calc(800px - 160%)'}, - {at: 0, expect: 'left 480px top 400px'}, + {at: 0, expect: 'left calc(0% + 480px) top calc(0% + 400px)'}, {at: 0.125, expect: 'calc(420px + 30%) calc(350px + 20%)'}, {at: 0.875, expect: 'calc(210% + 60px) calc(140% + 50px)'}, {at: 1, expect: 'right -140% bottom -60%'}, @@ -54,12 +54,12 @@ from: 'left top', to: 'left 8px bottom 20%', }, [ - {at: -1, expect: '-8px -80%'}, + {at: -1, expect: 'calc(0% - 8px) -80%'}, {at: 0, expect: 'left top'}, - {at: 0.125, expect: '1px 10%'}, - {at: 0.875, expect: '7px 70%'}, - {at: 1, expect: 'left 8px bottom 20%'}, - {at: 2, expect: '16px 160%'} + {at: 0.125, expect: 'calc(0% + 1px) 10%'}, + {at: 0.875, expect: 'calc(0% + 7px) 70%'}, + {at: 1, expect: 'left calc(0% + 8px) bottom 20%'}, + {at: 2, expect: 'calc(0% + 16px) 160%'} ]); test_no_interpolation({
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/animation/reftests/offset-path-with-transforms-001.html b/third_party/blink/web_tests/external/wpt/css/motion/animation/reftests/offset-path-with-transforms-001.html new file mode 100644 index 0000000..c554264 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/motion/animation/reftests/offset-path-with-transforms-001.html
@@ -0,0 +1,35 @@ +<!DOCTYPE html> +<html class="reftest-wait"> + <head> + <title>CSS Motion Path: Combined transformation matrix interpolation</title> + <link rel="help" href="https://drafts.csswg.org/css-transforms-2/#ctm"> + <link rel="match" href="offset-path-with-transforms-ref.html"> + <meta name="assert" content="This tests animating combined transformation matrix."> + <style> + @keyframes anim { + to { + translate: 0px 100px; + offset-distance: 100%; + transform: translateX(-100px); + } + } + #target { + position: absolute; + width: 100px; + height: 50px; + background-color: lime; + offset-path: path("M25 0v100"); + animation: anim 10s -5s paused linear; + } + </style> + </head> + <body onload="load()"> + <div id="target"></div> + <div style='width: 50px; height: 100px; background-color: red;'></div> + </body> + <script> + requestAnimationFrame(() => { + document.documentElement.classList.remove('reftest-wait'); + }); + </script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/animation/reftests/offset-path-with-transforms-ref.html b/third_party/blink/web_tests/external/wpt/css/motion/animation/reftests/offset-path-with-transforms-ref.html new file mode 100644 index 0000000..413369e0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/motion/animation/reftests/offset-path-with-transforms-ref.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> + <head> + <title>CSS Motion Path: Combined transformation matrix interpolation reference</title> + <style> + #target { + width: 50px; + height: 100px; + background-color: lime; + } + </style> + </head> + <body> + <div id="target"></div> + </body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/offset-supports-calc-expected.txt b/third_party/blink/web_tests/external/wpt/css/motion/offset-supports-calc-expected.txt new file mode 100644 index 0000000..c777241 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/motion/offset-supports-calc-expected.txt
@@ -0,0 +1,8 @@ +This is a testharness.js-based test. +FAIL offset-position supports calc assert_equals: expected "calc(20% + 30px) calc(100% - 40px)" but got "calc(20% + 30px) calc(100% + -40px)" +PASS offset-path supports calc +FAIL offset-distance supports calc assert_equals: expected "calc(50% - 100px)" but got "calc(50% + -100px)" +PASS offset-rotate supports calc +FAIL offset-anchor supports calc assert_equals: expected "calc(20% + 30px) calc(100% - 40px)" but got "calc(20% + 30px) calc(100% + -40px)" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/offset-supports-calc.html b/third_party/blink/web_tests/external/wpt/css/motion/offset-supports-calc.html index 9ec737e..907694f 100644 --- a/third_party/blink/web_tests/external/wpt/css/motion/offset-supports-calc.html +++ b/third_party/blink/web_tests/external/wpt/css/motion/offset-supports-calc.html
@@ -22,7 +22,7 @@ test(function(){ target.style = 'offset-position: calc(30px + 20%) calc(-200px + 8em + 100%);'; - assert_equals(getComputedStyle(target).offsetPosition, 'calc(20% + 30px) calc(100% + -40px)'); + assert_equals(getComputedStyle(target).offsetPosition, 'calc(20% + 30px) calc(100% - 40px)'); }, 'offset-position supports calc'); test(function(){ @@ -32,7 +32,7 @@ test(function(){ target.style = 'offset-distance: calc(-100px + 50%);'; - assert_equals(getComputedStyle(target).offsetDistance, 'calc(50% + -100px)'); + assert_equals(getComputedStyle(target).offsetDistance, 'calc(50% - 100px)'); }, 'offset-distance supports calc'); test(function(){ @@ -42,7 +42,7 @@ test(function(){ target.style = 'offset-anchor: calc(30px + 20%) calc(-200px + 8em + 100%);'; - assert_equals(getComputedStyle(target).offsetAnchor, 'calc(20% + 30px) calc(100% + -40px)'); + assert_equals(getComputedStyle(target).offsetAnchor, 'calc(20% + 30px) calc(100% - 40px)'); }, 'offset-anchor supports calc'); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-anchor-parsing-valid.html b/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-anchor-parsing-valid.html index a69a5ce..6cb4d44 100644 --- a/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-anchor-parsing-valid.html +++ b/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-anchor-parsing-valid.html
@@ -19,7 +19,7 @@ test_valid_value("offset-anchor", "right center"); test_valid_value("offset-anchor", "center top"); test_valid_value("offset-anchor", "center bottom"); -test_valid_value("offset-anchor", "calc(10px + 20%) center"); +test_valid_value("offset-anchor", "calc(20% + 10px) center"); test_valid_value("offset-anchor", "right 30em"); test_valid_value("offset-anchor", "10px 20%"); test_valid_value("offset-anchor", "left -10px top -20%");
diff --git a/third_party/blink/web_tests/external/wpt/fetch/corb/script-resource-with-nonsniffable-types.tentative.sub.html b/third_party/blink/web_tests/external/wpt/fetch/corb/script-resource-with-nonsniffable-types.tentative.sub.html index bf42d0e..4cbdd7b 100644 --- a/third_party/blink/web_tests/external/wpt/fetch/corb/script-resource-with-nonsniffable-types.tentative.sub.html +++ b/third_party/blink/web_tests/external/wpt/fetch/corb/script-resource-with-nonsniffable-types.tentative.sub.html
@@ -56,7 +56,6 @@ "application/gzip", "application/x-gzip", "application/x-protobuf", - "application/x-www-form-urlencoded", "application/zip", "multipart/byteranges", "text/event-stream",
diff --git a/third_party/blink/web_tests/external/wpt/fonts/math/fraction-denominatordisplaystyleshiftdown6000-axisheight1000-rulethickness1000.woff b/third_party/blink/web_tests/external/wpt/fonts/math/fraction-denominatordisplaystyleshiftdown6000-axisheight1000-rulethickness1000.woff new file mode 100644 index 0000000..28e41f5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fonts/math/fraction-denominatordisplaystyleshiftdown6000-axisheight1000-rulethickness1000.woff Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/fonts/math/fraction-denominatordisplaystyleshiftdown6000-rulethickness1000.woff b/third_party/blink/web_tests/external/wpt/fonts/math/fraction-denominatordisplaystyleshiftdown6000-rulethickness1000.woff deleted file mode 100644 index 3d90e64..0000000 --- a/third_party/blink/web_tests/external/wpt/fonts/math/fraction-denominatordisplaystyleshiftdown6000-rulethickness1000.woff +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/fonts/math/fraction-denominatorshiftdown3000-axisheight1000-rulethickness1000.woff b/third_party/blink/web_tests/external/wpt/fonts/math/fraction-denominatorshiftdown3000-axisheight1000-rulethickness1000.woff new file mode 100644 index 0000000..f0e0d5c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fonts/math/fraction-denominatorshiftdown3000-axisheight1000-rulethickness1000.woff Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/fonts/math/fraction-denominatorshiftdown3000-rulethickness1000.woff b/third_party/blink/web_tests/external/wpt/fonts/math/fraction-denominatorshiftdown3000-rulethickness1000.woff deleted file mode 100644 index 0b7efba..0000000 --- a/third_party/blink/web_tests/external/wpt/fonts/math/fraction-denominatorshiftdown3000-rulethickness1000.woff +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/fonts/math/fraction-numeratordisplaystyleshiftup2000-axisheight1000-rulethickness1000.woff b/third_party/blink/web_tests/external/wpt/fonts/math/fraction-numeratordisplaystyleshiftup2000-axisheight1000-rulethickness1000.woff new file mode 100644 index 0000000..d6f530d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fonts/math/fraction-numeratordisplaystyleshiftup2000-axisheight1000-rulethickness1000.woff Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/fonts/math/fraction-numeratordisplaystyleshiftup2000-rulethickness1000.woff b/third_party/blink/web_tests/external/wpt/fonts/math/fraction-numeratordisplaystyleshiftup2000-rulethickness1000.woff deleted file mode 100644 index 920c81eb..0000000 --- a/third_party/blink/web_tests/external/wpt/fonts/math/fraction-numeratordisplaystyleshiftup2000-rulethickness1000.woff +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/fonts/math/fraction-numeratorshiftup11000-axisheight1000-rulethickness1000.woff b/third_party/blink/web_tests/external/wpt/fonts/math/fraction-numeratorshiftup11000-axisheight1000-rulethickness1000.woff new file mode 100644 index 0000000..d2685397 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fonts/math/fraction-numeratorshiftup11000-axisheight1000-rulethickness1000.woff Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/fonts/math/fraction-numeratorshiftup11000-rulethickness1000.woff b/third_party/blink/web_tests/external/wpt/fonts/math/fraction-numeratorshiftup11000-rulethickness1000.woff deleted file mode 100644 index 3e70cd2..0000000 --- a/third_party/blink/web_tests/external/wpt/fonts/math/fraction-numeratorshiftup11000-rulethickness1000.woff +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/fonts/math/stack-bottomdisplaystyleshiftdown5000-axisheight1000.woff b/third_party/blink/web_tests/external/wpt/fonts/math/stack-bottomdisplaystyleshiftdown5000-axisheight1000.woff new file mode 100644 index 0000000..d8f8ae4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fonts/math/stack-bottomdisplaystyleshiftdown5000-axisheight1000.woff Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/fonts/math/stack-bottomdisplaystyleshiftdown5000.woff b/third_party/blink/web_tests/external/wpt/fonts/math/stack-bottomdisplaystyleshiftdown5000.woff deleted file mode 100644 index 8761585..0000000 --- a/third_party/blink/web_tests/external/wpt/fonts/math/stack-bottomdisplaystyleshiftdown5000.woff +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/fonts/math/stack-bottomshiftdown6000-axisheight1000.woff b/third_party/blink/web_tests/external/wpt/fonts/math/stack-bottomshiftdown6000-axisheight1000.woff new file mode 100644 index 0000000..a3a491d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fonts/math/stack-bottomshiftdown6000-axisheight1000.woff Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/fonts/math/stack-bottomshiftdown6000.woff b/third_party/blink/web_tests/external/wpt/fonts/math/stack-bottomshiftdown6000.woff deleted file mode 100644 index 96ebce2..0000000 --- a/third_party/blink/web_tests/external/wpt/fonts/math/stack-bottomshiftdown6000.woff +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/fonts/math/stack-topdisplaystyleshiftup3000-axisheight1000.woff b/third_party/blink/web_tests/external/wpt/fonts/math/stack-topdisplaystyleshiftup3000-axisheight1000.woff new file mode 100644 index 0000000..bb286182 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fonts/math/stack-topdisplaystyleshiftup3000-axisheight1000.woff Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/fonts/math/stack-topdisplaystyleshiftup3000.woff b/third_party/blink/web_tests/external/wpt/fonts/math/stack-topdisplaystyleshiftup3000.woff deleted file mode 100644 index 556226f..0000000 --- a/third_party/blink/web_tests/external/wpt/fonts/math/stack-topdisplaystyleshiftup3000.woff +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/fonts/math/stack-topshiftup9000-axisheight1000.woff b/third_party/blink/web_tests/external/wpt/fonts/math/stack-topshiftup9000-axisheight1000.woff new file mode 100644 index 0000000..52bc0445 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fonts/math/stack-topshiftup9000-axisheight1000.woff Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/fonts/math/stack-topshiftup9000.woff b/third_party/blink/web_tests/external/wpt/fonts/math/stack-topshiftup9000.woff deleted file mode 100644 index d036e89..0000000 --- a/third_party/blink/web_tests/external/wpt/fonts/math/stack-topshiftup9000.woff +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/resources/echo-iframe.html.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/resources/echo-iframe.html.headers new file mode 100644 index 0000000..66044509 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/resources/echo-iframe.html.headers
@@ -0,0 +1 @@ +Cross-Origin-Embedder-Policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/resources/echo-worker.js.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/resources/echo-worker.js.headers new file mode 100644 index 0000000..66044509 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/resources/echo-worker.js.headers
@@ -0,0 +1 @@ +Cross-Origin-Embedder-Policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success-and-failure.html b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success-and-failure.https.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success-and-failure.html rename to third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success-and-failure.https.html
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success-and-failure.https.html.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success-and-failure.https.html.headers new file mode 100644 index 0000000..63b60e4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success-and-failure.https.html.headers
@@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/identity-not-preserved.html b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/identity-not-preserved.https.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/identity-not-preserved.html rename to third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/identity-not-preserved.https.html
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/identity-not-preserved.https.html.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/identity-not-preserved.https.html.headers new file mode 100644 index 0000000..63b60e4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/identity-not-preserved.https.html.headers
@@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https-expected.txt new file mode 100644 index 0000000..7b70ea2 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL postMessaging to a dedicated sub-worker allows them to see each others' modifications Worker is not defined +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https.html b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https.html new file mode 100644 index 0000000..dd221502 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https.html
@@ -0,0 +1,8 @@ +<!doctype html> +<meta charset=utf-8> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> +<script> +fetch_tests_from_worker(new SharedWorker("resources/nested-worker-success.js")); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https.html.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https.html.headers new file mode 100644 index 0000000..63b60e4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https.html.headers
@@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.any.js b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.any.js deleted file mode 100644 index 5388ebcc..0000000 --- a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.any.js +++ /dev/null
@@ -1,9 +0,0 @@ -// META: global=!default,dedicatedworker,sharedworker -// META: script=resources/test-incrementer.js -"use strict"; - -promise_test(t => { - const worker = new Worker("resources/incrementer-worker.js"); - - return testSharingViaIncrementerScript(t, worker, "parent worker", worker, "sub-worker"); -}, "postMessaging to a dedicated sub-worker allows them to see each others' modifications");
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.https.html b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.https.html new file mode 100644 index 0000000..aeee370 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.https.html
@@ -0,0 +1,8 @@ +<!doctype html> +<meta charset=utf-8> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> +<script> +fetch_tests_from_worker(new Worker("resources/nested-worker-success.js")); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.https.html.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.https.html.headers new file mode 100644 index 0000000..63b60e4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.https.html.headers
@@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any-expected.txt new file mode 100644 index 0000000..03e29e36 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any-expected.txt
@@ -0,0 +1,6 @@ +This is a testharness.js-based test. +FAIL SharedArrayBuffer over MessageChannel without COOP+COEP assert_throws: function "() => channel.port1.postMessage(sab)" did not throw +FAIL SharedArrayBuffer over BroadcastChannel without COOP+COEP assert_throws: function "() => channel.postMessage(sab)" did not throw +FAIL SharedArrayBuffer over postMessage() without COOP+COEP assert_throws: function "() => self.postMessage(sab)" did not throw +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.js b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.js new file mode 100644 index 0000000..96276d7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.js
@@ -0,0 +1,18 @@ +test(() => { + const sab = new SharedArrayBuffer(); + const channel = new MessageChannel(); + assert_throws("DataCloneError", () => channel.port1.postMessage(sab)); +}, "SharedArrayBuffer over MessageChannel without COOP+COEP"); + +test(() => { + const sab = new SharedArrayBuffer(); + const channel = new BroadcastChannel("Is mir egal"); + assert_throws("DataCloneError", () => channel.postMessage(sab)); +}, "SharedArrayBuffer over BroadcastChannel without COOP+COEP"); + +if (self.GLOBAL.isWindow()) { + test(() => { + const sab = new SharedArrayBuffer(); + assert_throws("DataCloneError", () => self.postMessage(sab)); + }, "SharedArrayBuffer over postMessage() without COOP+COEP"); +}
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.worker-expected.txt new file mode 100644 index 0000000..6600416 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.worker-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +FAIL SharedArrayBuffer over MessageChannel without COOP+COEP assert_throws: function "() => channel.port1.postMessage(sab)" did not throw +FAIL SharedArrayBuffer over BroadcastChannel without COOP+COEP assert_throws: function "() => channel.postMessage(sab)" did not throw +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-transferring.html b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-transferring.https.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-transferring.html rename to third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-transferring.https.html
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-transferring.https.html.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-transferring.https.html.headers new file mode 100644 index 0000000..63b60e4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-transferring.https.html.headers
@@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-iframe.html.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-iframe.html.headers index 66044509..1528bf0 100644 --- a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-iframe.html.headers +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-iframe.html.headers
@@ -1 +1,2 @@ Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Resource-Policy: cross-site
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-sharedworker.js.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-sharedworker.js.headers new file mode 100644 index 0000000..66044509 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-sharedworker.js.headers
@@ -0,0 +1 @@ +Cross-Origin-Embedder-Policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-worker.js.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-worker.js.headers new file mode 100644 index 0000000..66044509 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-worker.js.headers
@@ -0,0 +1 @@ +Cross-Origin-Embedder-Policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe-domain.sub.html.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe-domain.sub.html.headers new file mode 100644 index 0000000..56d0ac3 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe-domain.sub.html.headers
@@ -0,0 +1,2 @@ +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Resource-Policy: same-site
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe-messagechannel.html.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe-messagechannel.html.headers new file mode 100644 index 0000000..1528bf0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe-messagechannel.html.headers
@@ -0,0 +1,2 @@ +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Resource-Policy: cross-site
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe.html.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe.html.headers new file mode 100644 index 0000000..1528bf0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe.html.headers
@@ -0,0 +1,2 @@ +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Resource-Policy: cross-site
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-popup.html.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-popup.html.headers new file mode 100644 index 0000000..63b60e4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-popup.html.headers
@@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker-with-channel.js.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker-with-channel.js.headers new file mode 100644 index 0000000..66044509 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker-with-channel.js.headers
@@ -0,0 +1 @@ +Cross-Origin-Embedder-Policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker.js.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker.js.headers new file mode 100644 index 0000000..66044509 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker.js.headers
@@ -0,0 +1 @@ +Cross-Origin-Embedder-Policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-1.html.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-1.html.headers new file mode 100644 index 0000000..1528bf0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-1.html.headers
@@ -0,0 +1,2 @@ +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Resource-Policy: cross-site
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-2.html.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-2.html.headers new file mode 100644 index 0000000..1528bf0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-2.html.headers
@@ -0,0 +1,2 @@ +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Resource-Policy: cross-site
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-3.html.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-3.html.headers new file mode 100644 index 0000000..1528bf0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-3.html.headers
@@ -0,0 +1,2 @@ +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Resource-Policy: cross-site
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-4-incrementer.html.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-4-incrementer.html.headers new file mode 100644 index 0000000..1528bf0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-4-incrementer.html.headers
@@ -0,0 +1,2 @@ +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Resource-Policy: cross-site
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js new file mode 100644 index 0000000..9befc90 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js
@@ -0,0 +1,10 @@ +importScripts("/resources/testharness.js"); +importScripts("test-incrementer.js"); + +promise_test(t => { + const worker = new Worker("incrementer-worker.js"); + + return testSharingViaIncrementerScript(t, worker, "parent worker", worker, "sub-worker"); +}, "postMessaging to a dedicated sub-worker allows them to see each others' modifications"); + +done();
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js.headers new file mode 100644 index 0000000..66044509 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js.headers
@@ -0,0 +1 @@ +Cross-Origin-Embedder-Policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/serviceworker-failure.js.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/serviceworker-failure.js.headers new file mode 100644 index 0000000..66044509 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/serviceworker-failure.js.headers
@@ -0,0 +1 @@ +Cross-Origin-Embedder-Policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/sharedworker-failure.js.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/sharedworker-failure.js.headers new file mode 100644 index 0000000..66044509 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/sharedworker-failure.js.headers
@@ -0,0 +1 @@ +Cross-Origin-Embedder-Policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-history.html b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-history.https.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-history.html rename to third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-history.https.html
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-history.https.html.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-history.https.html.headers new file mode 100644 index 0000000..63b60e4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-history.https.html.headers
@@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-success.sub.html b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-success.https.sub.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-success.sub.html rename to third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-success.https.sub.html
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-success.https.sub.html.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-success.https.sub.html.headers new file mode 100644 index 0000000..63b60e4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-success.https.sub.html.headers
@@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel-success.html b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel-success.https.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel-success.html rename to third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel-success.https.html
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel-success.https.html.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel-success.https.html.headers new file mode 100644 index 0000000..63b60e4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel-success.https.html.headers
@@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-messagechannel-success.html b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-messagechannel-success.https.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-messagechannel-success.html rename to third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-messagechannel-success.https.html
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-messagechannel-success.https.html.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-messagechannel-success.https.html.headers new file mode 100644 index 0000000..63b60e4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-messagechannel-success.https.html.headers
@@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-serviceworker-failure.https.html.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-serviceworker-failure.https.html.headers new file mode 100644 index 0000000..63b60e4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-serviceworker-failure.https.html.headers
@@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-sharedworker-failure.html b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-sharedworker-failure.https.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-sharedworker-failure.html rename to third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-sharedworker-failure.https.html
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-sharedworker-failure.https.html.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-sharedworker-failure.https.html.headers new file mode 100644 index 0000000..63b60e4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-sharedworker-failure.https.html.headers
@@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-similar-but-cross-origin-success.sub.html b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-similar-but-cross-origin-success.https.sub.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-similar-but-cross-origin-success.sub.html rename to third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-similar-but-cross-origin-success.https.sub.html
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-similar-but-cross-origin-success.https.sub.html.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-similar-but-cross-origin-success.https.sub.html.headers new file mode 100644 index 0000000..63b60e4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-similar-but-cross-origin-success.https.sub.html.headers
@@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-simple-success.html b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-simple-success.https.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-simple-success.html rename to third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-simple-success.https.html
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-simple-success.https.html.headers b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-simple-success.https.html.headers new file mode 100644 index 0000000..63b60e4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-simple-success.https.html.headers
@@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/speech-api.idl b/third_party/blink/web_tests/external/wpt/interfaces/speech-api.idl index 6278d17..2ed9c2c 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/speech-api.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/speech-api.idl
@@ -90,7 +90,7 @@ }; // The object representing a speech grammar -[Exposed=Window, Constructor] +[Exposed=Window] interface SpeechGrammar { attribute DOMString src; attribute float weight; @@ -102,9 +102,9 @@ readonly attribute unsigned long length; getter SpeechGrammar item(unsigned long index); void addFromURI(DOMString src, - optional float weight); + optional float weight = 1.0); void addFromString(DOMString string, - optional float weight); + optional float weight = 1.0); }; [Exposed=Window]
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/web-nfc.idl b/third_party/blink/web_tests/external/wpt/interfaces/web-nfc.idl index 13afc276..f082a1e 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/web-nfc.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/web-nfc.idl
@@ -20,6 +20,7 @@ interface NDEFRecord { readonly attribute NDEFRecordType recordType; readonly attribute USVString mediaType; + USVString toText(); [NewObject] ArrayBuffer toArrayBuffer(); [NewObject] object toJSON(); @@ -28,6 +29,7 @@ dictionary NDEFRecordInit { NDEFRecordType recordType; USVString mediaType; + NDEFRecordData data; };
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl b/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl index 2c9eac5..ec4b76d 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl
@@ -18,8 +18,7 @@ enum XRSessionMode { "inline", - "immersive-vr", - "immersive-ar" + "immersive-vr" }; dictionary XRSessionInit { @@ -139,15 +138,6 @@ [SameObject] readonly attribute XRRigidTransform inverse; }; -[SecureContext, Exposed=Window, - Constructor(optional DOMPointInit origin, optional DOMPointInit direction), - Constructor(XRRigidTransform transform)] -interface XRRay { - [SameObject] readonly attribute DOMPointReadOnly origin; - [SameObject] readonly attribute DOMPointReadOnly direction; - readonly attribute Float32Array matrix; -}; - [SecureContext, Exposed=Window] interface XRPose { [SameObject] readonly attribute XRRigidTransform transform; readonly attribute boolean emulatedPosition; @@ -175,7 +165,6 @@ readonly attribute XRTargetRayMode targetRayMode; [SameObject] readonly attribute XRSpace targetRaySpace; [SameObject] readonly attribute XRSpace? gripSpace; - [SameObject] readonly attribute Gamepad? gamepad; [SameObject] readonly attribute FrozenArray<DOMString> profiles; }; @@ -186,12 +175,6 @@ getter XRInputSource(unsigned long index); }; -enum GamepadMappingType { - "", // Defined in the Gamepad API - "standard", // Defined in the Gamepad API - "xr-standard", -}; - typedef (WebGLRenderingContext or WebGL2RenderingContext) XRWebGLRenderingContext;
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-parameters-1.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-parameters-1.html index b8bc4051..ba47897c 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-parameters-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-parameters-1.html
@@ -21,32 +21,32 @@ src: url("/fonts/math/fraction-denominatordisplaystylegapmin5000-rulethickness1000.woff"); } @font-face { - font-family: denominatordisplaystyleshiftdown6000-rulethickness1000; - src: url("/fonts/math/fraction-denominatordisplaystyleshiftdown6000-rulethickness1000.woff"); + font-family: denominatordisplaystyleshiftdown6000-axisheight1000-rulethickness1000; + src: url("/fonts/math/fraction-denominatordisplaystyleshiftdown6000-axisheight1000-rulethickness1000.woff"); } @font-face { font-family: denominatorgapmin4000-rulethickness1000; src: url("/fonts/math/fraction-denominatorgapmin4000-rulethickness1000.woff"); } @font-face { - font-family: denominatorshiftdown3000-rulethickness1000; - src: url("/fonts/math/fraction-denominatorshiftdown3000-rulethickness1000.woff"); + font-family: denominatorshiftdown3000-axisheight1000-rulethickness1000; + src: url("/fonts/math/fraction-denominatorshiftdown3000-axisheight1000-rulethickness1000.woff"); } @font-face { font-family: numeratordisplaystylegapmin8000-rulethickness1000; src: url("/fonts/math/fraction-numeratordisplaystylegapmin8000-rulethickness1000.woff"); } @font-face { - font-family: numeratordisplaystyleshiftup2000-rulethickness1000; - src: url("/fonts/math/fraction-numeratordisplaystyleshiftup2000-rulethickness1000.woff"); + font-family: numeratordisplaystyleshiftup2000-axisheight1000-rulethickness1000; + src: url("/fonts/math/fraction-numeratordisplaystyleshiftup2000-axisheight1000-rulethickness1000.woff"); } @font-face { font-family: numeratorgapmin9000-rulethickness1000; src: url("/fonts/math/fraction-numeratorgapmin9000-rulethickness1000.woff"); } @font-face { - font-family: numeratorshiftup11000-rulethickness1000; - src: url("/fonts/math/fraction-numeratorshiftup11000-rulethickness1000.woff"); + font-family: numeratorshiftup11000-axisheight1000-rulethickness1000; + src: url("/fonts/math/fraction-numeratorshiftup11000-axisheight1000-rulethickness1000.woff"); } @font-face { font-family: rulethickness10000; @@ -177,7 +177,7 @@ </p> <hr/> <p> - <math display="block" style="font-family: denominatordisplaystyleshiftdown6000-rulethickness1000;"> + <math display="block" style="font-family: denominatordisplaystyleshiftdown6000-axisheight1000-rulethickness1000;"> <mspace id="ref0003" width="3em" height="1em" style="background: green"/> <mfrac> <mspace width="3em"/> @@ -198,7 +198,7 @@ </p> <hr/> <p> - <math style="font-family: denominatorshiftdown3000-rulethickness1000;"> + <math style="font-family: denominatorshiftdown3000-axisheight1000-rulethickness1000;"> <mspace id="ref0005" width="3em" height="1em" style="background: green"/> <mfrac> <mspace width="3em"/> @@ -219,7 +219,7 @@ </p> <hr/> <p> - <math display="block" style="font-family: numeratordisplaystyleshiftup2000-rulethickness1000;"> + <math display="block" style="font-family: numeratordisplaystyleshiftup2000-axisheight1000-rulethickness1000;"> <mspace id="ref0007" width="3em" depth="1em" style="background: green"/> <mfrac> @@ -241,7 +241,7 @@ </p> <hr/> <p> - <math style="font-family: numeratorshiftup11000-rulethickness1000;"> + <math style="font-family: numeratorshiftup11000-axisheight1000-rulethickness1000;"> <mspace id="ref0009" width="3em" depth="1em" style="background: green"/> <mfrac>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-parameters-2.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-parameters-2.html index ce2d299..9c363866 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-parameters-2.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-parameters-2.html
@@ -17,12 +17,12 @@ src: url("/fonts/math/stack-axisheight7000.woff"); } @font-face { - font-family: bottomdisplaystyleshiftdown5000; - src: url("/fonts/math/stack-bottomdisplaystyleshiftdown5000.woff"); + font-family: bottomdisplaystyleshiftdown5000-axisheight1000; + src: url("/fonts/math/stack-bottomdisplaystyleshiftdown5000-axisheight1000.woff"); } @font-face { - font-family: bottomshiftdown6000; - src: url("/fonts/math/stack-bottomshiftdown6000.woff"); + font-family: bottomshiftdown6000-axisheight1000; + src: url("/fonts/math/stack-bottomshiftdown6000-axisheight1000.woff"); } @font-face { font-family: displaystylegapmin4000; @@ -33,12 +33,12 @@ src: url("/fonts/math/stack-gapmin8000.woff"); } @font-face { - font-family: topdisplaystyleshiftup3000; - src: url("/fonts/math/stack-topdisplaystyleshiftup3000.woff"); + font-family: topdisplaystyleshiftup3000-axisheight1000; + src: url("/fonts/math/stack-topdisplaystyleshiftup3000-axisheight1000.woff"); } @font-face { - font-family: topshiftup9000; - src: url("/fonts/math/stack-topshiftup9000.woff"); + font-family: topshiftup9000-axisheight1000; + src: url("/fonts/math/stack-topshiftup9000-axisheight1000.woff"); } </style> <script> @@ -129,7 +129,7 @@ </p> <hr/> <p> - <math display="block" style="font-family: bottomdisplaystyleshiftdown5000;"> + <math display="block" style="font-family: bottomdisplaystyleshiftdown5000-axisheight1000;"> <mspace id="ref0002" width="3em" height="1em" style="background: green"/> <mfrac linethickness="0px"> <mspace width="3em"/> @@ -139,7 +139,7 @@ </p> <hr/> <p> - <math style="font-family: bottomshiftdown6000;"> + <math style="font-family: bottomshiftdown6000-axisheight1000;"> <mspace id="ref0003" width="3em" height="1em" style="background: green"/> <mfrac linethickness="0px"> <mspace width="3em"/> @@ -167,7 +167,7 @@ </p> <hr/> <p> - <math display="block" style="font-family: topdisplaystyleshiftup3000;"> + <math display="block" style="font-family: topdisplaystyleshiftup3000-axisheight1000;"> <mspace id="ref0006" width="3em" depth="1em" style="background: green"/> <mfrac linethickness="0px"> <mspace width="3em" height="1em" id="num0006" style="background: blue"/> @@ -177,7 +177,7 @@ </p> <hr/> <p> - <math style="font-family: topshiftup9000;"> + <math style="font-family: topshiftup9000-axisheight1000;"> <mspace id="ref0007" width="3em" depth="1em" style="background: green"/> <mfrac linethickness="0px"> <mspace width="3em" height="1em" id="num0007" style="background: blue"/>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/not-participating-to-parent-layout.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/not-participating-to-parent-layout.html new file mode 100644 index 0000000..89389fc --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/not-participating-to-parent-layout.html
@@ -0,0 +1,74 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Elements not participating to the layout of their parent</title> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#layout-algorithms"> +<meta name="assert" content="Verify that display: none and out-of-flow positioned elements do not participate to layout of their parent."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/layout-comparison.js"></script> +<script src="/mathml/support/mathml-fragments.js"></script> +<script> + var epsilon = 1; + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function runTests() { + + for (tag in MathMLFragments) { + if (!FragmentHelper.isValidChildOfMrow(tag) || + FragmentHelper.isEmpty(tag)) + continue; + // TODO: Add floats too? + ["display: none", + "position: absolute", + "position: fixed" + ].forEach(style => { + document.body.insertAdjacentHTML("beforeend", `<div style="position: absolute;">\ +<div style="display: inline-block"><math>${MathMLFragments[tag]}</math></div>\ +<div style="display: inline-block"><math>${MathMLFragments[tag]}</math></div>\ +</div>`); + var div = document.body.lastElementChild; + + var elementContainer = div.firstElementChild; + var elementContainerWidth = elementContainer.getBoundingClientRect().width; + var element = FragmentHelper.element(elementContainer); + FragmentHelper.forceNonEmptyElement(element); + var allowInvalid = true; + var child = FragmentHelper.appendChild(element, allowInvalid); + child.setAttribute("style", style); + + var referenceContainer = div.lastElementChild; + var referenceContainerWidth = referenceContainer.getBoundingClientRect().width; + var reference = FragmentHelper.element(referenceContainer); + FragmentHelper.forceNonEmptyElement(reference); + + var epsilon = 1; + + test(function() { + // FIXME(fwang): Feature detection should be done per-tag. + assert_true(MathMLFeatureDetection.has_mspace()); + assert_approx_equals(elementContainerWidth, referenceContainerWidth, epsilon); + }, `${tag} preferred width calculation is not affected by children with "${style}" style`); + + test(function() { + // FIXME(fwang): Feature detection should be done per-tag. + assert_true(MathMLFeatureDetection.has_mspace()); + compareLayout(element, reference, epsilon); + }, `${tag} layout is not affected by children with "${style}" style`); + + div.style = "display: none;"; // Hide the div after measurement. + }); + } + + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/clipboard-event-handlers.tentative.html b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/clipboard-event-handlers.tentative.html new file mode 100644 index 0000000..d293b15 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/clipboard-event-handlers.tentative.html
@@ -0,0 +1,84 @@ +<!DOCTYPE html> +<title>DocumentAndElementEventHandlers / clipboard events for MathML</title> +<link + rel="help" + href="https://mathml-refresh.github.io/mathml-core/#dom-and-javascript" +/> +<link + rel="help" + href="https://html.spec.whatwg.org/multipage/webappapis.html#documentandelementeventhandlers" +/> +<link + rel="help" + href="https://w3c.github.io/clipboard-apis/#clipboard-event-copy" +/> +<link + rel="help" + href="https://w3c.github.io/clipboard-apis/#clipboard-event-cut" +/> +<link + rel="help" + href="https://w3c.github.io/clipboard-apis/#clipboard-event-paste" +/> +<meta + name="assert" + content="MathMLElements incorporate a functional DocumentAndElementEventHandlers interface" +/> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="log"></div> +<math + oncopy="document.copyHappened = true" + oncut="document.cutHappened = true" + onpaste="document.pasteHappened = true" +> + <mi>E</mi> +</math> +<script> + const EVENTS = ["copy", "cut", "paste"]; + const el = document.querySelector("math"); + + function addEventListenerTest(name) { + async_test(test => { + el.addEventListener( + name, + test.step_func_done(e => { + assert_true( + true, + "MathML Elements should be able to receive ${name} events" + ); + }) + ); + const event = new ClipboardEvent(name, { + bubbles: true, + cancellable: true + }); + el.dispatchEvent(event); + }, `math.addEventListener for ${name}`); + } + + function evaluatedHandlerTest(name) { + const handlerName = "on" + name; + + test(() => { + const compiledHandler = el[handlerName]; + + assert_equals( + typeof compiledHandler, + "function", + `The ${handlerName} property must be a function` + ); + compiledHandler(); + assert_true( + window[name + "Happened"], + "Calling the handler must run the code" + ); + }, `${handlerName}: the content attribute must be compiled into a function as the corresponding property`); + } + + EVENTS.forEach(name => { + addEventListenerTest(name); + evaluatedHandlerTest(name); + }); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/css-inline-style-interface.tentative.html b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/css-inline-style-interface.tentative.html new file mode 100644 index 0000000..7089264 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/css-inline-style-interface.tentative.html
@@ -0,0 +1,57 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8" /> + <title>MathML 'ElementCSSInlineStyle` Mixin Tests</title> + <link + rel="help" + href="https://mathml-refresh.github.io/mathml-core/#dom-and-javascript" + /> + <style> + math * { + background-color: red; + } + </style> + <meta + name="assert" + content="MathMLElements incorporate a functional ElementCSSInlineStyle interface" + /> + <script src="/mathml/support/mathml-fragments.js"></script> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + </head> + <body> + <span + >This tests the presence and functionality of features of the + `ElementCSSInlineStyle` interface for MathMLElements</span + > + <math></math> + <script> + let mathEl = document.querySelector("math"); + + test(function() { + mathEl.style.backgroundColor = "lime"; + assert_equals( + getComputedStyle(mathEl).backgroundColor, + "rgb(0, 255, 0)", + "The applied background should be green." + ); + }, `The <math> element style property should be present and be functional.`); + + Object.keys(MathMLFragments).forEach(elName => { + mathEl.innerHTML = MathMLFragments[elName]; + + test(function() { + let el = FragmentHelper.element(mathEl); + el.style.backgroundColor = "blue"; + + assert_equals( + getComputedStyle(el).backgroundColor, + "rgb(0, 0, 255)", + "The applied background should be blue." + ); + }, `The ${elName}'s style property should be present and be functional.`); + }); + </script> + </body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/html-or-foreign-element-interfaces.tentative.html b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/html-or-foreign-element-interfaces.tentative.html new file mode 100644 index 0000000..1fcaf6c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/html-or-foreign-element-interfaces.tentative.html
@@ -0,0 +1,114 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8" /> + <title>MathML 'HTMLOrForeignElement` Mixin Tests</title> + <link + rel="help" + href="https://mathml-refresh.github.io/mathml-core/#dom-and-javascript" + /> + <style> + mi { + background-color: red; + } + :focus { + background-color: rgb(0, 255, 0); + } + </style> + <meta + name="assert" + content="MathMLElements incorporate a functional HTMLOrForeignElement interface" + /> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + </head> + <body tabindex="-1"> + <span tabindex="-1" + >This tests the presence and functionality of features of + `HTMLOrForeignElement` (currently `HTMLOrSVGElement`)</span + > + <math tabindex="-1"> + <mi>E</mi> + </math> + </body> + <script> + // spot check the functionality of several interfaces + let el = document.querySelector("mi"); + let mathEl = document.querySelector("math"); + + // this really belongs in + // https://github.com/web-platform-tests/wpt/blob/master/html/dom/elements/global-attributes/dataset.html + // it is here tentatively + test(function() { + var mathml = document.createElementNS( + "http://www.w3.org/1998/Math/MathML", + "math" + ); + assert_true(mathml.dataset instanceof DOMStringMap); + }, "MathML elements should have a .dataset"); + + // exercise some basic tests on .dataset + test(function() { + assert_equals( + Object.keys(el.dataset).toString(), + "", + "The .dataset property should be present" + ); + + el.setAttribute("data-one", "x"); + el.setAttribute("data-two", "y"); + + assert_equals( + el.dataset.one, + "x", + '.one should be "x" after setting the data-one attribute' + ); + assert_equals( + el.dataset.two, + "y", + '.one should be "y" after setting the data-two attribute' + ); + + el.dataset.one = "o"; + assert_equals( + el.getAttribute("data-one"), + "o", + 'the data-one attribute should reflect a change to dataset.one and contain "o"' + ); + }, "The dataset property should be present and be functional."); + + test(function() { + assert_equals(mathEl.tabIndex, -1); + }, "MathML elements should have a tabIndex property"); + + promise_test(function() { + function focus() { + mathEl.focus(); + return Promise.resolve(); + } + + return focus().then(() => { + assert_equals( + getComputedStyle(mathEl).backgroundColor, + "rgb(0, 255, 0)", + "MathML elements with tabindex=-1 should be programmatically focusable and apply :focus" + ); + }); + }, "MathML elements should work with focus predictably"); + + promise_test(function() { + function blur() { + mathEl.blur(); + return Promise.resolve(); + } + + return blur().then(() => { + assert_equals( + getComputedStyle(mathEl).backgroundColor, + "rgba(0, 0, 0, 0)", + "MathML elements with tabindex=-1 be programmatically blur() able" + ); + }); + }, "MathML elements should work with blur predictably"); + </script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/math-global-event-handlers.tentative.html b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/math-global-event-handlers.tentative.html new file mode 100644 index 0000000..92e1863 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/math-global-event-handlers.tentative.html
@@ -0,0 +1,108 @@ +<!DOCTYPE html> +<title>MathMLElement GlobalEventHandlers</title> +<link rel="author" title="Brian Kardell" href="mailto:bkardell@igalia.com" /> +<link + rel="help" + href="https://mathml-refresh.github.io/mathml-core/#dom-and-javascript" +/> +<link + rel="help" + href="https://html.spec.whatwg.org/multipage/#event-handler-idl-attributes" +/> +<link + rel="help" + href="https://html.spec.whatwg.org/multipage/#event-handler-content-attributes" +/> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/WebIDLParser.js"></script> + +<script> + "use strict"; + setup({ explicit_done: true }); + + // basic pattern lifted from /html/webappapis/scripting/events/event-handler-all-global-events.html + fetch("/interfaces/html.idl") + .then(res => res.text()) + .then(htmlIDL => { + const parsedHTMLIDL = WebIDL2.parse(htmlIDL); + const globalEventHandlers = parsedHTMLIDL.find( + idl => idl.name === "GlobalEventHandlers" + ); + + // onerror is too special + const names = globalEventHandlers.members + .map(member => member.name) + .filter(name => name !== "onerror"); + + for (const name of names) { + const withoutOn = name.substring(2); + + test(() => { + const location = MathMLElement.prototype; + assert_true( + location.hasOwnProperty(name), + `${location.constructor.name} has an own property named "${name}"` + ); + + assert_false( + name in Element.prototype, + `Element.prototype must not contain a "${name}" property` + ); + }, `${name}: must be on the appropriate locations for GlobalEventHandlers`); + + test(() => { + const location = document.createElementNS( + "http://www.w3.org/1998/Math/MathML", + "math" + ); + + assert_equals( + location[name], + null, + `The default value of the property is null for a ${ + location.constructor.name + } instance` + ); + }, `${name}: the default value must be null`); + + test(() => { + const el = document.createElementNS( + "http://www.w3.org/1998/Math/MathML", + "math" + ); + el.setAttribute(name, `window.${name}Happened = true;`); + const compiledHandler = el[name]; + + assert_equals( + typeof compiledHandler, + "function", + `The ${name} property must be a function` + ); + compiledHandler(); + assert_true( + window[name + "Happened"], + "Calling the handler must run the code" + ); + }, `${name}: the content attribute must be compiled into a function as the corresponding property`); + + test(() => { + const element = document.createElementNS( + "http://www.w3.org/1998/Math/MathML", + "math" + ); + element[name] = e => { + assert_equals( + e.currentTarget, + element, + "The event must be fired at the <math> element" + ); + }; + + element.dispatchEvent(new Event(withoutOn)); + }, `${name}: dispatching an Event at a <math> element must trigger element.${name}`); + } + + done(); + }); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/support/box-comparison.js b/third_party/blink/web_tests/external/wpt/mathml/support/box-comparison.js index 77d145b3..c46808f 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/support/box-comparison.js +++ b/third_party/blink/web_tests/external/wpt/mathml/support/box-comparison.js
@@ -22,7 +22,7 @@ if (!direction) direction = "ltr"; - document.body.insertAdjacentHTML("beforeend", `<div>\ + document.body.insertAdjacentHTML("beforeend", `<div style="position: absolute;">\ <math><mrow dir="${direction}">${MathMLFragments[tag]}</mrow></math>\ <math><mrow dir="${direction}">${MathMLFragments[tag]}</mrow></math>\ </div>`); @@ -64,7 +64,7 @@ if (!FragmentHelper.isValidChildOfMrow(tag)) throw `Invalid argument: ${tag}`; - document.body.insertAdjacentHTML("beforeend", `<div>\ + document.body.insertAdjacentHTML("beforeend", `<div style="position: absolute;">\ <math>${MathMLFragments[tag]}</math>\ <math>${MathMLFragments[tag]}</math>\ </div>`);
diff --git a/third_party/blink/web_tests/external/wpt/mathml/support/layout-comparison.js b/third_party/blink/web_tests/external/wpt/mathml/support/layout-comparison.js index b1a6899..f9111d0 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/support/layout-comparison.js +++ b/third_party/blink/web_tests/external/wpt/mathml/support/layout-comparison.js
@@ -37,36 +37,46 @@ } } -function compareLayout(element, reference, epsilon) { - if (element.children.length != reference.children.length) - throw "Reference should have the same number of children." +function participateToParentLayout(child) { + var style = window.getComputedStyle(child); + return style.getPropertyValue("display") !== "none" && + style.getPropertyValue("position") !== "absolute" && + style.getPropertyValue("position") !== "fixed"; +} +function childrenParticipatingToLayout(element) { + var children = []; + Array.from(element.children).forEach(child => { + if (participateToParentLayout(child)) + children.push(child); + }) + return children; +} + +function compareLayout(element, reference, epsilon) { // Compare sizes of elements and children. var param = getWritingMode(element, reference); compareSize(element, reference, epsilon); var elementBox = element.getBoundingClientRect(); var referenceBox = reference.getBoundingClientRect(); - for (var i = 0; i < element.children.length; i++) { - var childDisplay = window. - getComputedStyle(element.children[i]).getPropertyValue("display"); - var referenceChildDisplay = window. - getComputedStyle(reference.children[i]).getPropertyValue("display"); - if (referenceChildDisplay !== childDisplay) - throw "compareLayout: children of reference should have the same display values."; - if (childDisplay === "none") - continue; - compareSize(element.children[i], reference.children[i], epsilon); + var elementChildren = childrenParticipatingToLayout(element); + var referenceChildren = childrenParticipatingToLayout(reference); + if (elementChildren.length != referenceChildren.length) + throw "Reference should have the same number of children participating to layout." - var childBox = element.children[i].getBoundingClientRect(); - var referenceChildBox = reference.children[i].getBoundingClientRect(); + for (var i = 0; i < elementChildren.length; i++) { + compareSize(elementChildren[i], referenceChildren[i], epsilon); + + var childBox = elementChildren[i].getBoundingClientRect(); + var referenceChildBox = referenceChildren[i].getBoundingClientRect(); switch(param.mode) { case "horizontal-tb": - if (!param.rtl) - throw "compareLayout: unexpected writing-mode value"; - assert_approx_equals(elementBox.right - childBox.right, + assert_approx_equals(param.rtl ? + elementBox.right - childBox.right : + childBox.left - elementBox.left, referenceChildBox.left - referenceBox.left, epsilon, `inline position (child ${i})`);
diff --git a/third_party/blink/web_tests/external/wpt/mathml/support/mathml-fragments.js b/third_party/blink/web_tests/external/wpt/mathml/support/mathml-fragments.js index 013171c..7c7b003 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/support/mathml-fragments.js +++ b/third_party/blink/web_tests/external/wpt/mathml/support/mathml-fragments.js
@@ -138,17 +138,25 @@ return fragment.getElementsByClassName('element')[0]; }, - forceNonEmptyElement: function(fragment) { + appendChild: function(fragment, allowInvalid) { var element = this.element(fragment) || fragment; - if (element.firstElementChild) - return element.firstElementChild; - if (element.classList.contains("mathml-container")) - return element.appendChild(this.createElement("mrow")); if (element.classList.contains("foreign-container")) { var el = document.createElement("span"); el.textContent = "a"; return element.appendChild(el); } - throw "Cannot make the element nonempty"; + if (element.classList.contains("mathml-container") || allowInvalid) { + var el = this.createElement("mi"); + el.textContent = "a"; + return element.appendChild(el); + } + throw "Cannot append child to the element"; + }, + + forceNonEmptyElement: function(fragment) { + var element = this.element(fragment) || fragment; + if (element.firstElementChild) + return element.firstElementChild; + return this.appendChild(fragment); } }
diff --git a/third_party/blink/web_tests/external/wpt/mathml/tools/fractions.py b/third_party/blink/web_tests/external/wpt/mathml/tools/fractions.py index 8652806..42cfe46 100755 --- a/third_party/blink/web_tests/external/wpt/mathml/tools/fractions.py +++ b/third_party/blink/web_tests/external/wpt/mathml/tools/fractions.py
@@ -35,8 +35,8 @@ v1 = 6 * mathfont.em v2 = 1 * mathfont.em -f = mathfont.create("fraction-denominatordisplaystyleshiftdown%d-rulethickness%d" % (v1, v2)) -f.math.AxisHeight = 0 +f = mathfont.create("fraction-denominatordisplaystyleshiftdown%d-axisheight%d-rulethickness%d" % (v1, v2, v2)) +f.math.AxisHeight = v2 f.math.FractionDenominatorDisplayStyleGapMin = 0 f.math.FractionDenominatorDisplayStyleShiftDown = v1 f.math.FractionDenominatorGapMin = 0 @@ -65,8 +65,8 @@ v1 = 3 * mathfont.em v2 = 1 * mathfont.em -f = mathfont.create("fraction-denominatorshiftdown%d-rulethickness%d" % (v1, v2)) -f.math.AxisHeight = 0 +f = mathfont.create("fraction-denominatorshiftdown%d-axisheight%d-rulethickness%d" % (v1, v2, v2)) +f.math.AxisHeight = v2 f.math.FractionDenominatorDisplayStyleGapMin = 0 f.math.FractionDenominatorDisplayStyleShiftDown = 0 f.math.FractionDenominatorGapMin = 0 @@ -95,8 +95,8 @@ v1 = 2 * mathfont.em v2 = 1 * mathfont.em -f = mathfont.create("fraction-numeratordisplaystyleshiftup%d-rulethickness%d" % (v1, v2)) -f.math.AxisHeight = 0 +f = mathfont.create("fraction-numeratordisplaystyleshiftup%d-axisheight%d-rulethickness%d" % (v1, v2, v2)) +f.math.AxisHeight = v2 f.math.FractionDenominatorDisplayStyleGapMin = 0 f.math.FractionDenominatorDisplayStyleShiftDown = 0 f.math.FractionDenominatorGapMin = 0 @@ -125,8 +125,8 @@ v1 = 11 * mathfont.em v2 = 1 * mathfont.em -f = mathfont.create("fraction-numeratorshiftup%d-rulethickness%d" % (v1, v2)) -f.math.AxisHeight = 0 +f = mathfont.create("fraction-numeratorshiftup%d-axisheight%d-rulethickness%d" % (v1, v2, v2)) +f.math.AxisHeight = v2 f.math.FractionDenominatorDisplayStyleGapMin = 0 f.math.FractionDenominatorDisplayStyleShiftDown = 0 f.math.FractionDenominatorGapMin = 0
diff --git a/third_party/blink/web_tests/external/wpt/mathml/tools/stacks.py b/third_party/blink/web_tests/external/wpt/mathml/tools/stacks.py index 81f79be..18626291 100755 --- a/third_party/blink/web_tests/external/wpt/mathml/tools/stacks.py +++ b/third_party/blink/web_tests/external/wpt/mathml/tools/stacks.py
@@ -14,10 +14,11 @@ f.math.StackTopShiftUp = 0 mathfont.save(f) -v = 5 * mathfont.em -f = mathfont.create("stack-bottomdisplaystyleshiftdown%d" % v) -f.math.AxisHeight = 0 -f.math.StackBottomDisplayStyleShiftDown = v +v1 = 5 * mathfont.em +v2 = 1 * mathfont.em +f = mathfont.create("stack-bottomdisplaystyleshiftdown%d-axisheight%d" % (v1, v2)) +f.math.AxisHeight = v2 +f.math.StackBottomDisplayStyleShiftDown = v1 f.math.StackBottomShiftDown = 0 f.math.StackDisplayStyleGapMin = 0 f.math.StackGapMin = 0 @@ -25,11 +26,12 @@ f.math.StackTopShiftUp = 0 mathfont.save(f) -v = 6 * mathfont.em -f = mathfont.create("stack-bottomshiftdown%d" % v) -f.math.AxisHeight = 0 +v1 = 6 * mathfont.em +v2 = 1 * mathfont.em +f = mathfont.create("stack-bottomshiftdown%d-axisheight%d" % (v1, v2)) +f.math.AxisHeight = v2 f.math.StackBottomDisplayStyleShiftDown = 0 -f.math.StackBottomShiftDown = v +f.math.StackBottomShiftDown = v1 f.math.StackDisplayStyleGapMin = 0 f.math.StackGapMin = 0 f.math.StackTopDisplayStyleShiftUp = 0 @@ -58,24 +60,26 @@ f.math.StackTopShiftUp = 0 mathfont.save(f) -v = 3 * mathfont.em -f = mathfont.create("stack-topdisplaystyleshiftup%d" % v) -f.math.AxisHeight = 0 +v1 = 3 * mathfont.em +v2 = 1 * mathfont.em +f = mathfont.create("stack-topdisplaystyleshiftup%d-axisheight%d" % (v1, v2)) +f.math.AxisHeight = v2 f.math.StackBottomDisplayStyleShiftDown = 0 f.math.StackBottomShiftDown = 0 f.math.StackDisplayStyleGapMin = 0 f.math.StackGapMin = 0 -f.math.StackTopDisplayStyleShiftUp = v +f.math.StackTopDisplayStyleShiftUp = v1 f.math.StackTopShiftUp = 0 mathfont.save(f) -v = 9 * mathfont.em -f = mathfont.create("stack-topshiftup%d" % v) -f.math.AxisHeight = 0 +v1 = 9 * mathfont.em +v2 = 1 * mathfont.em +f = mathfont.create("stack-topshiftup%d-axisheight%d" % (v1, v2)) +f.math.AxisHeight = v2 f.math.StackBottomDisplayStyleShiftDown = 0 f.math.StackBottomShiftDown = 0 f.math.StackDisplayStyleGapMin = 0 f.math.StackGapMin = 0 f.math.StackTopDisplayStyleShiftUp = 0 -f.math.StackTopShiftUp = v +f.math.StackTopShiftUp = v1 mathfont.save(f)
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerlock/pointerevent_movementxy.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerlock/pointerevent_movementxy.html index 2d6147d..260ef48 100644 --- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerlock/pointerevent_movementxy.html +++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerlock/pointerevent_movementxy.html
@@ -38,16 +38,24 @@ </style> <script> var expectedPointerId = NaN; - var startSummation = false; - var lastScreenX = 0; - var lastScreenY = 0; + var lastScreenX = null; + var lastScreenY = null; function resetTestState() { - startSummation = false; - lastScreenX = 0; - lastScreenY = 0; + lastScreenX = null; + lastScreenY = null; } + var nonPointermoveEventList = [ + "pointerover", + "pointerenter", + "pointerdown", + "pointerup", + "pointerout", + "pointerleave", + "gotpointercapture", + "lostpointercapture"]; + function injectInput(pointerType) { var pointerId = pointerType + "Pointer1"; return new test_driver.Actions() @@ -55,7 +63,9 @@ .pointerMove(0, 0, {origin: box1}) .pointerDown() .pointerMove(20, 30, {origin: box1}) - .pointerMove(60, 40, {origin: box1}) + .pointerMove(50, 40, {origin: box1}) + .pointerMove(80, 30, {origin: box1}) + .pointerMove(110, 20, {origin: box1}) .pointerMove(0, 0, {origin: box2}) .pointerUp() .send(); @@ -65,15 +75,31 @@ var test_pointerEvent = setup_pointerevent_test("pointerevent attributes", ALL_POINTERS); [document, document.getElementById('innerFrame').contentDocument].forEach(function(element) { + nonPointermoveEventList.forEach(function(eventName) { + on_event(element, eventName, function (event) { + if (lastScreenX && lastScreenY) { + test_pointerEvent.step(function() { + assert_equals(event.movementX, 0, "movementX should be 0 for event other than pointermove."); + assert_equals(event.movementY, 0, "movementY should be 0 for event other than pointermove."); + }); + // Reset when entering the new frame. + if (event.type == "pointerenter") { + lastScreenX = null; + lastScreenY = null; + } + } + }); + }); + on_event(element, 'pointermove', function (event) { - if (startSummation) { - test_pointerEvent.step(function() { + test_pointerEvent.step(function() { + if (lastScreenX && lastScreenY) { assert_equals(event.movementX, event.screenX - lastScreenX, "movementX should be the delta between current event's and last event's screenX"); assert_equals(event.movementY, event.screenY - lastScreenY, "movementY should be the delta between current event's and last event's screenY"); - }); - lastScreenX = event.screenX; - lastScreenY = event.screenY; - } + } + }); + lastScreenX = event.screenX; + lastScreenY = event.screenY; }); }); on_event(document.querySelector('#box1'), 'pointerdown', function(event) { @@ -81,12 +107,10 @@ test_pointerEvent.step(function() { assert_equals(event.pointerType, expectedPointerType, "Use the instructed pointer type."); }); - startSummation = true; lastScreenX = event.screenX; lastScreenY = event.screenY; }); on_event(document.querySelector('#box2'), 'pointerup', function(event) { - startSummation = false; test_pointerEvent.done(); });
diff --git a/third_party/blink/web_tests/external/wpt/pointerlock/movementX_Y_basic.html b/third_party/blink/web_tests/external/wpt/pointerlock/movementX_Y_basic.html index b09d896..a317130 100644 --- a/third_party/blink/web_tests/external/wpt/pointerlock/movementX_Y_basic.html +++ b/third_party/blink/web_tests/external/wpt/pointerlock/movementX_Y_basic.html
@@ -128,8 +128,8 @@ } function run_test() { - x = window.innerWidth / 2; - y = window.innerHeight / 2; + x = Math.round(window.innerWidth / 2); + y = Math.round(window.innerHeight / 2); var actions = new test_driver.Actions(); actions.pointerMove(x, y) .pointerDown()
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt index f123296..4619031b 100644 --- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt
@@ -7,11 +7,9 @@ PASS Verify a cors worker script served by a service worker fails shared worker start. PASS Verify a no-cors cross-origin worker script served by a service worker fails dedicated worker start. PASS Verify a no-cors cross-origin worker script served by a service worker fails shared worker start. -PASS Register a service worker for worker subresource interception tests. FAIL Requests on a dedicated worker controlled by a service worker. assert_equals: expected "This load was successfully intercepted." but got "{\"error\": {\"message\": \"\", \"code\": 404}}" PASS Requests on a shared worker controlled by a service worker. FAIL Requests on a dedicated worker nested in a dedicated worker and controlled by a service worker assert_equals: expected "This load was successfully intercepted." but got "{\"error\": {\"message\": \"\", \"code\": 404}}" FAIL Requests on a dedicated worker nested in a shared worker and controlled by a service worker assert_equals: expected "This load was successfully intercepted." but got "Unexpected error! Worker is not defined" -PASS Unregister a service worker for subresource interception tests. Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/worker-interception.https.html b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/worker-interception.https.html index 302a214..204638a 100644 --- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/worker-interception.https.html +++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/worker-interception.https.html
@@ -7,8 +7,6 @@ <body> <script> -// ========== Worker main resource interception tests ========== - async function setup_service_worker(t, service_worker_url, scope) { const r = await service_worker_unregister_and_register( t, service_worker_url, scope); @@ -16,6 +14,8 @@ await wait_for_state(t, r.installing, 'activated'); } +// ========== Worker main resource interception tests ========== + promise_test(async t => { const worker_url = 'resources/dummy-synthesized-worker.js?dedicated'; const service_worker_url = 'resources/dummy-worker-interceptor.js'; @@ -126,15 +126,6 @@ // ========== Worker subresource interception tests ========== -const scope_for_subresource_interception = 'resources/load_worker.js'; - -promise_test(async t => { - const service_worker_url = 'resources/worker-load-interceptor.js'; - const r = await service_worker_unregister_and_register( - t, service_worker_url, scope_for_subresource_interception); - await wait_for_state(t, r.installing, 'activated'); -}, 'Register a service worker for worker subresource interception tests.'); - // Do not call this function multiple times without waiting for the promise // resolution because this sets new event handlers on |worker|. // TODO(nhiroki): To isolate multiple function calls, use MessagePort instead of @@ -156,33 +147,58 @@ assert_equals(data, 'This load was successfully intercepted.'); } -async function subresource_test(worker) { - await request_on_worker(worker, 'xhr'); - await request_on_worker(worker, 'fetch'); - await request_on_worker(worker, 'importScripts'); +// TODO(nhiroki): For optimization, register a service worker just once in an +// initial promise test. + +function dedicated_worker_subresource_test(worker_url, scope, description) { + promise_test(async t => { + const service_worker_url = 'resources/worker-load-interceptor.js'; + await setup_service_worker(t, service_worker_url, scope); + const worker = new Worker(worker_url); + + await request_on_worker(worker, 'xhr'); + await request_on_worker(worker, 'fetch'); + await request_on_worker(worker, 'importScripts'); + }, description); } -promise_test(async t => { - await subresource_test(new Worker('resources/load_worker.js')); -}, 'Requests on a dedicated worker controlled by a service worker.'); +function shared_worker_subresource_test(worker_url, scope, description) { + promise_test(async t => { + const service_worker_url = 'resources/worker-load-interceptor.js'; + await setup_service_worker(t, service_worker_url, scope); + const worker = new SharedWorker(worker_url); -promise_test(async t => { - await subresource_test(new SharedWorker('resources/load_worker.js')); -}, 'Requests on a shared worker controlled by a service worker.'); + await request_on_worker(worker, 'xhr'); + await request_on_worker(worker, 'fetch'); + await request_on_worker(worker, 'importScripts'); + }, description); +} -promise_test(async t => { - await subresource_test(new Worker('resources/nested_load_worker.js')); -}, 'Requests on a dedicated worker nested in a dedicated worker and ' + - 'controlled by a service worker'); +dedicated_worker_subresource_test( + 'resources/load_worker.js?dedicated', + 'resources/load_worker.js?dedicated', + 'Requests on a dedicated worker controlled by a service worker.'); -promise_test(async t => { - await subresource_test(new SharedWorker('resources/nested_load_worker.js')); -}, 'Requests on a dedicated worker nested in a shared worker and controlled ' + - 'by a service worker'); +shared_worker_subresource_test( + 'resources/load_worker.js?shared', + 'resources/load_worker.js?shared', + 'Requests on a shared worker controlled by a service worker.'); -promise_test(async t => { - await service_worker_unregister(t, scope_for_subresource_interception); -}, 'Unregister a service worker for subresource interception tests.'); +dedicated_worker_subresource_test( + 'resources/nested_load_worker.js?dedicated', + // TODO(nhiroki): This scope is wrong. This should be + // 'resources/load_worker.js?dedicated'. + 'resources/nested_load_worker.js?dedicated', + 'Requests on a dedicated worker nested in a dedicated worker and ' + + 'controlled by a service worker'); + +shared_worker_subresource_test( + 'resources/nested_load_worker.js?shared', + // TODO(nhiroki): This scope is wrong. This should be + // 'resources/load_worker.js?shared'. + 'resources/nested_load_worker.js?shared', + 'Requests on a dedicated worker nested in a shared worker and controlled ' + + 'by a service worker'); </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/discard-on-discard.html b/third_party/blink/web_tests/external/wpt/svg/animations/discard-on-discard.html new file mode 100644 index 0000000..4a6b9f93 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/animations/discard-on-discard.html
@@ -0,0 +1,54 @@ +<!doctype html> +<html> +<meta charset="utf-8"> +<title>Test the behavior of one discard applied on another discard</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/SVGAnimationTestCase-testharness.js"></script> + +<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <animate id="anim" attributeName="visibility" to="visible" begin="0s" end="5s"/> + <rect x="0" y="0" width="50" height="50" fill="rgb(255, 0, 0)"> + <set id="set1" attributeName="fill" to="rgb(0, 255, 0)" begin="2s" fill="freeze"/> + <set id="set2" attributeName="fill" to="rgb(0, 0, 255)" begin="3s" fill="freeze"/> + </rect> + + <discard id="discard1" xlink:href="#set1" begin="1s"/> + <discard id="discard2" xlink:href="#set2"/> + <discard id="discard3" xlink:href="#discard1"/> +</svg> + +<script> +var rootSVGElement = document.querySelector("svg"); +var epsilon = 1.0; + +// Setup animation test +function sample1() { + expectFillColor(rect1, 255, 0, 0); +} + +function sample2() { + expectFillColor(rect1, 0, 255, 0); +} + +smil_async_test((t) => { + var rects = rootSVGElement.ownerDocument.getElementsByTagName("rect"); + rect1 = rects[0]; + + const expectedValues = [ + // [animationId, time, sampleCallback] + ["anim", 0.0, sample1], + ["anim", 0.01, sample1], + ["anim", 2.0, sample2], + ["anim", 2.01, sample2], + ["anim", 3.0, sample2], + ["anim", 3.01, sample2] + ]; + + runAnimationTest(t, expectedValues); +}); + +window.animationStartsImmediately = true; + +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/force-use-shadow-tree-recreation-while-animating.html b/third_party/blink/web_tests/external/wpt/svg/animations/force-use-shadow-tree-recreation-while-animating.html new file mode 100644 index 0000000..7a60e02 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/animations/force-use-shadow-tree-recreation-while-animating.html
@@ -0,0 +1,65 @@ +<!doctype html> +<html> +<meta charset="utf-8"> +<title>This test forces use shadow tree recreation while an animating is running</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/SVGAnimationTestCase-testharness.js"></script> + +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd"> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + +<defs> + <rect id="rect" width="10" height="100" fill="red"> + <animate id="an1" attributeName="width" fill="freeze" from="10" to="100" begin="0s" dur="4s"/> + </rect> +</defs> + +<use xlink:href="#rect"/> + +</svg> + +<script> +var rootSVGElement = document.querySelector("svg"); +var epsilon = 1.0; + +// Setup animation test +function sample1() { + assert_approx_equals(rect.width.animVal.value, 10, epsilon); + assert_equals(rect.width.baseVal.value, 10); +} + +function sample2() { + assert_approx_equals(rect.width.animVal.value, 55, epsilon); + assert_equals(rect.width.baseVal.value, 10); +} + +function forceUseShadowTreeRecreation() { + rect.setAttribute("fill", "green"); +} + +function sample3() { + assert_approx_equals(rect.width.animVal.value, 100, epsilon); + assert_equals(rect.width.baseVal.value, 10); +} + +smil_async_test((t) => { + rect = rootSVGElement.ownerDocument.getElementsByTagName("rect")[0]; + + const expectedValues = [ + // [animationId, time, sampleCallback] + ["an1", 0.0, sample1], + ["an1", 1.999, sample2], + ["an1", 2.0, forceUseShadowTreeRecreation], + ["an1", 2.001, sample2], + ["an1", 4.0, sample3], + ["an1", 60.0, sample3], + ]; + + runAnimationTest(t, expectedValues); +}); + +window.animationStartsImmediately = true; + +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/multiple-animations-ending.html b/third_party/blink/web_tests/external/wpt/svg/animations/multiple-animations-ending.html new file mode 100644 index 0000000..a9b7853b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/animations/multiple-animations-ending.html
@@ -0,0 +1,421 @@ +<!doctype html> +<html> +<meta charset="utf-8"> +<title>This checks the effect on multiple animations ending on one target</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/SVGAnimationTestCase-testharness.js"></script> + +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd"> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + +<!-- Test that the first element can end while others continue without crashing, and the second + can end and remain frozen. Also test that a third element can animate after the second has ended + but that the result is still to return to the second animation's freeze position. --> +<rect x='0' y='0' width='50' height='50' fill='green'> + <animate id="an1" attributeName='x' from='0' to='100' begin='0s' dur='1s' /> + <animate id="an2" attributeName='x' from='200' to='250' begin='1.5s' dur='1s' fill='freeze' /> + <animate id="an3" attributeName='x' from='50' to='0' begin='2.5s' dur='0.5s' /> +</rect> + +<!-- Test that a second element can take priority over the first from 0-1s, then + test that the first element can animate for 1s, and finally test that the + second element can once again animate after the first has ended. After all + animations end, test that they are removed and the rect returns to its home. --> +<rect x='200' y='75' width='50' height='50' fill='green'> + <animate id="an4" attributeName='x' from='0' to='10' begin='1s' dur='1s'/> + <animate id="an5" attributeName='x' from='100' to='0' begin='0s' dur='2.5s'/> +</rect> + +<!-- Test that a repeating animation can take priority over another animation, and that the + end state is the second animation's freeze value. Also test that, after a pause, a third + animation can take over and have its freeze value satisfied at the end. --> +<rect x='0' y='150' width='50' height='50' fill='green'> + <animate id="an6" attributeName='x' from='200' to='240' begin='0s' dur='2s' fill='freeze'/> + <animate id="an7" attributeName='x' from='0' to='5' begin='1s' dur='0.1s' repeatCount="5" fill='freeze'/> + <animate id="an8" attributeName='x' from='250' to='150' begin='3s' dur='1s' fill='freeze'/> +</rect> + +<!-- Test that 4 animations can animate a rect in 20px 'steps' and that correct freeze values are + honored even though the animation elements are specified in non-sequential order. Also test + that two repeating animations (active for only a short duration) only momentarily + affect the overall animation and are correctly removed. --> +<rect x='0' y='225' width='50' height='50' fill='green'> + <animate id="an9" attributeName='x' from='200' to='250' begin='1.6s' dur='0.1s' repeatCount="2" fill='remove'/> + <animate id="anA" attributeName='x' from='160' to='180' begin='3s' dur='0.5s' fill='freeze'/> + <animate id="anB" attributeName='x' from='110' to='130' begin='2s' dur='0.5s' fill='freeze'/> + <animate id="anC" attributeName='x' from='10' to='30' begin='0s' dur='0.5s' fill='freeze'/> + <animate id="anD" attributeName='x' from='60' to='80' begin='1s' dur='0.5s' fill='freeze'/> + <animate id="anE" attributeName='x' from='200' to='250' begin='3.6s' dur='0.1s' repeatCount="2" fill='remove'/> +</rect> + +</svg> + +<script> +var rootSVGElement = document.querySelector("svg"); +var epsilon = 1.0; + +// Setup animation test +function sample1() { + assert_approx_equals(rect1.x.animVal.value, 0, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 100, epsilon); + assert_equals(rect2.x.baseVal.value, 200); + + assert_approx_equals(rect3.x.animVal.value, 200, epsilon); + assert_equals(rect3.x.baseVal.value, 0); + + assert_approx_equals(rect4.x.animVal.value, 10, epsilon); + assert_equals(rect4.x.baseVal.value, 0); +} + +function sample2() { + assert_approx_equals(rect1.x.animVal.value, 50, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 80, epsilon); + assert_equals(rect2.x.baseVal.value, 200); + + assert_approx_equals(rect3.x.animVal.value, 210, epsilon); + assert_equals(rect3.x.baseVal.value, 0); + + assert_approx_equals(rect4.x.animVal.value, 30, epsilon); + assert_equals(rect4.x.baseVal.value, 0); +} + +function sample3() { + assert_approx_equals(rect1.x.animVal.value, 50, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 80, epsilon); + assert_equals(rect2.x.baseVal.value, 200); + + assert_approx_equals(rect3.x.animVal.value, 210, epsilon); + assert_equals(rect3.x.baseVal.value, 0); + + assert_approx_equals(rect4.x.animVal.value, 30, epsilon); + assert_equals(rect4.x.baseVal.value, 0); +} + +function sample4() { + assert_approx_equals(rect1.x.animVal.value, 50, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 80, epsilon); + assert_equals(rect2.x.baseVal.value, 200); + + assert_approx_equals(rect3.x.animVal.value, 210, epsilon); + assert_equals(rect3.x.baseVal.value, 0); + + assert_approx_equals(rect4.x.animVal.value, 30, epsilon); + assert_equals(rect4.x.baseVal.value, 0); +} + +function sample5() { + assert_approx_equals(rect1.x.animVal.value, 100, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 60, epsilon); + assert_equals(rect2.x.baseVal.value, 200); + + assert_approx_equals(rect3.x.animVal.value, 220, epsilon); + assert_equals(rect3.x.baseVal.value, 0); + + assert_approx_equals(rect4.x.animVal.value, 30, epsilon); + assert_equals(rect4.x.baseVal.value, 0); +} + +function sample6() { + assert_approx_equals(rect1.x.animVal.value, 0, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 0, epsilon); + assert_equals(rect2.x.baseVal.value, 200); + + assert_approx_equals(rect3.x.animVal.value, 0, epsilon); + assert_equals(rect3.x.baseVal.value, 0); + + assert_approx_equals(rect4.x.animVal.value, 60, epsilon); + assert_equals(rect4.x.baseVal.value, 0); +} + +function sample7() { + assert_approx_equals(rect1.x.animVal.value, 0, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 0, epsilon); + assert_equals(rect2.x.baseVal.value, 200); + + assert_approx_equals(rect3.x.animVal.value, 0, epsilon); + assert_equals(rect3.x.baseVal.value, 0); + + assert_approx_equals(rect4.x.animVal.value, 60, epsilon); + assert_equals(rect4.x.baseVal.value, 0); +} + +function sample8() { + assert_approx_equals(rect1.x.animVal.value, 0, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 5, epsilon); + assert_equals(rect2.x.baseVal.value, 200); + + assert_approx_equals(rect3.x.animVal.value, 5, epsilon); + assert_equals(rect3.x.baseVal.value, 0); + + assert_approx_equals(rect4.x.animVal.value, 80, epsilon); + assert_equals(rect4.x.baseVal.value, 0); +} + +function sample9() { + assert_approx_equals(rect1.x.animVal.value, 200, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 5, epsilon); + assert_equals(rect2.x.baseVal.value, 200); + + assert_approx_equals(rect3.x.animVal.value, 5, epsilon); + assert_equals(rect3.x.baseVal.value, 0); + + assert_approx_equals(rect4.x.animVal.value, 80, epsilon); + assert_equals(rect4.x.baseVal.value, 0); +} + +function sample10() { + assert_approx_equals(rect1.x.animVal.value, 200, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 5, epsilon); + assert_equals(rect2.x.baseVal.value, 200); + + assert_approx_equals(rect3.x.animVal.value, 5, epsilon); + assert_equals(rect3.x.baseVal.value, 0); + + assert_approx_equals(rect4.x.animVal.value, 80, epsilon); + assert_equals(rect4.x.baseVal.value, 0); +} + +function sample11() { + assert_approx_equals(rect1.x.animVal.value, 225, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 10, epsilon); + assert_equals(rect2.x.baseVal.value, 200); + + assert_approx_equals(rect3.x.animVal.value, 5, epsilon); + assert_equals(rect3.x.baseVal.value, 0); + + assert_approx_equals(rect4.x.animVal.value, 80, epsilon); + assert_equals(rect4.x.baseVal.value, 0); +} + +function sample12() { + assert_approx_equals(rect1.x.animVal.value, 225, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 20, epsilon); + assert_equals(rect2.x.baseVal.value, 200); + + assert_approx_equals(rect3.x.animVal.value, 5, epsilon); + assert_equals(rect3.x.baseVal.value, 0); + + assert_approx_equals(rect4.x.animVal.value, 110, epsilon); + assert_equals(rect4.x.baseVal.value, 0); +} + +function sample13() { + assert_approx_equals(rect1.x.animVal.value, 225, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 20, epsilon); + assert_equals(rect2.x.baseVal.value, 200); + + assert_approx_equals(rect3.x.animVal.value, 5, epsilon); + assert_equals(rect3.x.baseVal.value, 0); + + assert_approx_equals(rect4.x.animVal.value, 110, epsilon); + assert_equals(rect4.x.baseVal.value, 0); +} + +function sample14() { + assert_approx_equals(rect1.x.animVal.value, 250, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 0, epsilon); + assert_equals(rect2.x.baseVal.value, 200); + + assert_approx_equals(rect3.x.animVal.value, 5, epsilon); + assert_equals(rect3.x.baseVal.value, 0); + + assert_approx_equals(rect4.x.animVal.value, 130, epsilon); + assert_equals(rect4.x.baseVal.value, 0); +} + +function sample15() { + assert_approx_equals(rect1.x.animVal.value, 50, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 200, epsilon); + assert_equals(rect2.x.baseVal.value, 200); + + assert_approx_equals(rect3.x.animVal.value, 5, epsilon); + assert_equals(rect3.x.baseVal.value, 0); + + assert_approx_equals(rect4.x.animVal.value, 130, epsilon); + assert_equals(rect4.x.baseVal.value, 0); +} + +function sample16() { + assert_approx_equals(rect1.x.animVal.value, 50, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 200, epsilon); + assert_equals(rect2.x.baseVal.value, 200); + + assert_approx_equals(rect3.x.animVal.value, 5, epsilon); + assert_equals(rect3.x.baseVal.value, 0); + + assert_approx_equals(rect4.x.animVal.value, 130, epsilon); + assert_equals(rect4.x.baseVal.value, 0); +} + +function sample17() { + assert_approx_equals(rect1.x.animVal.value, 0, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 200, epsilon); + assert_equals(rect2.x.baseVal.value, 200); + + assert_approx_equals(rect3.x.animVal.value, 5, epsilon); + assert_equals(rect3.x.baseVal.value, 0); + + assert_approx_equals(rect4.x.animVal.value, 130, epsilon); + assert_equals(rect4.x.baseVal.value, 0); +} + +function sample18() { + assert_approx_equals(rect1.x.animVal.value, 250, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 200, epsilon); + assert_equals(rect2.x.baseVal.value, 200); + + assert_approx_equals(rect3.x.animVal.value, 250, epsilon); + assert_equals(rect3.x.baseVal.value, 0); + + assert_approx_equals(rect4.x.animVal.value, 160, epsilon); + assert_equals(rect4.x.baseVal.value, 0); +} + +function sample19() { + assert_approx_equals(rect1.x.animVal.value, 250, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 200, epsilon); + assert_equals(rect2.x.baseVal.value, 200); + + assert_approx_equals(rect3.x.animVal.value, 250, epsilon); + assert_equals(rect3.x.baseVal.value, 0); + + assert_approx_equals(rect4.x.animVal.value, 160, epsilon); + assert_equals(rect4.x.baseVal.value, 0); +} + +function sample20() { + assert_approx_equals(rect1.x.animVal.value, 250, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 200, epsilon); + assert_equals(rect2.x.baseVal.value, 200); + + assert_approx_equals(rect3.x.animVal.value, 200, epsilon); + assert_equals(rect3.x.baseVal.value, 0); + + assert_approx_equals(rect4.x.animVal.value, 180, epsilon); + assert_equals(rect4.x.baseVal.value, 0); +} + +function sample21() { + assert_approx_equals(rect1.x.animVal.value, 250, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 200, epsilon); + assert_equals(rect2.x.baseVal.value, 200); + + assert_approx_equals(rect3.x.animVal.value, 200, epsilon); + assert_equals(rect3.x.baseVal.value, 0); + + assert_approx_equals(rect4.x.animVal.value, 180, epsilon); + assert_equals(rect4.x.baseVal.value, 0); +} + +function sample22() { + assert_approx_equals(rect1.x.animVal.value, 250, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 200, epsilon); + assert_equals(rect2.x.baseVal.value, 200); + + assert_approx_equals(rect3.x.animVal.value, 150, epsilon); + assert_equals(rect3.x.baseVal.value, 0); + + assert_approx_equals(rect4.x.animVal.value, 180, epsilon); + assert_equals(rect4.x.baseVal.value, 0); +} + +function sample23() { + assert_approx_equals(rect1.x.animVal.value, 250, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 200, epsilon); + assert_equals(rect2.x.baseVal.value, 200); + + assert_approx_equals(rect3.x.animVal.value, 150, epsilon); + assert_equals(rect3.x.baseVal.value, 0); + + assert_approx_equals(rect4.x.animVal.value, 180, epsilon); + assert_equals(rect4.x.baseVal.value, 0); +} + +smil_async_test((t) => { + var rects = rootSVGElement.ownerDocument.getElementsByTagName("rect"); + rect1 = rects[0]; + rect2 = rects[1]; + rect3 = rects[2]; + rect4 = rects[3]; + + const expectedValues = [ + // [animationId, time, sampleCallback] + ["an1", 0.0, sample1], + ["an1", 0.499, sample2], + ["an1", 0.5, sample3], + ["an1", 0.501, sample4], + ["an1", 0.999, sample5], + ["an1", 1.0, sample6], + ["an1", 1.001, sample7], + ["an1", 1.499, sample8], + ["an1", 1.5, sample9], + ["an1", 1.501, sample10], + ["an1", 1.999, sample11], + ["an1", 2.0, sample12], + ["an1", 2.001, sample13], + ["an1", 2.499, sample14], + ["an1", 2.5, sample15], + ["an1", 2.501, sample16], + ["an1", 2.999, sample17], + ["an1", 3.0, sample18], + ["an1", 3.001, sample19], + ["an1", 3.499, sample20], + ["an1", 3.5, sample21], + ["an1", 4.0, sample22], + ["an1", 9.0, sample23] + ]; + + runAnimationTest(t, expectedValues); +}); + +window.animationStartsImmediately = true; + +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/multiple-animations-fill-freeze.html b/third_party/blink/web_tests/external/wpt/svg/animations/multiple-animations-fill-freeze.html new file mode 100644 index 0000000..d4a71dca --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/animations/multiple-animations-fill-freeze.html
@@ -0,0 +1,149 @@ +<!doctype html> +<html> +<meta charset="utf-8"> +<title>This checks the effect on multiple animations on one target</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/SVGAnimationTestCase-testharness.js"></script> + +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd"> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + +<rect x='0' y='0' width='50' height='50' fill='green'> + <animate id="an1" attributeName='x' from='0' to='100' begin='0s' dur='2s' fill='freeze'/> + <animate id="an2" attributeName='x' from='150' to='250' begin='4s' dur='2s' fill='freeze'/> +</rect> + +<rect x='0' y='100' width='50' height='50' fill='green'> + <animate id="an3" attributeName='x' from='0' to='100' begin='0s' dur='2s' fill='remove'/> + <animate id="an4" attributeName='x' from='150' to='250' begin='4s' dur='2s' fill='freeze'/> +</rect> + +<rect x='0' y='200' width='50' height='50' fill='green'> + <animate id="an5" attributeName='x' from='0' to='100' begin='0s' dur='2s' fill='freeze'/> + <animate id="an6" attributeName='x' from='150' to='250' begin='4s' dur='2s' fill='remove'/> +</rect> + +</svg> + +<script> +var rootSVGElement = document.querySelector("svg"); +var epsilon = 1.0; + +// Setup animation test +function sample1() { + assert_approx_equals(rect1.x.animVal.value, 0, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 0, epsilon); + assert_equals(rect2.x.baseVal.value, 0); + + assert_approx_equals(rect3.x.animVal.value, 0, epsilon); + assert_equals(rect3.x.baseVal.value, 0); +} + +function sample2() { + assert_approx_equals(rect1.x.animVal.value, 50, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 50, epsilon); + assert_equals(rect2.x.baseVal.value, 0); + + assert_approx_equals(rect3.x.animVal.value, 50, epsilon); + assert_equals(rect3.x.baseVal.value, 0); +} + +function sample3() { + assert_approx_equals(rect1.x.animVal.value, 100, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 100, epsilon); + assert_equals(rect2.x.baseVal.value, 0); + + assert_approx_equals(rect3.x.animVal.value, 100, epsilon); + assert_equals(rect3.x.baseVal.value, 0); +} + +function sample4() { + assert_approx_equals(rect1.x.animVal.value, 100, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 0, epsilon); + assert_equals(rect2.x.baseVal.value, 0); + + assert_approx_equals(rect3.x.animVal.value, 100, epsilon); + assert_equals(rect3.x.baseVal.value, 0); +} + +function sample5() { + assert_approx_equals(rect1.x.animVal.value, 150, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 150, epsilon); + assert_equals(rect2.x.baseVal.value, 0); + + assert_approx_equals(rect3.x.animVal.value, 150, epsilon); + assert_equals(rect3.x.baseVal.value, 0); +} + +function sample6() { + assert_approx_equals(rect1.x.animVal.value, 200, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 200, epsilon); + assert_equals(rect2.x.baseVal.value, 0); + + assert_approx_equals(rect3.x.animVal.value, 200, epsilon); + assert_equals(rect3.x.baseVal.value, 0); +} + +function sample7() { + assert_approx_equals(rect1.x.animVal.value, 250, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 250, epsilon); + assert_equals(rect2.x.baseVal.value, 0); + + assert_approx_equals(rect3.x.animVal.value, 250, epsilon); + assert_equals(rect3.x.baseVal.value, 0); +} + +function sample8() { + assert_equals(rect1.x.animVal.value, 250); + assert_equals(rect1.x.baseVal.value, 0); + + assert_equals(rect2.x.animVal.value, 250); + assert_equals(rect2.x.baseVal.value, 0); + + assert_equals(rect3.x.animVal.value, 100); + assert_equals(rect3.x.baseVal.value, 0); +} + +smil_async_test((t) => { + var rects = rootSVGElement.ownerDocument.getElementsByTagName("rect"); + rect1 = rects[0]; + rect2 = rects[1]; + rect3 = rects[2]; + + const expectedValues = [ + // [animationId, time, sampleCallback] + ["an1", 0.0, sample1], + ["an1", 1.0, sample2], + ["an1", 1.999, sample3], + ["an1", 2.001, sample4], + ["an1", 3.0, sample4], + ["an1", 3.999, sample4], + ["an1", 4.0, sample5], + ["an1", 5.0, sample6], + ["an1", 5.999, sample7], + ["an1", 6.001, sample8], + ["an1", 60.0, sample8] + ]; + + runAnimationTest(t, expectedValues); +}); + +window.animationStartsImmediately = true; + +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/multiple-begin-additive-animation.html b/third_party/blink/web_tests/external/wpt/svg/animations/multiple-begin-additive-animation.html new file mode 100644 index 0000000..9e75bdf --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/animations/multiple-begin-additive-animation.html
@@ -0,0 +1,136 @@ +<!doctype html> +<html> +<meta charset="utf-8"> +<title>This tests additive='sum' support on animate elements with multiple begin times</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/SVGAnimationTestCase-testharness.js"></script> + +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd"> +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000"> +<rect width="100" height="100" fill="green"> + <animate id="an1" attributeName="y" attributeType="XML" begin="0s" dur="12s" from="100" to="900" fill="freeze" /> + <animate attributeName="x" attributeType="XML" calcMode="discrete" begin="0s; 2s" from="0" to="400" dur="8s" additive="sum" /> +</rect> +</svg> + +<script> +var rootSVGElement = document.querySelector("svg"); +var epsilon = 1.0; + +// Setup animation test +function checkBaseValues() { +return; + assert_equals(rect.x.baseVal.value, 0); + assert_equals(rect.y.baseVal.value, 0); +} + +function sample1() { + assert_equals(rect.x.animVal.value, 0); + assert_approx_equals(rect.y.animVal.value, 100, epsilon); + checkBaseValues(); +} + +function sample2() { + assert_equals(rect.x.animVal.value, 0); + assert_approx_equals(rect.y.animVal.value, 166.67, epsilon); + checkBaseValues(); +} + +function sample3() { + assert_equals(rect.x.animVal.value, 0); + assert_approx_equals(rect.y.animVal.value, 366.60, epsilon); + checkBaseValues(); +} + +function sample4() { + assert_equals(rect.x.animVal.value, 0); + assert_approx_equals(rect.y.animVal.value, 366.73, epsilon); + checkBaseValues(); +} + +function sample5() { + assert_equals(rect.x.animVal.value, 0); + assert_approx_equals(rect.y.animVal.value, 499.93, epsilon); + checkBaseValues(); +} + +function sample6() { + assert_equals(rect.x.animVal.value, 400); + assert_approx_equals(rect.y.animVal.value, 500.06, epsilon); + checkBaseValues(); +} + +function sample7() { + assert_equals(rect.x.animVal.value, 400); + assert_approx_equals(rect.y.animVal.value, 566.67, epsilon); + checkBaseValues(); +} + +function sample8() { + assert_equals(rect.x.animVal.value, 400); + assert_approx_equals(rect.y.animVal.value, 633.33, epsilon); + checkBaseValues(); +} + +function sample9() { + assert_equals(rect.x.animVal.value, 400); + assert_approx_equals(rect.y.animVal.value, 700, epsilon); + checkBaseValues(); +} + +function sample10() { + assert_equals(rect.x.animVal.value, 400); + assert_approx_equals(rect.y.animVal.value, 766.60, epsilon); + checkBaseValues(); +} + +function sample11() { + assert_equals(rect.x.animVal.value, 0); + assert_approx_equals(rect.y.animVal.value, 766.67, epsilon); + checkBaseValues(); +} + +function sample12() { + assert_equals(rect.x.animVal.value, 0); + assert_approx_equals(rect.y.animVal.value, 833.33, epsilon); + checkBaseValues(); +} + +function sample13() { + assert_equals(rect.x.animVal.value, 0); + assert_approx_equals(rect.y.animVal.value, 900, epsilon); + checkBaseValues(); +} + +smil_async_test((t) => { + rect = rootSVGElement.ownerDocument.getElementsByTagName("rect")[0]; + + // All animations in the test file use the same duration, so it's not needed to list all sample points individually for an5/an6/an7/an8. + const expectedValues = [ + // [animationId, time, sampleCallback] + ["an1", 0.0, sample1], + ["an1", 1.0, sample2], + ["an1", 3.999, sample3], + ["an1", 4.001, sample4], + ["an1", 5.999, sample5], + ["an1", 6.001, sample6], + ["an1", 7.0, sample7], + ["an1", 7.999, sample8], + ["an1", 8.001, sample8], + ["an1", 9.0, sample9], + ["an1", 9.999, sample10], + ["an1", 10.001, sample11], + ["an1", 11.0, sample12], + ["an1", 11.999, sample13], + ["an1", 12.001, sample13], + ["an1", 60.0, sample13] + ]; + + runAnimationTest(t, expectedValues); +}); + +window.animationStartsImmediately = true; + +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/non-additive-type-by-animation.html b/third_party/blink/web_tests/external/wpt/svg/animations/non-additive-type-by-animation.html new file mode 100644 index 0000000..b596f73 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/animations/non-additive-type-by-animation.html
@@ -0,0 +1,72 @@ +<!doctype html> +<html> +<meta charset="utf-8"> +<title>This by animation for all non-additive property types - should have no effect.</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/SVGAnimationTestCase-testharness.js"></script> + +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd"> +<svg id="svg" viewBox="0 0 200 200" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<defs> + <filter id="filter"> + <feConvolveMatrix id="feConvolveMatrix" kernelMatrix="0 1 0 0 1 0 0 1 0" order="6 6" targetX="5" preserveAlpha="false"/> + </filter> +</defs> + +<rect id="rect" y="100" width="100" height="100" fill="black" filter="url(#filter)"/> + +<!-- AnimatedBoolean --> +<animate id="an1" xlink:href="#feConvolveMatrix" attributeName="preserveAlpha" begin="0s" dur="4s" by="true" fill="freeze"/> + +<!-- AnimatedEnumeration --> +<animate xlink:href="#filter" attributeName="filterUnits" begin="0s" dur="4s" by="userSpaceOnUse" fill="freeze"/> + +<!-- AnimatedPreserveAspectRatio --> +<animate xlink:href="#svg" attributeName="preserveAspectRatio" begin="0s" dur="4s" by="xMaxYMax slice" fill="freeze"/> + +<!-- AnimatedString --> +<animate xlink:href="#feConvolveMatrix" attributeName="result" begin="0s" dur="4s" by="test" fill="freeze"/> + +</svg> + +<script> +var rootSVGElement = document.querySelector("svg"); +var epsilon = 1.0; + +// Setup animation test +function sample() { + assert_equals(feConvolveMatrix.preserveAlpha.animVal, false); + assert_equals(filter.filterUnits.animVal, SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX); + assert_equals(svg.preserveAspectRatio.animVal.align, SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE); + assert_equals(svg.preserveAspectRatio.animVal.meetOrSlice, SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET); + assert_equals(feConvolveMatrix.result.animVal, ""); + + assert_equals(feConvolveMatrix.preserveAlpha.baseVal, false); + assert_equals(filter.filterUnits.baseVal, SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX); + assert_equals(svg.preserveAspectRatio.baseVal.align, SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE); + assert_equals(svg.preserveAspectRatio.baseVal.meetOrSlice, SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET); + assert_equals(feConvolveMatrix.result.baseVal, ""); +} + +smil_async_test((t) => { + filter = rootSVGElement.ownerDocument.getElementsByTagName("filter")[0]; + feConvolveMatrix = rootSVGElement.ownerDocument.getElementsByTagName("feConvolveMatrix")[0]; + svg = rootSVGElement.ownerDocument.getElementsByTagName("svg")[0]; + + const expectedValues = [ + // [animationId, time, sampleCallback] + ["an1", 0.0, sample], + ["an1", 1.999, sample], + ["an1", 2.001, sample], + ["an1", 3.999, sample], + ["an1", 4.001, sample] + ]; + + runAnimationTest(t, expectedValues); +}); + +window.animationStartsImmediately = true; + +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/non-additive-type-from-by-animation.html b/third_party/blink/web_tests/external/wpt/svg/animations/non-additive-type-from-by-animation.html new file mode 100644 index 0000000..e974e381 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/animations/non-additive-type-from-by-animation.html
@@ -0,0 +1,72 @@ +<!doctype html> +<html> +<meta charset="utf-8"> +<title>This is a from by animation for all non-additive property types - should have no effect.</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/SVGAnimationTestCase-testharness.js"></script> + +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd"> +<svg id="svg" viewBox="0 0 200 200" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<defs> + <filter id="filter"> + <feConvolveMatrix id="feConvolveMatrix" kernelMatrix="0 1 0 0 1 0 0 1 0" order="6 6" targetX="5" preserveAlpha="false"/> + </filter> +</defs> + +<rect id="rect" y="100" width="100" height="100" fill="black" filter="url(#filter)"/> + +<!-- AnimatedBoolean --> +<animate id="an1" xlink:href="#feConvolveMatrix" attributeName="preserveAlpha" begin="0s" dur="4s" from="false" by="true" fill="freeze"/> + +<!-- AnimatedEnumeration --> +<animate xlink:href="#filter" attributeName="filterUnits" begin="0s" dur="4s" from="objectBoundingBox" by="userSpaceOnUse" fill="freeze"/> + +<!-- AnimatedPreserveAspectRatio --> +<animate xlink:href="#svg" attributeName="preserveAspectRatio" begin="0s" dur="4s" from="xMaxYMax meet" by="xMaxYMax slice" fill="freeze"/> + +<!-- AnimatedString --> +<animate xlink:href="#feConvolveMatrix" attributeName="result" begin="0s" dur="4s" from="foo" by="test" fill="freeze"/> + +</svg> + +<script> +var rootSVGElement = document.querySelector("svg"); +var epsilon = 1.0; + +// Setup animation test +function sample() { + assert_equals(feConvolveMatrix.preserveAlpha.animVal, false); + assert_equals(filter.filterUnits.animVal, SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX); + assert_equals(svg.preserveAspectRatio.animVal.align, SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE); + assert_equals(svg.preserveAspectRatio.animVal.meetOrSlice, SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET); + assert_equals(feConvolveMatrix.result.animVal, ""); + + assert_equals(feConvolveMatrix.preserveAlpha.baseVal, false); + assert_equals(filter.filterUnits.baseVal, SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX); + assert_equals(svg.preserveAspectRatio.baseVal.align, SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE); + assert_equals(svg.preserveAspectRatio.baseVal.meetOrSlice, SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET); + assert_equals(feConvolveMatrix.result.baseVal, ""); +} + +smil_async_test((t) => { + filter = rootSVGElement.ownerDocument.getElementsByTagName("filter")[0]; + feConvolveMatrix = rootSVGElement.ownerDocument.getElementsByTagName("feConvolveMatrix")[0]; + svg = rootSVGElement.ownerDocument.getElementsByTagName("svg")[0]; + + const expectedValues = [ + // [animationId, time, sampleCallback] + ["an1", 0.0, sample], + ["an1", 1.999, sample], + ["an1", 2.001, sample], + ["an1", 3.999, sample], + ["an1", 4.001, sample] + ]; + + runAnimationTest(t, expectedValues); +}); + +window.animationStartsImmediately = true; + +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/remove-animation-element-while-animation-is-running.html b/third_party/blink/web_tests/external/wpt/svg/animations/remove-animation-element-while-animation-is-running.html new file mode 100644 index 0000000..764d25b6 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/animations/remove-animation-element-while-animation-is-running.html
@@ -0,0 +1,85 @@ +<!doctype html> +<html> +<meta charset="utf-8"> +<title>This removes an animation element while the animation is running</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/SVGAnimationTestCase-testharness.js"></script> + +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd"> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + +<rect x='0' y='0' width='50' height='50' fill='green'> + <animate id="an1" attributeName='x' from='50' to='150' begin='0s' dur='2s' fill='freeze'/> +</rect> + +<rect x='0' y='100' width='50' height='50' fill='green'> + <animate id="an2" attributeName='x' from='50' to='150' begin='0s' dur='2s' fill='remove'/> +</rect> + +</svg> + +<script> +var rootSVGElement = document.querySelector("svg"); +var epsilon = 1.0; + +// Setup animation test +function sample1() { + assert_approx_equals(rect1.x.animVal.value, 50, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 50, epsilon); + assert_equals(rect2.x.baseVal.value, 0); +} + +function sample2() { + assert_approx_equals(rect1.x.animVal.value, 100, epsilon); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 100, epsilon); + assert_equals(rect2.x.baseVal.value, 0); + + // Remove the animation element animating rect1 + // The effect is that rect1 is now reset to the initial state, before any animation was applied to it. + // Compatible with FF. In Opera it shows a repainting bug currently (two rects are visible!). + var an1 = rootSVGElement.ownerDocument.getElementById("an1"); + an1.parentNode.removeChild(an1); +} + +function sample3() { + assert_equals(rect1.x.animVal.value, 0); + assert_equals(rect1.x.baseVal.value, 0); + + assert_approx_equals(rect2.x.animVal.value, 100, epsilon); + assert_equals(rect2.x.baseVal.value, 0); +} + +function sample4() { + assert_equals(rect1.x.animVal.value, 0); + assert_equals(rect1.x.baseVal.value, 0); + + assert_equals(rect2.x.animVal.value, 0); + assert_equals(rect2.x.baseVal.value, 0); +} + +smil_async_test((t) => { + var rects = rootSVGElement.ownerDocument.getElementsByTagName("rect"); + rect1 = rects[0]; + rect2 = rects[1]; + + const expectedValues = [ + // [animationId, time, sampleCallback] + ["an1", 0.0, sample1], + ["an1", 1.0, sample2], + ["an2", 1.001, sample3], + ["an2", 2.001, sample4], + ["an2", 60.0, sample4] + ]; + + runAnimationTest(t, expectedValues); +}); + +window.animationStartsImmediately = true; + +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/repeatn-remove-add-animation.html b/third_party/blink/web_tests/external/wpt/svg/animations/repeatn-remove-add-animation.html new file mode 100644 index 0000000..f192d27 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/animations/repeatn-remove-add-animation.html
@@ -0,0 +1,100 @@ +<!doctype html> +<html> +<meta charset="utf-8"> +<title>This removes and adds an animation element while the animation is repeating</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/SVGAnimationTestCase-testharness.js"></script> + +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd"> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + + <animate id="anim" attributeName="visibility" to="visible" begin="0s" dur="2s" repeatCount="4"/> + <rect x="0" y="0" width="100" height="100" fill="rgb(0, 255, 0)"> + <set attributeName="fill" to="rgb(255, 0, 0)" begin="anim.repeat(0)"/> + </rect> + <rect x="200" y="0" width="100" height="100" fill="rgb(255, 0, 0)"> + <set attributeName="fill" to="rgb(0, 255, 0)" begin="anim.repeat(1)"/> + </rect> + <rect x="0" y="200" width="100" height="100" fill="rgb(255, 0, 0)"> + <set attributeName="fill" to="rgb(0, 255, 0)" begin="anim.repeat(2)"/> + </rect> + <rect x="200" y="200" width="100" height="100" fill="rgb(255, 0, 0)"> + <set attributeName="fill" to="rgb(0, 255, 0)" begin="anim.repeat(3)"/> + </rect> + +</svg> + +<script> +var rootSVGElement = document.querySelector("svg"); +var epsilon = 1.0; + +// Setup animation test +function sample1() { + expectFillColor(rect1, 0, 255, 0); + expectFillColor(rect2, 255, 0, 0); + expectFillColor(rect3, 255, 0, 0); + expectFillColor(rect4, 255, 0, 0); +} + +function sample2() { + expectFillColor(rect1, 0, 255, 0); + expectFillColor(rect2, 0, 255, 0); + expectFillColor(rect3, 255, 0, 0); + expectFillColor(rect4, 255, 0, 0); +} + +function sample3() { + expectFillColor(rect1, 0, 255, 0); + expectFillColor(rect2, 0, 255, 0); + expectFillColor(rect3, 0, 255, 0); + expectFillColor(rect4, 255, 0, 0); +} + +function sample4() { + expectFillColor(rect1, 0, 255, 0); + expectFillColor(rect2, 0, 255, 0); + expectFillColor(rect3, 0, 255, 0); + expectFillColor(rect4, 0, 255, 0); +} + +function recreate() { + var anim1 = rootSVGElement.ownerDocument.getElementById("anim"); + anim1.parentNode.removeChild(anim1); + var anim2 = createSVGElement("animate"); + anim2.setAttribute("id", "anim"); + anim2.setAttribute("attributeName", "visibility"); + anim2.setAttribute("to", "visible"); + anim2.setAttribute("begin", "0s"); + anim2.setAttribute("dur", "2s"); + anim2.setAttribute("repeatCount", "4"); + rootSVGElement.appendChild(anim2); +} + +smil_async_test((t) => { + var rects = rootSVGElement.ownerDocument.getElementsByTagName("rect"); + rect1 = rects[0]; + rect2 = rects[1]; + rect3 = rects[2]; + rect4 = rects[3]; + + const expectedValues = [ + // [animationId, time, sampleCallback] + ["anim", 0.0, sample1], + ["anim", 0.001, sample1], + ["anim", 2.0, sample1], + ["anim", 2.001, sample2], + ["anim", 4.0, sample2], + ["anim", 4.001, sample3], + ["anim", 5.0, recreate], + ["anim", 6.0, sample3], + ["anim", 6.001, sample4] + ]; + + runAnimationTest(t, expectedValues); +}); + +window.animationStartsImmediately = true; + +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/single-values-animation.html b/third_party/blink/web_tests/external/wpt/svg/animations/single-values-animation.html new file mode 100644 index 0000000..40aa346 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/animations/single-values-animation.html
@@ -0,0 +1,51 @@ +<!doctype html> +<html> +<meta charset="utf-8"> +<title>This tests values animation with just a single entry</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/SVGAnimationTestCase-testharness.js"></script> + +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd"> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + +<!-- an1: Change width immediately to 100 at 2s --> +<rect width="10" height="100" fill="green"> + <animate id="an1" attributeType="XML" attributeName="width" fill="freeze" values="100" begin="2s"/> +</rect> + +</svg> + +<script> +var rootSVGElement = document.querySelector("svg"); +var epsilon = 1.0; + +// Setup animation test +function sample1() { + assert_approx_equals(rect.width.animVal.value, 10, epsilon); + assert_equals(rect.width.baseVal.value, 10); +} + +function sample2() { + assert_approx_equals(rect.width.animVal.value, 100, epsilon); + assert_equals(rect.width.baseVal.value, 10); +} + +smil_async_test((t) => { + rect = rootSVGElement.ownerDocument.getElementsByTagName("rect")[0]; + + const expectedValues = [ + // [animationId, time, sampleCallback] + ["an1", 0.0, sample1], + ["an1", 2.0, sample2], + ["an1", 4.0, sample2], + ["an1", 60.0, sample2] + ]; + + runAnimationTest(t, expectedValues); +}); + +window.animationStartsImmediately = true; + +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/svgangle-animation-deg-to-grad.html b/third_party/blink/web_tests/external/wpt/svg/animations/svgangle-animation-deg-to-grad.html new file mode 100644 index 0000000..7a814633 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/animations/svgangle-animation-deg-to-grad.html
@@ -0,0 +1,93 @@ +<!doctype html> +<html> +<meta charset="utf-8"> +<title>Tests SVGAngle animation from deg to grad.</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/SVGAnimationTestCase-testharness.js"></script> + +<svg> +</svg> + +<script> +var rootSVGElement = document.querySelector("svg"); +var epsilon = 1.0; + +// Setup test document +var defs = createSVGElement("defs"); + +var marker = createSVGElement("marker"); +marker.setAttribute("id", "marker"); +marker.setAttribute("viewBox", "0 0 10 10"); +marker.setAttribute("markerWidth", "4"); +marker.setAttribute("markerHeight", "3"); +marker.setAttribute("markerUnits", "strokeWidth"); +marker.setAttribute("refX", "1"); +marker.setAttribute("refY", "5"); +marker.setAttribute("orient", "0deg"); +defs.appendChild(marker); + +var polyline = createSVGElement("polyline"); +polyline.setAttribute("id", "polyline"); +polyline.setAttribute("points", "0,0 10,5 0,10 1,5"); +polyline.setAttribute("fill", "green"); +marker.appendChild(polyline); + +var path = createSVGElement("path"); +path.setAttribute("id", "path"); +path.setAttribute("d", "M45,50 L55,50"); +path.setAttribute("stroke-width","10"); +path.setAttribute("stroke", "green"); +path.setAttribute("marker-end", "url(#marker)"); +path.setAttribute("onclick", "executeTest()"); + +var animate = createSVGElement("animate"); +animate.setAttribute("id", "animation"); +animate.setAttribute("attributeName", "orient"); +animate.setAttribute("begin", "0s"); +animate.setAttribute("dur", "4s"); +animate.setAttribute("from", "0deg"); +animate.setAttribute("to", "200grad"); +marker.appendChild(animate); +rootSVGElement.appendChild(defs); +rootSVGElement.appendChild(path); + +// Setup animation test +function sample1() { + // Check initial/end conditions + assert_approx_equals(marker.orientAngle.animVal.value, 0, epsilon); + assert_equals(marker.orientAngle.baseVal.value, 0); + + assert_equals(marker.orientType.animVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); + assert_equals(marker.orientType.baseVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); +} + +function sample2() { + assert_approx_equals(marker.orientAngle.animVal.value, 90, epsilon); + assert_equals(marker.orientAngle.baseVal.value, 0); + + assert_equals(marker.orientType.animVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); + assert_equals(marker.orientType.baseVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); +} + +function sample3() { + assert_approx_equals(marker.orientAngle.animVal.value, 180, epsilon); + assert_equals(marker.orientAngle.baseVal.value, 0); + + assert_equals(marker.orientType.animVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); + assert_equals(marker.orientType.baseVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); +} + +smil_async_test((t) => { + const expectedValues = [ + // [animationId, time, sampleCallback] + ["animation", 0.0, sample1], + ["animation", 2.0, sample2], + ["animation", 3.999, sample3], + ["animation", 4.001, sample1] + ]; + + runAnimationTest(t, expectedValues); +}); + +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/svgangle-animation-deg-to-rad.html b/third_party/blink/web_tests/external/wpt/svg/animations/svgangle-animation-deg-to-rad.html new file mode 100644 index 0000000..b8ad730 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/animations/svgangle-animation-deg-to-rad.html
@@ -0,0 +1,93 @@ +<!doctype html> +<html> +<meta charset="utf-8"> +<title>Tests SVGAngle animation from deg to rad.</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/SVGAnimationTestCase-testharness.js"></script> + +<svg> +</svg> + +<script> +var rootSVGElement = document.querySelector("svg"); +var epsilon = 1.0; + +// Setup test document +var defs = createSVGElement("defs"); + +var marker = createSVGElement("marker"); +marker.setAttribute("id", "marker"); +marker.setAttribute("viewBox", "0 0 10 10"); +marker.setAttribute("markerWidth", "4"); +marker.setAttribute("markerHeight", "3"); +marker.setAttribute("markerUnits", "strokeWidth"); +marker.setAttribute("refX", "1"); +marker.setAttribute("refY", "5"); +marker.setAttribute("orient", "0deg"); +defs.appendChild(marker); + +var polyline = createSVGElement("polyline"); +polyline.setAttribute("id", "polyline"); +polyline.setAttribute("points", "0,0 10,5 0,10 1,5"); +polyline.setAttribute("fill", "green"); +marker.appendChild(polyline); + +var path = createSVGElement("path"); +path.setAttribute("id", "path"); +path.setAttribute("d", "M45,50 L55,50"); +path.setAttribute("stroke-width","10"); +path.setAttribute("stroke", "green"); +path.setAttribute("marker-end", "url(#marker)"); +path.setAttribute("onclick", "executeTest()"); + +var animate = createSVGElement("animate"); +animate.setAttribute("id", "animation"); +animate.setAttribute("attributeName", "orient"); +animate.setAttribute("begin", "0s"); +animate.setAttribute("dur", "4s"); +animate.setAttribute("from", "0deg"); +animate.setAttribute("to", "3.14159265rad"); +marker.appendChild(animate); +rootSVGElement.appendChild(defs); +rootSVGElement.appendChild(path); + +// Setup animation test +function sample1() { + // Check initial/end conditions + assert_approx_equals(marker.orientAngle.animVal.value, 0, epsilon); + assert_equals(marker.orientAngle.baseVal.value, 0); + + assert_equals(marker.orientType.animVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); + assert_equals(marker.orientType.baseVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); +} + +function sample2() { + assert_approx_equals(marker.orientAngle.animVal.value, 90, epsilon); + assert_equals(marker.orientAngle.baseVal.value, 0); + + assert_equals(marker.orientType.animVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); + assert_equals(marker.orientType.baseVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); +} + +function sample3() { + assert_approx_equals(marker.orientAngle.animVal.value, 180, epsilon); + assert_equals(marker.orientAngle.baseVal.value, 0); + + assert_equals(marker.orientType.animVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); + assert_equals(marker.orientType.baseVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); +} + +smil_async_test((t) => { + const expectedValues = [ + // [animationId, time, sampleCallback] + ["animation", 0.0, sample1], + ["animation", 2.0, sample2], + ["animation", 3.999, sample3], + ["animation", 4.001, sample1] + ]; + + runAnimationTest(t, expectedValues); +}); + +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/svgangle-animation-grad-to-deg.html b/third_party/blink/web_tests/external/wpt/svg/animations/svgangle-animation-grad-to-deg.html new file mode 100644 index 0000000..dd5822d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/animations/svgangle-animation-grad-to-deg.html
@@ -0,0 +1,93 @@ +<!doctype html> +<html> +<meta charset="utf-8"> +<title>Tests SVGAngle animation from grad to deg.</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/SVGAnimationTestCase-testharness.js"></script> + +<svg> +</svg> + +<script> +var rootSVGElement = document.querySelector("svg"); +var epsilon = 1.0; + +// Setup test document +var defs = createSVGElement("defs"); + +var marker = createSVGElement("marker"); +marker.setAttribute("id", "marker"); +marker.setAttribute("viewBox", "0 0 10 10"); +marker.setAttribute("markerWidth", "4"); +marker.setAttribute("markerHeight", "3"); +marker.setAttribute("markerUnits", "strokeWidth"); +marker.setAttribute("refX", "1"); +marker.setAttribute("refY", "5"); +marker.setAttribute("orient", "0deg"); +defs.appendChild(marker); + +var polyline = createSVGElement("polyline"); +polyline.setAttribute("id", "polyline"); +polyline.setAttribute("points", "0,0 10,5 0,10 1,5"); +polyline.setAttribute("fill", "green"); +marker.appendChild(polyline); + +var path = createSVGElement("path"); +path.setAttribute("id", "path"); +path.setAttribute("d", "M45,50 L55,50"); +path.setAttribute("stroke-width","10"); +path.setAttribute("stroke", "green"); +path.setAttribute("marker-end", "url(#marker)"); +path.setAttribute("onclick", "executeTest()"); + +var animate = createSVGElement("animate"); +animate.setAttribute("id", "animation"); +animate.setAttribute("attributeName", "orient"); +animate.setAttribute("begin", "0s"); +animate.setAttribute("dur", "4s"); +animate.setAttribute("from", "0grad"); +animate.setAttribute("to", "180deg"); +marker.appendChild(animate); +rootSVGElement.appendChild(defs); +rootSVGElement.appendChild(path); + +// Setup animation test +function sample1() { + // Check initial/end conditions + assert_approx_equals(marker.orientAngle.animVal.value, 0, epsilon); + assert_equals(marker.orientAngle.baseVal.value, 0); + + assert_equals(marker.orientType.animVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); + assert_equals(marker.orientType.baseVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); +} + +function sample2() { + assert_approx_equals(marker.orientAngle.animVal.value, 90, epsilon); + assert_equals(marker.orientAngle.baseVal.value, 0); + + assert_equals(marker.orientType.animVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); + assert_equals(marker.orientType.baseVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); +} + +function sample3() { + assert_approx_equals(marker.orientAngle.animVal.value, 180, epsilon); + assert_equals(marker.orientAngle.baseVal.value, 0); + + assert_equals(marker.orientType.animVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); + assert_equals(marker.orientType.baseVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); +} + +smil_async_test((t) => { + const expectedValues = [ + // [animationId, time, sampleCallback] + ["animation", 0.0, sample1], + ["animation", 2.0, sample2], + ["animation", 3.999, sample3], + ["animation", 4.001, sample1] + ]; + + runAnimationTest(t, expectedValues); +}); + +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/svgangle-animation-grad-to-rad.html b/third_party/blink/web_tests/external/wpt/svg/animations/svgangle-animation-grad-to-rad.html new file mode 100644 index 0000000..28bef66 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/animations/svgangle-animation-grad-to-rad.html
@@ -0,0 +1,93 @@ +<!doctype html> +<html> +<meta charset="utf-8"> +<title>Tests SVGAngle animation from grad to rad.</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/SVGAnimationTestCase-testharness.js"></script> + +<svg> +</svg> + +<script> +var rootSVGElement = document.querySelector("svg"); +var epsilon = 1.0; + +// Setup test document +var defs = createSVGElement("defs"); + +var marker = createSVGElement("marker"); +marker.setAttribute("id", "marker"); +marker.setAttribute("viewBox", "0 0 10 10"); +marker.setAttribute("markerWidth", "4"); +marker.setAttribute("markerHeight", "3"); +marker.setAttribute("markerUnits", "strokeWidth"); +marker.setAttribute("refX", "1"); +marker.setAttribute("refY", "5"); +marker.setAttribute("orient", "0deg"); +defs.appendChild(marker); + +var polyline = createSVGElement("polyline"); +polyline.setAttribute("id", "polyline"); +polyline.setAttribute("points", "0,0 10,5 0,10 1,5"); +polyline.setAttribute("fill", "green"); +marker.appendChild(polyline); + +var path = createSVGElement("path"); +path.setAttribute("id", "path"); +path.setAttribute("d", "M45,50 L55,50"); +path.setAttribute("stroke-width","10"); +path.setAttribute("stroke", "green"); +path.setAttribute("marker-end", "url(#marker)"); +path.setAttribute("onclick", "executeTest()"); + +var animate = createSVGElement("animate"); +animate.setAttribute("id", "animation"); +animate.setAttribute("attributeName", "orient"); +animate.setAttribute("begin", "0s"); +animate.setAttribute("dur", "4s"); +animate.setAttribute("from", "0grad"); +animate.setAttribute("to", "3.14159265rad"); +marker.appendChild(animate); +rootSVGElement.appendChild(defs); +rootSVGElement.appendChild(path); + +// Setup animation test +function sample1() { + // Check initial/end conditions + assert_approx_equals(marker.orientAngle.animVal.value, 0, epsilon); + assert_equals(marker.orientAngle.baseVal.value, 0); + + assert_equals(marker.orientType.animVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); + assert_equals(marker.orientType.baseVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); +} + +function sample2() { + assert_approx_equals(marker.orientAngle.animVal.value, 90, epsilon); + assert_equals(marker.orientAngle.baseVal.value, 0); + + assert_equals(marker.orientType.animVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); + assert_equals(marker.orientType.baseVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); +} + +function sample3() { + assert_approx_equals(marker.orientAngle.animVal.value, 180, epsilon); + assert_equals(marker.orientAngle.baseVal.value, 0); + + assert_equals(marker.orientType.animVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); + assert_equals(marker.orientType.baseVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); +} + +smil_async_test((t) => { + const expectedValues = [ + // [animationId, time, sampleCallback] + ["animation", 0.0, sample1], + ["animation", 2.0, sample2], + ["animation", 3.999, sample3], + ["animation", 4.001, sample1] + ]; + + runAnimationTest(t, expectedValues); +}); + +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/svgangle-animation-rad-to-deg.html b/third_party/blink/web_tests/external/wpt/svg/animations/svgangle-animation-rad-to-deg.html new file mode 100644 index 0000000..412f384 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/animations/svgangle-animation-rad-to-deg.html
@@ -0,0 +1,93 @@ +<!doctype html> +<html> +<meta charset="utf-8"> +<title>Tests SVGAngle animation from rad to deg.</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/SVGAnimationTestCase-testharness.js"></script> + +<svg> +</svg> + +<script> +var rootSVGElement = document.querySelector("svg"); +var epsilon = 1.0; + +// Setup test document +var defs = createSVGElement("defs"); + +var marker = createSVGElement("marker"); +marker.setAttribute("id", "marker"); +marker.setAttribute("viewBox", "0 0 10 10"); +marker.setAttribute("markerWidth", "4"); +marker.setAttribute("markerHeight", "3"); +marker.setAttribute("markerUnits", "strokeWidth"); +marker.setAttribute("refX", "1"); +marker.setAttribute("refY", "5"); +marker.setAttribute("orient", "0deg"); +defs.appendChild(marker); + +var polyline = createSVGElement("polyline"); +polyline.setAttribute("id", "polyline"); +polyline.setAttribute("points", "0,0 10,5 0,10 1,5"); +polyline.setAttribute("fill", "green"); +marker.appendChild(polyline); + +var path = createSVGElement("path"); +path.setAttribute("id", "path"); +path.setAttribute("d", "M45,50 L55,50"); +path.setAttribute("stroke-width","10"); +path.setAttribute("stroke", "green"); +path.setAttribute("marker-end", "url(#marker)"); +path.setAttribute("onclick", "executeTest()"); + +var animate = createSVGElement("animate"); +animate.setAttribute("id", "animation"); +animate.setAttribute("attributeName", "orient"); +animate.setAttribute("begin", "0s"); +animate.setAttribute("dur", "4s"); +animate.setAttribute("from", "0rad"); +animate.setAttribute("to", "180deg"); +marker.appendChild(animate); +rootSVGElement.appendChild(defs); +rootSVGElement.appendChild(path); + +// Setup animation test +function sample1() { + // Check initial/end conditions + assert_approx_equals(marker.orientAngle.animVal.value, 0, epsilon); + assert_equals(marker.orientAngle.baseVal.value, 0); + + assert_equals(marker.orientType.animVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); + assert_equals(marker.orientType.baseVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); +} + +function sample2() { + assert_approx_equals(marker.orientAngle.animVal.value, 90, epsilon); + assert_equals(marker.orientAngle.baseVal.value, 0); + + assert_equals(marker.orientType.animVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); + assert_equals(marker.orientType.baseVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); +} + +function sample3() { + assert_approx_equals(marker.orientAngle.animVal.value, 180, epsilon); + assert_equals(marker.orientAngle.baseVal.value, 0); + + assert_equals(marker.orientType.animVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); + assert_equals(marker.orientType.baseVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); +} + +smil_async_test((t) => { + const expectedValues = [ + // [animationId, time, sampleCallback] + ["animation", 0.0, sample1], + ["animation", 2.0, sample2], + ["animation", 3.999, sample3], + ["animation", 4.001, sample1] + ]; + + runAnimationTest(t, expectedValues); +}); + +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/svgangle-animation-rad-to-grad.html b/third_party/blink/web_tests/external/wpt/svg/animations/svgangle-animation-rad-to-grad.html new file mode 100644 index 0000000..d27c052 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/animations/svgangle-animation-rad-to-grad.html
@@ -0,0 +1,93 @@ +<!doctype html> +<html> +<meta charset="utf-8"> +<title>Tests SVGAngle animation from rad to grad.</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/SVGAnimationTestCase-testharness.js"></script> + +<svg> +</svg> + +<script> +var rootSVGElement = document.querySelector("svg"); +var epsilon = 1.0; + +// Setup test document +var defs = createSVGElement("defs"); + +var marker = createSVGElement("marker"); +marker.setAttribute("id", "marker"); +marker.setAttribute("viewBox", "0 0 10 10"); +marker.setAttribute("markerWidth", "4"); +marker.setAttribute("markerHeight", "3"); +marker.setAttribute("markerUnits", "strokeWidth"); +marker.setAttribute("refX", "1"); +marker.setAttribute("refY", "5"); +marker.setAttribute("orient", "0deg"); +defs.appendChild(marker); + +var polyline = createSVGElement("polyline"); +polyline.setAttribute("id", "polyline"); +polyline.setAttribute("points", "0,0 10,5 0,10 1,5"); +polyline.setAttribute("fill", "green"); +marker.appendChild(polyline); + +var path = createSVGElement("path"); +path.setAttribute("id", "path"); +path.setAttribute("d", "M45,50 L55,50"); +path.setAttribute("stroke-width","10"); +path.setAttribute("stroke", "green"); +path.setAttribute("marker-end", "url(#marker)"); +path.setAttribute("onclick", "executeTest()"); + +var animate = createSVGElement("animate"); +animate.setAttribute("id", "animation"); +animate.setAttribute("attributeName", "orient"); +animate.setAttribute("begin", "0s"); +animate.setAttribute("dur", "4s"); +animate.setAttribute("from", "0rad"); +animate.setAttribute("to", "200grad"); +marker.appendChild(animate); +rootSVGElement.appendChild(defs); +rootSVGElement.appendChild(path); + +// Setup animation test +function sample1() { + // Check initial/end conditions + assert_approx_equals(marker.orientAngle.animVal.value, 0, epsilon); + assert_equals(marker.orientAngle.baseVal.value, 0); + + assert_equals(marker.orientType.animVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); + assert_equals(marker.orientType.baseVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); +} + +function sample2() { + assert_approx_equals(marker.orientAngle.animVal.value, 90, epsilon); + assert_equals(marker.orientAngle.baseVal.value, 0); + + assert_equals(marker.orientType.animVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); + assert_equals(marker.orientType.baseVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); +} + +function sample3() { + assert_approx_equals(marker.orientAngle.animVal.value, 180, epsilon); + assert_equals(marker.orientAngle.baseVal.value, 0); + + assert_equals(marker.orientType.animVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); + assert_equals(marker.orientType.baseVal, SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE); +} + +smil_async_test((t) => { + const expectedValues = [ + // [animationId, time, sampleCallback] + ["animation", 0.0, sample1], + ["animation", 2.0, sample2], + ["animation", 3.999, sample3], + ["animation", 4.001, sample1] + ]; + + runAnimationTest(t, expectedValues); +}); + +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/svg/animations/script-tests/svgboolean-animation-1.js b/third_party/blink/web_tests/external/wpt/svg/animations/svgboolean-animation-1.html similarity index 61% rename from third_party/blink/web_tests/svg/animations/script-tests/svgboolean-animation-1.js rename to third_party/blink/web_tests/external/wpt/svg/animations/svgboolean-animation-1.html index 58a8988..3e3de673 100644 --- a/third_party/blink/web_tests/svg/animations/script-tests/svgboolean-animation-1.js +++ b/third_party/blink/web_tests/external/wpt/svg/animations/svgboolean-animation-1.html
@@ -1,5 +1,17 @@ -description("Test 'to' animation of SVGBoolean."); -createSVGTestCase(); +<!doctype html> +<html> +<meta charset="utf-8"> +<title>Test 'to' animation of SVGBoolean.</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/SVGAnimationTestCase-testharness.js"></script> + +<svg> +</svg> + +<script> +var rootSVGElement = document.querySelector("svg"); +var epsilon = 1.0; // Setup test document var defs = createSVGElement("defs"); @@ -27,7 +39,7 @@ var animate = createSVGElement("animate"); animate.setAttribute("id", "animation"); animate.setAttribute("attributeName", "preserveAlpha"); -animate.setAttribute("begin", "rect.click"); +animate.setAttribute("begin", "0s"); animate.setAttribute("dur", "4s"); animate.setAttribute("from", "false"); animate.setAttribute("to", "true"); @@ -35,21 +47,21 @@ // Setup animation test function sample1() { - shouldBe("feConvolveMatrix.preserveAlpha.animVal", "false"); - shouldBe("feConvolveMatrix.preserveAlpha.baseVal", "false"); + assert_equals(feConvolveMatrix.preserveAlpha.animVal, false); + assert_equals(feConvolveMatrix.preserveAlpha.baseVal, false); } function sample2() { - shouldBe("feConvolveMatrix.preserveAlpha.animVal", "false"); - shouldBe("feConvolveMatrix.preserveAlpha.baseVal", "false"); + assert_equals(feConvolveMatrix.preserveAlpha.animVal, false); + assert_equals(feConvolveMatrix.preserveAlpha.baseVal, false); } function sample3() { - shouldBe("feConvolveMatrix.preserveAlpha.animVal", "true"); - shouldBe("feConvolveMatrix.preserveAlpha.baseVal", "false"); + assert_equals(feConvolveMatrix.preserveAlpha.animVal, true); + assert_equals(feConvolveMatrix.preserveAlpha.baseVal, false); } -function executeTest() { +smil_async_test((t) => { const expectedValues = [ // [animationId, time, sampleCallback] ["animation", 0.0, sample1], @@ -58,7 +70,7 @@ ["animation", 4.001, sample1] ]; - runAnimationTest(expectedValues); -} + runAnimationTest(t, expectedValues); +}); -var successfullyParsed = true; +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/svg/animations/script-tests/svgenum-animation-1.js b/third_party/blink/web_tests/external/wpt/svg/animations/svgenum-animation-1.html similarity index 63% rename from third_party/blink/web_tests/svg/animations/script-tests/svgenum-animation-1.js rename to third_party/blink/web_tests/external/wpt/svg/animations/svgenum-animation-1.html index 9e15ea5..05b75e9 100644 --- a/third_party/blink/web_tests/svg/animations/script-tests/svgenum-animation-1.js +++ b/third_party/blink/web_tests/external/wpt/svg/animations/svgenum-animation-1.html
@@ -1,5 +1,17 @@ -description("Test SVGUnitTypes enumeration animations"); -createSVGTestCase(); +<!doctype html> +<html> +<meta charset="utf-8"> +<title>Test SVGUnitTypes enumeration animations</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/SVGAnimationTestCase-testharness.js"></script> + +<svg> +</svg> + +<script> +var rootSVGElement = document.querySelector("svg"); +var epsilon = 1.0; // Setup test document var defs = createSVGElement("defs"); @@ -30,7 +42,7 @@ var animate = createSVGElement("animate"); animate.setAttribute("id", "animation"); animate.setAttribute("attributeName", "patternContentUnits"); -animate.setAttribute("begin", "rect.click"); +animate.setAttribute("begin", "0s"); animate.setAttribute("dur", "4s"); animate.setAttribute("from", "userSpaceOnUse"); animate.setAttribute("to", "objectBoundingBox"); @@ -39,16 +51,16 @@ // Setup animation test function sample1() { - shouldBe("pattern.patternContentUnits.animVal", "SVGUnitTypes.SVG_UNIT_TYPE_USERSPACEONUSE"); - shouldBe("pattern.patternContentUnits.baseVal", "SVGUnitTypes.SVG_UNIT_TYPE_USERSPACEONUSE"); + assert_equals(pattern.patternContentUnits.animVal, SVGUnitTypes.SVG_UNIT_TYPE_USERSPACEONUSE); + assert_equals(pattern.patternContentUnits.baseVal, SVGUnitTypes.SVG_UNIT_TYPE_USERSPACEONUSE); } function sample2() { - shouldBe("pattern.patternContentUnits.animVal", "SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX"); - shouldBe("pattern.patternContentUnits.baseVal", "SVGUnitTypes.SVG_UNIT_TYPE_USERSPACEONUSE"); + assert_equals(pattern.patternContentUnits.animVal, SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX); + assert_equals(pattern.patternContentUnits.baseVal, SVGUnitTypes.SVG_UNIT_TYPE_USERSPACEONUSE); } -function executeTest() { +smil_async_test((t) => { const expectedValues = [ // [animationId, time, sampleCallback] ["animation", 0.0, sample1], @@ -58,7 +70,7 @@ ["animation", 4.001, sample2] ]; - runAnimationTest(expectedValues); -} + runAnimationTest(t, expectedValues); +}); -var successfullyParsed = true; +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/svg/animations/script-tests/svgenum-animation-10.js b/third_party/blink/web_tests/external/wpt/svg/animations/svgenum-animation-10.html similarity index 66% rename from third_party/blink/web_tests/svg/animations/script-tests/svgenum-animation-10.js rename to third_party/blink/web_tests/external/wpt/svg/animations/svgenum-animation-10.html index 4ac9268..e645ea50 100644 --- a/third_party/blink/web_tests/svg/animations/script-tests/svgenum-animation-10.js +++ b/third_party/blink/web_tests/external/wpt/svg/animations/svgenum-animation-10.html
@@ -1,5 +1,17 @@ -description("Test SVGMarkerUnitsType enumeration animations"); -createSVGTestCase(); +<!doctype html> +<html> +<meta charset="utf-8"> +<title>Test SVGMarkerUnitsType enumeration animations</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/SVGAnimationTestCase-testharness.js"></script> + +<svg> +</svg> + +<script> +var rootSVGElement = document.querySelector("svg"); +var epsilon = 1.0; // Setup test document var marker = createSVGElement("marker"); @@ -35,7 +47,7 @@ var animate1 = createSVGElement("animate"); animate1.setAttribute("id", "animation"); animate1.setAttribute("attributeName", "markerUnits"); -animate1.setAttribute("begin", "path.click"); +animate1.setAttribute("begin", "0s"); animate1.setAttribute("dur", "4s"); animate1.setAttribute("from", "userSpaceOnUse"); animate1.setAttribute("to", "strokeWidth"); @@ -44,16 +56,16 @@ // Setup animation test function sample1() { - shouldBe("marker.markerUnits.animVal", "SVGMarkerElement.SVG_MARKERUNITS_USERSPACEONUSE"); - shouldBe("marker.markerUnits.baseVal", "SVGMarkerElement.SVG_MARKERUNITS_USERSPACEONUSE"); + assert_equals(marker.markerUnits.animVal, SVGMarkerElement.SVG_MARKERUNITS_USERSPACEONUSE); + assert_equals(marker.markerUnits.baseVal, SVGMarkerElement.SVG_MARKERUNITS_USERSPACEONUSE); } function sample2() { - shouldBe("marker.markerUnits.animVal", "SVGMarkerElement.SVG_MARKERUNITS_STROKEWIDTH"); - shouldBe("marker.markerUnits.baseVal", "SVGMarkerElement.SVG_MARKERUNITS_USERSPACEONUSE"); + assert_equals(marker.markerUnits.animVal, SVGMarkerElement.SVG_MARKERUNITS_STROKEWIDTH); + assert_equals(marker.markerUnits.baseVal, SVGMarkerElement.SVG_MARKERUNITS_USERSPACEONUSE); } -function executeTest() { +smil_async_test((t) => { const expectedValues = [ // [animationId, time, sampleCallback] ["animation", 0.0, sample1], @@ -63,7 +75,7 @@ ["animation", 4.001, sample2] ]; - runAnimationTest(expectedValues); -} + runAnimationTest(t, expectedValues); +}); -var successfullyParsed = true; +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/svgenum-animation-11.html b/third_party/blink/web_tests/external/wpt/svg/animations/svgenum-animation-11.html new file mode 100644 index 0000000..ebf8409 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/animations/svgenum-animation-11.html
@@ -0,0 +1,95 @@ +<!doctype html> +<html> +<meta charset="utf-8"> +<title>Test BlendModeType enumeration animations</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/SVGAnimationTestCase-testharness.js"></script> + +<svg> +</svg> + +<script> +var rootSVGElement = document.querySelector("svg"); +var epsilon = 1.0; + +// Setup test document +var filter = createSVGElement("filter"); +filter.setAttribute("id", "filter"); +rootSVGElement.appendChild(filter); + +var feFlood = createSVGElement("feFlood"); +feFlood.setAttribute("in", "SourceGraphic"); +feFlood.setAttribute("flood-color", "green"); +feFlood.setAttribute("flood-opacity", "0.5"); +feFlood.setAttribute("result", "img"); +filter.appendChild(feFlood); + +var feBlend = createSVGElement("feBlend"); +feBlend.setAttribute("in", "SourceGraphic"); +feBlend.setAttribute("in2", "img"); +feBlend.setAttribute("mode", "lighten"); +filter.appendChild(feBlend); + +var rect = createSVGElement("rect"); +rect.setAttribute("id", "rect"); +rect.setAttribute("onclick", "executeTest()"); +rect.setAttribute("filter", "url(#filter)"); +rect.setAttribute("width", "100"); +rect.setAttribute("height", "100"); +rootSVGElement.appendChild(rect); + +var animate1 = createSVGElement("animate"); +animate1.setAttribute("id", "animation"); +animate1.setAttribute("attributeName", "mode"); +animate1.setAttribute("begin", "0s"); +animate1.setAttribute("dur", "5s"); +animate1.setAttribute("values", "normal;multiply;screen;darken;lighten"); +animate1.setAttribute("fill", "freeze"); +feBlend.appendChild(animate1); + +// Setup animation test +function sample1() { + assert_equals(feBlend.mode.animVal, SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN); + assert_equals(feBlend.mode.baseVal, SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN); +} + +function sample2() { + assert_equals(feBlend.mode.animVal, SVGFEBlendElement.SVG_FEBLEND_MODE_NORMAL); + assert_equals(feBlend.mode.baseVal, SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN); +} + +function sample3() { + assert_equals(feBlend.mode.animVal, SVGFEBlendElement.SVG_FEBLEND_MODE_MULTIPLY); + assert_equals(feBlend.mode.baseVal, SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN); +} + +function sample4() { + assert_equals(feBlend.mode.animVal, SVGFEBlendElement.SVG_FEBLEND_MODE_SCREEN); + assert_equals(feBlend.mode.baseVal, SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN); +} + +function sample5() { + assert_equals(feBlend.mode.animVal, SVGFEBlendElement.SVG_FEBLEND_MODE_DARKEN); + assert_equals(feBlend.mode.baseVal, SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN); +} + +smil_async_test((t) => { + const expectedValues = [ + // [animationId, time, sampleCallback] + ["animation", 0.0, sample1], + ["animation", 0.001, sample2], + ["animation", 0.999, sample2], + ["animation", 1.001, sample3], + ["animation", 1.999, sample3], + ["animation", 2.001, sample4], + ["animation", 2.999, sample4], + ["animation", 3.001, sample5], + ["animation", 3.999, sample5], + ["animation", 4.001, sample1] + ]; + + runAnimationTest(t, expectedValues); +}); + +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/svgenum-animation-12.html b/third_party/blink/web_tests/external/wpt/svg/animations/svgenum-animation-12.html new file mode 100644 index 0000000..bd60bbc2 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/animations/svgenum-animation-12.html
@@ -0,0 +1,81 @@ +<!doctype html> +<html> +<meta charset="utf-8"> +<title>Test SVGSpreadMethodType enumeration animations</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/SVGAnimationTestCase-testharness.js"></script> + +<svg> +</svg> + +<script> +var rootSVGElement = document.querySelector("svg"); +var epsilon = 1.0; + +// Setup test document +var gradient = createSVGElement("linearGradient"); +gradient.setAttribute("id", "gradient"); +rootSVGElement.appendChild(gradient); + +var stop = createSVGElement("stop"); +stop.setAttribute("offset", "1"); +stop.setAttribute("stop-color", "green"); +gradient.appendChild(stop); + +var feBlend = createSVGElement("feBlend"); +feBlend.setAttribute("in", "SourceGraphic"); +feBlend.setAttribute("in2", "img"); +feBlend.setAttribute("mode", "lighten"); +gradient.appendChild(feBlend); + +var rect = createSVGElement("rect"); +rect.setAttribute("id", "rect"); +rect.setAttribute("onclick", "executeTest()"); +rect.setAttribute("fill", "url(#gradient)"); +rect.setAttribute("width", "100"); +rect.setAttribute("height", "100"); +rootSVGElement.appendChild(rect); + +var animate1 = createSVGElement("animate"); +animate1.setAttribute("id", "animation"); +animate1.setAttribute("attributeName", "spreadMethod"); +animate1.setAttribute("begin", "0s"); +animate1.setAttribute("dur", "3s"); +animate1.setAttribute("values", "pad;reflect;repeat"); +animate1.setAttribute("fill", "freeze"); +gradient.appendChild(animate1); + +// Setup animation test +function sample1() { + assert_equals(gradient.spreadMethod.animVal, SVGGradientElement.SVG_SPREADMETHOD_PAD); + assert_equals(gradient.spreadMethod.baseVal, SVGGradientElement.SVG_SPREADMETHOD_PAD); +} + +function sample2() { + assert_equals(gradient.spreadMethod.animVal, SVGGradientElement.SVG_SPREADMETHOD_REFLECT); + assert_equals(gradient.spreadMethod.baseVal, SVGGradientElement.SVG_SPREADMETHOD_PAD); +} + +function sample3() { + assert_equals(gradient.spreadMethod.animVal, SVGGradientElement.SVG_SPREADMETHOD_REPEAT); + assert_equals(gradient.spreadMethod.baseVal, SVGGradientElement.SVG_SPREADMETHOD_PAD); +} + +smil_async_test((t) => { + const expectedValues = [ + // [animationId, time, sampleCallback] + ["animation", 0.0, sample1], + ["animation", 0.001, sample1], + ["animation", 0.999, sample1], + ["animation", 1.001, sample2], + ["animation", 1.999, sample2], + ["animation", 2.001, sample3], + ["animation", 2.999, sample3], + ["animation", 3.001, sample3] + ]; + + runAnimationTest(t, expectedValues); +}); + +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/svg/animations/script-tests/svgenum-animation-13.js b/third_party/blink/web_tests/external/wpt/svg/animations/svgenum-animation-13.html similarity index 63% rename from third_party/blink/web_tests/svg/animations/script-tests/svgenum-animation-13.js rename to third_party/blink/web_tests/external/wpt/svg/animations/svgenum-animation-13.html index b0973c7..c6dbb0c 100644 --- a/third_party/blink/web_tests/svg/animations/script-tests/svgenum-animation-13.js +++ b/third_party/blink/web_tests/external/wpt/svg/animations/svgenum-animation-13.html
@@ -1,5 +1,17 @@ -description("Test ChannelSelectorType enumeration animations"); -createSVGTestCase(); +<!doctype html> +<html> +<meta charset="utf-8"> +<title>Test ChannelSelectorType enumeration animations</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/SVGAnimationTestCase-testharness.js"></script> + +<svg> +</svg> + +<script> +var rootSVGElement = document.querySelector("svg"); +var epsilon = 1.0; // Setup test document var defsElement = createSVGElement("defs"); @@ -43,7 +55,7 @@ var animate1 = createSVGElement("animate"); animate1.setAttribute("id", "animation"); animate1.setAttribute("attributeName", "xChannelSelector"); -animate1.setAttribute("begin", "rect.click"); +animate1.setAttribute("begin", "0s"); animate1.setAttribute("dur", "4s"); animate1.setAttribute("values", "R;G;B;A"); animate1.setAttribute("fill", "freeze"); @@ -51,26 +63,26 @@ // Setup animation test function sample1() { - shouldBe("displacementMap.xChannelSelector.animVal", "SVGFEDisplacementMapElement.SVG_CHANNEL_B"); - shouldBe("displacementMap.xChannelSelector.baseVal", "SVGFEDisplacementMapElement.SVG_CHANNEL_B"); + assert_equals(displacementMap.xChannelSelector.animVal, SVGFEDisplacementMapElement.SVG_CHANNEL_B); + assert_equals(displacementMap.xChannelSelector.baseVal, SVGFEDisplacementMapElement.SVG_CHANNEL_B); } function sample2() { - shouldBe("displacementMap.xChannelSelector.animVal", "SVGFEDisplacementMapElement.SVG_CHANNEL_R"); - shouldBe("displacementMap.xChannelSelector.baseVal", "SVGFEDisplacementMapElement.SVG_CHANNEL_B"); + assert_equals(displacementMap.xChannelSelector.animVal, SVGFEDisplacementMapElement.SVG_CHANNEL_R); + assert_equals(displacementMap.xChannelSelector.baseVal, SVGFEDisplacementMapElement.SVG_CHANNEL_B); } function sample3() { - shouldBe("displacementMap.xChannelSelector.animVal", "SVGFEDisplacementMapElement.SVG_CHANNEL_G"); - shouldBe("displacementMap.xChannelSelector.baseVal", "SVGFEDisplacementMapElement.SVG_CHANNEL_B"); + assert_equals(displacementMap.xChannelSelector.animVal, SVGFEDisplacementMapElement.SVG_CHANNEL_G); + assert_equals(displacementMap.xChannelSelector.baseVal, SVGFEDisplacementMapElement.SVG_CHANNEL_B); } function sample4() { - shouldBe("displacementMap.xChannelSelector.animVal", "SVGFEDisplacementMapElement.SVG_CHANNEL_A"); - shouldBe("displacementMap.xChannelSelector.baseVal", "SVGFEDisplacementMapElement.SVG_CHANNEL_B"); + assert_equals(displacementMap.xChannelSelector.animVal, SVGFEDisplacementMapElement.SVG_CHANNEL_A); + assert_equals(displacementMap.xChannelSelector.baseVal, SVGFEDisplacementMapElement.SVG_CHANNEL_B); } -function executeTest() { +smil_async_test((t) => { const expectedValues = [ // [animationId, time, sampleCallback] ["animation", 0.0, sample1], @@ -85,7 +97,7 @@ ["animation", 4.001, sample4] ]; - runAnimationTest(expectedValues); -} + runAnimationTest(t, expectedValues); +}); -var successfullyParsed = true; +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/svg/animations/script-tests/svgenum-animation-2.js b/third_party/blink/web_tests/external/wpt/svg/animations/svgenum-animation-2.html similarity index 60% rename from third_party/blink/web_tests/svg/animations/script-tests/svgenum-animation-2.js rename to third_party/blink/web_tests/external/wpt/svg/animations/svgenum-animation-2.html index 1ad1bcef..a1e27a5e 100644 --- a/third_party/blink/web_tests/svg/animations/script-tests/svgenum-animation-2.js +++ b/third_party/blink/web_tests/external/wpt/svg/animations/svgenum-animation-2.html
@@ -1,5 +1,17 @@ -description("Test EdgeModeType enumeration animations"); -createSVGTestCase(); +<!doctype html> +<html> +<meta charset="utf-8"> +<title>Test EdgeModeType enumeration animations</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/SVGAnimationTestCase-testharness.js"></script> + +<svg> +</svg> + +<script> +var rootSVGElement = document.querySelector("svg"); +var epsilon = 1.0; // Setup test document var defs = createSVGElement("defs"); @@ -33,28 +45,28 @@ var animate = createSVGElement("animate"); animate.setAttribute("id", "animation"); animate.setAttribute("attributeName", "edgeMode"); -animate.setAttribute("begin", "rect.click"); +animate.setAttribute("begin", "0s"); animate.setAttribute("dur", "4s"); animate.setAttribute("values", "duplicate;none"); convolveMatrix.appendChild(animate); // Setup animation test function sample1() { - shouldBe("convolveMatrix.edgeMode.animVal", "SVGFEConvolveMatrixElement.SVG_EDGEMODE_WRAP"); - shouldBe("convolveMatrix.edgeMode.baseVal", "SVGFEConvolveMatrixElement.SVG_EDGEMODE_WRAP"); + assert_equals(convolveMatrix.edgeMode.animVal, SVGFEConvolveMatrixElement.SVG_EDGEMODE_WRAP); + assert_equals(convolveMatrix.edgeMode.baseVal, SVGFEConvolveMatrixElement.SVG_EDGEMODE_WRAP); } function sample2() { - shouldBe("convolveMatrix.edgeMode.animVal", "SVGFEConvolveMatrixElement.SVG_EDGEMODE_DUPLICATE"); - shouldBe("convolveMatrix.edgeMode.baseVal", "SVGFEConvolveMatrixElement.SVG_EDGEMODE_WRAP"); + assert_equals(convolveMatrix.edgeMode.animVal, SVGFEConvolveMatrixElement.SVG_EDGEMODE_DUPLICATE); + assert_equals(convolveMatrix.edgeMode.baseVal, SVGFEConvolveMatrixElement.SVG_EDGEMODE_WRAP); } function sample3() { - shouldBe("convolveMatrix.edgeMode.animVal", "SVGFEConvolveMatrixElement.SVG_EDGEMODE_NONE"); - shouldBe("convolveMatrix.edgeMode.baseVal", "SVGFEConvolveMatrixElement.SVG_EDGEMODE_WRAP"); + assert_equals(convolveMatrix.edgeMode.animVal, SVGFEConvolveMatrixElement.SVG_EDGEMODE_NONE); + assert_equals(convolveMatrix.edgeMode.baseVal, SVGFEConvolveMatrixElement.SVG_EDGEMODE_WRAP); } -function executeTest() { +smil_async_test((t) => { const expectedValues = [ // [animationId, time, sampleCallback] ["animation", 0.0, sample1], @@ -65,7 +77,7 @@ ["animation", 4.001, sample1] ]; - runAnimationTest(expectedValues); -} + runAnimationTest(t, expectedValues); +}); -var successfullyParsed = true; +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/svg/painting/parsing/fill-opacity-computed-expected.txt b/third_party/blink/web_tests/external/wpt/svg/painting/parsing/fill-opacity-computed-expected.txt deleted file mode 100644 index aaf3a6e..0000000 --- a/third_party/blink/web_tests/external/wpt/svg/painting/parsing/fill-opacity-computed-expected.txt +++ /dev/null
@@ -1,9 +0,0 @@ -This is a testharness.js-based test. -PASS Property fill-opacity value '-1' computes to '0' -PASS Property fill-opacity value '0.5' computes to '0.5' -PASS Property fill-opacity value '3' computes to '1' -FAIL Property fill-opacity value '-100%' computes to '0' assert_equals: expected "0" but got "1" -FAIL Property fill-opacity value '50%' computes to '0.5' assert_equals: expected "0.5" but got "1" -PASS Property fill-opacity value '300%' computes to '1' -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/svg/painting/parsing/fill-opacity-valid-expected.txt b/third_party/blink/web_tests/external/wpt/svg/painting/parsing/fill-opacity-valid-expected.txt deleted file mode 100644 index a93f1ba..0000000 --- a/third_party/blink/web_tests/external/wpt/svg/painting/parsing/fill-opacity-valid-expected.txt +++ /dev/null
@@ -1,9 +0,0 @@ -This is a testharness.js-based test. -PASS e.style['fill-opacity'] = "-1" should set the property value -PASS e.style['fill-opacity'] = "0.5" should set the property value -PASS e.style['fill-opacity'] = "3" should set the property value -FAIL e.style['fill-opacity'] = "-100%" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['fill-opacity'] = "50%" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['fill-opacity'] = "300%" 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/svg/painting/parsing/stroke-opacity-computed-expected.txt b/third_party/blink/web_tests/external/wpt/svg/painting/parsing/stroke-opacity-computed-expected.txt deleted file mode 100644 index ebc7606..0000000 --- a/third_party/blink/web_tests/external/wpt/svg/painting/parsing/stroke-opacity-computed-expected.txt +++ /dev/null
@@ -1,9 +0,0 @@ -This is a testharness.js-based test. -PASS Property stroke-opacity value '-1' computes to '0' -PASS Property stroke-opacity value '0.5' computes to '0.5' -PASS Property stroke-opacity value '3' computes to '1' -FAIL Property stroke-opacity value '-100%' computes to '0' assert_equals: expected "0" but got "1" -FAIL Property stroke-opacity value '50%' computes to '0.5' assert_equals: expected "0.5" but got "1" -PASS Property stroke-opacity value '300%' computes to '1' -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/svg/painting/parsing/stroke-opacity-valid-expected.txt b/third_party/blink/web_tests/external/wpt/svg/painting/parsing/stroke-opacity-valid-expected.txt deleted file mode 100644 index 21f5a3f..0000000 --- a/third_party/blink/web_tests/external/wpt/svg/painting/parsing/stroke-opacity-valid-expected.txt +++ /dev/null
@@ -1,9 +0,0 @@ -This is a testharness.js-based test. -PASS e.style['stroke-opacity'] = "-1" should set the property value -PASS e.style['stroke-opacity'] = "0.5" should set the property value -PASS e.style['stroke-opacity'] = "3" should set the property value -FAIL e.style['stroke-opacity'] = "-100%" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['stroke-opacity'] = "50%" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['stroke-opacity'] = "300%" 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/svg/pservers/parsing/stop-opacity-computed-expected.txt b/third_party/blink/web_tests/external/wpt/svg/pservers/parsing/stop-opacity-computed-expected.txt deleted file mode 100644 index 7cc6d1c0..0000000 --- a/third_party/blink/web_tests/external/wpt/svg/pservers/parsing/stop-opacity-computed-expected.txt +++ /dev/null
@@ -1,9 +0,0 @@ -This is a testharness.js-based test. -PASS Property stop-opacity value '-1' computes to '0' -PASS Property stop-opacity value '0.5' computes to '0.5' -PASS Property stop-opacity value '3' computes to '1' -FAIL Property stop-opacity value '-100%' computes to '0' assert_equals: expected "0" but got "1" -FAIL Property stop-opacity value '50%' computes to '0.5' assert_equals: expected "0.5" but got "1" -PASS Property stop-opacity value '300%' computes to '1' -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/svg/pservers/parsing/stop-opacity-valid-expected.txt b/third_party/blink/web_tests/external/wpt/svg/pservers/parsing/stop-opacity-valid-expected.txt deleted file mode 100644 index b8e8d535..0000000 --- a/third_party/blink/web_tests/external/wpt/svg/pservers/parsing/stop-opacity-valid-expected.txt +++ /dev/null
@@ -1,9 +0,0 @@ -This is a testharness.js-based test. -PASS e.style['stop-opacity'] = "-1" should set the property value -PASS e.style['stop-opacity'] = "0.5" should set the property value -PASS e.style['stop-opacity'] = "3" should set the property value -FAIL e.style['stop-opacity'] = "-100%" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['stop-opacity'] = "50%" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['stop-opacity'] = "300%" 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/tools/docker/__init__.py b/third_party/blink/web_tests/external/wpt/tools/docker/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/tools/docker/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/tools/docker/commands.json b/third_party/blink/web_tests/external/wpt/tools/docker/commands.json new file mode 100644 index 0000000..15182cc --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/tools/docker/commands.json
@@ -0,0 +1,6 @@ +{ + "docker-run": {"path": "frontend.py", "script": "run", "parser": "parser_run", "help": "Run wpt docker image", + "virtualenv": false}, + "docker-build": {"path": "frontend.py", "script": "build", "help": "Build wpt docker image", + "virtualenv": false} +}
diff --git a/third_party/blink/web_tests/external/wpt/tools/docker/frontend.py b/third_party/blink/web_tests/external/wpt/tools/docker/frontend.py new file mode 100644 index 0000000..c4a2073 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/tools/docker/frontend.py
@@ -0,0 +1,43 @@ +import argparse +import subprocess +import os + +here = os.path.abspath(os.path.dirname(__file__)) +wpt_root = os.path.abspath(os.path.join(here, os.pardir, os.pardir)) + +def build(*args, **kwargs): + subprocess.check_call(["docker", + "build", + "--tag", "wpt:local", + here]) + + +def parser_run(): + parser = argparse.ArgumentParser() + parser.add_argument("--rebuild", action="store_true", help="Force rebuild of image") + parser.add_argument("--checkout", action="store", + help="Revision to checkout in the image. " + "If this is not supplied we mount the wpt checkout on the host as " + "/home/test/web-platform-tests/") + parser.add_argument("--privileged", action="store_true", + help="Run the image in priviledged mode (required for emulators)") + return parser + + +def run(*args, **kwargs): + if kwargs["rebuild"]: + build() + + args = ["docker", "run"] + if kwargs["privileged"]: + args.append("--privileged") + if kwargs["checkout"]: + args.extend(["--env", "REF==%s" % kwargs["checkout"]]) + else: + args.extend(["--mount", + "type=bind,source=%s,target=/home/test/web-platform-tests" % wpt_root]) + args.extend(["-it", "wpt:local"]) + + proc = subprocess.Popen(args) + proc.wait() + return proc.returncode
diff --git a/third_party/blink/web_tests/external/wpt/tools/docker/start.sh b/third_party/blink/web_tests/external/wpt/tools/docker/start.sh index b1ff4a7..dbeeed4 100755 --- a/third_party/blink/web_tests/external/wpt/tools/docker/start.sh +++ b/third_party/blink/web_tests/external/wpt/tools/docker/start.sh
@@ -17,13 +17,15 @@ cd ~ -mkdir web-platform-tests -cd web-platform-tests +if [ ! -d web-platform-tests ]; then + mkdir web-platform-tests + cd web-platform-tests -git init -git remote add origin ${REMOTE} + git init + git remote add origin ${REMOTE} -# Initially we just fetch 50 commits in order to save several minutes of fetching -retry git fetch --quiet --depth=50 --tags origin ${REF}:task_head + # Initially we just fetch 50 commits in order to save several minutes of fetching + retry git fetch --quiet --depth=50 --tags origin ${REF}:task_head -git checkout --quiet task_head + git checkout --quiet task_head +fi
diff --git a/third_party/blink/web_tests/external/wpt/tools/pytest.ini b/third_party/blink/web_tests/external/wpt/tools/pytest.ini index b52e465..6bdb4d5 100644 --- a/third_party/blink/web_tests/external/wpt/tools/pytest.ini +++ b/third_party/blink/web_tests/external/wpt/tools/pytest.ini
@@ -1,3 +1,7 @@ [pytest] norecursedirs = .* {arch} *.egg html5lib third_party pywebsocket six wpt wptrunner -xfail_strict=true +xfail_strict = true +addopts = --strict-markers +markers = + slow: marks tests as slow (deselect with '-m "not slow"') + remote_network
diff --git a/third_party/blink/web_tests/external/wpt/tools/wpt/browser.py b/third_party/blink/web_tests/external/wpt/tools/wpt/browser.py index 6036b3d..0943ee9 100644 --- a/third_party/blink/web_tests/external/wpt/tools/wpt/browser.py +++ b/third_party/blink/web_tests/external/wpt/tools/wpt/browser.py
@@ -36,6 +36,7 @@ else: raise + class Browser(object): __metaclass__ = ABCMeta @@ -534,28 +535,32 @@ self.chromium_platform_string(), revision, self.platform_string()) return url - def _latest_chromedriver_url(self, browser_binary=None): - chrome_version = self.version(browser_binary) - assert chrome_version, "Cannot detect the version of Chrome" + def _latest_chromedriver_url(self, chrome_version): # Remove channel suffixes (e.g. " dev"). chrome_version = chrome_version.split(' ')[0] return (self._official_chromedriver_url(chrome_version) or self._chromium_chromedriver_url(chrome_version)) - def install_webdriver(self, dest=None, channel=None, browser_binary=None): + def install_webdriver_by_version(self, version, dest=None): + assert version, "Cannot install ChromeDriver without Chrome version" if dest is None: dest = os.pwd - if browser_binary is None: - browser_binary = self.find_binary(channel) - url = self._latest_chromedriver_url(browser_binary) + url = self._latest_chromedriver_url(version) self.logger.info("Downloading ChromeDriver from %s" % url) unzip(get(url).raw, dest) - chromedriver_dir = os.path.join(dest, 'chromedriver_%s' % self.platform_string()) + chromedriver_dir = os.path.join( + dest, 'chromedriver_%s' % self.platform_string()) if os.path.isfile(os.path.join(chromedriver_dir, "chromedriver")): shutil.move(os.path.join(chromedriver_dir, "chromedriver"), dest) shutil.rmtree(chromedriver_dir) return find_executable("chromedriver", dest) + def install_webdriver(self, dest=None, channel=None, browser_binary=None): + if browser_binary is None: + browser_binary = self.find_binary(channel) + return self.install_webdriver_by_version( + self.version(browser_binary), dest) + def version(self, binary=None, webdriver_binary=None): if not binary: self.logger.warning("No browser binary provided.") @@ -585,21 +590,43 @@ product = "chrome_android" requirements = "requirements_chrome_android.txt" + def __init__(self, logger): + super(ChromeAndroid, self).__init__(logger) + def install(self, dest=None, channel=None): raise NotImplementedError def find_binary(self, venv_path=None, channel=None): - raise NotImplementedError + if channel in ("beta", "dev", "canary"): + return "com.chrome." + channel + return "com.android.chrome" def find_webdriver(self, channel=None): return find_executable("chromedriver") def install_webdriver(self, dest=None, channel=None, browser_binary=None): + if browser_binary is None: + browser_binary = self.find_binary(channel) chrome = Chrome(self.logger) - return chrome.install_webdriver(dest, channel) + return chrome.install_webdriver_by_version( + self.version(browser_binary), dest) def version(self, binary=None, webdriver_binary=None): - return None + if not binary: + self.logger.warning("No package name provided.") + return None + + command = ['adb', 'shell', 'dumpsys', 'package', binary] + try: + output = call(*command) + except (subprocess.CalledProcessError, OSError): + self.logger.warning("Failed to call %s" % " ".join(command)) + return None + match = re.search(r'versionName=(.*)', output) + if not match: + self.logger.warning("Failed to find versionName") + return None + return match.group(1) class ChromeiOS(Browser): @@ -699,6 +726,7 @@ if m: return m.group(0) + class EdgeChromium(Browser): """MicrosoftEdge-specific interface.""" platform = { @@ -725,16 +753,16 @@ os.path.expandvars("$SYSTEMDRIVE\\Program Files\\Microsoft\\Edge Dev\\Application"), os.path.expandvars("$SYSTEMDRIVE\\Program Files (x86)\\Microsoft\\Edge Beta\\Application"), os.path.expandvars("$SYSTEMDRIVE\\Program Files (x86)\\Microsoft\\Edge Dev\\Application"), - os.path.expanduser("~\\AppData\Local\\Microsoft\\Edge SxS\\Application"),] + os.path.expanduser("~\\AppData\Local\\Microsoft\\Edge SxS\\Application")] return find_executable(binaryname, os.pathsep.join(winpaths)) if self.platform == "macos": binaryname = "Microsoft Edge Canary" binary = find_executable(binaryname) if not binary: macpaths = ["/Applications/Microsoft Edge.app/Contents/MacOS", - os.path.expanduser("~/Applications/Microsoft Edge.app/Contents/MacOS"), - "/Applications/Microsoft Edge Canary.app/Contents/MacOS", - os.path.expanduser("~/Applications/Microsoft Edge Canary.app/Contents/MacOS")] + os.path.expanduser("~/Applications/Microsoft Edge.app/Contents/MacOS"), + "/Applications/Microsoft Edge Canary.app/Contents/MacOS", + os.path.expanduser("~/Applications/Microsoft Edge Canary.app/Contents/MacOS")] return find_executable("Microsoft Edge Canary", os.pathsep.join(macpaths)) return binary @@ -797,6 +825,7 @@ self.logger.warning("Failed to find Edge binary.") return None + class Edge(Browser): """Edge-specific interface."""
diff --git a/third_party/blink/web_tests/external/wpt/tools/wpt/install.py b/third_party/blink/web_tests/external/wpt/tools/wpt/install.py index b107752..8215dfe0 100644 --- a/third_party/blink/web_tests/external/wpt/tools/wpt/install.py +++ b/third_party/blink/web_tests/external/wpt/tools/wpt/install.py
@@ -6,6 +6,7 @@ latest_channels = { 'firefox': 'nightly', 'chrome': 'dev', + 'chrome_android': 'dev', 'edgechromium': 'dev', 'safari': 'preview', 'servo': 'nightly'
diff --git a/third_party/blink/web_tests/external/wpt/tools/wpt/paths b/third_party/blink/web_tests/external/wpt/tools/wpt/paths index 4528222..093a715 100644 --- a/third_party/blink/web_tests/external/wpt/tools/wpt/paths +++ b/third_party/blink/web_tests/external/wpt/tools/wpt/paths
@@ -1,4 +1,5 @@ tools/ci/ +tools/docker/ tools/lint/ tools/manifest/ tools/serve/
diff --git a/third_party/blink/web_tests/external/wpt/tools/wpt/run.py b/third_party/blink/web_tests/external/wpt/tools/wpt/run.py index ae33d1b..617ea72 100644 --- a/third_party/blink/web_tests/external/wpt/tools/wpt/run.py +++ b/third_party/blink/web_tests/external/wpt/tools/wpt/run.py
@@ -281,7 +281,7 @@ logger.info("Downloading chromedriver") webdriver_binary = self.browser.install_webdriver( dest=self.venv.bin_path, - browser_binary=kwargs["binary"] + browser_binary=kwargs["binary"], ) else: logger.info("Using webdriver binary %s" % webdriver_binary) @@ -290,8 +290,8 @@ kwargs["webdriver_binary"] = webdriver_binary else: raise WptrunError("Unable to locate or install chromedriver binary") - if kwargs["browser_channel"] == "dev": - logger.info("Automatically turning on experimental features for Chrome Dev") + if browser_channel in ("dev", "canary"): + logger.info("Automatically turning on experimental features for Chrome Dev/Canary") kwargs["binary_args"].append("--enable-experimental-web-platform-features") # HACK(Hexcles): work around https://github.com/web-platform-tests/wpt/issues/16448 kwargs["webdriver_args"].append("--disable-build-check") @@ -302,6 +302,10 @@ browser_cls = browser.ChromeAndroid def setup_kwargs(self, kwargs): + browser_channel = kwargs["browser_channel"] + if kwargs["package_name"] is None: + kwargs["package_name"] = self.browser.find_binary( + channel=browser_channel) if kwargs["webdriver_binary"] is None: webdriver_binary = self.browser.find_webdriver() @@ -310,7 +314,10 @@ if install: logger.info("Downloading chromedriver") - webdriver_binary = self.browser.install_webdriver(dest=self.venv.bin_path) + webdriver_binary = self.browser.install_webdriver( + dest=self.venv.bin_path, + browser_binary=kwargs["package_name"], + ) else: logger.info("Using webdriver binary %s" % webdriver_binary) @@ -318,6 +325,11 @@ kwargs["webdriver_binary"] = webdriver_binary else: raise WptrunError("Unable to locate or install chromedriver binary") + if browser_channel in ("dev", "canary"): + logger.info("Automatically turning on experimental features for Chrome Dev/Canary") + kwargs["binary_args"].append("--enable-experimental-web-platform-features") + # HACK(Hexcles): work around https://github.com/web-platform-tests/wpt/issues/16448 + kwargs["webdriver_args"].append("--disable-build-check") class ChromeiOS(BrowserSetup): @@ -626,8 +638,10 @@ # Only update browser_version if it was not given as a command line # argument, so that it can be overridden on the command line. if not kwargs["browser_version"]: - kwargs["browser_version"] = setup_cls.browser.version(binary=kwargs.get("binary"), - webdriver_binary=kwargs.get("webdriver_binary")) + kwargs["browser_version"] = setup_cls.browser.version( + binary=kwargs.get("binary") or kwargs.get("package_name"), + webdriver_binary=kwargs.get("webdriver_binary"), + ) return kwargs
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/browsers/chrome_android.py b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/browsers/chrome_android.py index b7d553c..b8ebede 100644 --- a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/browsers/chrome_android.py +++ b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/browsers/chrome_android.py
@@ -25,11 +25,12 @@ def check_args(**kwargs): + require_arg(kwargs, "package_name") require_arg(kwargs, "webdriver_binary") def browser_kwargs(test_type, run_info_data, config, **kwargs): - return {"binary": kwargs["binary"], + return {"package_name": kwargs["package_name"], "webdriver_binary": kwargs["webdriver_binary"], "webdriver_args": kwargs.get("webdriver_args")} @@ -45,15 +46,13 @@ executor_kwargs = chrome_executor_kwargs(test_type, server_config, cache_manager, run_info_data, **kwargs) + # Remove unsupported options on mobile. del executor_kwargs["capabilities"]["goog:chromeOptions"]["prefs"] del executor_kwargs["capabilities"]["goog:chromeOptions"]["useAutomationExtension"] - # TODO(Hexcles): browser_channel should be properly supported. - package_name = "com.android.chrome" # stable channel - # Required to start on mobile + assert kwargs["package_name"], "missing --package-name" executor_kwargs["capabilities"]["goog:chromeOptions"]["androidPackage"] = \ - package_name - # Map wptrunner args to chromeOptions. + kwargs["package_name"] return executor_kwargs @@ -71,12 +70,10 @@ ``wptrunner.webdriver.ChromeDriverServer``. """ - def __init__(self, logger, binary, webdriver_binary="chromedriver", + def __init__(self, logger, package_name, webdriver_binary="chromedriver", webdriver_args=None): - """Creates a new representation of Chrome. The `binary` argument gives - the browser binary to use for testing.""" Browser.__init__(self, logger) - self.binary = binary + self.package_name = package_name self.server = ChromeDriverServer(self.logger, binary=webdriver_binary, args=webdriver_args)
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptserve/README.md b/third_party/blink/web_tests/external/wpt/tools/wptserve/README.md index 30a7dcc..6821dee38 100644 --- a/third_party/blink/web_tests/external/wpt/tools/wptserve/README.md +++ b/third_party/blink/web_tests/external/wpt/tools/wptserve/README.md
@@ -3,4 +3,4 @@ Web server designed for use with web-platform-tests. -[wptserve.readthedocs.io](http://wptserve.readthedocs.io/en/latest/index.html) +See the docs on [web-platform-tests.org](https://web-platform-tests.org/tools/wptserve/docs/index.html).
diff --git a/third_party/blink/web_tests/external/wpt/url/resources/setters_tests.json b/third_party/blink/web_tests/external/wpt/url/resources/setters_tests.json index db23d92..0b4f6b6 100644 --- a/third_party/blink/web_tests/external/wpt/url/resources/setters_tests.json +++ b/third_party/blink/web_tests/external/wpt/url/resources/setters_tests.json
@@ -597,7 +597,7 @@ } }, { - "comment": "Cannot-be-a-base means no password", + "comment": "Cannot-be-a-base means no host", "href": "data:text/plain,Stuff", "new_value": "example.net", "expected": { @@ -1074,7 +1074,7 @@ } }, { - "comment": "Cannot-be-a-base means no password", + "comment": "Cannot-be-a-base means no host", "href": "data:text/plain,Stuff", "new_value": "example.net", "expected": {
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/DocumentTimeline/constructor.html b/third_party/blink/web_tests/external/wpt/web-animations/interfaces/DocumentTimeline/constructor.html index e4714be..ca0997ac 100644 --- a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/DocumentTimeline/constructor.html +++ b/third_party/blink/web_tests/external/wpt/web-animations/interfaces/DocumentTimeline/constructor.html
@@ -5,6 +5,7 @@ <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <script src="../../testcommon.js"></script> +<script src="../../resources/timing-override.js"></script> <body> <div id="log"></div> <script>
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/resources/timing-override.js b/third_party/blink/web_tests/external/wpt/web-animations/resources/timing-override.js new file mode 100644 index 0000000..a1d65030 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/web-animations/resources/timing-override.js
@@ -0,0 +1,18 @@ +// Firefox implements unconditional clamping of 20 usec; and for certain web-animation tests, +// we hit some test failures because the Time Precision is too small. We override these functions +// on a per-test basis for Firefox only. +if(navigator.userAgent.toLowerCase().indexOf('firefox') > -1){ + window.assert_times_equal = (actual, expected, description) => { + let TIME_PRECISION = 0.02; + assert_approx_equals(actual, expected, TIME_PRECISION * 2, description); + }; + + window.assert_time_equals_literal = (actual, expected, description) => { + let TIME_PRECISION = 0.02; + if (Math.abs(expected) === Infinity) { + assert_equals(actual, expected, description); + } else { + assert_approx_equals(actual, expected, TIME_PRECISION, description); + } + } +}
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/timing-model/animations/finishing-an-animation.html b/third_party/blink/web_tests/external/wpt/web-animations/timing-model/animations/finishing-an-animation.html index cb824ae..779bee18 100644 --- a/third_party/blink/web_tests/external/wpt/web-animations/timing-model/animations/finishing-an-animation.html +++ b/third_party/blink/web_tests/external/wpt/web-animations/timing-model/animations/finishing-an-animation.html
@@ -6,6 +6,7 @@ <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <script src="../../testcommon.js"></script> +<script src="../../resources/timing-override.js"></script> <body> <div id="log"></div> <script>
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/timing-model/animations/setting-the-start-time-of-an-animation.html b/third_party/blink/web_tests/external/wpt/web-animations/timing-model/animations/setting-the-start-time-of-an-animation.html index 454a294..a172799 100644 --- a/third_party/blink/web_tests/external/wpt/web-animations/timing-model/animations/setting-the-start-time-of-an-animation.html +++ b/third_party/blink/web_tests/external/wpt/web-animations/timing-model/animations/setting-the-start-time-of-an-animation.html
@@ -5,6 +5,7 @@ <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <script src="../../testcommon.js"></script> +<script src="../../resources/timing-override.js"></script> <body> <div id="log"></div> <script> @@ -262,7 +263,7 @@ // calculated using the new playback rate assert_times_equal(anim.startTime, anim.timeline.currentTime - 25 * MS_PER_SEC); - assert_time_equals_literal(anim.currentTime, 50 * MS_PER_SEC); + assert_time_equals_literal(parseInt(anim.currentTime.toPrecision(5), 10), 50 * MS_PER_SEC); }, 'Setting the start time of a playing animation applies a pending playback rate'); </script>
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/timing-model/animations/the-current-time-of-an-animation.html b/third_party/blink/web_tests/external/wpt/web-animations/timing-model/animations/the-current-time-of-an-animation.html index a0e1a111..77a6b71 100644 --- a/third_party/blink/web_tests/external/wpt/web-animations/timing-model/animations/the-current-time-of-an-animation.html +++ b/third_party/blink/web_tests/external/wpt/web-animations/timing-model/animations/the-current-time-of-an-animation.html
@@ -5,6 +5,7 @@ <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <script src="../../testcommon.js"></script> +<script src="../../resources/timing-override.js"></script> <body> <div id="log"></div> <script>
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/timing-model/timelines/document-timelines.html b/third_party/blink/web_tests/external/wpt/web-animations/timing-model/timelines/document-timelines.html index 4023bba..f45865ac 100644 --- a/third_party/blink/web_tests/external/wpt/web-animations/timing-model/timelines/document-timelines.html +++ b/third_party/blink/web_tests/external/wpt/web-animations/timing-model/timelines/document-timelines.html
@@ -9,6 +9,10 @@ <script> 'use strict'; +function matchUnconditionalClamping(timestamp) { + return parseFloat((Math.floor(timestamp / .02) * .02).toPrecision(8), 10); +} + async_test(t => { assert_greater_than_equal(document.timeline.currentTime, 0, 'The current time is initially is positive or zero'); @@ -28,7 +32,7 @@ // so we use requestAnimationFrame instead. window.requestAnimationFrame(rafTime => { t.step(() => { - assert_equals(document.timeline.currentTime, rafTime, + assert_equals(document.timeline.currentTime, matchUnconditionalClamping(rafTime), 'The current time matches requestAnimationFrame time'); }); t.done();
diff --git a/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt index b4ff722..e95d7884 100644 --- a/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt +++ b/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 202 tests; 200 PASS, 2 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 192 tests; 190 PASS, 2 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS idl_test setup PASS Partial interface Navigator: original interface defined PASS Partial dictionary WebGLContextAttributes: original dictionary defined @@ -110,15 +110,6 @@ PASS XRRigidTransform interface: attribute orientation PASS XRRigidTransform interface: attribute matrix PASS XRRigidTransform interface: attribute inverse -PASS XRRay interface: existence and properties of interface object -PASS XRRay interface object length -PASS XRRay interface object name -PASS XRRay interface: existence and properties of interface prototype object -PASS XRRay interface: existence and properties of interface prototype object's "constructor" property -PASS XRRay interface: existence and properties of interface prototype object's @@unscopables property -PASS XRRay interface: attribute origin -PASS XRRay interface: attribute direction -PASS XRRay interface: attribute matrix PASS XRPose interface: existence and properties of interface object PASS XRPose interface object length PASS XRPose interface object name @@ -144,7 +135,6 @@ PASS XRInputSource interface: attribute targetRayMode PASS XRInputSource interface: attribute targetRaySpace PASS XRInputSource interface: attribute gripSpace -PASS XRInputSource interface: attribute gamepad PASS XRInputSource interface: attribute profiles PASS XRInputSourceArray interface: existence and properties of interface object PASS XRInputSourceArray interface object length
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-01-expected.html b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-01-expected.html new file mode 100644 index 0000000..d04c1bc0 --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-01-expected.html
@@ -0,0 +1,44 @@ +<!DOCTYPE html> +<html> +<head> +<style type="text/css"> + table { + border-collapse: collapse; + } + + td, th { + border: 1px solid; + border-bottom-color: black; + border-left-color: purple; + border-right-color: orange; + border-top-color: green; + padding: 8px; + text-align: left; + } + + tr:nth-child(even) { + background-color: blue; + color: red; + } +</style> +</head> +<body> + <table> + <tr> + <th>Column1</th> + <th>Column2</th> + <th>Column3</th> + </tr> + <tr> + <td>Entry1</td> + <td>Entry1</td> + <td>Entry1</td> + </tr> + <tr> + <td>Entry2</td> + <td>Entry2</td> + <td>Entry2</td> + </tr> + </table> +</body> +</html>
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-01.html b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-01.html new file mode 100644 index 0000000..c53078a --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-01.html
@@ -0,0 +1,45 @@ +<!DOCTYPE html> +<html> +<title>Test forced colors mode on table styles</title> +<link rel=match href=forced-colors-mode-01-expected.html> +<style type="text/css"> + table { + border-collapse: collapse; + } + + td, th { + border: 1px solid; + border-bottom-color: black; + border-left-color: purple; + border-right-color: orange; + border-top-color: green; + padding: 8px; + text-align: left; + } + + tr:nth-child(even) { + background-color: blue; + color: red; + } +</style> + +<body> + <table> + <tr> + <th>Column1</th> + <th>Column2</th> + <th>Column3</th> + </tr> + <tr> + <td>Entry1</td> + <td>Entry1</td> + <td>Entry1</td> + </tr> + <tr> + <td>Entry2</td> + <td>Entry2</td> + <td>Entry2</td> + </tr> + </table> +</body> +</html>
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-02-expected.html b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-02-expected.html new file mode 100644 index 0000000..8705bd2 --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-02-expected.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<html> +<head> +<style type="text/css"> + body { + background-color: lightblue; + } + #a { + background-color: lightgreen; + border: 25px solid green; + box-shadow: 2px 2px purple; + color: orange; + forced-color-adjust: auto; + margin: 25px; + padding: 25px; + text-shadow: 1px 1px gray; + width: 300px; + } + #b { + background-color: lightgreen; + border: 25px solid green; + box-shadow: 2px 2px purple; + color: orange; + forced-color-adjust: none; + margin: 25px; + padding: 25px; + text-shadow: 1px 1px gray; + width: 300px; + } +</style> +</head> +<body> + <div id="a"> + The colors and shadows of this text and text box should be overridden when in + forced colors mode (forced-color-adjust is set to auto.) + </div> + <div id="b"> + The colors and shadows of this text and text box should NOT be overridden when in + forced colors mode (forced-color-adjust is set to none.) + </div> +</body> +</html>
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-02.html b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-02.html new file mode 100644 index 0000000..e7cfcd5c --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-02.html
@@ -0,0 +1,44 @@ +<!DOCTYPE html> +<html> +<head> +<title>Forced colors mode - style overrides for text.</title> +<link rel=match href=forced-colors-mode-02-expected.html> +<style type="text/css"> + body { + background-color: lightblue; + } + #a { + background-color: lightgreen; + border: 25px solid green; + box-shadow: 2px 2px purple; + color: orange; + forced-color-adjust: auto; + margin: 25px; + padding: 25px; + text-shadow: 1px 1px gray; + width: 300px; + } + #b { + background-color: lightgreen; + border: 25px solid green; + box-shadow: 2px 2px purple; + color: orange; + forced-color-adjust: none; + margin: 25px; + padding: 25px; + text-shadow: 1px 1px gray; + width: 300px; + } +</style> +</head> +<body> + <div id="a"> + The colors and shadows of this text and text box should be overridden when in + forced colors mode (forced-color-adjust is set to auto.) + </div> + <div id="b"> + The colors and shadows of this text and text box should NOT be overridden when in + forced colors mode (forced-color-adjust is set to none.) + </div> +</body> +</html>
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-03-expected.txt b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-03-expected.txt new file mode 100644 index 0000000..5c7aaedd --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-03-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Checks that default highlighted text style does not get overridden in forced colors mode. assert_equals: expected "rgb(0, 0, 0)" but got "rgb(255, 165, 0)" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-03.html b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-03.html new file mode 100644 index 0000000..3eab7297 --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-03.html
@@ -0,0 +1,44 @@ +<!DOCTYPE html> +<html> +<head> +<title>Forced colors mode - highlighted text.</title> +<style type="text/css"> + #a { + color: orange; + forced-color-adjust: auto; + } + #b { + color: orange; + forced-color-adjust: none; + } +</style> +</head> +<body> + <mark id="a"> + This text should be black in forced colors mode because forced-color-adjust + is auto. The backgroud color should be yellow because the default + highlighted colors should not be overridden in forced colors mode. + </mark> + <mark id="b"> + This text should be orange in forced colors mode because + forced-color-adjust is none. The backgroud color should be yellow because + the default highlighted colors should not be overridden in forced colors + mode. + </mark> +</body> + +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script> + test(function(){ + assert_equals(getComputedStyle(a).color, "rgb(0, 0, 0)"); + + assert_equals(getComputedStyle(b).color, "rgb(255, 165, 0)"); + + assert_equals(getComputedStyle(a).backgroundColor, "rgb(255, 255, 0)"); + + assert_equals(getComputedStyle(b).backgroundColor, "rgb(255, 255, 0)"); + + }, "Checks that default highlighted text style does not get overridden in forced colors mode."); +</script> +</html>
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-04-expected.txt b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-04-expected.txt new file mode 100644 index 0000000..5f26c685 --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-04-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Checks hyperlinks are overridden in forced colors mode. assert_equals: expected "rgba(0, 0, 0, 0.18)" but got "rgb(0, 0, 255)" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-04.html b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-04.html new file mode 100644 index 0000000..368bead --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-04.html
@@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html> +<head> +<title>Forced colors mode - webkit-tap-highlight-color.</title> +<style type="text/css"> + a { + -webkit-tap-highlight-color: rgb(0, 0, 255); + } +</style> +</head> +<body> + <p> + <a href="https://www.wikipedia.org" id="link"> + This link color should be overridden when forced colors mode is enabled. + </a> + </p> +</body> + +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script> + test(function(){ + assert_equals(getComputedStyle(link).webkitTapHighlightColor, "rgba(0, 0, 0, 0.18)"); + }, "Checks hyperlinks are overridden in forced colors mode."); +</script> +</html>
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-05-expected.html b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-05-expected.html new file mode 100644 index 0000000..18fbc57 --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-05-expected.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html> +<head> +<style type="text/css"> + a { + color: rgb(255, 0, 0); + } +</style> +</head> +<body> + <p> + <a href="https://www.wikipedia.org" id="link"> + This link color should be overridden when forced colors mode is enabled. + </a> + </p> +</body> +</html>
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-05.html b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-05.html new file mode 100644 index 0000000..93fff5d --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-05.html
@@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> +<head> +<title>Forced colors mode - link color.</title> +<link rel=match href=forced-colors-mode-05-expected.html> +<style type="text/css"> + a { + color: rgb(255, 0, 0); + } +</style> +</head> +<body> + <p> + <a href="https://www.wikipedia.org" id="link"> + This link color should be overridden when forced colors mode is enabled. + </a> + </p> +</body> +</html>
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-06-expected.html b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-06-expected.html new file mode 100644 index 0000000..ee78fcb --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-06-expected.html
@@ -0,0 +1,7 @@ +<!DOCTYPE html> +<html> +<head> +<body> + <iframe src="forced-colors-mode-02-expected.html" width="500" height="500"></iframe> +</body> +</html>
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-06.html b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-06.html new file mode 100644 index 0000000..7a2dd29e --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-06.html
@@ -0,0 +1,11 @@ +<!DOCTYPE html> +<html> +<head> +<title>Forced colors mode - iframe. + Test that styles are overridden inside iframes in forced colors mode. +</title> +<link rel=match href=forced-colors-mode-06-expected.html> +<body> + <iframe src="forced-colors-mode-02.html" width="500" height="500"></iframe> +</body> +</html>
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-07-expected.html b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-07-expected.html new file mode 100644 index 0000000..15623ae8 --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-07-expected.html
@@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html> +<head> +<style> + p { + color: transparent; + } +</style> +<body> + <div style="background-color: rgb(0, 0, 255);"> + <p> + The text color should be overridden, and the background color of the + div element should also be overridden in forced colors mode. + </p> + </div> + <div style="background-color: transparent;"> + <p> + The text color should be overridden, but the background color of the + div element should remain transparent in forced colors mode. + </p> + </div> + <div style="background-color: rgba(0, 0, 0, 0);"> + <p> + The text color should be overridden, but the background color of the + div element should remain transparent in forced colors mode. + </p> + </div> +</body> +</html>
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-07.html b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-07.html new file mode 100644 index 0000000..b111479 --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-07.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<html> +<head> +<title>Forced colors mode - transparent colors.</title> +<link rel=match href=forced-colors-mode-07-expected.html> +<style> + p { + color: transparent; + } +</style> +<body> + <div style="background-color: rgb(0, 0, 255);"> + <p> + The text color should be overridden, and the background color of the + div element should also be overridden in forced colors mode. + </p> + </div> + <div style="background-color: transparent;"> + <p> + The text color should be overridden, but the background color of the + div element should remain transparent in forced colors mode. + </p> + </div> + <div style="background-color: rgba(0, 0, 0, 0);"> + <p> + The text color should be overridden, but the background color of the + div element should remain transparent in forced colors mode. + </p> + </div> +</body> +</html>
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-08-expected.html b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-08-expected.html new file mode 100644 index 0000000..c9e55d4 --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-08-expected.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html> +<head> +<style> + h1 { + outline-color: rgb(0, 0, 255); + outline-style: solid; + -webkit-column-count: 3; + -webkit-column-gap: 40px; + -webkit-column-rule-color: rgb(0, 0, 255); + -webkit-column-rule-style: solid; + } +</style> +</head> +<body> + <h1> + The outline-color and column-rule-color should be blue when forced colors + mode is off and WindowText in forced colors mode. + </h1> +</body> +</html>
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-08.html b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-08.html new file mode 100644 index 0000000..133f09ab --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-08.html
@@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html> +<head> +<title>Forced colors mode - outline and column color.</title> +<link rel=match href=forced-colors-mode-08-expected.html> +<style> + h1 { + outline-color: rgb(0, 0, 255); + outline-style: solid; + -webkit-column-count: 3; + -webkit-column-gap: 40px; + -webkit-column-rule-color: rgb(0, 0, 255); + -webkit-column-rule-style: solid; + } +</style> +</head> +<body> + <h1> + The outline-color and column-rule-color should be blue when forced colors + mode is off and WindowText in forced colors mode. + </h1> +</body> +</html>
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-09-expected.txt b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-09-expected.txt new file mode 100644 index 0000000..c13cecb --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-09-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Checks that styles defined inside/outside forced-colors are overridden in forced colors mode. assert_not_equals: got disallowed value "rgb(0, 0, 255)" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-09.html b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-09.html new file mode 100644 index 0000000..29b1a88 --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-09.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<title> + Forced colors mode - forced-colors media query. + Tests that styles defined inside or outside a forced-colors media query are + overridden in forced colors mode. +</title> +<style type="text/css"> + @media (forced-colors) { + p { + color: rgb(0, 0, 255); + } + } + p { + color: rgb(0, 0, 255); + } +</style> +</head> +<body> + <p id="p"> + This text should NOT be blue forced colors mode. + </p> +</body> + +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script> + test(function() { + assert_not_equals(getComputedStyle(p).color, "rgb(0, 0, 255)"); + }, "Checks that styles defined inside/outside forced-colors are overridden in forced colors mode."); + </script> +</html>
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-10-expected.txt b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-10-expected.txt new file mode 100644 index 0000000..dfa26792a --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-10-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Checks that styles defined inside/outside forced-colors are preserved in forced colors mode if forced-color-ajust is none. assert_equals: expected "rgb(0, 0, 255)" but got "rgb(0, 128, 0)" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-10.html b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-10.html new file mode 100644 index 0000000..3d5dca9d --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-10.html
@@ -0,0 +1,38 @@ +<!DOCTYPE html> +<html> +<head> +<title> + Forced colors mode - forced-colors media query. + Tests that styles defined inside/outside forced-color media query + are preserved in forced colors mode if forced-color-adjust is none + and that the ordering of styles is preserved. +</title> +<style type="text/css"> + p { + background-color: rgb(0, 128, 0); + color: rgb(0, 0, 255); + forced-color-adjust: none; + } + @media (forced-colors) { + p { + background-color: rgb(0, 0, 255); + color: rgb(0, 128, 0); + } + } +</style> +</head> +<body> + <p id="p"> + This text should be green in forced colors mode. + </p> +</body> + +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script> + test(function() { + assert_equals(getComputedStyle(p).backgroundColor, "rgb(0, 0, 255)"); + assert_equals(getComputedStyle(p).color, "rgb(0, 128, 0)"); + }, "Checks that styles defined inside/outside forced-colors are preserved in forced colors mode if forced-color-ajust is none."); + </script> +</html>
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-11-expected.txt b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-11-expected.txt new file mode 100644 index 0000000..06c5ac4 --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-11-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Checks that styles defined in forced-colors are preserved in forced colors mode. assert_equals: expected "rgb(0, 0, 255)" but got "rgba(0, 0, 0, 0)" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-11.html b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-11.html new file mode 100644 index 0000000..f38baf1 --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-11.html
@@ -0,0 +1,40 @@ +<!DOCTYPE html> +<html> +<head> +<title> + Forced colors mode - forced-colors media query. + Tests that styles defined inside forced-color media query + are preserved in forced colors mode if forced-color-adjust + is none. +</title> +<style type="text/css"> + @media (forced-colors: none) { + p { + background-color: rgb(255, 0, 0); + color: rgb(255, 255, 255); + } + } + @media (forced-colors: active) { + p { + background-color: rgb(0, 0, 255); + color: rgb(0, 128, 0); + forced-color-adjust: none; + } + } +</style> +</head> +<body> + <p id="p"> + This text should be green in forced colors mode. + </p> +</body> + +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script> + test(function() { + assert_equals(getComputedStyle(p).backgroundColor, "rgb(0, 0, 255)"); + assert_equals(getComputedStyle(p).color, "rgb(0, 128, 0)"); + }, "Checks that styles defined in forced-colors are preserved in forced colors mode."); + </script> +</html>
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-12-expected.txt b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-12-expected.txt new file mode 100644 index 0000000..5945bee0 --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-12-expected.txt
@@ -0,0 +1,4 @@ +FAIL - "color" property for "box" element at 0s expected: rgb(0, 0, 0) but saw: rgb(255, 0, 0) +FAIL - "color" property for "box" element at 0.5s expected: rgb(0, 0, 0) but saw: rgb(128, 64, 0) +FAIL - "color" property for "box" element at 1s expected: rgb(0, 0, 0) but saw: rgb(255, 0, 0) +
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-12.html b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-12.html new file mode 100644 index 0000000..16956ca --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-12.html
@@ -0,0 +1,39 @@ +<!DOCTYPE html> +<head> + <title> + Forced colors mode - animations. + Tests that animation colors are overridden in forced colors mode. + </title> + <style type="text/css"> + #forcedtextcolor { + color: WindowText; + forced-color-adjust: none; + } + #box { + animation-duration: 1s; + animation-iteration-count: infinite; + animation-timing-function: linear; + animation-name: anim; + } + @keyframes anim { + from { color: red; } + to { color: green; } + } + </style> +</head> +<body> + <div id="box"></div> + <p id="forcedtextcolor"></p> +</body> + +<script src="../../../animations/resources/animation-test-helpers.js"></script> +<script type="text/javascript" charset="utf-8"> + var textcolor = getComputedStyle(forcedtextcolor).color; + const expectedValues = [ + // [time, element-id, property, expected-value, tolerance] + [0.0, "box", "color", textcolor, 1], + [0.5, "box", "color", textcolor, 1], + [1.0, "box", "color", textcolor, 1], + ]; + runAnimationTest(expectedValues); +</script>
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-13-expected.txt b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-13-expected.txt new file mode 100644 index 0000000..f6555ac --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-13-expected.txt
@@ -0,0 +1,2 @@ +PASS - "color" property for "target" element at 0.5s saw something close to: 128,0,0 +
diff --git a/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-13.html b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-13.html new file mode 100644 index 0000000..a18ef2f --- /dev/null +++ b/third_party/blink/web_tests/fast/css/forced-colors-mode/forced-colors-mode-13.html
@@ -0,0 +1,33 @@ +<!doctype html> +<title> + Forced colors mode - transitions. + Tests that color transitions work in forced colors mode. + The only way to get transitions to work in forced colors mode is if + forced-color-adjust is none. Otherwise, the color will always be + overridden upon transition, and no transition will actually happen. +</title> +<style> + #target { + color: black; + font-size: 50px; + forced-color-adjust: none; + transition: all 1s linear; + } + + #target.final { color: red; } +</style> +<script src="../../../animations/resources/animation-test-helpers.js" type="text/javascript"></script> +<script> + const expectedValues = [ + // [time, element-id, property, expected-value, tolerance] + [0.5, 'target', 'color', [128, 0, 0], 64] + ]; + + function setupTest() + { + document.getElementById('target').className = 'final'; + } + + runTransitionTest(expectedValues, setupTest); +</script> +<span id="target">filler text</span>
diff --git a/third_party/blink/web_tests/fast/events/pointerevents/mouse-pointer-capture.html b/third_party/blink/web_tests/fast/events/pointerevents/mouse-pointer-capture.html index 8d10149..244b3da7 100644 --- a/third_party/blink/web_tests/fast/events/pointerevents/mouse-pointer-capture.html +++ b/third_party/blink/web_tests/fast/events/pointerevents/mouse-pointer-capture.html
@@ -47,8 +47,6 @@ "clientY", "layerX", "layerY", - "movementX", - "movementY", "offsetX", "offsetY", "pageX",
diff --git a/third_party/blink/web_tests/fast/events/update_hover_after_layout_change.html b/third_party/blink/web_tests/fast/events/update_hover_after_layout_change.html index 1f3722a..9d9fae2d 100644 --- a/third_party/blink/web_tests/fast/events/update_hover_after_layout_change.html +++ b/third_party/blink/web_tests/fast/events/update_hover_after_layout_change.html
@@ -18,7 +18,7 @@ </style> <script> -internals.runtimeFlags.updateHoverFromLayoutChangeAtBeginFrameEnabled = true; +internals.runtimeFlags.updateHoverAtBeginFrameEnabled = true; var eventList = []; var x = 100;
diff --git a/third_party/blink/web_tests/hid/hidDevice_deviceInfo.html b/third_party/blink/web_tests/hid/hidDevice_deviceInfo.html new file mode 100644 index 0000000..16b2d3f --- /dev/null +++ b/third_party/blink/web_tests/hid/hidDevice_deviceInfo.html
@@ -0,0 +1,205 @@ +<!DOCTYPE html> +<body> +<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> +<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> +<script src="file:///gen/services/device/public/mojom/hid.mojom.js"></script> +<script src="file:///gen/third_party/blink/public/mojom/hid/hid.mojom.js"></script> +<script src="resources/hid-test-utils.js"></script> +<script> + +const kTestVendorId = 0x1234; +const kTestProductId = 0xabcd; +const kTestReportId = 0x01; +const kButtonPrimary = 0x01; +const kTestGuid = 'test-guid'; +const kTestProductName = 'test-device'; +const kTestSerialNumber = 'test-serial'; +const kTestDeviceNode = 'test-device-node'; + +// Constructs and returns a device.mojom.HidDeviceInfo representing a +// gamepad-like device with one input report. The input report has a single +// 8-bit field with a button usage. +function createDeviceWithInputReport(fake) { + const nullUsage = new device.mojom.HidUsageAndPage(); + const buttonUsage = new device.mojom.HidUsageAndPage(); + buttonUsage.usagePage = device.mojom.kPageButton; + buttonUsage.usage = kButtonPrimary; + const gamePadUsage = new device.mojom.HidUsageAndPage(); + gamePadUsage.usagePage = device.mojom.kPageGenericDesktop; + gamePadUsage.usage = device.mojom.kGenericDesktopGamePad; + + const reportItem = new device.mojom.HidReportItem(); + reportItem.isRange = false; + reportItem.isConstant = false; // Data. + reportItem.isVariable = true; // Variable. + reportItem.isRelative = false; // Absolute. + reportItem.wrap = false; // No wrap. + reportItem.isNonLinear = false; // Linear. + reportItem.noPreferredState = false; // Preferred State. + reportItem.hasNullPosition = false; // No Null position. + reportItem.isVolatile = false; // Non Volatile. + reportItem.isBufferedBytes = false; // Bit Field. + reportItem.usages = [buttonUsage]; + reportItem.usageMinimum = nullUsage; + reportItem.usageMaximum = nullUsage; + reportItem.designatorMinimum = 0; + reportItem.designatorMaximum = 0; + reportItem.stringMinimum = 0; + reportItem.stringMaximum = 0; + reportItem.logicalMinimum = 0; + reportItem.logicalMaximum = 1; + reportItem.physicalMinimum = 0; + reportItem.physicalMaximum = 1; + reportItem.unitExponent = 0; + reportItem.unit = 0; // Unitless. + reportItem.reportSize = 8; // 1 byte. + reportItem.reportCount = 1; + + const report = new device.mojom.HidReportDescription(); + report.reportId = kTestReportId; + report.items = [reportItem]; + + const collection = new device.mojom.HidCollectionInfo(); + collection.usage = gamePadUsage; + collection.reportIds = [kTestReportId]; + collection.collectionType = device.mojom.kHIDCollectionTypeApplication; + collection.inputReports = [report]; + collection.outputReports = []; + collection.featureReports = []; + collection.children = []; + + const deviceInfo = fake.makeDevice(kTestVendorId, kTestProductId); + // The device guid will be set by fake.addDevice(). + deviceInfo.productName = kTestProductName; + deviceInfo.serialNumber = kTestSerialNumber; + deviceInfo.busType = device.mojom.HidBusType.kHIDBusTypeUSB; + deviceInfo.reportDescriptor = []; + deviceInfo.collections = [collection]; + deviceInfo.hasReportId = true; + deviceInfo.maxInputReportSize = 1; + deviceInfo.maxOutputReportSize = 0; + deviceInfo.maxFeatureReportSize = 0; + deviceInfo.deviceNode = kTestDeviceNode; + + return deviceInfo; +} + +hid_test(async (t, fake) => { + const deviceInfo = createDeviceWithInputReport(fake); + const guid = fake.addDevice(deviceInfo); + fake.setSelectedDevice(guid); + + await trustedClick(); + const d = await navigator.hid.requestDevice({filters: []}); + + assert_true(d instanceof HIDDevice, 'device instanceof HIDDevice'); + assert_false(d.opened, 'device.opened'); + assert_equals(d.vendorId, kTestVendorId, 'device.vendorId'); + assert_equals(d.productId, kTestProductId, 'device.productId'); + assert_equals(d.productName, kTestProductName, 'device.productName'); + assert_equals(d.collections.length, 1, 'device.collections.length'); + + const c = d.collections[0]; + assert_true(c instanceof HIDCollectionInfo, + 'collection instanceof HIDCollectionInfo'); + assert_equals(c.usagePage, device.mojom.kPageGenericDesktop, + 'collection.usagePage'); + assert_equals(c.usage, device.mojom.kGenericDesktopGamePad, + 'collection.usage'); + assert_equals(c.children.length, 0, 'collection.children.length'); + assert_equals(c.inputReports.length, 1, 'collection.inputReports.length'); + assert_equals(c.outputReports.length, 0, 'collection.outputReports.length'); + assert_equals(c.featureReports.length, 0, 'collection.featureReports.length'); + + const r = c.inputReports[0]; + assert_true(r instanceof HIDReportInfo, 'report instanceof HIDReportInfo'); + assert_equals(r.reportId, kTestReportId, 'report.reportId'); + assert_equals(r.items.length, 1, 'report.items.length'); + + const i = r.items[0]; + assert_true(i instanceof HIDReportItem, + 'reportItem instanceof HIDReportItem'); + assert_true(i.isAbsolute, 'reportItem.isAbsolute'); + assert_false(i.isArray, 'reportItem.isArray'); + assert_false(i.isRange, 'reportItem.isRange'); + assert_false(i.hasNull, 'reportItem.hasNull'); + assert_equals(i.usages.length, 1, 'reportItem.usages.length'); + assert_equals(i.usages[0], 0x00090001, 'reportItem.usages[0]'); + assert_equals(i.usageMinimum, 0, 'reportItem.usageMinimum'); + assert_equals(i.usageMaximum, 0, 'reportItem.usageMaximum'); + assert_equals(i.reportSize, 8, 'reportItem.reportSize'); + assert_equals(i.reportCount, 1, 'reportItem.reportCount'); + assert_equals(i.unitExponent, 0, 'reportItem.unitExponent'); + assert_equals(i.unitSystem, 'none', 'reportItem.unitSystem'); + assert_equals(i.unitFactorLengthExponent, 0, + 'reportItem.unitFactorLengthExponent'); + assert_equals(i.unitFactorMassExponent, 0, + 'reportItem.unitFactorMassExponent'); + assert_equals(i.unitFactorTimeExponent, 0, + 'reportItem.unitFactorTimeExponent'); + assert_equals(i.unitFactorTemperatureExponent, 0, + 'reportItem.unitFactorTemperatureExponent'); + assert_equals(i.unitFactorCurrentExponent, 0, + 'reportItem.unitFactorCurrentExponent'); + assert_equals(i.unitFactorLuminousIntensityExponent, 0, + 'reportItem.unitFactorLuminousIntensityExponent'); + assert_equals(i.logicalMinimum, 0, 'reportItem.logicalMinimum'); + assert_equals(i.logicalMaximum, 1, 'reportItem.logicalMaximum'); + assert_equals(i.physicalMinimum, 0, 'reportItem.physicalMinimum'); + assert_equals(i.physicalMaximum, 1, 'reportItem.physicalMaximum'); + assert_equals(i.strings.length, 0, 'reportItem.strings.length'); +}, 'HIDDevice preserves device info'); + +hid_test(async (t, fake) => { + const deviceInfo = createDeviceWithInputReport(fake); + + // Set the units to nano-Newtons. 10^-9 kg m/s^2 = 10^-4 g cm/s^2 + // |unit_exponent| is set to 0x0C which encodes the factor 10^-4. + // |unit| is a coded value representing "SI Linear, g cm/s^2". + // See "Device Class Definition for HID v1.11" section 6.2.2.7 for more + // information about HID unit values. + deviceInfo.collections[0].inputReports[0].items[0].unitExponent = 0x0C; + deviceInfo.collections[0].inputReports[0].items[0].unit = 0x0000E111; + + const guid = fake.addDevice(deviceInfo); + fake.setSelectedDevice(guid); + + await trustedClick(); + const d = await navigator.hid.requestDevice({filters: []}); + + assert_true(d instanceof HIDDevice, 'device instanceof HIDDevice'); + assert_equals(d.collections.length, 1, 'device.collections.length'); + + const c = d.collections[0]; + assert_true(c instanceof HIDCollectionInfo, + 'collection instanceof HIDCollectionInfo'); + assert_equals(c.inputReports.length, 1, 'collection.inputReports.length'); + + const r = c.inputReports[0]; + assert_true(r instanceof HIDReportInfo, 'report instanceof HIDReportInfo'); + assert_equals(r.items.length, 1, 'report.items.length'); + + const i = r.items[0]; + assert_true(i instanceof HIDReportItem, + 'reportItem instanceof HIDReportItem'); + assert_equals(i.unitExponent, -4, 'reportItem.unitExponent'); + assert_equals(i.unitSystem, 'si-linear', 'reportItem.unitSystem'); + assert_equals(i.unitFactorLengthExponent, 1, + 'reportItem.unitFactorLengthExponent'); + assert_equals(i.unitFactorMassExponent, 1, + 'reportItem.unitFactorMassExponent'); + assert_equals(i.unitFactorTimeExponent, -2, + 'reportItem.unitFactorTimeExponent'); + assert_equals(i.unitFactorTemperatureExponent, 0, + 'reportItem.unitFactorTemperatureExponent'); + assert_equals(i.unitFactorCurrentExponent, 0, + 'reportItem.unitFactorCurrentExponent'); + assert_equals(i.unitFactorLuminousIntensityExponent, 0, + 'reportItem.unitFactorLuminousIntensityExponent'); +}, 'HIDDevice preserves units'); + +</script> +</body>
diff --git a/third_party/blink/web_tests/hid/hidDevice_openAndClose.html b/third_party/blink/web_tests/hid/hidDevice_openAndClose.html new file mode 100644 index 0000000..6be9af6a --- /dev/null +++ b/third_party/blink/web_tests/hid/hidDevice_openAndClose.html
@@ -0,0 +1,70 @@ +<!DOCTYPE html> +<body> +<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> +<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> +<script src="file:///gen/services/device/public/mojom/hid.mojom.js"></script> +<script src="file:///gen/third_party/blink/public/mojom/hid/hid.mojom.js"></script> +<script src="resources/hid-test-utils.js"></script> +<script> + +const kTestVendorId = 0x1234; +const kTestProductId = 0xabcd; + +hid_test(async (t, fake) => { + const guid = fake.addDevice(fake.makeDevice(kTestVendorId, kTestProductId)); + fake.setSelectedDevice(guid); + + await trustedClick(); + const device = await navigator.hid.requestDevice({filters: []}); + assert_true(device instanceof HIDDevice); + assert_false(device.opened); + + await device.close(); + assert_false(device.opened); +}, 'Closing a closed device is not an error'); + +hid_test(async (t, fake) => { + const guid = fake.addDevice(fake.makeDevice(kTestVendorId, kTestProductId)); + fake.setSelectedDevice(guid); + + await trustedClick(); + const device = await navigator.hid.requestDevice({filters: []}); + assert_false(device.opened); + + await device.open(); + assert_true(device.opened); + + device.close(); + assert_false(device.opened); +}, 'Opening and closing a device works'); + +hid_test(async (t, fake) => { + const guid = fake.addDevice(fake.makeDevice(kTestVendorId, kTestProductId)); + fake.setSelectedDevice(guid); + + await trustedClick(); + const device = await navigator.hid.requestDevice({filters: []}); + assert_false(device.opened); + + await device.open(); + return promise_rejects(t, 'InvalidStateError', device.open()); +}, 'Opening a device twice is an error'); + +hid_test(async (t, fake) => { + const guid = fake.addDevice(fake.makeDevice(kTestVendorId, kTestProductId)); + fake.setSelectedDevice(guid); + + await trustedClick(); + const device = await navigator.hid.requestDevice({filters: []}); + assert_false(device.opened); + + const firstRequest = device.open(); + await promise_rejects(t, 'InvalidStateError', device.open()); + await firstRequest; +}, 'Opening a device twice simultaneously is an error'); + +</script> +</body>
diff --git a/third_party/blink/web_tests/hid/hidDevice_reports.html b/third_party/blink/web_tests/hid/hidDevice_reports.html new file mode 100644 index 0000000..83d8088 --- /dev/null +++ b/third_party/blink/web_tests/hid/hidDevice_reports.html
@@ -0,0 +1,99 @@ +<!DOCTYPE html> +<body> +<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> +<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> +<script src="file:///gen/services/device/public/mojom/hid.mojom.js"></script> +<script src="file:///gen/third_party/blink/public/mojom/hid/hid.mojom.js"></script> +<script src="resources/hid-test-utils.js"></script> +<script> + +const kTestVendorId = 0x1234; +const kTestProductId = 0xabcd; +const kReportId = 0x01; +const kReportBytes = new Uint8Array([0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]); + +// Creates a HidDeviceInfo, adds it to the HID service, opens a connection to +// the newly created device, and returns the HidConnection fake. +async function addAndOpenDevice(fake) { + const deviceInfo = fake.makeDevice(kTestVendorId, kTestProductId); + const guid = fake.addDevice(deviceInfo); + fake.setSelectedDevice(guid); + + await trustedClick(); + const device = await navigator.hid.requestDevice({filters: []}); + assert_true(device instanceof HIDDevice); + + await device.open(); + assert_true(device.opened); + + const fakeConnection = fake.getFakeConnection(guid); + return {device, fakeConnection}; +} + +hid_test(async (t, fake) => { + const {device, fakeConnection} = await addAndOpenDevice(fake); + // Register an oninputreport listener and check that it receives a simulated + // input report. + fakeConnection.simulateInputReport(kReportId, kReportBytes); + const inputReport = await oninputreport(device); + assert_equals(inputReport.reportId, kReportId); + compareDataViews(inputReport.data, new DataView(kReportBytes.buffer)); +}, 'oninputreport event listener works'); + +hid_test(async (t, fake) => { + const {device, fakeConnection} = await addAndOpenDevice(fake); + // Simulate write() success. + fakeConnection.queueExpectedWrite(true, kReportId, kReportBytes); + await device.sendReport(kReportId, kReportBytes); + fakeConnection.assertExpectationsMet(); +}, 'sendReport works'); + +hid_test(async (t, fake) => { + const {device, fakeConnection} = await addAndOpenDevice(fake); + // Simulate write() failure. + fakeConnection.queueExpectedWrite(false, kReportId, kReportBytes); + await promise_rejects(t, 'NotAllowedError', + device.sendReport(kReportId, kReportBytes)); + fakeConnection.assertExpectationsMet(); +}, 'Failed sendReport rejects'); + +hid_test(async (t, fake) => { + const {device, fakeConnection} = await addAndOpenDevice(fake); + // Simulate getFeatureReport() success. + fakeConnection.queueExpectedGetFeatureReport(true, kReportId, kReportBytes); + const featureReport = await device.receiveFeatureReport(kReportId); + compareDataViews(featureReport, new DataView(kReportBytes.buffer)); + fakeConnection.assertExpectationsMet(); +}, 'receiveFeatureReport works'); + +hid_test(async (t, fake) => { + const {device, fakeConnection} = await addAndOpenDevice(fake); + // Simulate getFeatureReport() failure. + fakeConnection.queueExpectedGetFeatureReport(false, kReportId, kReportBytes); + await promise_rejects(t, 'NotAllowedError', + device.receiveFeatureReport(kReportId)); + fakeConnection.assertExpectationsMet(); +}, 'Failed receiveFeatureReport rejects'); + +hid_test(async (t, fake) => { + const {device, fakeConnection} = await addAndOpenDevice(fake); + // Simulate sendFeatureReport() success. + fakeConnection.queueExpectedSendFeatureReport(true, kReportId, kReportBytes); + await device.sendFeatureReport(kReportId, kReportBytes); + fakeConnection.assertExpectationsMet(); +}, 'sendFeatureReport works'); + +hid_test(async (t, fake) => { + const {device, fakeConnection} = await addAndOpenDevice(fake); + // Simulate sendFeatureReport() failure. + fakeConnection.queueExpectedSendFeatureReport(false, kReportId, kReportBytes); + await promise_rejects(t, 'NotAllowedError', + device.sendFeatureReport(kReportId, kReportBytes)); + fakeConnection.assertExpectationsMet(); +}, 'Failed sendFeatureReport rejects'); + +</script> +</body>
diff --git a/third_party/blink/web_tests/hid/resources/hid-test-utils.js b/third_party/blink/web_tests/hid/resources/hid-test-utils.js index fb8a427..0fdbd659 100644 --- a/third_party/blink/web_tests/hid/resources/hid-test-utils.js +++ b/third_party/blink/web_tests/hid/resources/hid-test-utils.js
@@ -1,3 +1,126 @@ +// Compare two DataViews byte-by-byte. +function compareDataViews(actual, expected) { + assert_true(actual instanceof DataView, 'actual is DataView'); + assert_true(expected instanceof DataView, 'expected is DataView'); + assert_equals(actual.byteLength, expected.byteLength, 'lengths equal'); + for (let i = 0; i < expected.byteLength; ++i) { + assert_equals(actual.getUint8(i), expected.getUint8(i), + `Mismatch at byte ${i}.`); + } +} + +// Returns a Promise that resolves once |device| receives an input report. +function oninputreport(device) { + assert_true(device instanceof HIDDevice) + return new Promise(resolve => { device.oninputreport = resolve; }); +} + +// Fake implementation of device.mojom.HidConnection. HidConnection represents +// an open connection to a HID device and can be used to send and receive +// reports. +class FakeHidConnection { + constructor(client) { + this.client_ = client; + this.expectedWrites_ = []; + this.expectedGetFeatureReports_ = []; + this.expectedSendFeatureReports_ = []; + } + + bind(request) { + assert_equals(this.binding, undefined); + this.binding = new mojo.Binding(device.mojom.HidConnection, this, request); + this.binding.setConnectionErrorHandler(() => { this.binding = undefined; }); + } + + // Simulate an input report sent from the device to the host. The connection + // client's onInputReport method will be called with the provided |reportId| + // and |buffer|. + simulateInputReport(reportId, reportData) { + if (this.client_) { + this.client_.onInputReport(reportId, reportData); + } + } + + // Specify the result for an expected call to write. If |success| is true the + // write will be successful, otherwise it will simulate a failure. The + // parameters of the next write call must match |reportId| and |buffer|. + queueExpectedWrite(success, reportId, reportData) { + this.expectedWrites_.push({ + params: { reportId: reportId, data: reportData }, + result: { success: success }, + }); + } + + // Specify the result for an expected call to getFeatureReport. If |success| + // is true the operation is successful, otherwise it will simulate a failure. + // The parameter of the next getFeatureReport call must match |reportId|. + queueExpectedGetFeatureReport(success, reportId, reportData) { + this.expectedGetFeatureReports_.push({ + params: { reportId: reportId, }, + result: { success: success, buffer: reportData }, + }); + } + + // Specify the result for an expected call to sendFeatureReport. If |success| + // is true the operation is successful, otherwise it will simulate a failure. + // The parameters of the next sendFeatureReport call must match |reportId| and + // |buffer|. + queueExpectedSendFeatureReport(success, reportId, reportData) { + this.expectedSendFeatureReports_.push({ + params: { reportId: reportId, data: reportData }, + result: { success: success }, + }); + } + + // Asserts that there are no more expected operations. + assertExpectationsMet() { + assert_equals(this.expectedWrites_.length, 0); + assert_equals(this.expectedGetFeatureReports_.length, 0); + assert_equals(this.expectedSendFeatureReports_.length, 0); + } + + // Implementation of HidConnection::Write. Causes an assertion failure if + // there are no expected write operations, or if the parameters do not match + // the expected call. + async write(reportId, buffer) { + let expectedWrite = this.expectedWrites_.shift(); + assert_not_equals(expectedWrite, undefined); + assert_equals(reportId, expectedWrite.params.reportId); + let actual = new Uint8Array(buffer); + compareDataViews( + new DataView(actual.buffer, actual.byteOffset), + new DataView(expectedWrite.params.data.buffer, + expectedWrite.params.data.byteOffset)); + return expectedWrite.result; + } + + // Implementation of HidConnection::GetFeatureReport. Causes an assertion + // failure if there are no expected write operations, or if the parameters do + // not match the expected call. + async getFeatureReport(reportId) { + let expectedGetFeatureReport = this.expectedGetFeatureReports_.shift(); + assert_not_equals(expectedGetFeatureReport, undefined); + assert_equals(reportId, expectedGetFeatureReport.params.reportId); + return expectedGetFeatureReport.result; + } + + // Implementation of HidConnection::SendFeatureReport. Causes an assertion + // failure if there are no expected write operations, or if the parameters do + // not match the expected call. + async sendFeatureReport(reportId, buffer) { + let expectedSendFeatureReport = this.expectedSendFeatureReports_.shift(); + assert_not_equals(expectedSendFeatureReport, undefined); + assert_equals(reportId, expectedSendFeatureReport.params.reportId); + let actual = new Uint8Array(buffer); + compareDataViews( + new DataView(actual.buffer, actual.byteOffset), + new DataView(expectedSendFeatureReport.params.data.buffer, + expectedSendFeatureReport.params.data.byteOffset)); + return expectedSendFeatureReport.result; + } +} + + // A fake implementation of the HidService mojo interface. HidService manages // HID device access for clients in the render process. Typically, when a client // requests access to a HID device a chooser dialog is shown with a list of @@ -28,6 +151,7 @@ reset() { this.devices_ = new Map(); + this.fakeConnections_ = new Map(); this.selectedDevice_ = null; } @@ -66,6 +190,12 @@ this.selectedDevice_ = this.devices_.get(guid); } + // Returns the fake HidConnection object for this device, if there is one. A + // connection is created once the device is opened. + getFakeConnection(guid) { + return this.fakeConnections_.get(guid); + } + bind(handle) { this.bindingSet_.addBinding(this, handle); } @@ -82,6 +212,17 @@ async requestDevice(filters) { return { device: this.selectedDevice_ }; } + + // Returns a fake connection to the device with the specified GUID. If + // |connectionClient| is not null, its onInputReport method will be called + // when input reports are received. + async connect(guid, connectionClient) { + let fakeConnection = new FakeHidConnection(connectionClient); + let connectionPtr = new device.mojom.HidConnectionPtr(); + fakeConnection.bind(mojo.makeRequest(connectionPtr)); + this.fakeConnections_.set(guid, fakeConnection); + return { connection: connectionPtr }; + } } let fakeHidService = new FakeHidService();
diff --git a/third_party/blink/web_tests/http/tests/devtools/agents-enable-disable-expected.txt b/third_party/blink/web_tests/http/tests/devtools/agents-enable-disable-expected.txt index d7d0f50..a5e4e9e 100644 --- a/third_party/blink/web_tests/http/tests/devtools/agents-enable-disable-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/agents-enable-disable-expected.txt
@@ -12,6 +12,7 @@ IndexedDB.disable finished successfully LayerTree.disable finished successfully Log.disable finished successfully +Media.disable finished successfully Network.disable finished successfully Overlay.disable finished successfully Page.disable finished successfully @@ -57,6 +58,9 @@ Log.enable finished successfully Log.disable finished successfully +Media.enable finished successfully +Media.disable finished successfully + Network.enable finished successfully Network.disable finished successfully
diff --git a/third_party/blink/web_tests/http/tests/origin_trials/webexposed/webcomponentsv0-usecounter-customelementv0.html b/third_party/blink/web_tests/http/tests/origin_trials/webexposed/webcomponentsv0-usecounter-customelementv0.html index d0e6a9c6..71c247c 100644 --- a/third_party/blink/web_tests/http/tests/origin_trials/webexposed/webcomponentsv0-usecounter-customelementv0.html +++ b/third_party/blink/web_tests/http/tests/origin_trials/webexposed/webcomponentsv0-usecounter-customelementv0.html
@@ -5,21 +5,17 @@ --> <meta http-equiv="origin-trial" content="Ar9dxxaQ+S9WJDVAL5PqZEtGNqgN2jeewmtzi1+9TK2oavYps7dKu36815FgbztKvcJJ2QATr2g0k0U6nQaDOAMAAABXeyJvcmlnaW4iOiAiaHR0cDovLzEyNy4wLjAuMTo4MDAwIiwgImZlYXR1cmUiOiAiV2ViQ29tcG9uZW50c1YwIiwgImV4cGlyeSI6IDIwMDAwMDAwMDB9" /> +<div id="div"></div> + <script src="../../../../resources/testharness.js"></script> <script src="../../../../resources/testharnessreport.js"></script> <script> test(() => { // From blink/public/mojom/web_feature/web_feature.mojom const DocumentRegisterElementOnReverseOriginTrials = 2849; - assert_false(internals.isUseCounted(document, - DocumentRegisterElementOnReverseOriginTrials)); + assert_false(internals.isUseCounted(document, DocumentRegisterElementOnReverseOriginTrials)); document.registerElement('my-tag'); - const isCounted = internals.isUseCounted(document, - DocumentRegisterElementOnReverseOriginTrials); - // Behavior is different depending on if the runtime flag is enabled. - if (self.internals.runtimeFlags.customElementsV0Enabled) - assert_false(isCounted); - else - assert_true(isCounted); + const isCounted = internals.isUseCounted(document, DocumentRegisterElementOnReverseOriginTrials); + assert_true(isCounted); }, 'Comfirm DocumentRegisterElementOnReverseOriginTrials counter'); </script>
diff --git a/third_party/blink/web_tests/http/tests/origin_trials/webexposed/webcomponentsv0-usecounter-htmlimports.html b/third_party/blink/web_tests/http/tests/origin_trials/webexposed/webcomponentsv0-usecounter-htmlimports.html index e358cc8..fe11caf 100644 --- a/third_party/blink/web_tests/http/tests/origin_trials/webexposed/webcomponentsv0-usecounter-htmlimports.html +++ b/third_party/blink/web_tests/http/tests/origin_trials/webexposed/webcomponentsv0-usecounter-htmlimports.html
@@ -12,16 +12,10 @@ <script> test(() => { // From blink/public/mojom/web_feature/web_feature.mojom - var HTMLImportsOnReverseOriginTrials = 2847; - assert_false(internals.isUseCounted(document, - HTMLImportsOnReverseOriginTrials)); + const HTMLImportsOnReverseOriginTrials = 2847; + assert_false(internals.isUseCounted(document, HTMLImportsOnReverseOriginTrials)); div.innerHTML = "<link id='target' rel='import' href='resources/html-imports-hello.html'>" - var isCounted = internals.isUseCounted(document, - HTMLImportsOnReverseOriginTrials); - // Behavior is different depending on if the runtime flag is enabled. - if (self.internals.runtimeFlags.htmlImportsEnabled) - assert_false(isCounted); - else - assert_true(isCounted); + const isCounted = internals.isUseCounted(document, HTMLImportsOnReverseOriginTrials); + assert_true(isCounted); }, 'Comfirm HTMLImportsOnReverseOriginTrials counter'); </script>
diff --git a/third_party/blink/web_tests/http/tests/origin_trials/webexposed/webcomponentsv0-usecounter-shadowdomv0.html b/third_party/blink/web_tests/http/tests/origin_trials/webexposed/webcomponentsv0-usecounter-shadowdomv0.html index c5fcb583..5443751 100644 --- a/third_party/blink/web_tests/http/tests/origin_trials/webexposed/webcomponentsv0-usecounter-shadowdomv0.html +++ b/third_party/blink/web_tests/http/tests/origin_trials/webexposed/webcomponentsv0-usecounter-shadowdomv0.html
@@ -13,15 +13,9 @@ test(() => { // From blink/public/mojom/web_feature/web_feature.mojom const ElementCreateShadowRootOnReverseOriginTrials = 2848; - assert_false(internals.isUseCounted(document, - ElementCreateShadowRootOnReverseOriginTrials)); + assert_false(internals.isUseCounted(document, ElementCreateShadowRootOnReverseOriginTrials)); div.createShadowRoot(); - const isCounted = internals.isUseCounted(document, - ElementCreateShadowRootOnReverseOriginTrials); - // Behavior is different depending on if the runtime flag is enabled. - if (self.internals.runtimeFlags.shadowDOMV0Enabled) - assert_false(isCounted); - else - assert_true(isCounted); + const isCounted = internals.isUseCounted(document, ElementCreateShadowRootOnReverseOriginTrials); + assert_true(isCounted); }, 'Comfirm ElementCreateShadowRootOnReverseOriginTrials counter'); </script>
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/css/css-color/parsing/opacity-computed-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/css/css-color/parsing/opacity-computed-expected.txt deleted file mode 100644 index 08c678f..0000000 --- a/third_party/blink/web_tests/platform/linux/external/wpt/css/css-color/parsing/opacity-computed-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -This is a testharness.js-based test. -PASS Property opacity value '1' computes to '1' -PASS Property opacity value '0.5' computes to '0.5' -PASS Property opacity value '0' computes to '0' -PASS Property opacity value '-2' computes to '0' -PASS Property opacity value '3' computes to '1' -FAIL Property opacity value '-100%' computes to '0' assert_equals: expected "0" but got "1" -FAIL Property opacity value '50%' computes to '0.5' assert_equals: expected "0.5" but got "1" -PASS Property opacity value '300%' computes to '1' -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/url/url-setters-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/url/url-setters-expected.txt index c8bea77..40801a0 100644 --- a/third_party/blink/web_tests/platform/linux/external/wpt/url/url-setters-expected.txt +++ b/third_party/blink/web_tests/platform/linux/external/wpt/url/url-setters-expected.txt
@@ -208,9 +208,9 @@ PASS URL: Setting <mailto:me@example.net>.host = 'example.com' Cannot-be-a-base means no host PASS <a>: Setting <mailto:me@example.net>.host = 'example.com' Cannot-be-a-base means no host PASS <area>: Setting <mailto:me@example.net>.host = 'example.com' Cannot-be-a-base means no host -PASS URL: Setting <data:text/plain,Stuff>.host = 'example.net' Cannot-be-a-base means no password -PASS <a>: Setting <data:text/plain,Stuff>.host = 'example.net' Cannot-be-a-base means no password -PASS <area>: Setting <data:text/plain,Stuff>.host = 'example.net' Cannot-be-a-base means no password +PASS URL: Setting <data:text/plain,Stuff>.host = 'example.net' Cannot-be-a-base means no host +PASS <a>: Setting <data:text/plain,Stuff>.host = 'example.net' Cannot-be-a-base means no host +PASS <area>: Setting <data:text/plain,Stuff>.host = 'example.net' Cannot-be-a-base means no host PASS URL: Setting <http://example.net>.host = 'example.com:8080' PASS <a>: Setting <http://example.net>.host = 'example.com:8080' PASS <area>: Setting <http://example.net>.host = 'example.com:8080' @@ -352,9 +352,9 @@ PASS URL: Setting <mailto:me@example.net>.hostname = 'example.com' Cannot-be-a-base means no host PASS <a>: Setting <mailto:me@example.net>.hostname = 'example.com' Cannot-be-a-base means no host PASS <area>: Setting <mailto:me@example.net>.hostname = 'example.com' Cannot-be-a-base means no host -PASS URL: Setting <data:text/plain,Stuff>.hostname = 'example.net' Cannot-be-a-base means no password -PASS <a>: Setting <data:text/plain,Stuff>.hostname = 'example.net' Cannot-be-a-base means no password -PASS <area>: Setting <data:text/plain,Stuff>.hostname = 'example.net' Cannot-be-a-base means no password +PASS URL: Setting <data:text/plain,Stuff>.hostname = 'example.net' Cannot-be-a-base means no host +PASS <a>: Setting <data:text/plain,Stuff>.hostname = 'example.net' Cannot-be-a-base means no host +PASS <area>: Setting <data:text/plain,Stuff>.hostname = 'example.net' Cannot-be-a-base means no host PASS URL: Setting <http://example.net:8080>.hostname = 'example.com' PASS <a>: Setting <http://example.net:8080>.hostname = 'example.com' PASS <area>: Setting <http://example.net:8080>.hostname = 'example.com'
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/css/css-color/parsing/opacity-computed-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/css/css-color/parsing/opacity-computed-expected.txt deleted file mode 100644 index 08c678f..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/css/css-color/parsing/opacity-computed-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -This is a testharness.js-based test. -PASS Property opacity value '1' computes to '1' -PASS Property opacity value '0.5' computes to '0.5' -PASS Property opacity value '0' computes to '0' -PASS Property opacity value '-2' computes to '0' -PASS Property opacity value '3' computes to '1' -FAIL Property opacity value '-100%' computes to '0' assert_equals: expected "0" but got "1" -FAIL Property opacity value '50%' computes to '0.5' assert_equals: expected "0.5" but got "1" -PASS Property opacity value '300%' computes to '1' -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/external/wpt/css/css-color/parsing/opacity-computed-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.11/external/wpt/css/css-color/parsing/opacity-computed-expected.txt deleted file mode 100644 index 08c678f..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.11/external/wpt/css/css-color/parsing/opacity-computed-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -This is a testharness.js-based test. -PASS Property opacity value '1' computes to '1' -PASS Property opacity value '0.5' computes to '0.5' -PASS Property opacity value '0' computes to '0' -PASS Property opacity value '-2' computes to '0' -PASS Property opacity value '3' computes to '1' -FAIL Property opacity value '-100%' computes to '0' assert_equals: expected "0" but got "1" -FAIL Property opacity value '50%' computes to '0.5' assert_equals: expected "0.5" but got "1" -PASS Property opacity value '300%' computes to '1' -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/external/wpt/css/css-color/parsing/opacity-computed-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.12/external/wpt/css/css-color/parsing/opacity-computed-expected.txt deleted file mode 100644 index 08c678f..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.12/external/wpt/css/css-color/parsing/opacity-computed-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -This is a testharness.js-based test. -PASS Property opacity value '1' computes to '1' -PASS Property opacity value '0.5' computes to '0.5' -PASS Property opacity value '0' computes to '0' -PASS Property opacity value '-2' computes to '0' -PASS Property opacity value '3' computes to '1' -FAIL Property opacity value '-100%' computes to '0' assert_equals: expected "0" but got "1" -FAIL Property opacity value '50%' computes to '0.5' assert_equals: expected "0.5" but got "1" -PASS Property opacity value '300%' computes to '1' -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac-retina/external/wpt/css/css-color/parsing/opacity-computed-expected.txt b/third_party/blink/web_tests/platform/mac-retina/external/wpt/css/css-color/parsing/opacity-computed-expected.txt deleted file mode 100644 index 08c678f..0000000 --- a/third_party/blink/web_tests/platform/mac-retina/external/wpt/css/css-color/parsing/opacity-computed-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -This is a testharness.js-based test. -PASS Property opacity value '1' computes to '1' -PASS Property opacity value '0.5' computes to '0.5' -PASS Property opacity value '0' computes to '0' -PASS Property opacity value '-2' computes to '0' -PASS Property opacity value '3' computes to '1' -FAIL Property opacity value '-100%' computes to '0' assert_equals: expected "0" but got "1" -FAIL Property opacity value '50%' computes to '0.5' assert_equals: expected "0.5" but got "1" -PASS Property opacity value '300%' computes to '1' -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/css/css-color/parsing/opacity-computed-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/css/css-color/parsing/opacity-computed-expected.txt deleted file mode 100644 index 08c678f..0000000 --- a/third_party/blink/web_tests/platform/mac/external/wpt/css/css-color/parsing/opacity-computed-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -This is a testharness.js-based test. -PASS Property opacity value '1' computes to '1' -PASS Property opacity value '0.5' computes to '0.5' -PASS Property opacity value '0' computes to '0' -PASS Property opacity value '-2' computes to '0' -PASS Property opacity value '3' computes to '1' -FAIL Property opacity value '-100%' computes to '0' assert_equals: expected "0" but got "1" -FAIL Property opacity value '50%' computes to '0.5' assert_equals: expected "0.5" but got "1" -PASS Property opacity value '300%' computes to '1' -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/pointerevents/pointerlock/pointerevent_movementxy-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/pointerevents/pointerlock/pointerevent_movementxy-expected.txt deleted file mode 100644 index cfd42aa..0000000 --- a/third_party/blink/web_tests/platform/mac/external/wpt/pointerevents/pointerlock/pointerevent_movementxy-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL mouse pointerevent attributes assert_equals: movementX should be the delta between current event's and last event's screenX expected 20 but got 0 -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/url/url-setters-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/url/url-setters-expected.txt index c8bea77..40801a0 100644 --- a/third_party/blink/web_tests/platform/mac/external/wpt/url/url-setters-expected.txt +++ b/third_party/blink/web_tests/platform/mac/external/wpt/url/url-setters-expected.txt
@@ -208,9 +208,9 @@ PASS URL: Setting <mailto:me@example.net>.host = 'example.com' Cannot-be-a-base means no host PASS <a>: Setting <mailto:me@example.net>.host = 'example.com' Cannot-be-a-base means no host PASS <area>: Setting <mailto:me@example.net>.host = 'example.com' Cannot-be-a-base means no host -PASS URL: Setting <data:text/plain,Stuff>.host = 'example.net' Cannot-be-a-base means no password -PASS <a>: Setting <data:text/plain,Stuff>.host = 'example.net' Cannot-be-a-base means no password -PASS <area>: Setting <data:text/plain,Stuff>.host = 'example.net' Cannot-be-a-base means no password +PASS URL: Setting <data:text/plain,Stuff>.host = 'example.net' Cannot-be-a-base means no host +PASS <a>: Setting <data:text/plain,Stuff>.host = 'example.net' Cannot-be-a-base means no host +PASS <area>: Setting <data:text/plain,Stuff>.host = 'example.net' Cannot-be-a-base means no host PASS URL: Setting <http://example.net>.host = 'example.com:8080' PASS <a>: Setting <http://example.net>.host = 'example.com:8080' PASS <area>: Setting <http://example.net>.host = 'example.com:8080' @@ -352,9 +352,9 @@ PASS URL: Setting <mailto:me@example.net>.hostname = 'example.com' Cannot-be-a-base means no host PASS <a>: Setting <mailto:me@example.net>.hostname = 'example.com' Cannot-be-a-base means no host PASS <area>: Setting <mailto:me@example.net>.hostname = 'example.com' Cannot-be-a-base means no host -PASS URL: Setting <data:text/plain,Stuff>.hostname = 'example.net' Cannot-be-a-base means no password -PASS <a>: Setting <data:text/plain,Stuff>.hostname = 'example.net' Cannot-be-a-base means no password -PASS <area>: Setting <data:text/plain,Stuff>.hostname = 'example.net' Cannot-be-a-base means no password +PASS URL: Setting <data:text/plain,Stuff>.hostname = 'example.net' Cannot-be-a-base means no host +PASS <a>: Setting <data:text/plain,Stuff>.hostname = 'example.net' Cannot-be-a-base means no host +PASS <area>: Setting <data:text/plain,Stuff>.hostname = 'example.net' Cannot-be-a-base means no host PASS URL: Setting <http://example.net:8080>.hostname = 'example.com' PASS <a>: Setting <http://example.net:8080>.hostname = 'example.com' PASS <area>: Setting <http://example.net:8080>.hostname = 'example.com'
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/css/css-color/parsing/opacity-computed-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/css/css-color/parsing/opacity-computed-expected.txt deleted file mode 100644 index 08c678f..0000000 --- a/third_party/blink/web_tests/platform/win/external/wpt/css/css-color/parsing/opacity-computed-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -This is a testharness.js-based test. -PASS Property opacity value '1' computes to '1' -PASS Property opacity value '0.5' computes to '0.5' -PASS Property opacity value '0' computes to '0' -PASS Property opacity value '-2' computes to '0' -PASS Property opacity value '3' computes to '1' -FAIL Property opacity value '-100%' computes to '0' assert_equals: expected "0" but got "1" -FAIL Property opacity value '50%' computes to '0.5' assert_equals: expected "0.5" but got "1" -PASS Property opacity value '300%' computes to '1' -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/url/url-setters-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/url/url-setters-expected.txt index 91788be4..4ce8aeb 100644 --- a/third_party/blink/web_tests/platform/win/external/wpt/url/url-setters-expected.txt +++ b/third_party/blink/web_tests/platform/win/external/wpt/url/url-setters-expected.txt
@@ -208,9 +208,9 @@ PASS URL: Setting <mailto:me@example.net>.host = 'example.com' Cannot-be-a-base means no host PASS <a>: Setting <mailto:me@example.net>.host = 'example.com' Cannot-be-a-base means no host PASS <area>: Setting <mailto:me@example.net>.host = 'example.com' Cannot-be-a-base means no host -PASS URL: Setting <data:text/plain,Stuff>.host = 'example.net' Cannot-be-a-base means no password -PASS <a>: Setting <data:text/plain,Stuff>.host = 'example.net' Cannot-be-a-base means no password -PASS <area>: Setting <data:text/plain,Stuff>.host = 'example.net' Cannot-be-a-base means no password +PASS URL: Setting <data:text/plain,Stuff>.host = 'example.net' Cannot-be-a-base means no host +PASS <a>: Setting <data:text/plain,Stuff>.host = 'example.net' Cannot-be-a-base means no host +PASS <area>: Setting <data:text/plain,Stuff>.host = 'example.net' Cannot-be-a-base means no host PASS URL: Setting <http://example.net>.host = 'example.com:8080' PASS <a>: Setting <http://example.net>.host = 'example.com:8080' PASS <area>: Setting <http://example.net>.host = 'example.com:8080' @@ -352,9 +352,9 @@ PASS URL: Setting <mailto:me@example.net>.hostname = 'example.com' Cannot-be-a-base means no host PASS <a>: Setting <mailto:me@example.net>.hostname = 'example.com' Cannot-be-a-base means no host PASS <area>: Setting <mailto:me@example.net>.hostname = 'example.com' Cannot-be-a-base means no host -PASS URL: Setting <data:text/plain,Stuff>.hostname = 'example.net' Cannot-be-a-base means no password -PASS <a>: Setting <data:text/plain,Stuff>.hostname = 'example.net' Cannot-be-a-base means no password -PASS <area>: Setting <data:text/plain,Stuff>.hostname = 'example.net' Cannot-be-a-base means no password +PASS URL: Setting <data:text/plain,Stuff>.hostname = 'example.net' Cannot-be-a-base means no host +PASS <a>: Setting <data:text/plain,Stuff>.hostname = 'example.net' Cannot-be-a-base means no host +PASS <area>: Setting <data:text/plain,Stuff>.hostname = 'example.net' Cannot-be-a-base means no host PASS URL: Setting <http://example.net:8080>.hostname = 'example.com' PASS <a>: Setting <http://example.net:8080>.hostname = 'example.com' PASS <area>: Setting <http://example.net:8080>.hostname = 'example.com'
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/css/css-color/parsing/opacity-computed-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/css/css-color/parsing/opacity-computed-expected.txt deleted file mode 100644 index 08c678f..0000000 --- a/third_party/blink/web_tests/platform/win7/external/wpt/css/css-color/parsing/opacity-computed-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -This is a testharness.js-based test. -PASS Property opacity value '1' computes to '1' -PASS Property opacity value '0.5' computes to '0.5' -PASS Property opacity value '0' computes to '0' -PASS Property opacity value '-2' computes to '0' -PASS Property opacity value '3' computes to '1' -FAIL Property opacity value '-100%' computes to '0' assert_equals: expected "0" but got "1" -FAIL Property opacity value '50%' computes to '0.5' assert_equals: expected "0.5" but got "1" -PASS Property opacity value '300%' computes to '1' -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/svg/animations/discard-on-discard-expected.txt b/third_party/blink/web_tests/svg/animations/discard-on-discard-expected.txt deleted file mode 100644 index 815ba51..0000000 --- a/third_party/blink/web_tests/svg/animations/discard-on-discard-expected.txt +++ /dev/null
@@ -1,28 +0,0 @@ -SVG 1.1 dynamic animation tests - -Test the behavior of one discard applied on another discard - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS colorComponents[1] is 255 -PASS colorComponents[2] is 0 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 255 -PASS colorComponents[2] is 0 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 0 -PASS colorComponents[2] is 255 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 0 -PASS colorComponents[2] is 255 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 0 -PASS colorComponents[2] is 255 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 0 -PASS colorComponents[2] is 255 -PASS colorComponents[3] is 0 -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/svg/animations/discard-on-discard.html b/third_party/blink/web_tests/svg/animations/discard-on-discard.html deleted file mode 100644 index 03395e15..0000000 --- a/third_party/blink/web_tests/svg/animations/discard-on-discard.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -<script src="resources/SVGTestCase.js"></script> -<script src="resources/SVGAnimationTestCase.js"></script> -</head> -<body onload="runSMILTest()"> -<h1>SVG 1.1 dynamic animation tests</h1> -<p id="description"></p> -<div id="console"></div> -<script src="script-tests/discard-on-discard.js"></script> -</body> -</html>
diff --git a/third_party/blink/web_tests/svg/animations/force-use-shadow-tree-recreation-while-animating-expected.txt b/third_party/blink/web_tests/svg/animations/force-use-shadow-tree-recreation-while-animating-expected.txt deleted file mode 100644 index 43197c33..0000000 --- a/third_party/blink/web_tests/svg/animations/force-use-shadow-tree-recreation-while-animating-expected.txt +++ /dev/null
@@ -1,20 +0,0 @@ -SVG 1.1 dynamic animation tests - -This test forces use shadow tree recreation while an animating is running - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS rect.width.animVal.value is 10 -PASS rect.width.baseVal.value is 10 -PASS rect.width.animVal.value is 55 -PASS rect.width.baseVal.value is 10 -PASS rect.width.animVal.value is 55 -PASS rect.width.baseVal.value is 10 -PASS rect.width.animVal.value is 100 -PASS rect.width.baseVal.value is 10 -PASS rect.width.animVal.value is 100 -PASS rect.width.baseVal.value is 10 -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/svg/animations/force-use-shadow-tree-recreation-while-animating.html b/third_party/blink/web_tests/svg/animations/force-use-shadow-tree-recreation-while-animating.html deleted file mode 100644 index b5d3d6b..0000000 --- a/third_party/blink/web_tests/svg/animations/force-use-shadow-tree-recreation-while-animating.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -<script src="resources/SVGTestCase.js"></script> -<script src="resources/SVGAnimationTestCase.js"></script> -</head> -<body onload="runSMILTest()"> -<h1>SVG 1.1 dynamic animation tests</h1> -<p id="description"></p> -<div id="console"></div> -<script src="script-tests/force-use-shadow-tree-recreation-while-animating.js"></script> -</body> -</html>
diff --git a/third_party/blink/web_tests/svg/animations/multiple-animations-ending-expected.txt b/third_party/blink/web_tests/svg/animations/multiple-animations-ending-expected.txt deleted file mode 100644 index db74ff2..0000000 --- a/third_party/blink/web_tests/svg/animations/multiple-animations-ending-expected.txt +++ /dev/null
@@ -1,194 +0,0 @@ -Test the effect of multiple animations ending. - -This checks the effect on multiple animations ending on one target - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS rect1.x.animVal.value is 0 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 100 -PASS rect2.x.baseVal.value is 200 -PASS rect3.x.animVal.value is 200 -PASS rect3.x.baseVal.value is 0 -PASS rect4.x.animVal.value is 10 -PASS rect4.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 50 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 80 -PASS rect2.x.baseVal.value is 200 -PASS rect3.x.animVal.value is 210 -PASS rect3.x.baseVal.value is 0 -PASS rect4.x.animVal.value is 30 -PASS rect4.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 50 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 80 -PASS rect2.x.baseVal.value is 200 -PASS rect3.x.animVal.value is 210 -PASS rect3.x.baseVal.value is 0 -PASS rect4.x.animVal.value is 30 -PASS rect4.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 50 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 80 -PASS rect2.x.baseVal.value is 200 -PASS rect3.x.animVal.value is 210 -PASS rect3.x.baseVal.value is 0 -PASS rect4.x.animVal.value is 30 -PASS rect4.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 100 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 60 -PASS rect2.x.baseVal.value is 200 -PASS rect3.x.animVal.value is 220 -PASS rect3.x.baseVal.value is 0 -PASS rect4.x.animVal.value is 30 -PASS rect4.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 0 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 0 -PASS rect2.x.baseVal.value is 200 -PASS rect3.x.animVal.value is 0 -PASS rect3.x.baseVal.value is 0 -PASS rect4.x.animVal.value is 60 -PASS rect4.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 0 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 0 -PASS rect2.x.baseVal.value is 200 -PASS rect3.x.animVal.value is 0 -PASS rect3.x.baseVal.value is 0 -PASS rect4.x.animVal.value is 60 -PASS rect4.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 0 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 5 -PASS rect2.x.baseVal.value is 200 -PASS rect3.x.animVal.value is 5 -PASS rect3.x.baseVal.value is 0 -PASS rect4.x.animVal.value is 80 -PASS rect4.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 200 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 5 -PASS rect2.x.baseVal.value is 200 -PASS rect3.x.animVal.value is 5 -PASS rect3.x.baseVal.value is 0 -PASS rect4.x.animVal.value is 80 -PASS rect4.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 200 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 5 -PASS rect2.x.baseVal.value is 200 -PASS rect3.x.animVal.value is 5 -PASS rect3.x.baseVal.value is 0 -PASS rect4.x.animVal.value is 80 -PASS rect4.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 225 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 10 -PASS rect2.x.baseVal.value is 200 -PASS rect3.x.animVal.value is 5 -PASS rect3.x.baseVal.value is 0 -PASS rect4.x.animVal.value is 80 -PASS rect4.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 225 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 20 -PASS rect2.x.baseVal.value is 200 -PASS rect3.x.animVal.value is 5 -PASS rect3.x.baseVal.value is 0 -PASS rect4.x.animVal.value is 110 -PASS rect4.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 225 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 20 -PASS rect2.x.baseVal.value is 200 -PASS rect3.x.animVal.value is 5 -PASS rect3.x.baseVal.value is 0 -PASS rect4.x.animVal.value is 110 -PASS rect4.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 250 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 0 -PASS rect2.x.baseVal.value is 200 -PASS rect3.x.animVal.value is 5 -PASS rect3.x.baseVal.value is 0 -PASS rect4.x.animVal.value is 130 -PASS rect4.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 50 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 200 -PASS rect2.x.baseVal.value is 200 -PASS rect3.x.animVal.value is 5 -PASS rect3.x.baseVal.value is 0 -PASS rect4.x.animVal.value is 130 -PASS rect4.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 50 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 200 -PASS rect2.x.baseVal.value is 200 -PASS rect3.x.animVal.value is 5 -PASS rect3.x.baseVal.value is 0 -PASS rect4.x.animVal.value is 130 -PASS rect4.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 0 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 200 -PASS rect2.x.baseVal.value is 200 -PASS rect3.x.animVal.value is 5 -PASS rect3.x.baseVal.value is 0 -PASS rect4.x.animVal.value is 130 -PASS rect4.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 250 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 200 -PASS rect2.x.baseVal.value is 200 -PASS rect3.x.animVal.value is 250 -PASS rect3.x.baseVal.value is 0 -PASS rect4.x.animVal.value is 160 -PASS rect4.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 250 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 200 -PASS rect2.x.baseVal.value is 200 -PASS rect3.x.animVal.value is 250 -PASS rect3.x.baseVal.value is 0 -PASS rect4.x.animVal.value is 160 -PASS rect4.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 250 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 200 -PASS rect2.x.baseVal.value is 200 -PASS rect3.x.animVal.value is 200 -PASS rect3.x.baseVal.value is 0 -PASS rect4.x.animVal.value is 180 -PASS rect4.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 250 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 200 -PASS rect2.x.baseVal.value is 200 -PASS rect3.x.animVal.value is 200 -PASS rect3.x.baseVal.value is 0 -PASS rect4.x.animVal.value is 180 -PASS rect4.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 250 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 200 -PASS rect2.x.baseVal.value is 200 -PASS rect3.x.animVal.value is 150 -PASS rect3.x.baseVal.value is 0 -PASS rect4.x.animVal.value is 180 -PASS rect4.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 250 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 200 -PASS rect2.x.baseVal.value is 200 -PASS rect3.x.animVal.value is 150 -PASS rect3.x.baseVal.value is 0 -PASS rect4.x.animVal.value is 180 -PASS rect4.x.baseVal.value is 0 -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/svg/animations/multiple-animations-ending.html b/third_party/blink/web_tests/svg/animations/multiple-animations-ending.html deleted file mode 100644 index 02b569a..0000000 --- a/third_party/blink/web_tests/svg/animations/multiple-animations-ending.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -<script src="resources/SVGTestCase.js"></script> -<script src="resources/SVGAnimationTestCase.js"></script> -</head> -<body onload="runSMILTest()"> -<h1>Test the effect of multiple animations ending.</h1> -<p id="description"></p> -<div id="console"></div> -<script src="script-tests/multiple-animations-ending.js"></script> -</body> -</html>
diff --git a/third_party/blink/web_tests/svg/animations/multiple-animations-fill-freeze-expected.txt b/third_party/blink/web_tests/svg/animations/multiple-animations-fill-freeze-expected.txt deleted file mode 100644 index dfbf6cfa..0000000 --- a/third_party/blink/web_tests/svg/animations/multiple-animations-fill-freeze-expected.txt +++ /dev/null
@@ -1,76 +0,0 @@ -SVG 1.1 dynamic animation tests - -This checks the effect on multiple animations on one target - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS rect1.x.animVal.value is 0 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 0 -PASS rect2.x.baseVal.value is 0 -PASS rect3.x.animVal.value is 0 -PASS rect3.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 50 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 50 -PASS rect2.x.baseVal.value is 0 -PASS rect3.x.animVal.value is 50 -PASS rect3.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 100 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 100 -PASS rect2.x.baseVal.value is 0 -PASS rect3.x.animVal.value is 100 -PASS rect3.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 100 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 0 -PASS rect2.x.baseVal.value is 0 -PASS rect3.x.animVal.value is 100 -PASS rect3.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 100 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 0 -PASS rect2.x.baseVal.value is 0 -PASS rect3.x.animVal.value is 100 -PASS rect3.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 100 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 0 -PASS rect2.x.baseVal.value is 0 -PASS rect3.x.animVal.value is 100 -PASS rect3.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 150 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 150 -PASS rect2.x.baseVal.value is 0 -PASS rect3.x.animVal.value is 150 -PASS rect3.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 200 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 200 -PASS rect2.x.baseVal.value is 0 -PASS rect3.x.animVal.value is 200 -PASS rect3.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 250 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 250 -PASS rect2.x.baseVal.value is 0 -PASS rect3.x.animVal.value is 250 -PASS rect3.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 250 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 250 -PASS rect2.x.baseVal.value is 0 -PASS rect3.x.animVal.value is 100 -PASS rect3.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 250 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 250 -PASS rect2.x.baseVal.value is 0 -PASS rect3.x.animVal.value is 100 -PASS rect3.x.baseVal.value is 0 -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/svg/animations/multiple-animations-fill-freeze.html b/third_party/blink/web_tests/svg/animations/multiple-animations-fill-freeze.html deleted file mode 100644 index 901ad6d..0000000 --- a/third_party/blink/web_tests/svg/animations/multiple-animations-fill-freeze.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -<script src="resources/SVGTestCase.js"></script> -<script src="resources/SVGAnimationTestCase.js"></script> -</head> -<body onload="runSMILTest()"> -<h1>SVG 1.1 dynamic animation tests</h1> -<p id="description"></p> -<div id="console"></div> -<script src="script-tests/multiple-animations-fill-freeze.js"></script> -</body> -</html>
diff --git a/third_party/blink/web_tests/svg/animations/multiple-begin-additive-animation-expected.txt b/third_party/blink/web_tests/svg/animations/multiple-begin-additive-animation-expected.txt deleted file mode 100644 index caf6c0a..0000000 --- a/third_party/blink/web_tests/svg/animations/multiple-begin-additive-animation-expected.txt +++ /dev/null
@@ -1,42 +0,0 @@ -SVG 1.1 dynamic animation tests - -This tests additive='sum' support on animate elements with multiple begin times - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS rect.x.animVal.value is 0 -PASS rect.y.animVal.value is 100 -PASS rect.x.animVal.value is 0 -PASS rect.y.animVal.value is 166.67 -PASS rect.x.animVal.value is 0 -PASS rect.y.animVal.value is 366.60 -PASS rect.x.animVal.value is 0 -PASS rect.y.animVal.value is 366.73 -PASS rect.x.animVal.value is 0 -PASS rect.y.animVal.value is 499.93 -PASS rect.x.animVal.value is 400 -PASS rect.y.animVal.value is 500.06 -PASS rect.x.animVal.value is 400 -PASS rect.y.animVal.value is 566.67 -PASS rect.x.animVal.value is 400 -PASS rect.y.animVal.value is 633.33 -PASS rect.x.animVal.value is 400 -PASS rect.y.animVal.value is 633.33 -PASS rect.x.animVal.value is 400 -PASS rect.y.animVal.value is 700 -PASS rect.x.animVal.value is 400 -PASS rect.y.animVal.value is 766.60 -PASS rect.x.animVal.value is 0 -PASS rect.y.animVal.value is 766.67 -PASS rect.x.animVal.value is 0 -PASS rect.y.animVal.value is 833.33 -PASS rect.x.animVal.value is 0 -PASS rect.y.animVal.value is 900 -PASS rect.x.animVal.value is 0 -PASS rect.y.animVal.value is 900 -PASS rect.x.animVal.value is 0 -PASS rect.y.animVal.value is 900 -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/svg/animations/multiple-begin-additive-animation.html b/third_party/blink/web_tests/svg/animations/multiple-begin-additive-animation.html deleted file mode 100644 index c27547c9..0000000 --- a/third_party/blink/web_tests/svg/animations/multiple-begin-additive-animation.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -<script src="resources/SVGTestCase.js"></script> -<script src="resources/SVGAnimationTestCase.js"></script> -</head> -<body onload="runSMILTest()"> -<h1>SVG 1.1 dynamic animation tests</h1> -<p id="description"></p> -<div id="console"></div> -<script src="script-tests/multiple-begin-additive-animation.js"></script> -</body> -</html>
diff --git a/third_party/blink/web_tests/svg/animations/non-additive-type-by-animation-expected.txt b/third_party/blink/web_tests/svg/animations/non-additive-type-by-animation-expected.txt deleted file mode 100644 index 6069e8e..0000000 --- a/third_party/blink/web_tests/svg/animations/non-additive-type-by-animation-expected.txt +++ /dev/null
@@ -1,60 +0,0 @@ -SVG 1.1 dynamic animation tests - -This by animation for all non-additive property types - should have no effect. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS feConvolveMatrix.preserveAlpha.animVal is false -PASS filter.filterUnits.animVal is SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX -PASS svg.preserveAspectRatio.animVal.align is SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE -PASS svg.preserveAspectRatio.animVal.meetOrSlice is SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET -PASS feConvolveMatrix.result.animVal is "" -PASS feConvolveMatrix.preserveAlpha.baseVal is false -PASS filter.filterUnits.baseVal is SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX -PASS svg.preserveAspectRatio.baseVal.align is SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE -PASS svg.preserveAspectRatio.baseVal.meetOrSlice is SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET -PASS feConvolveMatrix.result.baseVal is "" -PASS feConvolveMatrix.preserveAlpha.animVal is false -PASS filter.filterUnits.animVal is SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX -PASS svg.preserveAspectRatio.animVal.align is SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE -PASS svg.preserveAspectRatio.animVal.meetOrSlice is SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET -PASS feConvolveMatrix.result.animVal is "" -PASS feConvolveMatrix.preserveAlpha.baseVal is false -PASS filter.filterUnits.baseVal is SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX -PASS svg.preserveAspectRatio.baseVal.align is SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE -PASS svg.preserveAspectRatio.baseVal.meetOrSlice is SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET -PASS feConvolveMatrix.result.baseVal is "" -PASS feConvolveMatrix.preserveAlpha.animVal is false -PASS filter.filterUnits.animVal is SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX -PASS svg.preserveAspectRatio.animVal.align is SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE -PASS svg.preserveAspectRatio.animVal.meetOrSlice is SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET -PASS feConvolveMatrix.result.animVal is "" -PASS feConvolveMatrix.preserveAlpha.baseVal is false -PASS filter.filterUnits.baseVal is SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX -PASS svg.preserveAspectRatio.baseVal.align is SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE -PASS svg.preserveAspectRatio.baseVal.meetOrSlice is SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET -PASS feConvolveMatrix.result.baseVal is "" -PASS feConvolveMatrix.preserveAlpha.animVal is false -PASS filter.filterUnits.animVal is SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX -PASS svg.preserveAspectRatio.animVal.align is SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE -PASS svg.preserveAspectRatio.animVal.meetOrSlice is SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET -PASS feConvolveMatrix.result.animVal is "" -PASS feConvolveMatrix.preserveAlpha.baseVal is false -PASS filter.filterUnits.baseVal is SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX -PASS svg.preserveAspectRatio.baseVal.align is SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE -PASS svg.preserveAspectRatio.baseVal.meetOrSlice is SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET -PASS feConvolveMatrix.result.baseVal is "" -PASS feConvolveMatrix.preserveAlpha.animVal is false -PASS filter.filterUnits.animVal is SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX -PASS svg.preserveAspectRatio.animVal.align is SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE -PASS svg.preserveAspectRatio.animVal.meetOrSlice is SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET -PASS feConvolveMatrix.result.animVal is "" -PASS feConvolveMatrix.preserveAlpha.baseVal is false -PASS filter.filterUnits.baseVal is SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX -PASS svg.preserveAspectRatio.baseVal.align is SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE -PASS svg.preserveAspectRatio.baseVal.meetOrSlice is SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET -PASS feConvolveMatrix.result.baseVal is "" -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/svg/animations/non-additive-type-by-animation.html b/third_party/blink/web_tests/svg/animations/non-additive-type-by-animation.html deleted file mode 100644 index 75c1eea..0000000 --- a/third_party/blink/web_tests/svg/animations/non-additive-type-by-animation.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -<script src="resources/SVGTestCase.js"></script> -<script src="resources/SVGAnimationTestCase.js"></script> -</head> -<body onload="runSMILTest()"> -<h1>SVG 1.1 dynamic animation tests</h1> -<p id="description"></p> -<div id="console"></div> -<script src="script-tests/non-additive-type-by-animation.js"></script> -</body> -</html>
diff --git a/third_party/blink/web_tests/svg/animations/non-additive-type-from-by-animation-expected.txt b/third_party/blink/web_tests/svg/animations/non-additive-type-from-by-animation-expected.txt deleted file mode 100644 index 928be03..0000000 --- a/third_party/blink/web_tests/svg/animations/non-additive-type-from-by-animation-expected.txt +++ /dev/null
@@ -1,60 +0,0 @@ -SVG 1.1 dynamic animation tests - -This is a from by animation for all non-additive property types - should have no effect. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS feConvolveMatrix.preserveAlpha.animVal is false -PASS filter.filterUnits.animVal is SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX -PASS svg.preserveAspectRatio.animVal.align is SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE -PASS svg.preserveAspectRatio.animVal.meetOrSlice is SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET -PASS feConvolveMatrix.result.animVal is "" -PASS feConvolveMatrix.preserveAlpha.baseVal is false -PASS filter.filterUnits.baseVal is SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX -PASS svg.preserveAspectRatio.baseVal.align is SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE -PASS svg.preserveAspectRatio.baseVal.meetOrSlice is SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET -PASS feConvolveMatrix.result.baseVal is "" -PASS feConvolveMatrix.preserveAlpha.animVal is false -PASS filter.filterUnits.animVal is SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX -PASS svg.preserveAspectRatio.animVal.align is SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE -PASS svg.preserveAspectRatio.animVal.meetOrSlice is SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET -PASS feConvolveMatrix.result.animVal is "" -PASS feConvolveMatrix.preserveAlpha.baseVal is false -PASS filter.filterUnits.baseVal is SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX -PASS svg.preserveAspectRatio.baseVal.align is SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE -PASS svg.preserveAspectRatio.baseVal.meetOrSlice is SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET -PASS feConvolveMatrix.result.baseVal is "" -PASS feConvolveMatrix.preserveAlpha.animVal is false -PASS filter.filterUnits.animVal is SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX -PASS svg.preserveAspectRatio.animVal.align is SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE -PASS svg.preserveAspectRatio.animVal.meetOrSlice is SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET -PASS feConvolveMatrix.result.animVal is "" -PASS feConvolveMatrix.preserveAlpha.baseVal is false -PASS filter.filterUnits.baseVal is SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX -PASS svg.preserveAspectRatio.baseVal.align is SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE -PASS svg.preserveAspectRatio.baseVal.meetOrSlice is SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET -PASS feConvolveMatrix.result.baseVal is "" -PASS feConvolveMatrix.preserveAlpha.animVal is false -PASS filter.filterUnits.animVal is SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX -PASS svg.preserveAspectRatio.animVal.align is SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE -PASS svg.preserveAspectRatio.animVal.meetOrSlice is SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET -PASS feConvolveMatrix.result.animVal is "" -PASS feConvolveMatrix.preserveAlpha.baseVal is false -PASS filter.filterUnits.baseVal is SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX -PASS svg.preserveAspectRatio.baseVal.align is SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE -PASS svg.preserveAspectRatio.baseVal.meetOrSlice is SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET -PASS feConvolveMatrix.result.baseVal is "" -PASS feConvolveMatrix.preserveAlpha.animVal is false -PASS filter.filterUnits.animVal is SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX -PASS svg.preserveAspectRatio.animVal.align is SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE -PASS svg.preserveAspectRatio.animVal.meetOrSlice is SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET -PASS feConvolveMatrix.result.animVal is "" -PASS feConvolveMatrix.preserveAlpha.baseVal is false -PASS filter.filterUnits.baseVal is SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX -PASS svg.preserveAspectRatio.baseVal.align is SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE -PASS svg.preserveAspectRatio.baseVal.meetOrSlice is SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET -PASS feConvolveMatrix.result.baseVal is "" -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/svg/animations/non-additive-type-from-by-animation.html b/third_party/blink/web_tests/svg/animations/non-additive-type-from-by-animation.html deleted file mode 100644 index c96a6a6..0000000 --- a/third_party/blink/web_tests/svg/animations/non-additive-type-from-by-animation.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -<script src="resources/SVGTestCase.js"></script> -<script src="resources/SVGAnimationTestCase.js"></script> -</head> -<body onload="runSMILTest()"> -<h1>SVG 1.1 dynamic animation tests</h1> -<p id="description"></p> -<div id="console"></div> -<script src="script-tests/non-additive-type-from-by-animation.js"></script> -</body> -</html>
diff --git a/third_party/blink/web_tests/svg/animations/remove-animation-element-while-animation-is-running-expected.txt b/third_party/blink/web_tests/svg/animations/remove-animation-element-while-animation-is-running-expected.txt deleted file mode 100644 index 2994d27..0000000 --- a/third_party/blink/web_tests/svg/animations/remove-animation-element-while-animation-is-running-expected.txt +++ /dev/null
@@ -1,30 +0,0 @@ -SVG 1.1 dynamic animation tests - -This removes an animation element while the animation is running - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS rect1.x.animVal.value is 50 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 50 -PASS rect2.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 100 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 100 -PASS rect2.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 0 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 100 -PASS rect2.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 0 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 0 -PASS rect2.x.baseVal.value is 0 -PASS rect1.x.animVal.value is 0 -PASS rect1.x.baseVal.value is 0 -PASS rect2.x.animVal.value is 0 -PASS rect2.x.baseVal.value is 0 -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/svg/animations/remove-animation-element-while-animation-is-running.html b/third_party/blink/web_tests/svg/animations/remove-animation-element-while-animation-is-running.html deleted file mode 100644 index 770fc69d..0000000 --- a/third_party/blink/web_tests/svg/animations/remove-animation-element-while-animation-is-running.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -<script src="resources/SVGTestCase.js"></script> -<script src="resources/SVGAnimationTestCase.js"></script> -</head> -<body onload="runSMILTest()"> -<h1>SVG 1.1 dynamic animation tests</h1> -<p id="description"></p> -<div id="console"></div> -<script src="script-tests/remove-animation-element-while-animation-is-running.js"></script> -</body> -</html>
diff --git a/third_party/blink/web_tests/svg/animations/repeatn-remove-add-animation-expected.txt b/third_party/blink/web_tests/svg/animations/repeatn-remove-add-animation-expected.txt deleted file mode 100644 index befc6ee..0000000 --- a/third_party/blink/web_tests/svg/animations/repeatn-remove-add-animation-expected.txt +++ /dev/null
@@ -1,106 +0,0 @@ -SVG 1.1 dynamic animation tests - -This removes and adds an animation element while the animation is repeating - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS colorComponents[1] is 0 -PASS colorComponents[2] is 255 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 255 -PASS colorComponents[2] is 0 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 255 -PASS colorComponents[2] is 0 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 255 -PASS colorComponents[2] is 0 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 0 -PASS colorComponents[2] is 255 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 255 -PASS colorComponents[2] is 0 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 255 -PASS colorComponents[2] is 0 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 255 -PASS colorComponents[2] is 0 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 0 -PASS colorComponents[2] is 255 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 255 -PASS colorComponents[2] is 0 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 255 -PASS colorComponents[2] is 0 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 255 -PASS colorComponents[2] is 0 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 0 -PASS colorComponents[2] is 255 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 0 -PASS colorComponents[2] is 255 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 255 -PASS colorComponents[2] is 0 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 255 -PASS colorComponents[2] is 0 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 0 -PASS colorComponents[2] is 255 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 0 -PASS colorComponents[2] is 255 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 255 -PASS colorComponents[2] is 0 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 255 -PASS colorComponents[2] is 0 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 0 -PASS colorComponents[2] is 255 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 0 -PASS colorComponents[2] is 255 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 0 -PASS colorComponents[2] is 255 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 255 -PASS colorComponents[2] is 0 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 0 -PASS colorComponents[2] is 255 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 0 -PASS colorComponents[2] is 255 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 0 -PASS colorComponents[2] is 255 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 255 -PASS colorComponents[2] is 0 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 0 -PASS colorComponents[2] is 255 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 0 -PASS colorComponents[2] is 255 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 0 -PASS colorComponents[2] is 255 -PASS colorComponents[3] is 0 -PASS colorComponents[1] is 0 -PASS colorComponents[2] is 255 -PASS colorComponents[3] is 0 -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/svg/animations/repeatn-remove-add-animation.html b/third_party/blink/web_tests/svg/animations/repeatn-remove-add-animation.html deleted file mode 100644 index e234cf5f..0000000 --- a/third_party/blink/web_tests/svg/animations/repeatn-remove-add-animation.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -<script src="resources/SVGTestCase.js"></script> -<script src="resources/SVGAnimationTestCase.js"></script> -</head> -<body onload="runSMILTest()"> -<h1>SVG 1.1 dynamic animation tests</h1> -<p id="description"></p> -<div id="console"></div> -<script src="script-tests/repeatn-remove-add-animation.js"></script> -</body> -</html>
diff --git a/third_party/blink/web_tests/svg/animations/resources/discard-on-discard.svg b/third_party/blink/web_tests/svg/animations/resources/discard-on-discard.svg deleted file mode 100644 index caaf4ac..0000000 --- a/third_party/blink/web_tests/svg/animations/resources/discard-on-discard.svg +++ /dev/null
@@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> - <animate id="anim" attributeName="visibility" to="visible" begin="0s" end="5s"/> - <rect x="0" y="0" width="50" height="50" fill="rgb(255, 0, 0)"> - <set id="set1" attributeName="fill" to="rgb(0, 255, 0)" begin="2s" fill="freeze"/> - <set id="set2" attributeName="fill" to="rgb(0, 0, 255)" begin="3s" fill="freeze"/> - </rect> - - <discard id="discard1" xlink:href="#set1" begin="1s"/> - <discard id="discard2" xlink:href="#set2"/> - <discard id="discard3" xlink:href="#discard1"/> -</svg>
diff --git a/third_party/blink/web_tests/svg/animations/resources/force-use-shadow-tree-recreation-while-animating.svg b/third_party/blink/web_tests/svg/animations/resources/force-use-shadow-tree-recreation-while-animating.svg deleted file mode 100644 index 575889e..0000000 --- a/third_party/blink/web_tests/svg/animations/resources/force-use-shadow-tree-recreation-while-animating.svg +++ /dev/null
@@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd"> -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> - -<defs> - <rect id="rect" width="10" height="100" fill="red"> - <animate id="an1" attributeName="width" fill="freeze" from="10" to="100" begin="0s" dur="4s"/> - </rect> -</defs> - -<use xlink:href="#rect"/> - -</svg>
diff --git a/third_party/blink/web_tests/svg/animations/resources/multiple-animations-ending.svg b/third_party/blink/web_tests/svg/animations/resources/multiple-animations-ending.svg deleted file mode 100644 index ca57c2f..0000000 --- a/third_party/blink/web_tests/svg/animations/resources/multiple-animations-ending.svg +++ /dev/null
@@ -1,45 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd"> -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> - -<!-- Test that the first element can end while others continue without crashing, and the second - can end and remain frozen. Also test that a third element can animate after the second has ended - but that the result is still to return to the second animation's freeze position. --> -<rect x='0' y='0' width='50' height='50' fill='green'> - <animate id="an1" attributeName='x' from='0' to='100' begin='0s' dur='1s' /> - <animate id="an2" attributeName='x' from='200' to='250' begin='1.5s' dur='1s' fill='freeze' /> - <animate id="an3" attributeName='x' from='50' to='0' begin='2.5s' dur='0.5s' /> -</rect> - -<!-- Test that a second element can take priority over the first from 0-1s, then - test that the first element can animate for 1s, and finally test that the - second element can once again animate after the first has ended. After all - animations end, test that they are removed and the rect returns to its home. --> -<rect x='200' y='75' width='50' height='50' fill='green'> - <animate id="an4" attributeName='x' from='0' to='10' begin='1s' dur='1s'/> - <animate id="an5" attributeName='x' from='100' to='0' begin='0s' dur='2.5s'/> -</rect> - -<!-- Test that a repeating animation can take priority over another animation, and that the - end state is the second animation's freeze value. Also test that, after a pause, a third - animation can take over and have its freeze value satisfied at the end. --> -<rect x='0' y='150' width='50' height='50' fill='green'> - <animate id="an6" attributeName='x' from='200' to='240' begin='0s' dur='2s' fill='freeze'/> - <animate id="an7" attributeName='x' from='0' to='5' begin='1s' dur='0.1s' repeatCount="5" fill='freeze'/> - <animate id="an8" attributeName='x' from='250' to='150' begin='3s' dur='1s' fill='freeze'/> -</rect> - -<!-- Test that 4 animations can animate a rect in 20px 'steps' and that correct freeze values are - honored even though the animation elements are specified in non-sequential order. Also test - that two repeating animations (active for only a short duration) only momentarily - affect the overall animation and are correctly removed. --> -<rect x='0' y='225' width='50' height='50' fill='green'> - <animate id="an9" attributeName='x' from='200' to='250' begin='1.6s' dur='0.1s' repeatCount="2" fill='remove'/> - <animate id="anA" attributeName='x' from='160' to='180' begin='3s' dur='0.5s' fill='freeze'/> - <animate id="anB" attributeName='x' from='110' to='130' begin='2s' dur='0.5s' fill='freeze'/> - <animate id="anC" attributeName='x' from='10' to='30' begin='0s' dur='0.5s' fill='freeze'/> - <animate id="anD" attributeName='x' from='60' to='80' begin='1s' dur='0.5s' fill='freeze'/> - <animate id="anE" attributeName='x' from='200' to='250' begin='3.6s' dur='0.1s' repeatCount="2" fill='remove'/> -</rect> - -</svg>
diff --git a/third_party/blink/web_tests/svg/animations/resources/multiple-animations-fill-freeze.svg b/third_party/blink/web_tests/svg/animations/resources/multiple-animations-fill-freeze.svg deleted file mode 100644 index 11868bb..0000000 --- a/third_party/blink/web_tests/svg/animations/resources/multiple-animations-fill-freeze.svg +++ /dev/null
@@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd"> -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> - -<rect x='0' y='0' width='50' height='50' fill='green'> - <animate id="an1" attributeName='x' from='0' to='100' begin='0s' dur='2s' fill='freeze'/> - <animate id="an2" attributeName='x' from='150' to='250' begin='4s' dur='2s' fill='freeze'/> -</rect> - -<rect x='0' y='100' width='50' height='50' fill='green'> - <animate id="an3" attributeName='x' from='0' to='100' begin='0s' dur='2s' fill='remove'/> - <animate id="an4" attributeName='x' from='150' to='250' begin='4s' dur='2s' fill='freeze'/> -</rect> - -<rect x='0' y='200' width='50' height='50' fill='green'> - <animate id="an5" attributeName='x' from='0' to='100' begin='0s' dur='2s' fill='freeze'/> - <animate id="an6" attributeName='x' from='150' to='250' begin='4s' dur='2s' fill='remove'/> -</rect> - -</svg>
diff --git a/third_party/blink/web_tests/svg/animations/resources/multiple-begin-additive-animation.svg b/third_party/blink/web_tests/svg/animations/resources/multiple-begin-additive-animation.svg deleted file mode 100644 index 0a973e3..0000000 --- a/third_party/blink/web_tests/svg/animations/resources/multiple-begin-additive-animation.svg +++ /dev/null
@@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd"> -<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000"> -<rect width="100" height="100" fill="green"> - <animate id="an1" attributeName="y" attributeType="XML" begin="0s" dur="12s" from="100" to="900" fill="freeze" /> - <animate attributeName="x" attributeType="XML" calcMode="discrete" begin="0s; 2s" from="0" to="400" dur="8s" additive="sum" /> -</rect> -</svg>
diff --git a/third_party/blink/web_tests/svg/animations/resources/non-additive-type-by-animation.svg b/third_party/blink/web_tests/svg/animations/resources/non-additive-type-by-animation.svg deleted file mode 100644 index cf0a92b..0000000 --- a/third_party/blink/web_tests/svg/animations/resources/non-additive-type-by-animation.svg +++ /dev/null
@@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd"> -<svg id="svg" viewBox="0 0 200 200" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> -<defs> - <filter id="filter"> - <feConvolveMatrix id="feConvolveMatrix" kernelMatrix="0 1 0 0 1 0 0 1 0" order="6 6" targetX="5" preserveAlpha="false"/> - </filter> -</defs> - -<rect id="rect" y="100" width="100" height="100" fill="black" filter="url(#filter)"/> - -<!-- AnimatedBoolean --> -<animate id="an1" xlink:href="#feConvolveMatrix" attributeName="preserveAlpha" begin="0s" dur="4s" by="true" fill="freeze"/> - -<!-- AnimatedEnumeration --> -<animate xlink:href="#filter" attributeName="filterUnits" begin="0s" dur="4s" by="userSpaceOnUse" fill="freeze"/> - -<!-- AnimatedPreserveAspectRatio --> -<animate xlink:href="#svg" attributeName="preserveAspectRatio" begin="0s" dur="4s" by="xMaxYMax slice" fill="freeze"/> - -<!-- AnimatedString --> -<animate xlink:href="#feConvolveMatrix" attributeName="result" begin="0s" dur="4s" by="test" fill="freeze"/> - -</svg>
diff --git a/third_party/blink/web_tests/svg/animations/resources/non-additive-type-from-by-animation.svg b/third_party/blink/web_tests/svg/animations/resources/non-additive-type-from-by-animation.svg deleted file mode 100644 index ad2b00c5..0000000 --- a/third_party/blink/web_tests/svg/animations/resources/non-additive-type-from-by-animation.svg +++ /dev/null
@@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd"> -<svg id="svg" viewBox="0 0 200 200" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> -<defs> - <filter id="filter"> - <feConvolveMatrix id="feConvolveMatrix" kernelMatrix="0 1 0 0 1 0 0 1 0" order="6 6" targetX="5" preserveAlpha="false"/> - </filter> -</defs> - -<rect id="rect" y="100" width="100" height="100" fill="black" filter="url(#filter)"/> - -<!-- AnimatedBoolean --> -<animate id="an1" xlink:href="#feConvolveMatrix" attributeName="preserveAlpha" begin="0s" dur="4s" from="false" by="true" fill="freeze"/> - -<!-- AnimatedEnumeration --> -<animate xlink:href="#filter" attributeName="filterUnits" begin="0s" dur="4s" from="objectBoundingBox" by="userSpaceOnUse" fill="freeze"/> - -<!-- AnimatedPreserveAspectRatio --> -<animate xlink:href="#svg" attributeName="preserveAspectRatio" begin="0s" dur="4s" from="xMaxYMax meet" by="xMaxYMax slice" fill="freeze"/> - -<!-- AnimatedString --> -<animate xlink:href="#feConvolveMatrix" attributeName="result" begin="0s" dur="4s" from="foo" by="test" fill="freeze"/> - -</svg>
diff --git a/third_party/blink/web_tests/svg/animations/resources/remove-animation-element-while-animation-is-running.svg b/third_party/blink/web_tests/svg/animations/resources/remove-animation-element-while-animation-is-running.svg deleted file mode 100644 index 92c781209..0000000 --- a/third_party/blink/web_tests/svg/animations/resources/remove-animation-element-while-animation-is-running.svg +++ /dev/null
@@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd"> -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> - -<rect x='0' y='0' width='50' height='50' fill='green'> - <animate id="an1" attributeName='x' from='50' to='150' begin='0s' dur='2s' fill='freeze'/> -</rect> - -<rect x='0' y='100' width='50' height='50' fill='green'> - <animate id="an2" attributeName='x' from='50' to='150' begin='0s' dur='2s' fill='remove'/> -</rect> - -</svg>
diff --git a/third_party/blink/web_tests/svg/animations/resources/repeatn-remove-add-animation.svg b/third_party/blink/web_tests/svg/animations/resources/repeatn-remove-add-animation.svg deleted file mode 100644 index 5d1d74e..0000000 --- a/third_party/blink/web_tests/svg/animations/resources/repeatn-remove-add-animation.svg +++ /dev/null
@@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd"> -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> - - <animate id="anim" attributeName="visibility" to="visible" begin="0s" dur="2s" repeatCount="4"/> - <rect x="0" y="0" width="100" height="100" fill="rgb(0, 255, 0)"> - <set attributeName="fill" to="rgb(255, 0, 0)" begin="anim.repeat(0)"/> - </rect> - <rect x="200" y="0" width="100" height="100" fill="rgb(255, 0, 0)"> - <set attributeName="fill" to="rgb(0, 255, 0)" begin="anim.repeat(1)"/> - </rect> - <rect x="0" y="200" width="100" height="100" fill="rgb(255, 0, 0)"> - <set attributeName="fill" to="rgb(0, 255, 0)" begin="anim.repeat(2)"/> - </rect> - <rect x="200" y="200" width="100" height="100" fill="rgb(255, 0, 0)"> - <set attributeName="fill" to="rgb(0, 255, 0)" begin="anim.repeat(3)"/> - </rect> - -</svg>
diff --git a/third_party/blink/web_tests/svg/animations/resources/single-values-animation.svg b/third_party/blink/web_tests/svg/animations/resources/single-values-animation.svg deleted file mode 100644 index 3c35e73..0000000 --- a/third_party/blink/web_tests/svg/animations/resources/single-values-animation.svg +++ /dev/null
@@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd"> -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> - -<!-- an1: Change width immediately to 100 at 2s --> -<rect width="10" height="100" fill="green"> - <animate id="an1" attributeType="XML" attributeName="width" fill="freeze" values="100" begin="2s"/> -</rect> - -</svg>
diff --git a/third_party/blink/web_tests/svg/animations/script-tests/discard-on-discard.js b/third_party/blink/web_tests/svg/animations/script-tests/discard-on-discard.js deleted file mode 100644 index c2cd17e..0000000 --- a/third_party/blink/web_tests/svg/animations/script-tests/discard-on-discard.js +++ /dev/null
@@ -1,31 +0,0 @@ -description("Test the behavior of one discard applied on another discard"); -embedSVGTestCase("resources/discard-on-discard.svg"); - -// Setup animation test -function sample1() { - expectFillColor(rect1, 255, 0, 0); -} - -function sample2() { - expectFillColor(rect1, 0, 255, 0); -} - -function executeTest() { - var rects = rootSVGElement.ownerDocument.getElementsByTagName("rect"); - rect1 = rects[0]; - - const expectedValues = [ - // [animationId, time, sampleCallback] - ["anim", 0.0, sample1], - ["anim", 0.01, sample1], - ["anim", 2.0, sample2], - ["anim", 2.01, sample2], - ["anim", 3.0, sample2], - ["anim", 3.01, sample2] - ]; - - runAnimationTest(expectedValues); -} - -window.animationStartsImmediately = true; -var successfullyParsed = true;
diff --git a/third_party/blink/web_tests/svg/animations/script-tests/force-use-shadow-tree-recreation-while-animating.js b/third_party/blink/web_tests/svg/animations/script-tests/force-use-shadow-tree-recreation-while-animating.js deleted file mode 100644 index 7c00455..0000000 --- a/third_party/blink/web_tests/svg/animations/script-tests/force-use-shadow-tree-recreation-while-animating.js +++ /dev/null
@@ -1,41 +0,0 @@ -description("This test forces use shadow tree recreation while an animating is running"); -embedSVGTestCase("resources/force-use-shadow-tree-recreation-while-animating.svg"); - -// Setup animation test -function sample1() { - shouldBeCloseEnough("rect.width.animVal.value", "10"); - shouldBe("rect.width.baseVal.value", "10"); -} - -function sample2() { - shouldBeCloseEnough("rect.width.animVal.value", "55"); - shouldBe("rect.width.baseVal.value", "10"); -} - -function forceUseShadowTreeRecreation() { - rect.setAttribute("fill", "green"); -} - -function sample3() { - shouldBeCloseEnough("rect.width.animVal.value", "100"); - shouldBe("rect.width.baseVal.value", "10"); -} - -function executeTest() { - rect = rootSVGElement.ownerDocument.getElementsByTagName("rect")[0]; - - const expectedValues = [ - // [animationId, time, sampleCallback] - ["an1", 0.0, sample1], - ["an1", 1.999, sample2], - ["an1", 2.0, forceUseShadowTreeRecreation], - ["an1", 2.001, sample2], - ["an1", 4.0, sample3], - ["an1", 60.0, sample3], - ]; - - runAnimationTest(expectedValues); -} - -window.animationStartsImmediately = true; -var successfullyParsed = true;
diff --git a/third_party/blink/web_tests/svg/animations/script-tests/multiple-animations-ending.js b/third_party/blink/web_tests/svg/animations/script-tests/multiple-animations-ending.js deleted file mode 100644 index d143126..0000000 --- a/third_party/blink/web_tests/svg/animations/script-tests/multiple-animations-ending.js +++ /dev/null
@@ -1,365 +0,0 @@ -description("This checks the effect on multiple animations ending on one target"); -embedSVGTestCase("resources/multiple-animations-ending.svg"); - -// Setup animation test -function sample1() { - shouldBeCloseEnough("rect1.x.animVal.value", "0"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "100"); - shouldBe("rect2.x.baseVal.value", "200"); - - shouldBeCloseEnough("rect3.x.animVal.value", "200"); - shouldBe("rect3.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect4.x.animVal.value", "10"); - shouldBe("rect4.x.baseVal.value", "0"); -} - -function sample2() { - shouldBeCloseEnough("rect1.x.animVal.value", "50"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "80"); - shouldBe("rect2.x.baseVal.value", "200"); - - shouldBeCloseEnough("rect3.x.animVal.value", "210"); - shouldBe("rect3.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect4.x.animVal.value", "30"); - shouldBe("rect4.x.baseVal.value", "0"); -} - -function sample3() { - shouldBeCloseEnough("rect1.x.animVal.value", "50"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "80"); - shouldBe("rect2.x.baseVal.value", "200"); - - shouldBeCloseEnough("rect3.x.animVal.value", "210"); - shouldBe("rect3.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect4.x.animVal.value", "30"); - shouldBe("rect4.x.baseVal.value", "0"); -} - -function sample4() { - shouldBeCloseEnough("rect1.x.animVal.value", "50"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "80"); - shouldBe("rect2.x.baseVal.value", "200"); - - shouldBeCloseEnough("rect3.x.animVal.value", "210"); - shouldBe("rect3.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect4.x.animVal.value", "30"); - shouldBe("rect4.x.baseVal.value", "0"); -} - -function sample5() { - shouldBeCloseEnough("rect1.x.animVal.value", "100"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "60"); - shouldBe("rect2.x.baseVal.value", "200"); - - shouldBeCloseEnough("rect3.x.animVal.value", "220"); - shouldBe("rect3.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect4.x.animVal.value", "30"); - shouldBe("rect4.x.baseVal.value", "0"); -} - -function sample6() { - shouldBeCloseEnough("rect1.x.animVal.value", "0"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "0"); - shouldBe("rect2.x.baseVal.value", "200"); - - shouldBeCloseEnough("rect3.x.animVal.value", "0"); - shouldBe("rect3.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect4.x.animVal.value", "60"); - shouldBe("rect4.x.baseVal.value", "0"); -} - -function sample7() { - shouldBeCloseEnough("rect1.x.animVal.value", "0"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "0"); - shouldBe("rect2.x.baseVal.value", "200"); - - shouldBeCloseEnough("rect3.x.animVal.value", "0"); - shouldBe("rect3.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect4.x.animVal.value", "60"); - shouldBe("rect4.x.baseVal.value", "0"); -} - -function sample8() { - shouldBeCloseEnough("rect1.x.animVal.value", "0"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "5"); - shouldBe("rect2.x.baseVal.value", "200"); - - shouldBeCloseEnough("rect3.x.animVal.value", "5"); - shouldBe("rect3.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect4.x.animVal.value", "80"); - shouldBe("rect4.x.baseVal.value", "0"); -} - -function sample9() { - shouldBeCloseEnough("rect1.x.animVal.value", "200"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "5"); - shouldBe("rect2.x.baseVal.value", "200"); - - shouldBeCloseEnough("rect3.x.animVal.value", "5"); - shouldBe("rect3.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect4.x.animVal.value", "80"); - shouldBe("rect4.x.baseVal.value", "0"); -} - -function sample10() { - shouldBeCloseEnough("rect1.x.animVal.value", "200"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "5"); - shouldBe("rect2.x.baseVal.value", "200"); - - shouldBeCloseEnough("rect3.x.animVal.value", "5"); - shouldBe("rect3.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect4.x.animVal.value", "80"); - shouldBe("rect4.x.baseVal.value", "0"); -} - -function sample11() { - shouldBeCloseEnough("rect1.x.animVal.value", "225"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "10"); - shouldBe("rect2.x.baseVal.value", "200"); - - shouldBeCloseEnough("rect3.x.animVal.value", "5"); - shouldBe("rect3.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect4.x.animVal.value", "80"); - shouldBe("rect4.x.baseVal.value", "0"); -} - -function sample12() { - shouldBeCloseEnough("rect1.x.animVal.value", "225"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "20"); - shouldBe("rect2.x.baseVal.value", "200"); - - shouldBeCloseEnough("rect3.x.animVal.value", "5"); - shouldBe("rect3.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect4.x.animVal.value", "110"); - shouldBe("rect4.x.baseVal.value", "0"); -} - -function sample13() { - shouldBeCloseEnough("rect1.x.animVal.value", "225"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "20"); - shouldBe("rect2.x.baseVal.value", "200"); - - shouldBeCloseEnough("rect3.x.animVal.value", "5"); - shouldBe("rect3.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect4.x.animVal.value", "110"); - shouldBe("rect4.x.baseVal.value", "0"); -} - -function sample14() { - shouldBeCloseEnough("rect1.x.animVal.value", "250"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "0"); - shouldBe("rect2.x.baseVal.value", "200"); - - shouldBeCloseEnough("rect3.x.animVal.value", "5"); - shouldBe("rect3.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect4.x.animVal.value", "130"); - shouldBe("rect4.x.baseVal.value", "0"); -} - -function sample15() { - shouldBeCloseEnough("rect1.x.animVal.value", "50"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "200"); - shouldBe("rect2.x.baseVal.value", "200"); - - shouldBeCloseEnough("rect3.x.animVal.value", "5"); - shouldBe("rect3.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect4.x.animVal.value", "130"); - shouldBe("rect4.x.baseVal.value", "0"); -} - -function sample16() { - shouldBeCloseEnough("rect1.x.animVal.value", "50"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "200"); - shouldBe("rect2.x.baseVal.value", "200"); - - shouldBeCloseEnough("rect3.x.animVal.value", "5"); - shouldBe("rect3.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect4.x.animVal.value", "130"); - shouldBe("rect4.x.baseVal.value", "0"); -} - -function sample17() { - shouldBeCloseEnough("rect1.x.animVal.value", "0"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "200"); - shouldBe("rect2.x.baseVal.value", "200"); - - shouldBeCloseEnough("rect3.x.animVal.value", "5"); - shouldBe("rect3.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect4.x.animVal.value", "130"); - shouldBe("rect4.x.baseVal.value", "0"); -} - -function sample18() { - shouldBeCloseEnough("rect1.x.animVal.value", "250"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "200"); - shouldBe("rect2.x.baseVal.value", "200"); - - shouldBeCloseEnough("rect3.x.animVal.value", "250"); - shouldBe("rect3.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect4.x.animVal.value", "160"); - shouldBe("rect4.x.baseVal.value", "0"); -} - -function sample19() { - shouldBeCloseEnough("rect1.x.animVal.value", "250"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "200"); - shouldBe("rect2.x.baseVal.value", "200"); - - shouldBeCloseEnough("rect3.x.animVal.value", "250"); - shouldBe("rect3.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect4.x.animVal.value", "160"); - shouldBe("rect4.x.baseVal.value", "0"); -} - -function sample20() { - shouldBeCloseEnough("rect1.x.animVal.value", "250"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "200"); - shouldBe("rect2.x.baseVal.value", "200"); - - shouldBeCloseEnough("rect3.x.animVal.value", "200"); - shouldBe("rect3.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect4.x.animVal.value", "180"); - shouldBe("rect4.x.baseVal.value", "0"); -} - -function sample21() { - shouldBeCloseEnough("rect1.x.animVal.value", "250"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "200"); - shouldBe("rect2.x.baseVal.value", "200"); - - shouldBeCloseEnough("rect3.x.animVal.value", "200"); - shouldBe("rect3.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect4.x.animVal.value", "180"); - shouldBe("rect4.x.baseVal.value", "0"); -} - -function sample22() { - shouldBeCloseEnough("rect1.x.animVal.value", "250"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "200"); - shouldBe("rect2.x.baseVal.value", "200"); - - shouldBeCloseEnough("rect3.x.animVal.value", "150"); - shouldBe("rect3.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect4.x.animVal.value", "180"); - shouldBe("rect4.x.baseVal.value", "0"); -} - -function sample23() { - shouldBeCloseEnough("rect1.x.animVal.value", "250"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "200"); - shouldBe("rect2.x.baseVal.value", "200"); - - shouldBeCloseEnough("rect3.x.animVal.value", "150"); - shouldBe("rect3.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect4.x.animVal.value", "180"); - shouldBe("rect4.x.baseVal.value", "0"); -} - -function executeTest() { - var rects = rootSVGElement.ownerDocument.getElementsByTagName("rect"); - rect1 = rects[0]; - rect2 = rects[1]; - rect3 = rects[2]; - rect4 = rects[3]; - - const expectedValues = [ - // [animationId, time, sampleCallback] - ["an1", 0.0, sample1], - ["an1", 0.499, sample2], - ["an1", 0.5, sample3], - ["an1", 0.501, sample4], - ["an1", 0.999, sample5], - ["an1", 1.0, sample6], - ["an1", 1.001, sample7], - ["an1", 1.499, sample8], - ["an1", 1.5, sample9], - ["an1", 1.501, sample10], - ["an1", 1.999, sample11], - ["an1", 2.0, sample12], - ["an1", 2.001, sample13], - ["an1", 2.499, sample14], - ["an1", 2.5, sample15], - ["an1", 2.501, sample16], - ["an1", 2.999, sample17], - ["an1", 3.0, sample18], - ["an1", 3.001, sample19], - ["an1", 3.499, sample20], - ["an1", 3.5, sample21], - ["an1", 4.0, sample22], - ["an1", 9.0, sample23] - ]; - - runAnimationTest(expectedValues); -} - -window.animationStartsImmediately = true; -var successfullyParsed = true;
diff --git a/third_party/blink/web_tests/svg/animations/script-tests/multiple-animations-fill-freeze.js b/third_party/blink/web_tests/svg/animations/script-tests/multiple-animations-fill-freeze.js deleted file mode 100644 index 1681145..0000000 --- a/third_party/blink/web_tests/svg/animations/script-tests/multiple-animations-fill-freeze.js +++ /dev/null
@@ -1,118 +0,0 @@ -description("This checks the effect on multiple animations on one target"); -embedSVGTestCase("resources/multiple-animations-fill-freeze.svg"); - -// Setup animation test -function sample1() { - shouldBeCloseEnough("rect1.x.animVal.value", "0"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "0"); - shouldBe("rect2.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect3.x.animVal.value", "0"); - shouldBe("rect3.x.baseVal.value", "0"); -} - -function sample2() { - shouldBeCloseEnough("rect1.x.animVal.value", "50"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "50"); - shouldBe("rect2.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect3.x.animVal.value", "50"); - shouldBe("rect3.x.baseVal.value", "0"); -} - -function sample3() { - shouldBeCloseEnough("rect1.x.animVal.value", "100"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "100"); - shouldBe("rect2.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect3.x.animVal.value", "100"); - shouldBe("rect3.x.baseVal.value", "0"); -} - -function sample4() { - shouldBeCloseEnough("rect1.x.animVal.value", "100"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "0"); - shouldBe("rect2.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect3.x.animVal.value", "100"); - shouldBe("rect3.x.baseVal.value", "0"); -} - -function sample5() { - shouldBeCloseEnough("rect1.x.animVal.value", "150"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "150"); - shouldBe("rect2.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect3.x.animVal.value", "150"); - shouldBe("rect3.x.baseVal.value", "0"); -} - -function sample6() { - shouldBeCloseEnough("rect1.x.animVal.value", "200"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "200"); - shouldBe("rect2.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect3.x.animVal.value", "200"); - shouldBe("rect3.x.baseVal.value", "0"); -} - -function sample7() { - shouldBeCloseEnough("rect1.x.animVal.value", "250"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "250"); - shouldBe("rect2.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect3.x.animVal.value", "250"); - shouldBe("rect3.x.baseVal.value", "0"); -} - -function sample8() { - shouldBe("rect1.x.animVal.value", "250"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBe("rect2.x.animVal.value", "250"); - shouldBe("rect2.x.baseVal.value", "0"); - - shouldBe("rect3.x.animVal.value", "100"); - shouldBe("rect3.x.baseVal.value", "0"); -} - -function executeTest() { - var rects = rootSVGElement.ownerDocument.getElementsByTagName("rect"); - rect1 = rects[0]; - rect2 = rects[1]; - rect3 = rects[2]; - - const expectedValues = [ - // [animationId, time, sampleCallback] - ["an1", 0.0, sample1], - ["an1", 1.0, sample2], - ["an1", 1.999, sample3], - ["an1", 2.001, sample4], - ["an1", 3.0, sample4], - ["an1", 3.999, sample4], - ["an1", 4.0, sample5], - ["an1", 5.0, sample6], - ["an1", 5.999, sample7], - ["an1", 6.001, sample8], - ["an1", 60.0, sample8] - ]; - - runAnimationTest(expectedValues); -} - -window.animationStartsImmediately = true; -var successfullyParsed = true;
diff --git a/third_party/blink/web_tests/svg/animations/script-tests/multiple-begin-additive-animation.js b/third_party/blink/web_tests/svg/animations/script-tests/multiple-begin-additive-animation.js deleted file mode 100644 index a24cd68..0000000 --- a/third_party/blink/web_tests/svg/animations/script-tests/multiple-begin-additive-animation.js +++ /dev/null
@@ -1,117 +0,0 @@ -description("This tests additive='sum' support on animate elements with multiple begin times"); -embedSVGTestCase("resources/multiple-begin-additive-animation.svg"); - -// Setup animation test -function checkBaseValues() { -return; - shouldBe("rect.x.baseVal.value", "0"); - shouldBe("rect.y.baseVal.value", "0"); -} - -function sample1() { - shouldBe("rect.x.animVal.value", "0"); - shouldBeCloseEnough("rect.y.animVal.value", "100"); - checkBaseValues(); -} - -function sample2() { - shouldBe("rect.x.animVal.value", "0"); - shouldBeCloseEnough("rect.y.animVal.value", "166.67"); - checkBaseValues(); -} - -function sample3() { - shouldBe("rect.x.animVal.value", "0"); - shouldBeCloseEnough("rect.y.animVal.value", "366.60"); - checkBaseValues(); -} - -function sample4() { - shouldBe("rect.x.animVal.value", "0"); - shouldBeCloseEnough("rect.y.animVal.value", "366.73"); - checkBaseValues(); -} - -function sample5() { - shouldBe("rect.x.animVal.value", "0"); - shouldBeCloseEnough("rect.y.animVal.value", "499.93"); - checkBaseValues(); -} - -function sample6() { - shouldBe("rect.x.animVal.value", "400"); - shouldBeCloseEnough("rect.y.animVal.value", "500.06"); - checkBaseValues(); -} - -function sample7() { - shouldBe("rect.x.animVal.value", "400"); - shouldBeCloseEnough("rect.y.animVal.value", "566.67"); - checkBaseValues(); -} - -function sample8() { - shouldBe("rect.x.animVal.value", "400"); - shouldBeCloseEnough("rect.y.animVal.value", "633.33"); - checkBaseValues(); -} - -function sample9() { - shouldBe("rect.x.animVal.value", "400"); - shouldBeCloseEnough("rect.y.animVal.value", "700"); - checkBaseValues(); -} - -function sample10() { - shouldBe("rect.x.animVal.value", "400"); - shouldBeCloseEnough("rect.y.animVal.value", "766.60"); - checkBaseValues(); -} - -function sample11() { - shouldBe("rect.x.animVal.value", "0"); - shouldBeCloseEnough("rect.y.animVal.value", "766.67"); - checkBaseValues(); -} - -function sample12() { - shouldBe("rect.x.animVal.value", "0"); - shouldBeCloseEnough("rect.y.animVal.value", "833.33"); - checkBaseValues(); -} - -function sample13() { - shouldBe("rect.x.animVal.value", "0"); - shouldBeCloseEnough("rect.y.animVal.value", "900"); - checkBaseValues(); -} - -function executeTest() { - rect = rootSVGElement.ownerDocument.getElementsByTagName("rect")[0]; - - // All animations in the test file use the same duration, so it's not needed to list all sample points individually for an5/an6/an7/an8. - const expectedValues = [ - // [animationId, time, sampleCallback] - ["an1", 0.0, sample1], - ["an1", 1.0, sample2], - ["an1", 3.999, sample3], - ["an1", 4.001, sample4], - ["an1", 5.999, sample5], - ["an1", 6.001, sample6], - ["an1", 7.0, sample7], - ["an1", 7.999, sample8], - ["an1", 8.001, sample8], - ["an1", 9.0, sample9], - ["an1", 9.999, sample10], - ["an1", 10.001, sample11], - ["an1", 11.0, sample12], - ["an1", 11.999, sample13], - ["an1", 12.001, sample13], - ["an1", 60.0, sample13] - ]; - - runAnimationTest(expectedValues); -} - -window.animationStartsImmediately = true; -var successfullyParsed = true;
diff --git a/third_party/blink/web_tests/svg/animations/script-tests/non-additive-type-by-animation.js b/third_party/blink/web_tests/svg/animations/script-tests/non-additive-type-by-animation.js deleted file mode 100644 index e845cfff..0000000 --- a/third_party/blink/web_tests/svg/animations/script-tests/non-additive-type-by-animation.js +++ /dev/null
@@ -1,37 +0,0 @@ -description("This by animation for all non-additive property types - should have no effect."); -embedSVGTestCase("resources/non-additive-type-by-animation.svg"); - -// Setup animation test -function sample() { - shouldBe("feConvolveMatrix.preserveAlpha.animVal", "false"); - shouldBe("filter.filterUnits.animVal", "SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX"); - shouldBe("svg.preserveAspectRatio.animVal.align", "SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE"); - shouldBe("svg.preserveAspectRatio.animVal.meetOrSlice", "SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET"); - shouldBeEqualToString("feConvolveMatrix.result.animVal", ""); - - shouldBe("feConvolveMatrix.preserveAlpha.baseVal", "false"); - shouldBe("filter.filterUnits.baseVal", "SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX"); - shouldBe("svg.preserveAspectRatio.baseVal.align", "SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE"); - shouldBe("svg.preserveAspectRatio.baseVal.meetOrSlice", "SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET"); - shouldBeEqualToString("feConvolveMatrix.result.baseVal", ""); -} - -function executeTest() { - filter = rootSVGElement.ownerDocument.getElementsByTagName("filter")[0]; - feConvolveMatrix = rootSVGElement.ownerDocument.getElementsByTagName("feConvolveMatrix")[0]; - svg = rootSVGElement.ownerDocument.getElementsByTagName("svg")[0]; - - const expectedValues = [ - // [animationId, time, sampleCallback] - ["an1", 0.0, sample], - ["an1", 1.999, sample], - ["an1", 2.001, sample], - ["an1", 3.999, sample], - ["an1", 4.001, sample] - ]; - - runAnimationTest(expectedValues); -} - -window.animationStartsImmediately = true; -var successfullyParsed = true;
diff --git a/third_party/blink/web_tests/svg/animations/script-tests/non-additive-type-from-by-animation.js b/third_party/blink/web_tests/svg/animations/script-tests/non-additive-type-from-by-animation.js deleted file mode 100644 index fa3b9f76..0000000 --- a/third_party/blink/web_tests/svg/animations/script-tests/non-additive-type-from-by-animation.js +++ /dev/null
@@ -1,37 +0,0 @@ -description("This is a from by animation for all non-additive property types - should have no effect."); -embedSVGTestCase("resources/non-additive-type-from-by-animation.svg"); - -// Setup animation test -function sample() { - shouldBe("feConvolveMatrix.preserveAlpha.animVal", "false"); - shouldBe("filter.filterUnits.animVal", "SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX"); - shouldBe("svg.preserveAspectRatio.animVal.align", "SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE"); - shouldBe("svg.preserveAspectRatio.animVal.meetOrSlice", "SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET"); - shouldBeEqualToString("feConvolveMatrix.result.animVal", ""); - - shouldBe("feConvolveMatrix.preserveAlpha.baseVal", "false"); - shouldBe("filter.filterUnits.baseVal", "SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX"); - shouldBe("svg.preserveAspectRatio.baseVal.align", "SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE"); - shouldBe("svg.preserveAspectRatio.baseVal.meetOrSlice", "SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET"); - shouldBeEqualToString("feConvolveMatrix.result.baseVal", ""); -} - -function executeTest() { - filter = rootSVGElement.ownerDocument.getElementsByTagName("filter")[0]; - feConvolveMatrix = rootSVGElement.ownerDocument.getElementsByTagName("feConvolveMatrix")[0]; - svg = rootSVGElement.ownerDocument.getElementsByTagName("svg")[0]; - - const expectedValues = [ - // [animationId, time, sampleCallback] - ["an1", 0.0, sample], - ["an1", 1.999, sample], - ["an1", 2.001, sample], - ["an1", 3.999, sample], - ["an1", 4.001, sample] - ]; - - runAnimationTest(expectedValues); -} - -window.animationStartsImmediately = true; -var successfullyParsed = true;
diff --git a/third_party/blink/web_tests/svg/animations/script-tests/remove-animation-element-while-animation-is-running.js b/third_party/blink/web_tests/svg/animations/script-tests/remove-animation-element-while-animation-is-running.js deleted file mode 100644 index 9f745d93..0000000 --- a/third_party/blink/web_tests/svg/animations/script-tests/remove-animation-element-while-animation-is-running.js +++ /dev/null
@@ -1,61 +0,0 @@ -description("This removes an animation element while the animation is running"); -embedSVGTestCase("resources/remove-animation-element-while-animation-is-running.svg"); - -// Setup animation test -function sample1() { - shouldBeCloseEnough("rect1.x.animVal.value", "50"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "50"); - shouldBe("rect2.x.baseVal.value", "0"); -} - -function sample2() { - shouldBeCloseEnough("rect1.x.animVal.value", "100"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "100"); - shouldBe("rect2.x.baseVal.value", "0"); - - // Remove the animation element animating rect1 - // The effect is that rect1 is now reset to the initial state, before any animation was applied to it. - // Compatible with FF. In Opera it shows a repainting bug currently (two rects are visible!). - var an1 = rootSVGElement.ownerDocument.getElementById("an1"); - an1.parentNode.removeChild(an1); -} - -function sample3() { - shouldBe("rect1.x.animVal.value", "0"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBeCloseEnough("rect2.x.animVal.value", "100"); - shouldBe("rect2.x.baseVal.value", "0"); -} - -function sample4() { - shouldBe("rect1.x.animVal.value", "0"); - shouldBe("rect1.x.baseVal.value", "0"); - - shouldBe("rect2.x.animVal.value", "0"); - shouldBe("rect2.x.baseVal.value", "0"); -} - -function executeTest() { - var rects = rootSVGElement.ownerDocument.getElementsByTagName("rect"); - rect1 = rects[0]; - rect2 = rects[1]; - - const expectedValues = [ - // [animationId, time, sampleCallback] - ["an1", 0.0, sample1], - ["an1", 1.0, sample2], - ["an2", 1.001, sample3], - ["an2", 2.001, sample4], - ["an2", 60.0, sample4] - ]; - - runAnimationTest(expectedValues); -} - -window.animationStartsImmediately = true; -var successfullyParsed = true;
diff --git a/third_party/blink/web_tests/svg/animations/script-tests/repeatn-remove-add-animation.js b/third_party/blink/web_tests/svg/animations/script-tests/repeatn-remove-add-animation.js deleted file mode 100644 index 9325b002f..0000000 --- a/third_party/blink/web_tests/svg/animations/script-tests/repeatn-remove-add-animation.js +++ /dev/null
@@ -1,70 +0,0 @@ -description("This removes and adds an animation element while the animation is repeating"); -embedSVGTestCase("resources/repeatn-remove-add-animation.svg"); - -// Setup animation test -function sample1() { - expectFillColor(rect1, 0, 255, 0); - expectFillColor(rect2, 255, 0, 0); - expectFillColor(rect3, 255, 0, 0); - expectFillColor(rect4, 255, 0, 0); -} - -function sample2() { - expectFillColor(rect1, 0, 255, 0); - expectFillColor(rect2, 0, 255, 0); - expectFillColor(rect3, 255, 0, 0); - expectFillColor(rect4, 255, 0, 0); -} - -function sample3() { - expectFillColor(rect1, 0, 255, 0); - expectFillColor(rect2, 0, 255, 0); - expectFillColor(rect3, 0, 255, 0); - expectFillColor(rect4, 255, 0, 0); -} - -function sample4() { - expectFillColor(rect1, 0, 255, 0); - expectFillColor(rect2, 0, 255, 0); - expectFillColor(rect3, 0, 255, 0); - expectFillColor(rect4, 0, 255, 0); -} - -function recreate() { - var anim1 = rootSVGElement.ownerDocument.getElementById("anim"); - anim1.parentNode.removeChild(anim1); - var anim2 = createSVGElement("animate"); - anim2.setAttribute("id", "anim"); - anim2.setAttribute("attributeName", "visibility"); - anim2.setAttribute("to", "visible"); - anim2.setAttribute("begin", "0s"); - anim2.setAttribute("dur", "2s"); - anim2.setAttribute("repeatCount", "4"); - rootSVGElement.appendChild(anim2); -} - -function executeTest() { - var rects = rootSVGElement.ownerDocument.getElementsByTagName("rect"); - rect1 = rects[0]; - rect2 = rects[1]; - rect3 = rects[2]; - rect4 = rects[3]; - - const expectedValues = [ - // [animationId, time, sampleCallback] - ["anim", 0.0, sample1], - ["anim", 0.001, sample1], - ["anim", 2.0, sample1], - ["anim", 2.001, sample2], - ["anim", 4.0, sample2], - ["anim", 4.001, sample3], - ["anim", 5.0, recreate], - ["anim", 6.0, sample3], - ["anim", 6.001, sample4] - ]; - - runAnimationTest(expectedValues); -} - -window.animationStartsImmediately = true; -var successfullyParsed = true;
diff --git a/third_party/blink/web_tests/svg/animations/script-tests/single-values-animation.js b/third_party/blink/web_tests/svg/animations/script-tests/single-values-animation.js deleted file mode 100644 index 7a23ff5..0000000 --- a/third_party/blink/web_tests/svg/animations/script-tests/single-values-animation.js +++ /dev/null
@@ -1,30 +0,0 @@ -description("This tests values animation with just a single entry"); -embedSVGTestCase("resources/single-values-animation.svg"); - -// Setup animation test -function sample1() { - shouldBeCloseEnough("rect.width.animVal.value", "10"); - shouldBe("rect.width.baseVal.value", "10"); -} - -function sample2() { - shouldBeCloseEnough("rect.width.animVal.value", "100"); - shouldBe("rect.width.baseVal.value", "10"); -} - -function executeTest() { - rect = rootSVGElement.ownerDocument.getElementsByTagName("rect")[0]; - - const expectedValues = [ - // [animationId, time, sampleCallback] - ["an1", 0.0, sample1], - ["an1", 2.0, sample2], - ["an1", 4.0, sample2], - ["an1", 60.0, sample2] - ]; - - runAnimationTest(expectedValues); -} - -window.animationStartsImmediately = true; -var successfullyParsed = true;
diff --git a/third_party/blink/web_tests/svg/animations/script-tests/svgangle-animation-deg-to-grad.js b/third_party/blink/web_tests/svg/animations/script-tests/svgangle-animation-deg-to-grad.js deleted file mode 100644 index 59df81e..0000000 --- a/third_party/blink/web_tests/svg/animations/script-tests/svgangle-animation-deg-to-grad.js +++ /dev/null
@@ -1,81 +0,0 @@ -description("Tests SVGAngle animation from deg to grad."); -createSVGTestCase(); - -// Setup test document -var defs = createSVGElement("defs"); - -var marker = createSVGElement("marker"); -marker.setAttribute("id", "marker"); -marker.setAttribute("viewBox", "0 0 10 10"); -marker.setAttribute("markerWidth", "4"); -marker.setAttribute("markerHeight", "3"); -marker.setAttribute("markerUnits", "strokeWidth"); -marker.setAttribute("refX", "1"); -marker.setAttribute("refY", "5"); -marker.setAttribute("orient", "0deg"); -defs.appendChild(marker); - -var polyline = createSVGElement("polyline"); -polyline.setAttribute("id", "polyline"); -polyline.setAttribute("points", "0,0 10,5 0,10 1,5"); -polyline.setAttribute("fill", "green"); -marker.appendChild(polyline); - -var path = createSVGElement("path"); -path.setAttribute("id", "path"); -path.setAttribute("d", "M45,50 L55,50"); -path.setAttribute("stroke-width","10"); -path.setAttribute("stroke", "green"); -path.setAttribute("marker-end", "url(#marker)"); -path.setAttribute("onclick", "executeTest()"); - -var animate = createSVGElement("animate"); -animate.setAttribute("id", "animation"); -animate.setAttribute("attributeName", "orient"); -animate.setAttribute("begin", "path.click"); -animate.setAttribute("dur", "4s"); -animate.setAttribute("from", "0deg"); -animate.setAttribute("to", "200grad"); -marker.appendChild(animate); -rootSVGElement.appendChild(defs); -rootSVGElement.appendChild(path); - -// Setup animation test -function sample1() { - // Check initial/end conditions - shouldBeCloseEnough("marker.orientAngle.animVal.value", "0"); - shouldBe("marker.orientAngle.baseVal.value", "0"); - - shouldBe("marker.orientType.animVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); - shouldBe("marker.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); -} - -function sample2() { - shouldBeCloseEnough("marker.orientAngle.animVal.value", "90"); - shouldBe("marker.orientAngle.baseVal.value", "0"); - - shouldBe("marker.orientType.animVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); - shouldBe("marker.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); -} - -function sample3() { - shouldBeCloseEnough("marker.orientAngle.animVal.value", "180"); - shouldBe("marker.orientAngle.baseVal.value", "0"); - - shouldBe("marker.orientType.animVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); - shouldBe("marker.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); -} - -function executeTest() { - const expectedValues = [ - // [animationId, time, sampleCallback] - ["animation", 0.0, sample1], - ["animation", 2.0, sample2], - ["animation", 3.999, sample3], - ["animation", 4.001, sample1] - ]; - - runAnimationTest(expectedValues); -} - -var successfullyParsed = true;
diff --git a/third_party/blink/web_tests/svg/animations/script-tests/svgangle-animation-deg-to-rad.js b/third_party/blink/web_tests/svg/animations/script-tests/svgangle-animation-deg-to-rad.js deleted file mode 100644 index 2bfa0a51..0000000 --- a/third_party/blink/web_tests/svg/animations/script-tests/svgangle-animation-deg-to-rad.js +++ /dev/null
@@ -1,81 +0,0 @@ -description("Tests SVGAngle animation from deg to rad."); -createSVGTestCase(); - -// Setup test document -var defs = createSVGElement("defs"); - -var marker = createSVGElement("marker"); -marker.setAttribute("id", "marker"); -marker.setAttribute("viewBox", "0 0 10 10"); -marker.setAttribute("markerWidth", "4"); -marker.setAttribute("markerHeight", "3"); -marker.setAttribute("markerUnits", "strokeWidth"); -marker.setAttribute("refX", "1"); -marker.setAttribute("refY", "5"); -marker.setAttribute("orient", "0deg"); -defs.appendChild(marker); - -var polyline = createSVGElement("polyline"); -polyline.setAttribute("id", "polyline"); -polyline.setAttribute("points", "0,0 10,5 0,10 1,5"); -polyline.setAttribute("fill", "green"); -marker.appendChild(polyline); - -var path = createSVGElement("path"); -path.setAttribute("id", "path"); -path.setAttribute("d", "M45,50 L55,50"); -path.setAttribute("stroke-width","10"); -path.setAttribute("stroke", "green"); -path.setAttribute("marker-end", "url(#marker)"); -path.setAttribute("onclick", "executeTest()"); - -var animate = createSVGElement("animate"); -animate.setAttribute("id", "animation"); -animate.setAttribute("attributeName", "orient"); -animate.setAttribute("begin", "path.click"); -animate.setAttribute("dur", "4s"); -animate.setAttribute("from", "0deg"); -animate.setAttribute("to", "3.14159265rad"); -marker.appendChild(animate); -rootSVGElement.appendChild(defs); -rootSVGElement.appendChild(path); - -// Setup animation test -function sample1() { - // Check initial/end conditions - shouldBeCloseEnough("marker.orientAngle.animVal.value", "0"); - shouldBe("marker.orientAngle.baseVal.value", "0"); - - shouldBe("marker.orientType.animVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); - shouldBe("marker.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); -} - -function sample2() { - shouldBeCloseEnough("marker.orientAngle.animVal.value", "90"); - shouldBe("marker.orientAngle.baseVal.value", "0"); - - shouldBe("marker.orientType.animVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); - shouldBe("marker.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); -} - -function sample3() { - shouldBeCloseEnough("marker.orientAngle.animVal.value", "180"); - shouldBe("marker.orientAngle.baseVal.value", "0"); - - shouldBe("marker.orientType.animVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); - shouldBe("marker.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); -} - -function executeTest() { - const expectedValues = [ - // [animationId, time, sampleCallback] - ["animation", 0.0, sample1], - ["animation", 2.0, sample2], - ["animation", 3.999, sample3], - ["animation", 4.001, sample1] - ]; - - runAnimationTest(expectedValues); -} - -var successfullyParsed = true;
diff --git a/third_party/blink/web_tests/svg/animations/script-tests/svgangle-animation-grad-to-deg.js b/third_party/blink/web_tests/svg/animations/script-tests/svgangle-animation-grad-to-deg.js deleted file mode 100644 index 703f8890..0000000 --- a/third_party/blink/web_tests/svg/animations/script-tests/svgangle-animation-grad-to-deg.js +++ /dev/null
@@ -1,81 +0,0 @@ -description("Tests SVGAngle animation from grad to deg."); -createSVGTestCase(); - -// Setup test document -var defs = createSVGElement("defs"); - -var marker = createSVGElement("marker"); -marker.setAttribute("id", "marker"); -marker.setAttribute("viewBox", "0 0 10 10"); -marker.setAttribute("markerWidth", "4"); -marker.setAttribute("markerHeight", "3"); -marker.setAttribute("markerUnits", "strokeWidth"); -marker.setAttribute("refX", "1"); -marker.setAttribute("refY", "5"); -marker.setAttribute("orient", "0deg"); -defs.appendChild(marker); - -var polyline = createSVGElement("polyline"); -polyline.setAttribute("id", "polyline"); -polyline.setAttribute("points", "0,0 10,5 0,10 1,5"); -polyline.setAttribute("fill", "green"); -marker.appendChild(polyline); - -var path = createSVGElement("path"); -path.setAttribute("id", "path"); -path.setAttribute("d", "M45,50 L55,50"); -path.setAttribute("stroke-width","10"); -path.setAttribute("stroke", "green"); -path.setAttribute("marker-end", "url(#marker)"); -path.setAttribute("onclick", "executeTest()"); - -var animate = createSVGElement("animate"); -animate.setAttribute("id", "animation"); -animate.setAttribute("attributeName", "orient"); -animate.setAttribute("begin", "path.click"); -animate.setAttribute("dur", "4s"); -animate.setAttribute("from", "0grad"); -animate.setAttribute("to", "180deg"); -marker.appendChild(animate); -rootSVGElement.appendChild(defs); -rootSVGElement.appendChild(path); - -// Setup animation test -function sample1() { - // Check initial/end conditions - shouldBeCloseEnough("marker.orientAngle.animVal.value", "0"); - shouldBe("marker.orientAngle.baseVal.value", "0"); - - shouldBe("marker.orientType.animVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); - shouldBe("marker.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); -} - -function sample2() { - shouldBeCloseEnough("marker.orientAngle.animVal.value", "90"); - shouldBe("marker.orientAngle.baseVal.value", "0"); - - shouldBe("marker.orientType.animVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); - shouldBe("marker.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); -} - -function sample3() { - shouldBeCloseEnough("marker.orientAngle.animVal.value", "180"); - shouldBe("marker.orientAngle.baseVal.value", "0"); - - shouldBe("marker.orientType.animVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); - shouldBe("marker.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); -} - -function executeTest() { - const expectedValues = [ - // [animationId, time, sampleCallback] - ["animation", 0.0, sample1], - ["animation", 2.0, sample2], - ["animation", 3.999, sample3], - ["animation", 4.001, sample1] - ]; - - runAnimationTest(expectedValues); -} - -var successfullyParsed = true;
diff --git a/third_party/blink/web_tests/svg/animations/script-tests/svgangle-animation-grad-to-rad.js b/third_party/blink/web_tests/svg/animations/script-tests/svgangle-animation-grad-to-rad.js deleted file mode 100644 index 64ae5c7..0000000 --- a/third_party/blink/web_tests/svg/animations/script-tests/svgangle-animation-grad-to-rad.js +++ /dev/null
@@ -1,81 +0,0 @@ -description("Tests SVGAngle animation from grad to rad."); -createSVGTestCase(); - -// Setup test document -var defs = createSVGElement("defs"); - -var marker = createSVGElement("marker"); -marker.setAttribute("id", "marker"); -marker.setAttribute("viewBox", "0 0 10 10"); -marker.setAttribute("markerWidth", "4"); -marker.setAttribute("markerHeight", "3"); -marker.setAttribute("markerUnits", "strokeWidth"); -marker.setAttribute("refX", "1"); -marker.setAttribute("refY", "5"); -marker.setAttribute("orient", "0deg"); -defs.appendChild(marker); - -var polyline = createSVGElement("polyline"); -polyline.setAttribute("id", "polyline"); -polyline.setAttribute("points", "0,0 10,5 0,10 1,5"); -polyline.setAttribute("fill", "green"); -marker.appendChild(polyline); - -var path = createSVGElement("path"); -path.setAttribute("id", "path"); -path.setAttribute("d", "M45,50 L55,50"); -path.setAttribute("stroke-width","10"); -path.setAttribute("stroke", "green"); -path.setAttribute("marker-end", "url(#marker)"); -path.setAttribute("onclick", "executeTest()"); - -var animate = createSVGElement("animate"); -animate.setAttribute("id", "animation"); -animate.setAttribute("attributeName", "orient"); -animate.setAttribute("begin", "path.click"); -animate.setAttribute("dur", "4s"); -animate.setAttribute("from", "0grad"); -animate.setAttribute("to", "3.14159265rad"); -marker.appendChild(animate); -rootSVGElement.appendChild(defs); -rootSVGElement.appendChild(path); - -// Setup animation test -function sample1() { - // Check initial/end conditions - shouldBeCloseEnough("marker.orientAngle.animVal.value", "0"); - shouldBe("marker.orientAngle.baseVal.value", "0"); - - shouldBe("marker.orientType.animVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); - shouldBe("marker.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); -} - -function sample2() { - shouldBeCloseEnough("marker.orientAngle.animVal.value", "90"); - shouldBe("marker.orientAngle.baseVal.value", "0"); - - shouldBe("marker.orientType.animVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); - shouldBe("marker.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); -} - -function sample3() { - shouldBeCloseEnough("marker.orientAngle.animVal.value", "180"); - shouldBe("marker.orientAngle.baseVal.value", "0"); - - shouldBe("marker.orientType.animVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); - shouldBe("marker.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); -} - -function executeTest() { - const expectedValues = [ - // [animationId, time, sampleCallback] - ["animation", 0.0, sample1], - ["animation", 2.0, sample2], - ["animation", 3.999, sample3], - ["animation", 4.001, sample1] - ]; - - runAnimationTest(expectedValues); -} - -var successfullyParsed = true;
diff --git a/third_party/blink/web_tests/svg/animations/script-tests/svgangle-animation-rad-to-deg.js b/third_party/blink/web_tests/svg/animations/script-tests/svgangle-animation-rad-to-deg.js deleted file mode 100644 index 1475458..0000000 --- a/third_party/blink/web_tests/svg/animations/script-tests/svgangle-animation-rad-to-deg.js +++ /dev/null
@@ -1,81 +0,0 @@ -description("Tests SVGAngle animation from rad to deg."); -createSVGTestCase(); - -// Setup test document -var defs = createSVGElement("defs"); - -var marker = createSVGElement("marker"); -marker.setAttribute("id", "marker"); -marker.setAttribute("viewBox", "0 0 10 10"); -marker.setAttribute("markerWidth", "4"); -marker.setAttribute("markerHeight", "3"); -marker.setAttribute("markerUnits", "strokeWidth"); -marker.setAttribute("refX", "1"); -marker.setAttribute("refY", "5"); -marker.setAttribute("orient", "0deg"); -defs.appendChild(marker); - -var polyline = createSVGElement("polyline"); -polyline.setAttribute("id", "polyline"); -polyline.setAttribute("points", "0,0 10,5 0,10 1,5"); -polyline.setAttribute("fill", "green"); -marker.appendChild(polyline); - -var path = createSVGElement("path"); -path.setAttribute("id", "path"); -path.setAttribute("d", "M45,50 L55,50"); -path.setAttribute("stroke-width","10"); -path.setAttribute("stroke", "green"); -path.setAttribute("marker-end", "url(#marker)"); -path.setAttribute("onclick", "executeTest()"); - -var animate = createSVGElement("animate"); -animate.setAttribute("id", "animation"); -animate.setAttribute("attributeName", "orient"); -animate.setAttribute("begin", "path.click"); -animate.setAttribute("dur", "4s"); -animate.setAttribute("from", "0rad"); -animate.setAttribute("to", "180deg"); -marker.appendChild(animate); -rootSVGElement.appendChild(defs); -rootSVGElement.appendChild(path); - -// Setup animation test -function sample1() { - // Check initial/end conditions - shouldBeCloseEnough("marker.orientAngle.animVal.value", "0"); - shouldBe("marker.orientAngle.baseVal.value", "0"); - - shouldBe("marker.orientType.animVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); - shouldBe("marker.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); -} - -function sample2() { - shouldBeCloseEnough("marker.orientAngle.animVal.value", "90"); - shouldBe("marker.orientAngle.baseVal.value", "0"); - - shouldBe("marker.orientType.animVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); - shouldBe("marker.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); -} - -function sample3() { - shouldBeCloseEnough("marker.orientAngle.animVal.value", "180"); - shouldBe("marker.orientAngle.baseVal.value", "0"); - - shouldBe("marker.orientType.animVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); - shouldBe("marker.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); -} - -function executeTest() { - const expectedValues = [ - // [animationId, time, sampleCallback] - ["animation", 0.0, sample1], - ["animation", 2.0, sample2], - ["animation", 3.999, sample3], - ["animation", 4.001, sample1] - ]; - - runAnimationTest(expectedValues); -} - -var successfullyParsed = true;
diff --git a/third_party/blink/web_tests/svg/animations/script-tests/svgangle-animation-rad-to-grad.js b/third_party/blink/web_tests/svg/animations/script-tests/svgangle-animation-rad-to-grad.js deleted file mode 100644 index 9669a9da60..0000000 --- a/third_party/blink/web_tests/svg/animations/script-tests/svgangle-animation-rad-to-grad.js +++ /dev/null
@@ -1,81 +0,0 @@ -description("Tests SVGAngle animation from rad to grad."); -createSVGTestCase(); - -// Setup test document -var defs = createSVGElement("defs"); - -var marker = createSVGElement("marker"); -marker.setAttribute("id", "marker"); -marker.setAttribute("viewBox", "0 0 10 10"); -marker.setAttribute("markerWidth", "4"); -marker.setAttribute("markerHeight", "3"); -marker.setAttribute("markerUnits", "strokeWidth"); -marker.setAttribute("refX", "1"); -marker.setAttribute("refY", "5"); -marker.setAttribute("orient", "0deg"); -defs.appendChild(marker); - -var polyline = createSVGElement("polyline"); -polyline.setAttribute("id", "polyline"); -polyline.setAttribute("points", "0,0 10,5 0,10 1,5"); -polyline.setAttribute("fill", "green"); -marker.appendChild(polyline); - -var path = createSVGElement("path"); -path.setAttribute("id", "path"); -path.setAttribute("d", "M45,50 L55,50"); -path.setAttribute("stroke-width","10"); -path.setAttribute("stroke", "green"); -path.setAttribute("marker-end", "url(#marker)"); -path.setAttribute("onclick", "executeTest()"); - -var animate = createSVGElement("animate"); -animate.setAttribute("id", "animation"); -animate.setAttribute("attributeName", "orient"); -animate.setAttribute("begin", "path.click"); -animate.setAttribute("dur", "4s"); -animate.setAttribute("from", "0rad"); -animate.setAttribute("to", "200grad"); -marker.appendChild(animate); -rootSVGElement.appendChild(defs); -rootSVGElement.appendChild(path); - -// Setup animation test -function sample1() { - // Check initial/end conditions - shouldBeCloseEnough("marker.orientAngle.animVal.value", "0"); - shouldBe("marker.orientAngle.baseVal.value", "0"); - - shouldBe("marker.orientType.animVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); - shouldBe("marker.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); -} - -function sample2() { - shouldBeCloseEnough("marker.orientAngle.animVal.value", "90"); - shouldBe("marker.orientAngle.baseVal.value", "0"); - - shouldBe("marker.orientType.animVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); - shouldBe("marker.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); -} - -function sample3() { - shouldBeCloseEnough("marker.orientAngle.animVal.value", "180"); - shouldBe("marker.orientAngle.baseVal.value", "0"); - - shouldBe("marker.orientType.animVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); - shouldBe("marker.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); -} - -function executeTest() { - const expectedValues = [ - // [animationId, time, sampleCallback] - ["animation", 0.0, sample1], - ["animation", 2.0, sample2], - ["animation", 3.999, sample3], - ["animation", 4.001, sample1] - ]; - - runAnimationTest(expectedValues); -} - -var successfullyParsed = true;
diff --git a/third_party/blink/web_tests/svg/animations/script-tests/svgenum-animation-11.js b/third_party/blink/web_tests/svg/animations/script-tests/svgenum-animation-11.js deleted file mode 100644 index da7d63d..0000000 --- a/third_party/blink/web_tests/svg/animations/script-tests/svgenum-animation-11.js +++ /dev/null
@@ -1,83 +0,0 @@ -description("Test BlendModeType enumeration animations"); -createSVGTestCase(); - -// Setup test document -var filter = createSVGElement("filter"); -filter.setAttribute("id", "filter"); -rootSVGElement.appendChild(filter); - -var feFlood = createSVGElement("feFlood"); -feFlood.setAttribute("in", "SourceGraphic"); -feFlood.setAttribute("flood-color", "green"); -feFlood.setAttribute("flood-opacity", "0.5"); -feFlood.setAttribute("result", "img"); -filter.appendChild(feFlood); - -var feBlend = createSVGElement("feBlend"); -feBlend.setAttribute("in", "SourceGraphic"); -feBlend.setAttribute("in2", "img"); -feBlend.setAttribute("mode", "lighten"); -filter.appendChild(feBlend); - -var rect = createSVGElement("rect"); -rect.setAttribute("id", "rect"); -rect.setAttribute("onclick", "executeTest()"); -rect.setAttribute("filter", "url(#filter)"); -rect.setAttribute("width", "100"); -rect.setAttribute("height", "100"); -rootSVGElement.appendChild(rect); - -var animate1 = createSVGElement("animate"); -animate1.setAttribute("id", "animation"); -animate1.setAttribute("attributeName", "mode"); -animate1.setAttribute("begin", "rect.click"); -animate1.setAttribute("dur", "5s"); -animate1.setAttribute("values", "normal;multiply;screen;darken;lighten"); -animate1.setAttribute("fill", "freeze"); -feBlend.appendChild(animate1); - -// Setup animation test -function sample1() { - shouldBe("feBlend.mode.animVal", "SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN"); - shouldBe("feBlend.mode.baseVal", "SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN"); -} - -function sample2() { - shouldBe("feBlend.mode.animVal", "SVGFEBlendElement.SVG_FEBLEND_MODE_NORMAL"); - shouldBe("feBlend.mode.baseVal", "SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN"); -} - -function sample3() { - shouldBe("feBlend.mode.animVal", "SVGFEBlendElement.SVG_FEBLEND_MODE_MULTIPLY"); - shouldBe("feBlend.mode.baseVal", "SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN"); -} - -function sample4() { - shouldBe("feBlend.mode.animVal", "SVGFEBlendElement.SVG_FEBLEND_MODE_SCREEN"); - shouldBe("feBlend.mode.baseVal", "SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN"); -} - -function sample5() { - shouldBe("feBlend.mode.animVal", "SVGFEBlendElement.SVG_FEBLEND_MODE_DARKEN"); - shouldBe("feBlend.mode.baseVal", "SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN"); -} - -function executeTest() { - const expectedValues = [ - // [animationId, time, sampleCallback] - ["animation", 0.0, sample1], - ["animation", 0.001, sample2], - ["animation", 0.999, sample2], - ["animation", 1.001, sample3], - ["animation", 1.999, sample3], - ["animation", 2.001, sample4], - ["animation", 2.999, sample4], - ["animation", 3.001, sample5], - ["animation", 3.999, sample5], - ["animation", 4.001, sample1] - ]; - - runAnimationTest(expectedValues); -} - -var successfullyParsed = true;
diff --git a/third_party/blink/web_tests/svg/animations/script-tests/svgenum-animation-12.js b/third_party/blink/web_tests/svg/animations/script-tests/svgenum-animation-12.js deleted file mode 100644 index 1245ccd5..0000000 --- a/third_party/blink/web_tests/svg/animations/script-tests/svgenum-animation-12.js +++ /dev/null
@@ -1,69 +0,0 @@ -description("Test SVGSpreadMethodType enumeration animations"); -createSVGTestCase(); - -// Setup test document -var gradient = createSVGElement("linearGradient"); -gradient.setAttribute("id", "gradient"); -rootSVGElement.appendChild(gradient); - -var stop = createSVGElement("stop"); -stop.setAttribute("offset", "1"); -stop.setAttribute("stop-color", "green"); -gradient.appendChild(stop); - -var feBlend = createSVGElement("feBlend"); -feBlend.setAttribute("in", "SourceGraphic"); -feBlend.setAttribute("in2", "img"); -feBlend.setAttribute("mode", "lighten"); -gradient.appendChild(feBlend); - -var rect = createSVGElement("rect"); -rect.setAttribute("id", "rect"); -rect.setAttribute("onclick", "executeTest()"); -rect.setAttribute("fill", "url(#gradient)"); -rect.setAttribute("width", "100"); -rect.setAttribute("height", "100"); -rootSVGElement.appendChild(rect); - -var animate1 = createSVGElement("animate"); -animate1.setAttribute("id", "animation"); -animate1.setAttribute("attributeName", "spreadMethod"); -animate1.setAttribute("begin", "rect.click"); -animate1.setAttribute("dur", "3s"); -animate1.setAttribute("values", "pad;reflect;repeat"); -animate1.setAttribute("fill", "freeze"); -gradient.appendChild(animate1); - -// Setup animation test -function sample1() { - shouldBe("gradient.spreadMethod.animVal", "SVGGradientElement.SVG_SPREADMETHOD_PAD"); - shouldBe("gradient.spreadMethod.baseVal", "SVGGradientElement.SVG_SPREADMETHOD_PAD"); -} - -function sample2() { - shouldBe("gradient.spreadMethod.animVal", "SVGGradientElement.SVG_SPREADMETHOD_REFLECT"); - shouldBe("gradient.spreadMethod.baseVal", "SVGGradientElement.SVG_SPREADMETHOD_PAD"); -} - -function sample3() { - shouldBe("gradient.spreadMethod.animVal", "SVGGradientElement.SVG_SPREADMETHOD_REPEAT"); - shouldBe("gradient.spreadMethod.baseVal", "SVGGradientElement.SVG_SPREADMETHOD_PAD"); -} - -function executeTest() { - const expectedValues = [ - // [animationId, time, sampleCallback] - ["animation", 0.0, sample1], - ["animation", 0.001, sample1], - ["animation", 0.999, sample1], - ["animation", 1.001, sample2], - ["animation", 1.999, sample2], - ["animation", 2.001, sample3], - ["animation", 2.999, sample3], - ["animation", 3.001, sample3] - ]; - - runAnimationTest(expectedValues); -} - -var successfullyParsed = true;
diff --git a/third_party/blink/web_tests/svg/animations/single-values-animation-expected.txt b/third_party/blink/web_tests/svg/animations/single-values-animation-expected.txt deleted file mode 100644 index 0d0c7a9..0000000 --- a/third_party/blink/web_tests/svg/animations/single-values-animation-expected.txt +++ /dev/null
@@ -1,18 +0,0 @@ -SVG 1.1 dynamic animation tests - -This tests values animation with just a single entry - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS rect.width.animVal.value is 10 -PASS rect.width.baseVal.value is 10 -PASS rect.width.animVal.value is 100 -PASS rect.width.baseVal.value is 10 -PASS rect.width.animVal.value is 100 -PASS rect.width.baseVal.value is 10 -PASS rect.width.animVal.value is 100 -PASS rect.width.baseVal.value is 10 -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/svg/animations/single-values-animation.html b/third_party/blink/web_tests/svg/animations/single-values-animation.html deleted file mode 100644 index ecb407b7..0000000 --- a/third_party/blink/web_tests/svg/animations/single-values-animation.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -<script src="resources/SVGTestCase.js"></script> -<script src="resources/SVGAnimationTestCase.js"></script> -</head> -<body onload="runSMILTest()"> -<h1>SVG 1.1 dynamic animation tests</h1> -<p id="description"></p> -<div id="console"></div> -<script src="script-tests/single-values-animation.js"></script> -</body> -</html>
diff --git a/third_party/blink/web_tests/svg/animations/svgangle-animation-deg-to-grad-expected.txt b/third_party/blink/web_tests/svg/animations/svgangle-animation-deg-to-grad-expected.txt deleted file mode 100644 index e2ea002..0000000 --- a/third_party/blink/web_tests/svg/animations/svgangle-animation-deg-to-grad-expected.txt +++ /dev/null
@@ -1,26 +0,0 @@ -SVG 1.1 dynamic animation tests - -Tests SVGAngle animation from deg to grad. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS marker.orientAngle.animVal.value is 0 -PASS marker.orientAngle.baseVal.value is 0 -PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientAngle.animVal.value is 90 -PASS marker.orientAngle.baseVal.value is 0 -PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientAngle.animVal.value is 180 -PASS marker.orientAngle.baseVal.value is 0 -PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientAngle.animVal.value is 0 -PASS marker.orientAngle.baseVal.value is 0 -PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/svg/animations/svgangle-animation-deg-to-grad.html b/third_party/blink/web_tests/svg/animations/svgangle-animation-deg-to-grad.html deleted file mode 100644 index 26e9ea5..0000000 --- a/third_party/blink/web_tests/svg/animations/svgangle-animation-deg-to-grad.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -<script src="resources/SVGTestCase.js"></script> -<script src="resources/SVGAnimationTestCase.js"></script> -</head> -<body onload="runSMILTest()"> -<h1>SVG 1.1 dynamic animation tests</h1> -<p id="description"></p> -<div id="console"></div> -<script src="script-tests/svgangle-animation-deg-to-grad.js"></script> -</body> -</html>
diff --git a/third_party/blink/web_tests/svg/animations/svgangle-animation-deg-to-rad-expected.txt b/third_party/blink/web_tests/svg/animations/svgangle-animation-deg-to-rad-expected.txt deleted file mode 100644 index 49acee69..0000000 --- a/third_party/blink/web_tests/svg/animations/svgangle-animation-deg-to-rad-expected.txt +++ /dev/null
@@ -1,26 +0,0 @@ -SVG 1.1 dynamic animation tests - -Tests SVGAngle animation from deg to rad. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS marker.orientAngle.animVal.value is 0 -PASS marker.orientAngle.baseVal.value is 0 -PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientAngle.animVal.value is 90 -PASS marker.orientAngle.baseVal.value is 0 -PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientAngle.animVal.value is 180 -PASS marker.orientAngle.baseVal.value is 0 -PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientAngle.animVal.value is 0 -PASS marker.orientAngle.baseVal.value is 0 -PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/svg/animations/svgangle-animation-deg-to-rad.html b/third_party/blink/web_tests/svg/animations/svgangle-animation-deg-to-rad.html deleted file mode 100644 index 1023817..0000000 --- a/third_party/blink/web_tests/svg/animations/svgangle-animation-deg-to-rad.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -<script src="resources/SVGTestCase.js"></script> -<script src="resources/SVGAnimationTestCase.js"></script> -</head> -<body onload="runSMILTest()"> -<h1>SVG 1.1 dynamic animation tests</h1> -<p id="description"></p> -<div id="console"></div> -<script src="script-tests/svgangle-animation-deg-to-rad.js"></script> -</body> -</html>
diff --git a/third_party/blink/web_tests/svg/animations/svgangle-animation-grad-to-deg-expected.txt b/third_party/blink/web_tests/svg/animations/svgangle-animation-grad-to-deg-expected.txt deleted file mode 100644 index 581052c..0000000 --- a/third_party/blink/web_tests/svg/animations/svgangle-animation-grad-to-deg-expected.txt +++ /dev/null
@@ -1,26 +0,0 @@ -SVG 1.1 dynamic animation tests - -Tests SVGAngle animation from grad to deg. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS marker.orientAngle.animVal.value is 0 -PASS marker.orientAngle.baseVal.value is 0 -PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientAngle.animVal.value is 90 -PASS marker.orientAngle.baseVal.value is 0 -PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientAngle.animVal.value is 180 -PASS marker.orientAngle.baseVal.value is 0 -PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientAngle.animVal.value is 0 -PASS marker.orientAngle.baseVal.value is 0 -PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/svg/animations/svgangle-animation-grad-to-deg.html b/third_party/blink/web_tests/svg/animations/svgangle-animation-grad-to-deg.html deleted file mode 100644 index fb8ff1a..0000000 --- a/third_party/blink/web_tests/svg/animations/svgangle-animation-grad-to-deg.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -<script src="resources/SVGTestCase.js"></script> -<script src="resources/SVGAnimationTestCase.js"></script> -</head> -<body onload="runSMILTest()"> -<h1>SVG 1.1 dynamic animation tests</h1> -<p id="description"></p> -<div id="console"></div> -<script src="script-tests/svgangle-animation-grad-to-deg.js"></script> -</body> -</html>
diff --git a/third_party/blink/web_tests/svg/animations/svgangle-animation-grad-to-rad-expected.txt b/third_party/blink/web_tests/svg/animations/svgangle-animation-grad-to-rad-expected.txt deleted file mode 100644 index e49150e..0000000 --- a/third_party/blink/web_tests/svg/animations/svgangle-animation-grad-to-rad-expected.txt +++ /dev/null
@@ -1,26 +0,0 @@ -SVG 1.1 dynamic animation tests - -Tests SVGAngle animation from grad to rad. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS marker.orientAngle.animVal.value is 0 -PASS marker.orientAngle.baseVal.value is 0 -PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientAngle.animVal.value is 90 -PASS marker.orientAngle.baseVal.value is 0 -PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientAngle.animVal.value is 180 -PASS marker.orientAngle.baseVal.value is 0 -PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientAngle.animVal.value is 0 -PASS marker.orientAngle.baseVal.value is 0 -PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/svg/animations/svgangle-animation-grad-to-rad.html b/third_party/blink/web_tests/svg/animations/svgangle-animation-grad-to-rad.html deleted file mode 100644 index bca3945..0000000 --- a/third_party/blink/web_tests/svg/animations/svgangle-animation-grad-to-rad.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -<script src="resources/SVGTestCase.js"></script> -<script src="resources/SVGAnimationTestCase.js"></script> -</head> -<body onload="runSMILTest()"> -<h1>SVG 1.1 dynamic animation tests</h1> -<p id="description"></p> -<div id="console"></div> -<script src="script-tests/svgangle-animation-grad-to-rad.js"></script> -</body> -</html>
diff --git a/third_party/blink/web_tests/svg/animations/svgangle-animation-rad-to-deg-expected.txt b/third_party/blink/web_tests/svg/animations/svgangle-animation-rad-to-deg-expected.txt deleted file mode 100644 index 6c9bd76..0000000 --- a/third_party/blink/web_tests/svg/animations/svgangle-animation-rad-to-deg-expected.txt +++ /dev/null
@@ -1,26 +0,0 @@ -SVG 1.1 dynamic animation tests - -Tests SVGAngle animation from rad to deg. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS marker.orientAngle.animVal.value is 0 -PASS marker.orientAngle.baseVal.value is 0 -PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientAngle.animVal.value is 90 -PASS marker.orientAngle.baseVal.value is 0 -PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientAngle.animVal.value is 180 -PASS marker.orientAngle.baseVal.value is 0 -PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientAngle.animVal.value is 0 -PASS marker.orientAngle.baseVal.value is 0 -PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/svg/animations/svgangle-animation-rad-to-deg.html b/third_party/blink/web_tests/svg/animations/svgangle-animation-rad-to-deg.html deleted file mode 100644 index 811a5fa..0000000 --- a/third_party/blink/web_tests/svg/animations/svgangle-animation-rad-to-deg.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -<script src="resources/SVGTestCase.js"></script> -<script src="resources/SVGAnimationTestCase.js"></script> -</head> -<body onload="runSMILTest()"> -<h1>SVG 1.1 dynamic animation tests</h1> -<p id="description"></p> -<div id="console"></div> -<script src="script-tests/svgangle-animation-rad-to-deg.js"></script> -</body> -</html>
diff --git a/third_party/blink/web_tests/svg/animations/svgangle-animation-rad-to-grad-expected.txt b/third_party/blink/web_tests/svg/animations/svgangle-animation-rad-to-grad-expected.txt deleted file mode 100644 index 1aa3d9e..0000000 --- a/third_party/blink/web_tests/svg/animations/svgangle-animation-rad-to-grad-expected.txt +++ /dev/null
@@ -1,26 +0,0 @@ -SVG 1.1 dynamic animation tests - -Tests SVGAngle animation from rad to grad. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS marker.orientAngle.animVal.value is 0 -PASS marker.orientAngle.baseVal.value is 0 -PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientAngle.animVal.value is 90 -PASS marker.orientAngle.baseVal.value is 0 -PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientAngle.animVal.value is 180 -PASS marker.orientAngle.baseVal.value is 0 -PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientAngle.animVal.value is 0 -PASS marker.orientAngle.baseVal.value is 0 -PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/svg/animations/svgangle-animation-rad-to-grad.html b/third_party/blink/web_tests/svg/animations/svgangle-animation-rad-to-grad.html deleted file mode 100644 index 84e89bb..0000000 --- a/third_party/blink/web_tests/svg/animations/svgangle-animation-rad-to-grad.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -<script src="resources/SVGTestCase.js"></script> -<script src="resources/SVGAnimationTestCase.js"></script> -</head> -<body onload="runSMILTest()"> -<h1>SVG 1.1 dynamic animation tests</h1> -<p id="description"></p> -<div id="console"></div> -<script src="script-tests/svgangle-animation-rad-to-grad.js"></script> -</body> -</html>
diff --git a/third_party/blink/web_tests/svg/animations/svgboolean-animation-1-expected.txt b/third_party/blink/web_tests/svg/animations/svgboolean-animation-1-expected.txt deleted file mode 100644 index d472ec3e..0000000 --- a/third_party/blink/web_tests/svg/animations/svgboolean-animation-1-expected.txt +++ /dev/null
@@ -1,18 +0,0 @@ -SVG 1.1 dynamic animation tests - -Test 'to' animation of SVGBoolean. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS feConvolveMatrix.preserveAlpha.animVal is false -PASS feConvolveMatrix.preserveAlpha.baseVal is false -PASS feConvolveMatrix.preserveAlpha.animVal is false -PASS feConvolveMatrix.preserveAlpha.baseVal is false -PASS feConvolveMatrix.preserveAlpha.animVal is true -PASS feConvolveMatrix.preserveAlpha.baseVal is false -PASS feConvolveMatrix.preserveAlpha.animVal is false -PASS feConvolveMatrix.preserveAlpha.baseVal is false -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/svg/animations/svgboolean-animation-1.html b/third_party/blink/web_tests/svg/animations/svgboolean-animation-1.html deleted file mode 100644 index 46c6172..0000000 --- a/third_party/blink/web_tests/svg/animations/svgboolean-animation-1.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -<script src="resources/SVGTestCase.js"></script> -<script src="resources/SVGAnimationTestCase.js"></script> -</head> -<body onload="runSMILTest()"> -<h1>SVG 1.1 dynamic animation tests</h1> -<p id="description"></p> -<div id="console"></div> -<script src="script-tests/svgboolean-animation-1.js"></script> -</body> -</html>
diff --git a/third_party/blink/web_tests/svg/animations/svgenum-animation-1-expected.txt b/third_party/blink/web_tests/svg/animations/svgenum-animation-1-expected.txt deleted file mode 100644 index 2bace712..0000000 --- a/third_party/blink/web_tests/svg/animations/svgenum-animation-1-expected.txt +++ /dev/null
@@ -1,20 +0,0 @@ -SVG 1.1 dynamic animation tests - -Test SVGUnitTypes enumeration animations - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS pattern.patternContentUnits.animVal is SVGUnitTypes.SVG_UNIT_TYPE_USERSPACEONUSE -PASS pattern.patternContentUnits.baseVal is SVGUnitTypes.SVG_UNIT_TYPE_USERSPACEONUSE -PASS pattern.patternContentUnits.animVal is SVGUnitTypes.SVG_UNIT_TYPE_USERSPACEONUSE -PASS pattern.patternContentUnits.baseVal is SVGUnitTypes.SVG_UNIT_TYPE_USERSPACEONUSE -PASS pattern.patternContentUnits.animVal is SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX -PASS pattern.patternContentUnits.baseVal is SVGUnitTypes.SVG_UNIT_TYPE_USERSPACEONUSE -PASS pattern.patternContentUnits.animVal is SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX -PASS pattern.patternContentUnits.baseVal is SVGUnitTypes.SVG_UNIT_TYPE_USERSPACEONUSE -PASS pattern.patternContentUnits.animVal is SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX -PASS pattern.patternContentUnits.baseVal is SVGUnitTypes.SVG_UNIT_TYPE_USERSPACEONUSE -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/svg/animations/svgenum-animation-1.html b/third_party/blink/web_tests/svg/animations/svgenum-animation-1.html deleted file mode 100644 index 6ce3cb3..0000000 --- a/third_party/blink/web_tests/svg/animations/svgenum-animation-1.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -<script src="resources/SVGTestCase.js"></script> -<script src="resources/SVGAnimationTestCase.js"></script> -</head> -<body onload="runSMILTest()"> -<h1>SVG 1.1 dynamic animation tests</h1> -<p id="description"></p> -<div id="console"></div> -<script src="script-tests/svgenum-animation-1.js"></script> -</body> -</html>
diff --git a/third_party/blink/web_tests/svg/animations/svgenum-animation-10-expected.txt b/third_party/blink/web_tests/svg/animations/svgenum-animation-10-expected.txt deleted file mode 100644 index 820ece38..0000000 --- a/third_party/blink/web_tests/svg/animations/svgenum-animation-10-expected.txt +++ /dev/null
@@ -1,20 +0,0 @@ -SVG 1.1 dynamic animation tests - -Test SVGMarkerUnitsType enumeration animations - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS marker.markerUnits.animVal is SVGMarkerElement.SVG_MARKERUNITS_USERSPACEONUSE -PASS marker.markerUnits.baseVal is SVGMarkerElement.SVG_MARKERUNITS_USERSPACEONUSE -PASS marker.markerUnits.animVal is SVGMarkerElement.SVG_MARKERUNITS_USERSPACEONUSE -PASS marker.markerUnits.baseVal is SVGMarkerElement.SVG_MARKERUNITS_USERSPACEONUSE -PASS marker.markerUnits.animVal is SVGMarkerElement.SVG_MARKERUNITS_STROKEWIDTH -PASS marker.markerUnits.baseVal is SVGMarkerElement.SVG_MARKERUNITS_USERSPACEONUSE -PASS marker.markerUnits.animVal is SVGMarkerElement.SVG_MARKERUNITS_STROKEWIDTH -PASS marker.markerUnits.baseVal is SVGMarkerElement.SVG_MARKERUNITS_USERSPACEONUSE -PASS marker.markerUnits.animVal is SVGMarkerElement.SVG_MARKERUNITS_STROKEWIDTH -PASS marker.markerUnits.baseVal is SVGMarkerElement.SVG_MARKERUNITS_USERSPACEONUSE -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/svg/animations/svgenum-animation-10.html b/third_party/blink/web_tests/svg/animations/svgenum-animation-10.html deleted file mode 100644 index dbd24d0c..0000000 --- a/third_party/blink/web_tests/svg/animations/svgenum-animation-10.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -<script src="resources/SVGTestCase.js"></script> -<script src="resources/SVGAnimationTestCase.js"></script> -</head> -<body onload="runSMILTest()"> -<h1>SVG 1.1 dynamic animation tests</h1> -<p id="description"></p> -<div id="console"></div> -<script src="script-tests/svgenum-animation-10.js"></script> -</body> -</html>
diff --git a/third_party/blink/web_tests/svg/animations/svgenum-animation-11-expected.txt b/third_party/blink/web_tests/svg/animations/svgenum-animation-11-expected.txt deleted file mode 100644 index a7596486..0000000 --- a/third_party/blink/web_tests/svg/animations/svgenum-animation-11-expected.txt +++ /dev/null
@@ -1,30 +0,0 @@ -SVG 1.1 dynamic animation tests - -Test BlendModeType enumeration animations - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS feBlend.mode.animVal is SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN -PASS feBlend.mode.baseVal is SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN -PASS feBlend.mode.animVal is SVGFEBlendElement.SVG_FEBLEND_MODE_NORMAL -PASS feBlend.mode.baseVal is SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN -PASS feBlend.mode.animVal is SVGFEBlendElement.SVG_FEBLEND_MODE_NORMAL -PASS feBlend.mode.baseVal is SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN -PASS feBlend.mode.animVal is SVGFEBlendElement.SVG_FEBLEND_MODE_MULTIPLY -PASS feBlend.mode.baseVal is SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN -PASS feBlend.mode.animVal is SVGFEBlendElement.SVG_FEBLEND_MODE_MULTIPLY -PASS feBlend.mode.baseVal is SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN -PASS feBlend.mode.animVal is SVGFEBlendElement.SVG_FEBLEND_MODE_SCREEN -PASS feBlend.mode.baseVal is SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN -PASS feBlend.mode.animVal is SVGFEBlendElement.SVG_FEBLEND_MODE_SCREEN -PASS feBlend.mode.baseVal is SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN -PASS feBlend.mode.animVal is SVGFEBlendElement.SVG_FEBLEND_MODE_DARKEN -PASS feBlend.mode.baseVal is SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN -PASS feBlend.mode.animVal is SVGFEBlendElement.SVG_FEBLEND_MODE_DARKEN -PASS feBlend.mode.baseVal is SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN -PASS feBlend.mode.animVal is SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN -PASS feBlend.mode.baseVal is SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/svg/animations/svgenum-animation-11.html b/third_party/blink/web_tests/svg/animations/svgenum-animation-11.html deleted file mode 100644 index 5493edbf..0000000 --- a/third_party/blink/web_tests/svg/animations/svgenum-animation-11.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -<script src="resources/SVGTestCase.js"></script> -<script src="resources/SVGAnimationTestCase.js"></script> -</head> -<body onload="runSMILTest()"> -<h1>SVG 1.1 dynamic animation tests</h1> -<p id="description"></p> -<div id="console"></div> -<script src="script-tests/svgenum-animation-11.js"></script> -</body> -</html>
diff --git a/third_party/blink/web_tests/svg/animations/svgenum-animation-12-expected.txt b/third_party/blink/web_tests/svg/animations/svgenum-animation-12-expected.txt deleted file mode 100644 index 75840c4..0000000 --- a/third_party/blink/web_tests/svg/animations/svgenum-animation-12-expected.txt +++ /dev/null
@@ -1,26 +0,0 @@ -SVG 1.1 dynamic animation tests - -Test SVGSpreadMethodType enumeration animations - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS gradient.spreadMethod.animVal is SVGGradientElement.SVG_SPREADMETHOD_PAD -PASS gradient.spreadMethod.baseVal is SVGGradientElement.SVG_SPREADMETHOD_PAD -PASS gradient.spreadMethod.animVal is SVGGradientElement.SVG_SPREADMETHOD_PAD -PASS gradient.spreadMethod.baseVal is SVGGradientElement.SVG_SPREADMETHOD_PAD -PASS gradient.spreadMethod.animVal is SVGGradientElement.SVG_SPREADMETHOD_PAD -PASS gradient.spreadMethod.baseVal is SVGGradientElement.SVG_SPREADMETHOD_PAD -PASS gradient.spreadMethod.animVal is SVGGradientElement.SVG_SPREADMETHOD_REFLECT -PASS gradient.spreadMethod.baseVal is SVGGradientElement.SVG_SPREADMETHOD_PAD -PASS gradient.spreadMethod.animVal is SVGGradientElement.SVG_SPREADMETHOD_REFLECT -PASS gradient.spreadMethod.baseVal is SVGGradientElement.SVG_SPREADMETHOD_PAD -PASS gradient.spreadMethod.animVal is SVGGradientElement.SVG_SPREADMETHOD_REPEAT -PASS gradient.spreadMethod.baseVal is SVGGradientElement.SVG_SPREADMETHOD_PAD -PASS gradient.spreadMethod.animVal is SVGGradientElement.SVG_SPREADMETHOD_REPEAT -PASS gradient.spreadMethod.baseVal is SVGGradientElement.SVG_SPREADMETHOD_PAD -PASS gradient.spreadMethod.animVal is SVGGradientElement.SVG_SPREADMETHOD_REPEAT -PASS gradient.spreadMethod.baseVal is SVGGradientElement.SVG_SPREADMETHOD_PAD -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/svg/animations/svgenum-animation-12.html b/third_party/blink/web_tests/svg/animations/svgenum-animation-12.html deleted file mode 100644 index bfcae26b..0000000 --- a/third_party/blink/web_tests/svg/animations/svgenum-animation-12.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -<script src="resources/SVGTestCase.js"></script> -<script src="resources/SVGAnimationTestCase.js"></script> -</head> -<body onload="runSMILTest()"> -<h1>SVG 1.1 dynamic animation tests</h1> -<p id="description"></p> -<div id="console"></div> -<script src="script-tests/svgenum-animation-12.js"></script> -</body> -</html>
diff --git a/third_party/blink/web_tests/svg/animations/svgenum-animation-13-expected.txt b/third_party/blink/web_tests/svg/animations/svgenum-animation-13-expected.txt deleted file mode 100644 index d64bf72..0000000 --- a/third_party/blink/web_tests/svg/animations/svgenum-animation-13-expected.txt +++ /dev/null
@@ -1,30 +0,0 @@ -SVG 1.1 dynamic animation tests - -Test ChannelSelectorType enumeration animations - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS displacementMap.xChannelSelector.animVal is SVGFEDisplacementMapElement.SVG_CHANNEL_B -PASS displacementMap.xChannelSelector.baseVal is SVGFEDisplacementMapElement.SVG_CHANNEL_B -PASS displacementMap.xChannelSelector.animVal is SVGFEDisplacementMapElement.SVG_CHANNEL_R -PASS displacementMap.xChannelSelector.baseVal is SVGFEDisplacementMapElement.SVG_CHANNEL_B -PASS displacementMap.xChannelSelector.animVal is SVGFEDisplacementMapElement.SVG_CHANNEL_R -PASS displacementMap.xChannelSelector.baseVal is SVGFEDisplacementMapElement.SVG_CHANNEL_B -PASS displacementMap.xChannelSelector.animVal is SVGFEDisplacementMapElement.SVG_CHANNEL_G -PASS displacementMap.xChannelSelector.baseVal is SVGFEDisplacementMapElement.SVG_CHANNEL_B -PASS displacementMap.xChannelSelector.animVal is SVGFEDisplacementMapElement.SVG_CHANNEL_G -PASS displacementMap.xChannelSelector.baseVal is SVGFEDisplacementMapElement.SVG_CHANNEL_B -PASS displacementMap.xChannelSelector.animVal is SVGFEDisplacementMapElement.SVG_CHANNEL_B -PASS displacementMap.xChannelSelector.baseVal is SVGFEDisplacementMapElement.SVG_CHANNEL_B -PASS displacementMap.xChannelSelector.animVal is SVGFEDisplacementMapElement.SVG_CHANNEL_B -PASS displacementMap.xChannelSelector.baseVal is SVGFEDisplacementMapElement.SVG_CHANNEL_B -PASS displacementMap.xChannelSelector.animVal is SVGFEDisplacementMapElement.SVG_CHANNEL_A -PASS displacementMap.xChannelSelector.baseVal is SVGFEDisplacementMapElement.SVG_CHANNEL_B -PASS displacementMap.xChannelSelector.animVal is SVGFEDisplacementMapElement.SVG_CHANNEL_A -PASS displacementMap.xChannelSelector.baseVal is SVGFEDisplacementMapElement.SVG_CHANNEL_B -PASS displacementMap.xChannelSelector.animVal is SVGFEDisplacementMapElement.SVG_CHANNEL_A -PASS displacementMap.xChannelSelector.baseVal is SVGFEDisplacementMapElement.SVG_CHANNEL_B -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/svg/animations/svgenum-animation-13.html b/third_party/blink/web_tests/svg/animations/svgenum-animation-13.html deleted file mode 100644 index 15e5009..0000000 --- a/third_party/blink/web_tests/svg/animations/svgenum-animation-13.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -<script src="resources/SVGTestCase.js"></script> -<script src="resources/SVGAnimationTestCase.js"></script> -</head> -<body onload="runSMILTest()"> -<h1>SVG 1.1 dynamic animation tests</h1> -<p id="description"></p> -<div id="console"></div> -<script src="script-tests/svgenum-animation-13.js"></script> -</body> -</html>
diff --git a/third_party/blink/web_tests/svg/animations/svgenum-animation-2-expected.txt b/third_party/blink/web_tests/svg/animations/svgenum-animation-2-expected.txt deleted file mode 100644 index 3bc21e1..0000000 --- a/third_party/blink/web_tests/svg/animations/svgenum-animation-2-expected.txt +++ /dev/null
@@ -1,22 +0,0 @@ -SVG 1.1 dynamic animation tests - -Test EdgeModeType enumeration animations - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS convolveMatrix.edgeMode.animVal is SVGFEConvolveMatrixElement.SVG_EDGEMODE_WRAP -PASS convolveMatrix.edgeMode.baseVal is SVGFEConvolveMatrixElement.SVG_EDGEMODE_WRAP -PASS convolveMatrix.edgeMode.animVal is SVGFEConvolveMatrixElement.SVG_EDGEMODE_DUPLICATE -PASS convolveMatrix.edgeMode.baseVal is SVGFEConvolveMatrixElement.SVG_EDGEMODE_WRAP -PASS convolveMatrix.edgeMode.animVal is SVGFEConvolveMatrixElement.SVG_EDGEMODE_DUPLICATE -PASS convolveMatrix.edgeMode.baseVal is SVGFEConvolveMatrixElement.SVG_EDGEMODE_WRAP -PASS convolveMatrix.edgeMode.animVal is SVGFEConvolveMatrixElement.SVG_EDGEMODE_NONE -PASS convolveMatrix.edgeMode.baseVal is SVGFEConvolveMatrixElement.SVG_EDGEMODE_WRAP -PASS convolveMatrix.edgeMode.animVal is SVGFEConvolveMatrixElement.SVG_EDGEMODE_NONE -PASS convolveMatrix.edgeMode.baseVal is SVGFEConvolveMatrixElement.SVG_EDGEMODE_WRAP -PASS convolveMatrix.edgeMode.animVal is SVGFEConvolveMatrixElement.SVG_EDGEMODE_WRAP -PASS convolveMatrix.edgeMode.baseVal is SVGFEConvolveMatrixElement.SVG_EDGEMODE_WRAP -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/svg/animations/svgenum-animation-2.html b/third_party/blink/web_tests/svg/animations/svgenum-animation-2.html deleted file mode 100644 index a191f168..0000000 --- a/third_party/blink/web_tests/svg/animations/svgenum-animation-2.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -<script src="resources/SVGTestCase.js"></script> -<script src="resources/SVGAnimationTestCase.js"></script> -</head> -<body onload="runSMILTest()"> -<h1>SVG 1.1 dynamic animation tests</h1> -<p id="description"></p> -<div id="console"></div> -<script src="script-tests/svgenum-animation-2.js"></script> -</body> -</html>
diff --git a/third_party/blink/web_tests/svg/css/opacity-not-supporting-percentage-expected.txt b/third_party/blink/web_tests/svg/css/opacity-not-supporting-percentage-expected.txt deleted file mode 100644 index f1c3400..0000000 --- a/third_party/blink/web_tests/svg/css/opacity-not-supporting-percentage-expected.txt +++ /dev/null
@@ -1,16 +0,0 @@ -Test opacity properties combined with percentage. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS CSS.supports("stroke-opacity", "0%") is false -PASS CSS.supports("stroke-opacity", "100%") is false -PASS CSS.supports("flood-opacity", "0%") is false -PASS CSS.supports("flood-opacity", "100%") is false -PASS CSS.supports("stop-opacity", "0%") is false -PASS CSS.supports("stop-opacity", "100%") is false -PASS CSS.supports("opacity", "0%") is false -PASS CSS.supports("opacity", "100%") is false -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/svg/css/opacity-not-supporting-percentage.html b/third_party/blink/web_tests/svg/css/opacity-not-supporting-percentage.html deleted file mode 100644 index ac7362c..0000000 --- a/third_party/blink/web_tests/svg/css/opacity-not-supporting-percentage.html +++ /dev/null
@@ -1,23 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> -<script src="../../resources/js-test.js"></script> -</head> -<body> -<script> - description("Test opacity properties combined with percentage."); - - shouldBeFalse('CSS.supports("stroke-opacity", "0%")'); - shouldBeFalse('CSS.supports("stroke-opacity", "100%")'); - - shouldBeFalse('CSS.supports("flood-opacity", "0%")'); - shouldBeFalse('CSS.supports("flood-opacity", "100%")'); - - shouldBeFalse('CSS.supports("stop-opacity", "0%")'); - shouldBeFalse('CSS.supports("stop-opacity", "100%")'); - - shouldBeFalse('CSS.supports("opacity", "0%")'); - shouldBeFalse('CSS.supports("opacity", "100%")'); -</script> -</body> -</html>
diff --git a/third_party/blink/web_tests/svg/custom/invalid-css.svg b/third_party/blink/web_tests/svg/custom/invalid-css.svg index 23734859a..a5994c6a 100644 --- a/third_party/blink/web_tests/svg/custom/invalid-css.svg +++ b/third_party/blink/web_tests/svg/custom/invalid-css.svg
@@ -16,7 +16,6 @@ stroke-dasharray: 10 5 10 auto; clip-path: url(#clip1) auto; clip-rule: evenodd auto; - opacity: 0%; /* does not seem supported yet */ visibility: hidden auto; } #circle {
diff --git a/third_party/blink/web_tests/virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-fullscreen-video.html b/third_party/blink/web_tests/virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-fullscreen-video.html index 212ec3d..783a3a6 100644 --- a/third_party/blink/web_tests/virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-fullscreen-video.html +++ b/third_party/blink/web_tests/virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-fullscreen-video.html
@@ -12,6 +12,9 @@ <script> let video = document.getElementById("video"); let button = document.getElementById("button"); + let fullscreened = new Promise((resolve) => { + document.addEventListener('fullscreenchange', resolve); + }); button.addEventListener('click', function() { video.requestFullscreen(); @@ -23,6 +26,13 @@ await snavCallback(); + await fullscreened; + + // snav state racily may have changed once or twice when fullscreen state + // changes. Waiting until a rAF after fullscreen changes should give snav + // state time to update properly. + await snav.rAF(); + assert_equals(window.internals.interestedElement, video, "Video element should have interest.");
diff --git a/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/README.txt b/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/README.txt new file mode 100644 index 0000000..de185c88 --- /dev/null +++ b/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/README.txt
@@ -0,0 +1 @@ +This directory is for testing Forced Colors mode implementation.
diff --git a/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-01-expected.html b/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-01-expected.html new file mode 100644 index 0000000..f8f9ce6 --- /dev/null +++ b/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-01-expected.html
@@ -0,0 +1,46 @@ +<!DOCTYPE html> +<html> +<head> +<style type="text/css"> + table { + border-collapse: collapse; + } + + td, th { + border: 1px solid; + border-bottom-color: WindowText; + border-left-color: WindowText; + border-right-color: WindowText; + border-top-color: WindowText; + forced-color-adjust: none; + padding: 8px; + text-align: left; + } + + tr:nth-child(even) { + background-color: Window; + color: WindowText; + forced-color-adjust: none; + } +</style> +</head> +<body> + <table> + <tr> + <th>Column1</th> + <th>Column2</th> + <th>Column3</th> + </tr> + <tr> + <td>Entry1</td> + <td>Entry1</td> + <td>Entry1</td> + </tr> + <tr> + <td>Entry2</td> + <td>Entry2</td> + <td>Entry2</td> + </tr> + </table> +</body> +</html>
diff --git a/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-02-expected.html b/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-02-expected.html new file mode 100644 index 0000000..c7078c36 --- /dev/null +++ b/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-02-expected.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<html> +<head> +<style type="text/css"> + body { + background-color: lightblue; + } + #a { + background-color: Window; + border: 25px solid WindowText; + box-shadow: 2px 2px Window; + color: WindowText; + forced-color-adjust: none; + margin: 25px; + padding: 25px; + text-shadow: 1px 1px Window; + width: 300px; + } + #b { + background-color: lightgreen; + border: 25px solid green; + box-shadow: 2px 2px purple; + color: orange; + forced-color-adjust: none; + margin: 25px; + padding: 25px; + text-shadow: 1px 1px gray; + width: 300px; + } +</style> +</head> +<body> + <div id="a"> + The colors and shadows of this text and text box should be overridden when in + forced colors mode (forced-color-adjust is set to auto.) + </div> + <div id="b"> + The colors and shadows of this text and text box should NOT be overridden when in + forced colors mode (forced-color-adjust is set to none.) + </div> +</body> +</html>
diff --git a/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-03-expected.txt b/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-03-expected.txt new file mode 100644 index 0000000..b497ff01 --- /dev/null +++ b/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-03-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +PASS Checks that default highlighted text style does not get overridden in forced colors mode. +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-04-expected.txt b/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-04-expected.txt new file mode 100644 index 0000000..26a63cd --- /dev/null +++ b/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-04-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +PASS Checks hyperlinks are overridden in forced colors mode. +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-05-expected.html b/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-05-expected.html new file mode 100644 index 0000000..083a735a --- /dev/null +++ b/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-05-expected.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> +<style type="text/css"> + a { + color: LinkText; + forced-color-adjust: none; + } +</style> +</head> +<body> + <p> + <a href="https://www.wikipedia.org" id="link"> + This link color should be overridden when forced colors mode is enabled. + </a> + </p> +</body> +</html>
diff --git a/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-06-expected.html b/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-06-expected.html new file mode 100644 index 0000000..ee78fcb --- /dev/null +++ b/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-06-expected.html
@@ -0,0 +1,7 @@ +<!DOCTYPE html> +<html> +<head> +<body> + <iframe src="forced-colors-mode-02-expected.html" width="500" height="500"></iframe> +</body> +</html>
diff --git a/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-07-expected.html b/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-07-expected.html new file mode 100644 index 0000000..aad20d16 --- /dev/null +++ b/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-07-expected.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<style> + p { + color: WindowText; + forced-color-adjust: none; + } + div { + forced-color-adjust: none; + } +</style> +<body> + <div style="background-color: Window;"> + <p> + The text color should be overridden, and the background color of the + div element should also be overridden in forced colors mode. + </p> + </div> + <div style="background-color: transparent;"> + <p> + The text color should be overridden, but the background color of the + div element should remain transparent in forced colors mode. + </p> + </div> + <div style="background-color: rgba(0, 0, 0, 0);"> + <p> + The text color should be overridden, but the background color of the + div element should remain transparent in forced colors mode. + </p> + </div> +</body> +</html>
diff --git a/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-08-expected.html b/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-08-expected.html new file mode 100644 index 0000000..b409f80 --- /dev/null +++ b/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-08-expected.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> +<head> +<style> + h1 { + forced-color-adjust: none; + outline-color: WindowText; + outline-style: solid; + -webkit-column-count: 3; + -webkit-column-gap: 40px; + -webkit-column-rule-color: WindowText; + -webkit-column-rule-style: solid; + } +</style> +</head> +<body> + <h1> + The outline-color and column-rule-color should be blue when forced colors + mode is off and WindowText in forced colors mode. + </h1> +</body> +</html>
diff --git a/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-09-expected.txt b/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-09-expected.txt new file mode 100644 index 0000000..22ecd5d --- /dev/null +++ b/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-09-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +PASS Checks that styles defined inside/outside forced-colors are overridden in forced colors mode. +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-10-expected.txt b/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-10-expected.txt new file mode 100644 index 0000000..cd96b903 --- /dev/null +++ b/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-10-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +PASS Checks that styles defined inside/outside forced-colors are preserved in forced colors mode if forced-color-ajust is none. +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-11-expected.txt b/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-11-expected.txt new file mode 100644 index 0000000..c1a32f8 --- /dev/null +++ b/third_party/blink/web_tests/virtual/forced-colors/fast/css/forced-colors-mode/forced-colors-mode-11-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +PASS Checks that styles defined in forced-colors are preserved in forced colors mode. +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt b/third_party/blink/web_tests/virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt index a9262980..7fede5d 100644 --- a/third_party/blink/web_tests/virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt +++ b/third_party/blink/web_tests/virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt
@@ -7,11 +7,9 @@ PASS Verify a cors worker script served by a service worker fails shared worker start. PASS Verify a no-cors cross-origin worker script served by a service worker fails dedicated worker start. PASS Verify a no-cors cross-origin worker script served by a service worker fails shared worker start. -PASS Register a service worker for worker subresource interception tests. PASS Requests on a dedicated worker controlled by a service worker. PASS Requests on a shared worker controlled by a service worker. -PASS Requests on a dedicated worker nested in a dedicated worker and controlled by a service worker +FAIL Requests on a dedicated worker nested in a dedicated worker and controlled by a service worker assert_equals: expected "This load was successfully intercepted." but got "{\"error\": {\"message\": \"\", \"code\": 404}}" FAIL Requests on a dedicated worker nested in a shared worker and controlled by a service worker assert_equals: expected "This load was successfully intercepted." but got "Unexpected error! Worker is not defined" -PASS Unregister a service worker for subresource interception tests. Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt index bd566dd..290b61c0 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -896,6 +896,10 @@ method keys method toMatrix method values +interface CSSTransition : Animation + attribute @@toStringTag + getter transitionProperty + method constructor interface CSSTranslate : CSSTransformComponent attribute @@toStringTag getter x
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-commit.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-commit.html new file mode 100644 index 0000000..564c452 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-commit.html
@@ -0,0 +1,49 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: acquire, commit</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="pass-container-with-child-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +#container { + contain: style layout; + width: 150px; + height: 150px; + background: lightblue; +} +#child { + width: 50px; + height: 50px; + background: lightgreen; +} +</style> + +<div id="log"></div> +<div id="container"></div> + +<script> +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + takeScreenshot(); +} + +function runTest() { + const container = document.getElementById("container"); + container.displayLock.acquire({ timeout: Infinity }).then(() => { + const child = document.createElement("div"); + child.id = "child"; + container.appendChild(child); + + container.displayLock.commit().then( + () => { finishTest("PASS"); }, + (e) => { finishTest("FAIL " + e.message); }); + }); +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-immediate-commit-resolves.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-immediate-commit-resolves.html new file mode 100644 index 0000000..ca88b181 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-immediate-commit-resolves.html
@@ -0,0 +1,49 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: acquire, immediate commit</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="pass-container-with-child-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +#container { + contain: style layout; + width: 150px; + height: 150px; + background: lightblue; +} +#child { + width: 50px; + height: 50px; + background: lightgreen; +} +</style> + +<div id="log"></div> +<div id="container"></div> + +<script> +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + takeScreenshot(); +} + +function runTest() { + const container = document.getElementById("container"); + container.displayLock.acquire({ timeout: Infinity }); + + const child = document.createElement("div"); + child.id = "child"; + container.appendChild(child); + + container.displayLock.commit().then( + () => { finishTest("PASS"); }, + (e) => { finishTest("FAIL " + e.message); }); +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-immediate-update-and-commit.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-immediate-update-and-commit.html new file mode 100644 index 0000000..08f175b --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-immediate-update-and-commit.html
@@ -0,0 +1,49 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: acquire, immediate updateAndCommit</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="pass-container-with-child-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +#container { + contain: style layout; + width: 150px; + height: 150px; + background: lightblue; +} +#child { + width: 50px; + height: 50px; + background: lightgreen; +} +</style> + +<div id="log"></div> +<div id="container"></div> + +<script> +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + takeScreenshot(); +} + +function runTest() { + const container = document.getElementById("container"); + container.displayLock.acquire({ timeout: Infinity }); + + const child = document.createElement("div"); + child.id = "child"; + container.appendChild(child); + + container.displayLock.updateAndCommit().then( + () => { finishTest("PASS"); }, + (e) => { finishTest("FAIL " + e.message); }); +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-in-breakable-div-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-in-breakable-div-ref.html new file mode 100644 index 0000000..deca548 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-in-breakable-div-ref.html
@@ -0,0 +1,21 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: acquire in div with columns</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<style> +#parent { + width: 100px; +} +#container { + border-top: solid green 50px; + border-bottom: solid green 50px; +} +</style> + +<div id="parent"> + <div id="container"></div> +</div> +
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-in-breakable-div.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-in-breakable-div.html new file mode 100644 index 0000000..d201d95 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-in-breakable-div.html
@@ -0,0 +1,37 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: acquire in div with columns</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="acquire-in-breakable-div-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +#container { + contain: style layout; + border-top: solid green 50px; + border-bottom: solid green 50px; +} +#parent { + columns: 2; + height: 0px; + width: 200px; + column-gap: 0; +} +</style> + +<div id="parent"> + <div id="container"></div> +</div> + +<script> +async function runTest() { + const container = document.getElementById("container"); + await container.displayLock.acquire({ timeout: Infinity }); + takeScreenshot(); +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-in-iframe-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-in-iframe-ref.html new file mode 100644 index 0000000..5cdb63b1 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-in-iframe-ref.html
@@ -0,0 +1,10 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: acquire in iframe (reference)</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<div id="log">PASS</div> +<iframe></iframe> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-in-iframe.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-in-iframe.html new file mode 100644 index 0000000..67dc437 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-in-iframe.html
@@ -0,0 +1,38 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: acquire in iframe</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="acquire-in-iframe-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<div id="log"></div> +<iframe id="frame" srcdoc=' + <style> + #container { + contain: style layout; + width: 100px; + height: 100px; + } + </style> + <div id="container">Lorem</div> +'></iframe> + +<script> +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + takeScreenshot(); +} + +function runTest() { + const container = document.getElementById("frame").contentDocument.getElementById("container"); + container.displayLock.acquire({ timeout: Infinity }).then( + () => { finishTest("PASS"); }, + (e) => { finishTest("FAIL " + e.message); }); +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-on-composited-layer.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-on-composited-layer.html new file mode 100644 index 0000000..7b356ce --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-on-composited-layer.html
@@ -0,0 +1,39 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: acquire on composited layer</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="pass-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +#container { + will-change: transform; + contain: style layout; + width: 150px; + height: 150px; +} +</style> + +<div id="log"></div> +<div id="container">Lorem ipsum</div> + +<script> +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + takeScreenshot(); +} + +function runTest() { + const container = document.getElementById("container"); + container.displayLock.acquire({ timeout: Infinity }).then( + () => { finishTest("PASS"); }, + (e) => { finishTest("FAIL " + e.message); } + ); +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-on-display-contents.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-on-display-contents.html new file mode 100644 index 0000000..41a7151 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-on-display-contents.html
@@ -0,0 +1,47 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: acquire, display:contents</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<body></body> +<script> +const REJECTION_MESSAGE = "Element has unsupported display type (display: contents)."; + +async_test(async (t) => { + let div = document.createElement("div"); + div.style = "display: contents; contain: style layout;"; + document.body.appendChild(div); + await div.displayLock.acquire({ timeout: Infinity }).then( + null, (e) => { + t.step(() => assert_equals(e.message, REJECTION_MESSAGE)); + t.done(); + }); +}, "Elements with display:contents can't be locked"); + +async_test(async (t) => { + let slot = document.createElement("slot"); + slot.style = "contain: style layout;"; + document.body.appendChild(slot); + await slot.displayLock.acquire({ timeout: Infinity }).then( + null, (e) => { + t.step(() => assert_equals(e.message, REJECTION_MESSAGE)); + t.done(); + }); +}, "<slot> can't be locked"); + +async_test(async (t) => { + let slot = document.createElement("slot"); + slot.style = "display: block; contain: style layout;"; + document.body.appendChild(slot); + await slot.displayLock.acquire({ timeout: Infinity }).then( + () => { + t.done(); + }); +}, "<slot> with changed display type can be locked"); +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-on-positioned-element.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-on-positioned-element.html new file mode 100644 index 0000000..d8c8542 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-on-positioned-element.html
@@ -0,0 +1,44 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: acquire, commit</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="pass-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +#container { + contain: style layout; + width: 150px; + height: 150px; + + position: absolute; + top: 0px; + left: 0px; +} +</style> + +<div id="log"></div> +<div id="container"></div> + +<script> +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + takeScreenshot(); +} + +function runTest() { + const container = document.getElementById("container"); + container.displayLock.acquire({ timeout: Infinity }).then(() => { + const child = document.createElement("div"); + document.body.appendChild(child); + + finishTest("PASS"); + }); +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-rejects-after-immediate-commit-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-rejects-after-immediate-commit-ref.html new file mode 100644 index 0000000..9a6718ef --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-rejects-after-immediate-commit-ref.html
@@ -0,0 +1,24 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: acquire rejects after quick commit (reference)</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<style> +#container { + contain: style layout; + width: 150px; + height: 150px; + background: lightblue; +} +#child { + width: 50px; + height: 50px; + background: lightgreen; +} +</style> + +<div id="log">PASS Lock commit was requested.</div> +<div id="container"><div id="child"></div></div> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-rejects-after-immediate-commit.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-rejects-after-immediate-commit.html new file mode 100644 index 0000000..0df6921 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-rejects-after-immediate-commit.html
@@ -0,0 +1,49 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: acquire rejects after quick commit</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="acquire-rejects-after-immediate-commit-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +#container { + contain: style layout; + width: 150px; + height: 150px; + background: lightblue; +} +#child { + width: 50px; + height: 50px; + background: lightgreen; +} +</style> + +<div id="log"></div> +<div id="container"></div> + +<script> +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + takeScreenshot(); +} + +function runTest() { + const container = document.getElementById("container"); + container.displayLock.acquire({ timeout: Infinity }).then( + () => { finishTest("FAIL"); }, + (e) => { finishTest("PASS " + e.message); }); + + const child = document.createElement("div"); + child.id = "child"; + container.appendChild(child); + + container.displayLock.commit(); +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-then-mark-for-reattach.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-then-mark-for-reattach.html new file mode 100644 index 0000000..fbf5014c8 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-then-mark-for-reattach.html
@@ -0,0 +1,45 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Display Locking: marking descendant for reattachment after acquire</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="pass-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<div id="log"></div> +<div id="host"><div id="slotted"></div></div> + +<script> +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + takeScreenshot(); +} + +function runTest() { + // Set up locked element within shadow root. + let shadowRoot = host.attachShadow({ mode: "open" }); + let locked = document.createElement("div"); + shadowRoot.appendChild(locked); + locked.style = "contain: style layout"; + locked.innerHTML = "<slot></slot>"; + locked.getBoundingClientRect(); + locked.displayLock.acquire({timeout: Infinity}); + + // Slotted will be recalced, because style dirtiness propagated + // to the DOM ancestor (host) instead of flat-tree (<slot>), and + // will trigger layout reattachment. + slotted.style = "display: none"; + // Do layout outside the locked subtree, shouldn't crash. + host.getBoundingClientRect(); + + // Check that everything is OK after we commit. + locked.displayLock.commit().then(() => { + locked.remove(); + finishTest("PASS"); + }); +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-update-disconnect-commit.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-update-disconnect-commit.html new file mode 100644 index 0000000..fa774cb84 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/acquire-update-disconnect-commit.html
@@ -0,0 +1,54 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: acquire, update, disconnect, commit</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="pass-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +#container { + contain: style layout; + width: 150px; + height: 150px; + background: lightblue; +} +#child { + width: 50px; + height: 50px; + background: lightgreen; +} +</style> + +<div id="log"></div> +<div id="container"></div> + +<script> +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + takeScreenshot(); +} + +function runTest() { + const container = document.getElementById("container"); + container.displayLock.acquire({ timeout: Infinity }).then(() => { + // Update, then disconnect the element, and commit. + const update_promise = container.displayLock.update(); + container.remove(); + const commit_promise = container.displayLock.commit(); + + // The update promise should reject and commit one should succeed. + Promise.all([ + new Promise((resolve, reject) => update_promise.then(reject, resolve)), + commit_promise + ]).then( + () => finishTest("PASS"), + () => finishTest("FAIL")); + }); +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/activatable-locked-element-allows-anchor-links-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/activatable-locked-element-allows-anchor-links-ref.html new file mode 100644 index 0000000..a743fd8 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/activatable-locked-element-allows-anchor-links-ref.html
@@ -0,0 +1,33 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: activatable allows anchor links (reference)</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<style> +.spacer { + width: 150px; + height: 3000px; + background: lightblue; +} +#container { + contain: style layout; + width: 150px; + height: 150px; + background: lightgreen; +} +#target { + width: 100px; + height: 100px; + background: green; +} +</style> + +<div class="spacer"></div> +<div id="container"><div id="target"></div></div> + +<script> +target.scrollIntoView(); +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/activatable-locked-element-allows-anchor-links.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/activatable-locked-element-allows-anchor-links.html new file mode 100644 index 0000000..2d7f7154 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/activatable-locked-element-allows-anchor-links.html
@@ -0,0 +1,43 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: activatable allows anchor links</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="activatable-locked-element-allows-anchor-links-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +.spacer { + width: 150px; + height: 3000px; + background: lightblue; +} +#container { + contain: style layout; + width: 150px; + height: 150px; + background: lightgreen; +} +#target { + width: 100px; + height: 100px; + background: green; +} +</style> + +<div class="spacer"></div> +<div id="container"><div id="target"></div></div> + +<script> +function runTest() { + const container = document.getElementById("container"); + container.displayLock.acquire({ timeout: Infinity, activatable: true }).then(() => { + location.href += "#target"; + requestAnimationFrame(takeScreenshot); + }); +} + +window.onload = () => { requestAnimationFrame(runTest); }; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/activate-commit-same-frame.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/activate-commit-same-frame.html new file mode 100644 index 0000000..4705208 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/activate-commit-same-frame.html
@@ -0,0 +1,55 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: activate commit same frame</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style> +.spacer { + width: 150px; + height: 3000px; + background: lightblue; +} +#container { + contain: style layout; + width: 150px; + height: 150px; + background: lightgreen; +} +#target { + width: 100px; + height: 100px; + background: green; +} +</style> + +<div class="spacer"></div> +<div id="container"><div id="target"></div></div> + +<script> +async_test((t) => { + async function runTest() { + let container = document.getElementById("container"); + + let acquire_promise = container.displayLock.acquire({ timeout: Infinity, activatable: true }); + await acquire_promise; + + target.scrollIntoView(); + let commit_promise = container.displayLock.commit(); + await commit_promise; + + t.step(() => assert_false(container.displayLock.locked, "context after commit & activation is unlocked")); + t.done(); + } + + window.onload = function() { + requestAnimationFrame(() => requestAnimationFrame(runTest)); + }; +}, "scrollIntoView and committing on the same frame should work"); + +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/activate-update-and-commit-same-frame.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/activate-update-and-commit-same-frame.html new file mode 100644 index 0000000..df12bd4 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/activate-update-and-commit-same-frame.html
@@ -0,0 +1,54 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: activate update+commit same frame</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style> +.spacer { + width: 150px; + height: 3000px; + background: lightblue; +} +#container { + contain: style layout; + width: 150px; + height: 150px; + background: lightgreen; +} +#target { + width: 100px; + height: 100px; + background: green; +} +</style> + +<div class="spacer"></div> +<div id="container"><div id="target"></div></div> + +<script> +async_test((t) => { + async function runTest() { + let container = document.getElementById("container"); + + let acquire_promise = container.displayLock.acquire({ timeout: Infinity, activatable: true }); + await acquire_promise; + + target.scrollIntoView(); + let update_and_commit_promise = container.displayLock.updateAndCommit(); + await update_and_commit_promise; + t.step(() => assert_false(container.displayLock.locked, "context after update & activation is unlocked")); + t.done(); + } + + window.onload = function() { + requestAnimationFrame(() => requestAnimationFrame(runTest)); + }; +}, "scrollIntoView and calling updateAndCommit on the same frame should work"); + +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/activate-update-same-frame.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/activate-update-same-frame.html new file mode 100644 index 0000000..4c37cb7 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/activate-update-same-frame.html
@@ -0,0 +1,54 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: activate update same frame</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style> +.spacer { + width: 150px; + height: 3000px; + background: lightblue; +} +#container { + contain: style layout; + width: 150px; + height: 150px; + background: lightgreen; +} +#target { + width: 100px; + height: 100px; + background: green; +} +</style> + +<div class="spacer"></div> +<div id="container"><div id="target"></div></div> + +<script> +async_test((t) => { + async function runTest() { + let container = document.getElementById("container"); + + let acquire_promise = container.displayLock.acquire({ timeout: Infinity, activatable: true }); + await acquire_promise; + + target.scrollIntoView(); + let update_promise = container.displayLock.update(); + await update_promise; + t.step(() => assert_false(container.displayLock.locked, "context after update & activation is unlocked")); + t.done(); + } + + window.onload = function() { + requestAnimationFrame(() => requestAnimationFrame(runTest)); + }; +}, "scrollIntoView and updating on the same frame should work"); + +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/anchor-links-ancestor.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/anchor-links-ancestor.html new file mode 100644 index 0000000..962e9c3a --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/anchor-links-ancestor.html
@@ -0,0 +1,82 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: anchor links via click</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + div { + contain: style layout; + } +</style> +<div id="outermost"> + Outermost + <div id="outer"> + Outer + <div id="inner"> + Inner + <div id="innermost"> + Innermost + </div> + </div> + </div> +</div> +<a id="innermostLink" href ="#innermost">Click</a> +<script> +'use strict'; +function prepareTest() { + return Promise.all([ + outer.displayLock.acquire({ timeout: Infinity, activatable: true }), + inner.displayLock.acquire({ timeout: Infinity, activatable: true }) + ]); +} + +promise_test(() => { + return new Promise((resolve, reject) => { + prepareTest().then(() => { + assert_false(outermost.displayLock.locked); + assert_true(outer.displayLock.locked); + assert_true(inner.displayLock.locked); + assert_false(innermost.displayLock.locked); + + let innerPromise = new Promise((resolve, reject) => { + inner.onbeforeactivate = (e) => { + assert_equals(e.activatedElement, innermost); + resolve(); + } + }); + + let outerPromise = new Promise((resolve, reject) => { + outer.onbeforeactivate = (e) => { + assert_equals(e.activatedElement, innermost); + // Resolve if this is directly targeted to #outer, + // instead of bubbling here. + if (e.target == outer) + resolve(); + } + }); + + let outermostPromise = new Promise((resolve, reject) => { + outermost.onbeforeactivate = (e) => { + assert_equals(e.activatedElement, innermost); + assert_not_equals(e.target, outermost); + // Resolve if this is targeted to #outer, which is + // dispatched after the event targeted to #inner. + if (e.target == outer) + resolve(); + } + }); + + innermost.onbeforeactivate = reject; + // Navigating to element in locked subtree should fire beforeactivate + // on locked ancestors, but not itself. + innermostLink.click(); + Promise.all([innerPromise, outerPromise, outermostPromise]).then(resolve); + }); + }); +}, "Activation through anchor link fires beforeactivate on locked ancestor"); +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/anchor-links.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/anchor-links.html new file mode 100644 index 0000000..99dab79 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/anchor-links.html
@@ -0,0 +1,47 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: anchor links</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + div { + contain: style layout; + } +</style> +<div id="outer"> + Outer + <div id="inner"> + Inner + <div id="innermost"> + Innermost + </div> + </div> +</div> +<a id="innerLink" href="#inner">Click</a> +<a id="innermostLink" href ="#innermost">Click</a> +<script> +'use strict'; +function prepareTest() { + innermost.onbeforeactivate = inner.onbeforeactivate = outer.onbeforeactivate = null; + return Promise.all([outer.displayLock.acquire({ timeout: Infinity, activatable: true }), + inner.displayLock.acquire({ timeout: Infinity, activatable: true })]); +} + +promise_test(() => { + return new Promise((resolve, reject) => { + prepareTest().then(() => { + assert_true(inner.displayLock.locked); + inner.onbeforeactivate = (e) => { + assert_equals(e.activatedElement, inner); + resolve(); + } + innerLink.click(); + }); + }); +}, "Activation through anchor link fires beforeactivate on locked element"); +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/commit-in-beforeactivate.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/commit-in-beforeactivate.html new file mode 100644 index 0000000..7f2b1f67 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/commit-in-beforeactivate.html
@@ -0,0 +1,38 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: commit in beforeactivate</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style> +div { + contain: style layout; +} +</style> +<div id="target"></div> + +<script> +'use strict'; + +async_test((t) => { + async function commit(target) { + target.displayLock.commit(); + t.done(); + } + + async function runTest() { + const target = document.getElementById("target"); + await target.displayLock.acquire({ timeout: Infinity, activatable: true }); + t.step(() => assert_true(target.displayLock.locked)); + + target.addEventListener("beforeactivate", () => commit(target)); + target.scrollIntoView(); + } + + window.onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +}, "Commit in beforeactivate"); +</script>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/focus-empty-layout.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/focus-empty-layout.html new file mode 100644 index 0000000..2a1e0b4 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/focus-empty-layout.html
@@ -0,0 +1,44 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: focus on new element</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<!-- +Focus on a div that doesn't have style/layout value yet. +--> + +<div id="container" style ="contain:style layout"> +</div> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script> +promise_test((t) => { + const acquirePromise = container.displayLock.acquire({ timeout: Infinity, activatable: true }); + return new Promise((resolve, reject) => { + const focusable = document.createElement("div"); + focusable.tabIndex = 0; + + const eventPromise = new Promise((resolve, reject) => { + container.onbeforeactivate = (e) => { + t.step(() => assert_equals(e.target, container)); + t.step(() => assert_equals(e.activatedElement, focusable)); + resolve(); + }; + }); + + acquirePromise.then(() => { + container.appendChild(focusable); + focusable.focus(); + eventPromise.then(() => { + t.step(() => assert_equals(document.activeElement, focusable)); + resolve(); + }); + }); + }); +}, "Activating locked element through tabindex navigation fires beforeactivate, focuses element"); +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/focus-next-updated-style.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/focus-next-updated-style.html new file mode 100644 index 0000000..b094677b --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/focus-next-updated-style.html
@@ -0,0 +1,38 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: focus on skipped element</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<!-- +Focus on a div that has updated style/layout. +--> + +<div id="container" style ="contain:style layout;"> + <div id="focusableA" tabindex="0">a</div> + <div id="focusableB" tabindex="0">b</div> +</div> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script> +promise_test((t) => { + const acquirePromise = container.displayLock.acquire({ timeout: Infinity, activatable: true }); + return new Promise((resolve, reject) => { + acquirePromise.then(() => { + focusableA.style = "display: none;"; + eventSender.keyDown("Tab", []); + t.step(() => assert_equals(document.activeElement, focusableB)); + eventSender.keyDown("Tab", []); + t.step(() => assert_equals(document.activeElement, focusableB)); + focusableA.style = "display: block;"; + eventSender.keyDown("Tab", []); + t.step(() => assert_equals(document.activeElement, focusableA)); + resolve(); + }); + }); +}, "Trying to focus on an element in a locked subtree that's not visible anymore will skip that element"); +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/focus-shadow.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/focus-shadow.html new file mode 100644 index 0000000..e4534906 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/focus-shadow.html
@@ -0,0 +1,48 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: focus shadow</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<div id="host"> + <input id="slotted" type="text"> +</div> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script> +promise_test((t) => { + const container = document.createElement("div"); + container.style = "contain: style layout;"; + container.innerHTML = "<slot></slot>"; + + const shadowRoot = host.attachShadow({ mode: "open" }); + shadowRoot.appendChild(container); + const acquirePromise = container.displayLock.acquire({ timeout: Infinity, activatable: true }); + + return new Promise((resolve, reject) => { + const eventPromise = new Promise((resolve, reject) => { + container.onbeforeactivate = (e) => { + t.step(() => assert_equals(e.target, container)); + t.step(() => assert_equals(e.activatedElement, slotted)); + resolve(); + }; + }); + host.onbeforeactivate = reject; + slotted.onbeforeactivate = reject; + + t.step(() => assert_not_equals(document.activeElement, slotted)); + acquirePromise.then(() => { + slotted.focus(); + + eventPromise.then(() => { + t.step(() => assert_equals(document.activeElement, slotted)); + resolve(); + }); + }); + }); +}, "Activating locked element through focus() fires beforeactivate, doesn't go through shadow boundary"); +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/focus-updated-style.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/focus-updated-style.html new file mode 100644 index 0000000..6964e7bb --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/focus-updated-style.html
@@ -0,0 +1,35 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: focus on styled element</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<!-- +Focus on a div that has updated style/layout. +--> + +<div id="container" style ="contain:style layout"> + <div id="focusable" tabIndex="0"> + focusable thing + </div> +</div> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script> +promise_test((t) => { + const acquirePromise = container.displayLock.acquire({ timeout: Infinity, activatable: true }); + return new Promise((resolve, reject) => { + acquirePromise.then(() => { + container.onbeforeactivate = reject; + focusable.style = "display: none"; + focusable.focus(); + t.step(() => assert_not_equals(document.activeElement, focusable)); + resolve(); + }); + }); +}, "Trying to focus on an element in a locked subtree that's not visible anymore won't work"); +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/focus.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/focus.html new file mode 100644 index 0000000..2389d44 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/focus.html
@@ -0,0 +1,39 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: focus via tab navigation</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<div id="container" style ="contain:style layout"> + <div id="focusable" tabIndex="0"> + Focusable div + </div> +</div> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script> +promise_test(() => { + const acquirePromise = container.displayLock.acquire({ timeout: Infinity, activatable: true }); + return new Promise((resolve, reject) => { + const eventPromise = new Promise((resolve, reject) => { + container.onbeforeactivate = (e) => { + assert_equals(e.target, container); + assert_equals(e.activatedElement, focusable); + resolve(); + }; + }); + + acquirePromise.then(() => { + eventSender.keyDown("Tab", ["shiftKey"]); + eventPromise.then(() => { + assert_equals(document.activeElement, focusable); + resolve(); + }); + }); + }); +}, "Activating locked element through tabindex navigation fires beforeactivate, focuses element"); +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/locked-element-focus.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/locked-element-focus.html new file mode 100644 index 0000000..c01558b2 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/locked-element-focus.html
@@ -0,0 +1,43 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: </title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<div id="container" style ="contain:style layout"> + <div id="focusable" tabIndex="0"> + Focusable div + </div> +</div> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script> +async_test((t) => { + + async function focusNonActivatableTest() { + const acquire_promise = container.displayLock.acquire({ timeout: Infinity }); + await acquire_promise; + t.step(() => assert_not_equals(document.activeElement, focusable)); + focusable.focus(); + t.step(() => assert_not_equals(document.activeElement, focusable)); + focusActivatableTest(); + } + + async function focusActivatableTest() { + t.step(() => assert_not_equals(document.activeElement, focusable)); + const acquire_promise = container.displayLock.acquire({ timeout: Infinity, activatable: true }); + await acquire_promise; + focusable.focus(); + t.step(() => assert_equals(document.activeElement, focusable)); + t.done(); + } + + window.onload = function() { + requestAnimationFrame(() => requestAnimationFrame(focusNonActivatableTest)); + }; +}, "Testing focus and force layout on element with locked flat-tree ancestor"); +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/locked-element-prevents-anchor-links.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/locked-element-prevents-anchor-links.html new file mode 100644 index 0000000..f0f3582 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/locked-element-prevents-anchor-links.html
@@ -0,0 +1,43 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: anchor links prevented</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="spacer-and-container-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +.spacer { + width: 150px; + height: 3000px; + background: lightblue; +} +#container { + contain: style layout; + width: 150px; + height: 150px; + background: lightgreen; +} +#target { + width: 100px; + height: 100px; + background: green; +} +</style> + +<div class="spacer"></div> +<div id="container"><div id="target"></div></div> + +<script> +function runTest() { + const container = document.getElementById("container"); + container.displayLock.acquire({ timeout: Infinity, size: [150, 150] }).then(() => { + location.href += "#target"; + requestAnimationFrame(takeScreenshot); + }); +} + +window.onload = () => { requestAnimationFrame(runTest); }; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/locked-element-prevents-scroll-into-view.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/locked-element-prevents-scroll-into-view.html new file mode 100644 index 0000000..66e71f4 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/locked-element-prevents-scroll-into-view.html
@@ -0,0 +1,43 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: scrollIntoView prevented</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="spacer-and-container-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +.spacer { + width: 150px; + height: 3000px; + background: lightblue; +} +#container { + contain: style layout; + width: 150px; + height: 150px; + background: lightgreen; +} +#target { + width: 100px; + height: 100px; + background: green; +} +</style> + +<div class="spacer"></div> +<div id="container"><div id="target"></div></div> + +<script> +function runTest() { + const container = document.getElementById("container"); + container.displayLock.acquire({ timeout: Infinity, size: [150, 150] }).then(() => { + document.getElementById("target").scrollIntoView(); + requestAnimationFrame(takeScreenshot); + }); +} + +window.onload = () => { requestAnimationFrame(runTest); }; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/scroll-into-view-beforeactivate.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/scroll-into-view-beforeactivate.html new file mode 100644 index 0000000..c5aa628 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/scroll-into-view-beforeactivate.html
@@ -0,0 +1,81 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: scrollIntoView event</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + div { + contain: style layout; + } +</style> +<div id="outermost"> + Outermost + <div id="outer"> + Outer + <div id="inner"> + Inner + <div id="innermost"> + Innermost + </div> + </div> + </div> +</div> +<script> +'use strict'; +function prepareTest() { + return Promise.all([ + outer.displayLock.acquire({ timeout: Infinity, activatable: true }), + inner.displayLock.acquire({ timeout: Infinity, activatable: true }) + ]); +} + +promise_test(() => { + return new Promise((resolve, reject) => { + prepareTest().then(() => { + assert_false(outermost.displayLock.locked); + assert_true(outer.displayLock.locked); + assert_true(inner.displayLock.locked); + assert_false(innermost.displayLock.locked); + + let innerPromise = new Promise((resolve, reject) => { + inner.onbeforeactivate = (e) => { + assert_equals(e.activatedElement, innermost); + resolve(); + } + }); + + let outerPromise = new Promise((resolve, reject) => { + outer.onbeforeactivate = (e) => { + assert_equals(e.activatedElement, innermost); + // Resolve if this is directly targeted to #outer, + // instead of bubbling here. + if (e.target == outer) + resolve(); + } + }); + + let outermostPromise = new Promise((resolve, reject) => { + outermost.onbeforeactivate = (e) => { + assert_equals(e.activatedElement, innermost); + assert_not_equals(e.target, outermost); + // Resolve if this is targeted to #outer, which is + // dispatched after the event targeted to #inner. + if (e.target == outer) + resolve(); + } + }); + + innermost.onbeforeactivate = reject; + // Navigating to element in locked subtree should fire beforeactivate + // on locked ancestors, but not itself. + innermost.scrollIntoView(); + Promise.all([innerPromise, outerPromise, outermostPromise]).then(resolve); + }); + }); +}, "Activation through scrollIntoView fires beforeactivate on locked ancestor"); +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/scroll-into-view-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/scroll-into-view-ref.html new file mode 100644 index 0000000..ce0e0b6 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/scroll-into-view-ref.html
@@ -0,0 +1,39 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: scrollIntoView (reference)</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<script src="/common/reftest-wait.js"></script> + +<style> +.spacer { + width: 150px; + height: 3000px; + background: lightblue; +} +#container { + contain: style layout; + width: 150px; + height: 150px; + background: lightgreen; +} +#target { + width: 100px; + height: 100px; + background: green; +} +</style> + +<div class="spacer"></div> +<div id="container"><div id="target"></div></div> + +<script> +function runTest() { + document.getElementById("target").scrollIntoView(); + requestAnimationFrame(takeScreenshot); +} + +window.onload = () => { requestAnimationFrame(runTest); }; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/scroll-into-view.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/scroll-into-view.html new file mode 100644 index 0000000..5882138 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/scroll-into-view.html
@@ -0,0 +1,43 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: scrollIntoView</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="scroll-into-view-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +.spacer { + width: 150px; + height: 3000px; + background: lightblue; +} +#container { + contain: style layout; + width: 150px; + height: 150px; + background: lightgreen; +} +#target { + width: 100px; + height: 100px; + background: green; +} +</style> + +<div class="spacer"></div> +<div id="container"><div id="target"></div></div> + +<script> +function runTest() { + const container = document.getElementById("container"); + container.displayLock.acquire({ timeout: Infinity, activatable: true }).then(() => { + document.getElementById("target").scrollIntoView(); + requestAnimationFrame(takeScreenshot); + }); +} + +window.onload = () => { requestAnimationFrame(runTest); }; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/spacer-and-container-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/spacer-and-container-ref.html new file mode 100644 index 0000000..73980d2d --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/activation/spacer-and-container-ref.html
@@ -0,0 +1,23 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: spacer and a container (reference)</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<style> +.spacer { + width: 150px; + height: 3000px; + background: lightblue; +} +#container { + contain: style layout; + width: 150px; + height: 150px; +} +</style> + +<div class="spacer"></div> +<div id="container"></div> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/commit-immediate-acquire-resolves-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/commit-immediate-acquire-resolves-ref.html new file mode 100644 index 0000000..d55ac961 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/commit-immediate-acquire-resolves-ref.html
@@ -0,0 +1,19 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: commit, quick acquire (reference)</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<style> +#container { + contain: style layout; + width: 150px; + height: 150px; + background: lightblue; +} +</style> + +<div id="log">PASS</div> +<div id="container"></div> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/commit-immediate-acquire-resolves.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/commit-immediate-acquire-resolves.html new file mode 100644 index 0000000..6f6fda38 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/commit-immediate-acquire-resolves.html
@@ -0,0 +1,48 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: commit, quick acquire</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="commit-immediate-acquire-resolves-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +#container { + contain: style layout; + width: 150px; + height: 150px; + background: lightblue; +} +#child { + width: 50px; + height: 50px; + background: lightgreen; +} +</style> + +<div id="log"></div> +<div id="container"></div> + +<script> +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + takeScreenshot(); +} + +function runTest() { + const container = document.getElementById("container"); + container.displayLock.acquire({ timeout: Infinity }).then(() => { + container.displayLock.commit(); + container.displayLock.acquire({ timeout: Infinity }).then(() => { + container.displayLock.commit().then( + () => { finishTest("PASS"); }, + (e) => { finishTest("FAIL " + e.message); }); + }); + }); +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/containment/acquire-changed-containment.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/containment/acquire-changed-containment.html new file mode 100644 index 0000000..c1ef658f --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/containment/acquire-changed-containment.html
@@ -0,0 +1,45 @@ +<!doctype html> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: acquire, containment changes</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="pass-no-containment-with-child-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +#container { + width: 150px; + height: 150px; + background: lightblue; +} +#child { + width: 50px; + height: 50px; + background: lightgreen; +} +</style> + +<div id="log"></div> +<div id="container" style="contain: style layout;"><div id="child" style="display: none;"></div></div> + +<script> +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + takeScreenshot(); +} + +function runTest() { + const container = document.getElementById("container"); + // Recalc child and container when acquiring. + container.style = ""; + child.style = ""; + container.displayLock.acquire({ timeout: Infinity }).then( + () => { finishTest("FAIL"); }, + (e) => { finishTest("PASS " + e.message); }); +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/containment/acquire-on-added-containment-after-acquire.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/containment/acquire-on-added-containment-after-acquire.html new file mode 100644 index 0000000..b2cae3a --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/containment/acquire-on-added-containment-after-acquire.html
@@ -0,0 +1,40 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: acquire, then add containment</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="acquire-on-added-containment-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +#container { + width: 150px; + height: 150px; +} +.contained { + contain: style layout; +} +</style> + +<div id="log"></div> +<div id="container">foo</div> + +<script> +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + takeScreenshot(); +} + +function runTest() { + const container = document.getElementById("container"); + container.displayLock.acquire({ timeout: Infinity }).then( + () => { finishTest("PASS"); }, + (e) => { finishTest("FAIL " + e.message); }); + container.classList = "contained"; +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/containment/acquire-on-added-containment-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/containment/acquire-on-added-containment-ref.html new file mode 100644 index 0000000..1802299 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/containment/acquire-on-added-containment-ref.html
@@ -0,0 +1,17 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: acquire on added containment (reference)</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<style> +#container { + width: 150px; + height: 150px; +} +</style> + +<div id="log">PASS</div> +<div id="container"></div> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/containment/acquire-on-added-containment.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/containment/acquire-on-added-containment.html new file mode 100644 index 0000000..f875978 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/containment/acquire-on-added-containment.html
@@ -0,0 +1,45 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: acquire after added containment</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="acquire-on-added-containment-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +#container { + width: 150px; + height: 150px; +} +.contained { + contain: style layout; +} +#child { + width: 50px; + height: 50px; + background: lightgreen; +} +</style> + +<div id="log"></div> +<div id="container">Lorem</div> + +<script> +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + takeScreenshot(); +} + +function runTest() { + const container = document.getElementById("container"); + container.classList = "contained"; + container.displayLock.acquire({ timeout: Infinity }).then( + () => { finishTest("PASS"); }, + (e) => { finishTest("FAIL " + e.message); }); +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/containment/acquire-on-no-containment.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/containment/acquire-on-no-containment.html new file mode 100644 index 0000000..52711d3 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/containment/acquire-on-no-containment.html
@@ -0,0 +1,37 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: acquire, no containment</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="pass-no-containment-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +#container { + width: 150px; + height: 150px; + background: lightblue; +} +</style> + +<div id="log"></div> +<div id="container"></div> + +<script> +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + takeScreenshot(); +} + +function runTest() { + const container = document.getElementById("container"); + container.displayLock.acquire({ timeout: Infinity }).then( + () => { finishTest("FAIL"); }, + (e) => { finishTest("PASS " + e.message); }); +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/containment/nested-containment.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/containment/nested-containment.html new file mode 100644 index 0000000..d64beb1 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/containment/nested-containment.html
@@ -0,0 +1,86 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: containment checks with nested locks</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<body> +<style> +.lockable, .parentOfLockable > div { + contain: style layout; +} +.randomClass > div { + color: red; +} +</style> +<script> +function forceLayout(el) { + el.offsetTop; +} + +function createParentAndChild() { + let parent = document.createElement("div"); + let child = document.createElement("div"); + parent.appendChild(child); + document.body.appendChild(parent); + parent.classList.add("lockable"); + forceLayout(child); + return parent; +} + +async_test(async(t) => { + let parent = createParentAndChild(); + let child = parent.firstChild; + await parent.displayLock.acquire({timeout: Infinity}); + t.step(() => assert_equals(parent.displayLock.locked, true)); + + let childPromise = child.displayLock.acquire({timeout: Infinity}); + childPromise.then(() => { + t.step(() => assert_equals(child.displayLock.locked, true)); + t.done(); + }); +}, "Nested locked element with clean style should not enforce containment requirement"); + +async_test(async(t) => { + let parent = createParentAndChild(); + let child = parent.firstChild; + await parent.displayLock.acquire({timeout: Infinity}); + t.step(() => assert_equals(parent.displayLock.locked, true)); + + // Will mark #child for style recalc. + parent.classList.add("randomClass"); + let childPromise = child.displayLock.acquire({timeout: Infinity}); + childPromise.then(() => { + // Lifecycle update has finished but since #child is within a locked subtree, + // its style is still dirty and we keep it locked. + t.step(() => assert_equals(child.displayLock.locked, true)); + forceLayout(child); + // Gets unlocked after forced recalc on #child. + t.step(() => assert_equals(child.displayLock.locked, false)); + t.done(); + }); +}, "Nested locked element that needs recalc should not enforce containment requirement"); + +async_test(async(t) => { + let parent = createParentAndChild(); + let child = parent.firstChild; + await parent.displayLock.acquire({timeout: Infinity}); + t.step(() => assert_equals(parent.displayLock.locked, true)); + + // Will mark #child for style recalc. + parent.classList.add("parentOfLockable"); + let childPromise = child.displayLock.acquire({timeout: Infinity}); + childPromise.then(() => { + t.step(() => assert_equals(child.displayLock.locked, true)); + forceLayout(child); + // Is still locked after forced recalc on #child because of added containment. + t.step(() => assert_equals(child.displayLock.locked, true)); + t.done(); + }); +}, "Nested locked element recalcs correctly when forced"); +</script> +</body>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/containment/pass-no-containment-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/containment/pass-no-containment-ref.html new file mode 100644 index 0000000..9cce14b2 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/containment/pass-no-containment-ref.html
@@ -0,0 +1,18 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: pass, no containment (reference)</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<style> +#container { + width: 150px; + height: 150px; + background: lightblue; +} +</style> + +<div id="log">PASS Containment requirement is not satisfied.</div> +<div id="container"></div> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/containment/pass-no-containment-with-child-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/containment/pass-no-containment-with-child-ref.html new file mode 100644 index 0000000..00127f4 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/containment/pass-no-containment-with-child-ref.html
@@ -0,0 +1,24 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: pass, container with child</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<style> +#container { + contain: style layout; + width: 150px; + height: 150px; + background: lightblue; +} +#child { + width: 50px; + height: 50px; + background: lightgreen; +} +</style> + +<div id="log">PASS Containment requirement is not satisfied.</div> +<div id="container"><div id="child"></div></div> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/delayed-acquire-removes-painted-output-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/delayed-acquire-removes-painted-output-ref.html new file mode 100644 index 0000000..a959aed --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/delayed-acquire-removes-painted-output-ref.html
@@ -0,0 +1,23 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: acquire removes paint (reference)</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<style> +#container { + contain: style layout; + width: 150px; + height: 150px; +} +#checker { + width: 50px; + height: 50px; + background: green; +} +</style> + +<div id="container"></div> +<div id="checker"></div> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/delayed-acquire-removes-painted-output.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/delayed-acquire-removes-painted-output.html new file mode 100644 index 0000000..0f945d4 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/delayed-acquire-removes-painted-output.html
@@ -0,0 +1,51 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: acquire removes paint</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="delayed-acquire-removes-painted-output-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +#container { + contain: style layout; + width: 150px; + height: 150px; +} +#checker { + width: 50px; + height: 50px; + background: green; +} +#child1 { + width: 100%; + height: 30px; + background: red; +} +#child2 { + contain: layout; + width: 100%; + height: 30px; + background: red; +} +</style> + +<div id="container"> + Lorem ipsum + <div id="child1">regular child</div> + <div id="child2">new formatting context child</div> +</div> +<div id="checker"></div> + +<script> +function runTest() { + const container = document.getElementById("container"); + container.displayLock.acquire({ timeout: Infinity, size: [150, 150] }).then(takeScreenshot); +} + +window.onload = () => { + requestAnimationFrame(() => requestAnimationFrame(runTest)); +}; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/inner-text.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/inner-text.html new file mode 100644 index 0000000..2a06aec --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/inner-text.html
@@ -0,0 +1,34 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: innerText</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style> +#container { + contain: style layout; +} +</style> + +This text should be visible. +<div id="container"> + This text should not be visible. + <div id="inner"> + This text is also not visible. + </div> +</div> + +<script> +promise_test(async () => { + const container = document.getElementById("container"); + await container.displayLock.acquire({ timeout: Infinity }); + + assert_equals(document.body.innerText, "This text should be visible."); + assert_equals(document.getElementById("inner").innerText, ""); +}, "innerText on locked element."); +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/intersection-observer.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/intersection-observer.html new file mode 100644 index 0000000..1787f6f --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/intersection-observer.html
@@ -0,0 +1,180 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: intersection observer interactions</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style> +div { + contain: style layout; + width: 100px; + height: 100px; +} +#spacer { + height: 3000px; +} +</style> + +<div id="target1"> + <div id="target2"></div> +</div> +<div id="target3"> + <div id="target4"></div> +</div> +<div id="spacer"></div> +<div id="find_me"></div> + +<script> +async_test((t) => { + let target1, target2, target3, target4; + let observer; + let entries = []; + + // Set everything up. + function enqueueStep1() { + target1 = document.getElementById("target1"); + target2 = document.getElementById("target2"); + target3 = document.getElementById("target3"); + target4 = document.getElementById("target4"); + + observer = new IntersectionObserver((new_entries) => { + entries = entries.concat(new_entries); + }); + observer.observe(target1); + observer.observe(target2); + observer.observe(target3); + observer.observe(target4); + + entries = entries.concat(observer.takeRecords()); + t.step(() => { assert_equals(entries.length, 0, "No initial notifications") }); + requestAnimationFrame(() => { + requestAnimationFrame(() => { + runStep1(); + }); + }); + } + + // Verify that all elements are visible at the start, with intersection events. + function runStep1() { + const step = arguments.callee.name; + t.step(() => { + assert_equals(entries.length, 4, step); + // Clear the observed visible targets. + for (let i = 0; i < entries.length; ++i) { + assert_true(entries[i].isIntersecting); + assert_true(entries[i].target === target1 || + entries[i].target === target2 || + entries[i].target === target3 || + entries[i].target === target4, step); + } + }); + + entries = []; + enqueueStep2(); + } + + // Lock target3. + async function enqueueStep2() { + await target3.displayLock.acquire({ timeout: Infinity }); + requestAnimationFrame(() => { + requestAnimationFrame(() => { + runStep2(); + }); + }); + } + + // Verify that the locked element received a not-intersecting event. + function runStep2() { + const step = arguments.callee.name; + t.step(() => { + assert_equals(entries.length, 1, step); + assert_false(entries[0].isIntersecting, step); + assert_equals(entries[0].target, target4, step); + }); + + entries = []; + enqueueStep3(); + } + + // Scroll all elements off screen. + function enqueueStep3() { + document.getElementById("find_me").scrollIntoView(); + requestAnimationFrame(() => { + requestAnimationFrame(() => { + runStep3(); + }); + }); + } + + // Verify that all elements received not intersecting event, except + // target4, which was already not intersecting due to being locked. + function runStep3() { + const step = arguments.callee.name; + t.step(() => { + assert_equals(entries.length, 3, step); + for (let i = 0; i < entries.length; ++i) { + assert_false(entries[i].isIntersecting, step); + assert_not_equals(entries[i].target, target4, step); + } + }); + + entries = []; + enqueueStep4(); + } + + // Scroll the elements back on screen. + function enqueueStep4() { + target1.scrollIntoView(); + requestAnimationFrame(() => { + requestAnimationFrame(() => { + runStep4(); + }); + }); + } + + // Verify that all elements received not intersecting event, except + // target4, which remains not intersecting. + function runStep4() { + const step = arguments.callee.name; + t.step(() => { + assert_equals(entries.length, 3, step); + for (let i = 0; i < entries.length; ++i) { + assert_true(entries[i].isIntersecting); + assert_not_equals(entries[i].target, target4, step); + } + }); + + entries = []; + enqueueStep5(); + } + + // Unlock target3. + async function enqueueStep5() { + await target3.displayLock.commit(); + requestAnimationFrame(() => { + requestAnimationFrame(() => { + runStep5(); + }); + }); + } + + function runStep5() { + const step = arguments.callee.name; + t.step(() => { + assert_equals(entries.length, 1, step); + assert_true(entries[0].isIntersecting, step); + assert_equals(entries[0].target, target4, step); + }); + t.done(); + } + + + window.onload = () => { + requestAnimationFrame(enqueueStep1); + }; +}, "IntersectionObserver interactions"); +</script>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/lock-crossorigin-iframe-and-change-size.sub.https.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/lock-crossorigin-iframe-and-change-size.sub.https.html new file mode 100644 index 0000000..42910776 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/lock-crossorigin-iframe-and-change-size.sub.https.html
@@ -0,0 +1,25 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: locks an iframe, and changes its size</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="lock-iframe-and-change-size-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +iframe { + contain: style layout; +} +</style> +<iframe id="frame" width=200 height=200 src='https://{{domains[www]}}:{{ports[https][0]}}/wpt_internal/display-lock/paint/resources/frame.html'></iframe> + +<script> +async function runTest() { + await document.getElementById("frame").displayLock.acquire({ timeout: Infinity }); + document.getElementById("frame").height = 300; + requestAnimationFrame(takeScreenshot); +} + +onload = () => { requestAnimationFrame(runTest); }; +</script>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/lock-iframe-and-change-size-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/lock-iframe-and-change-size-ref.html new file mode 100644 index 0000000..19e8920 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/lock-iframe-and-change-size-ref.html
@@ -0,0 +1,10 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: locks an iframe, and changes its size (reference)</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<iframe width=200 height=300></iframe> +</html> +
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/lock-iframe-and-change-size.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/lock-iframe-and-change-size.html new file mode 100644 index 0000000..b22c7175 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/lock-iframe-and-change-size.html
@@ -0,0 +1,25 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: locks an iframe, and changes its size</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="lock-iframe-and-change-size-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +iframe { + contain: style layout; +} +</style> +<iframe id=frame width=200 height=200 srcdoc='Lorem ipsum'></iframe> + +<script> +async function runTest() { + await document.getElementById("frame").displayLock.acquire({ timeout: Infinity }); + document.getElementById("frame").height = 300; + requestAnimationFrame(takeScreenshot); +} + +onload = () => { requestAnimationFrame(runTest); }; +</script>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/locked-attribute.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/locked-attribute.html new file mode 100644 index 0000000..2f893ff0 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/locked-attribute.html
@@ -0,0 +1,51 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: locked attribute</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<style> +#container { + contain: style layout; +} +</style> + +<div id="container"></div> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script> +async_test((t) => { + async function runTest() { + const container = document.getElementById("container"); + t.step(() => assert_false(container.displayLock.locked, "initial context is unlocked")); + + const acquire_promise = container.displayLock.acquire({ timeout: Infinity }); + t.step(() => assert_true(container.displayLock.locked, "context before acquire finishes is locked")); + + await acquire_promise; + t.step(() => assert_true(container.displayLock.locked, "context after acquire finishes is locked")); + + const update_promise = container.displayLock.update(); + t.step(() => assert_true(container.displayLock.locked, "context during update is locked")); + + await update_promise; + t.step(() => assert_true(container.displayLock.locked, "context after update is locked")); + + const commit_promise = container.displayLock.commit(); + t.step(() => assert_false(container.displayLock.locked, "context during commit is unlocked")); + + await commit_promise; + t.step(() => assert_false(container.displayLock.locked, "context after commit is unlocked")); + + t.done(); + } + + window.onload = function() { + requestAnimationFrame(() => requestAnimationFrame(runTest)); + }; +}, "locked attribute"); +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/locked-element-shifted-down-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/locked-element-shifted-down-ref.html new file mode 100644 index 0000000..0b5affa --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/locked-element-shifted-down-ref.html
@@ -0,0 +1,30 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: locked element shifted down (reference)</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<style> +#container { + contain: style layout; + width: 150px; + height: 150px; +} +#spacer { + width: 100px; + height: 100px; + background: lightgreen; +} +#checker { + width: 100px; + height: 50px; + background: green; +} +</style> + +<div id="log">PASS</div> +<div id="spacer"></div> +<div id="container"></div> +<div id="checker"></div> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/locked-element-shifted-down.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/locked-element-shifted-down.html new file mode 100644 index 0000000..4eccf68ce --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/locked-element-shifted-down.html
@@ -0,0 +1,50 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: locked element shifted down</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="locked-element-shifted-down-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +#container { + contain: style layout; + width: 150px; + height: 150px; +} +#spacer { + width: 100px; + height: 50px; + background: lightgreen; +} +#checker { + width: 100px; + height: 50px; + background: green; +} +</style> + +<div id="log"></div> +<div id="spacer"></div> +<div id="container">Lorem</div> +<div id="checker"></div> + +<script> +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + takeScreenshot(); +} + +function runTest() { + const container = document.getElementById("container"); + container.displayLock.acquire({ timeout: Infinity, size: [150, 150] }).then(() => { + document.getElementById("spacer").style.height = "100px"; + finishTest("PASS"); + }); +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/locked-shadow-descendant.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/locked-shadow-descendant.html new file mode 100644 index 0000000..64c595d0 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/locked-shadow-descendant.html
@@ -0,0 +1,55 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: locked shadow descendant</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<div id="host"> + <input id="slotted" type="text"> +</div> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script> +let container = document.createElement("div"); +container.style = "contain: style layout;"; +container.innerHTML = "<slot></slot>"; + +let shadowRoot = host.attachShadow({ mode: "open" }); +shadowRoot.appendChild(container); + +async_test((t) => { + async function focusTest() { + t.step(() => assert_not_equals(document.activeElement, slotted)); + t.step(() => assert_not_equals(shadowRoot.activeElement, slotted)); + + const acquire_promise = container.displayLock.acquire({ timeout: Infinity }); + await acquire_promise; + + t.step(() => assert_not_equals(document.activeElement, slotted)); + t.step(() => assert_not_equals(shadowRoot.activeElement, slotted)); + + slotted.focus(); + t.step(() => assert_not_equals(document.activeElement, slotted)); + t.step(() => assert_not_equals(shadowRoot.activeElement, slotted)); + + forceLayoutTest(); + } + + async function forceLayoutTest() { + t.step(() => assert_equals(slotted.offsetTop, 0)); + // Add a 20px div above the slotted div. + container.innerHTML = "<div style='height: 20px;'></div><slot></slot>"; + t.step(() => assert_equals(slotted.offsetTop, 20)); + t.done(); + } + + window.onload = function() { + requestAnimationFrame(() => requestAnimationFrame(focusTest)); + }; +}, "Testing focus and force layout on element with locked flat-tree ancestor"); + +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/locked-style.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/locked-style.html new file mode 100644 index 0000000..bd563333 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/locked-style.html
@@ -0,0 +1,60 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: style on locked element & child</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<style> +#container { + contain: style layout; +} +</style> + +<div id="container"> + <div id="child"> + <div id="grandchild"></div> + </div> +</div> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script> +async_test((t) => { + async function runTest() { + let container = document.getElementById("container"); + await container.displayLock.acquire({ timeout: Infinity }); + + container.style = "color: blue;"; + t.step(() => assert_equals(getComputedStyle(container).color, "rgb(0, 0, 255)", "container color changed to blue")); + t.step(() => assert_equals(getComputedStyle(child).color, "rgb(0, 0, 255)", "child inherits blue color")); + t.step(() => assert_equals(getComputedStyle(grandchild).color, "rgb(0, 0, 255)", "grandchild inherits blue color")); + + child.style = "color: green;"; + t.step(() => assert_equals(getComputedStyle(container).color, "rgb(0, 0, 255)", "container color is still blue")); + t.step(() => assert_equals(getComputedStyle(child).color, "rgb(0, 128, 0)", "child color changed to green")); + t.step(() => assert_equals(getComputedStyle(grandchild).color, "rgb(0, 128, 0)", "grandchild inherits green color")); + + // Commit container, lock child. + await container.displayLock.commit(); + child.style = "contain: style layout"; + await child.displayLock.acquire({ timeout: Infinity }); + + // Update style outside of the locked subtree. + container.style = "color: red;"; + container.offsetTop; + + // Inheritance works as usual through locked boundaries. + t.step(() => assert_equals(getComputedStyle(grandchild).color, "rgb(255, 0, 0)", "grandchild inherits red color")); + t.step(() => assert_equals(getComputedStyle(child).color, "rgb(255, 0, 0)", "child inherits red color")); + t.step(() => assert_equals(getComputedStyle(container).color, "rgb(255, 0, 0)", "container color changed to red")); + + t.done(); + } + + window.onload = function() { + requestAnimationFrame(() => requestAnimationFrame(runTest)); + }; +}, "getComputedStyle gets up-to-date style"); +</script> +
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/nested-acquire.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/nested-acquire.html new file mode 100644 index 0000000..e88e3efc --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/nested-acquire.html
@@ -0,0 +1,56 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: nested acquire</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="pass-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +.container { + contain: style layout; +} +#outer { + width: 100px; + height: 100px; +} +#inner { + width: 50px; + height: 50px; + background: lightgreen; +} +div > div > div { + width: 10px; + height: 10px; + background: red; +} +</style> + +<div id="log"></div> +<div id="outer" class="container"> + <div id="inner" class="container"></div> +</div> + +<script> +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + takeScreenshot(); +} + +async function runTest() { + const outer = document.getElementById("outer"); + const inner = document.getElementById("inner"); + + await outer.displayLock.acquire({ timeout: Infinity }); + // Dirty the inner layout + inner.appendChild(document.createElement("div")); + inner.displayLock.acquire().then( + () => { finishTest("PASS"); }, + (e) => { finishTest("FAIL " + e.message); }); +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/nested-commit.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/nested-commit.html new file mode 100644 index 0000000..c6cb976 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/nested-commit.html
@@ -0,0 +1,58 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: nested commit</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="pass-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +.container { + contain: style layout; +} +#outer { + width: 100px; + height: 100px; +} +#inner { + width: 50px; + height: 50px; + background: lightgreen; +} +div > div > div { + width: 10px; + height: 10px; + background: red; +} +</style> + +<div id="log"></div> +<div id="outer" class="container"> + <div id="inner" class="container"></div> +</div> + +<script> +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + takeScreenshot(); +} + +async function runTest() { + const outer = document.getElementById("outer"); + const inner = document.getElementById("inner"); + + await Promise.all([ + outer.displayLock.acquire({ timeout: Infinity }), + inner.displayLock.acquire({ timeout: Infinity })]); + // Dirty the inner layout + inner.appendChild(document.createElement("div")); + inner.displayLock.commit().then( + () => { finishTest("PASS"); }, + (e) => { finishTest("FAIL " + e.message); }); +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/nested-update-and-commit.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/nested-update-and-commit.html new file mode 100644 index 0000000..a2ff170 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/nested-update-and-commit.html
@@ -0,0 +1,60 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: nested updateAndCommit</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="pass-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +.container { + contain: style layout; +} +#outer { + width: 100px; + height: 100px; +} +#inner { + width: 50px; + height: 50px; + background: lightgreen; +} +div > div > div { + width: 10px; + height: 10px; + background: red; +} +</style> + +<div id="log"></div> +<div id="outer" class="container"> + <div id="inner" class="container"></div> +</div> + +<script> +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + takeScreenshot(); +} + +function runTest() { + const outer = document.getElementById("outer"); + const inner = document.getElementById("inner"); + + Promise.all([ + outer.displayLock.acquire({ timeout: Infinity }), + inner.displayLock.acquire({ timeout: Infinity })]) + .then(() => { + // Dirty the inner layout + inner.appendChild(document.createElement("div")); + inner.displayLock.updateAndCommit().then( + () => { finishTest("PASS"); }, + (e) => { finishTest("FAIL " + e.message); }); + }); +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/nested-update-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/nested-update-ref.html new file mode 100644 index 0000000..01c35a0 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/nested-update-ref.html
@@ -0,0 +1,9 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: nested update (reference)</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<div id="log">PASS Element is nested under a locked element.</div> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/nested-update.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/nested-update.html new file mode 100644 index 0000000..d22d7c4 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/nested-update.html
@@ -0,0 +1,58 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: nested update</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="nested-update-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +.container { + contain: style layout; +} +#outer { + width: 100px; + height: 100px; +} +#inner { + width: 50px; + height: 50px; + background: lightgreen; +} +div > div > div { + width: 10px; + height: 10px; + background: red; +} +</style> + +<div id="log"></div> +<div id="outer" class="container"> + <div id="inner" class="container"></div> +</div> + +<script> +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + takeScreenshot(); +} + +async function runTest() { + const outer = document.getElementById("outer"); + const inner = document.getElementById("inner"); + + await Promise.all([ + outer.displayLock.acquire({ timeout: Infinity }), + inner.displayLock.acquire({ timeout: Infinity })]); + // Dirty the inner layout + inner.appendChild(document.createElement("div")); + inner.displayLock.update().then( + () => { finishTest("FAIL"); }, + (e) => { finishTest("PASS " + e.message); }); +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/pass-container-with-child-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/pass-container-with-child-ref.html new file mode 100644 index 0000000..df8fbf42 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/pass-container-with-child-ref.html
@@ -0,0 +1,24 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: pass, container with child (reference)</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<style> +#container { + contain: style layout; + width: 150px; + height: 150px; + background: lightblue; +} +#child { + width: 50px; + height: 50px; + background: lightgreen; +} +</style> + +<div id="log">PASS</div> +<div id="container"><div id="child"></div></div> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/pass-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/pass-ref.html new file mode 100644 index 0000000..2df7d74c --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/pass-ref.html
@@ -0,0 +1,9 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: pass (reference)</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<div id="log">PASS</div> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-after-resize-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-after-resize-ref.html new file mode 100644 index 0000000..977d9fd --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-after-resize-ref.html
@@ -0,0 +1,24 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: acquire after resizing (reference)</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<style> +#container { + contain: style layout; + width: 150px; + height: 150px; +} +#spacer { + width: 50px; + height: 50px; + background: lightgreen; +} +</style> + +<div id="log">PASS</div> +<div id="container"></div> +<div id="spacer"></div> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-after-resize.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-after-resize.html new file mode 100644 index 0000000..04d5dab4 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/acquire-after-resize.html
@@ -0,0 +1,41 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: acquire after resizing</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="acquire-after-resize-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +.contained { + contain: style layout; +} +#spacer { + width: 50px; + height: 50px; + background: lightgreen; +} +</style> + +<div id="log"></div> +<div id="small" class="contained">Lorem ipsum</div> +<div id="spacer"> + +<script> +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + takeScreenshot(); +} + +function runTest() { + const container = document.getElementById("small"); + container.displayLock.acquire({ timeout: Infinity, size: [150, 150] }).then( + () => { finishTest("PASS"); }, + (e) => { finishTest("FAIL " + e.message); }); +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-with-child-lock-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-with-child-lock-ref.html new file mode 100644 index 0000000..d7d6511 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-with-child-lock-ref.html
@@ -0,0 +1,29 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: flex layout with child lock (reference)</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<style> +#flexer { + display: flex; + width: 200px; + height: 300px; + background: lightgreen; +} +#container { + background: lightblue; +} +#sizer { + width: 123px; + height: 234px; +} +</style> + +<div id="flexer"> + <div id="container"> + <div id="sizer"></div> + </div> +</div> +
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-with-child-lock.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-with-child-lock.html new file mode 100644 index 0000000..0a9af37 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-with-child-lock.html
@@ -0,0 +1,38 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: flex layout with child lock</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="flex-with-child-lock-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +#flexer { + display: flex; + width: 200px; + height: 300px; + background: lightgreen; +} +#container { + contain: style layout; + background: lightblue; +} +</style> + +<div id="flexer"> + <div id="container"> + <div></div> + </div> +</div> + +<script> +async function runTest() { + const container = document.getElementById("container"); + await container.displayLock.acquire({ timeout: Infinity, size: [123, 234] }); + takeScreenshot(); +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-with-descendant-lock-ref.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-with-descendant-lock-ref.html new file mode 100644 index 0000000..48a09b8 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-with-descendant-lock-ref.html
@@ -0,0 +1,31 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: flex layout with descendant lock (reference)</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<style> +#flexer { + display: flex; + width: 200px; + height: 300px; + background: lightgreen; +} +#container { + background: lightblue; +} +#sizer { + width: 123px; + height: 234px; +} +</style> + +<div id="flexer"> + <div> + <div id="container"> + <div id="sizer"></div> + </div> + </div> +</div> +
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-with-descendant-lock.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-with-descendant-lock.html new file mode 100644 index 0000000..471d9df --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/flex-with-descendant-lock.html
@@ -0,0 +1,40 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: flex layout with descendant lock</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="flex-with-descendant-lock-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +#flexer { + display: flex; + width: 200px; + height: 300px; + background: lightgreen; +} +#container { + contain: style layout; + background: lightblue; +} +</style> + +<div id="flexer"> + <div> + <div id="container"> + <div></div> + </div> + </div> +</div> + +<script> +async function runTest() { + const container = document.getElementById("container"); + await container.displayLock.acquire({ timeout: Infinity, size: [123, 234] }); + takeScreenshot(); +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/get-bounding-client-rect-block-layout-in-iframe.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/get-bounding-client-rect-block-layout-in-iframe.html new file mode 100644 index 0000000..bdab4eb6 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/get-bounding-client-rect-block-layout-in-iframe.html
@@ -0,0 +1,68 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: getBoundingClientRect on block layout</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style> +#container { + contain: style layout; + width: 123px; + height: 234px; +} +#frame { + padding: 0; + margin: 0; + width: 500px; + height: 500px; +} +</style> +<body> +<div id="container"> + <iframe id="frame" frameborder=0 srcdoc=' + <style> + body { + padding: 0; + margin: 0; + } + #target { + background: lightgreen; + width: 50%; + height: 50px; + } + </style> + <div id="target"></div> + '></iframe> +</div> + +<script> +let load_promise = new Promise((resolve) => { + window.onload = resolve; +}); + +async_test(async(t) => { + await load_promise; + + const container = document.getElementById("container"); + await container.displayLock.acquire({ timeout: Infinity }); + + const frame = document.getElementById("frame"); + frame.style.width = "224px"; + frame.style.height = "248px"; + + const target = frame.contentDocument.getElementById("target"); + t.step(() => assert_true(!!target, "sanity check that target exists")); + let rect = target.getBoundingClientRect(); + t.step(() => assert_equals(rect.width, 112, "target uses update frame size for width")); + t.step(() => assert_equals(rect.height, 50, "target uses set size for height")); + + t.done(); +}, "getBoundingClientRect in iframe"); + +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/get-bounding-client-rect-block-layout.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/get-bounding-client-rect-block-layout.html new file mode 100644 index 0000000..bbe152d5 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/get-bounding-client-rect-block-layout.html
@@ -0,0 +1,113 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: getBoundingClientRect on block layout</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style> +div { + contain: style layout; +} +</style> +<body> +<script> +const BODY_WIDTH = document.body.getBoundingClientRect().width; +const ACQUIRE_WIDTH = 33; +const ACQUIRE_HEIGHT = 44; + +async_test(async(t) => { + let container = document.createElement("div"); + container.style = "width: min-content;"; + let child = document.createElement("div"); + container.appendChild(child); + document.body.appendChild(container); + await container.displayLock.acquire({ timeout: Infinity, size: [ACQUIRE_WIDTH, ACQUIRE_HEIGHT] }); + + let rect = container.getBoundingClientRect(); + t.step(() => assert_equals(rect.width, ACQUIRE_WIDTH, + "Locked element with min-content uses width from acquire()")); + t.step(() => assert_equals(rect.height, ACQUIRE_HEIGHT, + "Locked element with min-content uses height from acquire()")); + + rect = child.getBoundingClientRect(); + t.step(() => assert_equals(rect.width, ACQUIRE_WIDTH, + "Child of locked element with min-content uses width from acquire()")); + t.step(() => assert_equals(rect.height, 0, + "Child of locked element with min-content & no content has zero height")); + + child.style = "width: 100px; height: 200px;"; + rect = container.getBoundingClientRect(); + t.step(() => assert_equals(rect.width, ACQUIRE_WIDTH, + "Locked element with min-content and sized child uses width from acquire()")); + t.step(() => assert_equals(rect.height, ACQUIRE_HEIGHT, + "Locked element with min-content and sized child uses height from acquire()")); + rect = child.getBoundingClientRect(); + t.step(() => assert_equals(rect.width, 100, + "Child of locked element with min-content uses width from style")); + t.step(() => assert_equals(rect.height, 200, + "Child of locked element with min-content uses height from style")); + + t.done(); +}, "getBoundingClientRect with min-content"); + +async_test(async(t) => { + let container = document.createElement("div"); + document.body.appendChild(container); + await container.displayLock.acquire({ timeout: Infinity, size: [ACQUIRE_WIDTH, ACQUIRE_HEIGHT] }); + let rect = container.getBoundingClientRect(); + + t.step(() => assert_equals(rect.width, BODY_WIDTH, + "Locked element uses width from body")); + t.step(() => assert_equals(rect.height, ACQUIRE_HEIGHT, + "Locked element uses height from acquire()")); + + await container.displayLock.acquire({ timeout: Infinity, size: [55, 66] }); + rect = container.getBoundingClientRect(); + t.step(() => assert_equals(rect.width, BODY_WIDTH, + "After re-acquire, locked element still uses width from body")); + t.step(() => assert_equals(rect.height, 66, + "After re-acquire, locked element uses height from the last acquire()")); + t.done(); +}, "getBoundingClientRect with re-acquire"); + +async_test(async (t) => { + let container = document.createElement("div"); + container.style = "width: 11px; height: 22px;"; + let child = document.createElement("div"); + container.appendChild(child); + document.body.appendChild(container); + + await container.displayLock.acquire({ timeout: Infinity, size: [ACQUIRE_WIDTH, ACQUIRE_HEIGHT] }); + + let rect = container.getBoundingClientRect(); + t.step(() => assert_equals(rect.width, 11, + "Styled locked element uses width from style")); + t.step(() => assert_equals(rect.height, 22, + "Styled locked element uses height from style")); + rect = child.getBoundingClientRect(); + t.step(() => assert_equals(rect.width, 11, + "Child of styled locked element uses width from locked element's style")); + t.step(() => assert_equals(rect.height, 0, + "Child of styled locked element with no content has zero height")); + + container.style = ""; + rect = container.getBoundingClientRect(); + t.step(() => assert_equals(rect.width, BODY_WIDTH, + "Unstyled locked element uses width from body")); + t.step(() => assert_equals(rect.height, ACQUIRE_HEIGHT, + "Unstyled locked element uses height given in acquire()")); + + rect = child.getBoundingClientRect(); + t.step(() => assert_equals(rect.width, BODY_WIDTH, + "Child of unstyled locked element uses width from locked element's width")); + t.step(() => assert_equals(rect.height, 0, + "Child of unstyled locked element with no content has zero height")); + t.done(); +}, "getBoundingClientRect with styled width & height"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/measure-forced-layout-after-commit.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/measure-forced-layout-after-commit.html new file mode 100644 index 0000000..0cb1d21 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/measure-forced-layout-after-commit.html
@@ -0,0 +1,92 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: measure forced layout after commit</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<style> +.contained { + contain: style layout; + background: lightgreen; +} +#large { + width: 200px; + height: 200px; +} +.child { + width: 20px; + height: 20%; + background: cyan; +} +#spacer { + width: 150px; + height: 150px; + background: green; +} +</style> + +<div id="parent"><div class="contained" id="small"><div id="large"></div></div></div> +<div id="spacer"></div> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script> +async_test((t) => { + function createChild(id) { + const child = document.createElement("div"); + child.classList = "child"; + child.id = id; + return child; + } + + function measureForced() { + t.step(() => { + // Ensure children are laid out; this forces a layout. + assert_equals(document.getElementById("0").offsetTop, 0, "0 forced"); + assert_equals(document.getElementById("1").offsetTop, 40, "1 forced"); + assert_equals(document.getElementById("2").offsetTop, 80, "2 forced"); + // Parent should be 100 height, since its child is locked. + assert_equals(document.getElementById("parent").offsetTop, 8, "parent forced"); + assert_equals(document.getElementById("spacer").offsetTop, 108, "spacer forced"); + }); + } + + function forcedMeasureAfterCommit() { + t.step(() => { + // Ensure children are still laid out. + assert_equals(document.getElementById("0").offsetTop, 0, "0 in commit"); + assert_equals(document.getElementById("1").offsetTop, 40, "1 in commit"); + assert_equals(document.getElementById("2").offsetTop, 80, "2 in commit"); + // Now the parent should encompass an unlocked container, so spacer is pushed down more. + assert_equals(document.getElementById("parent").offsetTop, 8, "parent in commit"); + assert_equals(document.getElementById("spacer").offsetTop, 208, "spacer in commit"); + }); + } + + function construct(container) { + container.appendChild(createChild("0")); + container.appendChild(createChild("1")); + container.appendChild(createChild("2")); + } + + async function runTest() { + const container = document.getElementById("small"); + await container.displayLock.acquire({ timeout: Infinity, size: [100, 100] }); + + construct(document.getElementById("large")); + measureForced(); + + container.displayLock.commit(); + forcedMeasureAfterCommit(); + t.done(); + } + + window.onload = function() { + requestAnimationFrame(() => requestAnimationFrame(runTest)); + }; +}, "Measure Forced Layout"); +</script> + +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/measure-forced-layout.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/measure-forced-layout.html new file mode 100644 index 0000000..ef16011 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/measure-forced-layout.html
@@ -0,0 +1,93 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: measure forced layout</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<style> +.contained { + contain: style layout; + background: lightgreen; +} +#large { + width: 200px; + height: 200px; +} +.child { + width: 20px; + height: 20%; + background: cyan; +} +#spacer { + width: 150px; + height: 150px; + background: green; +} +</style> + +<div id="parent"><div class="contained" id="small"><div id="large"></div></div></div> +<div id="spacer"></div> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script> +async_test((t) => { + function createChild(id) { + const child = document.createElement("div"); + child.classList = "child"; + child.id = id; + return child; + } + + function measureForced() { + t.step(() => { + // Ensure children are laid out; this forces a layout. + assert_equals(document.getElementById("0").offsetTop, 0, "0 forced"); + assert_equals(document.getElementById("1").offsetTop, 40, "1 forced"); + assert_equals(document.getElementById("2").offsetTop, 80, "2 forced"); + // Parent should be 100 height, since its child is locked. + assert_equals(document.getElementById("parent").offsetTop, 8, "parent forced"); + assert_equals(document.getElementById("spacer").offsetTop, 108, "spacer forced"); + }); + } + + function measureInCommit() { + t.step(() => { + // Ensure children are still laid out. + assert_equals(document.getElementById("0").offsetTop, 0, "0 in commit"); + assert_equals(document.getElementById("1").offsetTop, 40, "1 in commit"); + assert_equals(document.getElementById("2").offsetTop, 80, "2 in commit"); + // Now the parent should encompass an unlocked container, so spacer is pushed down more. + assert_equals(document.getElementById("parent").offsetTop, 8, "parent in commit"); + assert_equals(document.getElementById("spacer").offsetTop, 208, "spacer in commit"); + }); + } + + function construct(container) { + container.appendChild(createChild("0")); + container.appendChild(createChild("1")); + container.appendChild(createChild("2")); + } + + async function runTest() { + const container = document.getElementById("small"); + await container.displayLock.acquire({ timeout: Infinity, size: [100, 100] }); + + construct(document.getElementById("large")); + measureForced(); + + container.displayLock.commit().then(() => { + measureInCommit(); + t.done(); + }); + } + + window.onload = function() { + requestAnimationFrame(() => requestAnimationFrame(runTest)); + }; +}, "Measure Forced Layout"); +</script> + +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/measure-updated-layout.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/measure-updated-layout.html new file mode 100644 index 0000000..3d2d94a --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/measure-updated-layout.html
@@ -0,0 +1,95 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Display Locking: measure updated layout</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> + +<style> +.contained { + contain: style layout; + background: lightgreen; +} +#large { + width: 200px; + height: 200px; +} +.child { + width: 20px; + height: 20%; + background: cyan; +} +#spacer { + width: 150px; + height: 150px; + background: green; +} +</style> + +<div id="parent"><div class="contained" id="small"><div id="large"></div></div></div> +<div id="spacer"></div> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script> +async_test((t) => { + function createChild(id) { + const child = document.createElement("div"); + child.classList = "child"; + child.id = id; + return child; + } + + function construct(container) { + container.appendChild(createChild("0")); + container.appendChild(createChild("1")); + container.appendChild(createChild("2")); + } + + function measureInUpdate() { + t.step(() => { + // Ensure children are laid out; this forces a layout. + assert_equals(document.getElementById("0").offsetTop, 0, "0 in update"); + assert_equals(document.getElementById("1").offsetTop, 40, "1 in update"); + assert_equals(document.getElementById("2").offsetTop, 80, "2 in update"); + // Parent should be 100 height, since its child is locked. + assert_equals(document.getElementById("parent").offsetTop, 8, "parent in update"); + assert_equals(document.getElementById("spacer").offsetTop, 108, "spacer in update"); + }); + } + + function measureInCommit() { + t.step(() => { + // Ensure children are still laid out. + assert_equals(document.getElementById("0").offsetTop, 0, "0 in commit"); + assert_equals(document.getElementById("1").offsetTop, 40, "1 in commit"); + assert_equals(document.getElementById("2").offsetTop, 80, "2 in commit"); + // Now the parent should encompass the unlocked container, so spacer is pushed down further. + assert_equals(document.getElementById("parent").offsetTop, 8, "parent in commit"); + assert_equals(document.getElementById("spacer").offsetTop, 208, "spacer in commit"); + }); + } + + async function runTest() { + const container = document.getElementById("small"); + await container.displayLock.acquire({ timeout: Infinity, size: [100, 100] }); + + construct(document.getElementById("large")); + + container.displayLock.update().then(() => { + measureInUpdate(); + container.displayLock.commit().then(() => { + measureInCommit(); + t.done(); + }); + }); + } + + window.onload = function() { + requestAnimationFrame(() => requestAnimationFrame(runTest)); + }; +}, "Measure Updated Layout"); +</script> + +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/reacquire-different-size.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/reacquire-different-size.html new file mode 100644 index 0000000..e95a8b2 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/sizing/reacquire-different-size.html
@@ -0,0 +1,47 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: re-acquire with a different size</title> +<link rel="author" title="Rakina Zata Amni" href="mailto:rakina@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="acquire-after-resize-ref.html"> +<script src="/common/reftest-wait.js"></script> + +<style> +.contained { + contain: style layout; +} +#spacer { + width: 50px; + height: 50px; + background: lightgreen; +} +</style> + +<div id="log"></div> +<div id="small" class="contained"></div> +<div id="spacer"> + +<script> +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + takeScreenshot(); +} + +function runTest() { + const container = document.getElementById("small"); + container.displayLock.acquire({ timeout: Infinity, size: [123, 456] }).then( + () => { + // Re-acquire with a different size. + container.displayLock.acquire({ timeout: Infinity, size: [150, 150] }).then( + () => { finishTest("PASS"); }, + (e) => { finishTest("FAIL " + e.message); }); + }, + (e) => { finishTest("FAIL " + e.message); } + ); +} + +window.onload = runTest; +</script> +</html>
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium index 4910e0f..22a5996 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-10-1-7-gad3443c93 -Revision: ad3443c93121c59181fc4b46c5179d0d00bfcc4e +Version: VER-2-10-1-8-g734d60f63 +Revision: 734d60f63cfa27f9b337ddbb80adb9edd60475bf License: Custom license "inspired by the BSD, Artistic, and IJG (Independent JPEG Group) licenses" License File: src/docs/FTL.TXT
diff --git a/third_party/webxr_test_pages/OWNERS b/third_party/webxr_test_pages/OWNERS index 8bff5847..d06b118 100644 --- a/third_party/webxr_test_pages/OWNERS +++ b/third_party/webxr_test_pages/OWNERS
@@ -1,6 +1,7 @@ alcooper@chromium.org bajones@chromium.org bialpio@chromium.org +jacde@chromium.org klausw@chromium.org # TEAM: xr-dev@chromium.org
diff --git a/third_party/webxr_test_pages/webxr-samples/gamepad.html b/third_party/webxr_test_pages/webxr-samples/gamepad.html index cb0f1c7d..dd373a1 100644 --- a/third_party/webxr_test_pages/webxr-samples/gamepad.html +++ b/third_party/webxr_test_pages/webxr-samples/gamepad.html
@@ -171,22 +171,20 @@ } if (gamepad.mapping == "xr-standard") { - // Invert the y axis because gamepads follow the convention that -1 - // is up/forwards, but we want to have a forward joystick/touchpad - // input result in forward motion for the box. + if (gamepad.buttons.length >= 3 && gamepad.axes.length >= 2) { + // Handle touchpad movement. + // Invert the y axis because gamepads follow the convention that -1 + // is up/forwards, but we want to have a forward joystick/touchpad + // input result in forward motion for the box. + let dx = gamepad.axes[0]; + let dy = -gamepad.axes[1]; + this.boxes[2].move(dx, dy); + } - // xr-standard Gamepads always have at least one touchpad/joystick. - // Its button will always be in the second slot. - let dx = gamepad.axes[0]; - let dy = -gamepad.axes[1]; - this.boxes[1].move(dx, dy); - - if (gamepad.axes.length >= 4 && gamepad.buttons.length >= 4) { - // If an xr-standard Gamepad has a secondary touchpad/joystick, its - // button will be in the 4th slot and it will use the second pair - // of input axes. - dx = gamepad.axes[2]; - dy = -gamepad.axes[3]; + if (gamepad.buttons.length >= 4 && gamepad.axes.length >= 4) { + // Handle thumbstick movement. + let dx = gamepad.axes[2]; + let dy = -gamepad.axes[3]; this.boxes[3].move(dx, dy); } }
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 3ce86a3c..5d1c3ca4 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -198,6 +198,7 @@ 'chromeos-amd64-generic-rel-vm-tests': 'cros_chrome_sdk_headless_ozone_dcheck_always_on', 'chromeos-kevin-rel-hw-tests': 'cros_chrome_sdk_headless_ozone', 'chromeos-vm-code-coverage': 'cros_chrome_sdk_headless_ozone_coverage', + 'linux-bfcache-rel': 'release_bot_minimal_symbols', 'linux-chromeos-code-coverage': 'chromeos_with_codecs_release_bot_coverage', 'linux-chromeos-oobe-code-coverage': 'chromeos_with_codecs_release_bot_coverage', 'linux-fieldtrial-rel': 'release_bot_minimal_symbols', @@ -740,6 +741,7 @@ 'gpu-fyi-try-linux-intel-dqp': 'deqp_release_trybot', 'gpu-fyi-try-linux-intel-exp': 'gpu_fyi_tests_release_trybot', 'gpu-fyi-try-linux-intel-rel': 'gpu_fyi_tests_release_trybot', + 'gpu-fyi-try-linux-intel-skv': 'gpu_fyi_tests_release_trybot', 'gpu-fyi-try-linux-nvidia-dbg': 'gpu_fyi_tests_debug_trybot', 'gpu-fyi-try-linux-nvidia-dqp': 'deqp_release_trybot', 'gpu-fyi-try-linux-nvidia-exp': 'gpu_fyi_tests_release_trybot', @@ -1972,7 +1974,7 @@ }, 'cast': { - 'gn_args': 'is_chromecast=true', + 'gn_args': 'is_chromecast=true use_v4l2=true', }, 'cast_audio': {
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 987b99f..de5217a 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -20251,6 +20251,8 @@ <int value="1364" label="ACTION_DISABLE"/> <int value="1365" label="FILEMANAGERPRIVATEINTERNAL_IMPORTCROSTINIIMAGE"/> <int value="1366" label="AUTOTESTPRIVATE_GETSHELFITEMS"/> + <int value="1367" label="MANAGEMENT_INSTALLREPLACEMENTANDROIDAPP"/> + <int value="1368" label="MANAGEMENT_CANINSTALLREPLACEMENTANDROIDAPP"/> </enum> <enum name="ExtensionIconState"> @@ -20629,7 +20631,7 @@ <int value="59" label="kEnterprisePlatformKeysPrivate"/> <int value="60" label="kDeleted_ExperienceSamplingPrivate"/> <int value="61" label="kExperimental"/> - <int value="62" label="kExtensionView"/> + <int value="62" label="kDeleted_ExtensionView"/> <int value="63" label="kExternallyConnectableAllUrls"/> <int value="64" label="kFeedbackPrivate"/> <int value="65" label="kFileBrowserHandler"/> @@ -30171,12 +30173,20 @@ </enum> <enum name="IDBKeyPathType"> + <obsolete> + Removed August 2019. Was added to measure use of features which not all + actively developed browser engines supported. No longer relevant. + </obsolete> <int value="0" label="None">No key path.</int> <int value="1" label="String">Key path is a string.</int> <int value="2" label="Array">Key path is an array of strings.</int> </enum> <enum name="IDBKeyType"> + <obsolete> + Removed August 2019. Was added to measure use of features which not all + actively developed browser engines supported. No longer relevant. + </obsolete> <int value="0" label="Invalid">Invalid key.</int> <int value="1" label="Array">Key is an array.</int> <int value="2" label="Binary">Key is a binary buffer.</int> @@ -34121,6 +34131,7 @@ <int value="-2058762785" label="AllowDownloadResumptionWithoutStrongValidators:disabled"/> <int value="-2058656447" label="ContextualSearchUrlActions:enabled"/> + <int value="-2056351013" label="AutofillUpdatedCardUnmaskPromptUi:enabled"/> <int value="-2054612904" label="BuiltInModuleInfra:enabled"/> <int value="-2053860791" label="XGEOVisibleNetworks:enabled"/> <int value="-2048927838" label="AutoplayWhitelistSettings:enabled"/> @@ -35332,8 +35343,6 @@ <int value="-428599163" label="NTPDownloadSuggestions:enabled"/> <int value="-426815606" label="HomepageTile:enabled"/> <int value="-424701311" label="SignedHTTPExchange:disabled"/> - <int value="-424544273" - label="enable-experimental-accessibility-chromevox-rich-text-indication"/> <int value="-424134004" label="WebPaymentsExperimentalFeatures:disabled"/> <int value="-418868128" label="enable-experimental-web-platform-features"/> <int value="-416660617" label="EnforceTLS13Downgrade:disabled"/> @@ -35473,6 +35482,7 @@ <int value="-234687894" label="NonValidatingReloadOnRefreshContentV2:disabled"/> <int value="-234231190" label="SharingDeviceRegistration:enabled"/> + <int value="-231967261" label="AutofillUpdatedCardUnmaskPromptUi:disabled"/> <int value="-231922000" label="enable-renderer-mojo-channel"/> <int value="-231426350" label="AutofillEnableToolbarStatusChip:enabled"/> <int value="-230824955" label="NTPMostLikelyFaviconsFromServer:enabled"/> @@ -38962,6 +38972,12 @@ <int value="1" label="Has errors"/> </enum> +<enum name="MediaPlayerWatchTimeType"> + <int value="0" label="Non-HLS"/> + <int value="1" label="HLS audio-only"/> + <int value="2" label="HLS video"/> +</enum> + <enum name="MediaRecorderVEAUsed"> <int value="0" label="Not used"/> <int value="1" label="Used"/> @@ -47271,9 +47287,9 @@ <int value="1" label="Local-Memory Failure"/> <int value="2" label="Mapped-File Success"/> <int value="3" label="Mapped-File Failure"/> - <int value="5" label="Mapped-File Already Exists"/> - <int value="6" label="No Spare File"/> - <int value="7" label="Could Not Create Upload Directory"/> + <int value="4" label="Mapped-File Already Exists"/> + <int value="5" label="No Spare File"/> + <int value="6" label="Could Not Create Upload Directory"/> </enum> <enum name="PhotoEditorFileType"> @@ -48708,6 +48724,8 @@ loop was detected"/> <int value="10" label="(DEPRECATED IN M74) Disallowed by PreviewsState"/> <int value="11" label="The chrome-proxy header is invalid"/> + <int value="12" label="The network probe has not completed yet"/> + <int value="13" label="The network probe completed and failed"/> </enum> <enum name="PreviewsServerLitePageServerResponse">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 0ad11e5e..4c54ea8 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -53635,7 +53635,7 @@ </histogram> <histogram name="IOS.EnterTabSwitcherSnapshotResult" - enum="EnterTabSwitcherSnapshotResult" expires_after="2019-08-01"> + enum="EnterTabSwitcherSnapshotResult" expires_after="2020-08-01"> <owner>edchin@chromium.org</owner> <owner>justincohen@chromium.org</owner> <summary> @@ -53773,7 +53773,7 @@ </histogram> <histogram name="IOS.PageLoadedSnapshotResult" enum="PageLoadedSnapshotResult" - expires_after="2019-08-01"> + expires_after="2020-08-01"> <owner>edchin@chromium.org</owner> <owner>justincohen@chromium.org</owner> <summary> @@ -56291,6 +56291,17 @@ <summary>Android: Whether MediaPlayer exited without errors.</summary> </histogram> +<histogram name="Media.Android.MediaPlayerWatchTime" + enum="MediaPlayerWatchTimeType" expires_after="2020-07-31"> + <owner>sandersd@chromium.org</owner> + <owner>media-dev@chromium.org</owner> + <summary> + Wall time of MediaPlayer playbacks. Each count represents one second of + media playback. Multiple MediaPlayer instances can together accumulate watch + time faster than real time. + </summary> +</histogram> + <histogram name="Media.Android.NumMediaServerCrashes" expires_after="2017-04-12"> <obsolete> @@ -106906,6 +106917,16 @@ </summary> </histogram> +<histogram name="Printing.CUPS.MigratedMakeAndModel" enum="BooleanMigrated" + expires_after="M87"> + <owner>luum@chromium.org</owner> + <owner>cros-printing-dev@chromium.org</owner> + <summary> + Records when a synced printer's outdated separate make and model strings + have been migrated to the new merged form. + </summary> +</histogram> + <histogram name="Printing.CUPS.PpdSource" enum="PpdSource" expires_after="M77"> <obsolete> Most users do not provide their own PPDs. @@ -110203,6 +110224,17 @@ </summary> </histogram> +<histogram name="Renderer4.GpuImageDecodeState.CachePeakUsagePercent" + expires_after="2020-08-01"> + <owner>sashamcintosh@chromium.org</owner> + <owner>ericrk@chromium.org</owner> + <summary> + The current number of bytes locked by the GpuImageDecodeCache compared to + the maximum allowed number of bytes to lock. This value is recorded every + time the tile manager assigns GPU memory to tiles. + </summary> +</histogram> + <histogram name="Renderer4.GpuImageDecodeState.FirstLockWasted" enum="BooleanWasted"> <owner>vmpstr@chromium.org</owner> @@ -150005,6 +150037,10 @@ <histogram name="WebCore.IndexedDB.ObjectStore.IndexEntry.KeyType" enum="IDBKeyType" expires_after="M77"> + <obsolete> + Removed August 2019. Was added to measure use of features which not all + actively developed browser engines supported. No longer relevant. + </obsolete> <owner>jsbell@chromium.org</owner> <summary> The type of key (number, string, etc.) used for an index entry for a record @@ -150015,6 +150051,10 @@ <histogram name="WebCore.IndexedDB.ObjectStore.Record.KeyType" enum="IDBKeyType" expires_after="M87"> + <obsolete> + Removed August 2019. Was added to measure use of features which not all + actively developed browser engines supported. No longer relevant. + </obsolete> <owner>jsbell@chromium.org</owner> <summary> The type of key (number, string, etc.) used for a record being newly stored @@ -150149,6 +150189,10 @@ <histogram name="WebCore.IndexedDB.Schema.Index.KeyPathType" enum="IDBKeyPathType" expires_after="M77"> + <obsolete> + Removed August 2019. Was added to measure use of features which not all + actively developed browser engines supported. No longer relevant. + </obsolete> <owner>jsbell@chromium.org</owner> <summary> Records the 'keyPath' type (none, string, or array) during IDBObjectStore's @@ -150158,6 +150202,10 @@ <histogram name="WebCore.IndexedDB.Schema.Index.MultiEntry" enum="Boolean" expires_after="M77"> + <obsolete> + Removed August 2019. Was added to measure use of features which not all + actively developed browser engines supported. No longer relevant. + </obsolete> <owner>jsbell@chromium.org</owner> <summary> Records the 'multiEntry' flag value during IDBObjectStore's createIndex @@ -150167,6 +150215,10 @@ <histogram name="WebCore.IndexedDB.Schema.Index.Unique" enum="Boolean" expires_after="M77"> + <obsolete> + Removed August 2019. Was added to measure use of features which not all + actively developed browser engines supported. No longer relevant. + </obsolete> <owner>jsbell@chromium.org</owner> <summary> Records the 'unique' flag value during IDBObjectStore's createIndex @@ -150176,6 +150228,10 @@ <histogram name="WebCore.IndexedDB.Schema.ObjectStore.AutoIncrement" enum="Boolean" expires_after="M77"> + <obsolete> + Removed August 2019. Was added to measure use of features which not all + actively developed browser engines supported. No longer relevant. + </obsolete> <owner>jsbell@chromium.org</owner> <summary> Records the 'autoIncrement' flag value during IDBDatabase's @@ -150185,6 +150241,10 @@ <histogram name="WebCore.IndexedDB.Schema.ObjectStore.KeyPathType" enum="IDBKeyPathType" expires_after="M77"> + <obsolete> + Removed August 2019. Was added to measure use of features which not all + actively developed browser engines supported. No longer relevant. + </obsolete> <owner>jsbell@chromium.org</owner> <summary> Records the 'keyPath' type (none, string, or array) during IDBDatabase's
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index a089961b..64e1cf0 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -2412,6 +2412,44 @@ </metric> </event> +<event name="ContentIndex.Added"> + <owner>rayankans@chromium.org</owner> + <summary> + Collected when a new Content Index entry is registered. + </summary> + <metric name="Category" enum="ContentIndexCategory"> + <summary> + The type of the content registered. Corresponds to + blink.mojom.ContentCategory. + </summary> + </metric> +</event> + +<event name="ContentIndex.DeletedByUser"> + <owner>rayankans@chromium.org</owner> + <summary> + Collected when a Content Index entry is deleted by the user from the + Downloads page. + </summary> + <metric name="Deleted" enum="Boolean"> + <summary> + Always true. + </summary> + </metric> +</event> + +<event name="ContentIndex.Opened"> + <owner>rayankans@chromium.org</owner> + <summary> + Collected when a Content Index entry is opened from the Downloads page. + </summary> + <metric name="IsOffline" enum="Boolean"> + <summary> + Whether the browser was offline when the content was opened. + </summary> + </metric> +</event> + <event name="ContextualSearch"> <owner>donnd@chromium.org</owner> <summary>
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index 03ad481..179dbe5a 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -197,6 +197,7 @@ <item id="ppapi_download_request" hash_code="135967426" type="0" content_hash_code="110461402" os_list="linux,windows" file_path="chrome/browser/safe_browsing/download_protection/ppapi_download_request.cc"/> <item id="prefetch_download" hash_code="44583172" type="0" content_hash_code="21424542" os_list="linux,windows" file_path="components/offline_pages/core/prefetch/prefetch_downloader_impl.cc"/> <item id="prefetch_visuals" hash_code="91068704" type="0" content_hash_code="90439946" os_list="linux,windows" file_path="components/offline_pages/core/prefetch/visuals_fetch_by_url.cc"/> + <item id="previews_litepage_prober" hash_code="33813109" type="0" content_hash_code="123476142" os_list="linux,windows" file_path="chrome/browser/previews/previews_lite_page_decider.cc"/> <item id="previews_prober" hash_code="41010697" type="0" deprecated="2019-07-24" content_hash_code="51581107" file_path=""/> <item id="printer_job_handler" hash_code="67638271" type="1" second_id="111712433" content_hash_code="75712693" os_list="linux,windows" semantics_fields="2,3,4" file_path="chrome/service/cloud_print/printer_job_handler.cc"/> <item id="privet_http_impl" hash_code="71251498" type="0" content_hash_code="107348604" os_list="linux,windows" file_path="chrome/browser/printing/cloud_print/privet_http_impl.cc"/>
diff --git a/ui/accessibility/accessibility_switches.cc b/ui/accessibility/accessibility_switches.cc index 4f88eb12..8b8660d2 100644 --- a/ui/accessibility/accessibility_switches.cc +++ b/ui/accessibility/accessibility_switches.cc
@@ -40,10 +40,6 @@ const char kEnableExperimentalAccessibilityChromeVoxLanguageSwitching[] = "enable-experimental-accessibility-chromevox-language-switching"; -// Enables automatic rich text indication in ChromeVox that hasn't launched yet. -const char kEnableExperimentalAccessibilityChromeVoxRichTextIndication[] = - "enable-experimental-accessibility-chromevox-rich-text-indication"; - bool AreExperimentalAccessibilityFeaturesEnabled() { return base::CommandLine::ForCurrentProcess()->HasSwitch( ::switches::kEnableExperimentalAccessibilityFeatures);
diff --git a/ui/accessibility/accessibility_switches.h b/ui/accessibility/accessibility_switches.h index 191cee55..46f2776 100644 --- a/ui/accessibility/accessibility_switches.h +++ b/ui/accessibility/accessibility_switches.h
@@ -19,8 +19,6 @@ AX_EXPORT extern const char kEnableExperimentalAccessibilitySwitchAccessText[]; AX_EXPORT extern const char kEnableExperimentalAccessibilityChromeVoxLanguageSwitching[]; -AX_EXPORT extern const char - kEnableExperimentalAccessibilityChromeVoxRichTextIndication[]; // Returns true if experimental accessibility features are enabled. AX_EXPORT bool AreExperimentalAccessibilityFeaturesEnabled();
diff --git a/ui/accessibility/ax_action_target.h b/ui/accessibility/ax_action_target.h index 54bcd29..5387a289 100644 --- a/ui/accessibility/ax_action_target.h +++ b/ui/accessibility/ax_action_target.h
@@ -5,7 +5,7 @@ #ifndef UI_ACCESSIBILITY_AX_ACTION_TARGET_H_ #define UI_ACCESSIBILITY_AX_ACTION_TARGET_H_ -#include "ui/accessibility/ax_enums.mojom-shared.h" +#include "ui/accessibility/ax_enums.mojom-forward.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/rect.h"
diff --git a/ui/accessibility/ax_assistant_structure.h b/ui/accessibility/ax_assistant_structure.h index e582885..ab303c2 100644 --- a/ui/accessibility/ax_assistant_structure.h +++ b/ui/accessibility/ax_assistant_structure.h
@@ -11,7 +11,7 @@ #include "base/macros.h" #include "base/optional.h" #include "base/strings/string16.h" -#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_enums.mojom-forward.h" #include "ui/accessibility/ax_export.h" #include "ui/accessibility/ax_tree_update.h" #include "ui/gfx/geometry/rect.h"
diff --git a/ui/accessibility/ax_enum_util.cc b/ui/accessibility/ax_enum_util.cc index 84e2fdb..0d2e5c1f 100644 --- a/ui/accessibility/ax_enum_util.cc +++ b/ui/accessibility/ax_enum_util.cc
@@ -4,6 +4,8 @@ #include "ui/accessibility/ax_enum_util.h" +#include "ui/accessibility/ax_enums.mojom.h" + namespace ui { const char* ToString(ax::mojom::Event event) {
diff --git a/ui/accessibility/ax_enum_util.h b/ui/accessibility/ax_enum_util.h index 2de28d4..30c38da 100644 --- a/ui/accessibility/ax_enum_util.h +++ b/ui/accessibility/ax_enum_util.h
@@ -5,7 +5,7 @@ #ifndef UI_ACCESSIBILITY_AX_ENUM_UTIL_H_ #define UI_ACCESSIBILITY_AX_ENUM_UTIL_H_ -#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_enums.mojom-forward.h" #include "ui/accessibility/ax_export.h" namespace ui {
diff --git a/ui/accessibility/ax_node.cc b/ui/accessibility/ax_node.cc index 49417db..d8c510a 100644 --- a/ui/accessibility/ax_node.cc +++ b/ui/accessibility/ax_node.cc
@@ -34,6 +34,7 @@ AXNode::~AXNode() = default; size_t AXNode::GetUnignoredChildCount() const { + DCHECK(!tree_->GetTreeUpdateInProgressState()); return unignored_child_count_; } @@ -42,6 +43,7 @@ } AXNode* AXNode::GetUnignoredChildAtIndex(size_t index) const { + DCHECK(!tree_->GetTreeUpdateInProgressState()); size_t count = 0; for (auto it = UnignoredChildrenBegin(); it != UnignoredChildrenEnd(); ++it) { if (count == index) @@ -52,6 +54,7 @@ } AXNode* AXNode::GetUnignoredParent() const { + DCHECK(!tree_->GetTreeUpdateInProgressState()); AXNode* result = parent(); while (result && result->data().HasState(ax::mojom::State::kIgnored)) result = result->parent(); @@ -59,18 +62,22 @@ } size_t AXNode::GetUnignoredIndexInParent() const { + DCHECK(!tree_->GetTreeUpdateInProgressState()); return unignored_index_in_parent_; } AXNode* AXNode::GetFirstUnignoredChild() const { + DCHECK(!tree_->GetTreeUpdateInProgressState()); return ComputeFirstUnignoredChildRecursive(); } AXNode* AXNode::GetLastUnignoredChild() const { + DCHECK(!tree_->GetTreeUpdateInProgressState()); return ComputeLastUnignoredChildRecursive(); } AXNode* AXNode::GetNextUnignoredSibling() const { + DCHECK(!tree_->GetTreeUpdateInProgressState()); AXNode* parent_node = parent(); size_t index = index_in_parent() + 1; while (parent_node) { @@ -98,6 +105,7 @@ } AXNode* AXNode::GetPreviousUnignoredSibling() const { + DCHECK(!tree_->GetTreeUpdateInProgressState()); AXNode* parent_node = parent(); bool before_first_child = index_in_parent() <= 0; size_t index = index_in_parent() - 1; @@ -128,10 +136,12 @@ } AXNode::UnignoredChildIterator AXNode::UnignoredChildrenBegin() const { + DCHECK(!tree_->GetTreeUpdateInProgressState()); return UnignoredChildIterator(this, GetFirstUnignoredChild()); } AXNode::UnignoredChildIterator AXNode::UnignoredChildrenEnd() const { + DCHECK(!tree_->GetTreeUpdateInProgressState()); return UnignoredChildIterator(this, nullptr); } @@ -769,10 +779,11 @@ } AXNode* AXNode::ComputeLastUnignoredChildRecursive() const { + DCHECK(!tree_->GetTreeUpdateInProgressState()); if (children().size() == 0) return nullptr; - for (size_t i = children().size() - 1; i >= 0; --i) { + for (int i = static_cast<int>(children().size()) - 1; i >= 0; --i) { AXNode* child = children_[i]; if (!child->data().HasState(ax::mojom::State::kIgnored)) return child; @@ -785,6 +796,7 @@ } AXNode* AXNode::ComputeFirstUnignoredChildRecursive() const { + DCHECK(!tree_->GetTreeUpdateInProgressState()); for (size_t i = 0; i < children().size(); i++) { AXNode* child = children_[i]; if (!child->data().HasState(ax::mojom::State::kIgnored))
diff --git a/ui/accessibility/ax_role_properties.cc b/ui/accessibility/ax_role_properties.cc index 1cb85d6..c0075b1b 100644 --- a/ui/accessibility/ax_role_properties.cc +++ b/ui/accessibility/ax_role_properties.cc
@@ -5,6 +5,7 @@ #include "ui/accessibility/ax_role_properties.h" #include "build/build_config.h" +#include "ui/accessibility/ax_enums.mojom.h" namespace ui {
diff --git a/ui/accessibility/ax_role_properties.h b/ui/accessibility/ax_role_properties.h index 8dfee29..b5c3ae9 100644 --- a/ui/accessibility/ax_role_properties.h +++ b/ui/accessibility/ax_role_properties.h
@@ -5,7 +5,7 @@ #ifndef UI_ACCESSIBILITY_AX_ROLE_PROPERTIES_H_ #define UI_ACCESSIBILITY_AX_ROLE_PROPERTIES_H_ -#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_enums.mojom-forward.h" #include "ui/accessibility/ax_export.h" #include "ui/accessibility/ax_node_data.h"
diff --git a/ui/accessibility/ax_text_utils.cc b/ui/accessibility/ax_text_utils.cc index fdce319..ef3e0c7 100644 --- a/ui/accessibility/ax_text_utils.cc +++ b/ui/accessibility/ax_text_utils.cc
@@ -10,6 +10,7 @@ #include "base/optional.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "ui/accessibility/ax_enums.mojom.h" #include "ui/base/l10n/l10n_util.h" #include "ui/strings/grit/ui_strings.h"
diff --git a/ui/accessibility/ax_text_utils.h b/ui/accessibility/ax_text_utils.h index 07dabcb2..2e27307 100644 --- a/ui/accessibility/ax_text_utils.h +++ b/ui/accessibility/ax_text_utils.h
@@ -10,7 +10,7 @@ #include <vector> #include "base/strings/string16.h" -#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_enums.mojom-forward.h" #include "ui/accessibility/ax_export.h" #include "ui/accessibility/ax_text_boundary.h"
diff --git a/ui/accessibility/ax_tree.cc b/ui/accessibility/ax_tree.cc index feec195..5352b9d0 100644 --- a/ui/accessibility/ax_tree.cc +++ b/ui/accessibility/ax_tree.cc
@@ -544,6 +544,8 @@ AXTree::~AXTree() { if (root_) { RecursivelyNotifyNodeWillBeDeleted(root_); + base::AutoReset<bool> update_state_resetter(&tree_update_in_progress_, + true); DestroyNodeAndSubtree(root_, nullptr); } for (auto& entry : table_info_map_) @@ -756,11 +758,6 @@ } bool AXTree::Unserialize(const AXTreeUpdate& update) { - // Set update state to true. - // tree_update_in_progress_ gets set back to false whenever this function - // exits. - base::AutoReset<bool> update_state_resetter(&tree_update_in_progress_, true); - AXTreeUpdateState update_state(*this); const AXNode::AXID old_root_id = root_ ? root_->id() : AXNode::kInvalidAXID; @@ -812,6 +809,11 @@ } } + // Now that we have finished sending events for changes that will happen, + // set update state to true. |tree_update_in_progress_| gets set back to + // false whenever this function exits. + base::AutoReset<bool> update_state_resetter(&tree_update_in_progress_, true); + // Handle |node_id_to_clear| before applying ordinary node updates. // We distinguish between updating the root, e.g. changing its children or // some of its attributes, or replacing the root completely. If the root is @@ -1046,6 +1048,7 @@ AXNode::AXID id, size_t index_in_parent, AXTreeUpdateState* update_state) { + DCHECK(GetTreeUpdateInProgressState()); // |update_state| must already contain information about all of the expected // changes and invalidations to apply. If any of these are missing, observers // may not be notified of changes. @@ -1247,6 +1250,7 @@ bool AXTree::UpdateNode(const AXNodeData& src, bool is_new_root, AXTreeUpdateState* update_state) { + DCHECK(GetTreeUpdateInProgressState()); // This method updates one node in the tree based on serialized data // received in an AXTreeUpdate. See AXTreeUpdate for pre and post // conditions. @@ -1305,6 +1309,7 @@ void AXTree::NotifySubtreeWillBeReparentedOrDeleted( AXNode* node, const AXTreeUpdateState* update_state) { + DCHECK(!GetTreeUpdateInProgressState()); if (node->id() == AXNode::kInvalidAXID) return; @@ -1320,6 +1325,7 @@ void AXTree::NotifyNodeWillBeReparentedOrDeleted( AXNode* node, const AXTreeUpdateState* update_state) { + DCHECK(!GetTreeUpdateInProgressState()); if (node->id() == AXNode::kInvalidAXID) return; @@ -1333,6 +1339,7 @@ } void AXTree::RecursivelyNotifyNodeWillBeDeleted(AXNode* node) { + DCHECK(!GetTreeUpdateInProgressState()); if (node->id() == AXNode::kInvalidAXID) return; @@ -1345,6 +1352,7 @@ void AXTree::NotifyNodeHasBeenReparentedOrCreated( AXNode* node, const AXTreeUpdateState* update_state) { + DCHECK(!GetTreeUpdateInProgressState()); if (node->id() == AXNode::kInvalidAXID) return; @@ -1359,6 +1367,7 @@ void AXTree::NotifyNodeDataWillChange(const AXNodeData& old_data, const AXNodeData& new_data) { + DCHECK(!GetTreeUpdateInProgressState()); if (new_data.id == AXNode::kInvalidAXID) return; @@ -1369,6 +1378,7 @@ void AXTree::NotifyNodeDataHasBeenChanged(AXNode* node, const AXNodeData& old_data, const AXNodeData& new_data) { + DCHECK(!GetTreeUpdateInProgressState()); if (node->id() == AXNode::kInvalidAXID) return; @@ -1455,6 +1465,7 @@ } void AXTree::UpdateReverseRelations(AXNode* node, const AXNodeData& new_data) { + DCHECK(GetTreeUpdateInProgressState()); const AXNodeData& old_data = node->data(); int id = new_data.id; auto int_callback = [this, id](ax::mojom::IntAttribute attr, @@ -1593,6 +1604,7 @@ void AXTree::DestroySubtree(AXNode* node, AXTreeUpdateState* update_state) { + DCHECK(GetTreeUpdateInProgressState()); // |update_state| must already contain information about all of the expected // changes and invalidations to apply. If any of these are missing, observers // may not be notified of changes. @@ -1606,6 +1618,7 @@ void AXTree::DestroyNodeAndSubtree(AXNode* node, AXTreeUpdateState* update_state) { + DCHECK(GetTreeUpdateInProgressState()); DCHECK(!update_state || update_state->GetPendingDestroyNodeCount(node->id()) > 0); @@ -1641,6 +1654,7 @@ void AXTree::DeleteOldChildren(AXNode* node, const std::vector<int32_t>& new_child_ids, AXTreeUpdateState* update_state) { + DCHECK(GetTreeUpdateInProgressState()); // Create a set of child ids in |src| for fast lookup, we know the set does // not contain duplicate entries already, because that was handled when // populating |update_state| with information about all of the expected @@ -1659,6 +1673,7 @@ const std::vector<int32_t>& new_child_ids, std::vector<AXNode*>* new_children, AXTreeUpdateState* update_state) { + DCHECK(GetTreeUpdateInProgressState()); bool success = true; for (size_t i = 0; i < new_child_ids.size(); ++i) { int32_t child_id = new_child_ids[i];
diff --git a/ui/accessibility/ax_tree_observer.h b/ui/accessibility/ax_tree_observer.h index d6652ac..d530a2a 100644 --- a/ui/accessibility/ax_tree_observer.h +++ b/ui/accessibility/ax_tree_observer.h
@@ -6,7 +6,7 @@ #define UI_ACCESSIBILITY_AX_TREE_OBSERVER_H_ #include "base/observer_list_types.h" -#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_enums.mojom-forward.h" #include "ui/accessibility/ax_export.h" namespace ui {
diff --git a/ui/accessibility/ax_tree_unittest.cc b/ui/accessibility/ax_tree_unittest.cc index 7d4e14c..c85eb4f6 100644 --- a/ui/accessibility/ax_tree_unittest.cc +++ b/ui/accessibility/ax_tree_unittest.cc
@@ -1871,10 +1871,10 @@ // | |____ // | | | // 13(i) 14 15 - // | - // 16 + // | | + // 16 17 tree_update.root_id = 1; - tree_update.nodes.resize(16); + tree_update.nodes.resize(17); tree_update.nodes[0].id = 1; tree_update.nodes[0].child_ids = {2, 3, 4}; @@ -1915,11 +1915,15 @@ tree_update.nodes[12].AddState(ax::mojom::State::kIgnored); tree_update.nodes[13].id = 14; + tree_update.nodes[13].child_ids = {17}; tree_update.nodes[14].id = 15; tree_update.nodes[15].id = 16; + tree_update.nodes[16].id = 17; + tree_update.nodes[16].AddState(ax::mojom::State::kIgnored); + AXTree tree(tree_update); EXPECT_EQ(4, tree.GetFromId(1)->GetLastUnignoredChild()->id()); @@ -1938,6 +1942,7 @@ EXPECT_EQ(nullptr, tree.GetFromId(14)->GetLastUnignoredChild()); EXPECT_EQ(nullptr, tree.GetFromId(15)->GetLastUnignoredChild()); EXPECT_EQ(nullptr, tree.GetFromId(16)->GetLastUnignoredChild()); + EXPECT_EQ(nullptr, tree.GetFromId(17)->GetLastUnignoredChild()); } TEST(AXTreeTest, UnignoredNextPreviousChild) {
diff --git a/ui/accessibility/null_ax_action_target_unittest.cc b/ui/accessibility/null_ax_action_target_unittest.cc index bd037c8..4f75a79 100644 --- a/ui/accessibility/null_ax_action_target_unittest.cc +++ b/ui/accessibility/null_ax_action_target_unittest.cc
@@ -3,7 +3,9 @@ // found in the LICENSE file. #include "ui/accessibility/null_ax_action_target.h" + #include "testing/gtest/include/gtest/gtest.h" +#include "ui/accessibility/ax_enums.mojom.h" namespace ui {
diff --git a/ui/accessibility/platform/aura_window_properties.cc b/ui/accessibility/platform/aura_window_properties.cc index d2ebb7ee..bbd55bf6 100644 --- a/ui/accessibility/platform/aura_window_properties.cc +++ b/ui/accessibility/platform/aura_window_properties.cc
@@ -4,6 +4,7 @@ #include "ui/accessibility/platform/aura_window_properties.h" +#include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_tree_id.h" #include "ui/base/class_property.h"
diff --git a/ui/accessibility/platform/aura_window_properties.h b/ui/accessibility/platform/aura_window_properties.h index 8fcf89f..bee79a4 100644 --- a/ui/accessibility/platform/aura_window_properties.h +++ b/ui/accessibility/platform/aura_window_properties.h
@@ -7,7 +7,7 @@ #include <string> -#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_enums.mojom-forward.h" #include "ui/accessibility/ax_export.h" #include "ui/aura/window.h"
diff --git a/ui/accessibility/platform/ax_platform_node_base.cc b/ui/accessibility/platform/ax_platform_node_base.cc index ded7a98..16c0257 100644 --- a/ui/accessibility/platform/ax_platform_node_base.cc +++ b/ui/accessibility/platform/ax_platform_node_base.cc
@@ -726,6 +726,7 @@ bool AXPlatformNodeBase::IsInvisibleOrIgnored() const { const AXNodeData& data = GetData(); return data.HasState(ax::mojom::State::kInvisible) || + data.HasState(ax::mojom::State::kIgnored) || data.role == ax::mojom::Role::kIgnored; }
diff --git a/ui/aura/native_window_occlusion_tracker_win.cc b/ui/aura/native_window_occlusion_tracker_win.cc index 5553d08..e081a65 100644 --- a/ui/aura/native_window_occlusion_tracker_win.cc +++ b/ui/aura/native_window_occlusion_tracker_win.cc
@@ -95,8 +95,8 @@ // event hooks will happen on the same thread, as required by Windows, // and the task runner will have a message loop to call // EventHookCallback. - update_occlusion_task_runner_(base::CreateCOMSTATaskRunnerWithTraits( - {base::MayBlock(), + update_occlusion_task_runner_(base::CreateCOMSTATaskRunner( + {base::ThreadPool(), base::MayBlock(), // This may be needed to determine that a window is no longer // occluded. base::TaskPriority::USER_VISIBLE,
diff --git a/ui/base/clipboard/BUILD.gn b/ui/base/clipboard/BUILD.gn index cc189e3..85abbbf 100644 --- a/ui/base/clipboard/BUILD.gn +++ b/ui/base/clipboard/BUILD.gn
@@ -93,8 +93,8 @@ ] } else if (use_x11) { sources += [ - "clipboard_aurax11.cc", - "clipboard_aurax11.h", + "clipboard_x11.cc", + "clipboard_x11.h", ] configs += [ "//build/config/linux:x11" ] deps += [
diff --git a/ui/base/clipboard/clipboard_util_win.cc b/ui/base/clipboard/clipboard_util_win.cc index 5563b655..847b7ef 100644 --- a/ui/base/clipboard/clipboard_util_win.cc +++ b/ui/base/clipboard/clipboard_util_win.cc
@@ -623,8 +623,9 @@ } // Queue a task to actually write the temp files on a worker thread. - base::PostTaskWithTraitsAndReplyWithResult( - FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_BLOCKING}, + base::PostTaskAndReplyWithResult( + FROM_HERE, + {base::ThreadPool(), base::MayBlock(), base::TaskPriority::USER_BLOCKING}, base::BindOnce(&WriteAllFileContentsToTempFiles, display_names, memory_backed_contents), std::move(callback)); // callback on the UI thread
diff --git a/ui/base/clipboard/clipboard_aurax11.cc b/ui/base/clipboard/clipboard_x11.cc similarity index 73% rename from ui/base/clipboard/clipboard_aurax11.cc rename to ui/base/clipboard/clipboard_x11.cc index 63f9a13..952806c 100644 --- a/ui/base/clipboard/clipboard_aurax11.cc +++ b/ui/base/clipboard/clipboard_x11.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 "ui/base/clipboard/clipboard_aurax11.h" +#include "ui/base/clipboard/clipboard_x11.h" #include <stdint.h> @@ -85,16 +85,16 @@ XFixesSelectSelectionInput(gfx::GetXDisplay(), GetX11RootWindow(), clipboard_atom_, XFixesSetSelectionOwnerNotifyMask | - XFixesSelectionWindowDestroyNotifyMask | - XFixesSelectionClientCloseNotifyMask); + XFixesSelectionWindowDestroyNotifyMask | + XFixesSelectionClientCloseNotifyMask); // This seems to be semi-optional. For some reason, registering for any // selection notify events seems to subscribe us to events for both the // primary and the clipboard buffers. Register anyway just to be safe. XFixesSelectSelectionInput(gfx::GetXDisplay(), GetX11RootWindow(), XA_PRIMARY, XFixesSetSelectionOwnerNotifyMask | - XFixesSelectionWindowDestroyNotifyMask | - XFixesSelectionClientCloseNotifyMask); + XFixesSelectionWindowDestroyNotifyMask | + XFixesSelectionClientCloseNotifyMask); PlatformEventSource::GetInstance()->AddPlatformEventObserver(this); } @@ -128,7 +128,7 @@ // Represents a list of possible return types. Copy constructable. class TargetList { public: - typedef std::vector< ::Atom> AtomVector; + using AtomVector = std::vector<::Atom>; explicit TargetList(const AtomVector& target_list); @@ -161,21 +161,20 @@ } bool TargetList::ContainsAtom(::Atom atom) const { - return find(target_list_.begin(), target_list_.end(), atom) - != target_list_.end(); + return base::Contains(target_list_, atom); } } // namespace /////////////////////////////////////////////////////////////////////////////// -// ClipboardAuraX11::AuraX11Details +// ClipboardX11::X11Details // Private implementation of our X11 integration. Keeps X11 headers out of the // majority of chrome, which break badly. -class ClipboardAuraX11::AuraX11Details : public PlatformEventDispatcher { +class ClipboardX11::X11Details : public PlatformEventDispatcher { public: - AuraX11Details(); - ~AuraX11Details() override; + X11Details(); + ~X11Details() override; // Returns the X11 type that we pass to various XSelection functions for the // given type. @@ -203,7 +202,7 @@ void TakeOwnershipOfSelection(ClipboardType type); // Returns the first of |types| offered by the current selection holder in - // |data_out|, or returns NULL if none of those types are available. + // |data_out|, or returns nullptr if none of those types are available. // // If the selection holder is us, this call is synchronous and we pull // the data out of |clipboard_selection_| or |primary_selection_|. If the @@ -211,7 +210,7 @@ // and do the asynchronous dance with whatever application is holding the // selection. ui::SelectionData RequestAndWaitForTypes(ClipboardType type, - const std::vector< ::Atom>& types); + const std::vector<::Atom>& types); // Retrieves the list of possible data types the current clipboard owner has. // @@ -220,7 +219,7 @@ TargetList WaitAndGetTargetsList(ClipboardType type); // Returns a list of all text atoms that we handle. - std::vector< ::Atom> GetTextAtoms() const; + std::vector<::Atom> GetTextAtoms() const; // Returns a vector with a |format| converted to an X11 atom. std::vector<::Atom> GetAtomsForFormat(const ClipboardFormatType& format); @@ -257,10 +256,10 @@ SelectionOwner clipboard_owner_; SelectionOwner primary_owner_; - DISALLOW_COPY_AND_ASSIGN(AuraX11Details); + DISALLOW_COPY_AND_ASSIGN(X11Details); }; -ClipboardAuraX11::AuraX11Details::AuraX11Details() +ClipboardX11::X11Details::X11Details() : x_display_(gfx::GetXDisplay()), x_root_window_(DefaultRootWindow(x_display_)), x_window_(XCreateWindow(x_display_, @@ -286,14 +285,14 @@ PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); } -ClipboardAuraX11::AuraX11Details::~AuraX11Details() { +ClipboardX11::X11Details::~X11Details() { if (PlatformEventSource::GetInstance()) PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); XDestroyWindow(x_display_, x_window_); } -::Atom ClipboardAuraX11::AuraX11Details::LookupSelectionForClipboardType( +::Atom ClipboardX11::X11Details::LookupSelectionForClipboardType( ClipboardType type) const { if (type == ClipboardType::kCopyPaste) return GetCopyPasteSelection(); @@ -301,12 +300,12 @@ return XA_PRIMARY; } -::Atom ClipboardAuraX11::AuraX11Details::GetCopyPasteSelection() const { +::Atom ClipboardX11::X11Details::GetCopyPasteSelection() const { return gfx::GetAtom(kClipboard); } -const SelectionFormatMap& -ClipboardAuraX11::AuraX11Details::LookupStorageForAtom(::Atom atom) { +const SelectionFormatMap& ClipboardX11::X11Details::LookupStorageForAtom( + ::Atom atom) { if (atom == XA_PRIMARY) return primary_owner_.selection_format_map(); @@ -314,26 +313,25 @@ return clipboard_owner_.selection_format_map(); } -void ClipboardAuraX11::AuraX11Details::CreateNewClipboardData() { +void ClipboardX11::X11Details::CreateNewClipboardData() { clipboard_data_ = SelectionFormatMap(); } -void ClipboardAuraX11::AuraX11Details::InsertMapping( +void ClipboardX11::X11Details::InsertMapping( const std::string& key, const scoped_refptr<base::RefCountedMemory>& memory) { ::Atom atom_key = gfx::GetAtom(key.c_str()); clipboard_data_.Insert(atom_key, memory); } -void ClipboardAuraX11::AuraX11Details::TakeOwnershipOfSelection( - ClipboardType type) { +void ClipboardX11::X11Details::TakeOwnershipOfSelection(ClipboardType type) { if (type == ClipboardType::kCopyPaste) return clipboard_owner_.TakeOwnershipOfSelection(clipboard_data_); else return primary_owner_.TakeOwnershipOfSelection(clipboard_data_); } -SelectionData ClipboardAuraX11::AuraX11Details::RequestAndWaitForTypes( +SelectionData ClipboardX11::X11Details::RequestAndWaitForTypes( ClipboardType type, const std::vector<::Atom>& types) { ::Atom selection_name = LookupSelectionForClipboardType(type); @@ -351,7 +349,7 @@ TargetList targets = WaitAndGetTargetsList(type); ::Atom selection_name = LookupSelectionForClipboardType(type); - std::vector< ::Atom> intersection; + std::vector<::Atom> intersection; GetAtomIntersection(types, targets.target_list(), &intersection); return selection_requestor_.RequestAndWaitForTypes(selection_name, intersection); @@ -360,10 +358,9 @@ return SelectionData(); } -TargetList ClipboardAuraX11::AuraX11Details::WaitAndGetTargetsList( - ClipboardType type) { +TargetList ClipboardX11::X11Details::WaitAndGetTargetsList(ClipboardType type) { ::Atom selection_name = LookupSelectionForClipboardType(type); - std::vector< ::Atom> out; + std::vector<::Atom> out; if (XGetSelectionOwner(x_display_, selection_name) == x_window_) { // We can local fastpath and return the list of local targets. const SelectionFormatMap& format_map = LookupStorageForAtom(selection_name); @@ -392,7 +389,7 @@ // text. This is pretty unfortunate since it means we have to actually // copy the data to see if it is available, but at least this path // shouldn't be hit for conforming programs. - std::vector< ::Atom> types = GetTextAtoms(); + std::vector<::Atom> types = GetTextAtoms(); for (const auto& text_atom : types) { ::Atom type = x11::None; if (selection_requestor_.PerformBlockingConvertSelection( @@ -407,25 +404,23 @@ return TargetList(out); } -std::vector<::Atom> ClipboardAuraX11::AuraX11Details::GetTextAtoms() const { +std::vector<::Atom> ClipboardX11::X11Details::GetTextAtoms() const { return GetTextAtomsFrom(); } -std::vector<::Atom> ClipboardAuraX11::AuraX11Details::GetAtomsForFormat( +std::vector<::Atom> ClipboardX11::X11Details::GetAtomsForFormat( const ClipboardFormatType& format) { - std::vector< ::Atom> atoms; - atoms.push_back(gfx::GetAtom(format.ToString().c_str())); - return atoms; + return {gfx::GetAtom(format.ToString().c_str())}; } -void ClipboardAuraX11::AuraX11Details::Clear(ClipboardType type) { +void ClipboardX11::X11Details::Clear(ClipboardType type) { if (type == ClipboardType::kCopyPaste) clipboard_owner_.ClearSelectionOwner(); else primary_owner_.ClearSelectionOwner(); } -void ClipboardAuraX11::AuraX11Details::StoreCopyPasteDataAndWait() { +void ClipboardX11::X11Details::StoreCopyPasteDataAndWait() { ::Atom selection = GetCopyPasteSelection(); if (XGetSelectionOwner(x_display_, selection) != x_window_) return; @@ -446,21 +441,19 @@ base::TimeTicks::Now() - start); } -bool ClipboardAuraX11::AuraX11Details::CanDispatchEvent( - const PlatformEvent& event) { +bool ClipboardX11::X11Details::CanDispatchEvent(const PlatformEvent& event) { if (event->xany.window == x_window_) return true; if (event->type == PropertyNotify) { return primary_owner_.CanDispatchPropertyEvent(*event) || - clipboard_owner_.CanDispatchPropertyEvent(*event) || - selection_requestor_.CanDispatchPropertyEvent(*event); + clipboard_owner_.CanDispatchPropertyEvent(*event) || + selection_requestor_.CanDispatchPropertyEvent(*event); } return false; } -uint32_t ClipboardAuraX11::AuraX11Details::DispatchEvent( - const PlatformEvent& xev) { +uint32_t ClipboardX11::X11Details::DispatchEvent(const PlatformEvent& xev) { switch (xev->type) { case SelectionRequest: { if (xev->xselectionrequest.selection == XA_PRIMARY) { @@ -485,7 +478,7 @@ // because we never take ownership of it. DCHECK_EQ(GetCopyPasteSelection(), xev->xselection.selection); clipboard_owner_.OnSelectionClear(*xev); - } + } break; } case PropertyNotify: { @@ -507,26 +500,26 @@ /////////////////////////////////////////////////////////////////////////////// // Clipboard factory method. Clipboard* Clipboard::Create() { - return new ClipboardAuraX11; + return new ClipboardX11; } /////////////////////////////////////////////////////////////////////////////// -// ClipboardAuraX11 +// ClipboardX11 -ClipboardAuraX11::ClipboardAuraX11() : aurax11_details_(new AuraX11Details) { +ClipboardX11::ClipboardX11() : x11_details_(new X11Details) { DCHECK(CalledOnValidThread()); } -ClipboardAuraX11::~ClipboardAuraX11() { +ClipboardX11::~ClipboardX11() { DCHECK(CalledOnValidThread()); } -void ClipboardAuraX11::OnPreShutdown() { +void ClipboardX11::OnPreShutdown() { DCHECK(CalledOnValidThread()); - aurax11_details_->StoreCopyPasteDataAndWait(); + x11_details_->StoreCopyPasteDataAndWait(); } -uint64_t ClipboardAuraX11::GetSequenceNumber(ClipboardType type) const { +uint64_t ClipboardX11::GetSequenceNumber(ClipboardType type) const { DCHECK(CalledOnValidThread()); if (type == ClipboardType::kCopyPaste) return SelectionChangeObserver::GetInstance()->clipboard_sequence_number(); @@ -534,12 +527,12 @@ return SelectionChangeObserver::GetInstance()->primary_sequence_number(); } -bool ClipboardAuraX11::IsFormatAvailable(const ClipboardFormatType& format, - ClipboardType type) const { +bool ClipboardX11::IsFormatAvailable(const ClipboardFormatType& format, + ClipboardType type) const { DCHECK(CalledOnValidThread()); DCHECK(IsSupportedClipboardType(type)); - TargetList target_list = aurax11_details_->WaitAndGetTargetsList(type); + TargetList target_list = x11_details_->WaitAndGetTargetsList(type); if (format.Equals(ClipboardFormatType::GetPlainTextType()) || format.Equals(ClipboardFormatType::GetUrlType())) { return target_list.ContainsText(); @@ -547,22 +540,22 @@ return target_list.ContainsFormat(format); } -void ClipboardAuraX11::Clear(ClipboardType type) { +void ClipboardX11::Clear(ClipboardType type) { DCHECK(CalledOnValidThread()); DCHECK(IsSupportedClipboardType(type)); - aurax11_details_->Clear(type); + x11_details_->Clear(type); } -void ClipboardAuraX11::ReadAvailableTypes(ClipboardType type, - std::vector<base::string16>* types, - bool* contains_filenames) const { +void ClipboardX11::ReadAvailableTypes(ClipboardType type, + std::vector<base::string16>* types, + bool* contains_filenames) const { DCHECK(CalledOnValidThread()); if (!types || !contains_filenames) { NOTREACHED(); return; } - TargetList target_list = aurax11_details_->WaitAndGetTargetsList(type); + TargetList target_list = x11_details_->WaitAndGetTargetsList(type); types->clear(); @@ -576,42 +569,41 @@ types->push_back(base::UTF8ToUTF16(kMimeTypePNG)); *contains_filenames = false; - SelectionData data(aurax11_details_->RequestAndWaitForTypes( - type, aurax11_details_->GetAtomsForFormat( + SelectionData data(x11_details_->RequestAndWaitForTypes( + type, x11_details_->GetAtomsForFormat( ClipboardFormatType::GetWebCustomDataType()))); if (data.IsValid()) ReadCustomDataTypes(data.GetData(), data.GetSize(), types); } -void ClipboardAuraX11::ReadText(ClipboardType type, - base::string16* result) const { +void ClipboardX11::ReadText(ClipboardType type, base::string16* result) const { DCHECK(CalledOnValidThread()); - SelectionData data(aurax11_details_->RequestAndWaitForTypes( - type, aurax11_details_->GetTextAtoms())); + SelectionData data( + x11_details_->RequestAndWaitForTypes(type, x11_details_->GetTextAtoms())); if (data.IsValid()) { std::string text = data.GetText(); *result = base::UTF8ToUTF16(text); } } -void ClipboardAuraX11::ReadAsciiText(ClipboardType type, - std::string* result) const { +void ClipboardX11::ReadAsciiText(ClipboardType type, + std::string* result) const { DCHECK(CalledOnValidThread()); - SelectionData data(aurax11_details_->RequestAndWaitForTypes( - type, aurax11_details_->GetTextAtoms())); + SelectionData data( + x11_details_->RequestAndWaitForTypes(type, x11_details_->GetTextAtoms())); if (data.IsValid()) result->assign(data.GetText()); } // TODO(estade): handle different charsets. // TODO(port): set *src_url. -void ClipboardAuraX11::ReadHTML(ClipboardType type, - base::string16* markup, - std::string* src_url, - uint32_t* fragment_start, - uint32_t* fragment_end) const { +void ClipboardX11::ReadHTML(ClipboardType type, + base::string16* markup, + std::string* src_url, + uint32_t* fragment_start, + uint32_t* fragment_end) const { DCHECK(CalledOnValidThread()); markup->clear(); if (src_url) @@ -619,9 +611,9 @@ *fragment_start = 0; *fragment_end = 0; - SelectionData data(aurax11_details_->RequestAndWaitForTypes( + SelectionData data(x11_details_->RequestAndWaitForTypes( type, - aurax11_details_->GetAtomsForFormat(ClipboardFormatType::GetHtmlType()))); + x11_details_->GetAtomsForFormat(ClipboardFormatType::GetHtmlType()))); if (data.IsValid()) { *markup = data.GetHtml(); @@ -631,22 +623,22 @@ } } -void ClipboardAuraX11::ReadRTF(ClipboardType type, std::string* result) const { +void ClipboardX11::ReadRTF(ClipboardType type, std::string* result) const { DCHECK(CalledOnValidThread()); - SelectionData data(aurax11_details_->RequestAndWaitForTypes( + SelectionData data(x11_details_->RequestAndWaitForTypes( type, - aurax11_details_->GetAtomsForFormat(ClipboardFormatType::GetRtfType()))); + x11_details_->GetAtomsForFormat(ClipboardFormatType::GetRtfType()))); if (data.IsValid()) data.AssignTo(result); } -SkBitmap ClipboardAuraX11::ReadImage(ClipboardType type) const { +SkBitmap ClipboardX11::ReadImage(ClipboardType type) const { DCHECK(CalledOnValidThread()); - SelectionData data(aurax11_details_->RequestAndWaitForTypes( - type, aurax11_details_->GetAtomsForFormat( - ClipboardFormatType::GetBitmapType()))); + SelectionData data(x11_details_->RequestAndWaitForTypes( + type, + x11_details_->GetAtomsForFormat(ClipboardFormatType::GetBitmapType()))); if (data.IsValid()) { SkBitmap bitmap; if (gfx::PNGCodec::Decode(data.GetData(), data.GetSize(), &bitmap)) @@ -656,96 +648,95 @@ return SkBitmap(); } -void ClipboardAuraX11::ReadCustomData(ClipboardType clipboard_type, - const base::string16& type, - base::string16* result) const { +void ClipboardX11::ReadCustomData(ClipboardType clipboard_type, + const base::string16& type, + base::string16* result) const { DCHECK(CalledOnValidThread()); - SelectionData data(aurax11_details_->RequestAndWaitForTypes( - clipboard_type, aurax11_details_->GetAtomsForFormat( + SelectionData data(x11_details_->RequestAndWaitForTypes( + clipboard_type, x11_details_->GetAtomsForFormat( ClipboardFormatType::GetWebCustomDataType()))); if (data.IsValid()) ReadCustomDataForType(data.GetData(), data.GetSize(), type, result); } -void ClipboardAuraX11::ReadBookmark(base::string16* title, - std::string* url) const { +void ClipboardX11::ReadBookmark(base::string16* title, std::string* url) const { DCHECK(CalledOnValidThread()); // TODO(erg): This was left NOTIMPLEMENTED() in the gtk port too. NOTIMPLEMENTED(); } -void ClipboardAuraX11::ReadData(const ClipboardFormatType& format, - std::string* result) const { +void ClipboardX11::ReadData(const ClipboardFormatType& format, + std::string* result) const { DCHECK(CalledOnValidThread()); - SelectionData data(aurax11_details_->RequestAndWaitForTypes( - ClipboardType::kCopyPaste, aurax11_details_->GetAtomsForFormat(format))); + SelectionData data(x11_details_->RequestAndWaitForTypes( + ClipboardType::kCopyPaste, x11_details_->GetAtomsForFormat(format))); if (data.IsValid()) data.AssignTo(result); } -void ClipboardAuraX11::WriteObjects(ClipboardType type, - const ObjectMap& objects) { +void ClipboardX11::WriteObjects(ClipboardType type, const ObjectMap& objects) { DCHECK(CalledOnValidThread()); DCHECK(IsSupportedClipboardType(type)); - aurax11_details_->CreateNewClipboardData(); + x11_details_->CreateNewClipboardData(); for (const auto& object : objects) DispatchObject(static_cast<ObjectType>(object.first), object.second); - aurax11_details_->TakeOwnershipOfSelection(type); + x11_details_->TakeOwnershipOfSelection(type); if (type == ClipboardType::kCopyPaste) { auto text_iter = objects.find(CBF_TEXT); if (text_iter != objects.end()) { - aurax11_details_->CreateNewClipboardData(); + x11_details_->CreateNewClipboardData(); const ObjectMapParams& params_vector = text_iter->second; if (params_vector.size()) { const ObjectMapParam& char_vector = params_vector[0]; if (char_vector.size()) WriteText(&char_vector.front(), char_vector.size()); } - aurax11_details_->TakeOwnershipOfSelection(ClipboardType::kSelection); + x11_details_->TakeOwnershipOfSelection(ClipboardType::kSelection); } } } -void ClipboardAuraX11::WriteText(const char* text_data, size_t text_len) { +void ClipboardX11::WriteText(const char* text_data, size_t text_len) { std::string str(text_data, text_len); scoped_refptr<base::RefCountedMemory> mem( base::RefCountedString::TakeString(&str)); - aurax11_details_->InsertMapping(kMimeTypeText, mem); - aurax11_details_->InsertMapping(kText, mem); - aurax11_details_->InsertMapping(kString, mem); - aurax11_details_->InsertMapping(kUtf8String, mem); + x11_details_->InsertMapping(kMimeTypeText, mem); + x11_details_->InsertMapping(kText, mem); + x11_details_->InsertMapping(kString, mem); + x11_details_->InsertMapping(kUtf8String, mem); } -void ClipboardAuraX11::WriteHTML(const char* markup_data, - size_t markup_len, - const char* url_data, - size_t url_len) { +void ClipboardX11::WriteHTML(const char* markup_data, + size_t markup_len, + const char* url_data, + size_t url_len) { // TODO(estade): We need to expand relative links with |url_data|. - static const char* html_prefix = "<meta http-equiv=\"content-type\" " - "content=\"text/html; charset=utf-8\">"; + static const char* html_prefix = + "<meta http-equiv=\"content-type\" " + "content=\"text/html; charset=utf-8\">"; std::string data = html_prefix; data += std::string(markup_data, markup_len); - // Some programs expect NULL-terminated data. See http://crbug.com/42624 + // Some programs expect '\0'-terminated data. See http://crbug.com/42624 data += '\0'; scoped_refptr<base::RefCountedMemory> mem( base::RefCountedString::TakeString(&data)); - aurax11_details_->InsertMapping(kMimeTypeHTML, mem); + x11_details_->InsertMapping(kMimeTypeHTML, mem); } -void ClipboardAuraX11::WriteRTF(const char* rtf_data, size_t data_len) { +void ClipboardX11::WriteRTF(const char* rtf_data, size_t data_len) { WriteData(ClipboardFormatType::GetRtfType(), rtf_data, data_len); } -void ClipboardAuraX11::WriteBookmark(const char* title_data, - size_t title_len, - const char* url_data, - size_t url_len) { +void ClipboardX11::WriteBookmark(const char* title_data, + size_t title_len, + const char* url_data, + size_t url_len) { // Write as a mozilla url (UTF16: URL, newline, title). base::string16 url = base::UTF8ToUTF16(std::string(url_data, url_len) + "\n"); base::string16 title = @@ -757,32 +748,30 @@ scoped_refptr<base::RefCountedMemory> mem( base::RefCountedBytes::TakeVector(&data)); - aurax11_details_->InsertMapping(kMimeTypeMozillaURL, mem); + x11_details_->InsertMapping(kMimeTypeMozillaURL, mem); } // Write an extra flavor that signifies WebKit was the last to modify the // pasteboard. This flavor has no data. -void ClipboardAuraX11::WriteWebSmartPaste() { +void ClipboardX11::WriteWebSmartPaste() { std::string empty; - aurax11_details_->InsertMapping( - kMimeTypeWebkitSmartPaste, - scoped_refptr<base::RefCountedMemory>( - base::RefCountedString::TakeString(&empty))); + x11_details_->InsertMapping(kMimeTypeWebkitSmartPaste, + scoped_refptr<base::RefCountedMemory>( + base::RefCountedString::TakeString(&empty))); } -void ClipboardAuraX11::WriteBitmap(const SkBitmap& bitmap) { +void ClipboardX11::WriteBitmap(const SkBitmap& bitmap) { // Encode the bitmap as a PNG for transport. std::vector<unsigned char> output; if (gfx::PNGCodec::FastEncodeBGRASkBitmap(bitmap, false, &output)) { - aurax11_details_->InsertMapping(kMimeTypePNG, - base::RefCountedBytes::TakeVector( - &output)); + x11_details_->InsertMapping(kMimeTypePNG, + base::RefCountedBytes::TakeVector(&output)); } } -void ClipboardAuraX11::WriteData(const ClipboardFormatType& format, - const char* data_data, - size_t data_len) { +void ClipboardX11::WriteData(const ClipboardFormatType& format, + const char* data_data, + size_t data_len) { // We assume that certain mapping types are only written by trusted code. // Therefore we must upkeep their integrity. if (format.Equals(ClipboardFormatType::GetBitmapType())) @@ -791,7 +780,7 @@ std::vector<unsigned char> bytes(data_data, data_data + data_len); scoped_refptr<base::RefCountedMemory> mem( base::RefCountedBytes::TakeVector(&bytes)); - aurax11_details_->InsertMapping(format.ToString(), mem); + x11_details_->InsertMapping(format.ToString(), mem); } } // namespace ui
diff --git a/ui/base/clipboard/clipboard_aurax11.h b/ui/base/clipboard/clipboard_x11.h similarity index 87% rename from ui/base/clipboard/clipboard_aurax11.h rename to ui/base/clipboard/clipboard_x11.h index 29d860c..6e32a395 100644 --- a/ui/base/clipboard/clipboard_aurax11.h +++ b/ui/base/clipboard/clipboard_x11.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 UI_BASE_CLIPBOARD_CLIPBOARD_AURAX11_H_ -#define UI_BASE_CLIPBOARD_CLIPBOARD_AURAX11_H_ +#ifndef UI_BASE_CLIPBOARD_CLIPBOARD_X11_H_ +#define UI_BASE_CLIPBOARD_CLIPBOARD_X11_H_ #include <stddef.h> #include <stdint.h> @@ -15,12 +15,12 @@ namespace ui { -class ClipboardAuraX11 : public Clipboard { +class ClipboardX11 : public Clipboard { private: friend class Clipboard; - ClipboardAuraX11(); - ~ClipboardAuraX11() override; + ClipboardX11(); + ~ClipboardX11() override; // Clipboard overrides: void OnPreShutdown() override; @@ -65,12 +65,12 @@ // TODO(dcheng): Is this still needed now that each platform clipboard has its // own class derived from Clipboard? - class AuraX11Details; - std::unique_ptr<AuraX11Details> aurax11_details_; + class X11Details; + std::unique_ptr<X11Details> x11_details_; - DISALLOW_COPY_AND_ASSIGN(ClipboardAuraX11); + DISALLOW_COPY_AND_ASSIGN(ClipboardX11); }; } // namespace ui -#endif // UI_BASE_CLIPBOARD_CLIPBOARD_AURAX11_H_ +#endif // UI_BASE_CLIPBOARD_CLIPBOARD_X11_H_
diff --git a/ui/base/ime/win/on_screen_keyboard_display_manager_input_pane.cc b/ui/base/ime/win/on_screen_keyboard_display_manager_input_pane.cc index b114660..83210e7 100644 --- a/ui/base/ime/win/on_screen_keyboard_display_manager_input_pane.cc +++ b/ui/base/ime/win/on_screen_keyboard_display_manager_input_pane.cc
@@ -175,7 +175,7 @@ : hwnd_(hwnd), main_task_runner_(base::ThreadTaskRunnerHandle::Get()), background_task_runner_( - base::CreateCOMSTATaskRunnerWithTraits({base::MayBlock()})), + base::CreateCOMSTATaskRunner({base::ThreadPool(), base::MayBlock()})), virtual_keyboard_input_pane_( base::MakeRefCounted<OnScreenKeyboardDisplayManagerInputPane:: VirtualKeyboardInputPane>( @@ -236,7 +236,7 @@ void OnScreenKeyboardDisplayManagerInputPane::SetInputPaneForTesting( Microsoft::WRL::ComPtr<ABI::Windows::UI::ViewManagement::IInputPane> pane) { DCHECK(main_task_runner_->BelongsToCurrentThread()); - base::CreateCOMSTATaskRunnerWithTraits({base::MayBlock()}) + base::CreateCOMSTATaskRunner({base::ThreadPool(), base::MayBlock()}) ->PostTask(FROM_HERE, base::BindOnce( &OnScreenKeyboardDisplayManagerInputPane::
diff --git a/ui/base/resource/resource_bundle.cc b/ui/base/resource/resource_bundle.cc index fa666755..fe6ebde 100644 --- a/ui/base/resource/resource_bundle.cc +++ b/ui/base/resource/resource_bundle.cc
@@ -149,18 +149,16 @@ } // Helper function for decompressing resource. -std::string Decompress(base::StringPiece data) { - std::string response; - if (HasBrotliHeader(data)) { - bool success = BrotliDecompress(data, &response); +void Decompress(base::StringPiece data, std::string* output) { + if (HasGzipHeader(data)) { + bool success = compression::GzipUncompress(data, output); DCHECK(success); - } else if (HasGzipHeader(data)) { - bool success = compression::GzipUncompress(data, &response); + } else if (HasBrotliHeader(data)) { + bool success = BrotliDecompress(data, output); DCHECK(success); } else { NOTREACHED() << "Resource is not compressed"; } - return response; } } // namespace @@ -580,17 +578,23 @@ base::RefCountedMemory* ResourceBundle::LoadDataResourceBytesForScale( int resource_id, ScaleFactor scale_factor) const { - base::RefCountedMemory* bytes = NULL; + base::RefCountedMemory* bytes = nullptr; if (delegate_) bytes = delegate_->LoadDataResourceBytes(resource_id, scale_factor); if (!bytes) { base::StringPiece data = GetRawDataResourceForScale(resource_id, scale_factor); - if (!data.empty()) - bytes = new base::RefCountedStaticMemory(data.data(), data.length()); + if (!data.empty()) { + if (HasGzipHeader(data) || HasBrotliHeader(data)) { + base::RefCountedString* bytes_string = new base::RefCountedString(); + Decompress(data, &(bytes_string->data())); + bytes = bytes_string; + } else { + bytes = new base::RefCountedStaticMemory(data.data(), data.length()); + } + } } - return bytes; } @@ -635,7 +639,9 @@ std::string ResourceBundle::DecompressDataResourceScaled( int resource_id, ScaleFactor scaling_factor) { - return Decompress(GetRawDataResourceForScale(resource_id, scaling_factor)); + std::string output; + Decompress(GetRawDataResourceForScale(resource_id, scaling_factor), &output); + return output; } std::string ResourceBundle::DecompressLocalizedDataResource(int resource_id) { @@ -653,7 +659,9 @@ data = GetRawDataResource(resource_id); } } - return Decompress(data); + std::string output; + Decompress(data, &output); + return output; } bool ResourceBundle::IsGzipped(int resource_id) const {
diff --git a/ui/base/resource/resource_bundle.h b/ui/base/resource/resource_bundle.h index f5a0917..a342b41 100644 --- a/ui/base/resource/resource_bundle.h +++ b/ui/base/resource/resource_bundle.h
@@ -231,10 +231,10 @@ bool IsBrotli(int resource_id) const; // Loads the raw bytes of a data resource nearest the scale factor - // |scale_factor| into |bytes|, without doing any processing or - // interpretation of the resource. Use ResourceHandle::SCALE_FACTOR_NONE - // for scale independent image resources (such as wallpaper). - // Returns NULL if we fail to read the resource. + // |scale_factor| into |bytes|. If the resource is compressed, decompress + // before returning. Use ResourceHandle::SCALE_FACTOR_NONE for scale + // independent image resources (such as wallpaper). Returns nullptr if we fail + // to read the resource. base::RefCountedMemory* LoadDataResourceBytesForScale( int resource_id, ScaleFactor scale_factor) const;
diff --git a/ui/base/resource/resource_bundle_unittest.cc b/ui/base/resource/resource_bundle_unittest.cc index 4ba4897c3..71cc9102 100644 --- a/ui/base/resource/resource_bundle_unittest.cc +++ b/ui/base/resource/resource_bundle_unittest.cc
@@ -398,9 +398,40 @@ DISALLOW_COPY_AND_ASSIGN(ResourceBundleImageTest); }; +TEST_F(ResourceBundleImageTest, LoadDataResourceBytes) { + base::FilePath data_path = dir_path().Append(FILE_PATH_LITERAL("sample.pak")); + + // Dump contents into the pak files. + ASSERT_EQ(base::WriteFile(data_path, kSampleCompressPakContentsV5, + kSampleCompressPakSizeV5), + static_cast<int>(kSampleCompressPakSizeV5)); + + // Load pak file. + ResourceBundle* resource_bundle = CreateResourceBundleWithEmptyLocalePak(); + resource_bundle->AddDataPackFromPath(data_path, SCALE_FACTOR_NONE); + + // Test normal uncompressed data. + scoped_refptr<base::RefCountedMemory> resource = + resource_bundle->LoadDataResourceBytes(4); + EXPECT_EQ("this is id 4", + std::string(resource->front_as<char>(), resource->size())); + + // Test the brotli data. + scoped_refptr<base::RefCountedMemory> brotli_resource = + resource_bundle->LoadDataResourceBytes(6); + EXPECT_EQ("this is id 6", std::string(brotli_resource->front_as<char>(), + brotli_resource->size())); + + // Test the gzipped data. + scoped_refptr<base::RefCountedMemory> gzip_resource = + resource_bundle->LoadDataResourceBytes(8); + EXPECT_EQ("this is id 8", std::string(gzip_resource->front_as<char>(), + gzip_resource->size())); +} + // Verify that we don't crash when trying to load a resource that is not found. // In some cases, we fail to mmap resources.pak, but try to keep going anyway. -TEST_F(ResourceBundleImageTest, LoadDataResourceBytes) { +TEST_F(ResourceBundleImageTest, LoadDataResourceBytesNotFound) { base::FilePath data_path = dir_path().Append(FILE_PATH_LITERAL("sample.pak")); // Dump contents into the pak files.
diff --git a/ui/base/win/session_change_observer.cc b/ui/base/win/session_change_observer.cc index 9fe8503..f848e25 100644 --- a/ui/base/win/session_change_observer.cc +++ b/ui/base/win/session_change_observer.cc
@@ -37,8 +37,8 @@ base::IgnoreResult(&WTSRegisterSessionNotification), gfx::SingletonHwnd::GetInstance()->hwnd(), NOTIFY_FOR_THIS_SESSION); - base::CreateCOMSTATaskRunnerWithTraits({})->PostTask( - FROM_HERE, std::move(wts_register)); + base::CreateCOMSTATaskRunner({base::ThreadPool()}) + ->PostTask(FROM_HERE, std::move(wts_register)); } ~WtsRegistrationNotificationManager() { RemoveSingletonHwndObserver(); }
diff --git a/ui/display/win/color_profile_reader.cc b/ui/display/win/color_profile_reader.cc index a2b4f1b4..b59d683d 100644 --- a/ui/display/win/color_profile_reader.cc +++ b/ui/display/win/color_profile_reader.cc
@@ -61,8 +61,9 @@ return; update_in_flight_ = true; - base::PostTaskWithTraitsAndReplyWithResult( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, + base::PostTaskAndReplyWithResult( + FROM_HERE, + {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT}, base::Bind(&ColorProfileReader::ReadProfilesOnBackgroundThread, new_device_to_path_map), base::Bind(&ColorProfileReader::ReadProfilesCompleted,
diff --git a/ui/events/blink/blink_features.cc b/ui/events/blink/blink_features.cc index b173f77..468ae89b 100644 --- a/ui/events/blink/blink_features.cc +++ b/ui/events/blink/blink_features.cc
@@ -16,7 +16,7 @@ base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kUpdateHoverAtBeginFrame{"UpdateHoverAtBeginFrame", - base::FEATURE_ENABLED_BY_DEFAULT}; + base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kCompositorTouchAction{"CompositorTouchAction", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/ui/events/ozone/device/device_manager_manual.cc b/ui/events/ozone/device/device_manager_manual.cc index f4887fd..c179021 100644 --- a/ui/events/ozone/device/device_manager_manual.cc +++ b/ui/events/ozone/device/device_manager_manual.cc
@@ -34,8 +34,8 @@ } // namespace DeviceManagerManual::DeviceManagerManual() - : blocking_task_runner_( - base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()})), + : blocking_task_runner_(base::CreateSequencedTaskRunner( + {base::ThreadPool(), base::MayBlock()})), watcher_(new base::FilePathWatcher, base::OnTaskRunnerDeleter(blocking_task_runner_)), weak_ptr_factory_(this) {} @@ -81,9 +81,10 @@ void DeviceManagerManual::InitiateScanDevices() { std::vector<base::FilePath>* result = new std::vector<base::FilePath>(); - base::PostTaskWithTraitsAndReply( + base::PostTaskAndReply( FROM_HERE, - {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + {base::ThreadPool(), base::MayBlock(), + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, base::BindOnce(&ScanDevicesOnWorkerThread, result), base::BindOnce(&DeviceManagerManual::OnDevicesScanned, weak_ptr_factory_.GetWeakPtr(), base::Owned(result)));
diff --git a/ui/events/ozone/evdev/libgestures_glue/gesture_feedback.cc b/ui/events/ozone/evdev/libgestures_glue/gesture_feedback.cc index 3836f7f..2da19db 100644 --- a/ui/events/ozone/evdev/libgestures_glue/gesture_feedback.cc +++ b/ui/events/ozone/evdev/libgestures_glue/gesture_feedback.cc
@@ -237,9 +237,9 @@ } // Compress touchpad/mouse logs asynchronously - base::PostTaskWithTraitsAndReply( + base::PostTaskAndReply( FROM_HERE, - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, + {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, base::BindOnce(&CompressDumpedLog, base::Passed(&log_paths_to_be_compressed)),
diff --git a/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc b/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc index d9657b6f..be7d4b7a 100644 --- a/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc +++ b/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc
@@ -687,12 +687,12 @@ } LoadKeymapCallback reply_callback = base::BindOnce( &XkbKeyboardLayoutEngine::OnKeymapLoaded, weak_ptr_factory_.GetWeakPtr()); - base::PostTaskWithTraits( - FROM_HERE, - {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, - base::BindOnce(&LoadKeymap, layout_name, - base::ThreadTaskRunnerHandle::Get(), - std::move(reply_callback))); + base::PostTask(FROM_HERE, + {base::ThreadPool(), base::MayBlock(), + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + base::BindOnce(&LoadKeymap, layout_name, + base::ThreadTaskRunnerHandle::Get(), + std::move(reply_callback))); #else NOTIMPLEMENTED(); #endif // defined(OS_CHROMEOS)
diff --git a/ui/events/platform/x11/x11_hotplug_event_handler.cc b/ui/events/platform/x11/x11_hotplug_event_handler.cc index 6d6b14f..8a30e23 100644 --- a/ui/events/platform/x11/x11_hotplug_event_handler.cc +++ b/ui/events/platform/x11/x11_hotplug_event_handler.cc
@@ -444,9 +444,10 @@ // Parse the device information asynchronously since this operation may block. // Once the device information is extracted the parsed devices will be // returned via the callbacks. - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, - {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + {base::ThreadPool(), base::MayBlock(), + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, base::BindOnce(&HandleHotplugEventInWorker, device_infos, display_state, base::ThreadTaskRunnerHandle::Get(), callbacks)); }
diff --git a/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js b/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js index c547ac5c..1f5a9a9 100644 --- a/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js +++ b/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js
@@ -652,19 +652,14 @@ } else { item.sourceMessage = entries.length.toString(); } - // TODO(crbug.com/947388) Use VolumeManager/getLocationInfo - // for i18n translations of the path name. - let destinationName = null; - if (destinationEntry instanceof VolumeEntry) { - destinationName = destinationEntry.name; - } else { - destinationName = destinationEntry.fullPath; - } - if (destinationName) { - item.destinationMessage = destinationName.replace(/^\//, ''); - item.subMessage = - strf('TO_FOLDER_NAME', item.destinationMessage); - } + // Store the destination name for display in messages. + const destinationLocationInfo = + this.volumeManager_.getLocationInfo(destinationEntry); + const destinationName = util.getEntryLabel( + destinationLocationInfo, destinationEntry); + item.destinationMessage = destinationName; + item.subMessage = + strf('TO_FOLDER_NAME', item.destinationMessage); this.progressCenter_.updateItem(item); // Check if cross share is needed or not. return this.getMultiProfileShareEntries_(entries);
diff --git a/ui/message_center/message_center_impl.cc b/ui/message_center/message_center_impl.cc index ae9c596..6b0745b 100644 --- a/ui/message_center/message_center_impl.cc +++ b/ui/message_center/message_center_impl.cc
@@ -186,15 +186,16 @@ // |notification_list| will replace the notification instead of adding new. // This is essentially an update rather than addition. bool already_exists = (notification_list_->GetNotificationById(id) != NULL); + if (already_exists) { + UpdateNotification(id, std::move(notification)); + return; + } + notification_list_->AddNotification(std::move(notification)); visible_notifications_ = notification_list_->GetVisibleNotifications(blockers_); - for (auto& observer : observer_list_) { - if (already_exists) - observer.OnNotificationUpdated(id); - else - observer.OnNotificationAdded(id); + observer.OnNotificationAdded(id); } }
diff --git a/ui/message_center/message_center_impl_unittest.cc b/ui/message_center/message_center_impl_unittest.cc index 6b05dc59..fdb8635 100644 --- a/ui/message_center/message_center_impl_unittest.cc +++ b/ui/message_center/message_center_impl_unittest.cc
@@ -457,6 +457,35 @@ base::MessageLoopCurrent::Get()->SetTaskRunner(old_task_runner); } +TEST_F(MessageCenterImplTest, Renotify) { + message_center()->SetHasMessageCenterView(true); + const std::string id("id"); + + // Add notification initially. + std::unique_ptr<Notification> notification = CreateSimpleNotification(id); + message_center()->AddNotification(std::move(notification)); + auto popups = message_center()->GetPopupNotifications(); + EXPECT_EQ(1u, popups.size()); + EXPECT_TRUE(PopupNotificationsContain(popups, id)); + + // Mark notification as shown. + message_center()->MarkSinglePopupAsShown(id, true); + EXPECT_EQ(0u, message_center()->GetPopupNotifications().size()); + + // Add notification again without |renotify| flag. It should not pop-up again. + notification = CreateSimpleNotification(id); + message_center()->AddNotification(std::move(notification)); + EXPECT_EQ(0u, message_center()->GetPopupNotifications().size()); + + // Add notification again with |renotify| flag. It should pop-up again. + notification = CreateSimpleNotification(id); + notification->set_renotify(true); + message_center()->AddNotification(std::move(notification)); + popups = message_center()->GetPopupNotifications(); + EXPECT_EQ(1u, popups.size()); + EXPECT_TRUE(PopupNotificationsContain(popups, id)); +} + TEST_F(MessageCenterImplTest, NotificationBlocker) { NotifierId notifier_id(NotifierType::APPLICATION, "app1"); // Multiple blockers to verify the case that one blocker blocks but another
diff --git a/ui/ozone/platform/drm/gpu/gbm_surfaceless.cc b/ui/ozone/platform/drm/gpu/gbm_surfaceless.cc index dd5d9e8..07b16ea 100644 --- a/ui/ozone/platform/drm/gpu/gbm_surfaceless.cc +++ b/ui/ozone/platform/drm/gpu/gbm_surfaceless.cc
@@ -155,10 +155,11 @@ base::OnceClosure fence_retired_callback = base::BindOnce( &GbmSurfaceless::FenceRetired, weak_factory_.GetWeakPtr(), frame); - base::PostTaskWithTraitsAndReply( - FROM_HERE, - {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, - std::move(fence_wait_task), std::move(fence_retired_callback)); + base::PostTaskAndReply(FROM_HERE, + {base::ThreadPool(), base::MayBlock(), + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + std::move(fence_wait_task), + std::move(fence_retired_callback)); } void GbmSurfaceless::PostSubBufferAsync(
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc index 4cca0e5..3a058b1 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc +++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc
@@ -121,9 +121,10 @@ void HardwareDisplayPlaneManagerLegacy::RequestPlanesReadyCallback( DrmOverlayPlaneList planes, base::OnceCallback<void(DrmOverlayPlaneList planes)> callback) { - base::PostTaskWithTraitsAndReplyWithResult( + base::PostTaskAndReplyWithResult( FROM_HERE, - {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + {base::ThreadPool(), base::MayBlock(), + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, base::BindOnce(&WaitForPlaneFences, std::move(planes)), std::move(callback)); }
diff --git a/ui/ozone/platform/drm/host/drm_display_host_manager.cc b/ui/ozone/platform/drm/host/drm_display_host_manager.cc index 666b731..89972f00 100644 --- a/ui/ozone/platform/drm/host/drm_display_host_manager.cc +++ b/ui/ozone/platform/drm/host/drm_display_host_manager.cc
@@ -252,9 +252,9 @@ switch (event.action_type) { case DeviceEvent::ADD: if (drm_devices_.find(event.path) == drm_devices_.end()) { - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, - {base::MayBlock(), + {base::ThreadPool(), base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, base::BindOnce( &OpenDeviceAsync, event.path,
diff --git a/ui/ozone/platform/headless/headless_surface_factory.cc b/ui/ozone/platform/headless/headless_surface_factory.cc index cba06426..4ec93cec 100644 --- a/ui/ozone/platform/headless/headless_surface_factory.cc +++ b/ui/ozone/platform/headless/headless_surface_factory.cc
@@ -63,10 +63,10 @@ // TODO(dnicoara) Use SkImage instead to potentially avoid a copy. // See crbug.com/361605 for details. if (surface_->getCanvas()->readPixels(bitmap, 0, 0)) { - base::PostTaskWithTraits( - FROM_HERE, - {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, - base::BindOnce(&WriteDataToFile, base_path_, bitmap)); + base::PostTask(FROM_HERE, + {base::ThreadPool(), base::MayBlock(), + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + base::BindOnce(&WriteDataToFile, base_path_, bitmap)); } } std::unique_ptr<gfx::VSyncProvider> CreateVSyncProvider() override {
diff --git a/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc b/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc index 70ea08a..24df94f 100644 --- a/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc +++ b/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc
@@ -118,10 +118,11 @@ base::OnceClosure fence_retired_callback = base::BindOnce( &GbmSurfacelessWayland::FenceRetired, weak_factory_.GetWeakPtr(), frame); - base::PostTaskWithTraitsAndReply( - FROM_HERE, - {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, - std::move(fence_wait_task), std::move(fence_retired_callback)); + base::PostTaskAndReply(FROM_HERE, + {base::ThreadPool(), base::MayBlock(), + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + std::move(fence_wait_task), + std::move(fence_retired_callback)); } void GbmSurfacelessWayland::PostSubBufferAsync(
diff --git a/ui/ozone/platform/wayland/test/test_data_offer.cc b/ui/ozone/platform/wayland/test/test_data_offer.cc index f2d86fab1..64e8b4f 100644 --- a/ui/ozone/platform/wayland/test/test_data_offer.cc +++ b/ui/ozone/platform/wayland/test/test_data_offer.cc
@@ -62,8 +62,8 @@ TestDataOffer::TestDataOffer(wl_resource* resource) : ServerObject(resource), - task_runner_( - base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()})), + task_runner_(base::CreateSequencedTaskRunner( + {base::ThreadPool(), base::MayBlock()})), write_data_weak_ptr_factory_(this) {} TestDataOffer::~TestDataOffer() {}
diff --git a/ui/ozone/platform/wayland/test/test_data_source.cc b/ui/ozone/platform/wayland/test/test_data_source.cc index 797a2bf..6757ff3 100644 --- a/ui/ozone/platform/wayland/test/test_data_source.cc +++ b/ui/ozone/platform/wayland/test/test_data_source.cc
@@ -63,8 +63,8 @@ TestDataSource::TestDataSource(wl_resource* resource) : ServerObject(resource), - task_runner_( - base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()})) {} + task_runner_(base::CreateSequencedTaskRunner( + {base::ThreadPool(), base::MayBlock()})) {} TestDataSource::~TestDataSource() {}
diff --git a/ui/shell_dialogs/base_shell_dialog_win.cc b/ui/shell_dialogs/base_shell_dialog_win.cc index 6ff0ac2..d434d86 100644 --- a/ui/shell_dialogs/base_shell_dialog_win.cc +++ b/ui/shell_dialogs/base_shell_dialog_win.cc
@@ -19,8 +19,8 @@ // have a situation where a modal dialog in one window blocks the appearance // of a modal dialog in another. scoped_refptr<base::SingleThreadTaskRunner> CreateDialogTaskRunner() { - return CreateCOMSTATaskRunnerWithTraits( - {base::TaskPriority::USER_BLOCKING, + return CreateCOMSTATaskRunner( + {base::ThreadPool(), base::TaskPriority::USER_BLOCKING, base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN, base::MayBlock()}, base::SingleThreadTaskRunnerThreadMode::DEDICATED); }
diff --git a/ui/snapshot/snapshot.cc b/ui/snapshot/snapshot.cc index 1c4af953..4e276d1 100644 --- a/ui/snapshot/snapshot.cc +++ b/ui/snapshot/snapshot.cc
@@ -42,8 +42,9 @@ const base::Callback<void(scoped_refptr<base::RefCountedMemory> data)>& callback, gfx::Image image) { - base::PostTaskWithTraitsAndReplyWithResult( - FROM_HERE, {base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + base::PostTaskAndReplyWithResult( + FROM_HERE, + {base::ThreadPool(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, base::Bind(encode_func, std::move(image)), callback); }
diff --git a/ui/snapshot/snapshot_async.cc b/ui/snapshot/snapshot_async.cc index 713a2ae..ffb65ab 100644 --- a/ui/snapshot/snapshot_async.cc +++ b/ui/snapshot/snapshot_async.cc
@@ -48,8 +48,9 @@ // from GPU. Image scaling is implemented in content::GlHelper, but it's can't // be used here because it's not in content/public. Move the scaling code // somewhere so that it can be reused here. - base::PostTaskWithTraitsAndReplyWithResult( - FROM_HERE, {base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + base::PostTaskAndReplyWithResult( + FROM_HERE, + {base::ThreadPool(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, base::Bind(ScaleBitmap, bitmap, target_size), base::Bind(&OnFrameScalingFinished, callback)); }
diff --git a/ui/views/accessibility/ax_aura_obj_cache.cc b/ui/views/accessibility/ax_aura_obj_cache.cc index fe2916a..8f15d55 100644 --- a/ui/views/accessibility/ax_aura_obj_cache.cc +++ b/ui/views/accessibility/ax_aura_obj_cache.cc
@@ -6,6 +6,7 @@ #include "base/no_destructor.h" #include "base/strings/string_util.h" +#include "ui/accessibility/ax_enums.mojom.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/client/focus_client.h" #include "ui/aura/window.h"
diff --git a/ui/views/accessibility/ax_aura_obj_cache.h b/ui/views/accessibility/ax_aura_obj_cache.h index a84bb4d..e19a221 100644 --- a/ui/views/accessibility/ax_aura_obj_cache.h +++ b/ui/views/accessibility/ax_aura_obj_cache.h
@@ -13,7 +13,7 @@ #include <vector> #include "base/macros.h" -#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_enums.mojom-forward.h" #include "ui/aura/client/focus_change_observer.h" #include "ui/views/views_export.h"
diff --git a/ui/views/accessibility/ax_event_manager.h b/ui/views/accessibility/ax_event_manager.h index 6eef3ef..1ccb2bf 100644 --- a/ui/views/accessibility/ax_event_manager.h +++ b/ui/views/accessibility/ax_event_manager.h
@@ -7,7 +7,7 @@ #include "base/macros.h" #include "base/observer_list.h" -#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_enums.mojom-forward.h" #include "ui/views/views_export.h" namespace views {
diff --git a/ui/views/accessibility/ax_event_observer.h b/ui/views/accessibility/ax_event_observer.h index 5fc3c812..9dfd0a2 100644 --- a/ui/views/accessibility/ax_event_observer.h +++ b/ui/views/accessibility/ax_event_observer.h
@@ -6,7 +6,7 @@ #define UI_VIEWS_ACCESSIBILITY_AX_EVENT_OBSERVER_H_ #include "base/observer_list_types.h" -#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_enums.mojom-forward.h" #include "ui/views/views_export.h" namespace views {
diff --git a/ui/views/accessibility/ax_virtual_view.h b/ui/views/accessibility/ax_virtual_view.h index de69e08..3f32b0b 100644 --- a/ui/views/accessibility/ax_virtual_view.h +++ b/ui/views/accessibility/ax_virtual_view.h
@@ -14,7 +14,7 @@ #include "base/callback_forward.h" #include "base/macros.h" #include "base/strings/string16.h" -#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_enums.mojom-forward.h" #include "ui/accessibility/ax_node_data.h" #include "ui/accessibility/platform/ax_platform_node_delegate_base.h" #include "ui/accessibility/platform/ax_unique_id.h"
diff --git a/ui/views/accessibility/ax_window_obj_wrapper.h b/ui/views/accessibility/ax_window_obj_wrapper.h index 2aed3d6..7b25c9bd 100644 --- a/ui/views/accessibility/ax_window_obj_wrapper.h +++ b/ui/views/accessibility/ax_window_obj_wrapper.h
@@ -8,7 +8,7 @@ #include <stdint.h> #include "base/macros.h" -#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_enums.mojom-forward.h" #include "ui/accessibility/platform/ax_unique_id.h" #include "ui/aura/window_observer.h" #include "ui/views/accessibility/ax_aura_obj_wrapper.h"
diff --git a/ui/views/accessibility/view_accessibility.cc b/ui/views/accessibility/view_accessibility.cc index 4bc4f406..30cb812 100644 --- a/ui/views/accessibility/view_accessibility.cc +++ b/ui/views/accessibility/view_accessibility.cc
@@ -9,6 +9,7 @@ #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" +#include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/platform/ax_platform_node.h" #include "ui/base/buildflags.h" #include "ui/views/view.h"
diff --git a/ui/views/accessibility/view_accessibility.h b/ui/views/accessibility/view_accessibility.h index 0eb196e..1c30893 100644 --- a/ui/views/accessibility/view_accessibility.h +++ b/ui/views/accessibility/view_accessibility.h
@@ -12,7 +12,7 @@ #include "base/macros.h" #include "base/strings/string16.h" #include "build/build_config.h" -#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_enums.mojom-forward.h" #include "ui/accessibility/ax_node_data.h" #include "ui/accessibility/platform/ax_unique_id.h" #include "ui/gfx/native_widget_types.h"
diff --git a/ui/views/accessibility/view_ax_platform_node_delegate.h b/ui/views/accessibility/view_ax_platform_node_delegate.h index d6fed0dd..bb06557 100644 --- a/ui/views/accessibility/view_ax_platform_node_delegate.h +++ b/ui/views/accessibility/view_ax_platform_node_delegate.h
@@ -10,7 +10,7 @@ #include "base/macros.h" #include "base/strings/string16.h" #include "build/build_config.h" -#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_enums.mojom-forward.h" #include "ui/accessibility/ax_node_data.h" #include "ui/accessibility/platform/ax_platform_node_delegate_base.h" #include "ui/gfx/geometry/rect.h"
diff --git a/ui/views/bubble/bubble_dialog_delegate_view.cc b/ui/views/bubble/bubble_dialog_delegate_view.cc index e7d3bbcb..8ce310e3 100644 --- a/ui/views/bubble/bubble_dialog_delegate_view.cc +++ b/ui/views/bubble/bubble_dialog_delegate_view.cc
@@ -8,6 +8,7 @@ #include "base/feature_list.h" #include "base/metrics/histogram_macros.h" #include "build/build_config.h" +#include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_node_data.h" #include "ui/base/default_style.h" #include "ui/base/resource/resource_bundle.h"
diff --git a/ui/views/bubble/bubble_dialog_delegate_view.h b/ui/views/bubble/bubble_dialog_delegate_view.h index 77288a2..97e965a 100644 --- a/ui/views/bubble/bubble_dialog_delegate_view.h +++ b/ui/views/bubble/bubble_dialog_delegate_view.h
@@ -10,7 +10,7 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "build/build_config.h" -#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_enums.mojom-forward.h" #include "ui/base/accelerators/accelerator.h" #include "ui/views/bubble/bubble_border.h" #include "ui/views/view_tracker.h"
diff --git a/ui/views/controls/native/native_view_host.cc b/ui/views/controls/native/native_view_host.cc index d6116fd..bc1cb3a 100644 --- a/ui/views/controls/native/native_view_host.cc +++ b/ui/views/controls/native/native_view_host.cc
@@ -5,6 +5,7 @@ #include "ui/views/controls/native/native_view_host.h" #include "base/logging.h" +#include "ui/accessibility/ax_enums.mojom.h" #include "ui/base/cursor/cursor.h" #include "ui/gfx/canvas.h" #include "ui/views/controls/native/native_view_host_wrapper.h"
diff --git a/ui/views/controls/slider_unittest.cc b/ui/views/controls/slider_unittest.cc index e8036f2..51ca3c4c 100644 --- a/ui/views/controls/slider_unittest.cc +++ b/ui/views/controls/slider_unittest.cc
@@ -14,6 +14,7 @@ #include "base/time/time.h" #include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/accessibility/ax_enums.mojom.h" #include "ui/events/event.h" #include "ui/events/gesture_event_details.h" #include "ui/events/keycodes/keyboard_codes.h"
diff --git a/ui/views/view.h b/ui/views/view.h index 75eecfb..3984bd5 100644 --- a/ui/views/view.h +++ b/ui/views/view.h
@@ -24,7 +24,7 @@ #include "base/macros.h" #include "build/build_config.h" #include "third_party/skia/include/core/SkPath.h" -#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_enums.mojom-forward.h" #include "ui/base/accelerators/accelerator.h" #include "ui/base/class_property.h" #include "ui/base/clipboard/clipboard_format_type.h"
diff --git a/ui/views/view_unittest.cc b/ui/views/view_unittest.cc index 02fdd039..dc0f44fa 100644 --- a/ui/views/view_unittest.cc +++ b/ui/views/view_unittest.cc
@@ -25,6 +25,7 @@ #include "build/build_config.h" #include "cc/paint/display_item_list.h" #include "components/viz/common/surfaces/parent_local_surface_id_allocator.h" +#include "ui/accessibility/ax_enums.mojom.h" #include "ui/base/accelerators/accelerator.h" #include "ui/base/clipboard/clipboard.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc index 4f4386a..9f23530 100644 --- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc +++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" +#include "ui/accessibility/ax_enums.mojom.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/client/cursor_client.h" #include "ui/aura/client/drag_drop_client.h"
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc index 7e31a1c1..0eedc26 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -377,7 +377,16 @@ } ui::ZOrderLevel DesktopWindowTreeHostWin::GetZOrderLevel() const { - return z_order_; + bool window_always_on_top = message_handler_->IsAlwaysOnTop(); + bool level_always_on_top = z_order_ != ui::ZOrderLevel::kNormal; + + if (window_always_on_top == level_always_on_top) + return z_order_; + + // If something external has forced a window to be always-on-top, map it to + // kFloatingWindow as a reasonable equivalent. + return window_always_on_top ? ui::ZOrderLevel::kFloatingWindow + : ui::ZOrderLevel::kNormal; } void DesktopWindowTreeHostWin::SetVisibleOnAllWorkspaces(bool always_visible) {
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc index b03a5bc..7c4f1e8 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
@@ -683,9 +683,10 @@ if (window_always_on_top == level_always_on_top) return z_order_; - // Something external has forced a window to be always-on-top; map it to + // If something external has forced a window to be always-on-top, map it to // kFloatingWindow as a reasonable equivalent. - return ui::ZOrderLevel::kFloatingWindow; + return window_always_on_top ? ui::ZOrderLevel::kFloatingWindow + : ui::ZOrderLevel::kNormal; } void DesktopWindowTreeHostX11::SetVisible(bool visible) {
diff --git a/ui/views/widget/widget_delegate.cc b/ui/views/widget/widget_delegate.cc index 703ee49..96ee046 100644 --- a/ui/views/widget/widget_delegate.cc +++ b/ui/views/widget/widget_delegate.cc
@@ -6,6 +6,7 @@ #include "base/logging.h" #include "base/strings/utf_string_conversions.h" +#include "ui/accessibility/ax_enums.mojom.h" #include "ui/gfx/image/image_skia.h" #include "ui/views/view.h" #include "ui/views/views_delegate.h"
diff --git a/ui/views/widget/widget_delegate.h b/ui/views/widget/widget_delegate.h index 7758573..e71776db 100644 --- a/ui/views/widget/widget_delegate.h +++ b/ui/views/widget/widget_delegate.h
@@ -9,7 +9,7 @@ #include <vector> #include "base/macros.h" -#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_enums.mojom-forward.h" #include "ui/base/ui_base_types.h" #include "ui/views/view.h" #include "ui/views/widget/widget.h"
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc index f6209967..c578a96b 100644 --- a/ui/views/win/hwnd_message_handler.cc +++ b/ui/views/win/hwnd_message_handler.cc
@@ -808,6 +808,10 @@ return fullscreen_handler_->fullscreen(); } +bool HWNDMessageHandler::IsAlwaysOnTop() const { + return (GetWindowLong(hwnd(), GWL_EXSTYLE) & WS_EX_TOPMOST) != 0; +} + bool HWNDMessageHandler::RunMoveLoop(const gfx::Vector2d& drag_offset, bool hide_on_escape) { ReleaseCapture();
diff --git a/ui/views/win/hwnd_message_handler.h b/ui/views/win/hwnd_message_handler.h index 6c4c93ed..3bccc5c 100644 --- a/ui/views/win/hwnd_message_handler.h +++ b/ui/views/win/hwnd_message_handler.h
@@ -137,6 +137,7 @@ bool IsMinimized() const; bool IsMaximized() const; bool IsFullscreen() const; + bool IsAlwaysOnTop() const; bool RunMoveLoop(const gfx::Vector2d& drag_offset, bool hide_on_escape); void EndMoveLoop();
diff --git a/ui/views/window/dialog_delegate.cc b/ui/views/window/dialog_delegate.cc index b397f2f..a173b43 100644 --- a/ui/views/window/dialog_delegate.cc +++ b/ui/views/window/dialog_delegate.cc
@@ -10,6 +10,7 @@ #include "base/logging.h" #include "base/metrics/histogram_macros.h" #include "build/build_config.h" +#include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_node_data.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/color_palette.h"
diff --git a/ui/views/window/dialog_delegate.h b/ui/views/window/dialog_delegate.h index 114e1f97..0eb49e1a 100644 --- a/ui/views/window/dialog_delegate.h +++ b/ui/views/window/dialog_delegate.h
@@ -11,7 +11,7 @@ #include "base/macros.h" #include "base/strings/string16.h" #include "base/time/time.h" -#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_enums.mojom-forward.h" #include "ui/base/ui_base_types.h" #include "ui/views/views_export.h" #include "ui/views/widget/widget.h"
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/mojo_api.js b/ui/webui/resources/cr_components/chromeos/multidevice_setup/mojo_api.js index 1bcf093..c344992 100644 --- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/mojo_api.js +++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/mojo_api.js
@@ -6,26 +6,26 @@ /** @interface */ class MojoInterfaceProvider { /** - * @return {!chromeos.multideviceSetup.mojom.MultiDeviceSetupProxy} + * @return {!chromeos.multideviceSetup.mojom.MultiDeviceSetupRemote} */ - getMojoServiceProxy() {} + getMojoServiceRemote() {} } /** @implements {multidevice_setup.MojoInterfaceProvider} */ class MojoInterfaceProviderImpl { constructor() { - /** @private {?chromeos.multideviceSetup.mojom.MultiDeviceSetupProxy} */ - this.proxy_ = null; + /** @private {?chromeos.multideviceSetup.mojom.MultiDeviceSetupRemote} */ + this.remote_ = null; } /** @override */ - getMojoServiceProxy() { - if (!this.proxy_) { - this.proxy_ = - chromeos.multideviceSetup.mojom.MultiDeviceSetup.getProxy(); + getMojoServiceRemote() { + if (!this.remote_) { + this.remote_ = + chromeos.multideviceSetup.mojom.MultiDeviceSetup.getRemote(); } - return this.proxy_; + return this.remote_; } }
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/multidevice_setup.js b/ui/webui/resources/cr_components/chromeos/multidevice_setup/multidevice_setup.js index b8455ca..9aa8509 100644 --- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/multidevice_setup.js +++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/multidevice_setup.js
@@ -149,7 +149,7 @@ }, initializeSetupFlow: function() { - this.mojoInterfaceProvider_.getMojoServiceProxy() + this.mojoInterfaceProvider_.getMojoServiceRemote() .getEligibleHostDevices() .then((responseParams) => { if (responseParams.eligibleHostDevices.length == 0) {
diff --git a/ui/webui/resources/cr_components/chromeos/network/OWNERS b/ui/webui/resources/cr_components/chromeos/network/OWNERS new file mode 100644 index 0000000..c970217 --- /dev/null +++ b/ui/webui/resources/cr_components/chromeos/network/OWNERS
@@ -0,0 +1,4 @@ +khorimoto@chromium.org +stevenjb@chromium.org + +# COMPONENT: UI>Shell>Networking
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_password_input.js b/ui/webui/resources/cr_components/chromeos/network/network_password_input.js index 647cf6ab..dbb7c595b 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_password_input.js +++ b/ui/webui/resources/cr_components/chromeos/network/network_password_input.js
@@ -62,6 +62,10 @@ focus: function() { this.$$('cr-input').focus(); + + // If the input has any contents, the should be selected when focus is + // applied. + this.$$('cr-input').select(); }, /** @@ -164,6 +168,4 @@ onInput_: function(e) { this.restoreUnknown_ = false; }, - - });
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_siminfo.html b/ui/webui/resources/cr_components/chromeos/network/network_siminfo.html index ad150c8..a0a5d3b7 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_siminfo.html +++ b/ui/webui/resources/cr_components/chromeos/network/network_siminfo.html
@@ -53,7 +53,7 @@ <!-- SIM missing UI --> <div class="property-box two-line" - hidden$="[[hasSim_(deviceStateProperties_)]]"> + hidden$="[[!showSimMissing_(deviceStateProperties_)]]"> <div class="start layout horizontal center"> <iron-icon icon="cr:sim-card-alert"></iron-icon> <div class="error">[[i18n('networkSimCardMissing')]]</div>
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_siminfo.js b/ui/webui/resources/cr_components/chromeos/network/network_siminfo.js index ed4ec31..ae7c5ad 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_siminfo.js +++ b/ui/webui/resources/cr_components/chromeos/network/network_siminfo.js
@@ -166,7 +166,7 @@ if (this.$.enterPinDialog.open) { this.$.enterPin.focus(); } else if (this.$.changePinDialog.open) { - this.$.changePinOld.focus()(); + this.$.changePinOld.focus(); } else if (this.$.unlockPinDialog.open) { this.$.unlockPin.focus(); } else if (this.$.unlockPukDialog.open) { @@ -485,9 +485,9 @@ * @return {boolean} * @private */ - hasSim_: function() { + showSimMissing_: function() { return !!this.deviceStateProperties_ && - !!this.deviceStateProperties_.simLockStatus; + !this.deviceStateProperties_.simLockStatus; }, /**