diff --git a/AUTHORS b/AUTHORS index 15477cbc..e1b3fe7 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -19,6 +19,7 @@ Abhishek Kanike <abhishek.ka@samsung.com> Abhishek Singh <abhi.rathore@samsung.com> Adam Bonner <abonner-chromium@solscope.com> +Adam Bujalski <abujalski@gmail.com> Adam Kallai <kadam@inf.u-szeged.hu> Adam Roben <adam@github.com> Adam Treat <adam.treat@samsung.com>
diff --git a/DEPS b/DEPS index 79a6cf74..90c20c7 100644 --- a/DEPS +++ b/DEPS
@@ -142,11 +142,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': 'effee206579608fad40658e608db4aa13910f76f', + 'skia_revision': '4d03689edb5dfdce22f11414d2351ce2b221a410', # 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': 'c382128adc7b4bb1678d6357bbbc993e62afce38', + 'v8_revision': 'da069071ec861916b268f20bcc21d2d440299a74', # 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. @@ -154,15 +154,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': '2afc3398b3d824c1ca7d9a7066f8c10ae52f03c6', + 'angle_revision': 'da904484bfc696193c15d89c9c6e847afeb978cc', # 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': '142f4581ffc9a90213c2c80496de6d3436208e94', + 'swiftshader_revision': 'a29aa7717ff8963249d44e2163b78689dfde7565', # 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': 'c2cdb2edb607b9907d8f2360cce5825cfef2828b', + 'pdfium_revision': '815726bc4c6997a9054ad124b2b6b82e45008ac5', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -205,7 +205,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': '2c752374f1ec682dc41e179278071bc8621bff3e', + 'catapult_revision': '63f7fcc05ac1011f52d81e926f8638e7aea91133', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -273,11 +273,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'shaderc_revision': '30d8262c71d9267c213103cf37a412fd6fd4c483', + 'shaderc_revision': '23bbb3211ecee065c118b14b4c8bd13f0a61c04d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': 'ce32a94b3711d6a94f59deb2876f5507a4b674fc', + 'dawn_revision': '4886403b610c39e2fa92463503b5b6d872b82736', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -806,7 +806,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '16584a68b378caef055f936da36d044aee87865d', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '104b067af6a2eea63e010a4d2a3038c59f178436', 'condition': 'checkout_linux', }, @@ -900,7 +900,7 @@ }, 'src/third_party/glslang/src': - Var('chromium_git') + '/external/github.com/KhronosGroup/glslang.git' + '@' + '974a586688c169c5724faf34ed5ed6c8e7563711', + Var('chromium_git') + '/external/github.com/KhronosGroup/glslang.git' + '@' + '22683b409e6df419da940df561b24b4b5d8ab90a', 'src/third_party/google_toolbox_for_mac/src': { 'url': Var('chromium_git') + '/external/github.com/google/google-toolbox-for-mac.git' + '@' + Var('google_toolbox_for_mac_revision'), @@ -1080,13 +1080,13 @@ }, 'src/third_party/libvpx/source/libvpx': - Var('chromium_git') + '/webm/libvpx.git' + '@' + '30e7f9d856eb1cc6df895f6d9562493e04f6116d', + Var('chromium_git') + '/webm/libvpx.git' + '@' + 'cd9f1763c861edfd86d2814e029a34f3ce821e72', 'src/third_party/libwebm/source': Var('chromium_git') + '/webm/libwebm.git' + '@' + '51ca718c3adf0ddedacd7df25fe45f67dc5a9ce1', 'src/third_party/libyuv': - Var('chromium_git') + '/libyuv/libyuv.git' + '@' + 'b36c86fdfe746d7be904c3a565b047b24d58087e', # from r1714 + Var('chromium_git') + '/libyuv/libyuv.git' + '@' + '09cfb2bbd61448da73a65cdf8eac3594290522bf', # from r1714 'src/third_party/lighttpd': { 'url': Var('chromium_git') + '/chromium/deps/lighttpd.git' + '@' + Var('lighttpd_revision'), @@ -1191,7 +1191,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '6ce3dc661e2c8757ae4b29633c21c2146179b7e5', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'd1674c0531e0260965667cd9c70609bc1c4cccb2', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1359,7 +1359,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '6f0b34abee8dba611c253738d955c59f703c147a', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '14be7993c6cb04d2c26bad9762c4b09390e2aa1d', + Var('webrtc_git') + '/src.git' + '@' + '02d7d353a90bccc6fdd0e517af31fab50944d31c', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1400,7 +1400,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@9c72a3d95c97c8047c931fe8f1b75a2d4ba99c9f', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@dbcafbd04544f460eadeccb3a7f8f5b6149937cc', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/browser/aw_browser_context.cc b/android_webview/browser/aw_browser_context.cc index 9e17af6a..c6a08f1f 100644 --- a/android_webview/browser/aw_browser_context.cc +++ b/android_webview/browser/aw_browser_context.cc
@@ -8,6 +8,7 @@ #include <string> #include <utility> +#include "android_webview/browser/aw_browser_policy_connector.h" #include "android_webview/browser/aw_download_manager_delegate.h" #include "android_webview/browser/aw_form_database_service.h" #include "android_webview/browser/aw_metrics_service_client.h" @@ -24,11 +25,18 @@ #include "base/single_thread_task_runner.h" #include "base/task/post_task.h" #include "components/autofill/core/browser/autocomplete_history_manager.h" +#include "components/autofill/core/common/autofill_prefs.h" #include "components/download/public/common/in_progress_download_manager.h" #include "components/keyed_service/core/simple_key_map.h" #include "components/policy/core/browser/browser_policy_connector_base.h" +#include "components/policy/core/browser/configuration_policy_pref_store.h" +#include "components/policy/core/browser/url_blacklist_manager.h" +#include "components/pref_registry/pref_registry_syncable.h" +#include "components/prefs/in_memory_pref_store.h" +#include "components/prefs/json_pref_store.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" +#include "components/prefs/pref_service_factory.h" #include "components/safe_browsing/triggers/trigger_manager.h" #include "components/url_formatter/url_fixer.h" #include "components/user_prefs/user_prefs.h" @@ -44,7 +52,6 @@ #include "net/proxy_resolution/proxy_resolution_service.h" #include "services/network/public/cpp/features.h" #include "services/preferences/tracked/segregated_pref_store.h" - using base::FilePath; using content::BrowserThread; @@ -100,22 +107,14 @@ } // namespace -AwBrowserContext::AwBrowserContext( - const base::FilePath path, - std::unique_ptr<PrefService> pref_service, - std::unique_ptr<policy::BrowserPolicyConnectorBase> policy_connector) - : context_storage_path_(path), - user_pref_service_(std::move(pref_service)), - browser_policy_connector_(std::move(policy_connector)), +AwBrowserContext::AwBrowserContext() + : context_storage_path_(GetContextStoragePath()), simple_factory_key_(GetPath(), IsOffTheRecord()) { DCHECK(!g_browser_context); g_browser_context = this; SimpleKeyMap::GetInstance()->Associate(this, &simple_factory_key_); - BrowserContext::Initialize(this, path); - - pref_change_registrar_.Init(user_pref_service_.get()); - user_prefs::UserPrefs::Set(this, user_pref_service_.get()); + BrowserContext::Initialize(this, context_storage_path_); // This constructor is entered during the creation of ContentBrowserClient, // before browser threads are created. Therefore any checks to enforce @@ -164,12 +163,66 @@ } // static +base::FilePath AwBrowserContext::GetContextStoragePath() { + base::FilePath user_data_dir; + if (!base::PathService::Get(base::DIR_ANDROID_APP_DATA, &user_data_dir)) { + NOTREACHED() << "Failed to get app data directory for Android WebView"; + } + + return user_data_dir; +} + +// static void AwBrowserContext::RegisterPrefs(PrefRegistrySimple* registry) { + safe_browsing::RegisterProfilePrefs(registry); + + // Register the Autocomplete Data Retention Policy pref. + // The default value '0' represents the latest Chrome major version on which + // the retention policy ran. By setting it to a low default value, we're + // making sure it runs now (as it only runs once per major version). + registry->RegisterIntegerPref( + autofill::prefs::kAutocompleteLastVersionRetentionPolicy, 0); + + // We only use the autocomplete feature of Autofill, which is controlled via + // the manager_delegate. We don't use the rest of Autofill, which is why it is + // hardcoded as disabled here. + // TODO(crbug.com/873740): The following also disables autocomplete. + // Investigate what the intended behavior is. + registry->RegisterBooleanPref(autofill::prefs::kAutofillProfileEnabled, + false); + registry->RegisterBooleanPref(autofill::prefs::kAutofillCreditCardEnabled, + false); + registry->RegisterStringPref(prefs::kAuthServerWhitelist, std::string()); registry->RegisterStringPref(prefs::kAuthAndroidNegotiateAccountType, std::string()); } +void AwBrowserContext::CreateUserPrefService() { + browser_policy_connector_ = std::make_unique<AwBrowserPolicyConnector>(); + + auto pref_registry = base::MakeRefCounted<user_prefs::PrefRegistrySyncable>(); + + RegisterPrefs(pref_registry.get()); + + PrefServiceFactory pref_service_factory; + pref_service_factory.set_user_prefs( + base::MakeRefCounted<InMemoryPrefStore>()); + + policy::URLBlacklistManager::RegisterProfilePrefs(pref_registry.get()); + pref_service_factory.set_managed_prefs( + base::MakeRefCounted<policy::ConfigurationPolicyPrefStore>( + browser_policy_connector_.get(), + browser_policy_connector_->GetPolicyService(), + browser_policy_connector_->GetHandlerList(), + policy::POLICY_LEVEL_MANDATORY)); + + user_pref_service_ = pref_service_factory.Create(pref_registry); + pref_change_registrar_.Init(user_pref_service_.get()); + + user_prefs::UserPrefs::Set(this, user_pref_service_.get()); +} + // static std::vector<std::string> AwBrowserContext::GetAuthSchemes() { // In Chrome this is configurable via the AuthSchemes policy. For WebView @@ -182,6 +235,8 @@ void AwBrowserContext::PreMainMessageLoopRun(net::NetLog* net_log) { FilePath cache_path = GetCacheDir(); + CreateUserPrefService(); + if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) { url_request_context_getter_ = new AwURLRequestContextGetter(cache_path, CreateProxyConfigService(),
diff --git a/android_webview/browser/aw_browser_context.h b/android_webview/browser/aw_browser_context.h index 0b7c78b..048b0ca 100644 --- a/android_webview/browser/aw_browser_context.h +++ b/android_webview/browser/aw_browser_context.h
@@ -23,7 +23,6 @@ class GURL; class PrefService; -class PrefRegistrySimple; namespace autofill { class AutocompleteHistoryManager; @@ -74,10 +73,7 @@ class AwBrowserContext : public content::BrowserContext, public visitedlink::VisitedLinkDelegate { public: - AwBrowserContext( - const base::FilePath path, - std::unique_ptr<PrefService> pref_service, - std::unique_ptr<policy::BrowserPolicyConnectorBase> policy_connector); + AwBrowserContext(); ~AwBrowserContext() override; // Currently only one instance per process is supported. @@ -92,6 +88,7 @@ // common/aw_paths.h (http://crbug.com/934184). static base::FilePath GetCacheDir(); static base::FilePath GetCookieStorePath(); + static base::FilePath GetContextStoragePath(); static void RegisterPrefs(PrefRegistrySimple* registry); @@ -148,6 +145,7 @@ private: void OnAuthPrefsChanged(); + void CreateUserPrefService(); // The file path where data for this context is persisted. base::FilePath context_storage_path_;
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc index 0b4382c1..0818133 100644 --- a/android_webview/browser/aw_content_browser_client.cc +++ b/android_webview/browser/aw_content_browser_client.cc
@@ -23,6 +23,7 @@ #include "android_webview/browser/aw_feature_list_creator.h" #include "android_webview/browser/aw_http_auth_handler.h" #include "android_webview/browser/aw_quota_permission_context.h" +#include "android_webview/browser/aw_resource_context.h" #include "android_webview/browser/aw_settings.h" #include "android_webview/browser/aw_speech_recognition_manager_delegate.h" #include "android_webview/browser/aw_web_contents_view_delegate.h" @@ -86,6 +87,7 @@ #include "content/public/browser/storage_partition.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_descriptors.h" +#include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "content/public/common/service_names.mojom.h" #include "content/public/common/url_constants.h" @@ -432,14 +434,7 @@ } AwBrowserContext* AwContentBrowserClient::InitBrowserContext() { - base::FilePath user_data_dir; - if (!base::PathService::Get(base::DIR_ANDROID_APP_DATA, &user_data_dir)) { - NOTREACHED() << "Failed to get app data directory for Android WebView"; - } - - browser_context_ = std::make_unique<AwBrowserContext>( - user_data_dir, aw_feature_list_creator_->TakePrefService(), - aw_feature_list_creator_->TakeBrowserPolicyConnector()); + browser_context_ = std::make_unique<AwBrowserContext>(); return browser_context_.get(); } @@ -866,6 +861,7 @@ content::NavigationUIData* navigation_ui_data, int frame_tree_node_id) { DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK(!base::FeatureList::IsEnabled(::features::kNavigationLoaderOnUI)); std::vector<std::unique_ptr<content::URLLoaderThrottle>> result; @@ -893,8 +889,40 @@ const bool is_reload = ui::PageTransitionCoreTypeIs( static_cast<ui::PageTransition>(request.transition_type), ui::PAGE_TRANSITION_RELOAD); - if (is_load_url || is_go_back_forward || is_reload) - result.push_back(std::make_unique<AwURLLoaderThrottle>(resource_context)); + if (is_load_url || is_go_back_forward || is_reload) { + result.push_back(std::make_unique<AwURLLoaderThrottle>( + static_cast<AwResourceContext*>(resource_context))); + } + } + + return result; +} + +std::vector<std::unique_ptr<content::URLLoaderThrottle>> +AwContentBrowserClient::CreateURLLoaderThrottles( + const network::ResourceRequest& request, + content::BrowserContext* browser_context, + const base::RepeatingCallback<content::WebContents*()>& wc_getter, + content::NavigationUIData* navigation_ui_data, + int frame_tree_node_id) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + std::vector<std::unique_ptr<content::URLLoaderThrottle>> result; + + if (request.resource_type == + static_cast<int>(content::ResourceType::kMainFrame)) { + const bool is_load_url = + request.transition_type & ui::PAGE_TRANSITION_FROM_API; + const bool is_go_back_forward = + request.transition_type & ui::PAGE_TRANSITION_FORWARD_BACK; + const bool is_reload = ui::PageTransitionCoreTypeIs( + static_cast<ui::PageTransition>(request.transition_type), + ui::PAGE_TRANSITION_RELOAD); + if (is_load_url || is_go_back_forward || is_reload) { + result.push_back( + std::make_unique<AwURLLoaderThrottle>(static_cast<AwResourceContext*>( + browser_context->GetResourceContext()))); + } } return result;
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h index f7cd6a6..d15ef02 100644 --- a/android_webview/browser/aw_content_browser_client.h +++ b/android_webview/browser/aw_content_browser_client.h
@@ -189,6 +189,13 @@ const base::RepeatingCallback<content::WebContents*()>& wc_getter, content::NavigationUIData* navigation_ui_data, int frame_tree_node_id) override; + std::vector<std::unique_ptr<content::URLLoaderThrottle>> + CreateURLLoaderThrottles( + const network::ResourceRequest& request, + content::BrowserContext* browser_context, + const base::RepeatingCallback<content::WebContents*()>& wc_getter, + content::NavigationUIData* navigation_ui_data, + int frame_tree_node_id) override; bool ShouldOverrideUrlLoading(int frame_tree_node_id, bool browser_initiated, const GURL& gurl,
diff --git a/android_webview/browser/aw_feature_list_creator.cc b/android_webview/browser/aw_feature_list_creator.cc index 217a7a0..be90a46 100644 --- a/android_webview/browser/aw_feature_list_creator.cc +++ b/android_webview/browser/aw_feature_list_creator.cc
@@ -11,7 +11,6 @@ #include <vector> #include "android_webview/browser/aw_browser_context.h" -#include "android_webview/browser/aw_browser_policy_connector.h" #include "android_webview/browser/aw_metrics_service_client.h" #include "android_webview/browser/aw_variations_seed_bridge.h" #include "android_webview/browser/net/aw_url_request_context_getter.h" @@ -28,8 +27,6 @@ #include "components/cdm/browser/media_drm_storage_impl.h" #include "components/metrics/metrics_pref_names.h" #include "components/metrics/metrics_service.h" -#include "components/policy/core/browser/configuration_policy_pref_store.h" -#include "components/policy/core/browser/url_blacklist_manager.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/in_memory_pref_store.h" #include "components/prefs/json_pref_store.h" @@ -73,32 +70,11 @@ return path; } -std::unique_ptr<PrefService> CreatePrefService( - policy::BrowserPolicyConnectorBase* browser_policy_connector) { +std::unique_ptr<PrefService> CreatePrefService() { auto pref_registry = base::MakeRefCounted<user_prefs::PrefRegistrySyncable>(); - // We only use the autocomplete feature of Autofill, which is controlled via - // the manager_delegate. We don't use the rest of Autofill, which is why it is - // hardcoded as disabled here. - // TODO(crbug.com/873740): The following also disables autocomplete. - // Investigate what the intended behavior is. - pref_registry->RegisterBooleanPref(autofill::prefs::kAutofillProfileEnabled, - false); - pref_registry->RegisterBooleanPref( - autofill::prefs::kAutofillCreditCardEnabled, false); - policy::URLBlacklistManager::RegisterProfilePrefs(pref_registry.get()); - - // Register the Autocomplete Data Retention Policy pref. - // The default value '0' represents the latest Chrome major version on which - // the retention policy ran. By setting it to a low default value, we're - // making sure it runs now (as it only runs once per major version). - pref_registry->RegisterIntegerPref( - autofill::prefs::kAutocompleteLastVersionRetentionPolicy, 0); - - AwBrowserContext::RegisterPrefs(pref_registry.get()); metrics::MetricsService::RegisterPrefs(pref_registry.get()); variations::VariationsService::RegisterPrefs(pref_registry.get()); - safe_browsing::RegisterProfilePrefs(pref_registry.get()); #if BUILDFLAG(ENABLE_MOJO_CDM) cdm::MediaDrmStorageImpl::RegisterProfilePrefs(pref_registry.get()); @@ -117,12 +93,7 @@ base::MakeRefCounted<InMemoryPrefStore>(), base::MakeRefCounted<JsonPrefStore>(GetPrefStorePath()), persistent_prefs, /*validation_delegate=*/nullptr)); - pref_service_factory.set_managed_prefs( - base::MakeRefCounted<policy::ConfigurationPolicyPrefStore>( - browser_policy_connector, - browser_policy_connector->GetPolicyService(), - browser_policy_connector->GetHandlerList(), - policy::POLICY_LEVEL_MANDATORY)); + pref_service_factory.set_read_error_callback( base::BindRepeating(&HandleReadError)); @@ -186,8 +157,7 @@ } void AwFeatureListCreator::CreateFeatureListAndFieldTrials() { - browser_policy_connector_ = std::make_unique<AwBrowserPolicyConnector>(); - local_state_ = CreatePrefService(browser_policy_connector_.get()); + local_state_ = CreatePrefService(); AwMetricsServiceClient::GetInstance()->Initialize(local_state_.get()); SetUpFieldTrials(); }
diff --git a/android_webview/browser/aw_feature_list_creator.h b/android_webview/browser/aw_feature_list_creator.h index 79c0e4a..0742ceaf 100644 --- a/android_webview/browser/aw_feature_list_creator.h +++ b/android_webview/browser/aw_feature_list_creator.h
@@ -35,13 +35,6 @@ return std::move(local_state_); } - // Passes ownership of the |browser_policy_connector_| to the caller. - std::unique_ptr<policy::BrowserPolicyConnectorBase> - TakeBrowserPolicyConnector() { - DCHECK(browser_policy_connector_); - return std::move(browser_policy_connector_); - } - private: // Sets up the field trials and related initialization. void SetUpFieldTrials(); @@ -63,10 +56,6 @@ std::unique_ptr<variations::VariationsFieldTrialCreator> variations_field_trial_creator_; - // If TakePrefService() is called, the caller will take the ownership - // of this variable. Stop using this variable afterwards. - std::unique_ptr<policy::BrowserPolicyConnectorBase> browser_policy_connector_; - std::unique_ptr<AwVariationsServiceClient> client_; DISALLOW_COPY_AND_ASSIGN(AwFeatureListCreator);
diff --git a/android_webview/browser/aw_resource_context.cc b/android_webview/browser/aw_resource_context.cc index 8de62b9c..cb8f0d7 100644 --- a/android_webview/browser/aw_resource_context.cc +++ b/android_webview/browser/aw_resource_context.cc
@@ -30,7 +30,6 @@ } std::string AwResourceContext::GetExtraHeaders(const GURL& url) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); if (!url.is_valid()) return std::string(); base::AutoLock scoped_lock(extra_headers_lock_); std::map<std::string, std::string>::iterator iter =
diff --git a/android_webview/browser/network_service/aw_url_loader_throttle.cc b/android_webview/browser/network_service/aw_url_loader_throttle.cc index cc96d28..94d2e9c1 100644 --- a/android_webview/browser/network_service/aw_url_loader_throttle.cc +++ b/android_webview/browser/network_service/aw_url_loader_throttle.cc
@@ -5,21 +5,17 @@ #include "android_webview/browser/network_service/aw_url_loader_throttle.h" #include "android_webview/browser/aw_resource_context.h" -#include "content/public/browser/browser_thread.h" #include "net/http/http_response_headers.h" namespace android_webview { -AwURLLoaderThrottle::AwURLLoaderThrottle( - content::ResourceContext* resource_context) - : aw_resource_context_(static_cast<AwResourceContext*>(resource_context)) {} +AwURLLoaderThrottle::AwURLLoaderThrottle(AwResourceContext* aw_resource_context) + : aw_resource_context_(aw_resource_context) {} AwURLLoaderThrottle::~AwURLLoaderThrottle() = default; void AwURLLoaderThrottle::WillStartRequest(network::ResourceRequest* request, bool* defer) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - AddExtraHeadersIfNeeded(request->url, &request->headers); } @@ -29,8 +25,6 @@ bool* defer, std::vector<std::string>* to_be_removed_request_headers, net::HttpRequestHeaders* modified_request_headers) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - AddExtraHeadersIfNeeded(redirect_info->new_url, modified_request_headers); }
diff --git a/android_webview/browser/network_service/aw_url_loader_throttle.h b/android_webview/browser/network_service/aw_url_loader_throttle.h index 38901ed..20f212a 100644 --- a/android_webview/browser/network_service/aw_url_loader_throttle.h +++ b/android_webview/browser/network_service/aw_url_loader_throttle.h
@@ -10,10 +10,6 @@ class GURL; -namespace content { -class ResourceContext; -} - namespace net { class HttpRequestHeaders; } @@ -23,7 +19,7 @@ class AwURLLoaderThrottle : public content::URLLoaderThrottle { public: - explicit AwURLLoaderThrottle(content::ResourceContext* resource_context); + explicit AwURLLoaderThrottle(AwResourceContext* aw_resource_context); ~AwURLLoaderThrottle() override; // content::URLLoaderThrottle implementation:
diff --git a/android_webview/docs/quick-start.md b/android_webview/docs/quick-start.md index c1c6ef9c..a69dc52 100644 --- a/android_webview/docs/quick-start.md +++ b/android_webview/docs/quick-start.md
@@ -167,7 +167,7 @@ not in the WebView provider whitelist. Double-check the package name in your GN args. If you're on AOSP (any OS level), choose `"com.android.webview"`. If you're on L-M, choose -`"com.android.google.webview"`. In either case, you'll likely need to [remove +`"com.google.android.webview"`. In either case, you'll likely need to [remove the preinstalled WebView APK](/android_webview/tools/remove_preinstalled_webview.py).
diff --git a/ash/login/ui/parent_access_view.cc b/ash/login/ui/parent_access_view.cc index a90eaf60..84e26c5 100644 --- a/ash/login/ui/parent_access_view.cc +++ b/ash/login/ui/parent_access_view.cc
@@ -59,8 +59,8 @@ constexpr int kParentAccessViewHeightDp = 340; constexpr int kParentAccessViewTabletModeHeightDp = 580; constexpr int kParentAccessViewRoundedCornerRadiusDp = 8; -constexpr int kParentAccessViewVerticalInsetDp = 16; -constexpr int kParentAccessViewHorizontalInsetDp = 26; +constexpr int kParentAccessViewVerticalInsetDp = 24; +constexpr int kParentAccessViewHorizontalInsetDp = 36; constexpr int kLockIconSizeDp = 24;
diff --git a/ash/shell/content/client/shell_browser_main_parts.cc b/ash/shell/content/client/shell_browser_main_parts.cc index 88bf8194..513e88d7 100644 --- a/ash/shell/content/client/shell_browser_main_parts.cc +++ b/ash/shell/content/client/shell_browser_main_parts.cc
@@ -33,7 +33,6 @@ #include "content/public/browser/system_connector.h" #include "content/public/common/content_switches.h" #include "content/shell/browser/shell_browser_context.h" -#include "content/shell/browser/shell_net_log.h" #include "device/bluetooth/dbus/bluez_dbus_manager.h" #include "net/base/net_module.h" #include "services/service_manager/public/cpp/connector.h" @@ -67,9 +66,7 @@ } void ShellBrowserMainParts::PreMainMessageLoopRun() { - net_log_.reset(new content::ShellNetLog("ash_shell")); - browser_context_.reset( - new content::ShellBrowserContext(false, net_log_.get())); + browser_context_.reset(new content::ShellBrowserContext(false)); // A ViewsDelegate is required. if (!views::ViewsDelegate::GetInstance())
diff --git a/ash/shell/content/client/shell_browser_main_parts.h b/ash/shell/content/client/shell_browser_main_parts.h index d5133255..181ca4b 100644 --- a/ash/shell/content/client/shell_browser_main_parts.h +++ b/ash/shell/content/client/shell_browser_main_parts.h
@@ -15,10 +15,6 @@ struct MainFunctionParams; } -namespace net { -class NetLog; -} - namespace views { class ViewsDelegate; } @@ -52,7 +48,6 @@ } private: - std::unique_ptr<net::NetLog> net_log_; std::unique_ptr<content::ShellBrowserContext> browser_context_; std::unique_ptr<views::ViewsDelegate> views_delegate_; std::unique_ptr<WindowWatcher> window_watcher_;
diff --git a/ash/system/unified/feature_pods_container_view.cc b/ash/system/unified/feature_pods_container_view.cc index 3fe2433b..4b52c1a 100644 --- a/ash/system/unified/feature_pods_container_view.cc +++ b/ash/system/unified/feature_pods_container_view.cc
@@ -87,17 +87,6 @@ kUnifiedFeaturePodCollapsedSize.height(); } -void FeaturePodsContainerView::SaveFocus() { - const auto i = std::find_if(children().cbegin(), children().cend(), - [](const auto* v) { return v->HasFocus(); }); - focused_button_ = (i == children().cend()) ? nullptr : *i; -} - -void FeaturePodsContainerView::RestoreFocus() { - if (focused_button_) - focused_button_->RequestFocus(); -} - gfx::Size FeaturePodsContainerView::CalculatePreferredSize() const { return gfx::Size( kTrayMenuWidth,
diff --git a/ash/system/unified/feature_pods_container_view.h b/ash/system/unified/feature_pods_container_view.h index c67844a..e41589a 100644 --- a/ash/system/unified/feature_pods_container_view.h +++ b/ash/system/unified/feature_pods_container_view.h
@@ -43,11 +43,6 @@ // Get the height of the view when |expanded_amount| is set to 0.0. int GetCollapsedHeight() const; - // Save and restore keyboard focus of a child feature pod button. If no button - // has focus or no focus is saved, these methods are no-op. - void SaveFocus(); - void RestoreFocus(); - // Returns the number of children that prefer to be visible. int GetVisibleCount() const; @@ -109,9 +104,6 @@ // always false if FeaturePodsContainerView is not in the call stack. bool changing_visibility_ = false; - // A button that had focus at the point SaveButtonFocus is called. - views::View* focused_button_ = nullptr; - // A view model that contains all visible feature pod buttons. // Used to calculate required number of pages. views::ViewModelT<FeaturePodButton> visible_buttons_;
diff --git a/ash/system/unified/unified_system_tray_controller.cc b/ash/system/unified/unified_system_tray_controller.cc index 0098c71b..0a25cf3 100644 --- a/ash/system/unified/unified_system_tray_controller.cc +++ b/ash/system/unified/unified_system_tray_controller.cc
@@ -295,7 +295,7 @@ detailed_view_controller_.reset(); unified_view_->ResetDetailedView(); if (restore_focus) - unified_view_->RestoreFeaturePodFocus(); + unified_view_->RestoreFocus(); } void UnifiedSystemTrayController::CloseBubble() { @@ -382,7 +382,7 @@ animation_->Reset(1.0); UpdateExpandedAmount(); - unified_view_->SaveFeaturePodFocus(); + unified_view_->SaveFocus(); views::FocusManager* manager = unified_view_->GetFocusManager(); if (manager && manager->GetFocusedView()) manager->ClearFocus();
diff --git a/ash/system/unified/unified_system_tray_view.cc b/ash/system/unified/unified_system_tray_view.cc index ef7e06e..e6a48aff 100644 --- a/ash/system/unified/unified_system_tray_view.cc +++ b/ash/system/unified/unified_system_tray_view.cc
@@ -338,12 +338,17 @@ Layout(); } -void UnifiedSystemTrayView::SaveFeaturePodFocus() { - feature_pods_container_->SaveFocus(); +void UnifiedSystemTrayView::SaveFocus() { + auto* focus_manager = GetFocusManager(); + if (!focus_manager) + return; + + saved_focused_view_ = focus_manager->GetFocusedView(); } -void UnifiedSystemTrayView::RestoreFeaturePodFocus() { - feature_pods_container_->RestoreFocus(); +void UnifiedSystemTrayView::RestoreFocus() { + if (saved_focused_view_) + saved_focused_view_->RequestFocus(); } void UnifiedSystemTrayView::SetExpandedAmount(double expanded_amount) {
diff --git a/ash/system/unified/unified_system_tray_view.h b/ash/system/unified/unified_system_tray_view.h index 139e461..0394d6ca 100644 --- a/ash/system/unified/unified_system_tray_view.h +++ b/ash/system/unified/unified_system_tray_view.h
@@ -80,9 +80,10 @@ // It deletes |detailed_view| and children. void ResetDetailedView(); - // Save and restore keyboard focus of feature pod. - void SaveFeaturePodFocus(); - void RestoreFeaturePodFocus(); + // Save and restore keyboard focus of the currently focused element. Called + // before transitioning into a detailed view. + void SaveFocus(); + void RestoreFocus(); // Change the expanded state. 0.0 if collapsed, and 1.0 if expanded. // Otherwise, it shows intermediate state. @@ -164,6 +165,9 @@ // The maximum height available to the view. int max_height_ = 0; + // The view that is saved by calling SaveFocus(). + views::View* saved_focused_view_ = nullptr; + const std::unique_ptr<FocusSearch> focus_search_; const std::unique_ptr<ui::EventHandler> interacted_by_tap_recorder_;
diff --git a/ash/wm/overview/overview_session.cc b/ash/wm/overview/overview_session.cc index 47fd6d7..57bd1294 100644 --- a/ash/wm/overview/overview_session.cc +++ b/ash/wm/overview/overview_session.cc
@@ -13,6 +13,7 @@ #include "ash/metrics/user_metrics_recorder.h" #include "ash/public/cpp/ash_features.h" #include "ash/public/cpp/shell_window_ids.h" +#include "ash/public/cpp/window_properties.h" #include "ash/screen_util.h" #include "ash/shelf/shelf.h" #include "ash/shelf/shelf_constants.h" @@ -20,6 +21,7 @@ #include "ash/strings/grit/ash_strings.h" #include "ash/wm/desks/desk.h" #include "ash/wm/desks/desks_controller.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/mru_window_tracker.h" #include "ash/wm/overview/overview_controller.h" #include "ash/wm/overview/overview_delegate.h" @@ -1032,6 +1034,9 @@ } void OverviewSession::UpdateNoWindowsWidget() { + if (is_shutting_down_) + return; + // Hide the widget if there is an item in overview. if (!IsEmpty()) { no_windows_widget_.reset(); @@ -1041,6 +1046,7 @@ if (!no_windows_widget_) { // Create and fade in the widget. RoundedLabelWidget::InitParams params; + params.name = "OverviewNoWindowsLabel"; params.horizontal_padding = kNoItemsIndicatorHorizontalPaddingDp; params.vertical_padding = kNoItemsIndicatorVerticalPaddingDp; params.background_color = kNoItemsIndicatorBackgroundColor; @@ -1049,14 +1055,15 @@ params.preferred_height = kNoItemsIndicatorHeightDp; params.message_id = IDS_ASH_OVERVIEW_NO_RECENT_ITEMS; params.parent = Shell::GetPrimaryRootWindow()->GetChildById( - kShellWindowId_AlwaysOnTopContainer); + desks_util::GetActiveDeskContainerId()); no_windows_widget_ = std::make_unique<RoundedLabelWidget>(); no_windows_widget_->Init(params); aura::Window* widget_window = no_windows_widget_->GetNativeWindow(); + widget_window->SetProperty(kHideInDeskMiniViewKey, true); + widget_window->parent()->StackChildAtBottom(widget_window); ScopedOverviewAnimationSettings settings(OVERVIEW_ANIMATION_NO_RECENTS_FADE, widget_window); - widget_window->SetName("OverviewNoWindowsLabel"); no_windows_widget_->SetOpacity(1.f); }
diff --git a/ash/wm/overview/rounded_label_widget.cc b/ash/wm/overview/rounded_label_widget.cc index 8b98c68..0b851b0 100644 --- a/ash/wm/overview/rounded_label_widget.cc +++ b/ash/wm/overview/rounded_label_widget.cc
@@ -69,12 +69,15 @@ } // namespace +RoundedLabelWidget::InitParams::InitParams() = default; + RoundedLabelWidget::RoundedLabelWidget() = default; RoundedLabelWidget::~RoundedLabelWidget() = default; void RoundedLabelWidget::Init(const InitParams& params) { views::Widget::InitParams widget_params; + widget_params.name = params.name; widget_params.type = views::Widget::InitParams::TYPE_POPUP; widget_params.keep_on_top = false; widget_params.ownership =
diff --git a/ash/wm/overview/rounded_label_widget.h b/ash/wm/overview/rounded_label_widget.h index ba00b290..958e5472 100644 --- a/ash/wm/overview/rounded_label_widget.h +++ b/ash/wm/overview/rounded_label_widget.h
@@ -5,6 +5,8 @@ #ifndef ASH_WM_OVERVIEW_ROUNDED_LABEL_WIDGET_H_ #define ASH_WM_OVERVIEW_ROUNDED_LABEL_WIDGET_H_ +#include <string> + #include "base/macros.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/geometry/rect.h" @@ -18,6 +20,8 @@ public: // Params to modify the look of the label. struct InitParams { + InitParams(); + std::string name; int horizontal_padding; int vertical_padding; SkColor background_color;
diff --git a/base/android/jni_generator/README.md b/base/android/jni_generator/README.md index dd462d0d4..33a7008 100644 --- a/base/android/jni_generator/README.md +++ b/base/android/jni_generator/README.md
@@ -154,13 +154,14 @@ #### Testing Mockable Natives -(Currently JniMocker only works for junit/robolectric tests, and is not yet -ready for instrumentation tests.) - 1. Add the `JniMocker` rule to your test. 2. Call `JniMocker#mock` in a `setUp()` method for each interface you want to stub out. +Note: Mocking native methods doesn't work in tests that are part of APKs that +use an [`apk_under_test`](https://cs.chromium.org/search/?q=file:BUILD.gn+%22apk_under_test+%3D%22&type=cs). +[This crbug](http://crbug.com/890452) tracks removing the `apk_under_test` variable. + JniMocker will reset the stubs during `tearDown()`. ```java @@ -249,9 +250,3 @@ * Python unit tests live in `jni_generator_tests.py` * A working demo app exists as `//base/android/jni_generator:sample_jni_apk` - -## Known Issues - -The `jni_generator` can cause build issues when source files that are used by -JNI are moved due to how `include_dirs` are handled. This is tracked in -[issue 964169](http://crbug.com/964169). \ No newline at end of file
diff --git a/base/memory/fake_memory_pressure_monitor.cc b/base/memory/fake_memory_pressure_monitor.cc index 713b161..59fd3ef6 100644 --- a/base/memory/fake_memory_pressure_monitor.cc +++ b/base/memory/fake_memory_pressure_monitor.cc
@@ -20,7 +20,7 @@ } base::MemoryPressureMonitor::MemoryPressureLevel -FakeMemoryPressureMonitor::GetCurrentPressureLevel() { +FakeMemoryPressureMonitor::GetCurrentPressureLevel() const { return memory_pressure_level_; }
diff --git a/base/memory/fake_memory_pressure_monitor.h b/base/memory/fake_memory_pressure_monitor.h index 2194b5f8..d012876 100644 --- a/base/memory/fake_memory_pressure_monitor.h +++ b/base/memory/fake_memory_pressure_monitor.h
@@ -19,7 +19,7 @@ void SetAndNotifyMemoryPressure(MemoryPressureLevel level); // base::MemoryPressureMonitor overrides: - MemoryPressureLevel GetCurrentPressureLevel() override; + MemoryPressureLevel GetCurrentPressureLevel() const override; void SetDispatchCallback(const DispatchCallback& callback) override; private:
diff --git a/base/memory/memory_pressure_monitor.h b/base/memory/memory_pressure_monitor.h index 13bc483..40d3415 100644 --- a/base/memory/memory_pressure_monitor.h +++ b/base/memory/memory_pressure_monitor.h
@@ -40,7 +40,7 @@ static const base::TimeDelta kUMAMemoryPressureLevelPeriod; // Returns the currently observed memory pressure. - virtual MemoryPressureLevel GetCurrentPressureLevel() = 0; + virtual MemoryPressureLevel GetCurrentPressureLevel() const = 0; // Sets a notification callback. The default callback invokes // base::MemoryPressureListener::NotifyMemoryPressure.
diff --git a/base/memory/memory_pressure_monitor_chromeos.cc b/base/memory/memory_pressure_monitor_chromeos.cc index 2b4ff01c..a75d2be 100644 --- a/base/memory/memory_pressure_monitor_chromeos.cc +++ b/base/memory/memory_pressure_monitor_chromeos.cc
@@ -149,7 +149,7 @@ } MemoryPressureListener::MemoryPressureLevel -MemoryPressureMonitor::GetCurrentPressureLevel() { +MemoryPressureMonitor::GetCurrentPressureLevel() const { return current_memory_pressure_level_; }
diff --git a/base/memory/memory_pressure_monitor_chromeos.h b/base/memory/memory_pressure_monitor_chromeos.h index 563ba85..722c1d6 100644 --- a/base/memory/memory_pressure_monitor_chromeos.h +++ b/base/memory/memory_pressure_monitor_chromeos.h
@@ -59,7 +59,7 @@ // Get the current memory pressure level. MemoryPressureListener::MemoryPressureLevel GetCurrentPressureLevel() - override; + const override; void SetDispatchCallback(const DispatchCallback& callback) override; // Returns a type-casted version of the current memory pressure monitor. A
diff --git a/base/memory/memory_pressure_monitor_mac.cc b/base/memory/memory_pressure_monitor_mac.cc index a91e52a..bd829fcf 100644 --- a/base/memory/memory_pressure_monitor_mac.cc +++ b/base/memory/memory_pressure_monitor_mac.cc
@@ -165,7 +165,7 @@ } MemoryPressureListener::MemoryPressureLevel -MemoryPressureMonitor::GetCurrentPressureLevel() { +MemoryPressureMonitor::GetCurrentPressureLevel() const { return last_pressure_level_; }
diff --git a/base/memory/memory_pressure_monitor_mac.h b/base/memory/memory_pressure_monitor_mac.h index b85b6c90..b98a5c3e 100644 --- a/base/memory/memory_pressure_monitor_mac.h +++ b/base/memory/memory_pressure_monitor_mac.h
@@ -29,7 +29,7 @@ ~MemoryPressureMonitor() override; // Returns the currently-observed memory pressure. - MemoryPressureLevel GetCurrentPressureLevel() override; + MemoryPressureLevel GetCurrentPressureLevel() const override; void SetDispatchCallback(const DispatchCallback& callback) override;
diff --git a/base/memory/memory_pressure_monitor_notifying_chromeos.cc b/base/memory/memory_pressure_monitor_notifying_chromeos.cc index 74e96c0..cb0eeb5 100644 --- a/base/memory/memory_pressure_monitor_notifying_chromeos.cc +++ b/base/memory/memory_pressure_monitor_notifying_chromeos.cc
@@ -203,7 +203,7 @@ } MemoryPressureListener::MemoryPressureLevel -MemoryPressureMonitorNotifying::GetCurrentPressureLevel() { +MemoryPressureMonitorNotifying::GetCurrentPressureLevel() const { return current_memory_pressure_level_; }
diff --git a/base/memory/memory_pressure_monitor_notifying_chromeos.h b/base/memory/memory_pressure_monitor_notifying_chromeos.h index 5af176f..6761cc5 100644 --- a/base/memory/memory_pressure_monitor_notifying_chromeos.h +++ b/base/memory/memory_pressure_monitor_notifying_chromeos.h
@@ -42,7 +42,7 @@ // Get the current memory pressure level. MemoryPressureListener::MemoryPressureLevel GetCurrentPressureLevel() - override; + const override; void SetDispatchCallback(const DispatchCallback& callback) override; // GetMarginFileParts returns a vector of the configured margin file values.
diff --git a/base/memory/memory_pressure_monitor_win.cc b/base/memory/memory_pressure_monitor_win.cc index 34a3d71..f2ccb7d7 100644 --- a/base/memory/memory_pressure_monitor_win.cc +++ b/base/memory/memory_pressure_monitor_win.cc
@@ -88,7 +88,7 @@ } MemoryPressureListener::MemoryPressureLevel -MemoryPressureMonitor::GetCurrentPressureLevel() { +MemoryPressureMonitor::GetCurrentPressureLevel() const { return current_memory_pressure_level_; }
diff --git a/base/memory/memory_pressure_monitor_win.h b/base/memory/memory_pressure_monitor_win.h index 6a7d0bb8..6d9df60 100644 --- a/base/memory/memory_pressure_monitor_win.h +++ b/base/memory/memory_pressure_monitor_win.h
@@ -55,7 +55,7 @@ void CheckMemoryPressureSoon(); // Get the current memory pressure level. This can be called from any thread. - MemoryPressureLevel GetCurrentPressureLevel() override; + MemoryPressureLevel GetCurrentPressureLevel() const override; void SetDispatchCallback(const DispatchCallback& callback) override; // Returns the moderate pressure level free memory threshold, in MB.
diff --git a/base/metrics/field_trial_unittest.cc b/base/metrics/field_trial_unittest.cc index c542bcf..f925fbc 100644 --- a/base/metrics/field_trial_unittest.cc +++ b/base/metrics/field_trial_unittest.cc
@@ -1212,10 +1212,8 @@ } TEST(FieldTrialListTest, InstantiateAllocator) { - test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.Init(); - FieldTrialList field_trial_list(nullptr); + FieldTrialList::CreateFieldTrial("Trial1", "Group1"); FieldTrialList::InstantiateFieldTrialAllocatorIfNeeded(); @@ -1240,7 +1238,6 @@ test::ScopedFeatureList scoped_feature_list; scoped_feature_list.Init(); - FieldTrialList field_trial_list(nullptr); FieldTrialList::CreateFieldTrial("Trial1", "Group1"); FieldTrialList::InstantiateFieldTrialAllocatorIfNeeded(); FieldTrialList::AllStatesToString(&save_string, false); @@ -1267,7 +1264,6 @@ // Create a simulated trial and a real trial and call group() on them, which // should only add the real trial to the field trial allocator. - FieldTrialList field_trial_list(nullptr); FieldTrialList::InstantiateFieldTrialAllocatorIfNeeded(); // This shouldn't add to the allocator. @@ -1304,7 +1300,6 @@ std::string group_name("Group1"); // Create a field trial with some params. - FieldTrialList field_trial_list(nullptr); FieldTrialList::CreateFieldTrial(trial_name, group_name); std::map<std::string, std::string> params; params["key1"] = "value1"; @@ -1346,7 +1341,6 @@ scoped_feature_list.Init(); // Create a field trial with some params. - FieldTrialList field_trial_list(nullptr); FieldTrial* trial = FieldTrialList::CreateFieldTrial(trial_name, group_name); std::map<std::string, std::string> params;
diff --git a/base/test/BUILD.gn b/base/test/BUILD.gn index 5632c71e..fe1864b 100644 --- a/base/test/BUILD.gn +++ b/base/test/BUILD.gn
@@ -53,7 +53,6 @@ "copy_only_int.h", "do_nothing_promise.cc", "do_nothing_promise.h", - "fuzzed_data_provider.h", "gmock_callback_support.h", "gtest_util.cc", "gtest_util.h",
diff --git a/base/test/fuzzed_data_provider.h b/base/test/fuzzed_data_provider.h deleted file mode 100644 index 33d1c00..0000000 --- a/base/test/fuzzed_data_provider.h +++ /dev/null
@@ -1,206 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_TEST_FUZZED_DATA_PROVIDER_H_ -#define BASE_TEST_FUZZED_DATA_PROVIDER_H_ - -#include <limits.h> -#include <stddef.h> -#include <stdint.h> - -#include <algorithm> -#include <cstring> -#include <string> -#include <type_traits> -#include <utility> -#include <vector> - -// A single-header library providing an utility class to break up an array of -// bytes (supposedly provided by a fuzzing engine) for multiple consumers. -// Whenever run on the same input, provides the same output, as long as its -// methods are called in the same order, with the same arguments. - -// TODO(mmoroz): move this out of //base as it should be an independent library. -namespace base { - -class FuzzedDataProvider { - public: - typedef uint8_t data_type; - - // |data| is an array of length |size| that the FuzzedDataProvider wraps to - // provide more granular access. |data| must outlive the FuzzedDataProvider. - FuzzedDataProvider(const uint8_t* data, size_t size) - : data_ptr_(data), remaining_bytes_(size) {} - ~FuzzedDataProvider() = default; - - // Returns a std::vector containing |num_bytes| of input data. If fewer than - // |num_bytes| of data remain, returns a shorter std::vector containing all - // of the data that's left. - template <typename T = data_type> - std::vector<T> ConsumeBytes(size_t num_bytes) { - static_assert(sizeof(T) == sizeof(data_type), "Incompatible data type."); - - num_bytes = std::min(num_bytes, remaining_bytes_); - - // The point of using the size-based constructor below is to increase the - // odds of having a vector object with capacity being equal to the length. - // That part is always implementation specific, but at least both libc++ and - // libstdc++ allocate the requested number of bytes in that constructor, - // which seems to be a natual choice for other implementations as well. - // To increase the odds even more, we also call |shrink_to_fit| below. - std::vector<T> result(num_bytes); - std::memcpy(result.data(), data_ptr_, num_bytes); - Advance(num_bytes); - - // Even though |shrink_to_fit| is also implementation specific, we expect it - // to provide an additional assurance in case vector's constructor allocated - // a buffer which is larger than the actual amount of data we put inside it. - result.shrink_to_fit(); - return result; - } - - // Prefer using |ConsumeBytes| unless you actually need a std::string object. - // Returns a std::string containing |num_bytes| of input data. If fewer than - // |num_bytes| of data remain, returns a shorter std::string containing all - // of the data that's left. - std::string ConsumeBytesAsString(size_t num_bytes) { - static_assert(sizeof(std::string::value_type) == sizeof(data_type), - "ConsumeBytesAsString cannot convert the data to a string."); - - num_bytes = std::min(num_bytes, remaining_bytes_); - std::string result( - reinterpret_cast<const std::string::value_type*>(data_ptr_), num_bytes); - Advance(num_bytes); - return result; - } - - // Returns a number in the range [min, max] by consuming bytes from the input - // data. The value might not be uniformly distributed in the given range. If - // there's no input data left, always returns |min|. |min| must be less than - // or equal to |max|. - template <typename T> - T ConsumeIntegralInRange(T min, T max) { - static_assert(std::is_integral<T>::value, "An integral type is required."); - static_assert(sizeof(T) <= sizeof(uint64_t), "Unsupported integral type."); - - if (min > max) - abort(); - - // Use the biggest type possible to hold the range and the result. - uint64_t range = static_cast<uint64_t>(max) - min; - uint64_t result = 0; - size_t offset = 0; - - while (offset < sizeof(T) * CHAR_BIT && (range >> offset) > 0 && - remaining_bytes_ != 0) { - // Pull bytes off the end of the seed data. Experimentally, this seems to - // allow the fuzzer to more easily explore the input space. This makes - // sense, since it works by modifying inputs that caused new code to run, - // and this data is often used to encode length of data read by - // |ConsumeBytes|. Separating out read lengths makes it easier modify the - // contents of the data that is actually read. - --remaining_bytes_; - result = (result << CHAR_BIT) | data_ptr_[remaining_bytes_]; - offset += CHAR_BIT; - } - - // Avoid division by 0, in the case |range + 1| results in overflow. - if (range != std::numeric_limits<decltype(range)>::max()) - result = result % (range + 1); - - return static_cast<T>(min + result); - } - - // Returns a std::string of length from 0 to |max_length|. When it runs out of - // input data, returns what remains of the input. Designed to be more stable - // with respect to a fuzzer inserting characters than just picking a random - // length and then consuming that many bytes with |ConsumeBytes|. - std::string ConsumeRandomLengthString(size_t max_length) { - // Reads bytes from the start of |data_ptr_|. Maps "\\" to "\", and maps "\" - // followed by anything else to the end of the string. As a result of this - // logic, a fuzzer can insert characters into the string, and the string - // will be lengthened to include those new characters, resulting in a more - // stable fuzzer than picking the length of a string independently from - // picking its contents. - std::string result; - for (size_t i = 0; i < max_length && remaining_bytes_ != 0; ++i) { - char next = static_cast<char>(data_ptr_[0]); - Advance(1); - if (next == '\\' && remaining_bytes_ != 0) { - next = static_cast<char>(data_ptr_[0]); - Advance(1); - if (next != '\\') - return result; - } - result += next; - } - - result.shrink_to_fit(); - return result; - } - - // Returns a std::vector containing all remaining bytes of the input data. - template <typename T = data_type> - std::vector<T> ConsumeRemainingBytes() { - return ConsumeBytes<T>(remaining_bytes_); - } - - // Prefer using |ConsumeRemainingBytes| unless you actually need a std::string - // object. - // Returns a std::vector containing all remaining bytes of the input data. - std::string ConsumeRemainingBytesAsString() { - return ConsumeBytesAsString(remaining_bytes_); - } - - // Returns a number in the range [Type's min, Type's max]. The value might - // not be uniformly distributed in the given range. If there's no input data - // left, always returns |min|. - template <typename T> - T ConsumeIntegral() { - return ConsumeIntegralInRange(std::numeric_limits<T>::min(), - std::numeric_limits<T>::max()); - } - - // Reads one byte and returns a bool, or false when no data remains. - bool ConsumeBool() { return 1 & ConsumeIntegral<uint8_t>(); } - - // Returns a value from |array|, consuming as many bytes as needed to do so. - // |array| must be a fixed-size array. - template <typename T, size_t size> - T PickValueInArray(T (&array)[size]) { - return array[ConsumeIntegralInRange<size_t>(0, size - 1)]; - } - - // Return an enum value. The enum must start at 0 and be contiguous. It must - // also contain kMaxValue aliased to its largest (inclusive) value. Such as: - // enum class Foo { SomeValue, OtherValue, kMaxValue = OtherValue }; - template <typename T> - T ConsumeEnum() { - static_assert(std::is_enum<T>::value, "|T| must be an enum type."); - return static_cast<T>(ConsumeIntegralInRange<uint32_t>( - 0, static_cast<uint32_t>(T::kMaxValue))); - } - - // Reports the remaining bytes available for fuzzed input. - size_t remaining_bytes() { return remaining_bytes_; } - - private: - FuzzedDataProvider(const FuzzedDataProvider&) = delete; - FuzzedDataProvider& operator=(const FuzzedDataProvider&) = delete; - - void Advance(size_t num_bytes) { - if (num_bytes > remaining_bytes_) - abort(); - - data_ptr_ += num_bytes; - remaining_bytes_ -= num_bytes; - } - - const data_type* data_ptr_; - size_t remaining_bytes_; -}; - -} // namespace base - -#endif // BASE_TEST_FUZZED_DATA_PROVIDER_H_
diff --git a/base/test/scoped_feature_list.cc b/base/test/scoped_feature_list.cc index e855543c..e23a5579 100644 --- a/base/test/scoped_feature_list.cc +++ b/base/test/scoped_feature_list.cc
@@ -150,9 +150,7 @@ } void ScopedFeatureList::Init() { - std::unique_ptr<FeatureList> feature_list(new FeatureList); - feature_list->InitializeFromCommandLine(std::string(), std::string()); - InitWithFeatureList(std::move(feature_list)); + InitWithFeaturesImpl({}, {}, {}); } void ScopedFeatureList::InitWithFeatureList(
diff --git a/base/test/scoped_feature_list.h b/base/test/scoped_feature_list.h index 1402c85..586deed 100644 --- a/base/test/scoped_feature_list.h +++ b/base/test/scoped_feature_list.h
@@ -51,10 +51,9 @@ // Resets the instance to a non-initialized state. void Reset(); - // WARNING: This method will reset any globally configured features to their - // default values, which can hide feature interaction bugs. Please use - // sparingly. https://crbug.com/713390 - // Initializes and registers a FeatureList instance with no overrides. + // Initializes and registers a FeatureList instance without any additional + // enabled or disabled features. Existing state, if any, will be kept. This is + // equivalent to calling InitWithFeatures({}, {}). void Init(); // WARNING: This method will reset any globally configured features to their
diff --git a/base/threading/sequence_bound.h b/base/threading/sequence_bound.h index df8e818..37b5b524 100644 --- a/base/threading/sequence_bound.h +++ b/base/threading/sequence_bound.h
@@ -234,8 +234,8 @@ // Run on impl thread to construct |t|'s storage. template <typename... Args> - static void ConstructOwnerRecord(T* t, Args&&... args) { - new (t) T(std::forward<Args>(args)...); + static void ConstructOwnerRecord(T* t, std::decay_t<Args>&&... args) { + new (t) T(std::move(args)...); } // Destruct the object associated with |t|, and delete |storage|.
diff --git a/base/threading/sequence_bound_unittest.cc b/base/threading/sequence_bound_unittest.cc index 4514573..b571c8d 100644 --- a/base/threading/sequence_bound_unittest.cc +++ b/base/threading/sequence_bound_unittest.cc
@@ -323,4 +323,25 @@ "|VirtuallyDerived shouldn't be a virtual base of |Base|"); } +TEST_F(SequenceBoundTest, LvalueConstructionParameter) { + // Note here that |value_ptr| is an lvalue, while |&value| would be an rvalue. + Value value = kInitialValue; + Value* value_ptr = &value; + SequenceBound<Derived> derived(task_runner_, value_ptr); + { + derived.Post(FROM_HERE, &Derived::SetValue, kDifferentValue); + base::RunLoop run_loop; + task_runner_->PostTask(FROM_HERE, run_loop.QuitClosure()); + run_loop.Run(); + EXPECT_EQ(value, kDifferentValue); + } + { + derived.Reset(); + base::RunLoop run_loop; + task_runner_->PostTask(FROM_HERE, run_loop.QuitClosure()); + run_loop.Run(); + EXPECT_EQ(value, kDerivedDtorValue); + } +} + } // namespace base
diff --git a/build/android/apk_operations.py b/build/android/apk_operations.py index 78400c7..7395d2c 100755 --- a/build/android/apk_operations.py +++ b/build/android/apk_operations.py
@@ -692,24 +692,26 @@ def _ParseLine(self, line): tokens = line.split(None, 6) - date = tokens[0] - invokation_time = tokens[1] - pid = int(tokens[2]) - tid = int(tokens[3]) - priority = tokens[4] - tag = tokens[5] - if len(tokens) > 6: - original_message = tokens[6] - else: # Empty log message - original_message = '' + + def consume_token_or_default(default): + return tokens.pop(0) if len(tokens) > 0 else default + + date = consume_token_or_default('') + invokation_time = consume_token_or_default('') + pid = int(consume_token_or_default(-1)) + tid = int(consume_token_or_default(-1)) + priority = consume_token_or_default('') + tag = consume_token_or_default('') + original_message = consume_token_or_default('') + # Example: # 09-19 06:35:51.113 9060 9154 W GCoreFlp: No location... # 09-19 06:01:26.174 9060 10617 I Auth : [ReflectiveChannelBinder]... # Parsing "GCoreFlp:" vs "Auth :", we only want tag to contain the word, # and we don't want to keep the colon for the message. - if tag[-1] == ':': + if tag and tag[-1] == ':': tag = tag[:-1] - else: + elif len(original_message) > 2: original_message = original_message[2:] return self.ParsedLine( date, invokation_time, pid, tid, priority, tag, original_message)
diff --git a/build/chromeos/test_runner.py b/build/chromeos/test_runner.py index f4e2f3c..147221d 100755 --- a/build/chromeos/test_runner.py +++ b/build/chromeos/test_runner.py
@@ -64,10 +64,10 @@ # /home is mounted with "noexec" in the device, but some of our tools # and tests use the home dir as a workspace (eg: vpython downloads - # python binaries to ~/.vpython-root). /tmp doesn't have this + # python binaries to ~/.vpython-root). /usr/local/tmp doesn't have this # restriction, so change the location of the home dir for the # duration of the test. - 'export HOME=/tmp', + 'export HOME=/usr/local/tmp', ] def __init__(self, args, unknown_args):
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index 70f4929..57befd8f 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -370,6 +370,12 @@ # header_output: Path to the generated .h file (optional). # sources_blacklist: List of .java files that should be skipped. (optional) # namespace: Registration functions will be wrapped into this. (optional) + # require_native_mocks: Enforce that any native calls using + # org.chromium.base.annotations.NativeMethods must have a mock set + # (optional). + # enable_native_mocks: Allow native calls using + # org.chromium.base.annotations.NativeMethods to be mocked in tests + # (optional). # # Example # generate_jni_registration("chrome_jni_registration") { @@ -414,11 +420,11 @@ if (defined(invoker.enable_native_mocks) && invoker.enable_native_mocks) { args += [ "--enable_proxy_mocks" ] - } - if (defined(invoker.require_native_mocks) && - invoker.require_native_mocks) { - args += [ "--require_mocks" ] + if (defined(invoker.require_native_mocks) && + invoker.require_native_mocks) { + args += [ "--require_mocks" ] + } } if (defined(invoker.header_output)) { @@ -2029,6 +2035,12 @@ # Optional, default 23. # max_sdk_version: The maximum Android SDK version this target supports. # Optional, default not set. + # require_native_mocks: Enforce that any native calls using + # org.chromium.base.annotations.NativeMethods must have a mock set + # (optional). + # enable_native_mocks: Allow native calls using + # org.chromium.base.annotations.NativeMethods to be mocked in tests + # (optional). template("android_apk_or_module") { forward_variables_from(invoker, [ "testonly" ]) assert(defined(invoker.final_apk_path) || defined(invoker.name)) @@ -2639,6 +2651,11 @@ if (_generate_final_jni) { generate_jni_registration("${_template_name}__final_jni") { + forward_variables_from(invoker, + [ + "enable_native_mocks", + "require_native_mocks", + ]) target = ":$_template_name" if (defined(invoker.jni_registration_header)) { header_output = invoker.jni_registration_header @@ -3268,6 +3285,7 @@ "dont_load_shared_libraries", "enable_chromium_linker_tests", "enable_multidex", + "enable_native_mocks", "final_apk_path", "generate_buildconfig_java", "generate_final_jni", @@ -3302,6 +3320,7 @@ "resource_blacklist_regex", "resource_ids_provider_dep", "resources_config_path", + "require_native_mocks", "secondary_abi_loadable_modules", "secondary_abi_shared_libraries", "secondary_native_lib_placeholders", @@ -3595,6 +3614,8 @@ ] if (defined(invoker.apk_under_test)) { data_deps += [ invoker.apk_under_test ] + } else { + enable_native_mocks = true } if (defined(invoker.additional_apks)) { data_deps += invoker.additional_apks
diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni index 9bcc5d2e..7d71a12 100644 --- a/build/config/compiler/compiler.gni +++ b/build/config/compiler/compiler.gni
@@ -76,6 +76,11 @@ # It's currently not possible to collect AFDO profiles on anything but # x86{,_64}. using_mismatched_sample_profile = current_cpu != "x64" && current_cpu != "x86" + + # Whether an error should be raised on attempts to make debug builds with + # is_component_build=false. Very large debug symbols can have unwanted side + # effects so this is enforced by default for chromium. + forbid_non_component_debug_builds = build_with_chromium } assert(!is_cfi || use_thin_lto, "CFI requires ThinLTO") @@ -232,8 +237,8 @@ # info or variable info, so we can leave that out to speed up the build. # Sanitizers also require symbols for filename suppressions to work. symbol_level = 1 - } else if ((!is_nacl && !is_linux && !is_fuchsia && current_os != "aix") || is_debug || - is_official_build || is_chromecast) { + } else if ((!is_nacl && !is_linux && !is_fuchsia && current_os != "aix") || + is_debug || is_official_build || is_chromecast) { # Linux builds slower by having symbols as part of the target binary, # whereas Mac and Windows have them separate, so in Release Linux, default # them off, but keep them on for Official builds and Chromecast builds. @@ -256,7 +261,7 @@ # because the is_component_build flag is set to false in various components of # the build (like nacl) and we don't want to assert on those. # iOS does not support component builds so add an exception for this platform. -if (build_with_chromium) { +if (forbid_non_component_debug_builds) { assert(symbol_level != 2 || current_toolchain != default_toolchain || is_component_build || !is_debug || is_ios, "Can't do non-component debug builds at symbol_level=2")
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 9522b9c..db96dbf 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -8909064476425739776 \ No newline at end of file +8909016706543512784 \ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 2b8b660a..d5d8184 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -8909076652554121136 \ No newline at end of file +8909064474621102512 \ No newline at end of file
diff --git a/cc/tiles/software_image_decode_cache_utils.h b/cc/tiles/software_image_decode_cache_utils.h index 835d68c..3293d8b4 100644 --- a/cc/tiles/software_image_decode_cache_utils.h +++ b/cc/tiles/software_image_decode_cache_utils.h
@@ -50,12 +50,11 @@ bool operator==(const CacheKey& other) const { // The frame_key always has to be the same. However, after that all // original decodes are the same, so if we can use the original decode, - // return true. If not, then we have to compare every field. Note we don't - // compare |nearest_neighbor_| because we would only use kOriginal type in - // that case (dchecked below), which implies no scale. The returned scale - // to Skia would respect the nearest neighbor value of the requested - // image. - DCHECK(!is_nearest_neighbor_ || type_ == kOriginal); + // return true. If not, then we have to compare every field. + // |nearest_neighbor_| is not compared below since it is not used for + // scaled decodes and does not affect the contents of the cache entry + // (just passed to skia for the filtering to be done at raster time). + DCHECK(!is_nearest_neighbor_ || type_ != kSubrectAndScale); return frame_key_ == other.frame_key_ && type_ == other.type_ && target_color_space_ == other.target_color_space_ && (type_ == kOriginal || (src_rect_ == other.src_rect_ &&
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index a59bace..515cc0e 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -1321,7 +1321,7 @@ if (is_component_build) { ldflags += [ "-rpath", - "@loader_path/../../../../../../../..", + "@loader_path/../../../../../..", "-Wl,-reexport_library,libchrome_dll.dylib", ]
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 0c5f78e9..2c7b24ec 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -2612,8 +2612,8 @@ "java/src/org/chromium/chrome/browser/offlinepages/BackgroundSchedulerBridge.java", "java/src/org/chromium/chrome/browser/offlinepages/CCTRequestStatus.java", "java/src/org/chromium/chrome/browser/offlinepages/CctOfflinePageModelObserver.java", + "java/src/org/chromium/chrome/browser/offlinepages/OfflinePageArchivePublisherBridge.java", "java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java", - "java/src/org/chromium/chrome/browser/offlinepages/OfflinePagesDownloadManagerBridge.java", "java/src/org/chromium/chrome/browser/offlinepages/PublishPageCallback.java", "java/src/org/chromium/chrome/browser/offlinepages/RequestCoordinatorBridge.java", "java/src/org/chromium/chrome/browser/offlinepages/SavePageRequest.java",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index c9c5753..bffe389 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -1002,12 +1002,12 @@ "java/src/org/chromium/chrome/browser/offlinepages/DeletedPageInfo.java", "java/src/org/chromium/chrome/browser/offlinepages/GetPagesByNamespaceForLivePageSharingCallback.java", "java/src/org/chromium/chrome/browser/offlinepages/OfflineBackgroundTask.java", + "java/src/org/chromium/chrome/browser/offlinepages/OfflinePageArchivePublisherBridge.java", "java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java", "java/src/org/chromium/chrome/browser/offlinepages/OfflinePageItem.java", "java/src/org/chromium/chrome/browser/offlinepages/OfflinePageOrigin.java", "java/src/org/chromium/chrome/browser/offlinepages/OfflinePageTabObserver.java", "java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java", - "java/src/org/chromium/chrome/browser/offlinepages/OfflinePagesDownloadManagerBridge.java", "java/src/org/chromium/chrome/browser/offlinepages/PublishPageCallback.java", "java/src/org/chromium/chrome/browser/offlinepages/RequestCoordinatorBridge.java", "java/src/org/chromium/chrome/browser/offlinepages/SavePageAndShareCallback.java",
diff --git a/chrome/android/features/tab_ui/BUILD.gn b/chrome/android/features/tab_ui/BUILD.gn index a4c49ae..e6d9578 100644 --- a/chrome/android/features/tab_ui/BUILD.gn +++ b/chrome/android/features/tab_ui/BUILD.gn
@@ -63,6 +63,7 @@ "java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripToolbarViewProperties.java", "java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripViewBinder.java", "java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripViewHolder.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/UndoGroupSnackbarController.java", ] deps = [
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherCoordinator.java index 14f44cf8..f623d9cd 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherCoordinator.java
@@ -21,6 +21,7 @@ import org.chromium.chrome.browser.gesturenav.HistoryNavigationLayout; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.lifecycle.Destroyable; +import org.chromium.chrome.browser.snackbar.SnackbarManager; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabCreatorManager; import org.chromium.chrome.browser.tabmodel.TabList; @@ -47,6 +48,7 @@ private final MultiThumbnailCardProvider mMultiThumbnailCardProvider; private final TabGridDialogCoordinator mTabGridDialogCoordinator; private final TabSelectionEditorCoordinator mTabSelectionEditorCoordinator; + private final UndoGroupSnackbarController mUndoGroupSnackbarController; private final MenuOrKeyboardActionController .MenuOrKeyboardActionHandler mGridTabSwitcherMenuActionHandler = @@ -66,7 +68,8 @@ ActivityLifecycleDispatcher lifecycleDispatcher, TabModelSelector tabModelSelector, TabContentManager tabContentManager, CompositorViewHolder compositorViewHolder, ChromeFullscreenManager fullscreenManager, TabCreatorManager tabCreatorManager, - MenuOrKeyboardActionController menuOrKeyboardActionController, Runnable backPress) { + MenuOrKeyboardActionController menuOrKeyboardActionController, Runnable backPress, + SnackbarManager.SnackbarManageable snackbarManageable) { PropertyModel containerViewModel = new PropertyModel(TabListContainerProperties.ALL_KEYS); mTabSelectionEditorCoordinator = new TabSelectionEditorCoordinator( @@ -84,6 +87,9 @@ mTabSelectionEditorCoordinator.getController()); gridCardOnClickListenerProvider = mMediator::getGridCardOnClickListener; + + mUndoGroupSnackbarController = + new UndoGroupSnackbarController(context, tabModelSelector, snackbarManageable); } else { mTabGridDialogCoordinator = null; @@ -92,6 +98,7 @@ mTabSelectionEditorCoordinator.getController()); gridCardOnClickListenerProvider = null; + mUndoGroupSnackbarController = null; } mMultiThumbnailCardProvider =
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java index 96e66ee..da201e71 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
@@ -420,6 +420,8 @@ @Override public void didMoveWithinGroup( Tab movedTab, int tabModelOldIndex, int tabModelNewIndex) { + if (tabModelNewIndex == tabModelOldIndex) return; + int curPosition = mModel.indexFromId(movedTab.getId()); TabModel tabModel = mTabModelSelector.getCurrentModel(); @@ -449,8 +451,12 @@ } if (mActionsOnAllRelatedTabs) { Tab currentSelectedTab = mTabModelSelector.getCurrentTab(); - addTabInfoToModel(movedTab, mModel.size(), - currentSelectedTab.getId() == movedTab.getId()); + int index = TabModelUtils.getTabIndexById( + mTabModelSelector.getTabModelFilterProvider() + .getCurrentTabModelFilter(), + movedTab.getId()); + addTabInfoToModel( + movedTab, index, currentSelectedTab.getId() == movedTab.getId()); boolean isSelected = mTabModelSelector.getCurrentTabId() == filter.getTabAt(prevFilterIndex).getId(); updateTab(prevFilterIndex, filter.getTabAt(prevFilterIndex), isSelected, @@ -481,7 +487,7 @@ @Override public void didMoveTabGroup( Tab movedTab, int tabModelOldIndex, int tabModelNewIndex) { - if (!mActionsOnAllRelatedTabs) return; + if (!mActionsOnAllRelatedTabs || tabModelNewIndex == tabModelOldIndex) return; TabGroupModelFilter filter = (TabGroupModelFilter) mTabModelSelector.getTabModelFilterProvider() .getCurrentTabModelFilter(); @@ -518,6 +524,10 @@ mModel.move(curPosition, newPosition); } + + @Override + public void didCreateGroup( + List<Tab> tabs, List<Integer> tabOriginalIndex, boolean isSameGroup) {} }; ((TabGroupModelFilter) mTabModelSelector.getTabModelFilterProvider().getTabModelFilter( @@ -598,7 +608,7 @@ sTabClosedFromMapTabClosedFromMap.put(tabId, TabClosedFrom.GRID_TAB_SWITCHER_GROUP); } - public void setActionOnAllRelatedTabsForTest(boolean actionOnAllRelatedTabs) { + void setActionOnAllRelatedTabsForTest(boolean actionOnAllRelatedTabs) { mActionsOnAllRelatedTabs = actionOnAllRelatedTabs; } @@ -609,9 +619,10 @@ } private void onTabAdded(Tab tab, boolean onlyShowRelatedTabs) { - List<Tab> related = getRelatedTabsForId(tab.getId()); int index; if (onlyShowRelatedTabs) { + if (mModel.size() == 0) return; + List<Tab> related = getRelatedTabsForId(mModel.get(0).get(TabProperties.TAB_ID)); index = related.indexOf(tab); if (index == -1) return; } else {
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 ee063ae..dae9029 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
@@ -39,7 +39,7 @@ return new GridTabSwitcherCoordinator(activity, activity.getLifecycleDispatcher(), activity.getTabModelSelector(), activity.getTabContentManager(), activity.getCompositorViewHolder(), activity.getFullscreenManager(), activity, - activity.getMenuOrKeyboardActionController(), activity::onBackPressed); + activity.getMenuOrKeyboardActionController(), activity::onBackPressed, activity); } @Override
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMediator.java index a787747..d384ebe 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMediator.java
@@ -69,7 +69,7 @@ (TabGroupModelFilter) mTabModelSelector.getTabModelFilterProvider() .getCurrentTabModelFilter(); - tabGroupModelFilter.mergeListOfTabsToGroup(selectedTabs, destinationTab); + tabGroupModelFilter.mergeListOfTabsToGroup(selectedTabs, destinationTab, false, true); hide();
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/UndoGroupSnackbarController.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/UndoGroupSnackbarController.java new file mode 100644 index 0000000..0dc3f20 --- /dev/null +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/UndoGroupSnackbarController.java
@@ -0,0 +1,113 @@ +// 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.chrome.browser.tasks.tab_management; + +import android.content.Context; + +import org.chromium.chrome.browser.snackbar.Snackbar; +import org.chromium.chrome.browser.snackbar.SnackbarManager; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; +import org.chromium.chrome.browser.tasks.tabgroup.TabGroupModelFilter; +import org.chromium.chrome.tab_ui.R; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +/** + * A controller that listens to + * {@link TabGroupModelFilter.Observer#didCreateGroup(List, List, boolean)} and shows a + * undo snackbar. + */ +public class UndoGroupSnackbarController implements SnackbarManager.SnackbarController { + private final Context mContext; + private final TabModelSelector mTabModelSelector; + private final SnackbarManager.SnackbarManageable mSnackbarManageable; + private final TabGroupModelFilter.Observer mTabGroupModelFilterObserver; + + private class TabUndoInfo { + public final Tab tab; + public final int tabOriginalIndex; + public final int tabOriginalGroupId; + + TabUndoInfo(Tab tab, int tabIndex, int tabGroupId) { + this.tab = tab; + this.tabOriginalIndex = tabIndex; + this.tabOriginalGroupId = tabGroupId; + } + } + + public UndoGroupSnackbarController(Context context, TabModelSelector tabModelSelector, + SnackbarManager.SnackbarManageable snackbarManageable) { + mContext = context; + mTabModelSelector = tabModelSelector; + mSnackbarManageable = snackbarManageable; + mTabGroupModelFilterObserver = new TabGroupModelFilter.Observer() { + @Override + public void didMergeTabToGroup(Tab movedTab, int selectedTabIdInGroup) {} + + @Override + public void didMoveTabGroup(Tab movedTab, int tabModelOldIndex, int tabModelNewIndex) {} + + @Override + public void didMoveWithinGroup( + Tab movedTab, int tabModelOldIndex, int tabModelNewIndex) {} + + @Override + public void didMoveTabOutOfGroup(Tab movedTab, int prevFilterIndex) {} + + @Override + public void didCreateGroup( + List<Tab> tabs, List<Integer> tabOriginalIndex, boolean isSameGroup) { + assert tabs.size() == tabOriginalIndex.size(); + + List<TabUndoInfo> tabUndoInfo = new ArrayList<>(); + for (int i = 0; i < tabs.size(); i++) { + Tab tab = tabs.get(i); + int index = tabOriginalIndex.get(i); + int groupId = isSameGroup ? tabs.get(0).getId() : tab.getId(); + + tabUndoInfo.add(new TabUndoInfo(tab, index, groupId)); + } + showUndoGroupSnackbar(tabUndoInfo); + } + }; + + ((TabGroupModelFilter) mTabModelSelector.getTabModelFilterProvider().getTabModelFilter( + false)) + .addTabGroupObserver(mTabGroupModelFilterObserver); + ((TabGroupModelFilter) mTabModelSelector.getTabModelFilterProvider().getTabModelFilter( + true)) + .addTabGroupObserver(mTabGroupModelFilterObserver); + } + + private void showUndoGroupSnackbar(List<TabUndoInfo> tabUndoInfo) { + String content = String.format(Locale.getDefault(), "%d", tabUndoInfo.size()); + mSnackbarManageable.getSnackbarManager().showSnackbar( + Snackbar.make(content, this, Snackbar.TYPE_ACTION, + Snackbar.UMA_TAB_GROUP_MANUAL_CREATION_UNDO) + .setTemplateText(mContext.getString(R.string.undo_bar_group_tabs_message)) + .setAction(mContext.getString(R.string.undo), tabUndoInfo)); + } + + @Override + public void onAction(Object actionData) { + undo((List<TabUndoInfo>) actionData); + } + + private void undo(List<TabUndoInfo> data) { + assert data.size() != 0; + + TabGroupModelFilter tabGroupModelFilter = + (TabGroupModelFilter) mTabModelSelector.getTabModelFilterProvider() + .getCurrentTabModelFilter(); + for (int i = data.size() - 1; i >= 0; i--) { + TabUndoInfo info = data.get(i); + tabGroupModelFilter.undoGroupedTab( + info.tab, info.tabOriginalIndex, info.tabOriginalGroupId); + } + } +}
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java index e6143f21..2289c27 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java
@@ -456,14 +456,14 @@ } @Test - public void tabAdditionEnd() { + public void tabAddition_Dialog_End() { initAndAssertAllProperties(); Tab newTab = prepareTab(TAB3_ID, TAB3_TITLE); doReturn(3).when(mTabModel).getCount(); doReturn(Arrays.asList(mTab1, mTab2, newTab)) .when(mTabModelFilter) - .getRelatedTabList(eq(TAB3_ID)); + .getRelatedTabList(eq(TAB1_ID)); mTabModelObserverCaptor.getValue().didAddTab(newTab, TabLaunchType.FROM_CHROME_UI); @@ -473,14 +473,14 @@ } @Test - public void tabAdditionMiddle() { + public void tabAddition_Dialog_Middle() { initAndAssertAllProperties(); Tab newTab = prepareTab(TAB3_ID, TAB3_TITLE); doReturn(3).when(mTabModel).getCount(); doReturn(Arrays.asList(mTab1, newTab, mTab2)) .when(mTabModelFilter) - .getRelatedTabList(eq(TAB3_ID)); + .getRelatedTabList(eq(TAB1_ID)); mTabModelObserverCaptor.getValue().didAddTab(newTab, TabLaunchType.FROM_CHROME_UI); @@ -490,6 +490,19 @@ } @Test + public void tabAddition_Dialog_Skip() { + initAndAssertAllProperties(); + + Tab newTab = prepareTab(TAB3_ID, TAB3_TITLE); + // newTab is of another group. + doReturn(Arrays.asList(mTab1, mTab2)).when(mTabModelFilter).getRelatedTabList(eq(TAB1_ID)); + + mTabModelObserverCaptor.getValue().didAddTab(newTab, TabLaunchType.FROM_CHROME_UI); + + assertThat(mModel.size(), equalTo(2)); + } + + @Test public void tabSelection() { initAndAssertAllProperties(); @@ -509,7 +522,7 @@ doReturn(3).when(mTabModel).getCount(); doReturn(Arrays.asList(mTab1, mTab2, newTab)) .when(mTabModelFilter) - .getRelatedTabList(eq(TAB3_ID)); + .getRelatedTabList(eq(TAB1_ID)); mTabModelObserverCaptor.getValue().tabClosureUndone(newTab); @@ -569,6 +582,7 @@ // Assume that TabGroupModelFilter is already updated. doReturn(mTab2).when(mTabGroupModelFilter).getTabAt(POSITION1); doReturn(mTab1).when(mTabGroupModelFilter).getTabAt(POSITION2); + doReturn(2).when(mTabGroupModelFilter).getCount(); mTabGroupModelFilterObserverCaptor.getValue().didMoveTabOutOfGroup(mTab1, POSITION1); @@ -600,6 +614,7 @@ // Assume that TabGroupModelFilter is already updated. doReturn(mTab1).when(mTabGroupModelFilter).getTabAt(POSITION1); doReturn(mTab2).when(mTabGroupModelFilter).getTabAt(POSITION2); + doReturn(2).when(mTabGroupModelFilter).getCount(); mTabGroupModelFilterObserverCaptor.getValue().didMoveTabOutOfGroup(mTab2, POSITION1); @@ -754,6 +769,78 @@ assertThat(mModel.get(0).get(TabProperties.TITLE), equalTo(TAB2_TITLE)); } + @Test + public void undoGrouped_One_Adjacent_Tab() { + setUpForTabGroupOperation(); + + // Assume there are 3 tabs in TabModel, mTab2 just grouped with mTab1; + Tab tab3 = prepareTab(TAB3_ID, TAB3_TITLE); + List<Tab> tabs = new ArrayList<>(Arrays.asList(mTab1, tab3)); + mMediator.resetWithListOfTabs(tabs, false); + assertThat(mModel.size(), equalTo(2)); + + // Assume undo grouping mTab2 with mTab1. + doReturn(3).when(mTabGroupModelFilter).getCount(); + doReturn(mTab1).when(mTabGroupModelFilter).getTabAt(POSITION1); + doReturn(mTab2).when(mTabGroupModelFilter).getTabAt(POSITION2); + doReturn(tab3).when(mTabGroupModelFilter).getTabAt(2); + + mTabGroupModelFilterObserverCaptor.getValue().didMoveTabOutOfGroup(mTab2, POSITION1); + + assertThat(mModel.size(), equalTo(3)); + assertThat(mModel.indexFromId(TAB1_ID), equalTo(0)); + assertThat(mModel.indexFromId(TAB2_ID), equalTo(1)); + assertThat(mModel.indexFromId(TAB3_ID), equalTo(2)); + } + + @Test + public void undoForwardGrouped_One_Tab() { + setUpForTabGroupOperation(); + + // Assume there are 3 tabs in TabModel, tab3 just grouped with mTab1; + Tab tab3 = prepareTab(TAB3_ID, TAB3_TITLE); + List<Tab> tabs = new ArrayList<>(Arrays.asList(mTab1, mTab2)); + mMediator.resetWithListOfTabs(tabs, false); + assertThat(mModel.size(), equalTo(2)); + + // Assume undo grouping tab3 with mTab1. + doReturn(3).when(mTabGroupModelFilter).getCount(); + doReturn(mTab1).when(mTabGroupModelFilter).getTabAt(POSITION1); + doReturn(mTab2).when(mTabGroupModelFilter).getTabAt(POSITION2); + doReturn(tab3).when(mTabGroupModelFilter).getTabAt(2); + + mTabGroupModelFilterObserverCaptor.getValue().didMoveTabOutOfGroup(tab3, POSITION1); + + assertThat(mModel.size(), equalTo(3)); + assertThat(mModel.indexFromId(TAB1_ID), equalTo(0)); + assertThat(mModel.indexFromId(TAB2_ID), equalTo(1)); + assertThat(mModel.indexFromId(TAB3_ID), equalTo(2)); + } + + @Test + public void undoBackwardGrouped_One_Tab() { + setUpForTabGroupOperation(); + + // Assume there are 3 tabs in TabModel, mTab1 just grouped with mTab2; + Tab tab3 = prepareTab(TAB3_ID, TAB3_TITLE); + List<Tab> tabs = new ArrayList<>(Arrays.asList(mTab2, tab3)); + mMediator.resetWithListOfTabs(tabs, false); + assertThat(mModel.size(), equalTo(2)); + + // Assume undo grouping tab3 with mTab1. + doReturn(3).when(mTabGroupModelFilter).getCount(); + doReturn(mTab1).when(mTabGroupModelFilter).getTabAt(POSITION1); + doReturn(mTab2).when(mTabGroupModelFilter).getTabAt(POSITION2); + doReturn(tab3).when(mTabGroupModelFilter).getTabAt(2); + + mTabGroupModelFilterObserverCaptor.getValue().didMoveTabOutOfGroup(mTab1, POSITION2); + + assertThat(mModel.size(), equalTo(3)); + assertThat(mModel.indexFromId(TAB1_ID), equalTo(0)); + assertThat(mModel.indexFromId(TAB2_ID), equalTo(1)); + assertThat(mModel.indexFromId(TAB3_ID), equalTo(2)); + } + private void initAndAssertAllProperties() { List<Tab> tabs = new ArrayList<>(); for (int i = 0; i < mTabModel.getCount(); i++) {
diff --git a/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShell.java b/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShell.java index d1a52ce..a0351ee 100644 --- a/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShell.java +++ b/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShell.java
@@ -208,9 +208,6 @@ if (mVrBrowsingEnabled) { injectVrRootView(); - - // Hide FindInPage toolbar. - mActivity.getFindToolbarManager().hideToolbar(); } // This overrides the default intent created by GVR to return to Chrome when the DON flow
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedImageLoader.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedImageLoader.java index 583159f..6037ab5d 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedImageLoader.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedImageLoader.java
@@ -142,6 +142,13 @@ */ private @DrawableRes int lookupDrawableIdentifier(String resourceName) { switch (resourceName) { + case BundledAssets.AMP_ICON: + case BundledAssets.AMP_ICON_DARK_BG: + return R.drawable.ic_amp_24dp; + case BundledAssets.MENU_ICON: + return R.drawable.ic_more_vert_24dp_on_light_bg; + case BundledAssets.MENU_ICON_DARK_BG: + return R.drawable.ic_more_vert_24dp_on_dark_bg; case BundledAssets.OFFLINE_INDICATOR_BADGE: return R.drawable.ic_offline_pin_24dp_on_light_bg; case BundledAssets.OFFLINE_INDICATOR_BADGE_DARK_BG:
diff --git a/chrome/android/java/res/drawable-hdpi/ic_amp_24dp.png b/chrome/android/java/res/drawable-hdpi/ic_amp_24dp.png new file mode 100644 index 0000000..2216d7d --- /dev/null +++ b/chrome/android/java/res/drawable-hdpi/ic_amp_24dp.png Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/ic_more_vert_24dp_on_dark_bg.png b/chrome/android/java/res/drawable-hdpi/ic_more_vert_24dp_on_dark_bg.png new file mode 100644 index 0000000..ffb6a7f --- /dev/null +++ b/chrome/android/java/res/drawable-hdpi/ic_more_vert_24dp_on_dark_bg.png Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/ic_more_vert_24dp_on_light_bg.png b/chrome/android/java/res/drawable-hdpi/ic_more_vert_24dp_on_light_bg.png new file mode 100644 index 0000000..5bde3f7 --- /dev/null +++ b/chrome/android/java/res/drawable-hdpi/ic_more_vert_24dp_on_light_bg.png Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/ic_more_vert_black_24dp.png b/chrome/android/java/res/drawable-hdpi/ic_more_vert_black_24dp.png deleted file mode 100644 index fa58ddccc..0000000 --- a/chrome/android/java/res/drawable-hdpi/ic_more_vert_black_24dp.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/ic_amp_24dp.png b/chrome/android/java/res/drawable-mdpi/ic_amp_24dp.png new file mode 100644 index 0000000..4998126 --- /dev/null +++ b/chrome/android/java/res/drawable-mdpi/ic_amp_24dp.png Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/ic_more_vert_24dp_on_dark_bg.png b/chrome/android/java/res/drawable-mdpi/ic_more_vert_24dp_on_dark_bg.png new file mode 100644 index 0000000..2358e561 --- /dev/null +++ b/chrome/android/java/res/drawable-mdpi/ic_more_vert_24dp_on_dark_bg.png Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/ic_more_vert_24dp_on_light_bg.png b/chrome/android/java/res/drawable-mdpi/ic_more_vert_24dp_on_light_bg.png new file mode 100644 index 0000000..7c08bc4 --- /dev/null +++ b/chrome/android/java/res/drawable-mdpi/ic_more_vert_24dp_on_light_bg.png Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/ic_more_vert_black_24dp.png b/chrome/android/java/res/drawable-mdpi/ic_more_vert_black_24dp.png deleted file mode 100644 index 1380bf5..0000000 --- a/chrome/android/java/res/drawable-mdpi/ic_more_vert_black_24dp.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/ic_amp_24dp.png b/chrome/android/java/res/drawable-xhdpi/ic_amp_24dp.png new file mode 100644 index 0000000..3f5b945 --- /dev/null +++ b/chrome/android/java/res/drawable-xhdpi/ic_amp_24dp.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/ic_more_vert_24dp_on_dark_bg.png b/chrome/android/java/res/drawable-xhdpi/ic_more_vert_24dp_on_dark_bg.png new file mode 100644 index 0000000..7385c967 --- /dev/null +++ b/chrome/android/java/res/drawable-xhdpi/ic_more_vert_24dp_on_dark_bg.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/ic_more_vert_24dp_on_light_bg.png b/chrome/android/java/res/drawable-xhdpi/ic_more_vert_24dp_on_light_bg.png new file mode 100644 index 0000000..0324bdb --- /dev/null +++ b/chrome/android/java/res/drawable-xhdpi/ic_more_vert_24dp_on_light_bg.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/ic_more_vert_black_24dp.png b/chrome/android/java/res/drawable-xhdpi/ic_more_vert_black_24dp.png deleted file mode 100644 index c92d445..0000000 --- a/chrome/android/java/res/drawable-xhdpi/ic_more_vert_black_24dp.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/ic_amp_24dp.png b/chrome/android/java/res/drawable-xxhdpi/ic_amp_24dp.png new file mode 100644 index 0000000..fea7a785 --- /dev/null +++ b/chrome/android/java/res/drawable-xxhdpi/ic_amp_24dp.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/ic_more_vert_24dp_on_dark_bg.png b/chrome/android/java/res/drawable-xxhdpi/ic_more_vert_24dp_on_dark_bg.png new file mode 100644 index 0000000..979ebcfd --- /dev/null +++ b/chrome/android/java/res/drawable-xxhdpi/ic_more_vert_24dp_on_dark_bg.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/ic_more_vert_24dp_on_light_bg.png b/chrome/android/java/res/drawable-xxhdpi/ic_more_vert_24dp_on_light_bg.png new file mode 100644 index 0000000..62dd9165 --- /dev/null +++ b/chrome/android/java/res/drawable-xxhdpi/ic_more_vert_24dp_on_light_bg.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/ic_more_vert_black_24dp.png b/chrome/android/java/res/drawable-xxhdpi/ic_more_vert_black_24dp.png deleted file mode 100644 index 94b09da..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/ic_more_vert_black_24dp.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/ic_amp_24dp.png b/chrome/android/java/res/drawable-xxxhdpi/ic_amp_24dp.png new file mode 100644 index 0000000..c5d24b9 --- /dev/null +++ b/chrome/android/java/res/drawable-xxxhdpi/ic_amp_24dp.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/ic_more_vert_24dp_on_dark_bg.png b/chrome/android/java/res/drawable-xxxhdpi/ic_more_vert_24dp_on_dark_bg.png new file mode 100644 index 0000000..ea57cd6 --- /dev/null +++ b/chrome/android/java/res/drawable-xxxhdpi/ic_more_vert_24dp_on_dark_bg.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/ic_more_vert_24dp_on_light_bg.png b/chrome/android/java/res/drawable-xxxhdpi/ic_more_vert_24dp_on_light_bg.png new file mode 100644 index 0000000..f58a28cf --- /dev/null +++ b/chrome/android/java/res/drawable-xxxhdpi/ic_more_vert_24dp_on_light_bg.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/ic_more_vert_black_24dp.png b/chrome/android/java/res/drawable-xxxhdpi/ic_more_vert_black_24dp.png deleted file mode 100644 index 3bf4e985..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/ic_more_vert_black_24dp.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/layout/accept_languages_item.xml b/chrome/android/java/res/layout/accept_languages_item.xml index 690b012..deae885 100644 --- a/chrome/android/java/res/layout/accept_languages_item.xml +++ b/chrome/android/java/res/layout/accept_languages_item.xml
@@ -46,7 +46,7 @@ android:paddingStart="@dimen/selectable_list_layout_row_padding" android:paddingEnd="@dimen/selectable_list_layout_row_padding" android:background="@null" - android:src="@drawable/ic_more_vert_black_24dp" + android:src="@drawable/ic_more_vert_24dp" app:menuWidth="@dimen/pref_languages_item_popup_width" app:tint="@color/standard_mode_tint" tools:ignore="ContentDescription" />
diff --git a/chrome/android/java/res/layout/bottom_toolbar_menu_button.xml b/chrome/android/java/res/layout/bottom_toolbar_menu_button.xml index 01d34843..d7c3d3cc 100644 --- a/chrome/android/java/res/layout/bottom_toolbar_menu_button.xml +++ b/chrome/android/java/res/layout/bottom_toolbar_menu_button.xml
@@ -17,7 +17,7 @@ android:layout_height="wrap_content" android:layout_width="wrap_content" android:background="@null" - android:src="@drawable/ic_more_vert_black_24dp" + android:src="@drawable/ic_more_vert_24dp" android:importantForAccessibility="no" android:layout_gravity="center" app:tint="@color/standard_mode_tint" />
diff --git a/chrome/android/java/res/layout/custom_tabs_toolbar.xml b/chrome/android/java/res/layout/custom_tabs_toolbar.xml index 9e37eb7..0319aca4 100644 --- a/chrome/android/java/res/layout/custom_tabs_toolbar.xml +++ b/chrome/android/java/res/layout/custom_tabs_toolbar.xml
@@ -102,7 +102,7 @@ android:layout_gravity="center_vertical|end" android:layout_width="42dp" android:paddingEnd="4dp" - android:src="@drawable/ic_more_vert_black_24dp" + android:src="@drawable/ic_more_vert_24dp" android:contentDescription="@string/accessibility_toolbar_btn_menu" android:background="@null" app:tint="@color/standard_mode_tint" />
diff --git a/chrome/android/java/res/layout/empty_background_view_tablet.xml b/chrome/android/java/res/layout/empty_background_view_tablet.xml index 2ff8f6f..8d935d96 100644 --- a/chrome/android/java/res/layout/empty_background_view_tablet.xml +++ b/chrome/android/java/res/layout/empty_background_view_tablet.xml
@@ -45,7 +45,7 @@ style="@style/ToolbarButton" android:layout_width="48dp" android:layout_height="@dimen/toolbar_height_no_shadow" - android:src="@drawable/ic_more_vert_black_24dp" + android:src="@drawable/ic_more_vert_24dp" android:scaleType="center" android:contentDescription="@string/accessibility_toolbar_btn_menu" android:paddingStart="2dp"
diff --git a/chrome/android/java/res/layout/infobar_translate_compact_content.xml b/chrome/android/java/res/layout/infobar_translate_compact_content.xml index dc12798..449f21d 100644 --- a/chrome/android/java/res/layout/infobar_translate_compact_content.xml +++ b/chrome/android/java/res/layout/infobar_translate_compact_content.xml
@@ -32,6 +32,6 @@ android:scaleType="center" android:background="?attr/selectableItemBackground" android:contentDescription="@string/accessibility_toolbar_btn_menu" - android:src="@drawable/ic_more_vert_black_24dp" + android:src="@drawable/ic_more_vert_24dp" app:tint="@color/standard_mode_tint" /> </LinearLayout>
diff --git a/chrome/android/java/res/layout/list_menu_button.xml b/chrome/android/java/res/layout/list_menu_button.xml index cbc932f7..5972c366 100644 --- a/chrome/android/java/res/layout/list_menu_button.xml +++ b/chrome/android/java/res/layout/list_menu_button.xml
@@ -15,6 +15,6 @@ android:paddingStart="@dimen/selectable_list_layout_row_padding" android:paddingEnd="@dimen/selectable_list_layout_row_padding" android:background="@null" - android:src="@drawable/ic_more_vert_black_24dp" + android:src="@drawable/ic_more_vert_24dp" app:tint="@color/standard_mode_tint" tools:ignore="ContentDescription" />
diff --git a/chrome/android/java/res/layout/menu_button.xml b/chrome/android/java/res/layout/menu_button.xml index 9b88b45..21421a3 100644 --- a/chrome/android/java/res/layout/menu_button.xml +++ b/chrome/android/java/res/layout/menu_button.xml
@@ -15,7 +15,7 @@ <org.chromium.ui.widget.ChromeImageButton android:id="@+id/menu_button" style="@style/ToolbarMenuButtonPhone" - android:src="@drawable/ic_more_vert_black_24dp" + android:src="@drawable/ic_more_vert_24dp" android:contentDescription="@string/accessibility_toolbar_btn_menu" android:layout_gravity="center" app:tint="@color/standard_mode_tint" />
diff --git a/chrome/android/java/res/layout/toolbar_tablet.xml b/chrome/android/java/res/layout/toolbar_tablet.xml index 4ead17f..12630f4 100644 --- a/chrome/android/java/res/layout/toolbar_tablet.xml +++ b/chrome/android/java/res/layout/toolbar_tablet.xml
@@ -84,7 +84,7 @@ <org.chromium.ui.widget.ChromeImageButton android:id="@+id/menu_button" style="@style/ToolbarMenuButtonTablet" - android:src="@drawable/ic_more_vert_black_24dp" + android:src="@drawable/ic_more_vert_24dp" android:contentDescription="@string/accessibility_toolbar_btn_menu" android:layout_gravity="center" app:tint="@color/standard_mode_tint" />
diff --git a/chrome/android/java/res/values/drawables.xml b/chrome/android/java/res/values/drawables.xml index 13b97976..2da6607 100644 --- a/chrome/android/java/res/values/drawables.xml +++ b/chrome/android/java/res/values/drawables.xml
@@ -7,6 +7,7 @@ <drawable name="ntp_search_box">@drawable/modern_toolbar_text_box_background</drawable> <drawable name="badge_update">@drawable/badge_update_dark</drawable> <drawable name="ic_error_24dp_filled">@drawable/ic_error_grey800_24dp_filled</drawable> + <drawable name="ic_more_vert_24dp">@drawable/ic_more_vert_24dp_on_light_bg</drawable> <drawable name="ic_offline_pin_24dp">@drawable/ic_offline_pin_24dp_on_light_bg</drawable> <drawable name="ic_play_circle_filled_24dp"> @drawable/ic_play_circle_filled_24dp_on_light_bg
diff --git a/chrome/android/java/res_night/values-night/drawables.xml b/chrome/android/java/res_night/values-night/drawables.xml index 0d6929ad..2c54f0f4 100644 --- a/chrome/android/java/res_night/values-night/drawables.xml +++ b/chrome/android/java/res_night/values-night/drawables.xml
@@ -5,6 +5,7 @@ <resources> <drawable name="badge_update">@drawable/badge_update_light</drawable> <drawable name="ic_error_24dp_filled">@drawable/ic_error_white_24dp_filled</drawable> + <drawable name="ic_more_vert_24dp">@drawable/ic_more_vert_24dp_on_dark_bg</drawable> <drawable name="ic_offline_pin_24dp">@drawable/ic_offline_pin_24dp_on_dark_bg</drawable> <drawable name="ic_play_circle_filled_24dp"> @drawable/ic_play_circle_filled_24dp_on_dark_bg
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java index a31b993..1cd08339 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -47,6 +47,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.DiscardableReferencePool; import org.chromium.base.ObservableSupplier; +import org.chromium.base.ObservableSupplierImpl; import org.chromium.base.StrictModeContext; import org.chromium.base.SysUtils; import org.chromium.base.TraceEvent; @@ -64,7 +65,6 @@ import org.chromium.chrome.browser.bookmarks.BookmarkModel; import org.chromium.chrome.browser.bookmarks.BookmarkUtils; import org.chromium.chrome.browser.compositor.CompositorViewHolder; -import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.StateChangeReason; import org.chromium.chrome.browser.compositor.bottombar.ephemeraltab.EphemeralTabPanel; import org.chromium.chrome.browser.compositor.layouts.Layout; import org.chromium.chrome.browser.compositor.layouts.LayoutManager; @@ -156,7 +156,6 @@ import org.chromium.chrome.browser.widget.ScrimView; import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet; import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetController; -import org.chromium.chrome.browser.widget.findinpage.FindToolbarManager; import org.chromium.chrome.browser.widget.textbubble.TextBubble; import org.chromium.components.bookmarks.BookmarkId; import org.chromium.components.feature_engagement.EventConstants; @@ -273,14 +272,14 @@ private PictureInPictureController mPictureInPictureController; private CompositorViewHolder mCompositorViewHolder; + private ObservableSupplierImpl<LayoutManager> mLayoutManagerSupplier = + new ObservableSupplierImpl<>(); private InsetObserverView mInsetObserverView; private ContextualSearchManager mContextualSearchManager; protected ReaderModeManager mReaderModeManager; private SnackbarManager mSnackbarManager; @Nullable private ToolbarManager mToolbarManager; - @Nullable - private FindToolbarManager mFindToolbarManager; private BottomSheetController mBottomSheetController; private UpdateNotificationController mUpdateNotificationController; private BottomSheet mBottomSheet; @@ -628,8 +627,9 @@ } private void initializeToolbarIfNecessary() { - // TODO(pshmakov): make ToolbarManager and FindToolbarManager lazy, don't create them unless - // getToolbarManager() or getFindToolbarManager() is called. + // TODO(https://crbug.com/931496): Move toolbar ownership to RootUiCoordinator. + // TODO(pshmakov): make ToolbarManager lazy, don't create them unless getToolbarManager() + // is called. if (!mToolbarInitialized) { mToolbarInitialized = true; initializeToolbar(); @@ -649,8 +649,6 @@ mToolbarManager = new ToolbarManager(this, toolbarContainer, getCompositorViewHolder().getInvalidator(), urlFocusChangedCallback, mTabThemeColorProvider); - mFindToolbarManager = - new FindToolbarManager(this, mToolbarManager.getActionModeControllerCallback()); } } @@ -733,17 +731,6 @@ } /** - * @return {@link FindToolbarManager} that belongs to this activity. - */ - @Nullable - public FindToolbarManager getFindToolbarManager() { - if (isInitialLayoutInflationComplete()) { - initializeToolbarIfNecessary(); - } - return mFindToolbarManager; - } - - /** * @return The {@link ManualFillingComponent} that belongs to this activity. */ public ManualFillingComponent getManualFillingComponent() { @@ -835,9 +822,6 @@ if (isContextualSearchAllowed() && ContextualSearchFieldTrial.isEnabled()) { mContextualSearchManager = new ContextualSearchManager(this, this); - if (mFindToolbarManager != null) { - mContextualSearchManager.setFindToolbarManager(mFindToolbarManager); - } } if (ReaderModeManager.isEnabled(this)) { @@ -1869,6 +1853,16 @@ mActivityTabProvider.setLayoutManager(layoutManager); EphemeralTabPanel panel = layoutManager.getEphemeralTabPanel(); if (panel != null) panel.setChromeActivity(this); + + mLayoutManagerSupplier.set(layoutManager); + } + + /** + * @return An {@link ObservableSupplier} that will supply the {@link LayoutManager} when it is + * ready. + */ + public ObservableSupplier<LayoutManager> getLayoutManagerSupplier() { + return mLayoutManagerSupplier; } /** @@ -2084,22 +2078,6 @@ if (id == R.id.preferences_id) { PreferencesLauncher.launchSettingsPage(this, null); RecordUserAction.record("MobileMenuSettings"); - } else if (id == R.id.find_in_page_id) { - if (mFindToolbarManager == null) return false; - - mFindToolbarManager.showToolbar(); - if (mContextualSearchManager != null) { - getContextualSearchManager().hideContextualSearch(StateChangeReason.UNKNOWN); - } - if (getEphemeralTabPanel() != null) { - getEphemeralTabPanel().closePanel(StateChangeReason.UNKNOWN, true); - } - if (fromMenu) { - RecordUserAction.record("MobileMenuFindInPage"); - } else { - RecordUserAction.record("MobileShortcutFindInPage"); - } - return true; } if (id == R.id.update_menu_id) { @@ -2519,6 +2497,13 @@ } /** + * @return Whether this activity supports the find in page feature. + */ + public boolean supportsFindInPage() { + return true; + } + + /** * TODO(mthiesse): Figure out a way to clean this up. The problem is that the * TouchlessUiCoordinator has an implementation of the ModalDialogManager, which is created in * AsyncInitializationActivity#onCreateInternal, before any ChromeActivity init functions are
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index 402e898..08947b0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -751,9 +751,9 @@ } getToolbarManager().initializeWithNative(mTabModelSelectorImpl, - getFullscreenManager().getBrowserVisibilityDelegate(), getFindToolbarManager(), - mOverviewModeController, mLayoutManager, tabSwitcherClickHandler, - newTabClickHandler, bookmarkClickHandler, null); + getFullscreenManager().getBrowserVisibilityDelegate(), mOverviewModeController, + mLayoutManager, tabSwitcherClickHandler, newTabClickHandler, + bookmarkClickHandler, null); mLayoutManager.setToolbarManager(getToolbarManager()); @@ -2303,7 +2303,6 @@ @Override public void onOverviewModeStartedShowing(boolean showToolbar) { - if (getFindToolbarManager() != null) getFindToolbarManager().hideToolbar(); if (getAssistStatusHandler() != null) getAssistStatusHandler().updateAssistState(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java index a81b15df..74c4a2b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
@@ -47,8 +47,6 @@ import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver; import org.chromium.chrome.browser.tabmodel.TabSelectionType; -import org.chromium.chrome.browser.widget.findinpage.FindToolbarManager; -import org.chromium.chrome.browser.widget.findinpage.FindToolbarObserver; import org.chromium.components.feature_engagement.EventConstants; import org.chromium.components.feature_engagement.FeatureConstants; import org.chromium.components.feature_engagement.Tracker; @@ -152,8 +150,6 @@ private OverlayPanelContentViewDelegate mSearchContentViewDelegate; private TabModelSelectorTabModelObserver mTabModelObserver; private TabModelSelectorTabObserver mTabModelSelectorTabObserver; - private FindToolbarManager mFindToolbarManager; - private FindToolbarObserver mFindToolbarObserver; private ContextualSearchIPH mInProductHelp; private boolean mDidStartLoadingResolvedSearchRequest; @@ -278,30 +274,6 @@ } /** - * Sets the {@link FindToolbarManager} and attaches an observer that dismisses the Contextual - * Search panel when the find toolbar is shown. - * - * @param findToolbarManager The {@link FindToolbarManager} for the current activity. - */ - public void setFindToolbarManager(FindToolbarManager findToolbarManager) { - if (mFindToolbarManager != null) { - mFindToolbarManager.removeObserver(mFindToolbarObserver); - } - - mFindToolbarManager = findToolbarManager; - - if (mFindToolbarObserver == null) { - mFindToolbarObserver = new FindToolbarObserver() { - @Override - public void onFindToolbarShown() { - hideContextualSearch(StateChangeReason.UNKNOWN); - } - }; - } - mFindToolbarManager.addObserver(mFindToolbarObserver); - } - - /** * Destroys the native Contextual Search Manager. * Call this method before orphaning this object to allow it to be garbage collected. */ @@ -313,11 +285,6 @@ nativeDestroy(mNativeContextualSearchManagerPtr); stopListeningForHideNotifications(); mTabRedirectHandler.clear(); - if (mFindToolbarManager != null) { - mFindToolbarManager.removeObserver(mFindToolbarObserver); - mFindToolbarManager = null; - mFindToolbarObserver = null; - } mInternalStateController.enter(InternalState.UNDEFINED); } @@ -434,9 +401,6 @@ */ private void showContextualSearch(@StateChangeReason int stateChangeReason) { assert mSearchPanel != null; - if (mFindToolbarManager != null) { - mFindToolbarManager.hideToolbar(false); - } // Dismiss the undo SnackBar if present by committing all tab closures. mActivity.getTabModelSelector().commitAllTabClosures();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarCoordinator.java index 904ed394..deb2a5e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarCoordinator.java
@@ -35,7 +35,6 @@ import org.chromium.chrome.browser.toolbar.ToolbarManager; import org.chromium.chrome.browser.util.ColorUtils; import org.chromium.chrome.browser.util.FeatureUtilities; -import org.chromium.chrome.browser.widget.findinpage.FindToolbarManager; import javax.inject.Inject; import javax.inject.Named; @@ -67,7 +66,6 @@ private final Context mAppContext; private final CustomTabActivityTabController mTabController; private final Lazy<ChromeFullscreenManager> mFullscreenManager; - private final Lazy<FindToolbarManager> mFindToolbarManager; private final CustomTabActivityNavigationController mNavigationController; private final TabObserverRegistrar mTabObserverRegistrar; private final CustomTabStatusBarColorProvider mStatusBarColorProvider; @@ -87,7 +85,6 @@ @Named(APP_CONTEXT) Context appContext, CustomTabActivityTabController tabController, Lazy<ChromeFullscreenManager> fullscreenManager, - Lazy<FindToolbarManager> findToolbarManager, CustomTabActivityNavigationController navigationController, TabObserverRegistrar tabObserverRegistrar, CustomTabStatusBarColorProvider statusBarColorProvider, @@ -101,7 +98,6 @@ mAppContext = appContext; mTabController = tabController; mFullscreenManager = fullscreenManager; - mFindToolbarManager = findToolbarManager; mNavigationController = navigationController; mTabObserverRegistrar = tabObserverRegistrar; mStatusBarColorProvider = statusBarColorProvider; @@ -231,8 +227,8 @@ mActivity.findViewById(R.id.control_container)); mToolbarManager.get().initializeWithNative(mTabController.getTabModelSelector(), - mFullscreenManager.get().getBrowserVisibilityDelegate(), mFindToolbarManager.get(), - null, layoutDriver, null, null, null, v -> onCloseButtonClick()); + mFullscreenManager.get().getBrowserVisibilityDelegate(), null, layoutDriver, null, + null, null, v -> onCloseButtonClick()); mInitializedToolbarWithNative = true; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeActivityCommonsModule.java b/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeActivityCommonsModule.java index b3ab4a1..2d29bdf 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeActivityCommonsModule.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeActivityCommonsModule.java
@@ -24,7 +24,6 @@ import org.chromium.chrome.browser.ui.system.StatusBarColorController; import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetController; import org.chromium.content_public.browser.ScreenOrientationProvider; -import org.chromium.chrome.browser.widget.findinpage.FindToolbarManager; import org.chromium.ui.base.ActivityWindowAndroid; import javax.inject.Named; @@ -144,9 +143,4 @@ public ScreenOrientationProvider provideScreenOrientationProvider() { return ScreenOrientationProvider.getInstance(); } - - @Provides - public FindToolbarManager provideFindToolbarManager() { - return mActivity.getFindToolbarManager(); - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePagesDownloadManagerBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageArchivePublisherBridge.java similarity index 96% rename from chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePagesDownloadManagerBridge.java rename to chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageArchivePublisherBridge.java index 35215fd..fc92a54 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePagesDownloadManagerBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageArchivePublisherBridge.java
@@ -20,9 +20,9 @@ * transfer all C++ calls over to Java land for making the call to ADM. This is a one-way bridge, * from C++ to Java only. The Java side of this bridge is not called by other Java code. */ -@JNINamespace("offline_pages::android") -public class OfflinePagesDownloadManagerBridge { - private static final String TAG = "OfflinePagesDMBridge"; +@JNINamespace("offline_pages") +public class OfflinePageArchivePublisherBridge { + private static final String TAG = "Publisher"; /** Offline pages should not be scanned as for media content. */ public static final boolean IS_MEDIA_SCANNER_SCANNABLE = false;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java index 5bc237d6e..ef2e053 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java
@@ -58,17 +58,9 @@ if (profile == null) return null; - OfflinePageBridge bridge = nativeGetOfflinePageBridgeForProfileKey(profile.getProfileKey()); - - // TODO(crbug.com/978871): Storing Profile is a temporary hack during the transition - // of some members to RequestCoordinatorBridge. - if (bridge != null) { - bridge.mProfile = profile; - } - return bridge; + return nativeGetOfflinePageBridgeForProfileKey(profile.getProfileKey()); } - private Profile mProfile; private long mNativeOfflinePageBridge; private boolean mIsNativeOfflinePageModelLoaded; private final ObserverList<OfflinePageModelObserver> mObservers = @@ -220,70 +212,6 @@ } /** - * Gets all the URLs in the request queue. - * - * @return A list of {@link SavePageRequest} representing all the queued requests. - * @deprecated Use {@link - * RequestCoordinatorBridge#getRequestsInQueue(Callback<SavePageRequest[]>)} instead. - */ - @Deprecated - @VisibleForTesting - public void getRequestsInQueue(Callback<SavePageRequest[]> callback) { - RequestCoordinatorBridge.getForProfile(mProfile).getRequestsInQueue(callback); - } - - /** - * Contains a result for a remove page request. - * @deprecated Use {@link RequestCoordinatorBridge.RequestRemovedResult} instead. - */ - @Deprecated - public static class RequestRemovedResult { - private long mRequestId; - private int mUpdateRequestResult; - - public RequestRemovedResult(long requestId, int requestResult) { - mRequestId = requestId; - mUpdateRequestResult = requestResult; - } - - /** Request ID as found in the SavePageRequest. */ - public long getRequestId() { - return mRequestId; - } - - /** {@see org.chromium.components.offlinepages.background.UpdateRequestResult} enum. */ - public int getUpdateRequestResult() { - return mUpdateRequestResult; - } - } - - /** - * Removes SavePageRequests from the request queue. - * - * The callback will be called with |null| in the case that the queue is unavailable. This can - * happen in incognito, for example. - * - * @param requestIdList The IDs of the requests to remove. - * @param callback Called when the removal is done, with the SavePageRequest objects that were - * actually removed. - * @deprecated Use {@link RequestCoordinatorBridge#removeRequestsFromQueue(List<Long>, - * Callback<List<RequestCoordinatorBridge.RequestRemovedResult>>)} instead. - */ - @Deprecated - public void removeRequestsFromQueue( - List<Long> requestIdList, Callback<List<RequestRemovedResult>> callback) { - RequestCoordinatorBridge.getForProfile(mProfile).removeRequestsFromQueue( - requestIdList, (results) -> { - List<RequestRemovedResult> transformedResults = new ArrayList<>(results.size()); - for (RequestCoordinatorBridge.RequestRemovedResult result : results) { - transformedResults.add(new RequestRemovedResult( - result.getRequestId(), result.getUpdateRequestResult())); - } - callback.onResult(transformedResults); - }); - } - - /** * Get the offline page associated with the provided offline URL. * * @param onlineUrl URL of the page. @@ -351,143 +279,6 @@ } /** - * Save the given URL as an offline page when the network becomes available. - * - * The page is marked as not having been saved by the user. Use the 3-argument form to specify - * a user request. - * - * @param url The given URL to save for later. - * @param clientId The client ID for the offline page to be saved later. - * @deprecated Use {@link RequestCoordinatorBridge#savePageLater(String, ClientId)} instead. - */ - @Deprecated - @VisibleForTesting - public void savePageLater(String url, ClientId clientId) { - savePageLater(url, clientId, true); - } - - /** - * Save the given URL as an offline page when the network becomes available. Origin is - * assumed to be Chrome. - * - * @param url The given URL to save for later. - * @param clientId The client ID for the offline page to be saved later. - * @param userRequested Whether this request should be prioritized because the user explicitly - * requested it. - * @deprecated Use {@link RequestCoordinatorBridge#savePageLater(String, ClientId, boolean)} - * instead. - */ - @Deprecated - public void savePageLater(final String url, final ClientId clientId, boolean userRequested) { - savePageLater(url, clientId, userRequested, new OfflinePageOrigin()); - } - - /** - * Save the given URL as an offline page when the network becomes available with the given - * origin. - * - * @param url The given URL to save for later - * @param clientId The clientId for the offline page to be saved later. - * @param userRequested Whether this request should be prioritized because the user explicitly - * requested it. - * @param origin The app that initiated the request. - * @deprecated Use {@link RequestCoordinatorBridge#savePageLater(String, ClientId, boolean, - * OfflinePageOrigin)} instead. - */ - @Deprecated - public void savePageLater(final String url, final ClientId clientId, boolean userRequested, - OfflinePageOrigin origin) { - savePageLater(url, clientId, userRequested, origin, null); - } - - /** - * Save the given URL as an offline page when the network becomes available with the given - * origin. Callback with status when done. - * - * @param url The given URL to save for later. - * @param clientId the clientId for the offline page to be saved later. - * @param userRequested Whether this request should be prioritized because the user explicitly - * requested it. - * @param origin The app that initiated the request. - * @param callback Callback for whether the URL is successfully added to queue. Non-zero number - * represents a failure reason (See offline_pages::AddRequestResult enum). 0 is - * success. - * @deprecated Use {@link RequestCoordinatorBridge#savePageLater(String, ClientId, boolean, - * OfflinePageOrigin, Callback<Integer>)} instead. - */ - @Deprecated - public void savePageLater(final String url, final ClientId clientId, boolean userRequested, - OfflinePageOrigin origin, Callback<Integer> callback) { - Callback<Integer> wrapper = new Callback<Integer>() { - @Override - public void onResult(Integer i) { - if (callback != null) { - callback.onResult(i); - } - } - }; - RequestCoordinatorBridge.getForProfile(mProfile).savePageLater( - url, clientId, userRequested, origin, callback); - } - - /** - * Save the given URL as an offline page when the network becomes available with a randomly - * generated clientId in the given namespace. Origin is defaulted to Chrome. - * - * @param url The given URL to save for later. - * @param namespace The namespace for the offline page to be saved later. - * @param userRequested Whether this request should be prioritized because the user explicitly - * requested it. - * @deprecated Use {@link RequestCoordinatorBridge#savePageLater(String, String, boolean)} - * instead. - */ - @Deprecated - public void savePageLater(final String url, final String namespace, boolean userRequested) { - savePageLater(url, namespace, userRequested, new OfflinePageOrigin()); - } - - /** - * Save the given URL as an offline page when the network becomes available with a randomly - * generated clientId in the given namespace and the given origin. - * - * @param url The given URL to save for later - * @param namespace The namespace for the offline page to be saved later. - * @param userRequested Whether this request should be prioritized because the user explicitly - * requested it. - * @param origin The app that initiated the request. - * @deprecated Use {@link RequestCoordinatorBridge#savePageLater(String, String, boolean, - * OfflinePageOrigin)} instead. - */ - @Deprecated - public void savePageLater(final String url, final String namespace, boolean userRequested, - OfflinePageOrigin origin) { - savePageLater(url, namespace, userRequested, origin, null); - } - - /** - * Save the given URL as an offline page when the network becomes available with a randomly - * generated clientId in the given namespace and the given origin. Calls back with whether - * the URL has been successfully added to queue. - * - * @param url The given URL to save for later - * @param namespace The namespace for the offline page to be saved later. - * @param userRequested Whether this request should be prioritized because the user explicitly - * requested it. - * @param origin The app that initiated the request. - * @param callback Callback to call whether the URL is successfully added to the queue. Non-zero - * number represents failure reason (see offline_pages::AddRequestResult enum). - * @deprecated Use {@link RequestCoordinatorBridge#savePageLater(String, String, boolean, - * OfflinePageOrigin, Callback<Integer>)} instead. - * 0 is success. - */ - @Deprecated - public void savePageLater(final String url, final String namespace, boolean userRequested, - OfflinePageOrigin origin, Callback<Integer> callback) { - ClientId clientId = ClientId.createGuidClientIdForNamespace(namespace); - savePageLater(url, clientId, userRequested, origin, callback); - } - - /** * Deletes an offline page related to a specified bookmark. * * @param clientId Client ID for which the offline copy will be deleted.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionViewBinder.java index a3be117a..9e11de43 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionViewBinder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionViewBinder.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.browser.omnibox.suggestions.answer; +import android.support.v4.view.ViewCompat; + import org.chromium.chrome.R; import org.chromium.chrome.browser.omnibox.suggestions.SuggestionCommonProperties; import org.chromium.chrome.browser.omnibox.suggestions.answer.AnswerSuggestionViewProperties.AnswerIcon; @@ -37,6 +39,9 @@ propertyKey)) { view.setLine2AccessibilityDescription(model.get( AnswerSuggestionViewProperties.TEXT_LINE_2_ACCESSIBILITY_DESCRIPTION)); + } else if (SuggestionCommonProperties.LAYOUT_DIRECTION.equals(propertyKey)) { + ViewCompat.setLayoutDirection( + view, model.get(SuggestionCommonProperties.LAYOUT_DIRECTION)); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/editurl/EditUrlSuggestionViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/editurl/EditUrlSuggestionViewBinder.java index 3e0500b..3c6388c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/editurl/EditUrlSuggestionViewBinder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/editurl/EditUrlSuggestionViewBinder.java
@@ -7,6 +7,7 @@ import android.graphics.Bitmap; import android.graphics.drawable.Drawable; import android.support.v4.graphics.drawable.DrawableCompat; +import android.support.v7.content.res.AppCompatResources; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; @@ -60,7 +61,8 @@ view.setImageBitmap(bitmap); } else { boolean useDarkColors = model.get(SuggestionCommonProperties.USE_DARK_COLORS); - Drawable icon = view.getContext().getResources().getDrawable(R.drawable.ic_globe_24dp); + Drawable icon = + AppCompatResources.getDrawable(view.getContext(), R.drawable.ic_globe_24dp); int color = view.getContext().getResources().getColor(useDarkColors ? R.color.default_icon_color_secondary_list : R.color.white_mode_tint);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/entity/EntitySuggestionViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/entity/EntitySuggestionViewBinder.java index 44bcf82..ab7043d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/entity/EntitySuggestionViewBinder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/entity/EntitySuggestionViewBinder.java
@@ -7,6 +7,7 @@ import android.graphics.Bitmap; import android.graphics.Color; import android.os.Handler; +import android.support.v4.view.ViewCompat; import android.view.MotionEvent; import org.chromium.chrome.browser.omnibox.suggestions.SuggestionCommonProperties; @@ -104,6 +105,9 @@ applySuggestionImage(model, view); } else if (SuggestionCommonProperties.USE_DARK_COLORS.equals(propertyKey)) { view.setUseDarkColors(model.get(SuggestionCommonProperties.USE_DARK_COLORS)); + } else if (SuggestionCommonProperties.LAYOUT_DIRECTION.equals(propertyKey)) { + ViewCompat.setLayoutDirection( + view, model.get(SuggestionCommonProperties.LAYOUT_DIRECTION)); } } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestFactory.java index 6f56531..a8502a6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestFactory.java
@@ -8,6 +8,8 @@ import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeFeatureList; +import org.chromium.chrome.browser.preferences.Pref; +import org.chromium.chrome.browser.preferences.PrefServiceBridge; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelUtils; import org.chromium.components.payments.ErrorStrings; @@ -118,6 +120,11 @@ } @Override + public boolean prefsCanMakePayment() { + return PrefServiceBridge.getInstance().getBoolean(Pref.CAN_MAKE_PAYMENT_ENABLED); + } + + @Override public boolean skipUiForBasicCard() { return false; // Only tests do this. }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java index 7a59337..0e7d82a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
@@ -34,8 +34,6 @@ import org.chromium.chrome.browser.payments.ui.SectionInformation; import org.chromium.chrome.browser.payments.ui.ShoppingCart; import org.chromium.chrome.browser.preferences.MainPreferences; -import org.chromium.chrome.browser.preferences.Pref; -import org.chromium.chrome.browser.preferences.PrefServiceBridge; import org.chromium.chrome.browser.preferences.PreferencesLauncher; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.ssl.SecurityStateModel; @@ -132,6 +130,10 @@ */ boolean isWebContentsActive(TabModel model, WebContents webContents); /** + * Returns whether the preferences allow CAN_MAKE_PAYMENT. + */ + boolean prefsCanMakePayment(); + /** * Returns true if the UI can be skipped for "basic-card" scenarios. This will only ever * be true in tests. */ @@ -1875,7 +1877,7 @@ mIsCanMakePaymentResponsePending = false; boolean response = legacyMode ? mHasEnrolledInstrument : mArePaymentMethodsSupported; - response &= PrefServiceBridge.getInstance().getBoolean(Pref.CAN_MAKE_PAYMENT_ENABLED); + response &= mDelegate.prefsCanMakePayment(); // Only need to enforce query quota in legacy mode. Per-method quota not supported. if (legacyMode @@ -2010,8 +2012,7 @@ } // Always return false when can make payment is disabled. - mHasEnrolledInstrument &= - PrefServiceBridge.getInstance().getBoolean(Pref.CAN_MAKE_PAYMENT_ENABLED); + mHasEnrolledInstrument &= mDelegate.prefsCanMakePayment(); int additionalTextResourceId = app.getAdditionalAppTextResourceId(); if (additionalTextResourceId != 0) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ServiceWorkerPaymentAppBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ServiceWorkerPaymentAppBridge.java index 3307133..a988da2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ServiceWorkerPaymentAppBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ServiceWorkerPaymentAppBridge.java
@@ -25,6 +25,7 @@ import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.WebContents; import org.chromium.payments.mojom.PaymentDetailsModifier; +import org.chromium.payments.mojom.PaymentEventResponseType; import org.chromium.payments.mojom.PaymentItem; import org.chromium.payments.mojom.PaymentMethodData; @@ -257,13 +258,15 @@ // Notify closing payment app window so as to abort payment if unsecure. WebContents webContents = tab.getWebContents(); if (!SslValidityChecker.isValidPageInPaymentHandlerWindow(webContents)) { - onClosingPaymentAppWindow(webContents); + nativeOnClosingPaymentAppWindow(webContents, + PaymentEventResponseType.PAYMENT_HANDLER_INSECURE_NAVIGATION); } } @Override public void onDidAttachInterstitialPage(Tab tab) { - onClosingPaymentAppWindow(tab.getWebContents()); + nativeOnClosingPaymentAppWindow(tab.getWebContents(), + PaymentEventResponseType.PAYMENT_HANDLER_INSECURE_NAVIGATION); } }); } @@ -274,7 +277,8 @@ * @param webContents The web contents in the opened window. */ public static void onClosingPaymentAppWindow(WebContents webContents) { - nativeOnClosingPaymentAppWindow(webContents); + nativeOnClosingPaymentAppWindow( + webContents, PaymentEventResponseType.PAYMENT_HANDLER_WINDOW_CLOSING); } @CalledByNative @@ -479,5 +483,5 @@ String topOrigin, String paymentRequestOrigin, PaymentMethodData[] methodData, PaymentDetailsModifier[] modifiers, CanMakePaymentCallback callback); - private static native void nativeOnClosingPaymentAppWindow(WebContents webContents); + private static native void nativeOnClosingPaymentAppWindow(WebContents webContents, int reason); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferences.java index a55626ef..24e28d6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferences.java
@@ -15,7 +15,6 @@ import android.view.MenuItem; import org.chromium.base.BuildInfo; -import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.contextualsearch.ContextualSearchFieldTrial; @@ -156,7 +155,6 @@ (boolean) newValue); } else if (PREF_NETWORK_PREDICTIONS.equals(key)) { PrefServiceBridge.getInstance().setNetworkPredictionEnabled((boolean) newValue); - recordNetworkPredictionEnablingUMA((boolean) newValue); } else if (PREF_NAVIGATION_ERROR.equals(key)) { PrefServiceBridge.getInstance().setResolveNavigationErrorEnabled((boolean) newValue); } else if (PREF_CAN_MAKE_PAYMENT.equals(key)) { @@ -167,11 +165,6 @@ return true; } - private void recordNetworkPredictionEnablingUMA(boolean enabled) { - // Report user turning on and off NetworkPrediction. - RecordHistogram.recordBooleanHistogram("PrefService.NetworkPredictionEnabled", enabled); - } - @Override public void onResume() { super.onResume();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/Snackbar.java b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/Snackbar.java index 9ea8a47..fb10292 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/Snackbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/Snackbar.java
@@ -83,6 +83,7 @@ public static final int UMA_AUTOFILL_ASSISTANT_STOP_UNDO = 29; public static final int UMA_TAB_CLOSE_MULTIPLE_UNDO = 30; public static final int UMA_SEARCH_ENGINE_CHOICE_NOTIFICATION = 31; + public static final int UMA_TAB_GROUP_MANUAL_CREATION_UNDO = 32; private SnackbarController mController; private CharSequence mText;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tabgroup/TabGroupModelFilter.java b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tabgroup/TabGroupModelFilter.java index 368b289..037f6ae 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tabgroup/TabGroupModelFilter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tabgroup/TabGroupModelFilter.java
@@ -82,6 +82,16 @@ * moveTab} is in before ungrouping. */ void didMoveTabOutOfGroup(Tab movedTab, int prevFilterIndex); + + /** + * This method is called after a group is created manually by user. Either using the + * TabSelectionEditor (Group tab menu item) or using drag and drop. + * @param tabs The list of modified {@link Tab}s. + * @param tabOriginalIndex The original tab index for each modified tab. + * @param isSameGroup Whether the given list is in a group already. + */ + void didCreateGroup( + List<Tab> tabs, List<Integer> tabOriginalIndex, boolean isSameGroup); } /** @@ -279,8 +289,10 @@ tabsToMerge.get(tabsToMerge.size() - 1), group.getLastShownTabId()); } } else { - mergeListOfTabsToGroup(tabsToMerge, destinationTab); + mergeListOfTabsToGroup(tabsToMerge, destinationTab, true, false); } + // TODO(978508): Send didCreateGroup signal to activate the + // {@link UndoGroupSnackbarController}. } /** @@ -291,22 +303,36 @@ * * @param tabs List of {@link Tab}s to be appended. * @param destinationTab The destination {@link Tab} to be append to. + * @param isSameGroup Whether the given list of {@link Tab}s belongs in the same group + * originally. + * @param notify Whether or not to notify observers about the merging events. */ - public void mergeListOfTabsToGroup(List<Tab> tabs, Tab destinationTab) { + public void mergeListOfTabsToGroup( + List<Tab> tabs, Tab destinationTab, boolean isSameGroup, boolean notify) { int destinationGroupId = destinationTab.getRootId(); int destinationIndexInTabModel = getTabModelDestinationIndex(destinationTab); + List<Integer> originalIndexes = new ArrayList<>(); for (int i = 0; i < tabs.size(); i++) { Tab tab = tabs.get(i); + int index = TabModelUtils.getTabIndexById(getTabModel(), tab.getId()); + assert index != TabModel.INVALID_TAB_INDEX; + originalIndexes.add(index); + if (tab.getId() == destinationTab.getId()) continue; - int index = TabModelUtils.getTabIndexById(getTabModel(), tab.getId()); boolean isMergingBackward = index < destinationIndexInTabModel; tab.setRootId(destinationGroupId); getTabModel().moveTab(tab.getId(), isMergingBackward ? destinationIndexInTabModel : destinationIndexInTabModel++); } + + if (notify) { + for (Observer observer : mGroupFilterObserver) { + observer.didCreateGroup(tabs, originalIndexes, isSameGroup); + } + } } /** @@ -367,6 +393,26 @@ return firstTabIndexInTabModel != destinationIndexInTabModel; } + /** + * This method undo the given grouped {@link Tab}. + * + * @param tab undo this grouped {@link Tab}. + * @param originalIndex The tab index before grouped. + * @param originalGroupId The rootId before grouped. + */ + public void undoGroupedTab(Tab tab, int originalIndex, int originalGroupId) { + int currentIndex = TabModelUtils.getTabIndexById(getTabModel(), tab.getId()); + assert currentIndex != TabModel.INVALID_TAB_INDEX; + + tab.setRootId(originalGroupId); + if (currentIndex == originalIndex) { + didMoveTab(tab, originalIndex, currentIndex); + } else { + if (currentIndex < originalIndex) originalIndex++; + getTabModel().moveTab(tab.getId(), originalIndex); + } + } + // TODO(crbug.com/951608): follow up with sessions count histogram for TabGroups. private int updateAndGetSessionsCount(int groupId) { ThreadUtils.assertOnBackgroundThread();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabCountProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabCountProvider.java index 5a85cc99..86fe4ea 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabCountProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabCountProvider.java
@@ -160,6 +160,12 @@ public void didMoveTabOutOfGroup(Tab moveTab, int oldFilterIndex) { updateTabCount(); } + + @Override + public void didCreateGroup( + List<Tab> tabs, List<Integer> tabOriginalIndex, boolean isSameGroup) { + updateTabCount(); + } }; if (mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter()
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java index 0468a3ec..2593b38b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -935,17 +935,15 @@ * * @param tabModelSelector The selector that handles tab management. * @param controlsVisibilityDelegate The delegate to handle visibility of browser controls. - * @param findToolbarManager The manager for find in page. * @param overviewModeBehavior The overview mode manager. * @param layoutManager A {@link LayoutManager} instance used to watch for scene * changes. */ public void initializeWithNative(TabModelSelector tabModelSelector, BrowserStateBrowserControlsVisibilityDelegate controlsVisibilityDelegate, - FindToolbarManager findToolbarManager, OverviewModeBehavior overviewModeBehavior, - LayoutManager layoutManager, OnClickListener tabSwitcherClickHandler, - OnClickListener newTabClickHandler, OnClickListener bookmarkClickHandler, - OnClickListener customTabsBackClickHandler) { + OverviewModeBehavior overviewModeBehavior, LayoutManager layoutManager, + OnClickListener tabSwitcherClickHandler, OnClickListener newTabClickHandler, + OnClickListener bookmarkClickHandler, OnClickListener customTabsBackClickHandler) { assert !mInitializedWithNative; mTabModelSelector = tabModelSelector; @@ -971,15 +969,12 @@ mLocationBarModel.setShouldShowOmniboxInOverviewMode( ReturnToChromeExperimentsUtil.shouldShowOmniboxOnTabSwitcher()); - mFindToolbarManager = findToolbarManager; assert controlsVisibilityDelegate != null; mControlsVisibilityDelegate = controlsVisibilityDelegate; mNativeLibraryReady = false; - mFindToolbarManager.addObserver(mFindToolbarObserver); - if (overviewModeBehavior != null) { mOverviewModeBehavior = overviewModeBehavior; mOverviewModeBehavior.addOverviewModeObserver(mOverviewModeObserver); @@ -1030,6 +1025,15 @@ } /** + * Set the {@link FindToolbarManager}. + * @param findToolbarManager The manager for find in page. + */ + public void setFindToolbarManager(FindToolbarManager findToolbarManager) { + mFindToolbarManager = findToolbarManager; + mFindToolbarManager.addObserver(mFindToolbarObserver); + } + + /** * Show the update badge in both the top and bottom toolbar. * TODO(amaralp): Only the top or bottom menu should be visible. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java index 746c121..6c5e472 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java
@@ -2702,7 +2702,7 @@ private void setTabSwitcherAnimationMenuDrawable() { mTabSwitcherAnimationMenuDrawable = ApiCompatibilityUtils - .getDrawable(getResources(), R.drawable.ic_more_vert_black_24dp) + .getDrawable(getResources(), R.drawable.ic_more_vert_24dp_on_dark_bg) .mutate(); ((BitmapDrawable) mTabSwitcherAnimationMenuDrawable).setGravity(Gravity.CENTER); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java index 83ebebba..8fabb70 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
@@ -6,15 +6,25 @@ import android.support.annotation.Nullable; +import org.chromium.base.Callback; import org.chromium.base.VisibleForTesting; +import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.MenuOrKeyboardActionController; import org.chromium.chrome.browser.appmenu.AppMenuBlocker; import org.chromium.chrome.browser.appmenu.AppMenuCoordinator; import org.chromium.chrome.browser.appmenu.AppMenuCoordinatorFactory; +import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel; +import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.lifecycle.Destroyable; import org.chromium.chrome.browser.lifecycle.InflationObserver; +import org.chromium.chrome.browser.vr.VrModeObserver; +import org.chromium.chrome.browser.vr.VrModuleProvider; +import org.chromium.chrome.browser.widget.findinpage.FindToolbarManager; +import org.chromium.chrome.browser.widget.findinpage.FindToolbarObserver; import org.chromium.ui.base.DeviceFormFactor; /** @@ -31,6 +41,19 @@ protected @Nullable AppMenuCoordinator mAppMenuCoordinator; private final MenuOrKeyboardActionController mMenuOrKeyboardActionController; + protected @Nullable FindToolbarManager mFindToolbarManager; + private @Nullable FindToolbarObserver mFindToolbarObserver; + + private Callback<LayoutManager> mLayoutManagerSupplierCallback; + private OverlayPanelManager mOverlayPanelManager; + private OverlayPanelManager.OverlayPanelManagerObserver mOverlayPanelManagerObserver; + + private Callback<OverviewModeBehavior> mOverviewModeBehaviorSupplierCallback; + private OverviewModeBehavior mOverviewModeBehavior; + private OverviewModeBehavior.OverviewModeObserver mOverviewModeObserver; + + private VrModeObserver mVrModeObserver; + /** * Create a new {@link RootUiCoordinator} for the given activity. * @param activity The containing {@link ChromeActivity}. TODO(https://crbug.com/931496): @@ -39,19 +62,42 @@ public RootUiCoordinator(ChromeActivity activity) { mActivity = activity; mActivity.getLifecycleDispatcher().register(this); + mMenuOrKeyboardActionController = mActivity.getMenuOrKeyboardActionController(); mMenuOrKeyboardActionController.registerMenuOrKeyboardActionHandler(this); + + initLayoutManagerSupplierObserver(); + initOverviewModeSupplierObserver(); } @Override public void destroy() { mMenuOrKeyboardActionController.unregisterMenuOrKeyboardActionHandler(this); - mActivity = null; + + mActivity.getLayoutManagerSupplier().removeObserver(mLayoutManagerSupplierCallback); + if (mOverlayPanelManager != null) { + mOverlayPanelManager.removeObserver(mOverlayPanelManagerObserver); + } + + if (mActivity.getOverviewModeBehaviorSupplier() != null) { + mActivity.getOverviewModeBehaviorSupplier().removeObserver( + mOverviewModeBehaviorSupplierCallback); + } + if (mOverviewModeBehavior != null) { + mOverviewModeBehavior.removeOverviewModeObserver(mOverviewModeObserver); + } + if (mAppMenuCoordinator != null) { mAppMenuCoordinator.unregisterAppMenuBlocker(this); mAppMenuCoordinator.unregisterAppMenuBlocker(mActivity); mAppMenuCoordinator.destroy(); } + + if (mFindToolbarManager != null) mFindToolbarManager.removeObserver(mFindToolbarObserver); + + if (mVrModeObserver != null) VrModuleProvider.unregisterVrModeObserver(mVrModeObserver); + + mActivity = null; } @Override @@ -59,37 +105,45 @@ @Override public void onPostInflationStartup() { - // TODO(https://crbug.com/931496): Revisit this as part of the broader - // discussion around activity-specific UI customizations. - if (mActivity.supportsAppMenu()) { - mAppMenuCoordinator = AppMenuCoordinatorFactory.createAppMenuCoordinator(mActivity, - mActivity.getLifecycleDispatcher(), mActivity.getToolbarManager(), mActivity, - mActivity.getWindow().getDecorView(), - mActivity.getOverviewModeBehaviorSupplier()); - mActivity.getToolbarManager().onAppMenuInitialized( - mAppMenuCoordinator.getAppMenuHandler(), - mAppMenuCoordinator.getAppMenuPropertiesDelegate()); - mAppMenuCoordinator.registerAppMenuBlocker(this); - mAppMenuCoordinator.registerAppMenuBlocker(mActivity); - } else if (mActivity.getToolbarManager() != null) { - mActivity.getToolbarManager().getToolbar().disableMenuButton(); - } + initAppMenu(); + initFindToolbarManager(); + + mVrModeObserver = new VrModeObserver() { + @Override + public void onEnterVr() { + mFindToolbarManager.hideToolbar(); + } + + @Override + public void onExitVr() {} + }; + VrModuleProvider.registerVrModeObserver(mVrModeObserver); } + // MenuOrKeyboardActionHandler implementation + @Override public boolean onMenuOrKeyboardAction(int id, boolean fromMenu) { if (id == R.id.show_menu && mAppMenuCoordinator != null) { mAppMenuCoordinator.showAppMenuForKeyboardEvent(); return true; + } else if (id == R.id.find_in_page_id) { + if (mFindToolbarManager == null) return false; + + mFindToolbarManager.showToolbar(); + + if (fromMenu) { + RecordUserAction.record("MobileMenuFindInPage"); + } else { + RecordUserAction.record("MobileShortcutFindInPage"); + } + return true; } return false; } - @VisibleForTesting - public AppMenuCoordinator getAppMenuCoordinatorForTesting() { - return mAppMenuCoordinator; - } + // AppMenuBlocker implementation @Override public boolean canShowAppMenu() { @@ -108,12 +162,132 @@ } // Do not show the menu if we are in find in page view. - if (mActivity.getFindToolbarManager() != null - && mActivity.getFindToolbarManager().isShowing() + if (mFindToolbarManager != null && mFindToolbarManager.isShowing() && !DeviceFormFactor.isNonMultiDisplayContextOnTablet(mActivity)) { return false; } return true; } + + // Private class methods + + private void initLayoutManagerSupplierObserver() { + mLayoutManagerSupplierCallback = layoutManager -> { + if (mOverlayPanelManager != null) { + mOverlayPanelManager.removeObserver(mOverlayPanelManagerObserver); + } + mOverlayPanelManager = layoutManager.getOverlayPanelManager(); + + if (mOverlayPanelManagerObserver == null) { + mOverlayPanelManagerObserver = + new OverlayPanelManager.OverlayPanelManagerObserver() { + @Override + public void onOverlayPanelShown() { + if (mFindToolbarManager != null) { + mFindToolbarManager.hideToolbar(false); + } + } + + @Override + public void onOverlayPanelHidden() {} + }; + } + + mOverlayPanelManager.addObserver(mOverlayPanelManagerObserver); + }; + mActivity.getLayoutManagerSupplier().addObserver(mLayoutManagerSupplierCallback); + } + + private void initOverviewModeSupplierObserver() { + if (mActivity.getOverviewModeBehaviorSupplier() != null) { + mOverviewModeBehaviorSupplierCallback = overviewModeBehavior -> { + if (mOverviewModeBehavior != null) { + mOverviewModeBehavior.removeOverviewModeObserver(mOverviewModeObserver); + } + + mOverviewModeBehavior = overviewModeBehavior; + + if (mOverviewModeObserver == null) { + mOverviewModeObserver = new OverviewModeBehavior.OverviewModeObserver() { + @Override + public void onOverviewModeStartedShowing(boolean showToolbar) { + if (mFindToolbarManager != null) mFindToolbarManager.hideToolbar(); + } + + @Override + public void onOverviewModeFinishedShowing() {} + + @Override + public void onOverviewModeStartedHiding( + boolean showToolbar, boolean delayAnimation) {} + + @Override + public void onOverviewModeFinishedHiding() {} + }; + } + mOverviewModeBehavior.addOverviewModeObserver(mOverviewModeObserver); + }; + mActivity.getOverviewModeBehaviorSupplier().addObserver( + mOverviewModeBehaviorSupplierCallback); + } + } + + private void initAppMenu() { + // TODO(https://crbug.com/931496): Revisit this as part of the broader + // discussion around activity-specific UI customizations. + if (mActivity.supportsAppMenu()) { + mAppMenuCoordinator = AppMenuCoordinatorFactory.createAppMenuCoordinator(mActivity, + mActivity.getLifecycleDispatcher(), mActivity.getToolbarManager(), mActivity, + mActivity.getWindow().getDecorView(), + mActivity.getOverviewModeBehaviorSupplier()); + mActivity.getToolbarManager().onAppMenuInitialized( + mAppMenuCoordinator.getAppMenuHandler(), + mAppMenuCoordinator.getAppMenuPropertiesDelegate()); + mAppMenuCoordinator.registerAppMenuBlocker(this); + mAppMenuCoordinator.registerAppMenuBlocker(mActivity); + } else if (mActivity.getToolbarManager() != null) { + mActivity.getToolbarManager().getToolbar().disableMenuButton(); + } + } + + private void initFindToolbarManager() { + if (!mActivity.supportsFindInPage()) return; + + int stubId = R.id.find_toolbar_stub; + if (DeviceFormFactor.isNonMultiDisplayContextOnTablet(mActivity)) { + stubId = R.id.find_toolbar_tablet_stub; + } + mFindToolbarManager = new FindToolbarManager(mActivity.findViewById(stubId), + mActivity.getTabModelSelector(), mActivity.getWindowAndroid(), + mActivity.getToolbarManager().getActionModeControllerCallback()); + + mFindToolbarObserver = new FindToolbarObserver() { + @Override + public void onFindToolbarShown() { + if (mActivity.getContextualSearchManager() != null) { + mActivity.getContextualSearchManager().hideContextualSearch( + OverlayPanel.StateChangeReason.UNKNOWN); + } + if (mActivity.getEphemeralTabPanel() != null) { + mActivity.getEphemeralTabPanel().closePanel( + OverlayPanel.StateChangeReason.UNKNOWN, true); + } + } + + @Override + public void onFindToolbarHidden() {} + }; + + mFindToolbarManager.addObserver(mFindToolbarObserver); + + mActivity.getToolbarManager().setFindToolbarManager(mFindToolbarManager); + } + + // Testing methods + + @VisibleForTesting + public AppMenuCoordinator getAppMenuCoordinatorForTesting() { + return mAppMenuCoordinator; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java index f95f5ac5..09a30313 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java
@@ -317,8 +317,8 @@ (ViewGroup) findViewById(android.R.id.content), (ToolbarControlContainer) findViewById(R.id.control_container)); getToolbarManager().initializeWithNative(getTabModelSelector(), - getFullscreenManager().getBrowserVisibilityDelegate(), getFindToolbarManager(), - null, layoutDriver, null, null, null, view -> onToolbarCloseButtonClicked()); + getFullscreenManager().getBrowserVisibilityDelegate(), null, layoutDriver, null, + null, null, view -> onToolbarCloseButtonClicked()); getToolbarManager().setShowTitle(true); getToolbarManager().setCloseButtonDrawable(null); // Hides close button.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webauth/AuthenticatorImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/webauth/AuthenticatorImpl.java index 45d9479..19187e7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webauth/AuthenticatorImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webauth/AuthenticatorImpl.java
@@ -26,7 +26,7 @@ /** * Android implementation of the authenticator.mojom interface. */ -public class AuthenticatorImpl extends EmptyHandlerResponseCallback implements Authenticator { +public class AuthenticatorImpl extends HandlerResponseCallback implements Authenticator { private final RenderFrameHost mRenderFrameHost; private final WebContents mWebContents;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webauth/EmptyHandlerResponseCallback.java b/chrome/android/java/src/org/chromium/chrome/browser/webauth/EmptyHandlerResponseCallback.java index 9c53c5ef..a657b05 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webauth/EmptyHandlerResponseCallback.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webauth/EmptyHandlerResponseCallback.java
@@ -11,7 +11,7 @@ * Empty HandlerResponseCallback Temporarily used for landing CLs for * IsUserVerifyingPlatformAuthenticatorAvailable error response. */ -public class EmptyHandlerResponseCallback implements HandlerResponseCallback { +public class EmptyHandlerResponseCallback extends HandlerResponseCallback { @Override public void onRegisterResponse(Integer status, MakeCredentialAuthenticatorResponse response){};
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webauth/HandlerResponseCallback.java b/chrome/android/java/src/org/chromium/chrome/browser/webauth/HandlerResponseCallback.java index 35c67b06..f90efbe6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webauth/HandlerResponseCallback.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webauth/HandlerResponseCallback.java
@@ -10,27 +10,27 @@ /** * Callback for receiving responses from an internal handler. */ -public interface HandlerResponseCallback { +public class HandlerResponseCallback { /** - * Interface that returns the response from a request to register a + * Callback for handling the response from a request to register a * credential with an authenticator. */ - void onRegisterResponse(Integer status, MakeCredentialAuthenticatorResponse response); + public void onRegisterResponse(Integer status, MakeCredentialAuthenticatorResponse response){}; /** - * Interface that returns the response from a request to use a credential + * Callback for handling the response from a request to use a credential * to produce a signed assertion. */ - void onSignResponse(Integer status, GetAssertionAuthenticatorResponse response); + public void onSignResponse(Integer status, GetAssertionAuthenticatorResponse response){}; /** - * Interface that returns the response from a request to call + * Callback for handling response from a request to call * isUserVerifyingPlatformAuthenticatorAvailable. */ - void onIsUserVerifyingPlatformAuthenticatorAvailableResponse(boolean isUVPAA); + public void onIsUserVerifyingPlatformAuthenticatorAvailableResponse(boolean isUVPAA){}; /** - * Interface that returns any errors from either register or sign requests. + * Callback for handling any errors from either register or sign requests. */ - void onError(Integer status); + public void onError(Integer status){}; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/findinpage/FindToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/findinpage/FindToolbarManager.java index 2311864..582c6dd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/findinpage/FindToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/findinpage/FindToolbarManager.java
@@ -9,26 +9,33 @@ import android.view.ViewStub; import org.chromium.base.ObserverList; -import org.chromium.chrome.R; -import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; +import org.chromium.ui.base.WindowAndroid; /** * Manages the interactions with the find toolbar. */ public class FindToolbarManager { private FindToolbar mFindToolbar; - private final ChromeActivity mActivity; + private final ViewStub mFindToolbarStub; + private final TabModelSelector mTabModelSelector; + private final WindowAndroid mWindowAndroid; private final ActionMode.Callback mCallback; private final ObserverList<FindToolbarObserver> mObservers; /** * Creates an instance of a {@link FindToolbarManager}. - * @param activity The ChromeActivity that contains the {@link FindToolbar}. + * @param findToolbarStub The {@link ViewStub} where for the find toolbar. + * @param tabModelSelector The {@link TabModelSelector} for the containing activity. + * @param windowAndroid The {@link WindowAndroid} for the containing activity. * @param callback The ActionMode.Callback that will be used when selection occurs on the * {@link FindToolbar}. */ - public FindToolbarManager(ChromeActivity activity, ActionMode.Callback callback) { - mActivity = activity; + public FindToolbarManager(ViewStub findToolbarStub, TabModelSelector tabModelSelector, + WindowAndroid windowAndroid, ActionMode.Callback callback) { + mFindToolbarStub = findToolbarStub; + mTabModelSelector = tabModelSelector; + mWindowAndroid = windowAndroid; mCallback = callback; mObservers = new ObserverList<FindToolbarObserver>(); } @@ -62,13 +69,9 @@ */ public void showToolbar() { if (mFindToolbar == null) { - int stubId = R.id.find_toolbar_stub; - if (mActivity.isTablet()) { - stubId = R.id.find_toolbar_tablet_stub; - } - mFindToolbar = (FindToolbar) ((ViewStub) mActivity.findViewById(stubId)).inflate(); - mFindToolbar.setTabModelSelector(mActivity.getTabModelSelector()); - mFindToolbar.setWindowAndroid(mActivity.getWindowAndroid()); + mFindToolbar = (FindToolbar) mFindToolbarStub.inflate(); + mFindToolbar.setTabModelSelector(mTabModelSelector); + mFindToolbar.setWindowAndroid(mWindowAndroid); mFindToolbar.setActionModeCallbackForTextEdit(mCallback); mFindToolbar.setObserver(new FindToolbarObserver() { @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/findinpage/FindToolbarObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/findinpage/FindToolbarObserver.java index a09d6f6..f0c0e1d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/findinpage/FindToolbarObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/findinpage/FindToolbarObserver.java
@@ -7,18 +7,14 @@ /** * Observer for find in page actions. */ -public class FindToolbarObserver { - +public interface FindToolbarObserver { /** * Notified when the find in page toolbar has been shown. */ - public void onFindToolbarShown() { - } + void onFindToolbarShown(); /** * Notified when the find in page toolbar has been hidden. */ - public void onFindToolbarHidden() { - } - + void onFindToolbarHidden(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListToolbar.java index fc5c7c2..117758d1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListToolbar.java
@@ -11,6 +11,7 @@ import android.graphics.drawable.Drawable; import android.support.annotation.CallSuper; import android.support.annotation.StringRes; +import android.support.v4.graphics.drawable.DrawableCompat; import android.support.v4.view.ViewCompat; import android.support.v7.content.res.AppCompatResources; import android.support.v7.widget.Toolbar; @@ -47,6 +48,7 @@ import org.chromium.chrome.browser.widget.displaystyle.UiConfig; import org.chromium.chrome.browser.widget.selection.SelectionDelegate.SelectionObserver; import org.chromium.ui.KeyboardVisibilityDelegate; +import org.chromium.ui.UiUtils; import java.util.List; @@ -98,9 +100,9 @@ private boolean mUpdateStatusBarColor; protected NumberRollView mNumberRollView; - private TintedDrawable mNormalMenuButton; - private TintedDrawable mSelectionMenuButton; - private TintedDrawable mNavigationIconDrawable; + private Drawable mNormalMenuButton; + private Drawable mSelectionMenuButton; + private Drawable mNavigationIconDrawable; private int mNavigationButton; private int mTitleResId; @@ -199,12 +201,12 @@ // TODO(twellington): add the concept of normal & selected tint to apply to all toolbar // buttons. - mNormalMenuButton = TintedDrawable.constructTintedDrawable( - getContext(), R.drawable.ic_more_vert_black_24dp); - mSelectionMenuButton = TintedDrawable.constructTintedDrawable(getContext(), - R.drawable.ic_more_vert_black_24dp, R.color.default_icon_color_inverse); - mNavigationIconDrawable = TintedDrawable.constructTintedDrawable( - getContext(), R.drawable.ic_arrow_back_white_24dp); + mNormalMenuButton = UiUtils.getTintedDrawable( + getContext(), R.drawable.ic_more_vert_24dp, R.color.standard_mode_tint); + mSelectionMenuButton = UiUtils.getTintedDrawable( + getContext(), R.drawable.ic_more_vert_24dp, R.color.default_icon_color_inverse); + mNavigationIconDrawable = UiUtils.getTintedDrawable( + getContext(), R.drawable.ic_arrow_back_white_24dp, R.color.standard_mode_tint); VrModuleProvider.registerVrModeObserver(this); if (VrModuleProvider.getDelegate().isInVr()) onEnterVr(); @@ -217,8 +219,8 @@ // Will not be needed after a tint is applied to all toolbar buttons. MenuItem extraMenuItem = getMenu().findItem(mExtraMenuItemId); if (extraMenuItem != null) { - Drawable iconDrawable = TintedDrawable.constructTintedDrawable( - getContext(), R.drawable.ic_more_vert_black_24dp, R.color.standard_mode_tint); + Drawable iconDrawable = UiUtils.getTintedDrawable( + getContext(), R.drawable.ic_more_vert_24dp, R.color.standard_mode_tint); extraMenuItem.setIcon(iconDrawable); } } @@ -368,11 +370,11 @@ case NAVIGATION_BUTTON_NONE: break; case NAVIGATION_BUTTON_BACK: - mNavigationIconDrawable.setTint(mDarkIconColorList); + DrawableCompat.setTintList(mNavigationIconDrawable, mDarkIconColorList); contentDescriptionId = R.string.accessibility_toolbar_btn_back; break; case NAVIGATION_BUTTON_SELECTION_BACK: - mNavigationIconDrawable.setTint(mLightIconColorList); + DrawableCompat.setTintList(mNavigationIconDrawable, mLightIconColorList); contentDescriptionId = R.string.accessibility_cancel_selection; break; default:
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridgeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridgeTest.java index d79f553..b4d82e3 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridgeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridgeTest.java
@@ -34,7 +34,6 @@ import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.components.offlinepages.DeletePageResult; import org.chromium.components.offlinepages.SavePageResult; -import org.chromium.components.offlinepages.background.UpdateRequestResult; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.test.util.TestThreadUtils; @@ -177,40 +176,6 @@ @Test @MediumTest @RetryOnFailure - public void testGetRequestsInQueue() throws Exception { - String url = "https://www.google.com/"; - String namespace = "custom_tabs"; - savePageLater(url, namespace); - SavePageRequest[] requests = OfflineTestUtil.getRequestsInQueue(); - Assert.assertEquals(1, requests.length); - Assert.assertEquals(namespace, requests[0].getClientId().getNamespace()); - Assert.assertEquals(url, requests[0].getUrl()); - - String url2 = "https://mail.google.com/"; - String namespace2 = "last_n"; - savePageLater(url2, namespace2); - requests = OfflineTestUtil.getRequestsInQueue(); - Assert.assertEquals(2, requests.length); - - HashSet<String> expectedUrls = new HashSet<>(); - expectedUrls.add(url); - expectedUrls.add(url2); - - HashSet<String> expectedNamespaces = new HashSet<>(); - expectedNamespaces.add(namespace); - expectedNamespaces.add(namespace2); - - for (SavePageRequest request : requests) { - Assert.assertTrue(expectedNamespaces.contains(request.getClientId().getNamespace())); - expectedNamespaces.remove(request.getClientId().getNamespace()); - Assert.assertTrue(expectedUrls.contains(request.getUrl())); - expectedUrls.remove(request.getUrl()); - } - } - - @Test - @MediumTest - @RetryOnFailure public void testOfflinePageBridgeDisabledInIncognito() throws Exception { initializeBridgeForProfile(true); Assert.assertEquals(null, mOfflinePageBridge); @@ -218,35 +183,6 @@ @Test @MediumTest - @RetryOnFailure - public void testRemoveRequestsFromQueue() throws Exception { - String url = "https://www.google.com/"; - String namespace = "custom_tabs"; - savePageLater(url, namespace); - - String url2 = "https://mail.google.com/"; - String namespace2 = "last_n"; - savePageLater(url2, namespace2); - - SavePageRequest[] requests = OfflineTestUtil.getRequestsInQueue(); - Assert.assertEquals(2, requests.length); - - List<Long> requestsToRemove = new ArrayList<>(); - requestsToRemove.add(Long.valueOf(requests[1].getRequestId())); - - List<OfflinePageBridge.RequestRemovedResult> removed = - removeRequestsFromQueue(requestsToRemove); - Assert.assertEquals(requests[1].getRequestId(), removed.get(0).getRequestId()); - Assert.assertEquals(UpdateRequestResult.SUCCESS, removed.get(0).getUpdateRequestResult()); - SavePageRequest[] remaining = OfflineTestUtil.getRequestsInQueue(); - Assert.assertEquals(1, remaining.length); - - Assert.assertEquals(requests[0].getRequestId(), remaining[0].getRequestId()); - Assert.assertEquals(requests[0].getUrl(), remaining[0].getUrl()); - } - - @Test - @MediumTest public void testDeletePagesByOfflineIds() throws Exception { // Save 3 pages and record their offline IDs to delete later. Set<String> pageUrls = new HashSet<>(); @@ -559,43 +495,6 @@ return result; } - private void savePageLater(final String url, final String namespace) - throws InterruptedException { - final Semaphore semaphore = new Semaphore(0); - PostTask.runOrPostTask(UiThreadTaskTraits.DEFAULT, () -> { - mOfflinePageBridge.savePageLater(url, namespace, true /* userRequested */, - new OfflinePageOrigin(), new Callback<Integer>() { - @Override - public void onResult(Integer i) { - Assert.assertEquals("SavePageLater did not succeed", Integer.valueOf(0), - i); // 0 is SUCCESS - semaphore.release(); - } - }); - }); - Assert.assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS)); - } - - private List<OfflinePageBridge.RequestRemovedResult> removeRequestsFromQueue( - final List<Long> requestsToRemove) throws InterruptedException { - final AtomicReference<List<OfflinePageBridge.RequestRemovedResult>> ref = - new AtomicReference<>(); - final Semaphore semaphore = new Semaphore(0); - PostTask.runOrPostTask(UiThreadTaskTraits.DEFAULT, () -> { - mOfflinePageBridge.removeRequestsFromQueue( - requestsToRemove, new Callback<List<OfflinePageBridge.RequestRemovedResult>>() { - @Override - public void onResult( - List<OfflinePageBridge.RequestRemovedResult> removedRequests) { - ref.set(removedRequests); - semaphore.release(); - } - }); - }); - Assert.assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS)); - return ref.get(); - } - private LoadUrlParams getLoadUrlParamsForOpeningMhtmlFileOrContent(String url) throws InterruptedException { final AtomicReference<LoadUrlParams> ref = new AtomicReference<>();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentMetricsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentMetricsTest.java index 39ba99ea..07ff494 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentMetricsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentMetricsTest.java
@@ -84,7 +84,7 @@ // Make sure the canMakePayment events were logged correctly. int expectedSample = Event.SHOWN | Event.USER_ABORTED | Event.CAN_MAKE_PAYMENT_TRUE | Event.HAS_ENROLLED_INSTRUMENT_FALSE | Event.REQUEST_METHOD_BASIC_CARD - | Event.REQUEST_METHOD_OTHER; + | Event.REQUEST_METHOD_OTHER | Event.NEEDS_COMPLETION_PAYMENT; Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( "PaymentRequest.Events", expectedSample)); @@ -127,7 +127,8 @@ int expectedSample = Event.SHOWN | Event.PAY_CLICKED | Event.RECEIVED_INSTRUMENT_DETAILS | Event.COMPLETED | Event.CAN_MAKE_PAYMENT_TRUE | Event.HAS_ENROLLED_INSTRUMENT_FALSE | Event.REQUEST_METHOD_BASIC_CARD - | Event.REQUEST_METHOD_OTHER | Event.SELECTED_CREDIT_CARD; + | Event.REQUEST_METHOD_OTHER | Event.SELECTED_CREDIT_CARD + | Event.NEEDS_COMPLETION_PAYMENT; Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( "PaymentRequest.Events", expectedSample)); @@ -250,7 +251,7 @@ // Make sure no canMakePayment events were logged. int expectedSample = Event.SHOWN | Event.USER_ABORTED | Event.REQUEST_METHOD_BASIC_CARD - | Event.REQUEST_METHOD_OTHER; + | Event.REQUEST_METHOD_OTHER | Event.NEEDS_COMPLETION_PAYMENT; Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( "PaymentRequest.Events", expectedSample));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java index 622c53c..64172def 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java
@@ -616,9 +616,11 @@ mPaymentRequestTestRule.expectResultContains( new String[] {"User closed the Payment Request UI."}); - // Make sure the events were logged correctly. + // Make sure the events were logged correctly. Since the added credit card is using the same + // incomplete profile for billing address, NEEDS_COMPLETION_PAYMENT is also set. int expectedSample = Event.SHOWN | Event.USER_ABORTED | Event.HAD_INITIAL_FORM_OF_PAYMENT - | Event.REQUEST_SHIPPING | Event.REQUEST_METHOD_BASIC_CARD; + | Event.REQUEST_SHIPPING | Event.REQUEST_METHOD_BASIC_CARD + | Event.NEEDS_COMPLETION_PAYMENT | Event.NEEDS_COMPLETION_SHIPPING; Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( "PaymentRequest.Events", expectedSample)); @@ -652,7 +654,8 @@ // Make sure the events were logged correctly. int expectedSample = Event.SHOWN | Event.USER_ABORTED | Event.HAD_INITIAL_FORM_OF_PAYMENT - | Event.REQUEST_SHIPPING | Event.REQUEST_METHOD_BASIC_CARD; + | Event.REQUEST_SHIPPING | Event.REQUEST_METHOD_BASIC_CARD + | Event.NEEDS_COMPLETION_PAYMENT; Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( "PaymentRequest.Events", expectedSample)); @@ -687,7 +690,7 @@ // Make sure the events were logged correctly. int expectedSample = Event.SHOWN | Event.USER_ABORTED | Event.REQUEST_SHIPPING - | Event.REQUEST_METHOD_BASIC_CARD; + | Event.REQUEST_METHOD_BASIC_CARD | Event.NEEDS_COMPLETION_PAYMENT; Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( "PaymentRequest.Events", expectedSample)); @@ -720,7 +723,7 @@ // Make sure the events were logged correctly. int expectedSample = Event.SHOWN | Event.USER_ABORTED | Event.REQUEST_SHIPPING - | Event.REQUEST_METHOD_BASIC_CARD; + | Event.REQUEST_METHOD_BASIC_CARD | Event.NEEDS_COMPLETION_PAYMENT; Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( "PaymentRequest.Events", expectedSample)); @@ -753,7 +756,8 @@ // Make sure the events were logged correctly. int expectedSample = Event.SHOWN | Event.USER_ABORTED | Event.REQUEST_SHIPPING - | Event.REQUEST_METHOD_BASIC_CARD | Event.REQUEST_METHOD_OTHER; + | Event.REQUEST_METHOD_BASIC_CARD | Event.REQUEST_METHOD_OTHER + | Event.NEEDS_COMPLETION_PAYMENT; Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( "PaymentRequest.Events", expectedSample)); @@ -818,10 +822,12 @@ mPaymentRequestTestRule.expectResultContains( new String[] {"User closed the Payment Request UI."}); - // Make sure the events were logged correctly. + // Make sure the events were logged correctly. Since the added credit card is using the same + // incomplete profile, NEEDS_COMPLETION_PAYMENT is also set. int expectedSample = Event.SHOWN | Event.USER_ABORTED | Event.HAD_INITIAL_FORM_OF_PAYMENT | Event.REQUEST_SHIPPING | Event.REQUEST_METHOD_BASIC_CARD - | Event.REQUEST_METHOD_OTHER; + | Event.REQUEST_METHOD_OTHER | Event.NEEDS_COMPLETION_PAYMENT + | Event.NEEDS_COMPLETION_SHIPPING; Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( "PaymentRequest.Events", expectedSample)); @@ -960,7 +966,8 @@ // Make sure the events were logged correctly. int expectedSample = Event.SHOWN | Event.USER_ABORTED | Event.REQUEST_SHIPPING - | Event.REQUEST_METHOD_BASIC_CARD | Event.REQUEST_METHOD_OTHER; + | Event.REQUEST_METHOD_BASIC_CARD | Event.REQUEST_METHOD_OTHER + | Event.NEEDS_COMPLETION_PAYMENT; Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( "PaymentRequest.Events", expectedSample));
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/tasks/tabgroup/TabGroupModelFilterUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/tasks/tabgroup/TabGroupModelFilterUnitTest.java index 4705c96..7d862df2 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/tasks/tabgroup/TabGroupModelFilterUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/tasks/tabgroup/TabGroupModelFilterUnitTest.java
@@ -6,6 +6,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; @@ -463,7 +464,7 @@ new ArrayList<>(Arrays.asList(mTab2, mTab3, mTab5, mTab6, mTab1, mTab4)); List<Tab> tabsToMerge = new ArrayList<>(Arrays.asList(mTab1, mTab4)); - mTabGroupModelFilter.mergeListOfTabsToGroup(tabsToMerge, mTab5); + mTabGroupModelFilter.mergeListOfTabsToGroup(tabsToMerge, mTab5, false, false); verify(mTabModel).moveTab(mTab1.getId(), POSITION6 + 1); verify(mTabModel).moveTab(mTab4.getId(), POSITION6 + 1); @@ -479,7 +480,7 @@ List<Tab> expectedTabModel = new ArrayList<>(Arrays.asList(mTab1, mTab4, newTab, mTab2, mTab3, mTab5, mTab6)); - mTabGroupModelFilter.mergeListOfTabsToGroup(tabsToMerge, mTab1); + mTabGroupModelFilter.mergeListOfTabsToGroup(tabsToMerge, mTab1, false, false); verify(mTabModel).moveTab(mTab4.getId(), POSITION1 + 1); verify(mTabModel).moveTab(newTab.getId(), POSITION1 + 2); @@ -495,7 +496,7 @@ List<Tab> expectedTabModel = new ArrayList<>(Arrays.asList(mTab2, mTab3, mTab4, mTab1, newTab, mTab5, mTab6)); - mTabGroupModelFilter.mergeListOfTabsToGroup(tabsToMerge, mTab4); + mTabGroupModelFilter.mergeListOfTabsToGroup(tabsToMerge, mTab4, false, false); verify(mTabModel).moveTab(mTab1.getId(), POSITION4 + 1); verify(mTabModel).moveTab(newTab.getId(), POSITION4 + 1); @@ -551,4 +552,74 @@ verify(mTabGroupModelFilterObserver, never()) .didMoveTabGroup(any(Tab.class), anyInt(), anyInt()); } + + @Test + public void undoGroupedTab_NoUpdateTabModel() { + List<Tab> expectedTabModel = + new ArrayList<>(Arrays.asList(mTab1, mTab2, mTab3, mTab4, mTab5, mTab6)); + + // Simulate we just grouped mTab4 with mTab2 and mTab3 + doReturn(TAB2_ROOT_ID).when(mTab4).getRootId(); + mTabGroupModelFilter.resetFilterState(); + assertThat(mTab4.getRootId(), equalTo(TAB2_ROOT_ID)); + assertThat(mTabGroupModelFilter.indexOf(mTab4), equalTo(1)); + + // Undo the grouped action + mTabGroupModelFilter.undoGroupedTab(mTab4, POSITION4, TAB4_ROOT_ID); + + assertArrayEquals(mTabs.toArray(), expectedTabModel.toArray()); + assertThat(mTab4.getRootId(), equalTo(TAB4_ROOT_ID)); + assertThat(mTabGroupModelFilter.indexOf(mTab4), equalTo(2)); + } + + @Test + public void undoGroupedTab_Forward_UpdateTabModel() { + List<Tab> expectedTabModel = + new ArrayList<>(Arrays.asList(mTab1, mTab2, mTab3, mTab4, mTab5, mTab6)); + + // Simulate we just grouped mTab1 with mTab4 + doReturn(TAB4_ROOT_ID).when(mTab1).getRootId(); + mTabModel.moveTab(mTab1.getId(), POSITION4 + 1); + mTabGroupModelFilter.resetFilterState(); + assertThat(mTab1.getRootId(), equalTo(TAB4_ROOT_ID)); + assertThat(mTabGroupModelFilter.indexOf(mTab1), equalTo(1)); + assertFalse(Arrays.equals(mTabs.toArray(), expectedTabModel.toArray())); + + // Undo the grouped action. + mTabGroupModelFilter.undoGroupedTab(mTab1, POSITION1, TAB1_ROOT_ID); + + assertArrayEquals(mTabs.toArray(), expectedTabModel.toArray()); + assertThat(mTab1.getRootId(), equalTo(TAB1_ROOT_ID)); + assertThat(mTabGroupModelFilter.indexOf(mTab1), equalTo(0)); + } + + @Test + public void undoGroupedTab_Backward_UpdateTabModel() { + List<Tab> expectedTabModel = + new ArrayList<>(Arrays.asList(mTab1, mTab2, mTab3, mTab4, mTab5, mTab6)); + + // Simulate we just grouped mTab4 with mTab1 + doReturn(TAB1_ROOT_ID).when(mTab4).getRootId(); + mTabModel.moveTab(mTab4.getId(), POSITION1 + 1); + mTabGroupModelFilter.resetFilterState(); + assertThat(mTab4.getRootId(), equalTo(TAB1_ROOT_ID)); + assertThat(mTabGroupModelFilter.indexOf(mTab4), equalTo(0)); + assertFalse(Arrays.equals(mTabs.toArray(), expectedTabModel.toArray())); + + // Undo the grouped action. + mTabGroupModelFilter.undoGroupedTab(mTab4, POSITION4, TAB4_ROOT_ID); + + assertArrayEquals(mTabs.toArray(), expectedTabModel.toArray()); + assertThat(mTab4.getRootId(), equalTo(TAB4_ROOT_ID)); + assertThat(mTabGroupModelFilter.indexOf(mTab4), equalTo(2)); + } + + @Test(expected = AssertionError.class) + public void undoGroupedTab_AssertTest() { + // Simulate mTab6 is not in TabModel. + doReturn(5).when(mTabModel).getCount(); + + // Undo the grouped action. + mTabGroupModelFilter.undoGroupedTab(mTab6, POSITION1, TAB1_ROOT_ID); + } }
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index bd362a3..7fc3f33 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-77.0.3836.0_rc-r1-merged.afdo.bz2 \ No newline at end of file +chromeos-chrome-amd64-77.0.3841.0_rc-r1-merged.afdo.bz2 \ No newline at end of file
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/DinoActivity.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/DinoActivity.java index 7d437b60..7b2ba47 100644 --- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/DinoActivity.java +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/DinoActivity.java
@@ -88,6 +88,11 @@ protected void initializeToolbar() {} @Override + public boolean supportsFindInPage() { + return false; + } + + @Override protected ChromeFullscreenManager createFullscreenManager() { return new ChromeFullscreenManager(this, () -> mBrowserControlsOffsetHelper, ChromeFullscreenManager.ControlsPosition.NONE);
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/NoTouchActivity.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/NoTouchActivity.java index 97ac9d9..b19b965 100644 --- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/NoTouchActivity.java +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/NoTouchActivity.java
@@ -205,6 +205,13 @@ @Override protected void initializeToolbar() {} + /** + * @return Whether this activity supports the find in page page + */ + public boolean supportsFindInPage() { + return false; + } + @Override protected ChromeFullscreenManager createFullscreenManager() { return new ChromeFullscreenManager(this,
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 5d787f3..239951c 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -484,12 +484,12 @@ "external_protocol/external_protocol_observer.h", "favicon/chrome_favicon_client.cc", "favicon/chrome_favicon_client.h", - "favicon/favicon_request_handler_factory.cc", - "favicon/favicon_request_handler_factory.h", "favicon/favicon_service_factory.cc", "favicon/favicon_service_factory.h", "favicon/favicon_utils.cc", "favicon/favicon_utils.h", + "favicon/history_ui_favicon_request_handler_factory.cc", + "favicon/history_ui_favicon_request_handler_factory.h", "favicon/large_icon_service_factory.cc", "favicon/large_icon_service_factory.h", "feature_engagement/tracker_factory.cc", @@ -4583,6 +4583,8 @@ "offline_pages/android/downloads/offline_page_share_helper.h", "offline_pages/android/load_termination_listener_impl.cc", "offline_pages/android/load_termination_listener_impl.h", + "offline_pages/android/offline_page_archive_publisher_impl.cc", + "offline_pages/android/offline_page_archive_publisher_impl.h", "offline_pages/android/offline_page_auto_fetcher.cc", "offline_pages/android/offline_page_auto_fetcher.h", "offline_pages/android/offline_page_auto_fetcher_service.cc", @@ -4594,8 +4596,6 @@ "offline_pages/android/offline_page_model_factory.cc", "offline_pages/android/offline_page_origin_utils_android.cc", "offline_pages/android/offline_page_utils_android.cc", - "offline_pages/android/offline_pages_download_manager_bridge.cc", - "offline_pages/android/offline_pages_download_manager_bridge.h", "offline_pages/android/prefetch_background_task_android.cc", "offline_pages/android/prefetch_background_task_android.h", "offline_pages/android/prefetch_background_task_scheduler_android.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 5630d3d..0984de9 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -2479,6 +2479,11 @@ flag_descriptions::kOmniboxNewAnswerLayoutName, flag_descriptions::kOmniboxNewAnswerLayoutDescription, kOsAndroid, FEATURE_VALUE_TYPE(omnibox::kOmniboxNewAnswerLayout)}, + + {"omnibox-on-device-head-suggestions", + flag_descriptions::kOmniboxOnDeviceHeadSuggestionsName, + flag_descriptions::kOmniboxOnDeviceHeadSuggestionsDescription, kOsAndroid, + FEATURE_VALUE_TYPE(omnibox::kOnDeviceHeadProvider)}, #endif // defined(OS_ANDROID) {"omnibox-rich-entity-suggestions", @@ -3315,10 +3320,6 @@ FEATURE_VALUE_TYPE(app_list_features::kEnableAppReinstallZeroState)}, #endif // OS_CHROMEOS - {"enable-bloated-renderer-detection", - flag_descriptions::kEnableBloatedRendererDetectionName, - flag_descriptions::kEnableBloatedRendererDetectionDescription, kOsAll, - FEATURE_VALUE_TYPE(features::kBloatedRendererDetection)}, {"enable-sync-uss-bookmarks", flag_descriptions::kEnableSyncUSSBookmarksName, flag_descriptions::kEnableSyncUSSBookmarksDescription, kOsAll,
diff --git a/chrome/browser/android/favicon_helper.cc b/chrome/browser/android/favicon_helper.cc index 08e017e..dd7c868 100644 --- a/chrome/browser/android/favicon_helper.cc +++ b/chrome/browser/android/favicon_helper.cc
@@ -17,14 +17,14 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "chrome/android/chrome_jni_headers/FaviconHelper_jni.h" -#include "chrome/browser/favicon/favicon_request_handler_factory.h" #include "chrome/browser/favicon/favicon_service_factory.h" +#include "chrome/browser/favicon/history_ui_favicon_request_handler_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_android.h" #include "chrome/browser/sync/session_sync_service_factory.h" -#include "components/favicon/core/favicon_request_handler.h" #include "components/favicon/core/favicon_service.h" #include "components/favicon/core/favicon_util.h" +#include "components/favicon/core/history_ui_favicon_request_handler.h" #include "components/favicon_base/favicon_util.h" #include "components/sync_sessions/open_tabs_ui_delegate.h" #include "components/sync_sessions/session_sync_service.h" @@ -152,12 +152,12 @@ DCHECK(session_sync_service); sync_sessions::OpenTabsUIDelegate* open_tabs = session_sync_service->GetOpenTabsUIDelegate(); - favicon::FaviconRequestHandler* favicon_request_handler = - FaviconRequestHandlerFactory::GetForBrowserContext(profile); + favicon::HistoryUiFaviconRequestHandler* history_ui_favicon_request_handler = + HistoryUiFaviconRequestHandlerFactory::GetForBrowserContext(profile); // Can be null in tests. - if (!favicon_request_handler) + if (!history_ui_favicon_request_handler) return false; - favicon_request_handler->GetRawFaviconForPageURL( + history_ui_favicon_request_handler->GetRawFaviconForPageURL( page_url, static_cast<int>(j_desired_size_in_pixel), base::BindOnce(&OnFaviconBitmapResultAvailable, ScopedJavaGlobalRef<jobject>(j_favicon_image_callback)),
diff --git a/chrome/browser/android/payments/service_worker_payment_app_bridge.cc b/chrome/browser/android/payments/service_worker_payment_app_bridge.cc index fe5752c87..b2149a8 100644 --- a/chrome/browser/android/payments/service_worker_payment_app_bridge.cc +++ b/chrome/browser/android/payments/service_worker_payment_app_bridge.cc
@@ -488,10 +488,12 @@ static void JNI_ServiceWorkerPaymentAppBridge_OnClosingPaymentAppWindow( JNIEnv* env, - const JavaParamRef<jobject>& jweb_contents) { + const JavaParamRef<jobject>& jweb_contents, + jint reason) { content::WebContents* web_contents = content::WebContents::FromJavaWebContents(jweb_contents); content::PaymentAppProvider::GetInstance()->OnClosingOpenedWindow( - web_contents->GetBrowserContext()); + web_contents->GetBrowserContext(), + static_cast<payments::mojom::PaymentEventResponseType>(reason)); }
diff --git a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc index 5fb3f623..1997173 100644 --- a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc +++ b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
@@ -391,14 +391,6 @@ base::DoNothing()); } -void ChromeAutocompleteProviderClient::OnAutocompleteControllerResultReady( - AutocompleteController* controller) { - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY, - content::Source<AutocompleteController>(controller), - content::NotificationService::NoDetails()); -} - // TODO(crbug.com/46623): Maintain a map of URL->WebContents for fast look-up. bool ChromeAutocompleteProviderClient::IsTabOpenWithURL( const GURL& url,
diff --git a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.h b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.h index bb354c8f5..0c44f334 100644 --- a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.h +++ b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.h
@@ -72,8 +72,6 @@ const base::string16& term) override; void PrefetchImage(const GURL& url) override; void StartServiceWorker(const GURL& destination_url) override; - void OnAutocompleteControllerResultReady( - AutocompleteController* controller) override; bool IsTabOpenWithURL(const GURL& url, const AutocompleteInput* input) override; bool IsBrowserUpdateAvailable() const override;
diff --git a/chrome/browser/background/background_contents_service.cc b/chrome/browser/background/background_contents_service.cc index 112f87d..d301c74 100644 --- a/chrome/browser/background/background_contents_service.cc +++ b/chrome/browser/background/background_contents_service.cc
@@ -99,37 +99,46 @@ void Click(const base::Optional<int>& button_index, const base::Optional<base::string16>& reply) override { - // http://crbug.com/247790 involves a crash notification balloon being - // clicked while the extension isn't in the TERMINATED state. In that case, - // any of the "reload" methods called below can unload the extension, which - // indirectly destroys *this, invalidating all the member variables, so we - // copy the extension ID before using it. - std::string copied_extension_id = extension_id_; - if (is_hosted_app_) { - // There can be a race here: user clicks the balloon, and simultaneously - // reloads the sad tab for the app. So we check here to be safe before - // loading the background page. - BackgroundContentsService* service = - BackgroundContentsServiceFactory::GetForProfile(profile_); - if (!service->GetAppBackgroundContents(copied_extension_id)) { - service->LoadBackgroundContentsForExtension(profile_, - copied_extension_id); - } - } else if (is_platform_app_) { - apps::AppLoadService::Get(profile_)->RestartApplication( - copied_extension_id); - } else { - extensions::ExtensionSystem::Get(profile_) - ->extension_service() - ->ReloadExtension(copied_extension_id); - } - - CloseBalloon(copied_extension_id, profile_); + // Pass arguments by value as HandleClick() might destroy *this. + HandleClick(is_hosted_app_, is_platform_app_, extension_id_, profile_); + // *this might be destroyed now, do not access any members anymore! } private: ~CrashNotificationDelegate() override {} + // Static to prevent accidental use of members as *this might get destroyed. + static void HandleClick(bool is_hosted_app, + bool is_platform_app, + std::string extension_id, + Profile* profile) { + // http://crbug.com/247790 involves a crash notification balloon being + // clicked while the extension isn't in the TERMINATED state. In that case, + // any of the "reload" methods called below can unload the extension, which + // indirectly destroys the CrashNotificationDelegate, invalidating all its + // member variables. Make sure to pass arguments by value when adding new + // ones to this method. + // TODO(knollr): Write a test for the flow of clicking on an extension + // crashed notification. + if (is_hosted_app) { + // There can be a race here: user clicks the balloon, and simultaneously + // reloads the sad tab for the app. So we check here to be safe before + // loading the background page. + BackgroundContentsService* service = + BackgroundContentsServiceFactory::GetForProfile(profile); + if (!service->GetAppBackgroundContents(extension_id)) + service->LoadBackgroundContentsForExtension(profile, extension_id); + } else if (is_platform_app) { + apps::AppLoadService::Get(profile)->RestartApplication(extension_id); + } else { + extensions::ExtensionSystem::Get(profile) + ->extension_service() + ->ReloadExtension(extension_id); + } + + CloseBalloon(extension_id, profile); + } + Profile* profile_; bool is_hosted_app_; bool is_platform_app_;
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index 828ad687..d7c3ddb 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc
@@ -982,10 +982,6 @@ master_prefs_->suppress_default_browser_prompt_for_version); } -#if defined(OS_WIN) - if (!master_prefs_->welcome_page_on_os_upgrade_enabled) - local_state->SetBoolean(prefs::kWelcomePageOnOSUpgradeEnabled, false); -#endif #endif // !defined(OS_ANDROID) && !defined(OS_CHROMEOS) return service_manager::RESULT_CODE_NORMAL_EXIT; }
diff --git a/chrome/browser/chrome_notification_types.h b/chrome/browser/chrome_notification_types.h index 8681df5..33fe370 100644 --- a/chrome/browser/chrome_notification_types.h +++ b/chrome/browser/chrome_notification_types.h
@@ -180,14 +180,6 @@ // The details are none and the source is a Profile*. NOTIFICATION_PROFILE_URL_REQUEST_CONTEXT_GETTER_INITIALIZED, - // Non-history storage services -------------------------------------------- - - // Autocomplete ------------------------------------------------------------ - - // Sent by the autocomplete controller when done. The source is the - // AutocompleteController, the details not used. - NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY, - // Printing ---------------------------------------------------------------- // Notification from PrintJob that an event occurred. It can be that a page @@ -313,10 +305,6 @@ NOTIFICATION_WALLPAPER_ANIMATION_FINISHED, #endif - // Sent when the FullscreenController changes, confirms, or denies mouse lock. - // The source is the browser's FullscreenController, no details. - NOTIFICATION_MOUSE_LOCK_CHANGED, - // Note:- // Currently only Content and Chrome define and use notifications. // Custom notifications not belonging to Content and Chrome should start
diff --git a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc index 0e856811..b519a0b0 100644 --- a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc +++ b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
@@ -231,6 +231,7 @@ SET_STRING("setSuccessfullyMessage", IDS_WALLPAPER_MANAGER_SET_SUCCESSFULLY_MESSAGE); SET_STRING("defaultWallpaperLabel", IDS_DEFAULT_WALLPAPER_ACCESSIBLE_LABEL); + SET_STRING("backButton", IDS_ACCNAME_BACK); #undef SET_STRING const std::string& app_locale = g_browser_process->GetApplicationLocale();
diff --git a/chrome/browser/chromeos/printing/cups_proxy_service_delegate_impl.cc b/chrome/browser/chromeos/printing/cups_proxy_service_delegate_impl.cc index 9c37432..5ec845c4 100644 --- a/chrome/browser/chromeos/printing/cups_proxy_service_delegate_impl.cc +++ b/chrome/browser/chromeos/printing/cups_proxy_service_delegate_impl.cc
@@ -45,6 +45,11 @@ return printers_manager_->IsPrinterInstalled(printer); } +scoped_refptr<base::SingleThreadTaskRunner> +CupsProxyServiceDelegateImpl::GetIOTaskRunner() { + return base::CreateSingleThreadTaskRunner({content::BrowserThread::IO}); +} + void CupsProxyServiceDelegateImpl::SetupPrinter( const Printer& printer, printing::PrinterSetupCallback cb) {
diff --git a/chrome/browser/chromeos/printing/cups_proxy_service_delegate_impl.h b/chrome/browser/chromeos/printing/cups_proxy_service_delegate_impl.h index bf2d172..8a786a8 100644 --- a/chrome/browser/chromeos/printing/cups_proxy_service_delegate_impl.h +++ b/chrome/browser/chromeos/printing/cups_proxy_service_delegate_impl.h
@@ -14,6 +14,8 @@ #include "chrome/services/cups_proxy/cups_proxy_service_delegate.h" #include "chromeos/printing/printer_configuration.h" +#include "base/task/post_task.h" + class Profile; namespace chromeos { @@ -40,6 +42,9 @@ // Returns whether |printer| is currently installed in CUPS with this config. bool IsPrinterInstalled(const Printer& printer) override; + // Returns an IO-thread task runner. + scoped_refptr<base::SingleThreadTaskRunner> GetIOTaskRunner() override; + // Install |printer| into CUPS. void SetupPrinter(const Printer& printer, printing::PrinterSetupCallback cb) override;
diff --git a/chrome/browser/chromeos/printing/usb_printer_detector.cc b/chrome/browser/chromeos/printing/usb_printer_detector.cc index 0e5de535..5c3a75d4 100644 --- a/chrome/browser/chromeos/printing/usb_printer_detector.cc +++ b/chrome/browser/chromeos/printing/usb_printer_detector.cc
@@ -27,11 +27,13 @@ #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/debug_daemon_client.h" #include "chromeos/printing/ppd_provider.h" +#include "chromeos/printing/usb_printer_id.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/system_connector.h" #include "mojo/public/cpp/bindings/associated_binding.h" #include "services/device/public/mojom/constants.mojom.h" +#include "services/device/public/mojom/usb_device.mojom.h" #include "services/device/public/mojom/usb_manager_client.mojom.h" #include "services/service_manager/public/cpp/connector.h" @@ -128,9 +130,24 @@ GuessEffectiveMakeAndModel(device_info)); entry.ppd_search_data.discovery_type = PrinterSearchData::PrinterDiscoveryType::kUsb; - // TODO(https://crbug.com/895037): Add in command set from IEEE1284 - printers_[device_info.guid] = entry; + // Query printer for an IEEE Device ID. + device::mojom::UsbDevicePtr device_ptr; + device_manager_->GetDevice(device_info.guid, mojo::MakeRequest(&device_ptr), + nullptr /* device_client */); + GetDeviceId(std::move(device_ptr), + base::BindOnce(&UsbPrinterDetectorImpl::OnGetDeviceId, + weak_factory_.GetWeakPtr(), std::move(entry), + device_info.guid)); + } + + void OnGetDeviceId(DetectedPrinter entry, + std::string guid, + UsbPrinterId printer_id) { + entry.ppd_search_data.printer_id = std::move(printer_id); + + // Add detected printer. + printers_[guid] = entry; if (on_printers_found_callback_) { on_printers_found_callback_.Run(GetPrinters()); }
diff --git a/chrome/browser/chromeos/printing/usb_printer_util.cc b/chrome/browser/chromeos/printing/usb_printer_util.cc index fe57a93..e486a02481 100644 --- a/chrome/browser/chromeos/printing/usb_printer_util.cc +++ b/chrome/browser/chromeos/printing/usb_printer_util.cc
@@ -7,10 +7,13 @@ #include <ctype.h> #include <stdint.h> +#include <algorithm> #include <string> +#include <utility> #include <vector> #include "base/big_endian.h" +#include "base/bind_helpers.h" #include "base/hash/md5.h" #include "base/strings/string16.h" #include "base/strings/string_piece.h" @@ -19,7 +22,9 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/grit/generated_resources.h" #include "chromeos/printing/printer_configuration.h" +#include "chromeos/printing/usb_printer_id.h" #include "services/device/public/cpp/usb/usb_utils.h" +#include "services/device/public/mojom/usb_device.mojom.h" #include "services/device/public/mojom/usb_enumeration_options.mojom.h" #include "services/device/public/mojom/usb_manager.mojom.h" #include "ui/base/l10n/l10n_util.h" @@ -41,6 +46,69 @@ // (http://www.usb.org/developers/docs/devclass_docs/IPP.zip). constexpr uint8_t kPrinterIppusbProtocol = 4; +// Configuration for a GET_DEVICE_ID Printer Class-Specific Request. +const int kGetDeviceIdRequest = 0; +const int kDefaultInterface = 0; +const int kDefaultConfiguration = 0; + +// Callback for device.mojom.UsbDevice.ControlTransferIn. +// Expects |data| to hold a newly queried Device ID. +void OnControlTransfer(device::mojom::UsbDevicePtr device_ptr, + GetDeviceIdCallback cb, + device::mojom::UsbTransferStatus status, + const std::vector<uint8_t>& data) { + if (status != device::mojom::UsbTransferStatus::COMPLETED || data.empty()) { + return std::move(cb).Run({}); + } + + // Cleanup device_ptr. + device_ptr->ReleaseInterface(kDefaultInterface, base::DoNothing()); + device_ptr->Close(base::DoNothing()); + + return std::move(cb).Run(UsbPrinterId(data)); +} + +// Callback for device.mojom.UsbDevice.ClaimInterface. +// If interface was claimed successfully, attempts to query printer for a +// Device ID. +void OnClaimInterface(device::mojom::UsbDevicePtr device_ptr, + GetDeviceIdCallback cb, + bool success) { + if (!success) { + return std::move(cb).Run({}); + } + + auto params = device::mojom::UsbControlTransferParams::New(); + params->type = device::mojom::UsbControlTransferType::CLASS; + params->recipient = device::mojom::UsbControlTransferRecipient::INTERFACE; + params->request = kGetDeviceIdRequest; + params->value = kDefaultConfiguration; // default config index + params->index = kDefaultInterface; // default interface index + + // Query for IEEE1284 string. + auto* device = device_ptr.get(); + device->ControlTransferIn( + std::move(params), 255 /* max size */, 2000 /* 2 second timeout */, + base::BindOnce(OnControlTransfer, std::move(device_ptr), std::move(cb))); +} + +// Callback for device.mojom.UsbDevice.Open. +// If device was opened successfully, attempts to claim printer's default +// interface. +void OnDeviceOpen(device::mojom::UsbDevicePtr device_ptr, + GetDeviceIdCallback cb, + device::mojom::UsbOpenDeviceError error) { + if (error != device::mojom::UsbOpenDeviceError::OK || !device_ptr) { + return std::move(cb).Run({}); + } + + // Claim interface. + auto* device = device_ptr.get(); + device->ClaimInterface( + kDefaultInterface, + base::BindOnce(OnClaimInterface, std::move(device_ptr), std::move(cb))); +} + // Escape URI strings the same way cups does it, so we end up with a URI cups // recognizes. Cups hex-encodes '%', ' ', and anything not in the standard // ASCII range. CUPS lets everything else through unchanged. @@ -108,7 +176,7 @@ // possible for that device. So we basically toss every bit of stable // information from the device into an MD5 hash, and then hexify the hash value // as a suffix to "usb-" as the final printer id. -std::string UsbPrinterId(const UsbDeviceInfo& device_info) { +std::string CreateUsbPrinterId(const UsbDeviceInfo& device_info) { // Paranoid checks; in the unlikely event someone messes with the USB device // definition, our (supposedly stable) hashes will change. static_assert(sizeof(device_info.class_code) == 1, "Class size changed"); @@ -258,9 +326,17 @@ printer->set_description(printer->display_name()); printer->set_uri(UsbPrinterUri(device_info)); - printer->set_id(UsbPrinterId(device_info)); + printer->set_id(CreateUsbPrinterId(device_info)); printer->set_supports_ippusb(UsbDeviceSupportsIppusb(device_info)); return printer; } +void GetDeviceId(device::mojom::UsbDevicePtr device_ptr, + GetDeviceIdCallback cb) { + // Open device. + auto* device = device_ptr.get(); + device->Open( + base::BindOnce(OnDeviceOpen, std::move(device_ptr), std::move(cb))); +} + } // namespace chromeos
diff --git a/chrome/browser/chromeos/printing/usb_printer_util.h b/chrome/browser/chromeos/printing/usb_printer_util.h index 76066b5..f05d8ce 100644 --- a/chrome/browser/chromeos/printing/usb_printer_util.h +++ b/chrome/browser/chromeos/printing/usb_printer_util.h
@@ -14,6 +14,7 @@ namespace chromeos { class Printer; +class UsbPrinterId; base::string16 GetManufacturerName( const device::mojom::UsbDeviceInfo& device_info); @@ -33,6 +34,12 @@ std::unique_ptr<Printer> UsbDeviceToPrinter( const device::mojom::UsbDeviceInfo& device_info); +// Expects |device_ptr| to be linked to a Printer-class USB Device. Queries the +// printer for its IEEE 1284 Standard Device ID. +using GetDeviceIdCallback = base::OnceCallback<void(UsbPrinterId)>; +void GetDeviceId(device::mojom::UsbDevicePtr device_ptr, + GetDeviceIdCallback cb); + } // namespace chromeos #endif // CHROME_BROWSER_CHROMEOS_PRINTING_USB_PRINTER_UTIL_H__
diff --git a/chrome/browser/download/download_request_limiter.cc b/chrome/browser/download/download_request_limiter.cc index e22cc6e..1cf321f 100644 --- a/chrome/browser/download/download_request_limiter.cc +++ b/chrome/browser/download/download_request_limiter.cc
@@ -147,11 +147,11 @@ if (navigation_handle->IsRendererInitiated()) { GURL origin = navigation_handle->GetURL().GetOrigin(); // Mark the origin as restricted. If the origin does not exist in - // |restricted_status_map_|, give it a default value of + // |download_status_map_|, give it a default value of // PROMPT_BEFORE_DOWNLOAD and content setting will be checked later once // CanDownloadImpl() is called. if (!origin.is_empty()) - restricted_status_map_.emplace(origin, PROMPT_BEFORE_DOWNLOAD); + download_status_map_.emplace(origin, PROMPT_BEFORE_DOWNLOAD); return; } @@ -290,8 +290,8 @@ DownloadRequestLimiter::DownloadStatus DownloadRequestLimiter::TabDownloadState::GetDownloadStatus( const GURL& request_origin) { - auto it = restricted_status_map_.find(request_origin); - if (it != restricted_status_map_.end()) + auto it = download_status_map_.find(request_origin); + if (it != download_status_map_.end()) return it->second; return ALLOW_ONE_DOWNLOAD; } @@ -415,10 +415,10 @@ origin_ = request_origin; if (!origin_.is_empty()) { - if (status_ == PROMPT_BEFORE_DOWNLOAD || status_ == DOWNLOADS_NOT_ALLOWED) - restricted_status_map_[request_origin] = status_; + if (status_ != ALLOW_ONE_DOWNLOAD) + download_status_map_[request_origin] = status_; else - restricted_status_map_.erase(request_origin); + download_status_map_.erase(request_origin); } if (!web_contents()) @@ -445,8 +445,12 @@ return true; GURL origin = navigation_handle->GetURL().GetOrigin(); - if (navigation_handle->GetPageTransition() & ui::PAGE_TRANSITION_FORWARD_BACK) - return restricted_status_map_.find(origin) != restricted_status_map_.end(); + if (navigation_handle->GetPageTransition() & + ui::PAGE_TRANSITION_FORWARD_BACK) { + auto it = download_status_map_.find(origin); + if (it != download_status_map_.end()) + return it->second != ALLOW_ALL_DOWNLOADS; + } return false; } @@ -581,11 +585,15 @@ setting = content_settings->GetContentSetting( initiator, initiator, CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, std::string()); - // Override the status if content setting is block or always allow. - if (setting == CONTENT_SETTING_BLOCK) + // Override the status if content setting is block. If the content setting + // is always allow, only reset the status if it is |DOWNLOADS_NOT_ALLOWED| + // so unnecessary notifications will not be triggered. + if (setting == CONTENT_SETTING_BLOCK) { status = DOWNLOADS_NOT_ALLOWED; - else if (setting == CONTENT_SETTING_ALLOW) + } else if (setting == CONTENT_SETTING_ALLOW && + status == DOWNLOADS_NOT_ALLOWED) { status = ALLOW_ALL_DOWNLOADS; + } } // Always call SetDownloadStatusAndNotify since we may need to change the
diff --git a/chrome/browser/download/download_request_limiter.h b/chrome/browser/download/download_request_limiter.h index f1a4901..83d3542 100644 --- a/chrome/browser/download/download_request_limiter.h +++ b/chrome/browser/download/download_request_limiter.h
@@ -208,9 +208,9 @@ // callbacks. std::vector<DownloadRequestLimiter::Callback> callbacks_; - // Origins that have restricted download state. + // Origins that have non-default download state. using DownloadStatusMap = std::map<GURL, DownloadStatus>; - DownloadStatusMap restricted_status_map_; + DownloadStatusMap download_status_map_; ScopedObserver<HostContentSettingsMap, content_settings::Observer> observer_;
diff --git a/chrome/browser/download/download_request_limiter_unittest.cc b/chrome/browser/download/download_request_limiter_unittest.cc index 1dcc88e..57b1285 100644 --- a/chrome/browser/download/download_request_limiter_unittest.cc +++ b/chrome/browser/download/download_request_limiter_unittest.cc
@@ -822,7 +822,7 @@ // ALLOW_ONE_DOWNLOAD default status. CanDownload(); ExpectAndResetCounts(1, 0, 0, __LINE__); - EXPECT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS, + EXPECT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD, download_request_limiter_->GetDownloadStatus(web_contents())); CanDownload();
diff --git a/chrome/browser/extensions/api/management/management_apitest.cc b/chrome/browser/extensions/api/management/management_apitest.cc index 851424d..9328e95 100644 --- a/chrome/browser/extensions/api/management/management_apitest.cc +++ b/chrome/browser/extensions/api/management/management_apitest.cc
@@ -68,8 +68,8 @@ DisableExtension(extension_ids_["disabled_app"]); } - // Load an app, and wait for a message from app "management/launch_on_install" - // indicating that the new app has been launched. + // Load an app, and wait for a message that it has been launched. This should + // be sent by the launched app, to ensure the page is fully loaded. void LoadAndWaitForLaunch(const std::string& app_path, std::string* out_app_id) { ExtensionTestMessageListener launched_app("launched app", false);
diff --git a/chrome/browser/extensions/api/omnibox/omnibox_api_browsertest.cc b/chrome/browser/extensions/api/omnibox/omnibox_api_browsertest.cc deleted file mode 100644 index 82c2994..0000000 --- a/chrome/browser/extensions/api/omnibox/omnibox_api_browsertest.cc +++ /dev/null
@@ -1,260 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/strings/string16.h" -#include "base/strings/utf_string_conversions.h" -#include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h" -#include "chrome/browser/extensions/api/omnibox/omnibox_api_testbase.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/search_engines/template_url_service_factory.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/location_bar/location_bar.h" -#include "chrome/test/base/search_test_utils.h" -#include "components/omnibox/browser/autocomplete_controller.h" -#include "components/omnibox/browser/autocomplete_input.h" -#include "components/omnibox/browser/autocomplete_match.h" -#include "components/omnibox/browser/autocomplete_result.h" -#include "components/omnibox/browser/omnibox_view.h" -#include "extensions/test/result_catcher.h" -#include "third_party/metrics_proto/omnibox_event.pb.h" -#include "ui/base/window_open_disposition.h" - -using base::ASCIIToUTF16; -using extensions::ResultCatcher; -using metrics::OmniboxEventProto; - -// http://crbug.com/167158 -IN_PROC_BROWSER_TEST_F(OmniboxApiTest, DISABLED_Basic) { - ASSERT_TRUE(RunExtensionTest("omnibox")) << message_; - - // The results depend on the TemplateURLService being loaded. Make sure it is - // loaded so that the autocomplete results are consistent. - Profile* profile = browser()->profile(); - search_test_utils::WaitForTemplateURLServiceToLoad( - TemplateURLServiceFactory::GetForProfile(profile)); - - AutocompleteController* autocomplete_controller = - GetAutocompleteController(browser()); - - // Test that our extension's keyword is suggested to us when we partially type - // it. - { - AutocompleteInput input(ASCIIToUTF16("keywor"), - metrics::OmniboxEventProto::NTP, - ChromeAutocompleteSchemeClassifier(profile)); - autocomplete_controller->Start(input); - WaitForAutocompleteDone(autocomplete_controller); - EXPECT_TRUE(autocomplete_controller->done()); - - // Now, peek into the controller to see if it has the results we expect. - // First result should be to search for what was typed, second should be to - // enter "extension keyword" mode. - const AutocompleteResult& result = autocomplete_controller->result(); - ASSERT_EQ(2U, result.size()) << AutocompleteResultAsString(result); - AutocompleteMatch match = result.match_at(0); - EXPECT_EQ(AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, match.type); - EXPECT_FALSE(match.deletable); - - match = result.match_at(1); - EXPECT_EQ(ASCIIToUTF16("kw"), match.keyword); - } - - // Test that our extension can send suggestions back to us. - { - AutocompleteInput input(ASCIIToUTF16("kw suggestio"), - metrics::OmniboxEventProto::NTP, - ChromeAutocompleteSchemeClassifier(profile)); - autocomplete_controller->Start(input); - WaitForAutocompleteDone(autocomplete_controller); - EXPECT_TRUE(autocomplete_controller->done()); - - // Now, peek into the controller to see if it has the results we expect. - // First result should be to invoke the keyword with what we typed, 2-4 - // should be to invoke with suggestions from the extension, and the last - // should be to search for what we typed. - const AutocompleteResult& result = autocomplete_controller->result(); - ASSERT_EQ(5U, result.size()) << AutocompleteResultAsString(result); - - EXPECT_EQ(ASCIIToUTF16("kw"), result.match_at(0).keyword); - EXPECT_EQ(ASCIIToUTF16("kw suggestio"), result.match_at(0).fill_into_edit); - EXPECT_EQ(AutocompleteMatchType::SEARCH_OTHER_ENGINE, - result.match_at(0).type); - EXPECT_EQ(AutocompleteProvider::TYPE_KEYWORD, - result.match_at(0).provider->type()); - EXPECT_EQ(ASCIIToUTF16("kw"), result.match_at(1).keyword); - EXPECT_EQ(ASCIIToUTF16("kw suggestion1"), - result.match_at(1).fill_into_edit); - EXPECT_EQ(AutocompleteProvider::TYPE_KEYWORD, - result.match_at(1).provider->type()); - EXPECT_EQ(ASCIIToUTF16("kw"), result.match_at(2).keyword); - EXPECT_EQ(ASCIIToUTF16("kw suggestion2"), - result.match_at(2).fill_into_edit); - EXPECT_EQ(AutocompleteProvider::TYPE_KEYWORD, - result.match_at(2).provider->type()); - EXPECT_EQ(ASCIIToUTF16("kw"), result.match_at(3).keyword); - EXPECT_EQ(ASCIIToUTF16("kw suggestion3"), - result.match_at(3).fill_into_edit); - EXPECT_EQ(AutocompleteProvider::TYPE_KEYWORD, - result.match_at(3).provider->type()); - - base::string16 description = - ASCIIToUTF16("Description with style: <match>, [dim], (url till end)"); - EXPECT_EQ(description, result.match_at(1).contents); - ASSERT_EQ(6u, result.match_at(1).contents_class.size()); - - EXPECT_EQ(0u, - result.match_at(1).contents_class[0].offset); - EXPECT_EQ(ACMatchClassification::NONE, - result.match_at(1).contents_class[0].style); - - EXPECT_EQ(description.find('<'), - result.match_at(1).contents_class[1].offset); - EXPECT_EQ(ACMatchClassification::MATCH, - result.match_at(1).contents_class[1].style); - - EXPECT_EQ(description.find('>') + 1u, - result.match_at(1).contents_class[2].offset); - EXPECT_EQ(ACMatchClassification::NONE, - result.match_at(1).contents_class[2].style); - - EXPECT_EQ(description.find('['), - result.match_at(1).contents_class[3].offset); - EXPECT_EQ(ACMatchClassification::DIM, - result.match_at(1).contents_class[3].style); - - EXPECT_EQ(description.find(']') + 1u, - result.match_at(1).contents_class[4].offset); - EXPECT_EQ(ACMatchClassification::NONE, - result.match_at(1).contents_class[4].style); - - EXPECT_EQ(description.find('('), - result.match_at(1).contents_class[5].offset); - EXPECT_EQ(ACMatchClassification::URL, - result.match_at(1).contents_class[5].style); - - AutocompleteMatch match = result.match_at(4); - EXPECT_EQ(AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, match.type); - EXPECT_EQ(AutocompleteProvider::TYPE_SEARCH, - result.match_at(4).provider->type()); - EXPECT_FALSE(match.deletable); - } - - // Flaky, see http://crbug.com/167158 - /* - { - LocationBar* location_bar = GetLocationBar(browser()); - ResultCatcher catcher; - OmniboxView* omnibox_view = location_bar->GetOmniboxView(); - omnibox_view->OnBeforePossibleChange(); - omnibox_view->SetUserText(ASCIIToUTF16("kw command")); - omnibox_view->OnAfterPossibleChange(true); - location_bar->AcceptInput(); - // This checks that the keyword provider (via javascript) - // gets told to navigate to the string "command". - EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); - } - */ -} - -IN_PROC_BROWSER_TEST_F(OmniboxApiTest, OnInputEntered) { - ASSERT_TRUE(RunExtensionTest("omnibox")) << message_; - Profile* profile = browser()->profile(); - search_test_utils::WaitForTemplateURLServiceToLoad( - TemplateURLServiceFactory::GetForProfile(profile)); - - LocationBar* location_bar = GetLocationBar(browser()); - OmniboxView* omnibox_view = location_bar->GetOmniboxView(); - ResultCatcher catcher; - AutocompleteController* autocomplete_controller = - GetAutocompleteController(browser()); - omnibox_view->OnBeforePossibleChange(); - omnibox_view->SetUserText(ASCIIToUTF16("kw command")); - omnibox_view->OnAfterPossibleChange(true); - - { - AutocompleteInput input(ASCIIToUTF16("kw command"), - metrics::OmniboxEventProto::NTP, - ChromeAutocompleteSchemeClassifier(profile)); - autocomplete_controller->Start(input); - } - omnibox_view->model()->AcceptInput(WindowOpenDisposition::CURRENT_TAB); - WaitForAutocompleteDone(autocomplete_controller); - EXPECT_TRUE(autocomplete_controller->done()); - EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); - - omnibox_view->OnBeforePossibleChange(); - omnibox_view->SetUserText(ASCIIToUTF16("kw newtab")); - omnibox_view->OnAfterPossibleChange(true); - WaitForAutocompleteDone(autocomplete_controller); - EXPECT_TRUE(autocomplete_controller->done()); - - { - AutocompleteInput input(ASCIIToUTF16("kw newtab"), - metrics::OmniboxEventProto::NTP, - ChromeAutocompleteSchemeClassifier(profile)); - autocomplete_controller->Start(input); - } - omnibox_view->model()->AcceptInput(WindowOpenDisposition::NEW_FOREGROUND_TAB); - WaitForAutocompleteDone(autocomplete_controller); - EXPECT_TRUE(autocomplete_controller->done()); - EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); -} - -// Tests that we get suggestions from and send input to the incognito context -// of an incognito split mode extension. -// http://crbug.com/100927 -// Test is flaky: http://crbug.com/101219 -IN_PROC_BROWSER_TEST_F(OmniboxApiTest, DISABLED_IncognitoSplitMode) { - Profile* profile = browser()->profile(); - ResultCatcher catcher_incognito; - catcher_incognito.RestrictToBrowserContext(profile->GetOffTheRecordProfile()); - - ASSERT_TRUE(RunExtensionTestIncognito("omnibox")) << message_; - - // Open an incognito window and wait for the incognito extension process to - // respond. - Browser* incognito_browser = CreateIncognitoBrowser(); - ASSERT_TRUE(catcher_incognito.GetNextResult()) << catcher_incognito.message(); - - // The results depend on the TemplateURLService being loaded. Make sure it is - // loaded so that the autocomplete results are consistent. - search_test_utils::WaitForTemplateURLServiceToLoad( - TemplateURLServiceFactory::GetForProfile(browser()->profile())); - - LocationBar* location_bar = GetLocationBar(incognito_browser); - AutocompleteController* autocomplete_controller = - GetAutocompleteController(incognito_browser); - - // Test that we get the incognito-specific suggestions. - { - AutocompleteInput input(ASCIIToUTF16("kw suggestio"), - metrics::OmniboxEventProto::NTP, - ChromeAutocompleteSchemeClassifier(profile)); - autocomplete_controller->Start(input); - WaitForAutocompleteDone(autocomplete_controller); - EXPECT_TRUE(autocomplete_controller->done()); - - // First result should be to invoke the keyword with what we typed, 2-4 - // should be to invoke with suggestions from the extension, and the last - // should be to search for what we typed. - const AutocompleteResult& result = autocomplete_controller->result(); - ASSERT_EQ(5U, result.size()) << AutocompleteResultAsString(result); - ASSERT_FALSE(result.match_at(0).keyword.empty()); - EXPECT_EQ(ASCIIToUTF16("kw suggestion3 incognito"), - result.match_at(3).fill_into_edit); - } - - // Test that our input is sent to the incognito context. The test will do a - // text comparison and succeed only if "command incognito" is sent to the - // incognito context. - { - ResultCatcher catcher; - AutocompleteInput input(ASCIIToUTF16("kw command incognito"), - metrics::OmniboxEventProto::NTP, - ChromeAutocompleteSchemeClassifier(profile)); - autocomplete_controller->Start(input); - location_bar->AcceptInput(); - EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); - } -}
diff --git a/chrome/browser/extensions/api/omnibox/omnibox_api_interactive_test.cc b/chrome/browser/extensions/api/omnibox/omnibox_api_interactive_test.cc index c45a45c..87a86d9 100644 --- a/chrome/browser/extensions/api/omnibox/omnibox_api_interactive_test.cc +++ b/chrome/browser/extensions/api/omnibox/omnibox_api_interactive_test.cc
@@ -2,21 +2,44 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/format_macros.h" +#include "base/strings/string16.h" +#include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h" -#include "chrome/browser/extensions/api/omnibox/omnibox_api_testbase.h" +#include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/extensions/extension_apitest.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/search_engines/template_url_service_factory.h" +#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" +#include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/location_bar/location_bar.h" #include "chrome/browser/ui/view_ids.h" #include "chrome/test/base/interactive_test_utils.h" #include "chrome/test/base/search_test_utils.h" +#include "chrome/test/base/ui_test_utils.h" +#include "components/omnibox/browser/autocomplete_controller.h" +#include "components/omnibox/browser/autocomplete_input.h" +#include "components/omnibox/browser/autocomplete_match.h" +#include "components/omnibox/browser/autocomplete_result.h" +#include "components/omnibox/browser/omnibox_controller_emitter.h" +#include "components/omnibox/browser/omnibox_popup_model.h" +#include "components/omnibox/browser/omnibox_view.h" +#include "content/public/test/test_utils.h" #include "extensions/test/extension_test_message_listener.h" #include "extensions/test/result_catcher.h" #include "third_party/metrics_proto/omnibox_event.pb.h" +#include "ui/base/window_open_disposition.h" namespace { +using base::ASCIIToUTF16; +using extensions::ResultCatcher; +using metrics::OmniboxEventProto; +using ui_test_utils::WaitForAutocompleteDone; + void InputKeys(Browser* browser, const std::vector<ui::KeyboardCode>& keys) { for (auto key : keys) { // Note that sending key presses can be flaky at times. @@ -25,8 +48,267 @@ } } +LocationBar* GetLocationBar(Browser* browser) { + return browser->window()->GetLocationBar(); +} + +AutocompleteController* GetAutocompleteController(Browser* browser) { + return GetLocationBar(browser) + ->GetOmniboxView() + ->model() + ->autocomplete_controller(); +} + +base::string16 AutocompleteResultAsString(const AutocompleteResult& result) { + std::string output(base::StringPrintf("{%" PRIuS "} ", result.size())); + for (size_t i = 0; i < result.size(); ++i) { + AutocompleteMatch match = result.match_at(i); + std::string provider_name = match.provider->GetName(); + output.append(base::StringPrintf("[\"%s\" by \"%s\"] ", + base::UTF16ToUTF8(match.contents).c_str(), + provider_name.c_str())); + } + return base::UTF8ToUTF16(output); +} + +using OmniboxApiTest = extensions::ExtensionApiTest; + } // namespace +// http://crbug.com/167158 +IN_PROC_BROWSER_TEST_F(OmniboxApiTest, DISABLED_Basic) { + ASSERT_TRUE(RunExtensionTest("omnibox")) << message_; + + // The results depend on the TemplateURLService being loaded. Make sure it is + // loaded so that the autocomplete results are consistent. + Profile* profile = browser()->profile(); + search_test_utils::WaitForTemplateURLServiceToLoad( + TemplateURLServiceFactory::GetForProfile(profile)); + + AutocompleteController* autocomplete_controller = + GetAutocompleteController(browser()); + + // Test that our extension's keyword is suggested to us when we partially type + // it. + { + AutocompleteInput input(ASCIIToUTF16("keywor"), + metrics::OmniboxEventProto::NTP, + ChromeAutocompleteSchemeClassifier(profile)); + autocomplete_controller->Start(input); + WaitForAutocompleteDone(browser()); + EXPECT_TRUE(autocomplete_controller->done()); + + // Now, peek into the controller to see if it has the results we expect. + // First result should be to search for what was typed, second should be to + // enter "extension keyword" mode. + const AutocompleteResult& result = autocomplete_controller->result(); + ASSERT_EQ(2U, result.size()) << AutocompleteResultAsString(result); + AutocompleteMatch match = result.match_at(0); + EXPECT_EQ(AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, match.type); + EXPECT_FALSE(match.deletable); + + match = result.match_at(1); + EXPECT_EQ(ASCIIToUTF16("kw"), match.keyword); + } + + // Test that our extension can send suggestions back to us. + { + AutocompleteInput input(ASCIIToUTF16("kw suggestio"), + metrics::OmniboxEventProto::NTP, + ChromeAutocompleteSchemeClassifier(profile)); + autocomplete_controller->Start(input); + WaitForAutocompleteDone(browser()); + EXPECT_TRUE(autocomplete_controller->done()); + + // Now, peek into the controller to see if it has the results we expect. + // First result should be to invoke the keyword with what we typed, 2-4 + // should be to invoke with suggestions from the extension, and the last + // should be to search for what we typed. + const AutocompleteResult& result = autocomplete_controller->result(); + ASSERT_EQ(5U, result.size()) << AutocompleteResultAsString(result); + + EXPECT_EQ(ASCIIToUTF16("kw"), result.match_at(0).keyword); + EXPECT_EQ(ASCIIToUTF16("kw suggestio"), result.match_at(0).fill_into_edit); + EXPECT_EQ(AutocompleteMatchType::SEARCH_OTHER_ENGINE, + result.match_at(0).type); + EXPECT_EQ(AutocompleteProvider::TYPE_KEYWORD, + result.match_at(0).provider->type()); + EXPECT_EQ(ASCIIToUTF16("kw"), result.match_at(1).keyword); + EXPECT_EQ(ASCIIToUTF16("kw suggestion1"), + result.match_at(1).fill_into_edit); + EXPECT_EQ(AutocompleteProvider::TYPE_KEYWORD, + result.match_at(1).provider->type()); + EXPECT_EQ(ASCIIToUTF16("kw"), result.match_at(2).keyword); + EXPECT_EQ(ASCIIToUTF16("kw suggestion2"), + result.match_at(2).fill_into_edit); + EXPECT_EQ(AutocompleteProvider::TYPE_KEYWORD, + result.match_at(2).provider->type()); + EXPECT_EQ(ASCIIToUTF16("kw"), result.match_at(3).keyword); + EXPECT_EQ(ASCIIToUTF16("kw suggestion3"), + result.match_at(3).fill_into_edit); + EXPECT_EQ(AutocompleteProvider::TYPE_KEYWORD, + result.match_at(3).provider->type()); + + base::string16 description = + ASCIIToUTF16("Description with style: <match>, [dim], (url till end)"); + EXPECT_EQ(description, result.match_at(1).contents); + ASSERT_EQ(6u, result.match_at(1).contents_class.size()); + + EXPECT_EQ(0u, result.match_at(1).contents_class[0].offset); + EXPECT_EQ(ACMatchClassification::NONE, + result.match_at(1).contents_class[0].style); + + EXPECT_EQ(description.find('<'), + result.match_at(1).contents_class[1].offset); + EXPECT_EQ(ACMatchClassification::MATCH, + result.match_at(1).contents_class[1].style); + + EXPECT_EQ(description.find('>') + 1u, + result.match_at(1).contents_class[2].offset); + EXPECT_EQ(ACMatchClassification::NONE, + result.match_at(1).contents_class[2].style); + + EXPECT_EQ(description.find('['), + result.match_at(1).contents_class[3].offset); + EXPECT_EQ(ACMatchClassification::DIM, + result.match_at(1).contents_class[3].style); + + EXPECT_EQ(description.find(']') + 1u, + result.match_at(1).contents_class[4].offset); + EXPECT_EQ(ACMatchClassification::NONE, + result.match_at(1).contents_class[4].style); + + EXPECT_EQ(description.find('('), + result.match_at(1).contents_class[5].offset); + EXPECT_EQ(ACMatchClassification::URL, + result.match_at(1).contents_class[5].style); + + AutocompleteMatch match = result.match_at(4); + EXPECT_EQ(AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, match.type); + EXPECT_EQ(AutocompleteProvider::TYPE_SEARCH, + result.match_at(4).provider->type()); + EXPECT_FALSE(match.deletable); + } + + // Flaky, see http://crbug.com/167158 + /* + { + LocationBar* location_bar = GetLocationBar(browser()); + ResultCatcher catcher; + OmniboxView* omnibox_view = location_bar->GetOmniboxView(); + omnibox_view->OnBeforePossibleChange(); + omnibox_view->SetUserText(ASCIIToUTF16("kw command")); + omnibox_view->OnAfterPossibleChange(true); + location_bar->AcceptInput(); + // This checks that the keyword provider (via javascript) + // gets told to navigate to the string "command". + EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); + } + */ +} + +IN_PROC_BROWSER_TEST_F(OmniboxApiTest, OnInputEntered) { + ASSERT_TRUE(RunExtensionTest("omnibox")) << message_; + Profile* profile = browser()->profile(); + search_test_utils::WaitForTemplateURLServiceToLoad( + TemplateURLServiceFactory::GetForProfile(profile)); + + LocationBar* location_bar = GetLocationBar(browser()); + OmniboxView* omnibox_view = location_bar->GetOmniboxView(); + ResultCatcher catcher; + AutocompleteController* autocomplete_controller = + GetAutocompleteController(browser()); + omnibox_view->OnBeforePossibleChange(); + omnibox_view->SetUserText(ASCIIToUTF16("kw command")); + omnibox_view->OnAfterPossibleChange(true); + + { + AutocompleteInput input(ASCIIToUTF16("kw command"), + metrics::OmniboxEventProto::NTP, + ChromeAutocompleteSchemeClassifier(profile)); + autocomplete_controller->Start(input); + } + omnibox_view->model()->AcceptInput(WindowOpenDisposition::CURRENT_TAB); + WaitForAutocompleteDone(browser()); + EXPECT_TRUE(autocomplete_controller->done()); + EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); + + omnibox_view->OnBeforePossibleChange(); + omnibox_view->SetUserText(ASCIIToUTF16("kw newtab")); + omnibox_view->OnAfterPossibleChange(true); + WaitForAutocompleteDone(browser()); + EXPECT_TRUE(autocomplete_controller->done()); + + { + AutocompleteInput input(ASCIIToUTF16("kw newtab"), + metrics::OmniboxEventProto::NTP, + ChromeAutocompleteSchemeClassifier(profile)); + autocomplete_controller->Start(input); + } + omnibox_view->model()->AcceptInput(WindowOpenDisposition::NEW_FOREGROUND_TAB); + WaitForAutocompleteDone(browser()); + EXPECT_TRUE(autocomplete_controller->done()); + EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); +} + +// Tests that we get suggestions from and send input to the incognito context +// of an incognito split mode extension. +// http://crbug.com/100927 +// Test is flaky: http://crbug.com/101219 +IN_PROC_BROWSER_TEST_F(OmniboxApiTest, DISABLED_IncognitoSplitMode) { + Profile* profile = browser()->profile(); + ResultCatcher catcher_incognito; + catcher_incognito.RestrictToBrowserContext(profile->GetOffTheRecordProfile()); + + ASSERT_TRUE(RunExtensionTestIncognito("omnibox")) << message_; + + // Open an incognito window and wait for the incognito extension process to + // respond. + Browser* incognito_browser = CreateIncognitoBrowser(); + ASSERT_TRUE(catcher_incognito.GetNextResult()) << catcher_incognito.message(); + + // The results depend on the TemplateURLService being loaded. Make sure it is + // loaded so that the autocomplete results are consistent. + search_test_utils::WaitForTemplateURLServiceToLoad( + TemplateURLServiceFactory::GetForProfile(browser()->profile())); + + LocationBar* location_bar = GetLocationBar(incognito_browser); + AutocompleteController* autocomplete_controller = + GetAutocompleteController(incognito_browser); + + // Test that we get the incognito-specific suggestions. + { + AutocompleteInput input(ASCIIToUTF16("kw suggestio"), + metrics::OmniboxEventProto::NTP, + ChromeAutocompleteSchemeClassifier(profile)); + autocomplete_controller->Start(input); + WaitForAutocompleteDone(browser()); + EXPECT_TRUE(autocomplete_controller->done()); + + // First result should be to invoke the keyword with what we typed, 2-4 + // should be to invoke with suggestions from the extension, and the last + // should be to search for what we typed. + const AutocompleteResult& result = autocomplete_controller->result(); + ASSERT_EQ(5U, result.size()) << AutocompleteResultAsString(result); + ASSERT_FALSE(result.match_at(0).keyword.empty()); + EXPECT_EQ(ASCIIToUTF16("kw suggestion3 incognito"), + result.match_at(3).fill_into_edit); + } + + // Test that our input is sent to the incognito context. The test will do a + // text comparison and succeed only if "command incognito" is sent to the + // incognito context. + { + ResultCatcher catcher; + AutocompleteInput input(ASCIIToUTF16("kw command incognito"), + metrics::OmniboxEventProto::NTP, + ChromeAutocompleteSchemeClassifier(profile)); + autocomplete_controller->Start(input); + location_bar->AcceptInput(); + EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); + } +} + // Tests that the autocomplete popup doesn't reopen after accepting input for // a given query. // http://crbug.com/88552 @@ -49,7 +331,7 @@ omnibox_view->OnBeforePossibleChange(); omnibox_view->SetUserText(base::ASCIIToUTF16("kw comman")); omnibox_view->OnAfterPossibleChange(true); - WaitForAutocompleteDone(autocomplete_controller); + WaitForAutocompleteDone(browser()); EXPECT_TRUE(autocomplete_controller->done()); EXPECT_TRUE(popup_model->IsOpen()); @@ -66,7 +348,7 @@ ChromeAutocompleteSchemeClassifier(profile)); autocomplete_controller->Start(input); location_bar->AcceptInput(); - WaitForAutocompleteDone(autocomplete_controller); + WaitForAutocompleteDone(browser()); EXPECT_TRUE(autocomplete_controller->done()); // This checks that the keyword provider (via javascript) // gets told to navigate to the string "command". @@ -100,7 +382,7 @@ // Input a keyword query and wait for suggestions from the extension. InputKeys(browser(), {ui::VKEY_K, ui::VKEY_W, ui::VKEY_SPACE, ui::VKEY_D}); - WaitForAutocompleteDone(autocomplete_controller); + WaitForAutocompleteDone(browser()); EXPECT_TRUE(autocomplete_controller->done()); // Peek into the controller to see if it has the results we expect. @@ -172,7 +454,7 @@ // Input a keyword query and wait for suggestions from the extension. InputKeys(browser(), {ui::VKEY_K, ui::VKEY_W, ui::VKEY_SPACE, ui::VKEY_D}); - WaitForAutocompleteDone(autocomplete_controller); + WaitForAutocompleteDone(browser()); EXPECT_TRUE(autocomplete_controller->done()); // Peek into the controller to see if it has the results we expect. @@ -209,7 +491,7 @@ InputKeys(browser(), {ui::VKEY_K, ui::VKEY_W, ui::VKEY_SPACE, ui::VKEY_BACK, ui::VKEY_D}); - WaitForAutocompleteDone(autocomplete_controller); + WaitForAutocompleteDone(browser()); EXPECT_TRUE(autocomplete_controller->done()); // Peek into the controller to see if it has the results we expect. Since
diff --git a/chrome/browser/extensions/api/omnibox/omnibox_api_testbase.h b/chrome/browser/extensions/api/omnibox/omnibox_api_testbase.h deleted file mode 100644 index 8d0f684..0000000 --- a/chrome/browser/extensions/api/omnibox/omnibox_api_testbase.h +++ /dev/null
@@ -1,62 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_EXTENSIONS_API_OMNIBOX_OMNIBOX_API_TESTBASE_H_ -#define CHROME_BROWSER_EXTENSIONS_API_OMNIBOX_OMNIBOX_API_TESTBASE_H_ - -#include <stddef.h> - -#include "base/format_macros.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/extensions/extension_apitest.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/location_bar/location_bar.h" -#include "components/omnibox/browser/autocomplete_match.h" -#include "components/omnibox/browser/autocomplete_result.h" -#include "components/omnibox/browser/omnibox_popup_model.h" -#include "components/omnibox/browser/omnibox_view.h" -#include "content/public/test/test_utils.h" - -class AutocompleteController; - -class OmniboxApiTest : public extensions::ExtensionApiTest { - protected: - LocationBar* GetLocationBar(Browser* browser) const { - return browser->window()->GetLocationBar(); - } - - AutocompleteController* GetAutocompleteController(Browser* browser) const { - return GetLocationBar(browser)->GetOmniboxView()->model()->popup_model()-> - autocomplete_controller(); - } - - // TODO(phajdan.jr): Get rid of this wait-in-a-loop pattern. - void WaitForAutocompleteDone(AutocompleteController* controller) { - while (!controller->done()) { - content::WindowedNotificationObserver ready_observer( - chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY, - content::Source<AutocompleteController>(controller)); - ready_observer.Wait(); - } - } - - static base::string16 AutocompleteResultAsString( - const AutocompleteResult& result) { - std::string output(base::StringPrintf("{%" PRIuS "} ", result.size())); - for (size_t i = 0; i < result.size(); ++i) { - AutocompleteMatch match = result.match_at(i); - std::string provider_name = match.provider->GetName(); - output.append( - base::StringPrintf("[\"%s\" by \"%s\"] ", - base::UTF16ToUTF8(match.contents).c_str(), - provider_name.c_str())); - } - return base::UTF8ToUTF16(output); - } -}; - -#endif // CHROME_BROWSER_EXTENSIONS_API_OMNIBOX_OMNIBOX_API_TESTBASE_H_
diff --git a/chrome/browser/extensions/api/web_request/web_request_apitest.cc b/chrome/browser/extensions/api/web_request/web_request_apitest.cc index e411538..3c5f8c1 100644 --- a/chrome/browser/extensions/api/web_request/web_request_apitest.cc +++ b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
@@ -253,6 +253,10 @@ test_dir.WriteFile(FILE_PATH_LITERAL("background.js"), R"( chrome.webRequest.onBeforeSendHeaders.addListener(function(details) { details.requestHeaders.push({name: 'foo', value: 'bar'}); + details.requestHeaders.push({ + name: 'frameId', + value: details.frameId.toString() + }); return {requestHeaders: details.requestHeaders}; }, {urls: ['*://*/echoheader*']}, ['blocking', 'requestHeaders']); @@ -2546,21 +2550,47 @@ // response for the navigation preload request, and respond with it to create // the page. GURL url = embedded_test_server()->GetURL( - "/echoheader?foo&service-worker-navigation-preload"); + "/echoheader?foo&frameId&service-worker-navigation-preload"); ui_test_utils::NavigateToURL(browser(), url); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + // Since the request was to "/echoheader", the response describes the request // headers. // - // The extension is expected to add a "foo: bar" header to the request - // before it goes to network. Verify that it did. + // The expectation is "bar\n0\ntrue" because... // - // The browser adds a "service-worker-navigation-preload: true" header for - // navigation preload requests, so also sanity check that header to prove - // that this test is really testing the navigation preload request. - EXPECT_EQ("bar\ntrue", - EvalJs(browser()->tab_strip_model()->GetActiveWebContents(), - "document.body.textContent;")); + // 1) The extension is expected to add a "foo: bar" header to the request + // before it goes to network. + // 2) The extension is similarly expected to add a "frameId: {id}" header, + // where {id} is details.frameId. This id is 0 for the main frame. + // 3) The browser adds a "service-worker-navigation-preload: true" header for + // navigation preload requests, so also sanity check that header to prove + // that this test is really testing the navigation preload request. + EXPECT_EQ("bar\n0\ntrue", EvalJs(web_contents, "document.body.textContent;")); + + // Repeat the test from an iframe, to test that details.frameId is populated + // correctly. + const char kAddIframe[] = R"( + (async () => { + const iframe = document.createElement('iframe'); + await new Promise(resolve => { + iframe.src = $1; + iframe.onload = resolve; + document.body.appendChild(iframe); + }); + const result = iframe.contentWindow.document.body.textContent; + + // Expect "bar\n{frameId}\ntrue" where {frameId} is a positive integer. + const split = result.split('\n'); + if (split[0] == 'bar' && parseInt(split[1]) > 0 && split[2] == 'true') + return 'ok'; + return 'bad result: ' + result; + })(); + )"; + + EXPECT_EQ("ok", EvalJs(web_contents, content::JsReplace(kAddIframe, url))); } // Ensure we don't strip off initiator incorrectly in web request events when
diff --git a/chrome/browser/extensions/bookmark_app_extension_util.cc b/chrome/browser/extensions/bookmark_app_extension_util.cc index 1d92612..6968b5b 100644 --- a/chrome/browser/extensions/bookmark_app_extension_util.cc +++ b/chrome/browser/extensions/bookmark_app_extension_util.cc
@@ -86,9 +86,9 @@ DCHECK(CanBookmarkAppBePinnedToShelf()); #if defined(OS_CHROMEOS) // ChromeLauncherController does not exist in unit tests. - if (ChromeLauncherController::instance()) { - ChromeLauncherController::instance()->shelf_model()->PinAppWithID( - extension->id()); + if (auto* controller = ChromeLauncherController::instance()) { + controller->PinAppWithID(extension->id()); + controller->UpdateV1AppState(extension->id()); } #endif // defined(OS_CHROMEOS) }
diff --git a/chrome/browser/favicon/favicon_request_handler_factory.h b/chrome/browser/favicon/favicon_request_handler_factory.h deleted file mode 100644 index 9690ab9..0000000 --- a/chrome/browser/favicon/favicon_request_handler_factory.h +++ /dev/null
@@ -1,46 +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 CHROME_BROWSER_FAVICON_FAVICON_REQUEST_HANDLER_FACTORY_H_ -#define CHROME_BROWSER_FAVICON_FAVICON_REQUEST_HANDLER_FACTORY_H_ - -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace base { -template <typename T> -struct DefaultSingletonTraits; -} - -namespace content { -class BrowserContext; -} - -namespace favicon { -class FaviconRequestHandler; -} - -class FaviconRequestHandlerFactory : public BrowserContextKeyedServiceFactory { - public: - static favicon::FaviconRequestHandler* GetForBrowserContext( - content::BrowserContext* context); - - static FaviconRequestHandlerFactory* GetInstance(); - - private: - friend struct base::DefaultSingletonTraits<FaviconRequestHandlerFactory>; - - FaviconRequestHandlerFactory(); - ~FaviconRequestHandlerFactory() override; - - // BrowserContextKeyedServiceFactory: - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; - KeyedService* BuildServiceInstanceFor( - content::BrowserContext* context) const override; - bool ServiceIsNULLWhileTesting() const override; - - DISALLOW_COPY_AND_ASSIGN(FaviconRequestHandlerFactory); -}; - -#endif // CHROME_BROWSER_FAVICON_FAVICON_REQUEST_HANDLER_FACTORY_H_
diff --git a/chrome/browser/favicon/favicon_request_handler_factory.cc b/chrome/browser/favicon/history_ui_favicon_request_handler_factory.cc similarity index 73% rename from chrome/browser/favicon/favicon_request_handler_factory.cc rename to chrome/browser/favicon/history_ui_favicon_request_handler_factory.cc index 27c820c..3212bfe 100644 --- a/chrome/browser/favicon/favicon_request_handler_factory.cc +++ b/chrome/browser/favicon/history_ui_favicon_request_handler_factory.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/favicon/favicon_request_handler_factory.h" +#include "chrome/browser/favicon/history_ui_favicon_request_handler_factory.h" #include "base/memory/singleton.h" #include "base/task/post_task.h" @@ -12,7 +12,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/browser/sync/session_sync_service_factory.h" -#include "components/favicon/core/favicon_request_handler.h" +#include "components/favicon/core/history_ui_favicon_request_handler_impl.h" #include "components/favicon_base/favicon_types.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/sync/driver/sync_service.h" @@ -41,21 +41,22 @@ } // namespace // static -favicon::FaviconRequestHandler* -FaviconRequestHandlerFactory::GetForBrowserContext( +favicon::HistoryUiFaviconRequestHandler* +HistoryUiFaviconRequestHandlerFactory::GetForBrowserContext( content::BrowserContext* context) { - return static_cast<favicon::FaviconRequestHandler*>( + return static_cast<favicon::HistoryUiFaviconRequestHandler*>( GetInstance()->GetServiceForBrowserContext(context, true)); } // static -FaviconRequestHandlerFactory* FaviconRequestHandlerFactory::GetInstance() { - return base::Singleton<FaviconRequestHandlerFactory>::get(); +HistoryUiFaviconRequestHandlerFactory* +HistoryUiFaviconRequestHandlerFactory::GetInstance() { + return base::Singleton<HistoryUiFaviconRequestHandlerFactory>::get(); } -FaviconRequestHandlerFactory::FaviconRequestHandlerFactory() +HistoryUiFaviconRequestHandlerFactory::HistoryUiFaviconRequestHandlerFactory() : BrowserContextKeyedServiceFactory( - "FaviconRequestHandler", + "HistoryUiFaviconRequestHandler", BrowserContextDependencyManager::GetInstance()) { DependsOn(FaviconServiceFactory::GetInstance()); DependsOn(LargeIconServiceFactory::GetInstance()); @@ -63,17 +64,19 @@ DependsOn(ProfileSyncServiceFactory::GetInstance()); } -FaviconRequestHandlerFactory::~FaviconRequestHandlerFactory() {} +HistoryUiFaviconRequestHandlerFactory:: + ~HistoryUiFaviconRequestHandlerFactory() {} -content::BrowserContext* FaviconRequestHandlerFactory::GetBrowserContextToUse( +content::BrowserContext* +HistoryUiFaviconRequestHandlerFactory::GetBrowserContextToUse( content::BrowserContext* context) const { return chrome::GetBrowserContextRedirectedInIncognito(context); } -KeyedService* FaviconRequestHandlerFactory::BuildServiceInstanceFor( +KeyedService* HistoryUiFaviconRequestHandlerFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { Profile* profile = Profile::FromBrowserContext(context); - return new favicon::FaviconRequestHandler( + return new favicon::HistoryUiFaviconRequestHandlerImpl( base::BindRepeating(&GetSyncedFaviconForPageUrl, SessionSyncServiceFactory::GetForProfile(profile)), base::BindRepeating(&CanSendHistoryData, @@ -83,6 +86,6 @@ LargeIconServiceFactory::GetForBrowserContext(context)); } -bool FaviconRequestHandlerFactory::ServiceIsNULLWhileTesting() const { +bool HistoryUiFaviconRequestHandlerFactory::ServiceIsNULLWhileTesting() const { return true; }
diff --git a/chrome/browser/favicon/history_ui_favicon_request_handler_factory.h b/chrome/browser/favicon/history_ui_favicon_request_handler_factory.h new file mode 100644 index 0000000..c9725d8 --- /dev/null +++ b/chrome/browser/favicon/history_ui_favicon_request_handler_factory.h
@@ -0,0 +1,48 @@ +// 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_FAVICON_HISTORY_UI_FAVICON_REQUEST_HANDLER_FACTORY_H_ +#define CHROME_BROWSER_FAVICON_HISTORY_UI_FAVICON_REQUEST_HANDLER_FACTORY_H_ + +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +namespace base { +template <typename T> +struct DefaultSingletonTraits; +} + +namespace content { +class BrowserContext; +} + +namespace favicon { +class HistoryUiFaviconRequestHandler; +} + +class HistoryUiFaviconRequestHandlerFactory + : public BrowserContextKeyedServiceFactory { + public: + static favicon::HistoryUiFaviconRequestHandler* GetForBrowserContext( + content::BrowserContext* context); + + static HistoryUiFaviconRequestHandlerFactory* GetInstance(); + + private: + friend struct base::DefaultSingletonTraits< + HistoryUiFaviconRequestHandlerFactory>; + + HistoryUiFaviconRequestHandlerFactory(); + ~HistoryUiFaviconRequestHandlerFactory() override; + + // BrowserContextKeyedServiceFactory: + content::BrowserContext* GetBrowserContextToUse( + content::BrowserContext* context) const override; + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override; + bool ServiceIsNULLWhileTesting() const override; + + DISALLOW_COPY_AND_ASSIGN(HistoryUiFaviconRequestHandlerFactory); +}; + +#endif // CHROME_BROWSER_FAVICON_HISTORY_UI_FAVICON_REQUEST_HANDLER_FACTORY_H_
diff --git a/chrome/browser/first_run/first_run.cc b/chrome/browser/first_run/first_run.cc index 8cca4b5d..ea97735 100644 --- a/chrome/browser/first_run/first_run.cc +++ b/chrome/browser/first_run/first_run.cc
@@ -336,13 +336,6 @@ install_prefs.GetString( installer::master_preferences::kDistroSuppressDefaultBrowserPromptPref, &out_prefs->suppress_default_browser_prompt_for_version); - - if (install_prefs.GetBool( - installer::master_preferences::kDistroWelcomePageOnOSUpgradeEnabled, - &value) && - !value) { - out_prefs->welcome_page_on_os_upgrade_enabled = false; - } } bool GetFirstRunSentinelFilePath(base::FilePath* path) {
diff --git a/chrome/browser/first_run/first_run.h b/chrome/browser/first_run/first_run.h index dbe046f..56e9d391 100644 --- a/chrome/browser/first_run/first_run.h +++ b/chrome/browser/first_run/first_run.h
@@ -64,7 +64,6 @@ bool make_chrome_default_for_user = false; bool suppress_first_run_default_browser_prompt = false; - bool welcome_page_on_os_upgrade_enabled = true; std::vector<GURL> new_tabs; std::vector<GURL> bookmarks; std::string import_bookmarks_path;
diff --git a/chrome/browser/first_run/first_run_unittest.cc b/chrome/browser/first_run/first_run_unittest.cc index 8b39b934..68a7134 100644 --- a/chrome/browser/first_run/first_run_unittest.cc +++ b/chrome/browser/first_run/first_run_unittest.cc
@@ -53,32 +53,6 @@ EXPECT_TRUE(install_prefs.master_dictionary().empty()); } -TEST_F(FirstRunTest, - SetupMasterPrefsFromInstallPrefs_WelcomePageOnOSUpgradeMissing) { - installer::MasterPreferences install_prefs("{\"distribution\":{}}"); - MasterPrefs out_prefs; - internal::SetupMasterPrefsFromInstallPrefs(install_prefs, &out_prefs); - EXPECT_TRUE(out_prefs.welcome_page_on_os_upgrade_enabled); -} - -TEST_F(FirstRunTest, - SetupMasterPrefsFromInstallPrefs_WelcomePageOnOSUpgradeEnabled) { - installer::MasterPreferences install_prefs( - "{\"distribution\":{\"welcome_page_on_os_upgrade_enabled\": true}}"); - MasterPrefs out_prefs; - internal::SetupMasterPrefsFromInstallPrefs(install_prefs, &out_prefs); - EXPECT_TRUE(out_prefs.welcome_page_on_os_upgrade_enabled); -} - -TEST_F(FirstRunTest, - SetupMasterPrefsFromInstallPrefs_WelcomePageOnOSUpgradeDisabled) { - installer::MasterPreferences install_prefs( - "{\"distribution\":{\"welcome_page_on_os_upgrade_enabled\": false}}"); - MasterPrefs out_prefs; - internal::SetupMasterPrefsFromInstallPrefs(install_prefs, &out_prefs); - EXPECT_FALSE(out_prefs.welcome_page_on_os_upgrade_enabled); -} - // No switches and no sentinel present. This is the standard case for first run. TEST_F(FirstRunTest, DetermineFirstRunState_FirstRun) { internal::FirstRunState result =
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index d98202f..414c88d 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -2485,6 +2485,11 @@ "expiry_milestone": 76 }, { + "name": "omnibox-on-device-head-suggestions", + "owners": [ "cechen", "suggest-2g@google.com" ], + "expiry_milestone": 80 + }, + { "name": "omnibox-pedal-suggestions", "owners": [ "orinj", "chrome-omnibox-team@google.com" ], "expiry_milestone": 76
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 6f81723..0901aa2 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -118,10 +118,6 @@ const char kDrawVerticallyEdgeToEdgeDescription[] = "Draw contents vertically from edge to edge."; -const char kEnableBloatedRendererDetectionName[] = "Bloated renderer detection"; -const char kEnableBloatedRendererDetectionDescription[] = - "Enable bloated renderer detection"; - extern const char kAutofillAlwaysShowServerCardsInSyncTransportName[] = "AlwaysShowServerCardsInSyncTransport"; extern const char kAutofillAlwaysShowServerCardsInSyncTransportDescription[] = @@ -1376,6 +1372,12 @@ "The maximum number of URL matches to show, unless there are no " "replacements."; +const char kOmniboxOnDeviceHeadSuggestionsName[] = + "Omnibox on device head suggestions"; +const char kOmniboxOnDeviceHeadSuggestionsDescription[] = + "Google head non personalized search suggestions provided by a compact on " + "device model"; + const char kOmniboxUIShowPlaceholderWhenCaretShowingName[] = "Omnibox UI Show Placeholder When Caret Showing"; const char kOmniboxUIShowPlaceholderWhenCaretShowingDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 9808db73..7e84c58 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -90,9 +90,6 @@ extern const char kAutomaticPasswordGenerationName[]; extern const char kAutomaticPasswordGenerationDescription[]; -extern const char kEnableBloatedRendererDetectionName[]; -extern const char kEnableBloatedRendererDetectionDescription[]; - extern const char kAutofillAlwaysShowServerCardsInSyncTransportName[]; extern const char kAutofillAlwaysShowServerCardsInSyncTransportDescription[]; @@ -831,6 +828,9 @@ extern const char kOmniboxMaxURLMatchesName[]; extern const char kOmniboxMaxURLMatchesDescription[]; +extern const char kOmniboxOnDeviceHeadSuggestionsName[]; +extern const char kOmniboxOnDeviceHeadSuggestionsDescription[]; + extern const char kOmniboxUIShowPlaceholderWhenCaretShowingName[]; extern const char kOmniboxUIShowPlaceholderWhenCaretShowingDescription[];
diff --git a/chrome/browser/notifications/proto/notification_data.proto b/chrome/browser/notifications/proto/notification_data.proto index 70814cb..02d089f 100644 --- a/chrome/browser/notifications/proto/notification_data.proto +++ b/chrome/browser/notifications/proto/notification_data.proto
@@ -14,9 +14,24 @@ optional bytes value = 2; } +// Button type. +enum ActionButtonType { + UNKNOWN_ACTION = 0; + HELPFUL = 1; + UNHELPFUL = 2; +} + // Stores data used to display a notification in the UI. -// Next tag: 6 +// Next tag: 7 message NotificationData { + // Represents the button on the notification. + // Next tag: 4 + message Button { + optional string text = 1; + optional ActionButtonType button_type = 2; + optional string id = 3; + } + // Identifier of the notification. optional string id = 1; @@ -32,4 +47,7 @@ // Custom data associated with a notification. repeated CustomData custom_data = 5; + + // A list of buttons on the notification. + repeated Button buttons = 6; }
diff --git a/chrome/browser/notifications/scheduler/internal/proto_conversion.cc b/chrome/browser/notifications/scheduler/internal/proto_conversion.cc index 4d70263..2167858 100644 --- a/chrome/browser/notifications/scheduler/internal/proto_conversion.cc +++ b/chrome/browser/notifications/scheduler/internal/proto_conversion.cc
@@ -171,6 +171,29 @@ NOTREACHED(); } +proto::ActionButtonType ToActionButtonType(ActionButtonType type) { + switch (type) { + case ActionButtonType::kUnknownAction: + return proto::ActionButtonType::UNKNOWN_ACTION; + case ActionButtonType::kHelpful: + return proto::ActionButtonType::HELPFUL; + case ActionButtonType::kUnhelpful: + return proto::ActionButtonType::UNHELPFUL; + } + NOTREACHED(); +} + +ActionButtonType FromActionButtonType(proto::ActionButtonType proto_type) { + switch (proto_type) { + case proto::ActionButtonType::UNKNOWN_ACTION: + return ActionButtonType::kUnknownAction; + case proto::ActionButtonType::HELPFUL: + return ActionButtonType::kHelpful; + case proto::ActionButtonType::UNHELPFUL: + return ActionButtonType::kUnhelpful; + } +} + // Converts NotificationData to proto buffer type. void NotificationDataToProto(NotificationData* notification_data, proto::NotificationData* proto) { @@ -182,6 +205,13 @@ data->set_key(pair.first); data->set_value(pair.second); } + + for (const auto& button : notification_data->buttons) { + auto* proto_button = proto->add_buttons(); + proto_button->set_text(base::UTF16ToUTF8(button.text)); + proto_button->set_button_type(ToActionButtonType(button.type)); + proto_button->set_id(button.id); + } } // Converts NotificationData from proto buffer type. @@ -194,6 +224,15 @@ const auto& pair = proto->custom_data(i); notification_data->custom_data.emplace(pair.key(), pair.value()); } + + for (int i = 0; i < proto->buttons_size(); ++i) { + NotificationData::Button button; + const auto& proto_button = proto->buttons(i); + button.text = base::UTF8ToUTF16(proto_button.text()); + button.type = FromActionButtonType(proto_button.button_type()); + button.id = proto_button.id(); + notification_data->buttons.emplace_back(button); + } } // Converts ScheduleParams::Priority to proto buffer type.
diff --git a/chrome/browser/notifications/scheduler/internal/proto_conversion_unittest.cc b/chrome/browser/notifications/scheduler/internal/proto_conversion_unittest.cc index b3184f13..20ccd82 100644 --- a/chrome/browser/notifications/scheduler/internal/proto_conversion_unittest.cc +++ b/chrome/browser/notifications/scheduler/internal/proto_conversion_unittest.cc
@@ -48,6 +48,16 @@ << " \n Expected: " << test::DebugString(&expected); } +NotificationData::Button CreateButton(const char* text, + ActionButtonType type, + const char* id) { + NotificationData::Button button; + button.text = base::UTF8ToUTF16(text); + button.type = type; + button.id = id; + return button; +} + TEST(ProtoConversionTest, IconEntryFromProto) { IconProto proto; proto.set_uuid(kUuid); @@ -187,5 +197,22 @@ } } +// Verifies buttons are converted correctly to proto buffers. +TEST(ProtoConversionTest, NotificationEntryButtonsConversion) { + NotificationEntry entry(SchedulerClientType::kTest2, kGuid); + bool success = + base::Time::FromString("04/25/20 01:00:00 AM", &entry.create_time); + DCHECK(success); + + NotificationData::Button button; + entry.notification_data.buttons.emplace_back( + CreateButton("text1", ActionButtonType::kUnknownAction, "id1")); + entry.notification_data.buttons.emplace_back( + CreateButton("text2", ActionButtonType::kHelpful, "id2")); + entry.notification_data.buttons.emplace_back( + CreateButton("text3", ActionButtonType::kUnhelpful, "id3")); + TestNotificationEntryConversion(&entry); +} + } // namespace } // namespace notifications
diff --git a/chrome/browser/notifications/scheduler/public/notification_data.cc b/chrome/browser/notifications/scheduler/public/notification_data.cc index 8337eb8..28c0773 100644 --- a/chrome/browser/notifications/scheduler/public/notification_data.cc +++ b/chrome/browser/notifications/scheduler/public/notification_data.cc
@@ -6,13 +6,23 @@ namespace notifications { +NotificationData::Button::Button() = default; +NotificationData::Button::Button(const Button& other) = default; + +bool NotificationData::Button::operator==(const Button& other) const { + return text == other.text && type == other.type && id == other.id; +} + +NotificationData::Button::~Button() = default; + NotificationData::NotificationData() = default; NotificationData::NotificationData(const NotificationData& other) = default; bool NotificationData::operator==(const NotificationData& other) const { return id == other.id && title == other.title && message == other.message && - icons.size() == other.icons.size() && custom_data == other.custom_data; + icons.size() == other.icons.size() && + custom_data == other.custom_data && buttons == other.buttons; } NotificationData::~NotificationData() = default;
diff --git a/chrome/browser/notifications/scheduler/public/notification_data.h b/chrome/browser/notifications/scheduler/public/notification_data.h index 13ea8c4..ade6de8 100644 --- a/chrome/browser/notifications/scheduler/public/notification_data.h +++ b/chrome/browser/notifications/scheduler/public/notification_data.h
@@ -10,6 +10,7 @@ #include <vector> #include "base/strings/string16.h" +#include "chrome/browser/notifications/scheduler/public/notification_scheduler_types.h" #include "third_party/skia/include/core/SkBitmap.h" namespace notifications { @@ -20,6 +21,23 @@ // or retrieving the hard coded assets and rewrites the data before notification // is shown in NotificationSchedulerClient::BeforeShowNotification(). struct NotificationData { + // Represents a button on the notification UI. + struct Button { + Button(); + Button(const Button& other); + bool operator==(const Button& other) const; + ~Button(); + + // The text associated with the button. + base::string16 text; + + // The button type. + ActionButtonType type; + + // The id of the button. + std::string id; + }; + using CustomData = std::map<std::string, std::string>; NotificationData(); NotificationData(const NotificationData& other); @@ -44,6 +62,9 @@ // Custom key value pair data associated with each notification. Will be sent // back after user interaction. CustomData custom_data; + + // A list of buttons on the notification. + std::vector<Button> buttons; }; } // namespace notifications
diff --git a/chrome/browser/offline_pages/android/offline_page_archive_publisher_impl.cc b/chrome/browser/offline_pages/android/offline_page_archive_publisher_impl.cc new file mode 100644 index 0000000..2377d7d --- /dev/null +++ b/chrome/browser/offline_pages/android/offline_page_archive_publisher_impl.cc
@@ -0,0 +1,173 @@ +// 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/offline_pages/android/offline_page_archive_publisher_impl.h" + +#include <errno.h> +#include <utility> + +#include "base/android/jni_android.h" +#include "base/android/jni_array.h" +#include "base/android/jni_string.h" +#include "base/android/scoped_java_ref.h" +#include "base/bind.h" +#include "base/files/file_util.h" +#include "base/sequenced_task_runner.h" +#include "base/strings/utf_string_conversions.h" +#include "base/task_runner_util.h" +#include "chrome/android/chrome_jni_headers/OfflinePageArchivePublisherBridge_jni.h" +#include "components/offline_pages/core/archive_manager.h" +#include "components/offline_pages/core/model/offline_page_model_utils.h" +#include "components/offline_pages/core/offline_store_utils.h" + +using base::android::ScopedJavaLocalRef; + +namespace offline_pages { + +namespace { + +using offline_pages::SavePageResult; + +// Creates a singleton Delegate. +OfflinePageArchivePublisherImpl::Delegate* GetDefaultDelegate() { + static OfflinePageArchivePublisherImpl::Delegate delegate; + return &delegate; +} + +// Helper function to do the move and register synchronously. Make sure this is +// called from a background thread. +PublishArchiveResult MoveAndRegisterArchive( + const offline_pages::OfflinePageItem& offline_page, + const base::FilePath& publish_directory, + OfflinePageArchivePublisherImpl::Delegate* delegate) { + PublishArchiveResult archive_result; + // Calculate the new file name. + base::FilePath new_file_path = + offline_pages::model_utils::GenerateUniqueFilenameForOfflinePage( + offline_page.title, offline_page.url, publish_directory); + + // Create the destination directory if it does not already exist. + if (!publish_directory.empty() && !base::DirectoryExists(publish_directory)) { + base::File::Error file_error; + base::CreateDirectoryAndGetError(publish_directory, &file_error); + } + + // Move the file. + bool moved = base::Move(offline_page.file_path, new_file_path); + if (!moved) { + archive_result.move_result = SavePageResult::FILE_MOVE_FAILED; + DVPLOG(0) << "OfflinePage publishing file move failure " << __func__; + + if (!base::PathExists(offline_page.file_path)) { + DVLOG(0) << "Can't copy from non-existent path, from " + << offline_page.file_path << " " << __func__; + } + if (!base::PathExists(publish_directory)) { + DVLOG(0) << "Target directory does not exist, " << publish_directory + << " " << __func__; + } + return archive_result; + } + + // Tell the download manager about our file, get back an id. + if (!delegate->IsDownloadManagerInstalled()) { + archive_result.move_result = SavePageResult::ADD_TO_DOWNLOAD_MANAGER_FAILED; + return archive_result; + } + + // TODO(petewil): Handle empty page title. + std::string page_title = base::UTF16ToUTF8(offline_page.title); + // We use the title for a description, since the add to the download manager + // fails without a description, and we don't have anything better to use. + int64_t download_id = delegate->AddCompletedDownload( + page_title, page_title, + offline_pages::store_utils::ToDatabaseFilePath(new_file_path), + offline_page.file_size, offline_page.url.spec(), std::string()); + if (download_id == 0LL) { + archive_result.move_result = SavePageResult::ADD_TO_DOWNLOAD_MANAGER_FAILED; + return archive_result; + } + + // Put results into the result object. + archive_result.move_result = SavePageResult::SUCCESS; + archive_result.new_file_path = new_file_path; + archive_result.download_id = download_id; + + return archive_result; +} + +} // namespace + +OfflinePageArchivePublisherImpl::OfflinePageArchivePublisherImpl( + ArchiveManager* archive_manager) + : archive_manager_(archive_manager), delegate_(GetDefaultDelegate()) {} + +OfflinePageArchivePublisherImpl::~OfflinePageArchivePublisherImpl() {} + +void OfflinePageArchivePublisherImpl::SetDelegateForTesting( + OfflinePageArchivePublisherImpl::Delegate* delegate) { + delegate_ = delegate; +} + +void OfflinePageArchivePublisherImpl::PublishArchive( + const OfflinePageItem& offline_page, + const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, + PublishArchiveDoneCallback publish_done_callback) const { + base::PostTaskAndReplyWithResult( + background_task_runner.get(), FROM_HERE, + base::BindOnce(&MoveAndRegisterArchive, offline_page, + archive_manager_->GetPublicArchivesDir(), delegate_), + base::BindOnce(std::move(publish_done_callback), offline_page)); +} + +void OfflinePageArchivePublisherImpl::UnpublishArchives( + const std::vector<int64_t>& download_manager_ids) const { + delegate_->Remove(download_manager_ids); +} + +// Delegate implementation using Android download manager. + +bool OfflinePageArchivePublisherImpl::Delegate::IsDownloadManagerInstalled() { + JNIEnv* env = base::android::AttachCurrentThread(); + jboolean is_installed = + Java_OfflinePageArchivePublisherBridge_isAndroidDownloadManagerInstalled( + env); + return is_installed; +} + +int64_t OfflinePageArchivePublisherImpl::Delegate::AddCompletedDownload( + const std::string& title, + const std::string& description, + const std::string& path, + int64_t length, + const std::string& uri, + const std::string& referer) { + JNIEnv* env = base::android::AttachCurrentThread(); + // Convert strings to jstring references. + ScopedJavaLocalRef<jstring> j_title = + base::android::ConvertUTF8ToJavaString(env, title); + ScopedJavaLocalRef<jstring> j_description = + base::android::ConvertUTF8ToJavaString(env, description); + ScopedJavaLocalRef<jstring> j_path = + base::android::ConvertUTF8ToJavaString(env, path); + ScopedJavaLocalRef<jstring> j_uri = + base::android::ConvertUTF8ToJavaString(env, uri); + ScopedJavaLocalRef<jstring> j_referer = + base::android::ConvertUTF8ToJavaString(env, referer); + + return Java_OfflinePageArchivePublisherBridge_addCompletedDownload( + env, j_title, j_description, j_path, length, j_uri, j_referer); +} + +int OfflinePageArchivePublisherImpl::Delegate::Remove( + const std::vector<int64_t>& android_download_manager_ids) { + JNIEnv* env = base::android::AttachCurrentThread(); + // Build a JNI array with our ID data. + ScopedJavaLocalRef<jlongArray> j_ids = + base::android::ToJavaLongArray(env, android_download_manager_ids); + + return Java_OfflinePageArchivePublisherBridge_remove(env, j_ids); +} + +} // namespace offline_pages
diff --git a/chrome/browser/offline_pages/android/offline_page_archive_publisher_impl.h b/chrome/browser/offline_pages/android/offline_page_archive_publisher_impl.h new file mode 100644 index 0000000..40fe4fe --- /dev/null +++ b/chrome/browser/offline_pages/android/offline_page_archive_publisher_impl.h
@@ -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. + +#ifndef CHROME_BROWSER_OFFLINE_PAGES_ANDROID_OFFLINE_PAGE_ARCHIVE_PUBLISHER_IMPL_H_ +#define CHROME_BROWSER_OFFLINE_PAGES_ANDROID_OFFLINE_PAGE_ARCHIVE_PUBLISHER_IMPL_H_ + +#include <cstdint> +#include <string> + +#include "base/callback.h" +#include "base/files/file_path.h" +#include "components/offline_pages/core/offline_page_archive_publisher.h" +#include "components/offline_pages/core/offline_page_item.h" +#include "components/offline_pages/core/offline_page_types.h" + +namespace base { +class SequencedTaskRunner; +} // namespace base + +namespace offline_pages { + +class ArchiveManager; + +class OfflinePageArchivePublisherImpl : public OfflinePageArchivePublisher { + public: + class Delegate { + public: + Delegate() = default; + + // Returns true if a system download manager is available on this platform. + virtual bool IsDownloadManagerInstalled(); + + // Returns the download manager ID of the download, which we will place in + // the offline pages database as part of the offline page item. + // TODO(petewil): it might make sense to move all these params into a + // struct. + virtual int64_t AddCompletedDownload(const std::string& title, + const std::string& description, + const std::string& path, + int64_t length, + const std::string& uri, + const std::string& referer); + + // Returns the number of pages removed. + virtual int Remove( + const std::vector<int64_t>& android_download_manager_ids); + + private: + Delegate(const Delegate&) = delete; + Delegate& operator=(const Delegate&) = delete; + }; + + explicit OfflinePageArchivePublisherImpl(ArchiveManager* archive_manager); + ~OfflinePageArchivePublisherImpl() override; + + void SetDelegateForTesting(Delegate* delegate); + + // OfflinePageArchivePublisher implementation. + void PublishArchive( + const OfflinePageItem& offline_page, + const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, + PublishArchiveDoneCallback publish_done_callback) const override; + + void UnpublishArchives( + const std::vector<int64_t>& download_manager_ids) const override; + + private: + ArchiveManager* archive_manager_; + Delegate* delegate_; +}; + +} // namespace offline_pages + +#endif // CHROME_BROWSER_OFFLINE_PAGES_ANDROID_OFFLINE_PAGE_ARCHIVE_PUBLISHER_IMPL_H_
diff --git a/chrome/browser/offline_pages/android/offline_page_archive_publisher_impl_unittest.cc b/chrome/browser/offline_pages/android/offline_page_archive_publisher_impl_unittest.cc new file mode 100644 index 0000000..66f829e --- /dev/null +++ b/chrome/browser/offline_pages/android/offline_page_archive_publisher_impl_unittest.cc
@@ -0,0 +1,173 @@ +// 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/offline_pages/android/offline_page_archive_publisher_impl.h" + +#include "base/bind.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/memory/weak_ptr.h" +#include "base/sequenced_task_runner.h" +#include "base/test/test_simple_task_runner.h" +#include "base/threading/thread_task_runner_handle.h" +#include "components/offline_pages/core/archive_manager.h" +#include "components/offline_pages/core/model/offline_page_item_generator.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { +const int64_t kDownloadId = 42LL; +} // namespace + +namespace offline_pages { + +class OfflinePageArchivePublisherImplTest + : public testing::Test, + public base::SupportsWeakPtr<OfflinePageArchivePublisherImplTest> { + public: + OfflinePageArchivePublisherImplTest() + : task_runner_(new base::TestSimpleTaskRunner), + task_runner_handle_(task_runner_), + weak_ptr_factory_(this) {} + ~OfflinePageArchivePublisherImplTest() override {} + + SavePageCallback save_page_callback; + + void SetUp() override; + void PumpLoop(); + + OfflinePageItemGenerator* page_generator() { return &page_generator_; } + + const base::FilePath& temporary_dir_path() { + return temporary_dir_.GetPath(); + } + const base::FilePath& private_archive_dir_path() { + return private_archive_dir_.GetPath(); + } + const base::FilePath& public_archive_dir_path() { + return public_archive_dir_.GetPath(); + } + const PublishArchiveResult& publish_archive_result() { + return publish_archive_result_; + } + scoped_refptr<base::SequencedTaskRunner> task_runner() { + return task_runner_; + } + base::WeakPtr<OfflinePageArchivePublisherImplTest> get_weak_ptr() { + return weak_ptr_factory_.GetWeakPtr(); + } + + void PublishArchiveDone(SavePageCallback save_page_callback, + const OfflinePageItem& offline_page, + PublishArchiveResult archive_result); + + private: + base::ScopedTempDir temporary_dir_; + base::ScopedTempDir private_archive_dir_; + base::ScopedTempDir public_archive_dir_; + OfflinePageItemGenerator page_generator_; + PublishArchiveResult publish_archive_result_; + scoped_refptr<base::TestSimpleTaskRunner> task_runner_; + base::ThreadTaskRunnerHandle task_runner_handle_; + base::WeakPtrFactory<OfflinePageArchivePublisherImplTest> weak_ptr_factory_; +}; + +void OfflinePageArchivePublisherImplTest::SetUp() { + ASSERT_TRUE(temporary_dir_.CreateUniqueTempDir()); + ASSERT_TRUE(private_archive_dir_.CreateUniqueTempDir()); + ASSERT_TRUE(public_archive_dir_.CreateUniqueTempDir()); +} + +class TestArchivePublisherDelegate + : public OfflinePageArchivePublisherImpl::Delegate { + public: + TestArchivePublisherDelegate(int64_t id_to_use, bool installed) + : download_id_(id_to_use), last_removed_id_(0), installed_(installed) {} + + bool IsDownloadManagerInstalled() override { return installed_; } + int64_t AddCompletedDownload(const std::string& title, + const std::string& description, + const std::string& path, + int64_t length, + const std::string& uri, + const std::string& referer) override { + return download_id_; + } + int Remove( + const std::vector<int64_t>& android_download_manager_ids) override { + int count = static_cast<int>(android_download_manager_ids.size()); + if (count > 0) + last_removed_id_ = android_download_manager_ids[count - 1]; + return count; + } + + int64_t last_removed_id() const { return last_removed_id_; } + + private: + int64_t download_id_; + int64_t last_removed_id_; + bool installed_; +}; + +void OfflinePageArchivePublisherImplTest::PublishArchiveDone( + SavePageCallback save_page_callback, + const OfflinePageItem& offline_page, + PublishArchiveResult archive_result) { + publish_archive_result_ = archive_result; +} + +void OfflinePageArchivePublisherImplTest::PumpLoop() { + task_runner_->RunUntilIdle(); +} + +TEST_F(OfflinePageArchivePublisherImplTest, PublishArchive) { + ArchiveManager archive_manager(temporary_dir_path(), + private_archive_dir_path(), + public_archive_dir_path(), task_runner()); + + OfflinePageArchivePublisherImpl publisher(&archive_manager); + TestArchivePublisherDelegate delegate(kDownloadId, true); + publisher.SetDelegateForTesting(&delegate); + + // Put an offline page into the private dir, adjust the FilePath. + page_generator()->SetArchiveDirectory(temporary_dir_path()); + OfflinePageItem offline_page = page_generator()->CreateItemWithTempFile(); + base::FilePath old_file_path = offline_page.file_path; + base::FilePath new_file_path = + public_archive_dir_path().Append(offline_page.file_path.BaseName()); + + publisher.PublishArchive( + offline_page, base::ThreadTaskRunnerHandle::Get(), + base::BindOnce(&OfflinePageArchivePublisherImplTest::PublishArchiveDone, + get_weak_ptr(), std::move(save_page_callback))); + PumpLoop(); + + EXPECT_EQ(SavePageResult::SUCCESS, publish_archive_result().move_result); + EXPECT_EQ(kDownloadId, publish_archive_result().download_id); + // Check there is a file in the new location. + EXPECT_TRUE(public_archive_dir_path().IsParent( + publish_archive_result().new_file_path)); + EXPECT_TRUE(base::PathExists(publish_archive_result().new_file_path)); + // Check there is no longer a file in the old location. + EXPECT_FALSE(base::PathExists(old_file_path)); +} + +TEST_F(OfflinePageArchivePublisherImplTest, UnpublishArchive) { + ArchiveManager archive_manager(temporary_dir_path(), + private_archive_dir_path(), + public_archive_dir_path(), task_runner()); + + TestArchivePublisherDelegate delegate(kDownloadId, true); + OfflinePageArchivePublisherImpl publisher(&archive_manager); + publisher.SetDelegateForTesting(&delegate); + + std::vector<int64_t> ids_to_remove = {kDownloadId}; + publisher.UnpublishArchives(std::move(ids_to_remove)); + + EXPECT_EQ(kDownloadId, delegate.last_removed_id()); +} + +// TODO(petewil): Add test cases for move failed, and adding to ADM failed. + +} // namespace offline_pages
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 cf5a2d3..ee62667 100644 --- a/chrome/browser/offline_pages/android/offline_page_model_factory.cc +++ b/chrome/browser/offline_pages/android/offline_page_model_factory.cc
@@ -17,7 +17,7 @@ #include "base/time/default_clock.h" #include "chrome/browser/download/download_prefs.h" #include "chrome/browser/offline_pages/android/cct_origin_observer.h" -#include "chrome/browser/offline_pages/android/offline_pages_download_manager_bridge.h" +#include "chrome/browser/offline_pages/android/offline_page_archive_publisher_impl.h" #include "chrome/browser/offline_pages/download_archive_manager.h" #include "chrome/browser/offline_pages/fresh_offline_content_observer.h" #include "chrome/browser/profiles/profile.h" @@ -78,16 +78,13 @@ profile_key->GetPrefs()); auto clock = std::make_unique<base::DefaultClock>(); - auto download_manager = - std::make_unique<android::OfflinePagesDownloadManagerBridge>(); - auto publisher = std::make_unique<OfflinePageArchivePublisher>( - archive_manager.get(), download_manager.get()); + auto publisher = + std::make_unique<OfflinePageArchivePublisherImpl>(archive_manager.get()); std::unique_ptr<OfflinePageModelTaskified> model = std::make_unique<OfflinePageModelTaskified>( std::move(metadata_store), std::move(archive_manager), - std::move(download_manager), std::move(publisher), - background_task_runner); + std::move(publisher), background_task_runner); CctOriginObserver::AttachToOfflinePageModel(model.get());
diff --git a/chrome/browser/offline_pages/android/offline_pages_download_manager_bridge.cc b/chrome/browser/offline_pages/android/offline_pages_download_manager_bridge.cc deleted file mode 100644 index 6fd0b124..0000000 --- a/chrome/browser/offline_pages/android/offline_pages_download_manager_bridge.cc +++ /dev/null
@@ -1,62 +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 "chrome/browser/offline_pages/android/offline_pages_download_manager_bridge.h" - -#include "base/android/jni_android.h" -#include "base/android/jni_array.h" -#include "base/android/jni_string.h" -#include "base/android/scoped_java_ref.h" -#include "chrome/android/chrome_jni_headers/OfflinePagesDownloadManagerBridge_jni.h" - -using base::android::JavaParamRef; -using base::android::ScopedJavaLocalRef; - -namespace offline_pages { -namespace android { - -bool OfflinePagesDownloadManagerBridge::IsDownloadManagerInstalled() { - JNIEnv* env = base::android::AttachCurrentThread(); - jboolean is_installed = - Java_OfflinePagesDownloadManagerBridge_isAndroidDownloadManagerInstalled( - env); - return is_installed; -} - -int64_t OfflinePagesDownloadManagerBridge::AddCompletedDownload( - const std::string& title, - const std::string& description, - const std::string& path, - int64_t length, - const std::string& uri, - const std::string& referer) { - JNIEnv* env = base::android::AttachCurrentThread(); - // Convert strings to jstring references. - ScopedJavaLocalRef<jstring> j_title = - base::android::ConvertUTF8ToJavaString(env, title); - ScopedJavaLocalRef<jstring> j_description = - base::android::ConvertUTF8ToJavaString(env, description); - ScopedJavaLocalRef<jstring> j_path = - base::android::ConvertUTF8ToJavaString(env, path); - ScopedJavaLocalRef<jstring> j_uri = - base::android::ConvertUTF8ToJavaString(env, uri); - ScopedJavaLocalRef<jstring> j_referer = - base::android::ConvertUTF8ToJavaString(env, referer); - - return Java_OfflinePagesDownloadManagerBridge_addCompletedDownload( - env, j_title, j_description, j_path, length, j_uri, j_referer); -} - -int OfflinePagesDownloadManagerBridge::Remove( - const std::vector<int64_t>& android_download_manager_ids) { - JNIEnv* env = base::android::AttachCurrentThread(); - // Build a JNI array with our ID data. - ScopedJavaLocalRef<jlongArray> j_ids = - base::android::ToJavaLongArray(env, android_download_manager_ids); - - return Java_OfflinePagesDownloadManagerBridge_remove(env, j_ids); -} - -} // namespace android -} // namespace offline_pages
diff --git a/chrome/browser/offline_pages/android/offline_pages_download_manager_bridge.h b/chrome/browser/offline_pages/android/offline_pages_download_manager_bridge.h deleted file mode 100644 index e22ba6af..0000000 --- a/chrome/browser/offline_pages/android/offline_pages_download_manager_bridge.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 CHROME_BROWSER_OFFLINE_PAGES_ANDROID_OFFLINE_PAGES_DOWNLOAD_MANAGER_BRIDGE_H_ -#define CHROME_BROWSER_OFFLINE_PAGES_ANDROID_OFFLINE_PAGES_DOWNLOAD_MANAGER_BRIDGE_H_ - -#include <stdint.h> - -#include <vector> - -#include "components/offline_pages/core/system_download_manager.h" - -namespace offline_pages { -namespace android { - -// Bridge between C++ and Java for communicating with the AndroidDownloadManager -// on Android. -class OfflinePagesDownloadManagerBridge : public SystemDownloadManager { - public: - bool IsDownloadManagerInstalled() override; - - int64_t AddCompletedDownload(const std::string& title, - const std::string& description, - const std::string& path, - int64_t length, - const std::string& uri, - const std::string& referer) override; - - int Remove(const std::vector<int64_t>& android_download_manager_ids) override; -}; - -} // namespace android -} // namespace offline_pages - -#endif // CHROME_BROWSER_OFFLINE_PAGES_ANDROID_OFFLINE_PAGES_DOWNLOAD_MANAGER_BRIDGE_H_
diff --git a/chrome/browser/offline_pages/android/prefetch_test_bridge.cc b/chrome/browser/offline_pages/android/prefetch_test_bridge.cc index 128c86e..a9940e1 100644 --- a/chrome/browser/offline_pages/android/prefetch_test_bridge.cc +++ b/chrome/browser/offline_pages/android/prefetch_test_bridge.cc
@@ -62,7 +62,7 @@ std::string image_data; base::android::JavaByteArrayToString(env, j_image_data, &image_data); - cache->SaveImage(url, image_data); + cache->SaveImage(url, image_data, false /* needs_transcoding */); } JNI_EXPORT void JNI_PrefetchTestBridge_AddCandidatePrefetchURL(
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 ab1de6d..758a3c32 100644 --- a/chrome/browser/offline_pages/offline_page_request_handler_unittest.cc +++ b/chrome/browser/offline_pages/offline_page_request_handler_unittest.cc
@@ -37,7 +37,6 @@ #include "components/offline_pages/core/offline_page_test_archive_publisher.h" #include "components/offline_pages/core/offline_page_test_archiver.h" #include "components/offline_pages/core/request_header/offline_page_navigation_ui_data.h" -#include "components/offline_pages/core/stub_system_download_manager.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/resource_request_info.h" @@ -865,8 +864,6 @@ key->GetPath().Append(chrome::kOfflinePageMetadataDirname); std::unique_ptr<OfflinePageMetadataStore> metadata_store( new OfflinePageMetadataStore(task_runner, store_path)); - auto download_manager = - std::make_unique<StubSystemDownloadManager>(kDownloadId, true); // Since we're not saving page into temporary dir, it's set the same as the // private dir. @@ -875,13 +872,13 @@ task_runner); auto archive_publisher = std::make_unique<OfflinePageTestArchivePublisher>( - archive_manager.get(), download_manager.get()); + archive_manager.get(), kDownloadId); // TODO(iwells): Figure out how to make use_verbatim_archive_path go away. archive_publisher->use_verbatim_archive_path(true); return std::unique_ptr<KeyedService>(new OfflinePageModelTaskified( std::move(metadata_store), std::move(archive_manager), - std::move(download_manager), std::move(archive_publisher), task_runner)); + std::move(archive_publisher), task_runner)); } // static
diff --git a/chrome/browser/offline_pages/test_offline_page_model_builder.cc b/chrome/browser/offline_pages/test_offline_page_model_builder.cc index 5003dde..3a02d2f2 100644 --- a/chrome/browser/offline_pages/test_offline_page_model_builder.cc +++ b/chrome/browser/offline_pages/test_offline_page_model_builder.cc
@@ -17,7 +17,6 @@ #include "components/offline_pages/core/model/offline_page_model_taskified.h" #include "components/offline_pages/core/offline_page_metadata_store.h" #include "components/offline_pages/core/offline_page_test_archive_publisher.h" -#include "components/offline_pages/core/stub_system_download_manager.h" namespace { const int64_t kDownloadId = 42LL; @@ -47,15 +46,12 @@ auto archive_manager = std::make_unique<ArchiveManager>( temporary_archives_dir, private_archives_dir, public_archives_dir, task_runner); - auto stub_download_manager = - std::make_unique<StubSystemDownloadManager>(kDownloadId, true); - auto publisher = std::make_unique<OfflinePageTestArchivePublisher>( - archive_manager.get(), stub_download_manager.get()); + archive_manager.get(), kDownloadId); return std::unique_ptr<KeyedService>(new OfflinePageModelTaskified( std::move(metadata_store), std::move(archive_manager), - std::move(stub_download_manager), std::move(publisher), task_runner)); + std::move(publisher), task_runner)); } } // namespace offline_pages
diff --git a/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_base.cc b/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_base.cc index 5f1bff1..809db81 100644 --- a/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_base.cc +++ b/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_base.cc
@@ -79,20 +79,15 @@ return 0; } - std::string session_key = data->session_key(); uint64_t page_id = data->page_id().value(); - char buf[8]; base::WriteBigEndian<uint64_t>(buf, page_id); - std::vector<char> to_hash; - std::copy(session_key.begin(), session_key.end(), - std::back_inserter(to_hash)); - to_hash.insert(to_hash.end(), buf, buf + 8); + std::string to_hash(data->session_key()); + to_hash.append(std::begin(buf), std::end(buf)); char hash[32]; - crypto::SHA256HashString(base::StringPiece(to_hash.begin(), to_hash.end()), - hash, 32); + crypto::SHA256HashString(base::StringPiece(to_hash), hash, 32); uint64_t uuid; base::ReadBigEndian<uint64_t>(hash, &uuid);
diff --git a/chrome/browser/page_load_metrics/observers/largest_contentful_paint_handler.h b/chrome/browser/page_load_metrics/observers/largest_contentful_paint_handler.h index 6a11714..59f205f6 100644 --- a/chrome/browser/page_load_metrics/observers/largest_contentful_paint_handler.h +++ b/chrome/browser/page_load_metrics/observers/largest_contentful_paint_handler.h
@@ -31,6 +31,7 @@ page_load_metrics::PageLoadMetricsObserver::LargestContentType Type() const { return type_; } + bool IsEmpty() const { // |size_| is not necessarily 0, for example, when the largest image is // still loading. @@ -62,13 +63,21 @@ class LargestContentfulPaintHandler { public: + using FrameTreeNodeId = + page_load_metrics::PageLoadMetricsObserver::FrameTreeNodeId; static void SetTestMode(bool enabled); LargestContentfulPaintHandler(); ~LargestContentfulPaintHandler(); - using FrameTreeNodeId = - page_load_metrics::PageLoadMetricsObserver::FrameTreeNodeId; void RecordTiming(const page_load_metrics::mojom::PaintTimingPtr&, content::RenderFrameHost* subframe_rfh); + inline void RecordMainFrameTreeNodeId(int main_frame_tree_node_id) { + main_frame_tree_node_id_.emplace(main_frame_tree_node_id); + } + + inline int MainFrameTreeNodeId() const { + return main_frame_tree_node_id_.value(); + } + // We merge the candidates from main frame and subframe to get the largest // candidate across all frames. const ContentfulPaintTimingInfo& MergeMainFrameAndSubframes(); @@ -83,6 +92,10 @@ ContentfulPaint main_frame_contentful_paint_; ContentfulPaint subframe_contentful_paint_; + // Used for Telemetry to distinguish the LCP events from different + // navigations. + base::Optional<int> main_frame_tree_node_id_; + // Navigation start offsets for the most recently committed document in each // frame. std::map<FrameTreeNodeId, base::TimeDelta> subframe_navigation_start_offset_;
diff --git a/chrome/browser/page_load_metrics/observers/previews_ukm_observer.cc b/chrome/browser/page_load_metrics/observers/previews_ukm_observer.cc index 5fbda6d9..f70e1814 100644 --- a/chrome/browser/page_load_metrics/observers/previews_ukm_observer.cc +++ b/chrome/browser/page_load_metrics/observers/previews_ukm_observer.cc
@@ -118,6 +118,10 @@ previews::PreviewsType::RESOURCE_LOADING_HINTS) { resource_loading_hints_seen_ = true; } + if (previews_state && previews::GetMainFramePreviewsType(previews_state) == + previews::PreviewsType::DEFER_ALL_SCRIPT) { + defer_all_script_seen_ = true; + } if (previews_user_data->cache_control_no_transform_directive()) { origin_opt_out_occurred_ = true; } @@ -139,6 +143,9 @@ resource_loading_hints_eligibility_reason_ = previews_user_data->EligibilityReasonForPreview( previews::PreviewsType::RESOURCE_LOADING_HINTS); + defer_all_script_eligibility_reason_ = + previews_user_data->EligibilityReasonForPreview( + previews::PreviewsType::DEFER_ALL_SCRIPT); offline_eligibility_reason_ = previews_user_data->EligibilityReasonForPreview( previews::PreviewsType::OFFLINE); @@ -219,9 +226,9 @@ // preview can be attempted and not commit. This incurs the penalty but may // also cause no preview to be committed. if (!lite_page_seen_ && !noscript_seen_ && !resource_loading_hints_seen_ && - !offline_preview_seen_ && !origin_opt_out_occurred_ && - !save_data_enabled_ && !lite_page_redirect_seen_ && - !navigation_restart_penalty_.has_value()) { + !defer_all_script_seen_ && !offline_preview_seen_ && + !origin_opt_out_occurred_ && !save_data_enabled_ && + !lite_page_redirect_seen_ && !navigation_restart_penalty_.has_value()) { return; } @@ -235,6 +242,8 @@ builder.Setnoscript(1); if (resource_loading_hints_seen_) builder.Setresource_loading_hints(1); + if (defer_all_script_seen_) + builder.Setdefer_all_script(1); if (offline_preview_seen_) builder.Setoffline_preview(1); // 2 is set here for legacy reasons as it denotes an optout through the @@ -271,6 +280,11 @@ builder.Setresource_loading_hints_eligibility_reason( static_cast<int>(resource_loading_hints_eligibility_reason_.value())); } + if (ShouldOptionalEligibilityReasonBeRecorded( + defer_all_script_eligibility_reason_)) { + builder.Setdefer_all_script_eligibility_reason( + static_cast<int>(defer_all_script_eligibility_reason_.value())); + } if (ShouldOptionalEligibilityReasonBeRecorded(offline_eligibility_reason_)) { builder.Setoffline_eligibility_reason( static_cast<int>(offline_eligibility_reason_.value()));
diff --git a/chrome/browser/page_load_metrics/observers/previews_ukm_observer.h b/chrome/browser/page_load_metrics/observers/previews_ukm_observer.h index 6bc3c6e..7213918 100644 --- a/chrome/browser/page_load_metrics/observers/previews_ukm_observer.h +++ b/chrome/browser/page_load_metrics/observers/previews_ukm_observer.h
@@ -69,24 +69,27 @@ bool lite_page_redirect_seen_ = false; bool noscript_seen_ = false; bool resource_loading_hints_seen_ = false; + bool defer_all_script_seen_ = false; bool offline_preview_seen_ = false; bool opt_out_occurred_ = false; bool origin_opt_out_occurred_ = false; bool save_data_enabled_ = false; bool previews_likely_ = false; base::Optional<previews::PreviewsEligibilityReason> - lite_page_eligibility_reason_ = base::nullopt; + lite_page_eligibility_reason_; base::Optional<previews::PreviewsEligibilityReason> - lite_page_redirect_eligibility_reason_ = base::nullopt; + lite_page_redirect_eligibility_reason_; base::Optional<previews::PreviewsEligibilityReason> - noscript_eligibility_reason_ = base::nullopt; + noscript_eligibility_reason_; base::Optional<previews::PreviewsEligibilityReason> - resource_loading_hints_eligibility_reason_ = base::nullopt; + resource_loading_hints_eligibility_reason_; base::Optional<previews::PreviewsEligibilityReason> - offline_eligibility_reason_ = base::nullopt; + defer_all_script_eligibility_reason_; + base::Optional<previews::PreviewsEligibilityReason> + offline_eligibility_reason_; CoinFlipHoldbackResult coin_flip_result_ = CoinFlipHoldbackResult::kNotSet; - base::Optional<base::TimeDelta> navigation_restart_penalty_ = base::nullopt; - base::Optional<std::string> serialized_hint_version_string_ = base::nullopt; + base::Optional<base::TimeDelta> navigation_restart_penalty_; + base::Optional<std::string> serialized_hint_version_string_; SEQUENCE_CHECKER(sequence_checker_);
diff --git a/chrome/browser/page_load_metrics/observers/previews_ukm_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/previews_ukm_observer_unittest.cc index c404b93..9c33c386 100644 --- a/chrome/browser/page_load_metrics/observers/previews_ukm_observer_unittest.cc +++ b/chrome/browser/page_load_metrics/observers/previews_ukm_observer_unittest.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h" #include "chrome/browser/page_load_metrics/page_load_metrics_observer.h" #include "chrome/browser/page_load_metrics/page_load_tracker.h" +#include "chrome/browser/previews/previews_content_util.h" #include "chrome/browser/previews/previews_ui_tab_helper.h" #include "chrome/test/base/testing_browser_process.h" #include "components/optimization_guide/proto/hints.pb.h" @@ -42,29 +43,19 @@ class TestPreviewsUKMObserver : public PreviewsUKMObserver { public: TestPreviewsUKMObserver( - PreviewsType committed_preview, + content::PreviewsState committed_state, content::PreviewsState allowed_state, - bool lite_page_received, - bool lite_page_redirect_received, - bool noscript_on, - bool resource_loading_hints_on, bool origin_opt_out_received, bool save_data_enabled, - bool is_offline_preview, CoinFlipHoldbackResult coin_flip_result, std::unordered_map<PreviewsType, PreviewsEligibilityReason> eligibility_reasons, base::Optional<base::TimeDelta> navigation_restart_penalty, base::Optional<std::string> hint_version_string) - : committed_preview_(committed_preview), + : committed_state_(committed_state), allowed_state_(allowed_state), - lite_page_received_(lite_page_received), - lite_page_redirect_received_(lite_page_redirect_received), - noscript_on_(noscript_on), - resource_loading_hints_on_(resource_loading_hints_on), origin_opt_out_received_(origin_opt_out_received), save_data_enabled_(save_data_enabled), - is_offline_preview_(is_offline_preview), coin_flip_result_(coin_flip_result), eligibility_reasons_(eligibility_reasons), navigation_restart_penalty_(navigation_restart_penalty), @@ -81,45 +72,12 @@ ui_tab_helper->CreatePreviewsUserDataForNavigationHandle( navigation_handle, 1u); - user_data->SetCommittedPreviewsTypeForTesting(committed_preview_); user_data->set_allowed_previews_state(allowed_state_); + user_data->set_committed_previews_state(committed_state_); + user_data->SetCommittedPreviewsTypeForTesting( + previews::GetMainFramePreviewsType(committed_state_)); user_data->set_coin_flip_holdback_result(coin_flip_result_); - if (noscript_on_) { - content::PreviewsState previews_state = - user_data->CommittedPreviewsState(); - user_data->set_committed_previews_state(previews_state |= - content::NOSCRIPT_ON); - } - - if (resource_loading_hints_on_) { - content::PreviewsState previews_state = - user_data->CommittedPreviewsState(); - user_data->set_committed_previews_state( - previews_state |= content::RESOURCE_LOADING_HINTS_ON); - } - - if (lite_page_received_) { - content::PreviewsState previews_state = - user_data->CommittedPreviewsState(); - user_data->set_committed_previews_state(previews_state |= - content::SERVER_LITE_PAGE_ON); - } - - if (lite_page_redirect_received_) { - content::PreviewsState previews_state = - user_data->CommittedPreviewsState(); - user_data->set_committed_previews_state(previews_state |= - content::LITE_PAGE_REDIRECT_ON); - } - - if (is_offline_preview_) { - content::PreviewsState previews_state = - user_data->CommittedPreviewsState(); - user_data->set_committed_previews_state(previews_state |= - content::OFFLINE_PAGE_ON); - } - if (navigation_restart_penalty_.has_value()) { user_data->set_server_lite_page_info( std::make_unique<previews::PreviewsUserData::ServerLitePageInfo>()); @@ -152,18 +110,13 @@ } bool IsOfflinePreview(content::WebContents* web_contents) const override { - return is_offline_preview_; + return committed_state_ == content::OFFLINE_PAGE_ON; } - PreviewsType committed_preview_; + content::PreviewsState committed_state_; content::PreviewsState allowed_state_; - bool lite_page_received_; - bool lite_page_redirect_received_; - bool noscript_on_; - bool resource_loading_hints_on_; bool origin_opt_out_received_; const bool save_data_enabled_; - const bool is_offline_preview_; CoinFlipHoldbackResult coin_flip_result_; std::unordered_map<PreviewsType, PreviewsEligibilityReason> eligibility_reasons_; @@ -179,49 +132,35 @@ PreviewsUKMObserverTest() {} ~PreviewsUKMObserverTest() override {} - void RunTest(content::PreviewsState allowed_state, - PreviewsType committed_preview, - bool lite_page_received, - bool lite_page_redirect_received, - bool noscript_on, - bool resource_loading_hints_on, + void RunTest(content::PreviewsState committed_state, + content::PreviewsState allowed_state, bool origin_opt_out, bool save_data_enabled, - bool is_offline_preview, CoinFlipHoldbackResult coin_flip_result, std::unordered_map<PreviewsType, PreviewsEligibilityReason> eligibility_reasons, base::Optional<base::TimeDelta> navigation_restart_penalty, base::Optional<std::string> hint_version_string) { - committed_preview_ = committed_preview; + committed_state_ = committed_state; allowed_state_ = allowed_state; - lite_page_received_ = lite_page_received; - lite_page_redirect_received_ = lite_page_redirect_received; - noscript_on_ = noscript_on; - resource_loading_hints_on_ = resource_loading_hints_on; origin_opt_out_ = origin_opt_out; save_data_enabled_ = save_data_enabled; - is_offline_preview_ = is_offline_preview; coin_flip_result_ = coin_flip_result; eligibility_reasons_ = eligibility_reasons; navigation_restart_penalty_ = navigation_restart_penalty; hint_version_string_ = hint_version_string; auto navigation = content::NavigationSimulator::CreateBrowserInitiated( GURL(kDefaultTestUrl), web_contents()); - if (is_offline_preview_) + if (committed_state == content::OFFLINE_PAGE_ON) navigation->SetContentsMimeType("multipart/related"); navigation->Commit(); } - void ValidateUKM(bool lite_page_expected, - bool lite_page_redirect_expected, - bool noscript_expected, - bool resource_loading_hints_expected, + void ValidateUKM(content::PreviewsState expected_recorded_previews, int opt_out_value, bool origin_opt_out_expected, bool save_data_enabled_expected, - bool offline_preview_expected, bool previews_likely_expected, CoinFlipHoldbackResult coin_flip_result_expected, std::unordered_map<PreviewsType, PreviewsEligibilityReason> @@ -229,10 +168,8 @@ base::Optional<base::TimeDelta> navigation_restart_penalty, base::Optional<int64_t> hint_generation_timestamp, base::Optional<int> hint_source) { - ValidatePreviewsUKM(lite_page_expected, lite_page_redirect_expected, - noscript_expected, resource_loading_hints_expected, - opt_out_value, origin_opt_out_expected, - save_data_enabled_expected, offline_preview_expected, + ValidatePreviewsUKM(expected_recorded_previews, opt_out_value, + origin_opt_out_expected, save_data_enabled_expected, previews_likely_expected, coin_flip_result_expected, eligibility_reasons, navigation_restart_penalty); ValidateOptimizationGuideUKM(hint_generation_timestamp, hint_source); @@ -246,18 +183,12 @@ protected: void RegisterObservers(page_load_metrics::PageLoadTracker* tracker) override { tracker->AddObserver(std::make_unique<TestPreviewsUKMObserver>( - committed_preview_, allowed_state_, lite_page_received_, - lite_page_redirect_received_, noscript_on_, resource_loading_hints_on_, - origin_opt_out_, save_data_enabled_, is_offline_preview_, + committed_state_, allowed_state_, origin_opt_out_, save_data_enabled_, coin_flip_result_, eligibility_reasons_, navigation_restart_penalty_, hint_version_string_)); // Data is only added to the first navigation after RunTest(). - committed_preview_ = PreviewsType::NONE; + committed_state_ = content::PREVIEWS_OFF; allowed_state_ = content::PREVIEWS_OFF; - lite_page_received_ = false; - lite_page_redirect_received_ = false; - noscript_on_ = false; - resource_loading_hints_on_ = false; origin_opt_out_ = false; coin_flip_result_ = CoinFlipHoldbackResult::kNotSet; eligibility_reasons_.clear(); @@ -267,14 +198,10 @@ private: void ValidatePreviewsUKM( - bool lite_page_expected, - bool lite_page_redirect_expected, - bool noscript_expected, - bool resource_loading_hints_expected, + content::PreviewsState expected_recorded_previews, int opt_out_value, bool origin_opt_out_expected, bool save_data_enabled_expected, - bool offline_preview_expected, bool previews_likely_expected, CoinFlipHoldbackResult coin_flip_result_expected, std::unordered_map<PreviewsType, PreviewsEligibilityReason> @@ -282,10 +209,8 @@ base::Optional<base::TimeDelta> navigation_restart_penalty) { using UkmEntry = ukm::builders::Previews; auto entries = test_ukm_recorder().GetEntriesByName(UkmEntry::kEntryName); - if (!lite_page_expected && !lite_page_redirect_expected && - !noscript_expected && !resource_loading_hints_expected && - opt_out_value == 0 && !origin_opt_out_expected && - !save_data_enabled_expected && !offline_preview_expected && + if (expected_recorded_previews == 0 && opt_out_value == 0 && + !origin_opt_out_expected && !save_data_enabled_expected && !previews_likely_expected && coin_flip_result_expected == CoinFlipHoldbackResult::kNotSet && !navigation_restart_penalty.has_value()) { @@ -293,27 +218,38 @@ return; } EXPECT_EQ(1u, entries.size()); - for (const auto* const entry : entries) { - test_ukm_recorder().ExpectEntrySourceHasUrl(entry, GURL(kDefaultTestUrl)); - EXPECT_EQ(lite_page_expected, test_ukm_recorder().EntryHasMetric( - entry, UkmEntry::klite_pageName)); - EXPECT_EQ(lite_page_redirect_expected, - test_ukm_recorder().EntryHasMetric( - entry, UkmEntry::klite_page_redirectName)); - EXPECT_EQ(noscript_expected, test_ukm_recorder().EntryHasMetric( - entry, UkmEntry::knoscriptName)); - EXPECT_EQ(resource_loading_hints_expected, - test_ukm_recorder().EntryHasMetric( - entry, UkmEntry::kresource_loading_hintsName)); - EXPECT_EQ(offline_preview_expected, - test_ukm_recorder().EntryHasMetric( - entry, UkmEntry::koffline_previewName)); - EXPECT_EQ(opt_out_value != 0, test_ukm_recorder().EntryHasMetric( - entry, UkmEntry::kopt_outName)); - if (opt_out_value != 0) { - test_ukm_recorder().ExpectEntryMetric(entry, UkmEntry::kopt_outName, - opt_out_value); - } + + const auto* const entry = entries.front(); + test_ukm_recorder().ExpectEntrySourceHasUrl(entry, GURL(kDefaultTestUrl)); + + // Collect the set of recorded previews into a PreviewsState bitmask to + // compare against the expected previews. + content::PreviewsState recorded_previews = 0; + if (test_ukm_recorder().EntryHasMetric(entry, + UkmEntry::koffline_previewName)) + recorded_previews |= content::OFFLINE_PAGE_ON; + if (test_ukm_recorder().EntryHasMetric(entry, UkmEntry::klite_pageName)) + recorded_previews |= content::SERVER_LITE_PAGE_ON; + if (test_ukm_recorder().EntryHasMetric(entry, + UkmEntry::klite_page_redirectName)) { + recorded_previews |= content::LITE_PAGE_REDIRECT_ON; + } + if (test_ukm_recorder().EntryHasMetric(entry, UkmEntry::knoscriptName)) + recorded_previews |= content::NOSCRIPT_ON; + if (test_ukm_recorder().EntryHasMetric( + entry, UkmEntry::kresource_loading_hintsName)) + recorded_previews |= content::RESOURCE_LOADING_HINTS_ON; + if (test_ukm_recorder().EntryHasMetric(entry, + UkmEntry::kdefer_all_scriptName)) + recorded_previews |= content::DEFER_ALL_SCRIPT_ON; + EXPECT_EQ(expected_recorded_previews, recorded_previews); + + EXPECT_EQ(opt_out_value != 0, test_ukm_recorder().EntryHasMetric( + entry, UkmEntry::kopt_outName)); + if (opt_out_value != 0) { + test_ukm_recorder().ExpectEntryMetric(entry, UkmEntry::kopt_outName, + opt_out_value); + } EXPECT_EQ(origin_opt_out_expected, test_ukm_recorder().EntryHasMetric( entry, UkmEntry::korigin_opt_outName)); @@ -386,7 +322,6 @@ EXPECT_FALSE(test_ukm_recorder().EntryHasMetric( entry, UkmEntry::koffline_eligibility_reasonName)); } - } } void ValidateOptimizationGuideUKM( @@ -420,15 +355,10 @@ } } - PreviewsType committed_preview_ = PreviewsType::NONE; + content::PreviewsState committed_state_ = content::PREVIEWS_OFF; content::PreviewsState allowed_state_ = content::PREVIEWS_OFF; - bool lite_page_received_ = false; - bool lite_page_redirect_received_ = false; - bool noscript_on_ = false; - bool resource_loading_hints_on_ = false; bool origin_opt_out_ = false; bool save_data_enabled_ = false; - bool is_offline_preview_ = false; std::unordered_map<PreviewsType, PreviewsEligibilityReason> eligibility_reasons_ = {}; CoinFlipHoldbackResult coin_flip_result_ = CoinFlipHoldbackResult::kNotSet; @@ -439,35 +369,28 @@ }; TEST_F(PreviewsUKMObserverTest, NoPreviewSeen) { - RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::NONE, - false /* lite_page_received */, - false /* lite_page_redirect_received */, false /* noscript_on */, - false /* resource_loading_hints_on */, false /* origin_opt_out */, - false /* save_data_enabled */, false /* is_offline_preview */, + RunTest(content::PREVIEWS_OFF /* committed_state */, + content::PREVIEWS_UNSPECIFIED /* allowed_state */, + false /* origin_opt_out */, false /* save_data_enabled */, CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_version_string */); NavigateToUntrackedUrl(); - ValidateUKM(false /* lite_page_expected */, - false /* lite_page_redirect_expected */, - false /* noscript_expected */, - false /* resource_loading_hints_expected */, - 0 /* opt_out_value */, false /* origin_opt_out_expected */, + ValidateUKM(content::PREVIEWS_UNSPECIFIED, 0 /* opt_out_value */, + false /* origin_opt_out_expected */, false /* save_data_enabled_expected */, - false /* offline_preview_expected */, false /* previews_likely */, - CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, + false /* previews_likely */, CoinFlipHoldbackResult::kNotSet, + {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_generation_timestamp */, base::nullopt /* hint_source */); } TEST_F(PreviewsUKMObserverTest, UntrackedPreviewTypeOptOut) { - RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::NONE, - false /* lite_page_received */, - false /* lite_page_redirect_received */, false /* noscript_on */, - false /* resource_loading_hints_on */, false /* origin_opt_out */, - false /* save_data_enabled */, false /* is_offline_preview */, + RunTest(content::PREVIEWS_OFF /* committed_state */, + content::PREVIEWS_UNSPECIFIED /* allowed_state */, + false /* origin_opt_out */, false /* save_data_enabled */, CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_version_string */); @@ -475,50 +398,41 @@ NavigateToUntrackedUrl(); // Opt out should not be added since we don't track this type. - ValidateUKM(false /* lite_page_expected */, - false /* lite_page_redirect_expected */, - false /* noscript_expected */, - false /* resource_loading_hints_expected */, - 0 /* opt_out_value */, false /* origin_opt_out_expected */, + ValidateUKM(content::PREVIEWS_UNSPECIFIED, 0 /* opt_out_value */, + false /* origin_opt_out_expected */, false /* save_data_enabled_expected */, - false /* offline_preview_expected */, false /* previews_likely */, - CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, + false /* previews_likely */, CoinFlipHoldbackResult::kNotSet, + {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_generation_timestamp */, base::nullopt /* hint_source */); } TEST_F(PreviewsUKMObserverTest, LitePageSeen) { - RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::NONE, - true /* lite_page_received */, - false /* lite_page_redirect_received */, false /* noscript_on */, - false /* resource_loading_hints_on */, false /* origin_opt_out */, - false /* save_data_enabled */, false /* is_offline_preview */, + RunTest(content::SERVER_LITE_PAGE_ON /* committed_state */, + content::SERVER_LITE_PAGE_ON | + content::DEFER_ALL_SCRIPT_ON /* allowed_state */, + false /* origin_opt_out */, false /* save_data_enabled */, CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_version_string */); NavigateToUntrackedUrl(); - ValidateUKM(true /* lite_page_expected */, - false /* lite_page_redirect_expected */, - false /* noscript_expected */, - false /* resource_loading_hints_expected */, - 0 /* opt_out_value */, false /* origin_opt_out_expected */, + ValidateUKM(content::SERVER_LITE_PAGE_ON, 0 /* opt_out_value */, + false /* origin_opt_out_expected */, false /* save_data_enabled_expected */, - false /* offline_preview_expected */, false /* previews_likely */, - CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, + true /* previews_likely */, CoinFlipHoldbackResult::kNotSet, + {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_generation_timestamp */, base::nullopt /* hint_source */); } TEST_F(PreviewsUKMObserverTest, LitePageOptOutChip) { - RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, - PreviewsType::LITE_PAGE, true /* lite_page_received */, - false /* lite_page_redirect_received */, false /* noscript_on */, - false /* resource_loading_hints_on */, false /* origin_opt_out */, - false /* save_data_enabled */, false /* is_offline_preview */, + RunTest(content::SERVER_LITE_PAGE_ON /* committed_state */, + content::SERVER_LITE_PAGE_ON /* allowed_state */, + false /* origin_opt_out */, false /* save_data_enabled */, CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_version_string */); @@ -526,50 +440,41 @@ observer()->BroadcastEventToObservers(PreviewsUITabHelper::OptOutEventKey()); NavigateToUntrackedUrl(); - ValidateUKM(true /* lite_page_expected */, - false /* lite_page_redirect_expected */, - false /* noscript_expected */, - false /* resource_loading_hints_expected */, - 2 /* opt_out_value */, false /* origin_opt_out_expected */, + ValidateUKM(content::SERVER_LITE_PAGE_ON, 2 /* opt_out_value */, + false /* origin_opt_out_expected */, false /* save_data_enabled_expected */, - false /* offline_preview_expected */, false /* previews_likely */, - CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, + true /* previews_likely */, CoinFlipHoldbackResult::kNotSet, + {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_generation_timestamp */, base::nullopt /* hint_source */); } TEST_F(PreviewsUKMObserverTest, LitePageRedirectSeen) { - RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::NONE, - false /* lite_page_received */, - true /* lite_page_redirect_received */, false /* noscript_on */, - false /* resource_loading_hints_on */, false /* origin_opt_out */, - false /* save_data_enabled */, false /* is_offline_preview */, + RunTest(content::LITE_PAGE_REDIRECT_ON /* committed_state */, + content::LITE_PAGE_REDIRECT_ON | + content::OFFLINE_PAGE_ON /* allowed_state */, + false /* origin_opt_out */, false /* save_data_enabled */, CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_version_string */); NavigateToUntrackedUrl(); - ValidateUKM(false /* lite_page_expected */, - true /* lite_page_redirect_expected */, - false /* noscript_expected */, - false /* resource_loading_hints_expected */, - 0 /* opt_out_value */, false /* origin_opt_out_expected */, + ValidateUKM(content::LITE_PAGE_REDIRECT_ON, 0 /* opt_out_value */, + false /* origin_opt_out_expected */, false /* save_data_enabled_expected */, - false /* offline_preview_expected */, false /* previews_likely */, - CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, + true /* previews_likely */, CoinFlipHoldbackResult::kNotSet, + {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_generation_timestamp */, base::nullopt /* hint_source */); } TEST_F(PreviewsUKMObserverTest, LitePageRedirectOptOutChip) { - RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, - PreviewsType::LITE_PAGE_REDIRECT, false /* lite_page_received */, - true /* lite_page_redirect_received */, false /* noscript_on */, - false /* resource_loading_hints_on */, false /* origin_opt_out */, - false /* save_data_enabled */, false /* is_offline_preview */, + RunTest(content::LITE_PAGE_REDIRECT_ON /* committed_state */, + content::LITE_PAGE_REDIRECT_ON /* allowed_state */, + false /* origin_opt_out */, false /* save_data_enabled */, CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_version_string */); @@ -577,49 +482,39 @@ observer()->BroadcastEventToObservers(PreviewsUITabHelper::OptOutEventKey()); NavigateToUntrackedUrl(); - ValidateUKM(false /* lite_page_expected */, - true /* lite_page_redirect_expected */, - false /* noscript_expected */, - false /* resource_loading_hints_expected */, - 2 /* opt_out_value */, false /* origin_opt_out_expected */, + ValidateUKM(content::LITE_PAGE_REDIRECT_ON, 2 /* opt_out_value */, + false /* origin_opt_out_expected */, false /* save_data_enabled_expected */, - false /* offline_preview_expected */, false /* previews_likely */, - CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, + true /* previews_likely */, CoinFlipHoldbackResult::kNotSet, + {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_generation_timestamp */, base::nullopt /* hint_source */); } TEST_F(PreviewsUKMObserverTest, NoScriptSeenWithBadVersionString) { - RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, - PreviewsType::NOSCRIPT, false /* lite_page_received */, - false /* lite_page_redirect_received */, true /* noscript_on */, - false /* resource_loading_hints_on */, false /* origin_opt_out */, - false /* save_data_enabled */, false /* is_offline_preview */, - CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, + RunTest(content::NOSCRIPT_ON /* committed_state */, + content::NOSCRIPT_ON /* allowed_state */, false /* origin_opt_out */, + false /* save_data_enabled */, CoinFlipHoldbackResult::kNotSet, + {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, "badversion"); NavigateToUntrackedUrl(); - ValidateUKM( - - false /* lite_page_expected */, false /* lite_page_redirect_expected */, - true /* noscript_expected */, false /* resource_loading_hints_expected */, - 0 /* opt_out_value */, false /* origin_opt_out_expected */, - false /* save_data_enabled_expected */, - false /* offline_preview_expected */, false /* previews_likely */, - CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, - base::nullopt /* navigation_restart_penalty */, - base::nullopt /* hint_generation_timestamp */, - base::nullopt /* hint_source */); + ValidateUKM(content::NOSCRIPT_ON, 0 /* opt_out_value */, + false /* origin_opt_out_expected */, + false /* save_data_enabled_expected */, + true /* previews_likely */, CoinFlipHoldbackResult::kNotSet, + {} /* eligibility_reasons */, + base::nullopt /* navigation_restart_penalty */, + base::nullopt /* hint_generation_timestamp */, + base::nullopt /* hint_source */); } TEST_F(PreviewsUKMObserverTest, NoScriptOptOutChip) { - RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, - PreviewsType::NOSCRIPT, false /* lite_page_received */, - false /* lite_page_redirect_received */, true /* noscript_on */, - false /* resource_loading_hints_on */, false /* origin_opt_out */, - false /* save_data_enabled */, false /* is_offline_preview */, + RunTest(content::NOSCRIPT_ON /* committed_state */, + content::PREVIEWS_UNSPECIFIED /* allowed_state */, + false /* origin_opt_out */, false /* save_data_enabled */, CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_version_string */); @@ -627,75 +522,60 @@ observer()->BroadcastEventToObservers(PreviewsUITabHelper::OptOutEventKey()); NavigateToUntrackedUrl(); - ValidateUKM( - - false /* lite_page_expected */, false /* lite_page_redirect_expected */, - true /* noscript_expected */, false /* resource_loading_hints_expected */, - 2 /* opt_out_value */, false /* origin_opt_out_expected */, - false /* save_data_enabled_expected */, - false /* offline_preview_expected */, false /* previews_likely */, - CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, - base::nullopt /* navigation_restart_penalty */, - base::nullopt /* hint_generation_timestamp */, - base::nullopt /* hint_source */); + ValidateUKM(content::NOSCRIPT_ON, 2 /* opt_out_value */, + false /* origin_opt_out_expected */, + false /* save_data_enabled_expected */, + true /* previews_likely */, CoinFlipHoldbackResult::kNotSet, + {} /* eligibility_reasons */, + base::nullopt /* navigation_restart_penalty */, + base::nullopt /* hint_generation_timestamp */, + base::nullopt /* hint_source */); } TEST_F(PreviewsUKMObserverTest, OfflinePreviewsSeen) { - RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, - PreviewsType::OFFLINE, false /* lite_page_received */, - false /* lite_page_redirect_received */, false /* noscript_on */, - false /* resource_loading_hints_on */, false /* origin_opt_out */, - false /* save_data_enabled */, true /* is_offline_preview */, + RunTest(content::OFFLINE_PAGE_ON /* committed_state */, + content::PREVIEWS_UNSPECIFIED /* allowed_state */, + false /* origin_opt_out */, false /* save_data_enabled */, CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_version_string */); NavigateToUntrackedUrl(); - ValidateUKM(false /* lite_page_expected */, - false /* lite_page_redirect_expected */, - false /* noscript_expected */, - false /* resource_loading_hints_expected */, - 0 /* opt_out_value */, false /* origin_opt_out_expected */, + ValidateUKM(content::OFFLINE_PAGE_ON, 0 /* opt_out_value */, + false /* origin_opt_out_expected */, false /* save_data_enabled_expected */, - true /* offline_preview_expected */, false /* previews_likely */, - CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, + true /* previews_likely */, CoinFlipHoldbackResult::kNotSet, + {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_generation_timestamp */, base::nullopt /* hint_source */); } TEST_F(PreviewsUKMObserverTest, ResourceLoadingHintsSeen) { - RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, - PreviewsType::RESOURCE_LOADING_HINTS, false /* lite_page_received */, - false /* lite_page_redirect_received */, false /* noscript_on */, - true /* resource_loading_hints_on */, false /* origin_opt_out */, - false /* save_data_enabled */, false /* is_offline_preview */, + RunTest(content::RESOURCE_LOADING_HINTS_ON /* committed_state */, + content::PREVIEWS_UNSPECIFIED /* allowed_state */, + false /* origin_opt_out */, false /* save_data_enabled */, CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_version_string */); NavigateToUntrackedUrl(); - ValidateUKM( - - false /* lite_page_expected */, false /* lite_page_redirect_expected */, - false /* noscript_expected */, true /* resource_loading_hints_expected */, - 0 /* opt_out_value */, false /* origin_opt_out_expected */, - false /* save_data_enabled_expected */, - false /* offline_preview_expected */, false /* previews_likely */, - CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, - base::nullopt /* navigation_restart_penalty */, - base::nullopt /* hint_generation_timestamp */, - base::nullopt /* hint_source */); + ValidateUKM(content::RESOURCE_LOADING_HINTS_ON, 0 /* opt_out_value */, + false /* origin_opt_out_expected */, + false /* save_data_enabled_expected */, + true /* previews_likely */, CoinFlipHoldbackResult::kNotSet, + {} /* eligibility_reasons */, + base::nullopt /* navigation_restart_penalty */, + base::nullopt /* hint_generation_timestamp */, + base::nullopt /* hint_source */); } TEST_F(PreviewsUKMObserverTest, ResourceLoadingHintsOptOutChip) { - RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, - PreviewsType::RESOURCE_LOADING_HINTS, false /* lite_page_received */, - false /* lite_page_redirect_received */, false /* noscript_on */, - true /* resource_loading_hints_on */, false /* origin_opt_out */, - false /* save_data_enabled */, false /* is_offline_preview */, + RunTest(content::RESOURCE_LOADING_HINTS_ON /* committed_state */, + content::PREVIEWS_UNSPECIFIED /* allowed_state */, + false /* origin_opt_out */, false /* save_data_enabled */, CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_version_string */); @@ -703,64 +583,92 @@ observer()->BroadcastEventToObservers(PreviewsUITabHelper::OptOutEventKey()); NavigateToUntrackedUrl(); - ValidateUKM( - - false /* lite_page_expected */, false /* lite_page_redirect_expected */, - false /* noscript_expected */, true /* resource_loading_hints_expected */, - 2 /* opt_out_value */, false /* origin_opt_out_expected */, - false /* save_data_enabled_expected */, - false /* offline_preview_expected */, false /* previews_likely */, - CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, - base::nullopt /* navigation_restart_penalty */, - base::nullopt /* hint_generation_timestamp */, - base::nullopt /* hint_source */); + ValidateUKM(content::RESOURCE_LOADING_HINTS_ON, 2 /* opt_out_value */, + false /* origin_opt_out_expected */, + false /* save_data_enabled_expected */, + true /* previews_likely */, CoinFlipHoldbackResult::kNotSet, + {} /* eligibility_reasons */, + base::nullopt /* navigation_restart_penalty */, + base::nullopt /* hint_generation_timestamp */, + base::nullopt /* hint_source */); } -TEST_F(PreviewsUKMObserverTest, OriginOptOut) { - RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::NONE, - false /* lite_page_received */, - false /* lite_page_redirect_received */, false /* noscript_on */, - false /* resource_loading_hints_on */, true /* origin_opt_out */, - false /* save_data_enabled */, false /* is_offline_preview */, +TEST_F(PreviewsUKMObserverTest, DeferAllScriptSeen) { + RunTest(content::DEFER_ALL_SCRIPT_ON /* committed_state */, + content::PREVIEWS_UNSPECIFIED /* allowed_state */, + false /* origin_opt_out */, false /* save_data_enabled */, CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_version_string */); NavigateToUntrackedUrl(); - ValidateUKM(false /* lite_page_expected */, - false /* lite_page_redirect_expected */, - false /* noscript_expected */, - false /* resource_loading_hints_expected */, - 0 /* opt_out_value */, true /* origin_opt_out_expected */, + ValidateUKM(content::DEFER_ALL_SCRIPT_ON, 0 /* opt_out_value */, + false /* origin_opt_out_expected */, false /* save_data_enabled_expected */, - false /* offline_preview_expected */, false /* previews_likely */, - CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, + true /* previews_likely */, CoinFlipHoldbackResult::kNotSet, + {} /* eligibility_reasons */, + base::nullopt /* navigation_restart_penalty */, + base::nullopt /* hint_generation_timestamp */, + base::nullopt /* hint_source */); +} + +TEST_F(PreviewsUKMObserverTest, DeferAllScriptOptOutChip) { + RunTest(content::DEFER_ALL_SCRIPT_ON /* committed_state */, + content::PREVIEWS_UNSPECIFIED /* allowed_state */, + false /* origin_opt_out */, false /* save_data_enabled */, + CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, + base::nullopt /* navigation_restart_penalty */, + base::nullopt /* hint_version_string */); + + observer()->BroadcastEventToObservers(PreviewsUITabHelper::OptOutEventKey()); + NavigateToUntrackedUrl(); + + ValidateUKM(content::DEFER_ALL_SCRIPT_ON, 2 /* opt_out_value */, + false /* origin_opt_out_expected */, + false /* save_data_enabled_expected */, + true /* previews_likely */, CoinFlipHoldbackResult::kNotSet, + {} /* eligibility_reasons */, + base::nullopt /* navigation_restart_penalty */, + base::nullopt /* hint_generation_timestamp */, + base::nullopt /* hint_source */); +} + +TEST_F(PreviewsUKMObserverTest, OriginOptOut) { + RunTest(content::PREVIEWS_OFF /* committed_state */, + content::PREVIEWS_UNSPECIFIED /* allowed_state */, + true /* origin_opt_out */, false /* save_data_enabled */, + CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, + base::nullopt /* navigation_restart_penalty */, + base::nullopt /* hint_version_string */); + + NavigateToUntrackedUrl(); + + ValidateUKM(content::PREVIEWS_UNSPECIFIED, 0 /* opt_out_value */, + true /* origin_opt_out_expected */, + false /* save_data_enabled_expected */, + false /* previews_likely */, CoinFlipHoldbackResult::kNotSet, + {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_generation_timestamp */, base::nullopt /* hint_source */); } TEST_F(PreviewsUKMObserverTest, DataSaverEnabled) { - RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::NONE, - false /* lite_page_received */, - false /* lite_page_redirect_received */, false /* noscript_on */, - false /* resource_loading_hints_on */, false /* origin_opt_out */, - true /* save_data_enabled */, false /* is_offline_preview */, + RunTest(content::PREVIEWS_OFF /* committed_state */, + content::PREVIEWS_UNSPECIFIED /* allowed_state */, + false /* origin_opt_out */, true /* save_data_enabled */, CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_version_string */); NavigateToUntrackedUrl(); - ValidateUKM(false /* lite_page_expected */, - false /* lite_page_redirect_expected */, - false /* noscript_expected */, - false /* resource_loading_hints_expected */, - 0 /* opt_out_value */, false /* origin_opt_out_expected */, + ValidateUKM(content::PREVIEWS_UNSPECIFIED, 0 /* opt_out_value */, + false /* origin_opt_out_expected */, true /* save_data_enabled_expected */, - false /* offline_preview_expected */, false /* previews_likely */, - CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, + false /* previews_likely */, CoinFlipHoldbackResult::kNotSet, + {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_generation_timestamp */, base::nullopt /* hint_source */); @@ -770,25 +678,19 @@ // committed so we do not consider the opt out tests here. TEST_F(PreviewsUKMObserverTest, NavigationRestartPenaltySeen) { RunTest( - content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::NONE, - false /* lite_page_received */, false /* lite_page_redirect_received */, - false /* noscript_on */, false /* resource_loading_hints_on */, + content::PREVIEWS_OFF /* committed_state */, + content::PREVIEWS_UNSPECIFIED /* allowed_state */, false /* origin_opt_out */, false /* save_data_enabled */, - false /* is_offline_preview */, CoinFlipHoldbackResult::kNotSet, - {} /* eligibility_reasons */, + CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, base::TimeDelta::FromMilliseconds(1337) /* navigation_restart_penalty */, base::nullopt /* hint_version_string */); NavigateToUntrackedUrl(); ValidateUKM( - - false /* lite_page_expected */, false /* lite_page_redirect_expected */, - false /* noscript_expected */, - false /* resource_loading_hints_expected */, 0 /* opt_out_value */, + content::PREVIEWS_UNSPECIFIED, 0 /* opt_out_value */, false /* origin_opt_out_expected */, - false /* save_data_enabled_expected */, - false /* offline_preview_expected */, false /* previews_likely */, + false /* save_data_enabled_expected */, false /* previews_likely */, CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, base::TimeDelta::FromMilliseconds(1337) /* navigation_restart_penalty */, base::nullopt /* hint_generation_timestamp */, @@ -796,24 +698,18 @@ } TEST_F(PreviewsUKMObserverTest, PreviewsLikelySet_PreCommitDecision) { - RunTest(content::OFFLINE_PAGE_ON | content::NOSCRIPT_ON /* allowed_state */, - PreviewsType::NONE, false /* lite_page_received */, - false /* lite_page_redirect_received */, false /* noscript_on */, - false /* resource_loading_hints_on */, false /* origin_opt_out */, - true /* save_data_enabled */, true /* is_offline_preview */, + RunTest(content::OFFLINE_PAGE_ON /* committed_state */, + content::OFFLINE_PAGE_ON | content::NOSCRIPT_ON /* allowed_state */, + false /* origin_opt_out */, true /* save_data_enabled */, CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_version_string */); NavigateToUntrackedUrl(); - ValidateUKM(false /* lite_page_expected */, - false /* lite_page_redirect_expected */, - false /* noscript_expected */, - false /* resource_loading_hints_expected */, - 0 /* opt_out_value */, false /* origin_opt_out_expected */, - true /* save_data_enabled_expected */, - true /* offline_preview_expected */, true /* previews_likely */, + ValidateUKM(content::OFFLINE_PAGE_ON, 0 /* opt_out_value */, + false /* origin_opt_out_expected */, + true /* save_data_enabled_expected */, true /* previews_likely */, CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_generation_timestamp */, @@ -821,74 +717,58 @@ } TEST_F(PreviewsUKMObserverTest, PreviewsLikelyNotSet_PostCommitDecision) { - RunTest(content::NOSCRIPT_ON /* allowed_state */, PreviewsType::NONE, - false /* lite_page_received */, - false /* lite_page_redirect_received */, false /* noscript_on */, - false /* resource_loading_hints_on */, false /* origin_opt_out */, - true /* save_data_enabled */, false /* is_offline_preview */, - CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, + RunTest(content::PREVIEWS_OFF /* committed_state */, + content::NOSCRIPT_ON /* allowed_state */, false /* origin_opt_out */, + true /* save_data_enabled */, CoinFlipHoldbackResult::kNotSet, + {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_version_string */); NavigateToUntrackedUrl(); - ValidateUKM(false /* lite_page_expected */, - false /* lite_page_redirect_expected */, - false /* noscript_expected */, - false /* resource_loading_hints_expected */, - 0 /* opt_out_value */, false /* origin_opt_out_expected */, + ValidateUKM(content::PREVIEWS_UNSPECIFIED, 0 /* opt_out_value */, + false /* origin_opt_out_expected */, true /* save_data_enabled_expected */, - false /* offline_preview_expected */, false /* previews_likely */, - CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, + false /* previews_likely */, CoinFlipHoldbackResult::kNotSet, + {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_generation_timestamp */, base::nullopt /* hint_source */); } TEST_F(PreviewsUKMObserverTest, PreviewsLikelyNotSet_PreviewsOff) { - RunTest(content::PREVIEWS_OFF /* allowed_state */, PreviewsType::NONE, - false /* lite_page_received */, - false /* lite_page_redirect_received */, false /* noscript_on */, - false /* resource_loading_hints_on */, false /* origin_opt_out */, - true /* save_data_enabled */, false /* is_offline_preview */, - CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, + RunTest(content::PREVIEWS_OFF /* committed_state */, + content::PREVIEWS_OFF /* allowed_state */, false /* origin_opt_out */, + true /* save_data_enabled */, CoinFlipHoldbackResult::kNotSet, + {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_version_string */); NavigateToUntrackedUrl(); - ValidateUKM(false /* lite_page_expected */, - false /* lite_page_redirect_expected */, - false /* noscript_expected */, - false /* resource_loading_hints_expected */, - 0 /* opt_out_value */, false /* origin_opt_out_expected */, + ValidateUKM(content::PREVIEWS_UNSPECIFIED, 0 /* opt_out_value */, + false /* origin_opt_out_expected */, true /* save_data_enabled_expected */, - false /* offline_preview_expected */, false /* previews_likely */, - CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, + false /* previews_likely */, CoinFlipHoldbackResult::kNotSet, + {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_generation_timestamp */, base::nullopt /* hint_source */); } TEST_F(PreviewsUKMObserverTest, CoinFlipResult_Holdback) { - RunTest(content::OFFLINE_PAGE_ON /* allowed_state */, PreviewsType::NONE, - false /* lite_page_received */, - false /* lite_page_redirect_received */, false /* noscript_on */, - false /* resource_loading_hints_on */, false /* origin_opt_out */, - true /* save_data_enabled */, true /* is_offline_preview */, + RunTest(content::OFFLINE_PAGE_ON /* committed_state */, + content::OFFLINE_PAGE_ON /* allowed_state */, + false /* origin_opt_out */, true /* save_data_enabled */, CoinFlipHoldbackResult::kHoldback, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_version_string */); NavigateToUntrackedUrl(); - ValidateUKM(false /* lite_page_expected */, - false /* lite_page_redirect_expected */, - false /* noscript_expected */, - false /* resource_loading_hints_expected */, - 0 /* opt_out_value */, false /* origin_opt_out_expected */, - true /* save_data_enabled_expected */, - true /* offline_preview_expected */, true /* previews_likely */, + ValidateUKM(content::OFFLINE_PAGE_ON, 0 /* opt_out_value */, + false /* origin_opt_out_expected */, + true /* save_data_enabled_expected */, true /* previews_likely */, CoinFlipHoldbackResult::kHoldback, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_generation_timestamp */, @@ -896,24 +776,18 @@ } TEST_F(PreviewsUKMObserverTest, CoinFlipResult_Allowed) { - RunTest(content::OFFLINE_PAGE_ON /* allowed_state */, PreviewsType::NONE, - false /* lite_page_received */, - false /* lite_page_redirect_received */, false /* noscript_on */, - false /* resource_loading_hints_on */, false /* origin_opt_out */, - true /* save_data_enabled */, true /* is_offline_preview */, + RunTest(content::OFFLINE_PAGE_ON /* committed_state */, + content::OFFLINE_PAGE_ON /* allowed_state */, + false /* origin_opt_out */, true /* save_data_enabled */, CoinFlipHoldbackResult::kAllowed, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_version_string */); NavigateToUntrackedUrl(); - ValidateUKM(false /* lite_page_expected */, - false /* lite_page_redirect_expected */, - false /* noscript_expected */, - false /* resource_loading_hints_expected */, - 0 /* opt_out_value */, false /* origin_opt_out_expected */, - true /* save_data_enabled_expected */, - true /* offline_preview_expected */, true /* previews_likely */, + ValidateUKM(content::OFFLINE_PAGE_ON, 0 /* opt_out_value */, + false /* origin_opt_out_expected */, + true /* save_data_enabled_expected */, true /* previews_likely */, CoinFlipHoldbackResult::kAllowed, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_generation_timestamp */, @@ -921,11 +795,9 @@ } TEST_F(PreviewsUKMObserverTest, LogPreviewsEligibilityReason_WithAllowed) { - RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::NONE, - false /* lite_page_received */, - false /* lite_page_redirect_received */, false /* noscript_on */, - false /* resource_loading_hints_on */, false /* origin_opt_out */, - true /* save_data_enabled */, false /* is_offline_preview */, + RunTest(content::PREVIEWS_OFF /* committed_state */, + content::PREVIEWS_UNSPECIFIED /* allowed_state */, + false /* origin_opt_out */, true /* save_data_enabled */, CoinFlipHoldbackResult::kNotSet, {{PreviewsType::OFFLINE, PreviewsEligibilityReason::BLACKLIST_UNAVAILABLE}, @@ -941,14 +813,10 @@ NavigateToUntrackedUrl(); - ValidateUKM(false /* lite_page_expected */, - false /* lite_page_redirect_expected */, - false /* noscript_expected */, - false /* resource_loading_hints_expected */, - 0 /* opt_out_value */, false /* origin_opt_out_expected */, + ValidateUKM(content::PREVIEWS_UNSPECIFIED, 0 /* opt_out_value */, + false /* origin_opt_out_expected */, true /* save_data_enabled_expected */, - false /* offline_preview_expected */, false /* previews_likely */, - CoinFlipHoldbackResult::kNotSet, + false /* previews_likely */, CoinFlipHoldbackResult::kNotSet, {{PreviewsType::OFFLINE, PreviewsEligibilityReason::BLACKLIST_UNAVAILABLE}, {PreviewsType::LITE_PAGE, @@ -962,11 +830,9 @@ } TEST_F(PreviewsUKMObserverTest, LogPreviewsEligibilityReason_NoneAllowed) { - RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::NONE, - false /* lite_page_received */, - false /* lite_page_redirect_received */, false /* noscript_on */, - false /* resource_loading_hints_on */, false /* origin_opt_out */, - true /* save_data_enabled */, false /* is_offline_preview */, + RunTest(content::PREVIEWS_OFF /* committed_state */, + content::PREVIEWS_UNSPECIFIED /* allowed_state */, + false /* origin_opt_out */, true /* save_data_enabled */, CoinFlipHoldbackResult::kNotSet, {{PreviewsType::OFFLINE, PreviewsEligibilityReason::BLACKLIST_UNAVAILABLE}, @@ -982,14 +848,10 @@ NavigateToUntrackedUrl(); - ValidateUKM(false /* lite_page_expected */, - false /* lite_page_redirect_expected */, - false /* noscript_expected */, - false /* resource_loading_hints_expected */, - 0 /* opt_out_value */, false /* origin_opt_out_expected */, + ValidateUKM(content::PREVIEWS_UNSPECIFIED, 0 /* opt_out_value */, + false /* origin_opt_out_expected */, true /* save_data_enabled_expected */, - false /* offline_preview_expected */, false /* previews_likely */, - CoinFlipHoldbackResult::kNotSet, + false /* previews_likely */, CoinFlipHoldbackResult::kNotSet, {{PreviewsType::OFFLINE, PreviewsEligibilityReason::BLACKLIST_UNAVAILABLE}, {PreviewsType::LITE_PAGE, @@ -1010,24 +872,18 @@ std::string hint_version_string; hint_version.SerializeToString(&hint_version_string); base::Base64Encode(hint_version_string, &hint_version_string); - RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::NONE, - false /* lite_page_received */, - false /* lite_page_redirect_received */, false /* noscript_on */, - false /* resource_loading_hints_on */, false /* origin_opt_out */, - true /* save_data_enabled */, false /* is_offline_preview */, + RunTest(content::PREVIEWS_OFF /* committed_state */, + content::PREVIEWS_UNSPECIFIED /* allowed_state */, + false /* origin_opt_out */, true /* save_data_enabled */, CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, hint_version_string); NavigateToUntrackedUrl(); ValidateUKM( - - false /* lite_page_expected */, false /* lite_page_redirect_expected */, - false /* noscript_expected */, - false /* resource_loading_hints_expected */, 0 /* opt_out_value */, + content::PREVIEWS_UNSPECIFIED, 0 /* opt_out_value */, false /* origin_opt_out_expected */, - true /* save_data_enabled_expected */, - false /* offline_preview_expected */, false /* previews_likely */, + true /* save_data_enabled_expected */, false /* previews_likely */, CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, 123 /* hint_generation_timestamp */, base::nullopt /* hint_source */); @@ -1041,24 +897,18 @@ std::string hint_version_string; hint_version.SerializeToString(&hint_version_string); base::Base64Encode(hint_version_string, &hint_version_string); - RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::NONE, - false /* lite_page_received */, - false /* lite_page_redirect_received */, false /* noscript_on */, - false /* resource_loading_hints_on */, false /* origin_opt_out */, - true /* save_data_enabled */, false /* is_offline_preview */, + RunTest(content::PREVIEWS_OFF /* committed_state */, + content::PREVIEWS_UNSPECIFIED /* allowed_state */, + false /* origin_opt_out */, true /* save_data_enabled */, CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, hint_version_string); NavigateToUntrackedUrl(); ValidateUKM( - - false /* lite_page_expected */, false /* lite_page_redirect_expected */, - false /* noscript_expected */, - false /* resource_loading_hints_expected */, 0 /* opt_out_value */, + content::PREVIEWS_UNSPECIFIED, 0 /* opt_out_value */, false /* origin_opt_out_expected */, - true /* save_data_enabled_expected */, - false /* offline_preview_expected */, false /* previews_likely */, + true /* save_data_enabled_expected */, false /* previews_likely */, CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_generation_timestamp */, 1 /* hint_source */); @@ -1066,147 +916,162 @@ TEST_F(PreviewsUKMObserverTest, LogOptimizationGuideHintVersion_NotActuallyAVersionProto) { - RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::NONE, - false /* lite_page_received */, - false /* lite_page_redirect_received */, false /* noscript_on */, - false /* resource_loading_hints_on */, false /* origin_opt_out */, - true /* save_data_enabled */, false /* is_offline_preview */, + RunTest(content::PREVIEWS_OFF /* committed_state */, + content::PREVIEWS_UNSPECIFIED /* allowed_state */, + false /* origin_opt_out */, true /* save_data_enabled */, CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, "notahintversion"); NavigateToUntrackedUrl(); - ValidateUKM(false /* lite_page_expected */, - false /* lite_page_redirect_expected */, - false /* noscript_expected */, - false /* resource_loading_hints_expected */, - 0 /* opt_out_value */, false /* origin_opt_out_expected */, + ValidateUKM(content::PREVIEWS_UNSPECIFIED, 0 /* opt_out_value */, + false /* origin_opt_out_expected */, true /* save_data_enabled_expected */, - false /* offline_preview_expected */, false /* previews_likely */, - CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, + false /* previews_likely */, CoinFlipHoldbackResult::kNotSet, + {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_generation_timestamp */, base::nullopt /* hint_source */); } TEST_F(PreviewsUKMObserverTest, CheckReportingForHidden) { - RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::NONE, - false /* lite_page_received */, - false /* lite_page_redirect_received */, false /* noscript_on */, - false /* resource_loading_hints_on */, false /* origin_opt_out */, - true /* save_data_enabled */, false /* is_offline_preview */, + RunTest(content::PREVIEWS_OFF /* committed_state */, + content::PREVIEWS_UNSPECIFIED /* allowed_state */, + false /* origin_opt_out */, true /* save_data_enabled */, CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_version_string */); web_contents()->WasHidden(); - ValidateUKM(false /* lite_page_expected */, - false /* lite_page_redirect_expected */, - false /* noscript_expected */, - false /* resource_loading_hints_expected */, - 0 /* opt_out_value */, false /* origin_opt_out_expected */, + ValidateUKM(content::PREVIEWS_UNSPECIFIED, 0 /* opt_out_value */, + false /* origin_opt_out_expected */, true /* save_data_enabled_expected */, - false /* offline_preview_expected */, false /* previews_likely */, - CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, + false /* previews_likely */, CoinFlipHoldbackResult::kNotSet, + {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_generation_timestamp */, base::nullopt /* hint_source */); } TEST_F(PreviewsUKMObserverTest, CheckReportingForFlushMetrics) { - RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, PreviewsType::NONE, - false /* lite_page_received */, - false /* lite_page_redirect_received */, false /* noscript_on */, - false /* resource_loading_hints_on */, false /* origin_opt_out */, - true /* save_data_enabled */, false /* is_offline_preview */, + RunTest(content::PREVIEWS_OFF /* committed_state */, + content::PREVIEWS_UNSPECIFIED /* allowed_state */, + false /* origin_opt_out */, true /* save_data_enabled */, CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_version_string */); SimulateAppEnterBackground(); - ValidateUKM(false /* lite_page_expected */, - false /* lite_page_redirect_expected */, - false /* noscript_expected */, - false /* resource_loading_hints_expected */, - 0 /* opt_out_value */, false /* origin_opt_out_expected */, + ValidateUKM(content::PREVIEWS_UNSPECIFIED, 0 /* opt_out_value */, + false /* origin_opt_out_expected */, true /* save_data_enabled_expected */, - false /* offline_preview_expected */, false /* previews_likely */, - CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, + false /* previews_likely */, CoinFlipHoldbackResult::kNotSet, + {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_generation_timestamp */, base::nullopt /* hint_source */); } TEST_F(PreviewsUKMObserverTest, TestPageEndReasonUMA) { - for (int i = static_cast<int>(PreviewsType::NONE); - i < static_cast<int>(PreviewsType::LAST); i++) { - PreviewsType type = static_cast<PreviewsType>(i); - if (type == PreviewsType::DEPRECATED_AMP_REDIRECTION) - continue; - if (type == PreviewsType::DEPRECATED_LOFI) - continue; - base::HistogramTester tester; - RunTest(content::PREVIEWS_UNSPECIFIED /* allowed_state */, type, - false /* lite_page_received */, - false /* lite_page_redirect_received */, false /* noscript_on */, - false /* resource_loading_hints_on */, false /* origin_opt_out */, - false /* save_data_enabled */, false /* is_offline_preview */, + + // No preview: + RunTest(content::PREVIEWS_OFF /* committed_state */, + content::PREVIEWS_UNSPECIFIED /* allowed_state */, + false /* origin_opt_out */, false /* save_data_enabled */, CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, base::nullopt /* navigation_restart_penalty */, base::nullopt /* hint_version_string */); - NavigateToUntrackedUrl(); - - // The top level metric is not recorded on a non-preview. - if (type != PreviewsType::NONE) { - tester.ExpectUniqueSample( - "Previews.PageEndReason", - page_load_metrics::PageEndReason::END_NEW_NAVIGATION, 1); - } - tester.ExpectUniqueSample( - "Previews.PageEndReason." + GetStringNameForType(type), - page_load_metrics::PageEndReason::END_NEW_NAVIGATION, 1); - } -} - -TEST_F(PreviewsUKMObserverTest, TestPageEndReasonUMACoinFlipHoldback) { - for (int i = static_cast<int>(PreviewsType::NONE); - i < static_cast<int>(PreviewsType::LAST); i++) { - PreviewsType type = static_cast<PreviewsType>(i); - if (type == PreviewsType::DEPRECATED_AMP_REDIRECTION) - continue; - if (type == PreviewsType::DEPRECATED_LOFI) - continue; - - base::HistogramTester tester; - RunTest(content::OFFLINE_PAGE_ON /* allowed_state */, type, - false /* lite_page_received */, - false /* lite_page_redirect_received */, false /* noscript_on */, - false /* resource_loading_hints_on */, false /* origin_opt_out */, - false /* save_data_enabled */, false /* is_offline_preview */, - CoinFlipHoldbackResult::kHoldback, {} /* eligibility_reasons */, - base::nullopt /* navigation_restart_penalty */, - base::nullopt /* hint_version_string */); - - NavigateToUntrackedUrl(); - - // The top level metric is not recorded on a non-preview. - tester.ExpectTotalCount("Previews.PageEndReason", 0); - // We do not expect the individual preview PageEndReason UMAs to get - // recorded when the preview was not actually shown. - if (type != PreviewsType::NONE) { - tester.ExpectTotalCount( - "Previews.PageEndReason." + GetStringNameForType(type), 0); - } - // Since the preview is not actually shown on the holdback, we expect the - // NONE-variant to be recorded. tester.ExpectUniqueSample( "Previews.PageEndReason.None", page_load_metrics::PageEndReason::END_NEW_NAVIGATION, 1); - } + // The top level metric is not recorded on a non-preview. + tester.ExpectTotalCount("Previews.PageEndReason", 0); + + // Lite Page Redirect: + RunTest(content::LITE_PAGE_REDIRECT_ON /* committed_state */, + content::PREVIEWS_UNSPECIFIED /* allowed_state */, + false /* origin_opt_out */, false /* save_data_enabled */, + CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, + base::nullopt /* navigation_restart_penalty */, + base::nullopt /* hint_version_string */); + NavigateToUntrackedUrl(); + tester.ExpectUniqueSample( + "Previews.PageEndReason.LitePageRedirect", + page_load_metrics::PageEndReason::END_NEW_NAVIGATION, 1); + tester.ExpectBucketCount( + "Previews.PageEndReason", + page_load_metrics::PageEndReason::END_NEW_NAVIGATION, 1); + + // Defer All Script: + RunTest(content::DEFER_ALL_SCRIPT_ON /* committed_state */, + content::PREVIEWS_UNSPECIFIED /* allowed_state */, + false /* origin_opt_out */, false /* save_data_enabled */, + CoinFlipHoldbackResult::kNotSet, {} /* eligibility_reasons */, + base::nullopt /* navigation_restart_penalty */, + base::nullopt /* hint_version_string */); + NavigateToUntrackedUrl(); + tester.ExpectUniqueSample( + "Previews.PageEndReason.DeferAllScript", + page_load_metrics::PageEndReason::END_NEW_NAVIGATION, 1); + tester.ExpectBucketCount( + "Previews.PageEndReason", + page_load_metrics::PageEndReason::END_NEW_NAVIGATION, 2); +} + +TEST_F(PreviewsUKMObserverTest, TestPageEndReasonUMACoinFlipHoldback) { + base::HistogramTester tester; + + // No preview: + RunTest(content::PREVIEWS_OFF /* committed_state */, + content::OFFLINE_PAGE_ON /* allowed_state */, + false /* origin_opt_out */, false /* save_data_enabled */, + CoinFlipHoldbackResult::kHoldback, {} /* eligibility_reasons */, + base::nullopt /* navigation_restart_penalty */, + base::nullopt /* hint_version_string */); + NavigateToUntrackedUrl(); + tester.ExpectUniqueSample( + "Previews.PageEndReason.None", + page_load_metrics::PageEndReason::END_NEW_NAVIGATION, 1); + // The top level metric is not recorded on a non-preview. + tester.ExpectTotalCount("Previews.PageEndReason", 0); + + // Lite Page Redirect: + RunTest(content::LITE_PAGE_REDIRECT_ON /* committed_state */, + content::OFFLINE_PAGE_ON /* allowed_state */, + false /* origin_opt_out */, false /* save_data_enabled */, + CoinFlipHoldbackResult::kHoldback, {} /* eligibility_reasons */, + base::nullopt /* navigation_restart_penalty */, + base::nullopt /* hint_version_string */); + NavigateToUntrackedUrl(); + // Preview was not actually shown, so expect no PageEndReason for it. + tester.ExpectTotalCount("Previews.PageEndReason.LitePageRedirect", 0); + tester.ExpectBucketCount("Previews.PageEndReason.None", + page_load_metrics::PageEndReason::END_NEW_NAVIGATION, + 2); + tester.ExpectBucketCount("Previews.PageEndReason", + page_load_metrics::PageEndReason::END_NEW_NAVIGATION, + 0); + + // Defer All Script: + RunTest(content::DEFER_ALL_SCRIPT_ON /* committed_state */, + content::OFFLINE_PAGE_ON /* allowed_state */, + false /* origin_opt_out */, false /* save_data_enabled */, + CoinFlipHoldbackResult::kHoldback, {} /* eligibility_reasons */, + base::nullopt /* navigation_restart_penalty */, + base::nullopt /* hint_version_string */); + NavigateToUntrackedUrl(); + // Preview was not actually shown, so expect no PageEndReason for it. + tester.ExpectTotalCount("Previews.PageEndReason.DeferAllScript", 0); + tester.ExpectBucketCount("Previews.PageEndReason.None", + page_load_metrics::PageEndReason::END_NEW_NAVIGATION, + 3); + tester.ExpectBucketCount("Previews.PageEndReason", + page_load_metrics::PageEndReason::END_NEW_NAVIGATION, + 0); } } // namespace
diff --git a/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.cc index a7dc8f6..43ceab7 100644 --- a/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.cc
@@ -139,6 +139,10 @@ UkmPageLoadMetricsObserver::ObservePolicy UkmPageLoadMetricsObserver::OnCommit( content::NavigationHandle* navigation_handle, ukm::SourceId source_id) { + if (navigation_handle->IsInMainFrame()) { + largest_contentful_paint_handler_.RecordMainFrameTreeNodeId( + navigation_handle->GetFrameTreeNodeId()); + } if (navigation_handle->GetWebContents()->GetContentsMimeType() == kOfflinePreviewsMimeType) { if (!IsOfflinePreview(navigation_handle->GetWebContents())) @@ -627,16 +631,21 @@ return; const page_load_metrics::ContentfulPaintTimingInfo& paint = largest_contentful_paint_handler_.MergeMainFrameAndSubframes(); + if (!paint.IsEmpty()) { - TRACE_EVENT_INSTANT1( + TRACE_EVENT_INSTANT2( "loading", "NavStartToLargestContentfulPaint::Candidate::AllFrames::UKM", - TRACE_EVENT_SCOPE_THREAD, "data", paint.DataAsTraceValue()); + TRACE_EVENT_SCOPE_THREAD, "data", paint.DataAsTraceValue(), + "main_frame_tree_node_id", + largest_contentful_paint_handler_.MainFrameTreeNodeId()); } else { - TRACE_EVENT_INSTANT0("loading", - "NavStartToLargestContentfulPaint::" - "Invalidate::AllFrames::UKM", - TRACE_EVENT_SCOPE_THREAD); + TRACE_EVENT_INSTANT1( + "loading", + "NavStartToLargestContentfulPaint::" + "Invalidate::AllFrames::UKM", + TRACE_EVENT_SCOPE_THREAD, "main_frame_tree_node_id", + largest_contentful_paint_handler_.MainFrameTreeNodeId()); } }
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc index 46534fd..78fd90ba 100644 --- a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc +++ b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
@@ -2148,9 +2148,8 @@ auto waiter = CreatePageLoadMetricsTestWaiter(); waiter->AddPageExpectation(TimingField::kLoadEvent); waiter->AddPageExpectation(TimingField::kFirstContentfulPaint); - LocationBar* location_bar = browser()->window()->GetLocationBar(); ui_test_utils::SendToOmniboxAndSubmit( - location_bar, embedded_test_server()->GetURL("/title1.html").spec(), + browser(), embedded_test_server()->GetURL("/title1.html").spec(), base::TimeTicks::Now()); waiter->Wait();
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index cf760950e..47251c8f 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -841,9 +841,6 @@ #endif // !defined(OS_CHROMEOS) && !defined(OS_ANDROID) #if defined(OS_WIN) - { key::kWelcomePageOnOSUpgradeEnabled, - prefs::kWelcomePageOnOSUpgradeEnabled, - base::Value::Type::BOOLEAN }, { key::kChromeCleanupEnabled, prefs::kSwReporterEnabled, base::Value::Type::BOOLEAN },
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc index e1ae927..2e77e2d 100644 --- a/chrome/browser/policy/policy_browsertest.cc +++ b/chrome/browser/policy/policy_browsertest.cc
@@ -1034,10 +1034,10 @@ content::WebContents* web_contents = browser->tab_strip_model()->GetActiveWebContents(); content::TestNavigationObserver observer(web_contents); - LocationBar* location_bar = browser->window()->GetLocationBar(); - ui_test_utils::SendToOmniboxAndSubmit(location_bar, url); - OmniboxEditModel* model = location_bar->GetOmniboxView()->model(); + ui_test_utils::SendToOmniboxAndSubmit(browser, url); observer.Wait(); + OmniboxEditModel* model = + browser->window()->GetLocationBar()->GetOmniboxView()->model(); EXPECT_TRUE(model->CurrentMatch(NULL).destination_url.is_valid()); EXPECT_EQ(GetExpectedSearchURL(expect_safe_search), web_contents->GetURL()); } @@ -1522,9 +1522,9 @@ // Verify that searching from the omnibox uses kSearchURL. chrome::FocusLocationBar(browser()); - LocationBar* location_bar = browser()->window()->GetLocationBar(); - ui_test_utils::SendToOmniboxAndSubmit(location_bar, "stuff to search for"); - OmniboxEditModel* model = location_bar->GetOmniboxView()->model(); + ui_test_utils::SendToOmniboxAndSubmit(browser(), "stuff to search for"); + OmniboxEditModel* model = + browser()->window()->GetLocationBar()->GetOmniboxView()->model(); EXPECT_TRUE(model->CurrentMatch(NULL).destination_url.is_valid()); content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); @@ -1539,7 +1539,7 @@ EXPECT_TRUE(service->GetDefaultSearchProvider()); UpdateProviderPolicy(policies); EXPECT_FALSE(service->GetDefaultSearchProvider()); - ui_test_utils::SendToOmniboxAndSubmit(location_bar, "should not work"); + ui_test_utils::SendToOmniboxAndSubmit(browser(), "should not work"); // This means that submitting won't trigger any action. EXPECT_FALSE(model->CurrentMatch(NULL).destination_url.is_valid()); EXPECT_EQ(GURL(url::kAboutBlankURL), web_contents->GetURL());
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc index 64ea7236..f2ccba3b 100644 --- a/chrome/browser/prerender/prerender_browsertest.cc +++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include <stddef.h> + #include <set> #include <string> #include <unordered_map> @@ -2332,17 +2333,6 @@ return GetLocationBar()->GetOmniboxView(); } - void WaitForAutocompleteDone(OmniboxView* omnibox_view) { - AutocompleteController* controller = - omnibox_view->model()->popup_model()->autocomplete_controller(); - while (!controller->done()) { - content::WindowedNotificationObserver ready_observer( - chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY, - content::Source<AutocompleteController>(controller)); - ready_observer.Wait(); - } - } - predictors::AutocompleteActionPredictor* GetAutocompleteActionPredictor() { Profile* profile = current_browser()->profile(); return predictors::AutocompleteActionPredictorFactory::GetForProfile( @@ -2392,7 +2382,7 @@ omnibox_view->SetUserText(base::UTF8ToUTF16( embedded_test_server()->GetURL("/empty.html?1").spec())); omnibox_view->OnAfterPossibleChange(true); - WaitForAutocompleteDone(omnibox_view); + ui_test_utils::WaitForAutocompleteDone(current_browser()); // Fake an omnibox prerender for a different URL. std::unique_ptr<TestPrerender> prerender =
diff --git a/chrome/browser/previews/defer_all_script_browsertest.cc b/chrome/browser/previews/defer_all_script_browsertest.cc index 8b6e69d9..2037eee 100644 --- a/chrome/browser/previews/defer_all_script_browsertest.cc +++ b/chrome/browser/previews/defer_all_script_browsertest.cc
@@ -302,7 +302,6 @@ test_ukm_recorder.ExpectEntryMetric(entry, UkmEntry::kcoin_flip_resultName, 2); test_ukm_recorder.ExpectEntryMetric(entry, UkmEntry::kpreviews_likelyName, 1); - // TODO(dougarnett): Verify preview type not set once ukm support landed. - // test_ukm_recorder.ExpectEntryMetric( - // entry, UkmEntry::kdefer_all_scriptName, false); + test_ukm_recorder.ExpectEntryMetric(entry, UkmEntry::kdefer_all_scriptName, + true); }
diff --git a/chrome/browser/previews/previews_prober.cc b/chrome/browser/previews/previews_prober.cc index 8ed87f1a..66aef53 100644 --- a/chrome/browser/previews/previews_prober.cc +++ b/chrome/browser/previews/previews_prober.cc
@@ -21,6 +21,13 @@ namespace { +std::string NameForClient(PreviewsProber::ClientName name) { + switch (name) { + case PreviewsProber::ClientName::kLitepages: + return "litepages"; + } +} + std::string HttpMethodToString(PreviewsProber::HttpMethod http_method) { switch (http_method) { case PreviewsProber::HttpMethod::kGet: @@ -57,7 +64,7 @@ PreviewsProber::PreviewsProber( Delegate* delegate, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - const std::string& name, + const ClientName name, const GURL& url, const HttpMethod http_method, const net::HttpRequestHeaders headers, @@ -76,7 +83,7 @@ PreviewsProber::PreviewsProber( Delegate* delegate, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - const std::string& name, + const ClientName name, const GURL& url, const HttpMethod http_method, const net::HttpRequestHeaders headers, @@ -84,7 +91,7 @@ const TimeoutPolicy& timeout_policy, const base::TickClock* tick_clock) : delegate_(delegate), - name_(name), + name_(NameForClient(name)), url_(url), http_method_(http_method), headers_(headers),
diff --git a/chrome/browser/previews/previews_prober.h b/chrome/browser/previews/previews_prober.h index 3c6e5c1a..6476e45 100644 --- a/chrome/browser/previews/previews_prober.h +++ b/chrome/browser/previews/previews_prober.h
@@ -51,6 +51,14 @@ std::unique_ptr<std::string> body) = 0; }; + // Callers who wish to use this class should add a value to this enum. This + // 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, + }; + // This enum describes the different algorithms that can be used to calculate // a time delta between probe events like retries or timeout ttl. enum class Backoff { @@ -108,7 +116,7 @@ PreviewsProber( Delegate* delegate, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - const std::string& name, + ClientName name, const GURL& url, HttpMethod http_method, const net::HttpRequestHeaders headers, @@ -134,7 +142,7 @@ PreviewsProber( Delegate* delegate, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - const std::string& name, + ClientName name, const GURL& url, HttpMethod http_method, const net::HttpRequestHeaders headers,
diff --git a/chrome/browser/previews/previews_prober_browsertest.cc b/chrome/browser/previews/previews_prober_browsertest.cc index 443de74..d962b40 100644 --- a/chrome/browser/previews/previews_prober_browsertest.cc +++ b/chrome/browser/previews/previews_prober_browsertest.cc
@@ -22,7 +22,6 @@ #include "services/service_manager/public/cpp/connector.h" namespace { -const char kName[] = "testing"; void WaitForCompletedProbe(PreviewsProber* prober) { while (true) { @@ -130,8 +129,9 @@ PreviewsProber::TimeoutPolicy timeout_policy; PreviewsProber prober(&delegate, browser()->profile()->GetURLLoaderFactory(), - kName, url, PreviewsProber::HttpMethod::kGet, headers, - retry_policy, timeout_policy); + PreviewsProber::ClientName::kLitepages, url, + PreviewsProber::HttpMethod::kGet, headers, retry_policy, + timeout_policy); prober.SendNowIfInactive(); WaitForCompletedProbe(&prober); @@ -150,8 +150,9 @@ timeout_policy.base_timeout = base::TimeDelta::FromMilliseconds(1); PreviewsProber prober(&delegate, browser()->profile()->GetURLLoaderFactory(), - kName, url, PreviewsProber::HttpMethod::kGet, headers, - retry_policy, timeout_policy); + PreviewsProber::ClientName::kLitepages, url, + PreviewsProber::HttpMethod::kGet, headers, retry_policy, + timeout_policy); prober.SendNowIfInactive(); WaitForCompletedProbe(&prober); @@ -166,8 +167,9 @@ PreviewsProber::TimeoutPolicy timeout_policy; PreviewsProber prober(&delegate, browser()->profile()->GetURLLoaderFactory(), - kName, url, PreviewsProber::HttpMethod::kGet, headers, - retry_policy, timeout_policy); + PreviewsProber::ClientName::kLitepages, url, + PreviewsProber::HttpMethod::kGet, headers, retry_policy, + timeout_policy); SimulateNetworkChange(network::mojom::ConnectionType::CONNECTION_4G); WaitForCompletedProbe(&prober);
diff --git a/chrome/browser/previews/previews_prober_unittest.cc b/chrome/browser/previews/previews_prober_unittest.cc index 8f312b9..ce36be51 100644 --- a/chrome/browser/previews/previews_prober_unittest.cc +++ b/chrome/browser/previews/previews_prober_unittest.cc
@@ -18,7 +18,6 @@ namespace { const GURL kTestUrl("https://test.com"); -const char kName[] = "testing"; } // namespace class TestDelegate : public PreviewsProber::Delegate { @@ -48,7 +47,7 @@ TestPreviewsProber( PreviewsProber::Delegate* delegate, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - const std::string& name, + const PreviewsProber::ClientName name, const GURL& url, const HttpMethod http_method, const net::HttpRequestHeaders headers, @@ -100,7 +99,8 @@ net::HttpRequestHeaders headers; headers.SetHeader("X-Testing", "Hello world"); return std::make_unique<TestPreviewsProber>( - delegate, test_shared_loader_factory_, kName, kTestUrl, + delegate, test_shared_loader_factory_, + PreviewsProber::ClientName::kLitepages, kTestUrl, PreviewsProber::HttpMethod::kGet, headers, retry_policy, timeout_policy, thread_bundle_.GetMockTickClock()); }
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc index 19386646..0ccf7965 100644 --- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc +++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -29,8 +29,8 @@ #include "chrome/browser/download/download_service_factory.h" #include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/engagement/site_engagement_service_factory.h" -#include "chrome/browser/favicon/favicon_request_handler_factory.h" #include "chrome/browser/favicon/favicon_service_factory.h" +#include "chrome/browser/favicon/history_ui_favicon_request_handler_factory.h" #include "chrome/browser/feature_engagement/tracker_factory.h" #include "chrome/browser/google/google_search_domain_mixing_metrics_emitter_factory.h" #include "chrome/browser/google/google_url_tracker_factory.h" @@ -274,7 +274,7 @@ extensions::VerifyTrustAPI::GetFactoryInstance(); #endif FaviconServiceFactory::GetInstance(); - FaviconRequestHandlerFactory::GetInstance(); + HistoryUiFaviconRequestHandlerFactory::GetInstance(); #if BUILDFLAG(ENABLE_LEGACY_DESKTOP_IN_PRODUCT_HELP) feature_engagement::BookmarkTrackerFactory::GetInstance(); feature_engagement::IncognitoWindowTrackerFactory::GetInstance();
diff --git a/chrome/browser/resources/chromeos/autoclick/autoclick.js b/chrome/browser/resources/chromeos/autoclick/autoclick.js index c0711b1..16e4a268 100644 --- a/chrome/browser/resources/chromeos/autoclick/autoclick.js +++ b/chrome/browser/resources/chromeos/autoclick/autoclick.js
@@ -10,13 +10,23 @@ const AUTOCLICK_FOCUS_RING_COLOR = '#aac9fa'; /** + * The amount of time to wait before hiding the focus rings from the display. + * @private {number} + * @const + */ +const AUTOCLICK_FOCUS_RING_DISPLAY_TIME_MS = 250; + +/** * Class to manage Automatic Clicks' interaction with the accessibility tree. */ class Autoclick { - constructor() { - console.log('Autoclick is enabled.'); - - + constructor(blinkFocusRings) { + /** + * Whether to blink the focus rings. Disabled during tests due to + * complications with callbacks. + * @private {boolean} + */ + this.blinkFocusRings_ = blinkFocusRings; /** * @private {chrome.automation.AutomationNode} @@ -53,6 +63,8 @@ * @private */ setFocusRings_(rects) { + // TODO(katie): Add a property to FocusRingInfo to set FocusRingBehavior + // to fade out. chrome.accessibilityPrivate.setFocusRings([{ rects: rects, type: chrome.accessibilityPrivate.FocusType.SOLID, @@ -97,8 +109,26 @@ } if (!node.location) return; - this.setFocusRings_([node.location]); - chrome.accessibilityPrivate.onScrollableBoundsForPointFound(node.location); + let bounds = node.location; + this.setFocusRings_([bounds]); + if (this.blinkFocusRings_) { + // Blink the focus ring briefly per UX spec, using timeouts to turn it + // off, on, and off again. The focus ring is only used to show the user + // where the scroll might occur, but is not persisted after the blink. + // Turn off after 500 ms. + setTimeout(() => { + this.setFocusRings_([]); + }, AUTOCLICK_FOCUS_RING_DISPLAY_TIME_MS * 2); + // Back on after an additional 250 ms. + setTimeout(() => { + this.setFocusRings_([bounds]); + }, AUTOCLICK_FOCUS_RING_DISPLAY_TIME_MS * 3); + // And off after another 500 ms. + setTimeout(() => { + this.setFocusRings_([]); + }, AUTOCLICK_FOCUS_RING_DISPLAY_TIME_MS * 5); + } + chrome.accessibilityPrivate.onScrollableBoundsForPointFound(bounds); } /** @@ -114,4 +144,4 @@ } // Initialize the Autoclick extension. -let autoclick = new Autoclick(); \ No newline at end of file +let autoclick = new Autoclick(true /* blink focus rings */);
diff --git a/chrome/browser/resources/chromeos/autoclick/autoclick_test.extjs b/chrome/browser/resources/chromeos/autoclick/autoclick_test.extjs index 720ae33..b381083 100644 --- a/chrome/browser/resources/chromeos/autoclick/autoclick_test.extjs +++ b/chrome/browser/resources/chromeos/autoclick/autoclick_test.extjs
@@ -15,7 +15,7 @@ chrome.accessibilityPrivate = this.mockAccessibilityPrivate; // Re-initialize Autoclick with mock AccessibilityPrivate API. - autoclick = new Autoclick(); + autoclick = new Autoclick(false /* do not blink focus rings */); } AutoclickE2ETest.prototype = { @@ -170,4 +170,4 @@ // TODO(crbug.com/978163): Add tests for when the scrollable area is scrolled // all the way up or down, left or right. Add tests for nested scrollable areas. // Add tests for root types like toolbar, dialog, and window to ensure -// we don't break boundaries when searching for scroll bars. \ No newline at end of file +// we don't break boundaries when searching for scroll bars.
diff --git a/chrome/browser/resources/chromeos/camera/src/js/mojo/imagecapture.js b/chrome/browser/resources/chromeos/camera/src/js/mojo/imagecapture.js index 36da568..2fad22c 100644 --- a/chrome/browser/resources/chromeos/camera/src/js/mojo/imagecapture.js +++ b/chrome/browser/resources/chromeos/camera/src/js/mojo/imagecapture.js
@@ -77,10 +77,11 @@ /** * Gets the data from Camera metadata by its tag. * @param {cros.mojom.CameraMetadata} metadata Camera metadata from which to - * query the data. + * query the data. * @param {cros.mojom.CameraMetadataTag} tag Camera metadata tag to query for. * @return {Array<Object>} An array containing elements whose types correspond - * to the format of input |tag|. If nothing is found, returns an empty array. + * to the format of input |tag|. If nothing is found, returns an empty + * array. * @private */ cca.mojo.getMetadataData_ = function(metadata, tag) { @@ -201,17 +202,13 @@ /** * Gets supported photo resolutions for specific camera. * @param {string} deviceId The renderer-facing device Id of the target camera - * which could be retrieved from MediaDeviceInfo.deviceId. + * which could be retrieved from MediaDeviceInfo.deviceId. * @return {Promise<Array<Object>>} Promise of supported resolutions. Each - * photo resolution is represented as [width, height]. + * photo resolution is represented as [width, height]. */ cca.mojo.getPhotoResolutions = function(deviceId) { const formatBlob = 33; const typeOutputStream = 0; - const formatIndex = 0; - const widthIndex = 1; - const heightIndex = 2; - const typeIndex = 3; const numElementPerEntry = 4; return cca.mojo.MojoInterface.getProxy().getCameraInfo(deviceId).then( @@ -229,17 +226,11 @@ } let supportedResolutions = []; - for (let configIdx = 0, configBase = 0; - configBase < streamConfigs.length; - configIdx++, configBase = configIdx * numElementPerEntry) { - const format = streamConfigs[configBase + formatIndex]; - if (format === formatBlob) { - const type = streamConfigs[configBase + typeIndex]; - if (type === typeOutputStream) { - const width = streamConfigs[configBase + widthIndex]; - const height = streamConfigs[configBase + heightIndex]; - supportedResolutions.push([width, height]); - } + for (let i = 0; i < streamConfigs.length; i += numElementPerEntry) { + const [format, width, height, type] = + streamConfigs.slice(i, i + numElementPerEntry); + if (format === formatBlob && type === typeOutputStream) { + supportedResolutions.push([width, height]); } } return supportedResolutions; @@ -249,18 +240,14 @@ /** * Gets supported video configurations for specific camera. * @param {string} deviceId The renderer-facing device Id of the target camera - * which could be retrieved from MediaDeviceInfo.deviceId. + * which could be retrieved from MediaDeviceInfo.deviceId. * @return {Promise<Array<Object>>} Promise of supported video configurations. - * Each configuration is represented as [width, height, fps]. + * Each configuration is represented as [width, height, maxFps]. */ cca.mojo.getVideoConfigs = function(deviceId) { // Currently we use YUV format for both recording and previewing on Chrome. const formatYuv = 35; const oneSecondInNs = 1000000000; - const formatIndex = 0; - const widthIndex = 1; - const heightIndex = 2; - const durationIndex = 3; const numElementPerEntry = 4; return cca.mojo.MojoInterface.getProxy().getCameraInfo(deviceId).then( @@ -279,17 +266,13 @@ } let supportedConfigs = []; - for (let configIdx = 0, configBase = 0; - configBase < minFrameDurationConfigs.length; - configIdx++, configBase = configIdx * numElementPerEntry) { - const format = minFrameDurationConfigs[configBase + formatIndex]; + for (let i = 0; i < minFrameDurationConfigs.length; + i += numElementPerEntry) { + const [format, width, height, minDuration] = + minFrameDurationConfigs.slice(i, i + numElementPerEntry); if (format === formatYuv) { - const width = minFrameDurationConfigs[configBase + widthIndex]; - const height = minFrameDurationConfigs[configBase + heightIndex]; - const fps = Math.round( - oneSecondInNs / - minFrameDurationConfigs[configBase + durationIndex]); - supportedConfigs.push([width, height, fps]); + const maxFps = Math.round(oneSecondInNs / minDuration); + supportedConfigs.push([width, height, maxFps]); } } return supportedConfigs; @@ -299,7 +282,7 @@ /** * Gets camera facing for given device. * @param {string} deviceId The renderer-facing device Id of the target camera - * which could be retrieved from MediaDeviceInfo.deviceId. + * which could be retrieved from MediaDeviceInfo.deviceId. * @return {Promise<cros.mojom.CameraFacing>} Promise of device facing. */ cca.mojo.getCameraFacing = function(deviceId) { @@ -308,3 +291,86 @@ return cameraInfo.facing; }); }; + +/** + * Gets supported fps ranges for specific camera. + * @param {string} deviceId The renderer-facing device Id of the target camera + * which could be retrieved from MediaDeviceInfo.deviceId. + * @return {Promise<Array<Object>>} Promise of supported fps ranges. Each range + * is represented as [min, max]. + */ +cca.mojo.getSupportedFpsRanges = function(deviceId) { + const numElementPerEntry = 2; + + return cca.mojo.MojoInterface.getProxy().getCameraInfo(deviceId).then( + ({cameraInfo}) => { + const staticMetadata = cameraInfo.staticCameraCharacteristics; + const availableFpsRanges = cca.mojo.getMetadataData_( + staticMetadata, + cros.mojom.CameraMetadataTag + .ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES); + // The data of |availableFpsRanges| looks like: + // availableFpsRanges: [RANGE_1_MIN, RANGE_1_MAX, + // RANGE_2_MIN, RANGE_2_MAX, ...] + if (availableFpsRanges.length % numElementPerEntry != 0) { + throw new Error('Unexpected length of available fps range configs'); + } + + let supportedFpsRanges = []; + for (let i = 0; i < availableFpsRanges.length; + i += numElementPerEntry) { + const [rangeMin, rangeMax] = + availableFpsRanges.slice(i, i + numElementPerEntry); + supportedFpsRanges.push([rangeMin, rangeMax]); + } + return supportedFpsRanges; + }); +}; + +/** + * Gets user media with custom negotiation through CrosImageCapture API, + * such as frame rate range negotiation. + * @param {string} deviceId The renderer-facing device Id of the target camera + * which could be retrieved from MediaDeviceInfo.deviceId. + * @param {MediaStreamConstraints} constraints The constraints that would be + * passed to get user media. If frame rate range negotiation is needed, the + * caller should either set exact field or set both min and max fields for + * frame rate property. + * @return {Promise<MediaStream>} Promise of the MediaStream that returned from + * MediaDevices.getUserMedia(). + */ +cca.mojo.getUserMedia = function(deviceId, constraints) { + let streamWidth = 0; + let streamHeight = 0; + let minFrameRate = 0; + let maxFrameRate = 0; + + if (constraints && constraints.video && constraints.video.frameRate) { + const frameRate = constraints.video.frameRate; + if (frameRate.exact) { + minFrameRate = frameRate.exact; + maxFrameRate = frameRate.exact; + } else if (frameRate.min && frameRate.max) { + minFrameRate = frameRate.min; + maxFrameRate = frameRate.max; + } + + streamWidth = constraints.video.width; + streamHeight = constraints.video.height; + } + + try { + return cca.mojo.MojoInterface.getProxy() + .setFpsRange( + deviceId, streamWidth, streamHeight, minFrameRate, maxFrameRate) + .then(({isSuccess}) => { + if (!isSuccess) { + console.error('Failed to negotiate the frame rate range.'); + } + return navigator.mediaDevices.getUserMedia(constraints); + }); + } catch (e) { + console.error(e); + } + return navigator.mediaDevices.getUserMedia(constraints); +};
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/main.html b/chrome/browser/resources/chromeos/wallpaper_manager/main.html index 13dcbbd..2b78418 100644 --- a/chrome/browser/resources/chromeos/wallpaper_manager/main.html +++ b/chrome/browser/resources/chromeos/wallpaper_manager/main.html
@@ -158,7 +158,8 @@ </div> <div id="top-header"> <div class="top-header-contents"> - <div id="cancel-preview-wallpaper" class="preview-option"></div> + <div id="cancel-preview-wallpaper" i18n-values="title:backButton" + class="preview-option"></div> <div id="image-title"></div> <div class="divider"></div> <div id="wallpaper-description"></div>
diff --git a/chrome/browser/resources/local_ntp/customize.js b/chrome/browser/resources/local_ntp/customize.js index 39a85f6..10079a0 100644 --- a/chrome/browser/resources/local_ntp/customize.js +++ b/chrome/browser/resources/local_ntp/customize.js
@@ -200,10 +200,10 @@ customize.builtTiles = false; /** - * The background image tile that was selected by the user. - * @type {?Element} + * The default title for the richer picker. + * @type {string} */ -customize.selectedBackgroundTile = null; +customize.richerPicker_defaultTitle = ''; /** * Called when the error notification should be shown. @@ -218,39 +218,53 @@ customize.hideCustomLinkNotification = null; /** - * The currently selected submenu (i.e. Background, Shortcuts, etc.) in the - * richer picker. Corresponds to the submenu's button element in the sidebar. - * @type {?Element} + * The currently active Background submenu. This can be the collections page or + * a collection's image menu. Defaults to the collections page. + * @type {Object} */ -customize.richerPicker_selectedSubmenu = null; +customize.richerPicker_openBackgroundSubmenu = { + menuId: customize.IDS.BACKGROUNDS_MENU, + title: '', +}; + +/** + * The currently selected submenu (i.e. Background, Shortcuts, etc.) in the + * richer picker. + * @type {Object} + */ +customize.richerPicker_selectedSubmenu = { + menuButton: null, // The submenu's button element in the sidebar. + menu: null, // The submenu's menu element. + // The submenu's title. Will usually be |customize.richerPicker_defaultTitle| + // unless this is a background collection's image menu. + title: '', +}; + +/** + * The currently selected options in the customization menu. + * @type {Object} + */ +customize.selectedOptions = { + background: null, // Contains the background image tile. + // Contains the selected shortcut type's DOM element, i.e. either custom links + // or most visited. + shortcutType: null, + shortcutsAreHidden: false, + color: null, // Contains the selected color tile's DOM element. +}; /** * The preselected options for Shortcuts in the richer picker. * @type {Object} */ customize.preselectedShortcutOptions = { - // Contains the selected type's DOM element, i.e. either custom links or most visited. + // Contains the selected type's DOM element, i.e. either custom links or most + // visited. shortcutType: null, isHidden: false, }; /** - * The currently selected options for Shortcuts in the richer picker. - * @type {Object} - */ -customize.selectedShortcutOptions = { - // Contains the preselected type's DOM element, i.e. either custom links or most visited. - shortcutType: null, - isHidden: false, -}; - -/** - * The currently selected option in the Colors menu. - * @type {?Element} - */ -customize.selectedColorTile = null; - -/** * Whether tiles for Colors menu already loaded. * @type {boolean} */ @@ -339,7 +353,7 @@ customize.unselectTile = function() { $(customize.IDS.DONE).disabled = true; - customize.selectedBackgroundTile = null; + customize.selectedOptions.background = null; $(customize.IDS.DONE).tabIndex = -1; }; @@ -358,37 +372,79 @@ /** * Apply selected styling to |menuButton| and make corresponding |menu| visible. - * @param {?Element} menuButton The button element to apply styling to. + * If |title| is not specified, the default title will be used. + * @param {?Element} menuButton The sidebar button element to apply styling to. * @param {?Element} menu The submenu element to apply styling to. + * @param {string=} title The submenu's title. */ -customize.richerPicker_selectSubmenu = function(menuButton, menu) { +customize.richerPicker_showSubmenu = function(menuButton, menu, title = '') { if (!menuButton || !menu) { return; } - customize.richerPicker_selectedSubmenu = menuButton; + + customize.richerPicker_hideOpenSubmenu(); + + if (!title) { // Use the default title if not specified. + title = customize.richerPicker_defaultTitle; + } + + // Save this as the currently open submenu. + customize.richerPicker_selectedSubmenu.menuButton = menuButton; + customize.richerPicker_selectedSubmenu.menu = menu; + customize.richerPicker_selectedSubmenu.title = title; + menuButton.classList.toggle(customize.CLASSES.SELECTED, true); menu.classList.toggle(customize.CLASSES.MENU_SHOWN, true); + $(customize.IDS.MENU_TITLE).textContent = title; + + // Indicate if this is a Background collection's image menu, which will enable + // the back button. + $(customize.IDS.CUSTOMIZATION_MENU) + .classList.toggle( + customize.CLASSES.ON_IMAGE_MENU, + menu.id === customize.IDS.BACKGROUNDS_IMAGE_MENU); +}; + +/** + * Hides the currently open submenu if any. + */ +customize.richerPicker_hideOpenSubmenu = function() { + if (!customize.richerPicker_selectedSubmenu.menuButton) { + return; // No submenu is open. + } + + customize.richerPicker_selectedSubmenu.menuButton.classList.toggle( + customize.CLASSES.SELECTED, false); + customize.richerPicker_selectedSubmenu.menu.classList.toggle( + customize.CLASSES.MENU_SHOWN, false); + $(customize.IDS.MENU_TITLE).textContent = customize.richerPicker_defaultTitle; + + customize.richerPicker_selectedSubmenu.menuButton = null; + customize.richerPicker_selectedSubmenu.menu = null; + customize.richerPicker_selectedSubmenu.title = + customize.richerPicker_defaultTitle; }; /** * Remove image tiles and maybe swap back to main background menu. - * @param {boolean} showMenu Whether the main background menu should be shown. */ -customize.richerPicker_resetImageMenu = function(showMenu) { +customize.richerPicker_resetImageMenu = function() { const backgroundMenu = $(customize.IDS.BACKGROUNDS_MENU); const imageMenu = $(customize.IDS.BACKGROUNDS_IMAGE_MENU); const menu = $(customize.IDS.CUSTOMIZATION_MENU); const menuTitle = $(customize.IDS.MENU_TITLE); imageMenu.innerHTML = ''; - imageMenu.classList.toggle(customize.CLASSES.MENU_SHOWN, false); - menuTitle.textContent = menuTitle.dataset.mainTitle; menu.classList.toggle(customize.CLASSES.ON_IMAGE_MENU, false); - backgroundMenu.classList.toggle(customize.CLASSES.MENU_SHOWN, showMenu); + customize.richerPicker_showSubmenu( + $(customize.IDS.BACKGROUNDS_BUTTON), backgroundMenu); + customize.richerPicker_openBackgroundSubmenu.menuId = + customize.IDS.BACKGROUNDS_MENU; + customize.richerPicker_openBackgroundSubmenu.title = ''; backgroundMenu.scrollTop = 0; customize.richerPicker_deselectBackgroundTile( - customize.selectedBackgroundTile); + customize.selectedOptions.background); }; /** @@ -404,14 +460,13 @@ }; /** - * Close and reset the dialog, and set the background. + * Close and reset the dialog if this is not the richer picker, and set the + * background. * @param {string} url The url of the selected background. */ customize.setBackground = function( url, attributionLine1, attributionLine2, attributionActionUrl) { - if (configData.richerPicker) { - customize.richerPicker_closeCustomizationMenu(); - } else { + if (!configData.richerPicker) { customize.closeCollectionDialog($(customize.IDS.MENU)); } window.chrome.embeddedSearch.newTabPage.setBackgroundURLWithAttributions( @@ -422,13 +477,19 @@ * Apply selected shortcut options. */ customize.richerPicker_setShortcutOptions = function() { - if (customize.preselectedShortcutOptions.shortcutType !== - customize.selectedShortcutOptions.shortcutType) { - chrome.embeddedSearch.newTabPage.toggleMostVisitedOrCustomLinks(); + const shortcutTypeChanged = + customize.preselectedShortcutOptions.shortcutType !== + customize.selectedOptions.shortcutType; + if (customize.preselectedShortcutOptions.shortcutsAreHidden !== + customize.selectedOptions.shortcutsAreHidden) { + // Only trigger a notification if |toggleMostVisitedOrCustomLinks| will not + // be called immediately after. Successive |onmostvisitedchange| events can + // interfere with each other. + chrome.embeddedSearch.newTabPage.toggleShortcutsVisibility( + !shortcutTypeChanged); } - if (customize.preselectedShortcutOptions.isHidden !== - customize.selectedShortcutOptions.isHidden) { - chrome.embeddedSearch.newTabPage.toggleShortcutsVisibility(); + if (shortcutTypeChanged) { + chrome.embeddedSearch.newTabPage.toggleMostVisitedOrCustomLinks(); } }; @@ -633,7 +694,7 @@ // In the RP the upload or default tile may be selected. if (configData.richerPicker) { customize.richerPicker_deselectBackgroundTile( - customize.selectedBackgroundTile); + customize.selectedOptions.background); } else { customize.resetSelectionDialog(); } @@ -707,10 +768,35 @@ }; /** - * Enable or disable the 'done' button. - * @param {boolean} enable True if the done button should be enabled. + * Return true if any shortcut option is selected. + * Note: Shortcut options are preselected according to current user settings. */ -customize.richerPicker_toggleDone = function(enable) { +customize.richerPicker_isShortcutOptionSelected = function() { + // Check if the currently selected options are not the preselection. + const notPreselectedType = + customize.preselectedShortcutOptions.shortcutType !== + customize.selectedOptions.shortcutType; + const notPreselectedHidden = + customize.preselectedShortcutOptions.shortcutsAreHidden !== + customize.selectedOptions.shortcutsAreHidden; + return notPreselectedType || notPreselectedHidden; +}; + +/** + * Return true if any option is selected. Used to enable the 'done' button. + */ +customize.richerPicker_isOptionSelected = function() { + return !!customize.selectedOptions.background || + !!customize.selectedOptions.color || + customize.richerPicker_isShortcutOptionSelected(); +}; + +/** + * Enable the 'done' button if any option is selected. If no option is selected, + * disable the 'done' button. + */ +customize.richerPicker_maybeToggleDone = function() { + const enable = customize.richerPicker_isOptionSelected(); $(customize.IDS.MENU_DONE).disabled = !enable; $(customize.IDS.MENU_DONE).tabIndex = enable ? 1 : 0; }; @@ -790,9 +876,9 @@ if (!tile) { return; } - customize.selectedBackgroundTile = tile; + customize.selectedOptions.background = tile; customize.richerPicker_applySelectedState(tile); - customize.richerPicker_toggleDone(true); + customize.richerPicker_maybeToggleDone(); customize.richerPicker_previewImage(tile); }; @@ -805,61 +891,47 @@ if (!tile) { return; } - customize.selectedBackgroundTile = null; + customize.selectedOptions.background = null; customize.richerPicker_removeSelectedState(tile); - customize.richerPicker_toggleDone(false); + customize.richerPicker_maybeToggleDone(); customize.richerPicker_unpreviewImage(tile); }; /** - * Enable the 'done' button if the selected shortcut options were not - * preselected. - * Note: Shortcut options are preselected according to current user settings. - */ -customize.richerPicker_maybeToggleDoneShortcuts = function() { - const notPreselectedType = - customize.preselectedShortcutOptions.shortcutType !== - customize.selectedShortcutOptions.shortcutType; - const notPreselectedHidden = customize.preselectedShortcutOptions.isHidden !== - customize.selectedShortcutOptions.isHidden; - customize.richerPicker_toggleDone(notPreselectedType || notPreselectedHidden); -}; - -/** * Handles shortcut type selection. Apply styling to a selected shortcut option * and enable the done button. * @param {?Element} shortcutType The shortcut type option's element. */ customize.richerPicker_selectShortcutType = function(shortcutType) { if (!shortcutType || - customize.selectedShortcutOptions.shortcutType === shortcutType) { + customize.selectedOptions.shortcutType === shortcutType) { return; // The option has already been selected. } // Clear the previous selection, if any. - if (customize.selectedShortcutOptions.shortcutType) { + if (customize.selectedOptions.shortcutType) { customize.richerPicker_removeSelectedState( - customize.selectedShortcutOptions.shortcutType); + customize.selectedOptions.shortcutType); } - customize.selectedShortcutOptions.shortcutType = shortcutType; + customize.selectedOptions.shortcutType = shortcutType; customize.richerPicker_applySelectedState(shortcutType); - customize.richerPicker_maybeToggleDoneShortcuts(); + customize.richerPicker_maybeToggleDone(); }; /** * Handles hide shortcuts toggle. Apply/remove styling for the toggle and * enable/disable the done button. - * @param {boolean} isHidden True if the shortcuts are hidden, i.e. the toggle + * @param {boolean} areHidden True if the shortcuts are hidden, i.e. the toggle * is on. */ -customize.richerPicker_toggleShortcutHide = function(isHidden) { +customize.richerPicker_toggleShortcutHide = function(areHidden) { // (De)select the shortcut hide option. $(customize.IDS.SHORTCUTS_HIDE) - .classList.toggle(customize.CLASSES.SELECTED, isHidden); - $(customize.IDS.SHORTCUTS_HIDE_TOGGLE).checked = isHidden; + .classList.toggle(customize.CLASSES.SELECTED, areHidden); + $(customize.IDS.SHORTCUTS_HIDE_TOGGLE).checked = areHidden; - customize.selectedShortcutOptions.isHidden = isHidden; - customize.richerPicker_maybeToggleDoneShortcuts(); + customize.selectedOptions.shortcutsAreHidden = areHidden; + customize.richerPicker_maybeToggleDone(); }; /** @@ -909,8 +981,14 @@ $(customize.IDS.MENU); if (configData.richerPicker) { - $(customize.IDS.MENU_TITLE).textContent = dialogTitle; menu.classList.toggle(customize.CLASSES.ON_IMAGE_MENU, true); + customize.richerPicker_showSubmenu( + $(customize.IDS.BACKGROUNDS_BUTTON), tileContainer, dialogTitle); + // Save the current image menu. Used to restore to when the Background + // submenu is reopened. + customize.richerPicker_openBackgroundSubmenu.menuId = + customize.IDS.BACKGROUNDS_IMAGE_MENU; + customize.richerPicker_openBackgroundSubmenu.title = dialogTitle; } else { $(customize.IDS.TITLE).textContent = dialogTitle; menu.classList.remove(customize.CLASSES.COLLECTION_DIALOG); @@ -918,17 +996,17 @@ } const tileInteraction = function(tile) { - if (customize.selectedBackgroundTile) { + if (customize.selectedOptions.background) { if (configData.richerPicker) { - const id = customize.selectedBackgroundTile.id; + const id = customize.selectedOptions.background.id; customize.richerPicker_deselectBackgroundTile( - customize.selectedBackgroundTile); + customize.selectedOptions.background); if (id === tile.id) { return; } } else { - customize.removeSelectedState(customize.selectedBackgroundTile); - if (customize.selectedBackgroundTile.id === tile.id) { + customize.removeSelectedState(customize.selectedOptions.background); + if (customize.selectedOptions.background.id === tile.id) { customize.unselectTile(); return; } @@ -939,7 +1017,7 @@ customize.richerPicker_selectBackgroundTile(tile); } else { customize.applySelectedState(tile); - customize.selectedBackgroundTile = tile; + customize.selectedOptions.background = tile; } $(customize.IDS.DONE).tabIndex = 0; @@ -957,7 +1035,7 @@ tileInteraction(event.currentTarget); } else if ( clickCount === 2 && - customize.selectedBackgroundTile === event.currentTarget) { + customize.selectedOptions.background === event.currentTarget) { customize.setBackground( event.currentTarget.dataset.url, event.currentTarget.dataset.attributionLine1, @@ -1158,64 +1236,55 @@ */ customize.richerPicker_openCustomizationMenu = function() { customize.richerPicker_resetCustomizationMenu(); - $(customize.IDS.BACKGROUNDS_MENU) - .classList.toggle(customize.CLASSES.MENU_SHOWN, true); - customize.richerPicker_selectedSubmenu = $(customize.IDS.BACKGROUNDS_BUTTON); + + customize.richerPicker_showSubmenu( + $(customize.IDS.BACKGROUNDS_BUTTON), $(customize.IDS.BACKGROUNDS_MENU)); + + customize.loadChromeBackgrounds(); + customize.loadColorTiles(); + if (!$(customize.IDS.CUSTOMIZATION_MENU).open) { + $(customize.IDS.CUSTOMIZATION_MENU).showModal(); + } }; /** * Reset the selected options in the customization menu. */ customize.richerPicker_resetSelectedOptions = function() { - if (customize.selectedBackgroundTile) { - // Reset background selection. - customize.richerPicker_removeSelectedState( - customize.selectedBackgroundTile); - customize.selectedBackgroundTile = null; - } else if (customize.selectedColorTile) { - // Reset color selection. - customize.richerPicker_removeSelectedState(customize.selectedColorTile); - customize.cancelColor(); - customize.selectedColorTile = null; - } + // Reset background selection. + customize.richerPicker_deselectBackgroundTile( + customize.selectedOptions.background); + customize.selectedOptions.background = null; + + // Reset color selection. + customize.richerPicker_removeSelectedState(customize.selectedOptions.color); + customize.selectedOptions.color = null; // Preselect the shortcut options. const shortcutType = chrome.embeddedSearch.newTabPage.isUsingMostVisited ? $(customize.IDS.SHORTCUTS_OPTION_MOST_VISITED) : $(customize.IDS.SHORTCUTS_OPTION_CUSTOM_LINKS); - const isHidden = !chrome.embeddedSearch.newTabPage.areShortcutsVisible; + const shortcutsAreHidden = + !chrome.embeddedSearch.newTabPage.areShortcutsVisible; customize.richerPicker_selectShortcutType(shortcutType); - customize.richerPicker_toggleShortcutHide(isHidden); - customize.selectedShortcutOptions.shortcutType = shortcutType; + customize.richerPicker_toggleShortcutHide(shortcutsAreHidden); + customize.selectedOptions.shortcutType = shortcutType; customize.preselectedShortcutOptions.shortcutType = shortcutType; - customize.selectedShortcutOptions.isHidden = isHidden; - customize.preselectedShortcutOptions.isHidden = isHidden; + customize.selectedOptions.shortcutsAreHidden = shortcutsAreHidden; + customize.preselectedShortcutOptions.shortcutsAreHidden = shortcutsAreHidden; }; /** * Resets the customization menu. */ customize.richerPicker_resetCustomizationMenu = function() { - // Reset the submenus. - customize.richerPicker_resetImageMenu(false); - $(customize.IDS.BACKGROUNDS_MENU) - .classList.toggle(customize.CLASSES.MENU_SHOWN, false); - $(customize.IDS.SHORTCUTS_MENU) - .classList.toggle(customize.CLASSES.MENU_SHOWN, false); - $(customize.IDS.COLORS_MENU) - .classList.toggle(customize.CLASSES.MENU_SHOWN, false); - if (customize.richerPicker_selectedSubmenu) { - customize.richerPicker_selectedSubmenu.classList.toggle( - customize.CLASSES.SELECTED, false); - customize.richerPicker_selectedSubmenu = null; - } - // Reset any selected options. customize.richerPicker_resetSelectedOptions(); - customize.richerPicker_toggleDone(false); + customize.richerPicker_resetImageMenu(); + customize.richerPicker_hideOpenSubmenu(); }; /** - * Close customization menu. + * Close and reset the customization menu. */ customize.richerPicker_closeCustomizationMenu = function() { $(customize.IDS.CUSTOMIZATION_MENU).close(); @@ -1223,6 +1292,39 @@ }; /** + * Cancel customization, revert any changes, and close the richer picker. + */ +customize.richerPicker_cancelCustomization = function() { + // Cancel any color changes. + if (customize.selectedOptions.color) { + customize.cancelColor(); + } + + customize.richerPicker_closeCustomizationMenu(); +}; + +/** + * Apply the currently selected customization options and close the richer + * picker. + */ +customize.richerPicker_applyCustomization = function() { + if (customize.selectedOptions.background) { + customize.setBackground( + customize.selectedOptions.background.dataset.url, + customize.selectedOptions.background.dataset.attributionLine1, + customize.selectedOptions.background.dataset.attributionLine2, + customize.selectedOptions.background.dataset.attributionActionUrl); + } + if (customize.richerPicker_isShortcutOptionSelected()) { + customize.richerPicker_setShortcutOptions(); + } + if (customize.selectedOptions.color) { + customize.confirmColor(); + } + customize.richerPicker_closeCustomizationMenu(); +}; + +/** * Initialize the settings menu, custom backgrounds dialogs, and custom * links menu items. Set the text and event handlers for the various * elements. @@ -1239,9 +1341,11 @@ $(customize.IDS.OPTIONS_TITLE).textContent = configData.translatedStrings.customizeBackground; - // Store the main menu title so it can be restored if needed. - $(customize.IDS.MENU_TITLE).dataset.mainTitle = - $(customize.IDS.MENU_TITLE).textContent; + if (configData.richerPicker) { + // Store the main menu title so it can be restored if needed. + customize.richerPicker_defaultTitle = + $(customize.IDS.MENU_TITLE).textContent; + } $(customize.IDS.EDIT_BG_ICON) .setAttribute( @@ -1254,11 +1358,6 @@ const editBackgroundInteraction = function() { if (configData.richerPicker) { customize.richerPicker_openCustomizationMenu(); - customize.loadChromeBackgrounds(); - customize.loadColorTiles(); - if (!$(customize.IDS.CUSTOMIZATION_MENU).open) { - $(customize.IDS.CUSTOMIZATION_MENU).showModal(); - } } else { editDialog.showModal(); } @@ -1269,11 +1368,7 @@ }; $(customize.IDS.MENU_CANCEL).onclick = function(event) { - if (customize.richerPicker_selectedSubmenu == - $(customize.IDS.COLORS_BUTTON)) { - customize.cancelColor(); - } - customize.richerPicker_closeCustomizationMenu(); + customize.richerPicker_cancelCustomization(); }; @@ -1561,7 +1656,7 @@ // Interactions with the back arrow on the image selection dialog. const backInteraction = function(event) { if (configData.richerPicker) { - customize.richerPicker_resetImageMenu(true); + customize.richerPicker_resetImageMenu(); } customize.resetSelectionDialog(); customize.showCollectionSelectionDialog(); @@ -1609,22 +1704,15 @@ if (done.disabled) { return; } - - if (customize.richerPicker_selectedSubmenu == - $(customize.IDS.COLORS_BUTTON)) { - customize.confirmColor(); - customize.richerPicker_closeCustomizationMenu(); - } else if ( - customize.richerPicker_selectedSubmenu == - $(customize.IDS.SHORTCUTS_BUTTON)) { - customize.richerPicker_setShortcutOptions(); - customize.richerPicker_closeCustomizationMenu(); - } else { + if (configData.richerPicker) { + customize.richerPicker_applyCustomization(); + } else if (customize.selectedOptions.background) { + // Also closes the customization menu. customize.setBackground( - customize.selectedBackgroundTile.dataset.url, - customize.selectedBackgroundTile.dataset.attributionLine1, - customize.selectedBackgroundTile.dataset.attributionLine2, - customize.selectedBackgroundTile.dataset.attributionActionUrl); + customize.selectedOptions.background.dataset.url, + customize.selectedOptions.background.dataset.attributionLine1, + customize.selectedOptions.background.dataset.attributionLine2, + customize.selectedOptions.background.dataset.attributionActionUrl); } }; $(customize.IDS.DONE).onclick = doneInteraction; @@ -1692,9 +1780,11 @@ }; const richerPickerOpenBackgrounds = function() { - customize.richerPicker_resetCustomizationMenu(); - customize.richerPicker_selectSubmenu( - $(customize.IDS.BACKGROUNDS_BUTTON), $(customize.IDS.BACKGROUNDS_MENU)); + // Open the previously open Background submenu, if applicable. + customize.richerPicker_showSubmenu( + $(customize.IDS.BACKGROUNDS_BUTTON), + $(customize.richerPicker_openBackgroundSubmenu.menuId), + customize.richerPicker_openBackgroundSubmenu.title); }; $(customize.IDS.BACKGROUNDS_BUTTON).onclick = richerPickerOpenBackgrounds; @@ -1744,8 +1834,7 @@ }; const richerPickerOpenShortcuts = function() { - customize.richerPicker_resetCustomizationMenu(); - customize.richerPicker_selectSubmenu( + customize.richerPicker_showSubmenu( $(customize.IDS.SHORTCUTS_BUTTON), $(customize.IDS.SHORTCUTS_MENU)); }; @@ -1758,8 +1847,7 @@ }; $(customize.IDS.COLORS_BUTTON).onclick = function() { - customize.richerPicker_resetCustomizationMenu(); - customize.richerPicker_selectSubmenu( + customize.richerPicker_showSubmenu( $(customize.IDS.COLORS_BUTTON), $(customize.IDS.COLORS_MENU)); ntpApiHandle.getColorsInfo(); }; @@ -1804,12 +1892,12 @@ return; } // Clear the previous selection, if any. - if (customize.selectedColorTile) { - customize.richerPicker_removeSelectedState(customize.selectedColorTile); + if (customize.selectedOptions.color) { + customize.richerPicker_removeSelectedState(customize.selectedOptions.color); } - customize.selectedColorTile = tile; + customize.selectedOptions.color = tile; customize.richerPicker_applySelectedState(tile); - customize.richerPicker_toggleDone(true); + customize.richerPicker_maybeToggleDone(); }; /**
diff --git a/chrome/browser/resources/local_ntp/externs.js b/chrome/browser/resources/local_ntp/externs.js index d6632a10..279b9dbc 100644 --- a/chrome/browser/resources/local_ntp/externs.js +++ b/chrome/browser/resources/local_ntp/externs.js
@@ -26,16 +26,20 @@ * The type of the config data object. The definition is based on * chrome/browser/search/local_ntp_source.cc: * LocalNtpSource::SearchConfigurationProvider::UpdateConfigData() - * @typedef {{translatedStrings: Array<string>, - * isGooglePage: boolean, - * googleBaseUrl: string, - * isAccessibleBrowser: boolean, + * @typedef {{alternateFakebox: boolean, + * alternateFakeboxRect: boolean, + * chromeColors: boolean, * enableShortcutsGrid: boolean, - * removeFakebox: boolean, - * alternateFakebox: boolean, * fakeboxSearchIcon: boolean, + * fakeboxSearchIconColor: boolean, + * googleBaseUrl: string, * hideShortcuts: boolean, - * chromeColors: boolean}} + * isAccessibleBrowser: boolean, + * isGooglePage: boolean, + * removeFakebox: boolean, + * richerPicker: boolean, + * showFakeboxPlaceholderOnFocus: boolean, + * translatedStrings: Array<string>}} */ let configData;
diff --git a/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.html b/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.html index e531e1a0..f6f7a00 100644 --- a/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.html +++ b/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.html
@@ -36,11 +36,13 @@ <settings-slider pref="{{prefs.webkit.webprefs.minimum_font_size}}" ticks="[[minimumFontSizeRange_]]" label-min="$i18n{tiny}" label-max="$i18n{huge}"></settings-slider> - <div id="minimumSizeSample" style=" - font-size:[[computeMinimumFontSize_( - prefs.webkit.webprefs.minimum_font_size.value)]]px; - font-family: - '[[prefs.webkit.webprefs.fonts.standard.Zyyy.value]]';"> + <div id="minimumSizeSample" + style=" + font-size:[[computeMinimumFontSize_( + prefs.webkit.webprefs.minimum_font_size.value)]]px; + font-family: + '[[prefs.webkit.webprefs.fonts.standard.Zyyy.value]]';" + hidden> [[computeMinimumFontSize_( prefs.webkit.webprefs.minimum_font_size.value)]]: $i18n{quickBrownFox}
diff --git a/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.js b/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.js index e3877f9..7852e2e 100644 --- a/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.js +++ b/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.js
@@ -76,6 +76,10 @@ }, }, + observers: [ + 'onMinimumSizeChange_(prefs.webkit.webprefs.minimum_font_size.value)', + ], + /** @private {?settings.FontsBrowserProxy} */ browserProxy_: null, @@ -136,12 +140,18 @@ /** * Get the minimum font size, accounting for unset prefs. - * @return {?} + * @return {number} * @private */ computeMinimumFontSize_: function() { - return this.get('prefs.webkit.webprefs.minimum_font_size.value') || - MINIMUM_FONT_SIZE_RANGE[0]; + const prefValue = this.get('prefs.webkit.webprefs.minimum_font_size.value'); + return /** @type {number} */ (prefValue) || MINIMUM_FONT_SIZE_RANGE[0]; + }, + + + /** @private */ + onMinimumSizeChange_: function() { + this.$.minimumSizeSample.hidden = this.computeMinimumFontSize_() <= 0; }, }); })();
diff --git a/chrome/browser/search/instant_service.cc b/chrome/browser/search/instant_service.cc index b4a946fa..0457b1f 100644 --- a/chrome/browser/search/instant_service.cc +++ b/chrome/browser/search/instant_service.cc
@@ -379,7 +379,7 @@ return true; } -bool InstantService::ToggleShortcutsVisibility() { +bool InstantService::ToggleShortcutsVisibility(bool do_notify) { // Non-Google NTPs are not supported. if (!most_visited_sites_ || !search_provider_observer_ || !search_provider_observer_->is_google()) { @@ -389,7 +389,9 @@ pref_service_->SetBoolean(prefs::kNtpShortcutsVisible, is_visible); most_visited_info_->is_visible = is_visible; - NotifyAboutMostVisitedInfo(); + if (do_notify) { + NotifyAboutMostVisitedInfo(); + } return true; }
diff --git a/chrome/browser/search/instant_service.h b/chrome/browser/search/instant_service.h index 4432b63..2a73342 100644 --- a/chrome/browser/search/instant_service.h +++ b/chrome/browser/search/instant_service.h
@@ -112,8 +112,10 @@ // false and does nothing if the profile is using a third-party NTP. bool ToggleMostVisitedOrCustomLinks(); // Invoked when the Instant page wants to toggle visibility of the tiles. + // Notifies observers only if |do_notify| is true, which is usually the case + // if |ToggleMostVisitedOrCustomLinks| will not be called immediately after. // Returns false and does nothing if the profile is using a third-party NTP. - bool ToggleShortcutsVisibility(); + bool ToggleShortcutsVisibility(bool do_notify); // Invoked to update theme information for the NTP. void UpdateThemeInfo();
diff --git a/chrome/browser/search/instant_service_unittest.cc b/chrome/browser/search/instant_service_unittest.cc index c20d5fc0..610fad2 100644 --- a/chrome/browser/search/instant_service_unittest.cc +++ b/chrome/browser/search/instant_service_unittest.cc
@@ -112,6 +112,9 @@ } TEST_F(InstantServiceTest, DoesToggleShortcutsVisibility) { + testing::StrictMock<MockInstantServiceObserver> mock_observer; + instant_service_->AddObserver(&mock_observer); + sync_preferences::TestingPrefServiceSyncable* pref_service = profile()->GetTestingPrefService(); SetUserSelectedDefaultSearchProvider("{google:baseURL}"); @@ -119,18 +122,22 @@ ASSERT_TRUE(instant_service_->most_visited_info_->is_visible); // Hide shortcuts. - EXPECT_TRUE(instant_service_->ToggleShortcutsVisibility()); + EXPECT_CALL(mock_observer, MostVisitedInfoChanged(testing::_)).Times(0); + EXPECT_TRUE(instant_service_->ToggleShortcutsVisibility(false)); EXPECT_FALSE(pref_service->GetBoolean(prefs::kNtpShortcutsVisible)); EXPECT_FALSE(instant_service_->most_visited_info_->is_visible); + thread_bundle()->RunUntilIdle(); - // Show shortcuts. - EXPECT_TRUE(instant_service_->ToggleShortcutsVisibility()); + // Show shortcuts, and check that a notification was sent. + EXPECT_CALL(mock_observer, MostVisitedInfoChanged(testing::_)).Times(1); + EXPECT_TRUE(instant_service_->ToggleShortcutsVisibility(true)); EXPECT_TRUE(pref_service->GetBoolean(prefs::kNtpShortcutsVisible)); EXPECT_TRUE(instant_service_->most_visited_info_->is_visible); // Should do nothing if this is a non-Google NTP. + EXPECT_CALL(mock_observer, MostVisitedInfoChanged(testing::_)).Times(0); SetUserSelectedDefaultSearchProvider("https://www.search.com"); - EXPECT_FALSE(instant_service_->ToggleShortcutsVisibility()); + EXPECT_FALSE(instant_service_->ToggleShortcutsVisibility(false)); EXPECT_TRUE(pref_service->GetBoolean(prefs::kNtpShortcutsVisible)); EXPECT_TRUE(instant_service_->most_visited_info_->is_visible); } @@ -176,7 +183,8 @@ const GURL kUrl("https://www.foo.com"); instant_service_->AddValidBackdropUrlForTesting(kUrl); - instant_service_->SetCustomBackgroundURLWithAttributions(kUrl, std::string(), std::string(), GURL()); + instant_service_->SetCustomBackgroundURLWithAttributions( + kUrl, std::string(), std::string(), GURL()); ThemeBackgroundInfo* theme_info = instant_service_->GetInitializedThemeInfo(); EXPECT_EQ(kUrl, theme_info->custom_background_url); @@ -193,7 +201,8 @@ ThemeBackgroundInfo* theme_info = instant_service_->GetInitializedThemeInfo(); EXPECT_EQ(kValidUrl.spec(), theme_info->custom_background_url.spec()); - instant_service_->SetCustomBackgroundURLWithAttributions(kInvalidUrl, std::string(), std::string(), GURL()); + instant_service_->SetCustomBackgroundURLWithAttributions( + kInvalidUrl, std::string(), std::string(), GURL()); theme_info = instant_service_->GetInitializedThemeInfo(); EXPECT_EQ(std::string(), theme_info->custom_background_url.spec());
diff --git a/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc b/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc index 05538d5..dacca77 100644 --- a/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc +++ b/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc
@@ -32,6 +32,7 @@ #include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_source.h" +#include "content/public/browser/notification_types.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_widget_host.h" #include "content/public/browser/render_widget_host_iterator.h" @@ -764,6 +765,7 @@ EXPECT_TRUE( ExecuteScript(grandchild, "location.href = '/fullscreen_frame.html'")); observer.Wait(); + grandchild = ChildFrameAt(child, 0); EXPECT_EQ(embedded_test_server()->GetURL("a.com", "/fullscreen_frame.html"), grandchild->GetLastCommittedURL()); @@ -916,6 +918,7 @@ EXPECT_TRUE( ExecuteScript(c_middle, "location.href = '/fullscreen_frame.html'")); observer.Wait(); + c_middle = ChildFrameAt(c_top, 0); EXPECT_EQ(embedded_test_server()->GetURL("c.com", "/fullscreen_frame.html"), c_middle->GetLastCommittedURL()); content::RenderFrameHost* c_bottom = ChildFrameAt(c_middle, 0);
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 412921d..389bd318 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -467,6 +467,7 @@ "//components/password_manager/core/browser", "//components/payments/content:utils", "//components/payments/content/icon", + "//components/payments/core:error_strings", "//components/pdf/browser", "//components/policy/core/browser", "//components/pref_registry", @@ -1431,6 +1432,8 @@ "app_list/search/launcher_search/launcher_search_result.h", "ash/accessibility/accessibility_controller_client.cc", "ash/accessibility/accessibility_controller_client.h", + "ash/arc_chrome_actions_client.cc", + "ash/arc_chrome_actions_client.h", "ash/ash_shell_init.cc", "ash/ash_shell_init.h", "ash/ash_util.cc",
diff --git a/chrome/browser/ui/android/ssl_client_certificate_request.cc b/chrome/browser/ui/android/ssl_client_certificate_request.cc index 9665976..9efd3b0 100644 --- a/chrome/browser/ui/android/ssl_client_certificate_request.cc +++ b/chrome/browser/ui/android/ssl_client_certificate_request.cc
@@ -302,7 +302,9 @@ // When we receive an OnCancel message, we remove this ClientCertRequest from // the queue of pending requests. auto should_keep = [this](auto* req) { return req != this; }; - pending_requests_->FilterPendingRequests(should_keep); + if (pending_requests_) { + pending_requests_->FilterPendingRequests(should_keep); + } } } // namespace
diff --git a/chrome/browser/ui/ash/arc_chrome_actions_client.cc b/chrome/browser/ui/ash/arc_chrome_actions_client.cc new file mode 100644 index 0000000..eb4d65b --- /dev/null +++ b/chrome/browser/ui/ash/arc_chrome_actions_client.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 "chrome/browser/ui/ash/arc_chrome_actions_client.h" + +#include "chrome/browser/chromeos/arc/arc_util.h" +#include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "components/arc/intent_helper/arc_intent_helper_bridge.h" +#include "components/user_manager/user_manager.h" + +ArcChromeActionsClient::ArcChromeActionsClient() { + arc::ArcIntentHelperBridge::SetFactoryResetDelegate(this); +} + +ArcChromeActionsClient::~ArcChromeActionsClient() { + arc::ArcIntentHelperBridge::SetFactoryResetDelegate(nullptr); +} + +void ArcChromeActionsClient::ResetArc() { + const user_manager::User* user = ArcChromeActionsClient::GetArcUser(); + Profile* profile = chromeos::ProfileHelper::Get()->GetProfileByUser(user); + arc::SetArcPlayStoreEnabledForProfile(profile, /*enabled=*/false); + arc::SetArcPlayStoreEnabledForProfile(profile, /*enabled=*/true); +} + +// ARC is only running for the primary user. +const user_manager::User* ArcChromeActionsClient::GetArcUser() { + return user_manager::UserManager::Get()->GetPrimaryUser(); +}
diff --git a/chrome/browser/ui/ash/arc_chrome_actions_client.h b/chrome/browser/ui/ash/arc_chrome_actions_client.h new file mode 100644 index 0000000..1120d8ab --- /dev/null +++ b/chrome/browser/ui/ash/arc_chrome_actions_client.h
@@ -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. + +#ifndef CHROME_BROWSER_UI_ASH_ARC_CHROME_ACTIONS_CLIENT_H_ +#define CHROME_BROWSER_UI_ASH_ARC_CHROME_ACTIONS_CLIENT_H_ + +#include "components/arc/intent_helper/factory_reset_delegate.h" + +namespace user_manager { +class User; +} + +// Allows ARC to call into browser code via ArcIntentHelperBridge, such +// as factory resetting ARC itself from Chrome. +// This should only for browser code not related to opening web URLs. +// For that, please use OpenUrlDelegate. +class ArcChromeActionsClient : public arc::FactoryResetDelegate { + public: + ArcChromeActionsClient(); + ~ArcChromeActionsClient() override; + + void ResetArc() override; + // Returns the primary user since it is not possible for + // non-primary user (e.g. secondary profile) to use ARC. + static const user_manager::User* GetArcUser(); + + private: + DISALLOW_COPY_AND_ASSIGN(ArcChromeActionsClient); +}; + +#endif // CHROME_BROWSER_UI_ASH_ARC_CHROME_ACTIONS_CLIENT_H_
diff --git a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc index ed5b9fe..371ea74 100644 --- a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc +++ b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc
@@ -25,6 +25,7 @@ #include "chrome/browser/sync/sync_error_notifier_factory_ash.h" #include "chrome/browser/ui/app_list/app_list_client_impl.h" #include "chrome/browser/ui/ash/accessibility/accessibility_controller_client.h" +#include "chrome/browser/ui/ash/arc_chrome_actions_client.h" #include "chrome/browser/ui/ash/ash_shell_init.h" #include "chrome/browser/ui/ash/cast_config_controller_media_router.h" #include "chrome/browser/ui/ash/chrome_new_window_client.h" @@ -159,6 +160,8 @@ ui::SelectFileDialog::SetFactory(new SelectFileDialogExtensionFactory); + arc_chrome_actions_client_ = std::make_unique<ArcChromeActionsClient>(); + #if BUILDFLAG(ENABLE_WAYLAND_SERVER) exo_parts_ = ExoParts::CreateIfNecessary(); #endif
diff --git a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.h b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.h index 5dd38371..8bcdb51 100644 --- a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.h +++ b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.h
@@ -21,6 +21,7 @@ class AccessibilityControllerClient; class AppListClientImpl; +class ArcChromeActionsClient; class AshShellInit; class CastConfigControllerMediaRouter; class ChromeNewWindowClient; @@ -76,6 +77,7 @@ std::unique_ptr<AccessibilityControllerClient> accessibility_controller_client_; std::unique_ptr<AppListClientImpl> app_list_client_; + std::unique_ptr<ArcChromeActionsClient> arc_chrome_actions_client_; std::unique_ptr<ChromeNewWindowClient> chrome_new_window_client_; std::unique_ptr<ImeControllerClient> ime_controller_client_; std::unique_ptr<ScreenOrientationDelegateChromeos>
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc index 48a3a5c..ceba2b3 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
@@ -487,6 +487,26 @@ SetItemStatusOrRemove(shelf_id, GetAppState(shelf_id.app_id)); } +void ChromeLauncherController::UpdateV1AppState(const std::string& app_id) { + for (Browser* browser : *BrowserList::GetInstance()) { + if (browser->is_app() || !browser->is_type_tabbed() || + !multi_user_util::IsProfileFromActiveUser(browser->profile())) { + continue; + } + for (int i = 0; i < browser->tab_strip_model()->count(); ++i) { + content::WebContents* const web_contents = + browser->tab_strip_model()->GetWebContentsAt(i); + if (launcher_controller_helper_->GetAppID(web_contents) != app_id) + continue; + UpdateAppState(web_contents, false /*remove*/); + if (browser->tab_strip_model()->GetActiveWebContents() == web_contents) { + GetBrowserShortcutLauncherItemController() + ->SetShelfIDForBrowserWindowContents(browser, web_contents); + } + } + } +} + ash::ShelfID ChromeLauncherController::GetShelfIDForWebContents( content::WebContents* contents) { std::string app_id = launcher_controller_helper_->GetAppID(contents);
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.h b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.h index 0707b86..276abb6 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.h +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.h
@@ -149,6 +149,11 @@ // the association of |contents| with an app. void UpdateAppState(content::WebContents* contents, bool remove); + // Updates app state for all tabs where a specific v1 app is running. + // This call is necessary if an app has been created for an existing + // web page (see IDC_CREATE_SHORTCUT). + void UpdateV1AppState(const std::string& app_id); + // Returns ShelfID for |contents|. If |contents| is not an app or is not // pinned, returns the id of browser shrotcut. ash::ShelfID GetShelfIDForWebContents(content::WebContents* contents);
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc index d2867997..f45f664 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
@@ -4544,10 +4544,13 @@ InitLauncherController(); const char* kPinnableApp = file_manager::kFileManagerAppId; - const char* kUnpinnableApp = file_manager::kGalleryAppId; + const char* kNoPinApps[] = {file_manager::kGalleryAppId, + extension_misc::kFeedbackExtensionId}; EXPECT_EQ(AppListControllerDelegate::PIN_EDITABLE, GetPinnableForAppID(kPinnableApp, profile())); - EXPECT_EQ(AppListControllerDelegate::NO_PIN, - GetPinnableForAppID(kUnpinnableApp, profile())); + for (const char* id : kNoPinApps) { + EXPECT_EQ(AppListControllerDelegate::NO_PIN, + GetPinnableForAppID(id, profile())); + } }
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.cc index 81c6e3a9..6549f851 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.cc
@@ -18,6 +18,7 @@ #include "chrome/common/pref_names.h" #include "components/prefs/pref_service.h" #include "extensions/browser/extension_registry.h" +#include "extensions/common/constants.h" #include "extensions/common/extension.h" const extensions::Extension* GetExtensionForAppID(const std::string& app_id, @@ -30,14 +31,15 @@ const std::string& app_id, Profile* profile) { // These file manager apps have a shelf presence, but can only be launched - // when provided a filename to open. Pinning them creates an item that does - // nothing. - const char* kUnpinnableAppIds[] = { + // when provided a filename to open. Likewise, the feedback extension needs + // context when launching. Pinning these creates an item that does nothing. + const char* kNoPinAppIds[] = { file_manager::kVideoPlayerAppId, file_manager::kGalleryAppId, file_manager::kAudioPlayerAppId, + extension_misc::kFeedbackExtensionId, }; - if (base::Contains(kUnpinnableAppIds, app_id)) + if (base::Contains(kNoPinAppIds, app_id)) return AppListControllerDelegate::NO_PIN; const base::ListValue* pref =
diff --git a/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc b/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc index eec89eba..7df5f3b 100644 --- a/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc +++ b/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc
@@ -526,9 +526,9 @@ TemplateURLService* service = TemplateURLServiceFactory::GetForProfile(browser()->profile()); search_test_utils::WaitForTemplateURLServiceToLoad(service); - LocationBar* location_bar = browser()->window()->GetLocationBar(); - ui_test_utils::SendToOmniboxAndSubmit(location_bar, search_string); - OmniboxEditModel* model = location_bar->GetOmniboxView()->model(); + ui_test_utils::SendToOmniboxAndSubmit(browser(), search_string); + OmniboxEditModel* model = + browser()->window()->GetLocationBar()->GetOmniboxView()->model(); EXPECT_EQ(GURL(search_string), model->CurrentMatch(nullptr).destination_url); EXPECT_EQ(base::ASCIIToUTF16(search_string), model->CurrentMatch(nullptr).contents);
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc index 642dc9d..fea598b 100644 --- a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc +++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc
@@ -64,6 +64,17 @@ return browser()->IsMouseLocked(); } + void PressKeyAndWaitForMouseLockRequest(ui::KeyboardCode key_code) { + base::RunLoop run_loop; + browser() + ->exclusive_access_manager() + ->mouse_lock_controller() + ->set_lock_state_callback_for_test(run_loop.QuitClosure()); + ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), key_code, false, + false, false, false)); + run_loop.Run(); + } + private: void ToggleTabFullscreen_Internal(bool enter_fullscreen, bool retry_until_success); @@ -299,12 +310,7 @@ ASSERT_FALSE(IsFullscreenBubbleDisplayed()); // Request to lock the mouse. - { - ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( - browser(), ui::VKEY_1, false, false, false, false, - chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, - content::NotificationService::AllSources())); - } + PressKeyAndWaitForMouseLockRequest(ui::VKEY_1); ASSERT_TRUE(IsMouseLocked()); ASSERT_FALSE(IsWindowFullscreenForTabOrPending()); @@ -329,10 +335,7 @@ // Request to lock the mouse and enter fullscreen. { FullscreenNotificationObserver fullscreen_observer(browser()); - ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( - browser(), ui::VKEY_B, false, true, false, false, - chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, - content::NotificationService::AllSources())); + PressKeyAndWaitForMouseLockRequest(ui::VKEY_B); fullscreen_observer.Wait(); } @@ -361,18 +364,12 @@ ASSERT_FALSE(IsFullscreenBubbleDisplayed()); // Lock the mouse without a user gesture, expect no response. - ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( - browser(), ui::VKEY_D, false, false, false, false, - chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, - content::NotificationService::AllSources())); + PressKeyAndWaitForMouseLockRequest(ui::VKEY_D); ASSERT_FALSE(IsFullscreenBubbleDisplayed()); ASSERT_FALSE(IsMouseLocked()); // Lock the mouse with a user gesture. - ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( - browser(), ui::VKEY_1, false, false, false, false, - chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, - content::NotificationService::AllSources())); + PressKeyAndWaitForMouseLockRequest(ui::VKEY_1); ASSERT_TRUE(IsFullscreenBubbleDisplayed()); ASSERT_TRUE(IsMouseLocked()); @@ -402,10 +399,7 @@ // Request to lock the mouse and enter fullscreen. { FullscreenNotificationObserver fullscreen_observer(browser()); - ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( - browser(), ui::VKEY_B, false, true, false, false, - chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, - content::NotificationService::AllSources())); + PressKeyAndWaitForMouseLockRequest(ui::VKEY_B); fullscreen_observer.Wait(); } ASSERT_TRUE(IsFullscreenBubbleDisplayed()); @@ -428,10 +422,7 @@ // Request to lock the mouse and enter fullscreen. FullscreenNotificationObserver fullscreen_observer(browser()); - ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( - browser(), ui::VKEY_B, false, true, false, false, - chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, - content::NotificationService::AllSources())); + PressKeyAndWaitForMouseLockRequest(ui::VKEY_B); fullscreen_observer.Wait(); // Confirm they are enabled and there is no prompt. @@ -456,57 +447,36 @@ ASSERT_FALSE(IsFullscreenBubbleDisplayed()); // Lock the mouse with a user gesture. - ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( - browser(), ui::VKEY_1, false, false, false, false, - chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, - content::NotificationService::AllSources())); + PressKeyAndWaitForMouseLockRequest(ui::VKEY_1); ASSERT_TRUE(IsFullscreenBubbleDisplayed()); ASSERT_TRUE(IsMouseLocked()); ASSERT_TRUE(IsFullscreenBubbleDisplayed()); // Unlock the mouse from target, make sure it's unlocked. - ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( - browser(), ui::VKEY_U, false, false, false, false, - chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, - content::NotificationService::AllSources())); + PressKeyAndWaitForMouseLockRequest(ui::VKEY_U); ASSERT_FALSE(IsMouseLocked()); ASSERT_FALSE(IsFullscreenBubbleDisplayed()); // Lock mouse again, make sure it works with no bubble. - ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( - browser(), ui::VKEY_1, false, false, false, false, - chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, - content::NotificationService::AllSources())); + PressKeyAndWaitForMouseLockRequest(ui::VKEY_1); ASSERT_TRUE(IsMouseLocked()); ASSERT_FALSE(IsFullscreenBubbleDisplayed()); // Unlock the mouse again by target. - ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( - browser(), ui::VKEY_U, false, false, false, false, - chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, - content::NotificationService::AllSources())); + PressKeyAndWaitForMouseLockRequest(ui::VKEY_U); ASSERT_FALSE(IsMouseLocked()); // Lock from target, not user gesture, make sure it works. - ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( - browser(), ui::VKEY_D, false, false, false, false, - chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, - content::NotificationService::AllSources())); + PressKeyAndWaitForMouseLockRequest(ui::VKEY_D); ASSERT_TRUE(IsMouseLocked()); ASSERT_FALSE(IsFullscreenBubbleDisplayed()); // Unlock by escape. - ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( - browser(), ui::VKEY_ESCAPE, false, false, false, false, - chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, - content::NotificationService::AllSources())); + PressKeyAndWaitForMouseLockRequest(ui::VKEY_ESCAPE); ASSERT_FALSE(IsMouseLocked()); // Lock the mouse with a user gesture, make sure we see bubble again. - ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( - browser(), ui::VKEY_1, false, false, false, false, - chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, - content::NotificationService::AllSources())); + PressKeyAndWaitForMouseLockRequest(ui::VKEY_1); ASSERT_TRUE(IsFullscreenBubbleDisplayed()); ASSERT_TRUE(IsMouseLocked()); } @@ -533,10 +503,7 @@ browser(), embedded_test_server()->GetURL(kFullscreenMouseLockHTML)); // Lock the mouse with a user gesture. - ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( - browser(), ui::VKEY_1, false, false, false, false, - chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, - content::NotificationService::AllSources())); + PressKeyAndWaitForMouseLockRequest(ui::VKEY_1); ASSERT_TRUE(IsFullscreenBubbleDisplayed()); ASSERT_TRUE(IsMouseLocked()); @@ -557,10 +524,7 @@ browser(), embedded_test_server()->GetURL(kFullscreenMouseLockHTML)); // Lock the mouse with a user gesture. - ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( - browser(), ui::VKEY_1, false, false, false, false, - chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, - content::NotificationService::AllSources())); + PressKeyAndWaitForMouseLockRequest(ui::VKEY_1); ASSERT_TRUE(IsFullscreenBubbleDisplayed()); ASSERT_TRUE(IsMouseLocked()); @@ -592,10 +556,7 @@ ui_test_utils::NavigateToURL(browser(), url); // Lock the mouse with a user gesture. - ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( - browser(), ui::VKEY_1, false, false, false, false, - chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, - content::NotificationService::AllSources())); + PressKeyAndWaitForMouseLockRequest(ui::VKEY_1); ASSERT_TRUE(IsFullscreenBubbleDisplayed()); ASSERT_TRUE(IsMouseLocked()); @@ -622,28 +583,26 @@ browser(), embedded_test_server()->GetURL(kFullscreenMouseLockHTML)); // Request mouse lock. - ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( - browser(), ui::VKEY_1, false, false, false, false, - chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, - content::NotificationService::AllSources())); + PressKeyAndWaitForMouseLockRequest(ui::VKEY_1); ASSERT_TRUE(IsMouseLocked()); ASSERT_TRUE(IsFullscreenBubbleDisplayed()); // Reload. Mouse lock request should be cleared. { - MouseLockNotificationObserver mouselock_observer; + base::RunLoop run_loop; + browser() + ->exclusive_access_manager() + ->mouse_lock_controller() + ->set_lock_state_callback_for_test(run_loop.QuitClosure()); Reload(); - mouselock_observer.Wait(); + run_loop.Run(); } // Request to lock the mouse and enter fullscreen. { FullscreenNotificationObserver fullscreen_observer(browser()); - ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( - browser(), ui::VKEY_B, false, true, false, false, - chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, - content::NotificationService::AllSources())); + PressKeyAndWaitForMouseLockRequest(ui::VKEY_B); fullscreen_observer.Wait(); }
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_test.h b/chrome/browser/ui/exclusive_access/fullscreen_controller_test.h index e7de20b..2042279 100644 --- a/chrome/browser/ui/exclusive_access/fullscreen_controller_test.h +++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_test.h
@@ -14,13 +14,11 @@ #include "base/scoped_observer.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/ui/exclusive_access/exclusive_access_bubble_hide_callback.h" #include "chrome/browser/ui/exclusive_access/exclusive_access_bubble_type.h" #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h" #include "chrome/browser/ui/exclusive_access/fullscreen_observer.h" #include "chrome/test/base/in_process_browser_test.h" -#include "content/public/browser/notification_service.h" #include "content/public/test/test_utils.h" #if defined(OS_MACOSX) @@ -54,17 +52,6 @@ DISALLOW_COPY_AND_ASSIGN(FullscreenNotificationObserver); }; -// Observer for NOTIFICATION_MOUSE_LOCK_CHANGED notifications. -class MouseLockNotificationObserver - : public content::WindowedNotificationObserver { - public: - MouseLockNotificationObserver() : WindowedNotificationObserver( - chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, - content::NotificationService::AllSources()) {} - protected: - DISALLOW_COPY_AND_ASSIGN(MouseLockNotificationObserver); -}; - // Test fixture with convenience functions for fullscreen, keyboard lock, and // mouse lock. class FullscreenControllerTest : public InProcessBrowserTest {
diff --git a/chrome/browser/ui/exclusive_access/mouse_lock_controller.cc b/chrome/browser/ui/exclusive_access/mouse_lock_controller.cc index 9eb606fd..deb2779 100644 --- a/chrome/browser/ui/exclusive_access/mouse_lock_controller.cc +++ b/chrome/browser/ui/exclusive_access/mouse_lock_controller.cc
@@ -6,7 +6,6 @@ #include "base/bind.h" #include "base/metrics/histogram_macros.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" @@ -14,7 +13,6 @@ #include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h" #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h" #include "components/content_settings/core/browser/host_content_settings_map.h" -#include "content/public/browser/notification_service.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host.h" #include "content/public/browser/render_widget_host_view.h" @@ -53,7 +51,8 @@ bool user_gesture, bool last_unlocked_by_target) { DCHECK(!IsMouseLocked()); - NotifyMouseLockChange(); + if (lock_state_callback_for_test_) + std::move(lock_state_callback_for_test_).Run(); // Must have a user gesture to prevent misbehaving sites from constantly // re-locking the mouse. Exceptions are when the page has unlocked @@ -122,21 +121,16 @@ } void MouseLockController::LostMouseLock() { + if (lock_state_callback_for_test_) + std::move(lock_state_callback_for_test_).Run(); + RecordExitingUMA(); mouse_lock_state_ = MOUSELOCK_UNLOCKED; SetTabWithExclusiveAccess(nullptr); - NotifyMouseLockChange(); exclusive_access_manager()->UpdateExclusiveAccessExitBubbleContent( ExclusiveAccessBubbleHideCallback()); } -void MouseLockController::NotifyMouseLockChange() { - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_MOUSE_LOCK_CHANGED, - content::Source<MouseLockController>(this), - content::NotificationService::NoDetails()); -} - void MouseLockController::UnlockMouse() { WebContents* tab = exclusive_access_tab();
diff --git a/chrome/browser/ui/exclusive_access/mouse_lock_controller.h b/chrome/browser/ui/exclusive_access/mouse_lock_controller.h index 70db0a9..429a0bcf 100644 --- a/chrome/browser/ui/exclusive_access/mouse_lock_controller.h +++ b/chrome/browser/ui/exclusive_access/mouse_lock_controller.h
@@ -64,6 +64,10 @@ bubble_hide_callback_for_test_ = std::move(callback_for_test); } + void set_lock_state_callback_for_test(base::OnceClosure callback) { + lock_state_callback_for_test_ = std::move(callback); + } + private: enum MouseLockState { MOUSELOCK_UNLOCKED, @@ -73,8 +77,6 @@ MOUSELOCK_LOCKED_SILENTLY }; - void NotifyMouseLockChange(); - void ExitExclusiveAccessIfNecessary() override; void NotifyTabExclusiveAccessLost() override; void RecordBubbleReshowsHistogram(int bubble_reshow_count) override; @@ -93,6 +95,9 @@ bool fake_mouse_lock_for_test_; ExclusiveAccessBubbleHideCallbackForTest bubble_hide_callback_for_test_; + // Called when the page requests (successfully or not) or loses mouse lock. + base::OnceClosure lock_state_callback_for_test_; + base::WeakPtrFactory<MouseLockController> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(MouseLockController);
diff --git a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc index f82a7a8..e6aa603 100644 --- a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc +++ b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
@@ -225,29 +225,25 @@ observer.WaitForNavigationFinished(); } - void WaitForTabOpenOrCloseForBrowser(const Browser* browser, - int expected_tab_count) { - int tab_count = browser->tab_strip_model()->count(); + void WaitForTabOpenOrClose(int expected_tab_count) { + int tab_count = browser()->tab_strip_model()->count(); if (tab_count == expected_tab_count) return; content::NotificationRegistrar registrar; - registrar.Add(this, - (tab_count < expected_tab_count) ? - static_cast<int>(chrome::NOTIFICATION_TAB_PARENTED) : - static_cast<int>(content::NOTIFICATION_WEB_CONTENTS_DESTROYED), + registrar.Add( + this, + (tab_count < expected_tab_count) + ? static_cast<int>(chrome::NOTIFICATION_TAB_PARENTED) + : static_cast<int>(content::NOTIFICATION_WEB_CONTENTS_DESTROYED), content::NotificationService::AllSources()); while (!HasFailure() && - browser->tab_strip_model()->count() != expected_tab_count) { + browser()->tab_strip_model()->count() != expected_tab_count) { content::RunMessageLoop(); } - ASSERT_EQ(expected_tab_count, browser->tab_strip_model()->count()); - } - - void WaitForTabOpenOrClose(int expected_tab_count) { - WaitForTabOpenOrCloseForBrowser(browser(), expected_tab_count); + ASSERT_EQ(expected_tab_count, browser()->tab_strip_model()->count()); } void WaitForAutocompleteControllerDone() { @@ -261,14 +257,7 @@ if (controller->done()) return; - content::NotificationRegistrar registrar; - registrar.Add(this, - chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY, - content::Source<AutocompleteController>(controller)); - - while (!HasFailure() && !controller->done()) - content::RunMessageLoop(); - + ui_test_utils::WaitForAutocompleteDone(browser()); ASSERT_TRUE(controller->done()); } @@ -385,12 +374,10 @@ switch (type) { case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: case chrome::NOTIFICATION_TAB_PARENTED: - case chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY: break; default: FAIL() << "Unexpected notification type"; } - base::RunLoop::QuitCurrentWhenIdleDeprecated(); } policy::MockConfigurationPolicyProvider* policy_provider() {
diff --git a/chrome/browser/ui/profile_error_dialog.cc b/chrome/browser/ui/profile_error_dialog.cc index 453bce9..ff6d152b 100644 --- a/chrome/browser/ui/profile_error_dialog.cc +++ b/chrome/browser/ui/profile_error_dialog.cc
@@ -17,7 +17,7 @@ namespace { -#if !defined(OS_ANDROID) +#if !defined(OS_ANDROID) && defined(GOOGLE_CHROME_BUILD) constexpr char kProfileErrorFeedbackCategory[] = "FEEDBACK_PROFILE_ERROR"; bool g_is_showing_profile_error_dialog = false; @@ -37,7 +37,7 @@ std::string() /* description_placeholder_text */, kProfileErrorFeedbackCategory, diagnostics); } -#endif // !defined(OS_ANDROID) +#endif // !defined(OS_ANDROID) && defined(GOOGLE_CHROME_BUILD) } // namespace @@ -46,7 +46,7 @@ const std::string& diagnostics) { #if defined(OS_ANDROID) NOTIMPLEMENTED(); -#else +#else // defined(OS_ANDROID) UMA_HISTOGRAM_ENUMERATION("Profile.ProfileError", static_cast<int>(type), static_cast<int>(ProfileErrorType::END)); if (base::CommandLine::ForCurrentProcess()->HasSwitch( @@ -54,6 +54,7 @@ return; } +#if defined(GOOGLE_CHROME_BUILD) if (g_is_showing_profile_error_dialog) return; @@ -63,5 +64,11 @@ l10n_util::GetStringUTF16(message_id), l10n_util::GetStringUTF16(IDS_PROFILE_ERROR_DIALOG_CHECKBOX), base::Bind(&OnProfileErrorDialogDismissed, diagnostics)); -#endif +#else // defined(GOOGLE_CHROME_BUILD) + chrome::ShowWarningMessageBox( + nullptr, l10n_util::GetStringUTF16(IDS_PROFILE_ERROR_DIALOG_TITLE), + l10n_util::GetStringUTF16(message_id)); +#endif // !defined(GOOGLE_CHROME_BUILD) + +#endif // !defined(OS_ANDROID) }
diff --git a/chrome/browser/ui/search/local_ntp_browsertest.cc b/chrome/browser/ui/search/local_ntp_browsertest.cc index c30d1628..14bbee3 100644 --- a/chrome/browser/ui/search/local_ntp_browsertest.cc +++ b/chrome/browser/ui/search/local_ntp_browsertest.cc
@@ -743,7 +743,8 @@ // Hide the shortcuts. local_ntp_test_utils::ExecuteScriptOnNTPAndWaitUntilLoaded( iframe, - "window.chrome.embeddedSearch.newTabPage.toggleShortcutsVisibility()"); + "window.chrome.embeddedSearch.newTabPage.toggleShortcutsVisibility(" + "true)"); // Check that the shortcuts are hidden. result = false; @@ -759,7 +760,8 @@ // Show the shortcuts. local_ntp_test_utils::ExecuteScriptOnNTPAndWaitUntilLoaded( iframe, - "window.chrome.embeddedSearch.newTabPage.toggleShortcutsVisibility()"); + "window.chrome.embeddedSearch.newTabPage.toggleShortcutsVisibility(" + "true)"); // Check that the shortcuts are visible. result = false; @@ -773,6 +775,101 @@ EXPECT_TRUE(result); } +IN_PROC_BROWSER_TEST_F(LocalNTPTest, ToggleShortcutVisibilityAndType) { + content::WebContents* active_tab = + local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank")); + + TestInstantServiceObserver observer( + InstantServiceFactory::GetForProfile(browser()->profile())); + + local_ntp_test_utils::NavigateToNTPAndWaitUntilLoaded(browser()); + observer.WaitForMostVisitedItems(kDefaultMostVisitedItemCount); + + // Initialize custom links by adding a shortcut. + content::RenderFrameHost* iframe = GetIframe(active_tab, kMostVisitedIframe); + local_ntp_test_utils::ExecuteScriptOnNTPAndWaitUntilLoaded( + iframe, + "window.chrome.embeddedSearch.newTabPage.updateCustomLink(-1, " + "'https://1.com', 'Title1')"); + // Confirm that there are the correct number of custom link tiles. + observer.WaitForMostVisitedItems(kDefaultMostVisitedItemCount + 1); + + // Check that the shortcuts are visible. + bool result = false; + ASSERT_TRUE(instant_test_utils::GetBoolFromJS( + iframe, "window.chrome.embeddedSearch.newTabPage.areShortcutsVisible", + &result)); + ASSERT_TRUE(result); + result = false; + ASSERT_TRUE(instant_test_utils::GetBoolFromJS( + iframe, "!document.body.classList.contains('hide')", &result)); + ASSERT_TRUE(result); + + // Hide the shortcuts and immediately enable Most Visited sites. The + // successive calls should not interfere with each other, and only a single + // update should be sent. + local_ntp_test_utils::ExecuteScriptOnNTPAndWaitUntilLoaded( + iframe, + "window.chrome.embeddedSearch.newTabPage.toggleShortcutsVisibility(" + "false); " + "window.chrome.embeddedSearch.newTabPage.toggleMostVisitedOrCustomLinks(" + ")"); + // Confirm that there are the correct number of Most Visited tiles. + observer.WaitForMostVisitedItems(kDefaultMostVisitedItemCount); + + // Check that the tiles have updated properly, i.e. the tiles should not have + // an edit menu nor be visible. + result = false; + ASSERT_TRUE(instant_test_utils::GetBoolFromJS( + iframe, "window.chrome.embeddedSearch.newTabPage.isUsingMostVisited", + &result)); + EXPECT_TRUE(result); + result = false; + ASSERT_TRUE(instant_test_utils::GetBoolFromJS( + iframe, "!document.querySelector('#mv-tiles .md-edit-menu')", &result)); + EXPECT_TRUE(result); + result = false; + ASSERT_TRUE(instant_test_utils::GetBoolFromJS( + iframe, "!window.chrome.embeddedSearch.newTabPage.areShortcutsVisible", + &result)); + EXPECT_TRUE(result); + result = false; + ASSERT_TRUE(instant_test_utils::GetBoolFromJS( + iframe, "document.body.classList.contains('hide')", &result)); + EXPECT_TRUE(result); + + // Show the shortcuts and immediately enable custom links. + local_ntp_test_utils::ExecuteScriptOnNTPAndWaitUntilLoaded( + iframe, + "window.chrome.embeddedSearch.newTabPage.toggleShortcutsVisibility(" + "false); " + "window.chrome.embeddedSearch.newTabPage.toggleMostVisitedOrCustomLinks(" + ")"); + // Confirm that there are the correct number of custom link tiles. + observer.WaitForMostVisitedItems(kDefaultMostVisitedItemCount + 1); + + // Check that the tiles have updated properly, i.e. the tiles should have an + // edit menu and be visible. + result = false; + ASSERT_TRUE(instant_test_utils::GetBoolFromJS( + iframe, "!window.chrome.embeddedSearch.newTabPage.isUsingMostVisited", + &result)); + EXPECT_TRUE(result); + result = false; + ASSERT_TRUE(instant_test_utils::GetBoolFromJS( + iframe, "!!document.querySelector('#mv-tiles .md-edit-menu')", &result)); + EXPECT_TRUE(result); + result = false; + ASSERT_TRUE(instant_test_utils::GetBoolFromJS( + iframe, "window.chrome.embeddedSearch.newTabPage.areShortcutsVisible", + &result)); + EXPECT_TRUE(result); + result = false; + ASSERT_TRUE(instant_test_utils::GetBoolFromJS( + iframe, "!document.body.classList.contains('hide')", &result)); + EXPECT_TRUE(result); +} + class LocalNTPRTLTest : public LocalNTPTest { public: LocalNTPRTLTest() {}
diff --git a/chrome/browser/ui/search/search_ipc_router.cc b/chrome/browser/ui/search/search_ipc_router.cc index 612d85b3..98ebd92 100644 --- a/chrome/browser/ui/search/search_ipc_router.cc +++ b/chrome/browser/ui/search/search_ipc_router.cc
@@ -268,14 +268,15 @@ delegate_->OnToggleMostVisitedOrCustomLinks(); } -void SearchIPCRouter::ToggleShortcutsVisibility(int page_seq_no) { +void SearchIPCRouter::ToggleShortcutsVisibility(int page_seq_no, + bool do_notify) { if (page_seq_no != commit_counter_) return; if (!policy_->ShouldProcessToggleShortcutsVisibility()) return; - delegate_->OnToggleShortcutsVisibility(); + delegate_->OnToggleShortcutsVisibility(do_notify); } void SearchIPCRouter::LogEvent(int page_seq_no,
diff --git a/chrome/browser/ui/search/search_ipc_router.h b/chrome/browser/ui/search/search_ipc_router.h index 9d807d2..1b4c0014 100644 --- a/chrome/browser/ui/search/search_ipc_router.h +++ b/chrome/browser/ui/search/search_ipc_router.h
@@ -82,7 +82,7 @@ // Called when the EmbeddedSearch wants to toggle visibility of the // shortcuts. - virtual void OnToggleShortcutsVisibility() = 0; + virtual void OnToggleShortcutsVisibility(bool do_notify) = 0; // Called to signal that an event has occurred on the New Tab Page at a // particular time since navigation start. @@ -255,7 +255,7 @@ void UndoCustomLinkAction(int page_seq_no) override; void ResetCustomLinks(int page_seq_no) override; void ToggleMostVisitedOrCustomLinks(int page_seq_no) override; - void ToggleShortcutsVisibility(int page_seq_no) override; + void ToggleShortcutsVisibility(int page_seq_no, bool do_notify) override; void LogEvent(int page_seq_no, NTPLoggingEventType event, base::TimeDelta time) override;
diff --git a/chrome/browser/ui/search/search_ipc_router_unittest.cc b/chrome/browser/ui/search/search_ipc_router_unittest.cc index a337c5d..674b12a 100644 --- a/chrome/browser/ui/search/search_ipc_router_unittest.cc +++ b/chrome/browser/ui/search/search_ipc_router_unittest.cc
@@ -72,7 +72,7 @@ MOCK_METHOD0(OnUndoCustomLinkAction, void()); MOCK_METHOD0(OnResetCustomLinks, void()); MOCK_METHOD0(OnToggleMostVisitedOrCustomLinks, void()); - MOCK_METHOD0(OnToggleShortcutsVisibility, void()); + MOCK_METHOD1(OnToggleShortcutsVisibility, void(bool do_notify)); MOCK_METHOD2(OnLogEvent, void(NTPLoggingEventType event, base::TimeDelta time)); MOCK_METHOD3(OnLogSuggestionEventWithValue, @@ -687,24 +687,26 @@ NavigateAndCommitActiveTab(GURL("chrome-search://foo/bar")); SetupMockDelegateAndPolicy(); MockSearchIPCRouterPolicy* policy = GetSearchIPCRouterPolicy(); - EXPECT_CALL(*mock_delegate(), OnToggleShortcutsVisibility()).Times(1); + EXPECT_CALL(*mock_delegate(), OnToggleShortcutsVisibility(false)).Times(1); EXPECT_CALL(*policy, ShouldProcessToggleShortcutsVisibility()) .Times(1) .WillOnce(Return(true)); - GetSearchIPCRouter().ToggleShortcutsVisibility(GetSearchIPCRouterSeqNo()); + GetSearchIPCRouter().ToggleShortcutsVisibility(GetSearchIPCRouterSeqNo(), + false); } TEST_F(SearchIPCRouterTest, IgnoreToggleShortcutsVisibility) { NavigateAndCommitActiveTab(GURL("chrome-search://foo/bar")); SetupMockDelegateAndPolicy(); MockSearchIPCRouterPolicy* policy = GetSearchIPCRouterPolicy(); - EXPECT_CALL(*mock_delegate(), OnToggleShortcutsVisibility()).Times(0); + EXPECT_CALL(*mock_delegate(), OnToggleShortcutsVisibility(true)).Times(0); EXPECT_CALL(*policy, ShouldProcessToggleShortcutsVisibility()) .Times(1) .WillOnce(Return(false)); - GetSearchIPCRouter().ToggleShortcutsVisibility(GetSearchIPCRouterSeqNo()); + GetSearchIPCRouter().ToggleShortcutsVisibility(GetSearchIPCRouterSeqNo(), + true); } TEST_F(SearchIPCRouterTest, ProcessPasteAndOpenDropdownMsg) {
diff --git a/chrome/browser/ui/search/search_tab_helper.cc b/chrome/browser/ui/search/search_tab_helper.cc index 03d7e58..d0c64b7b 100644 --- a/chrome/browser/ui/search/search_tab_helper.cc +++ b/chrome/browser/ui/search/search_tab_helper.cc
@@ -323,9 +323,9 @@ instant_service_->ToggleMostVisitedOrCustomLinks(); } -void SearchTabHelper::OnToggleShortcutsVisibility() { +void SearchTabHelper::OnToggleShortcutsVisibility(bool do_notify) { if (instant_service_) - instant_service_->ToggleShortcutsVisibility(); + instant_service_->ToggleShortcutsVisibility(do_notify); } void SearchTabHelper::OnLogEvent(NTPLoggingEventType event,
diff --git a/chrome/browser/ui/search/search_tab_helper.h b/chrome/browser/ui/search/search_tab_helper.h index ab0191c..fafc41c 100644 --- a/chrome/browser/ui/search/search_tab_helper.h +++ b/chrome/browser/ui/search/search_tab_helper.h
@@ -101,7 +101,7 @@ void OnUndoCustomLinkAction() override; void OnResetCustomLinks() override; void OnToggleMostVisitedOrCustomLinks() override; - void OnToggleShortcutsVisibility() override; + void OnToggleShortcutsVisibility(bool do_notify) override; void OnLogEvent(NTPLoggingEventType event, base::TimeDelta time) override; void OnLogSuggestionEventWithValue(NTPSuggestionsLoggingEventType event, int data,
diff --git a/chrome/browser/ui/startup/startup_browser_creator.cc b/chrome/browser/ui/startup/startup_browser_creator.cc index 04467bf..f798328 100644 --- a/chrome/browser/ui/startup/startup_browser_creator.cc +++ b/chrome/browser/ui/startup/startup_browser_creator.cc
@@ -479,9 +479,6 @@ // static void StartupBrowserCreator::RegisterLocalStatePrefs( PrefRegistrySimple* registry) { -#if defined(OS_WIN) - registry->RegisterBooleanPref(prefs::kWelcomePageOnOSUpgradeEnabled, true); -#endif #if !defined(OS_CHROMEOS) registry->RegisterBooleanPref(prefs::kPromotionalTabsEnabled, true); registry->RegisterBooleanPref(prefs::kCommandLineFlagSecurityWarningsEnabled,
diff --git a/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.cc b/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.cc index b083d2f3..2de1c80 100644 --- a/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.cc +++ b/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.cc
@@ -16,9 +16,9 @@ #include "build/build_config.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/app/vector_icons/vector_icons.h" -#include "chrome/browser/favicon/favicon_request_handler_factory.h" #include "chrome/browser/favicon/favicon_service_factory.h" #include "chrome/browser/favicon/favicon_utils.h" +#include "chrome/browser/favicon/history_ui_favicon_request_handler_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/search/search.h" #include "chrome/browser/sessions/session_restore.h" @@ -31,7 +31,7 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/toolbar/app_menu_model.h" #include "chrome/grit/generated_resources.h" -#include "components/favicon/core/favicon_request_handler.h" +#include "components/favicon/core/history_ui_favicon_request_handler.h" #include "components/favicon_base/favicon_types.h" #include "components/feature_engagement/buildflags.h" #include "components/prefs/scoped_user_pref_update.h" @@ -584,13 +584,15 @@ weak_ptr_factory_.GetWeakPtr(), command_id), &local_tab_cancelable_task_tracker_); } else { - favicon::FaviconRequestHandler* favicon_request_handler = - FaviconRequestHandlerFactory::GetForBrowserContext(browser_->profile()); + favicon::HistoryUiFaviconRequestHandler* + history_ui_favicon_request_handler = + HistoryUiFaviconRequestHandlerFactory::GetForBrowserContext( + browser_->profile()); // Can be null for tests. - if (!favicon_request_handler) + if (!history_ui_favicon_request_handler) return; sync_sessions::OpenTabsUIDelegate* open_tabs = GetOpenTabsUIDelegate(); - favicon_request_handler->GetFaviconImageForPageURL( + history_ui_favicon_request_handler->GetFaviconImageForPageURL( url, base::BindOnce(&RecentTabsSubMenuModel::OnFaviconDataAvailable, weak_ptr_factory_.GetWeakPtr(), command_id),
diff --git a/chrome/browser/ui/views/find_bar_views_interactive_uitest.cc b/chrome/browser/ui/views/find_bar_views_interactive_uitest.cc index 4ca9ce7..e90952b 100644 --- a/chrome/browser/ui/views/find_bar_views_interactive_uitest.cc +++ b/chrome/browser/ui/views/find_bar_views_interactive_uitest.cc
@@ -6,6 +6,7 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" +#include "chrome/app/chrome_command_ids.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" @@ -613,7 +614,7 @@ } #endif -IN_PROC_BROWSER_TEST_F(FindInPageTest, EscapeOnPageClosesFind) { +IN_PROC_BROWSER_TEST_F(FindInPageTest, GlobalEscapeClosesFind) { ASSERT_TRUE(embedded_test_server()->Start()); // Make sure Chrome is in the foreground, otherwise sending input // won't do anything and the test will hang. @@ -626,17 +627,13 @@ browser()->GetFindBarController()->Show(false, true); EXPECT_TRUE(IsViewFocused(browser(), VIEW_ID_FIND_IN_PAGE_TEXT_FIELD)); - // put focus onto the page - ASSERT_NO_FATAL_FAILURE( - ui_test_utils::ClickOnView(browser(), VIEW_ID_TAB_CONTAINER)); - ASSERT_TRUE(IsViewFocused(browser(), VIEW_ID_TAB_CONTAINER)); + // Put focus into location bar + chrome::FocusLocationBar(browser()); // Close find with escape ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_ESCAPE, false, false, false, false)); - // Focus should still be on the page - ASSERT_TRUE(IsViewFocused(browser(), VIEW_ID_TAB_CONTAINER)); // Find should be closed ASSERT_FALSE(IsFindBarVisible()); }
diff --git a/chrome/browser/ui/views/intent_picker_bubble_view.cc b/chrome/browser/ui/views/intent_picker_bubble_view.cc index e026f499..f07be172 100644 --- a/chrome/browser/ui/views/intent_picker_bubble_view.cc +++ b/chrome/browser/ui/views/intent_picker_bubble_view.cc
@@ -379,20 +379,24 @@ views::GridLayout::kFixedSize, kTitlePadding); scroll_view_ = layout->AddView(std::move(scroll_view)); layout->StartRow(views::GridLayout::kFixedSize, kColumnSetId, 0); - layout->AddView(CreateHorizontalSeparator()); - // This second ColumnSet has a padding column in order to manipulate the - // Checkbox positioning freely. - constexpr int kColumnSetIdPadded = 1; - views::ColumnSet* cs_padded = layout->AddColumnSet(kColumnSetIdPadded); - cs_padded->AddPaddingColumn(views::GridLayout::kFixedSize, kTitlePadding); - cs_padded->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER, - views::GridLayout::kFixedSize, views::GridLayout::FIXED, - kMaxIntentPickerLabelButtonWidth - 2 * kTitlePadding, 0); - - layout->StartRowWithPadding(views::GridLayout::kFixedSize, kColumnSetIdPadded, - views::GridLayout::kFixedSize, 0); if (show_remember_selection) { + layout->AddView(CreateHorizontalSeparator()); + + // This second ColumnSet has a padding column in order to manipulate the + // Checkbox positioning freely. + constexpr int kColumnSetIdPadded = 1; + views::ColumnSet* cs_padded = layout->AddColumnSet(kColumnSetIdPadded); + cs_padded->AddPaddingColumn(views::GridLayout::kFixedSize, kTitlePadding); + cs_padded->AddColumn( + views::GridLayout::FILL, views::GridLayout::CENTER, + views::GridLayout::kFixedSize, views::GridLayout::FIXED, + kMaxIntentPickerLabelButtonWidth - 2 * kTitlePadding, 0); + + layout->StartRowWithPadding(views::GridLayout::kFixedSize, + kColumnSetIdPadded, + views::GridLayout::kFixedSize, 0); + remember_selection_checkbox_ = layout->AddView( std::make_unique<views::Checkbox>(l10n_util::GetStringUTF16( IDS_INTENT_PICKER_BUBBLE_VIEW_REMEMBER_SELECTION)));
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc index 6a1917e..519db4b 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
@@ -121,7 +121,7 @@ animation_->Hide(); } -void OmniboxResultView::Invalidate() { +void OmniboxResultView::Invalidate(bool force_reapply_styles) { bool high_contrast = GetNativeTheme() && GetNativeTheme()->UsesHighContrastColors(); // TODO(tapted): Consider using background()->SetNativeControlColor() and @@ -191,7 +191,7 @@ // Normally, OmniboxTextView caches its appearance, but in high contrast, // selected-ness changes the text colors, so the styling of the text part of // the results needs to be recomputed. - if (high_contrast) { + if (high_contrast || force_reapply_styles) { suggestion_view_->content()->ReapplyStyling(); suggestion_view_->description()->ReapplyStyling(); } @@ -404,7 +404,7 @@ } void OmniboxResultView::OnThemeChanged() { - Invalidate(); + Invalidate(true); SchedulePaint(); }
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.h b/chrome/browser/ui/views/omnibox/omnibox_result_view.h index 580cb9b..dc2d8131 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_result_view.h +++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.h
@@ -60,7 +60,7 @@ void ShowKeyword(bool show_keyword); - void Invalidate(); + void Invalidate(bool force_reapply_styles = false); // Invoked when this result view has been selected. void OnSelected();
diff --git a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc index cca70446..b644f2f 100644 --- a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc +++ b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/ui/views/payments/payment_request_views_util.h" #include "chrome/grit/generated_resources.h" #include "components/payments/content/icon/icon_size.h" +#include "components/payments/core/error_strings.h" #include "components/payments/core/url_util.h" #include "components/web_modal/web_contents_modal_dialog_manager.h" #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h" @@ -290,9 +291,6 @@ content::WebContents* source) { DCHECK(source == web_contents()); if (!SslValidityChecker::IsValidPageInPaymentHandlerWindow(source)) { - log_.Error("Aborting payment handler window \"" + target_.spec() + - "\" because of insecure certificate state on \"" + - source->GetVisibleURL().spec() + "\""); AbortPayment(); } } @@ -330,9 +328,6 @@ if (!SslValidityChecker::IsValidPageInPaymentHandlerWindow( navigation_handle->GetWebContents())) { - log_.Error("Aborting payment handler window \"" + target_.spec() + - "\" because of navigation to an insecure url \"" + - navigation_handle->GetURL().spec() + "\""); AbortPayment(); return; } @@ -353,9 +348,6 @@ } void PaymentHandlerWebFlowViewController::DidAttachInterstitialPage() { - log_.Error("Aborting payment handler window \"" + target_.spec() + - "\" because of navigation to a page with invalid certificate " - "state or malicious content."); AbortPayment(); } @@ -363,7 +355,7 @@ if (web_contents()) web_contents()->Close(); - dialog()->ShowErrorMessage(); + state()->OnPaymentResponseError(errors::kPaymentHandlerInsecureNavigation); } } // namespace payments
diff --git a/chrome/browser/ui/views/payments/payment_request_completion_status_metrics_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_completion_status_metrics_browsertest.cc index 1d4f1d7..62306dc 100644 --- a/chrome/browser/ui/views/payments/payment_request_completion_status_metrics_browsertest.cc +++ b/chrome/browser/ui/views/payments/payment_request_completion_status_metrics_browsertest.cc
@@ -462,7 +462,8 @@ ASSERT_EQ(1U, buckets.size()); EXPECT_EQ(JourneyLogger::EVENT_INITIATED | JourneyLogger::EVENT_USER_ABORTED | JourneyLogger::EVENT_REQUEST_METHOD_BASIC_CARD | - JourneyLogger::EVENT_REQUEST_METHOD_OTHER, + JourneyLogger::EVENT_REQUEST_METHOD_OTHER | + JourneyLogger::EVENT_NEEDS_COMPLETION_PAYMENT, buckets[0].min); }
diff --git a/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc index 9b31df58..2a357f0 100644 --- a/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc +++ b/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc
@@ -840,7 +840,8 @@ JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE | JourneyLogger::EVENT_HAS_ENROLLED_INSTRUMENT_FALSE | JourneyLogger::EVENT_REQUEST_METHOD_OTHER | - JourneyLogger::EVENT_REQUEST_METHOD_BASIC_CARD, + JourneyLogger::EVENT_REQUEST_METHOD_BASIC_CARD | + JourneyLogger::EVENT_NEEDS_COMPLETION_PAYMENT, buckets[0].min); // Make sure that the metrics that required the Payment Request to be shown @@ -1040,7 +1041,8 @@ int64_t expected_step_metric = JourneyLogger::EVENT_SHOWN | JourneyLogger::EVENT_REQUEST_METHOD_BASIC_CARD | - JourneyLogger::EVENT_USER_ABORTED; + JourneyLogger::EVENT_USER_ABORTED | + JourneyLogger::EVENT_NEEDS_COMPLETION_PAYMENT; // Make sure the correct UMA events were logged. std::vector<base::Bucket> buckets =
diff --git a/chrome/browser/ui/views/payments/payment_request_missing_fields_metrics_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_missing_fields_metrics_browsertest.cc new file mode 100644 index 0000000..4152797 --- /dev/null +++ b/chrome/browser/ui/views/payments/payment_request_missing_fields_metrics_browsertest.cc
@@ -0,0 +1,235 @@ +// 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/test/metrics/histogram_tester.h" +#include "chrome/browser/ui/views/payments/payment_request_browsertest_base.h" +#include "components/autofill/core/browser/autofill_test_utils.h" +#include "components/autofill/core/browser/data_model/autofill_profile.h" +#include "components/autofill/core/browser/data_model/credit_card.h" +#include "components/autofill/core/browser/validation.h" +#include "components/payments/core/journey_logger.h" +#include "components/payments/core/payments_profile_comparator.h" + +namespace payments { + +using PaymentRequestMissingFieldsMetricsTest = PaymentRequestBrowserTestBase; + +// Tests that proper UMA metrics are logged when payment section has no +// suggestion. +IN_PROC_BROWSER_TEST_F(PaymentRequestMissingFieldsMetricsTest, + TestMissingPaymentMethod) { + NavigateTo("/payment_request_shipping_address_instance_test.html"); + base::HistogramTester histogram_tester; + + // Add an autofill profile for billing address without adding any cards. + autofill::AutofillProfile billing_address = autofill::test::GetFullProfile(); + AddAutofillProfile(billing_address); + + // Show a Payment Request. + InvokePaymentRequestUI(); + + // Navigate away to abort the Payment Request and trigger the logs. + NavigateTo("/payment_request_email_test.html"); + + // Make sure the correct events were logged. + int32_t expected_event_bits = JourneyLogger::EVENT_SHOWN | + JourneyLogger::EVENT_USER_ABORTED | + JourneyLogger::EVENT_REQUEST_SHIPPING | + JourneyLogger::EVENT_REQUEST_METHOD_BASIC_CARD | + JourneyLogger::EVENT_NEEDS_COMPLETION_PAYMENT; + histogram_tester.ExpectBucketCount("PaymentRequest.Events", + expected_event_bits, 1); + + // Since no card is added to the profile, all payment fields should be + // missing. + int32_t expected_missing_payment_bits = + autofill::CREDIT_CARD_EXPIRED | autofill::CREDIT_CARD_NO_CARDHOLDER | + autofill::CREDIT_CARD_NO_NUMBER | + autofill::CREDIT_CARD_NO_BILLING_ADDRESS; + histogram_tester.ExpectBucketCount("PaymentRequest.MissingPaymentFields", + expected_missing_payment_bits, 1); + + // There should be no log for missing shipping address fields since the + // section had one complete suggestion. + histogram_tester.ExpectTotalCount("PaymentRequest.MissingShippingFields", 0); +} + +// Tests that proper UMA metrics are logged when payment section has incomplete +// card. +IN_PROC_BROWSER_TEST_F(PaymentRequestMissingFieldsMetricsTest, + TestIncompleteCard) { + NavigateTo("/payment_request_shipping_address_instance_test.html"); + base::HistogramTester histogram_tester; + + // Add an autofill profile for billing address with a credit card missing card + // holder's name. + autofill::AutofillProfile billing_address = autofill::test::GetFullProfile(); + AddAutofillProfile(billing_address); + autofill::CreditCard card = autofill::test::GetIncompleteCreditCard(); + card.set_billing_address_id(billing_address.guid()); + AddCreditCard(card); // Visa + + // Show a Payment Request. + InvokePaymentRequestUI(); + + // Navigate away to abort the Payment Request and trigger the logs. + NavigateTo("/payment_request_email_test.html"); + + // Make sure the correct events were logged. Even though the suggested card + // is incomplete, EVENT_HAD_INITIAL_FORM_OF_PAYMENT is set since it only + // shows whether the payment suggestion list is empty or not. + int32_t expected_event_bits = + JourneyLogger::EVENT_SHOWN | JourneyLogger::EVENT_USER_ABORTED | + JourneyLogger::EVENT_HAD_INITIAL_FORM_OF_PAYMENT | + JourneyLogger::EVENT_REQUEST_SHIPPING | + JourneyLogger::EVENT_REQUEST_METHOD_BASIC_CARD | + JourneyLogger::EVENT_NEEDS_COMPLETION_PAYMENT; + histogram_tester.ExpectBucketCount("PaymentRequest.Events", + expected_event_bits, 1); + + int32_t expected_missing_payment_bits = autofill::CREDIT_CARD_NO_CARDHOLDER; + histogram_tester.ExpectBucketCount("PaymentRequest.MissingPaymentFields", + expected_missing_payment_bits, 1); + + // There should be no log for missing shipping address fields since the + // section had one complete suggestion. + histogram_tester.ExpectTotalCount("PaymentRequest.MissingShippingFields", 0); +} + +// Tests that proper UMA metrics are logged when payment section has expired +// card. +IN_PROC_BROWSER_TEST_F(PaymentRequestMissingFieldsMetricsTest, + TestExpiredCard) { + NavigateTo("/payment_request_shipping_address_instance_test.html"); + base::HistogramTester histogram_tester; + + // Add an autofill profile for billing address with an expired card. + autofill::AutofillProfile billing_address = autofill::test::GetFullProfile(); + AddAutofillProfile(billing_address); + autofill::CreditCard card = autofill::test::GetExpiredCreditCard(); + card.set_billing_address_id(billing_address.guid()); + AddCreditCard(card); // Visa + + // Show a Payment Request. + InvokePaymentRequestUI(); + + // Navigate away to abort the Payment Request and trigger the logs. + NavigateTo("/payment_request_email_test.html"); + + // Make sure the correct events were logged. + // EVENT_HAD_NECESSARY_COMPLETE_SUGGESTIONS is set since expired cards are + // treated as complete. + int32_t expected_event_bits = + JourneyLogger::EVENT_SHOWN | JourneyLogger::EVENT_USER_ABORTED | + JourneyLogger::EVENT_HAD_INITIAL_FORM_OF_PAYMENT | + JourneyLogger::EVENT_HAD_NECESSARY_COMPLETE_SUGGESTIONS | + JourneyLogger::EVENT_REQUEST_SHIPPING | + JourneyLogger::EVENT_REQUEST_METHOD_BASIC_CARD; + histogram_tester.ExpectBucketCount("PaymentRequest.Events", + expected_event_bits, 1); + + // Expired cards are considered as complete according to + // AutofillPaymentInstrument::IsCompleteForPayment(). + histogram_tester.ExpectTotalCount("PaymentRequest.MissingPaymentFields", 0); + + // There should be no log for missing shipping address fields since the + // section had one complete suggestion. + histogram_tester.ExpectTotalCount("PaymentRequest.MissingShippingFields", 0); +} + +// Tests that proper UMA metrics are logged when shipping section is incomplete. +IN_PROC_BROWSER_TEST_F(PaymentRequestMissingFieldsMetricsTest, + TestIncompleteShippingProfile) { + NavigateTo("/payment_request_shipping_address_instance_test.html"); + base::HistogramTester histogram_tester; + + // Add an incomplete profile for billing address. The profile has email + // address only. + autofill::AutofillProfile billing_address = + autofill::test::GetIncompleteProfile2(); + AddAutofillProfile(billing_address); + autofill::CreditCard card = autofill::test::GetCreditCard(); + card.set_billing_address_id(billing_address.guid()); + AddCreditCard(card); // Visa + + // Show a Payment Request. + InvokePaymentRequestUI(); + + // Navigate away to abort the Payment Request and trigger the logs. + NavigateTo("/payment_request_email_test.html"); + + // Make sure the correct events were logged. + int32_t expected_event_bits = + JourneyLogger::EVENT_SHOWN | JourneyLogger::EVENT_USER_ABORTED | + JourneyLogger::EVENT_HAD_INITIAL_FORM_OF_PAYMENT | + JourneyLogger::EVENT_REQUEST_SHIPPING | + JourneyLogger::EVENT_REQUEST_METHOD_BASIC_CARD | + JourneyLogger::EVENT_NEEDS_COMPLETION_SHIPPING; + histogram_tester.ExpectBucketCount("PaymentRequest.Events", + expected_event_bits, 1); + + // Since the incomplete profile has email address only, the rest of the bits + // should be logged in MissingShippingFields. + int32_t expected_missing_shipping_bits = PaymentsProfileComparator::kName | + PaymentsProfileComparator::kPhone | + PaymentsProfileComparator::kAddress; + histogram_tester.ExpectBucketCount("PaymentRequest.MissingShippingFields", + expected_missing_shipping_bits, 1); + + // There should be no log for missing payment fields since the section had one + // complete suggestion. + histogram_tester.ExpectTotalCount("PaymentRequest.MissingPaymentFields", 0); +} + +// Tests that proper UMA metrics are logged when contacts section is incomplete. +IN_PROC_BROWSER_TEST_F(PaymentRequestMissingFieldsMetricsTest, + TestIncompleteContactDetails) { + NavigateTo("/payment_request_contact_details_test.html"); + base::HistogramTester histogram_tester; + + // Add an incomplete profile for billing address. The profile has email + // address only. + autofill::AutofillProfile billing_address = + autofill::test::GetIncompleteProfile2(); + AddAutofillProfile(billing_address); + autofill::CreditCard card = autofill::test::GetCreditCard(); + card.set_billing_address_id(billing_address.guid()); + AddCreditCard(card); // Visa + + // Show a Payment Request. + InvokePaymentRequestUI(); + + // Navigate away to abort the Payment Request and trigger the logs. + NavigateTo("/payment_request_email_test.html"); + + // Make sure the correct events were logged. + int32_t expected_event_bits = + JourneyLogger::EVENT_SHOWN | JourneyLogger::EVENT_USER_ABORTED | + JourneyLogger::EVENT_HAD_INITIAL_FORM_OF_PAYMENT | + JourneyLogger::EVENT_REQUEST_PAYER_NAME | + JourneyLogger::EVENT_REQUEST_PAYER_EMAIL | + JourneyLogger::EVENT_REQUEST_PAYER_PHONE | + JourneyLogger::EVENT_REQUEST_METHOD_BASIC_CARD | + JourneyLogger::EVENT_REQUEST_METHOD_OTHER | + JourneyLogger::EVENT_NEEDS_COMPLETION_CONTACT_INFO; + histogram_tester.ExpectBucketCount("PaymentRequest.Events", + expected_event_bits, 1); + + // Since the incomplete profile has email address only, the rest of the bits + // should be logged in MissingContactFields. + int32_t expected_missing_contact_bits = + PaymentsProfileComparator::kName | PaymentsProfileComparator::kPhone; + histogram_tester.ExpectBucketCount("PaymentRequest.MissingContactFields", + expected_missing_contact_bits, 1); + + // There should be no log for missing payment fields since the section had one + // complete suggestion. + histogram_tester.ExpectTotalCount("PaymentRequest.MissingPaymentFields", 0); + + // Even though the profile is incomplete, there should be no log for missing + // shipping fields since shipping was not required. + histogram_tester.ExpectTotalCount("PaymentRequest.MissingShippingFields", 0); +} + +} // namespace payments
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view.cc b/chrome/browser/ui/views/translate/translate_bubble_view.cc index fe99a680..24af817 100644 --- a/chrome/browser/ui/views/translate/translate_bubble_view.cc +++ b/chrome/browser/ui/views/translate/translate_bubble_view.cc
@@ -226,7 +226,7 @@ before_translate_view_ = AddChildView(GM2CreateViewBeforeTranslate()); translating_view_ = AddChildView(GM2CreateViewTranslating()); after_translate_view_ = AddChildView(GM2CreateViewAfterTranslate()); - error_view_ = AddChildView(CreateViewError()); + error_view_ = AddChildView(CreateViewErrorGM2()); advanced_view_ = AddChildView(CreateViewAdvanced()); } else if (bubble_ui_model_ == language::TranslateUIBubbleModel::TAB) { // |tab_translate_view| is the child view being used before/during/after @@ -237,7 +237,7 @@ after_translate_view_ = tab_translate_view_; advanced_view_source_ = AddChildView(TabUiCreateViewAdvanedSource()); advanced_view_target_ = AddChildView(TabUiCreateViewAdvanedTarget()); - error_view_ = AddChildView(CreateViewError()); + error_view_ = AddChildView(CreateViewErrorTab()); } else { before_translate_view_ = AddChildView(CreateViewBeforeTranslate()); translating_view_ = AddChildView(CreateViewTranslating()); @@ -311,6 +311,13 @@ ResetLanguage(); break; } + case BUTTON_ID_RETURN: { + SwitchView(TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE); + tabbed_pane_->SelectTabAt(1); + UpdateChildVisibilities(); + SizeToContents(); + break; + } } } @@ -320,14 +327,12 @@ bool TranslateBubbleView::ShouldShowCloseButton() const { return bubble_ui_model_ != language::TranslateUIBubbleModel::TAB && - bubble_ui_model_ != language::TranslateUIBubbleModel::BUTTON_GM2 && - model_->GetViewState() != TranslateBubbleModel::VIEW_STATE_ERROR; + bubble_ui_model_ != language::TranslateUIBubbleModel::BUTTON_GM2; } bool TranslateBubbleView::ShouldShowWindowTitle() const { return bubble_ui_model_ != language::TranslateUIBubbleModel::TAB && - bubble_ui_model_ != language::TranslateUIBubbleModel::BUTTON_GM2 && - model_->GetViewState() != TranslateBubbleModel::VIEW_STATE_ERROR; + bubble_ui_model_ != language::TranslateUIBubbleModel::BUTTON_GM2; } void TranslateBubbleView::ResetLanguage() { @@ -657,7 +662,14 @@ SwitchView(TranslateBubbleModel::VIEW_STATE_TRANSLATING); } } else if (bubble_ui_model_ == language::TranslateUIBubbleModel::TAB) { - if (model_->IsPageTranslatedInCurrentLanguages()) { + // Switch back to the original page language if target language is the same + // as source language without triggering translating. + if (target_language_combobox_->GetSelectedIndex() == + model_->GetOriginalLanguageIndex()) { + SwitchView(TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE); + tabbed_pane_->SelectTabAt(0); + ShowOriginal(); + } else if (model_->IsPageTranslatedInCurrentLanguages()) { SwitchView(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE); SizeToContents(); } else { @@ -667,8 +679,9 @@ UpdateLanguageNames(&original_language_name, &target_language_name); tabbed_pane_->GetTabAt(0)->SetTitleText(original_language_name); tabbed_pane_->GetTabAt(1)->SetTitleText(target_language_name); - SwitchView(TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE); + model_->Translate(); tabbed_pane_->SelectTabAt(1); + SwitchView(TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE); } } else { if (model_->IsPageTranslatedInCurrentLanguages()) { @@ -703,24 +716,32 @@ source_language_combobox_->GetSelectedIndex() - 1) { UpdateAdvancedView(); break; + } else { + model_->UpdateOriginalLanguageIndex( + source_language_combobox_->GetSelectedIndex() - 1); + UpdateAdvancedView(); + translate::ReportUiAction(translate::SOURCE_LANGUAGE_MENU_CLICKED); + break; } - model_->UpdateOriginalLanguageIndex( - source_language_combobox_->GetSelectedIndex() - 1); - UpdateAdvancedView(); - translate::ReportUiAction(translate::SOURCE_LANGUAGE_MENU_CLICKED); - break; } case COMBOBOX_ID_TARGET_LANGUAGE: { if (model_->GetTargetLanguageIndex() == - target_language_combobox_->GetSelectedIndex()) { + target_language_combobox_->GetSelectedIndex() || + // TAB UI doesn't change target language if it's the same as original + // source language. It simply shows page in original language and + // return to |after_translate_view_|. + (bubble_ui_model_ == language::TranslateUIBubbleModel::TAB && + target_language_combobox_->GetSelectedIndex() == + model_->GetOriginalLanguageIndex())) { UpdateAdvancedView(); break; + } else { + model_->UpdateTargetLanguageIndex( + target_language_combobox_->GetSelectedIndex()); + UpdateAdvancedView(); + translate::ReportUiAction(translate::TARGET_LANGUAGE_MENU_CLICKED); + break; } - model_->UpdateTargetLanguageIndex( - target_language_combobox_->GetSelectedIndex()); - UpdateAdvancedView(); - translate::ReportUiAction(translate::TARGET_LANGUAGE_MENU_CLICKED); - break; } } } @@ -1266,6 +1287,69 @@ return view; } +std::unique_ptr<views::View> TranslateBubbleView::CreateViewErrorTab() { + auto return_button = views::MdTextButton::CreateSecondaryUiButton( + this, l10n_util::GetStringUTF16(IDS_CANCEL)); + return_button->SetID(BUTTON_ID_RETURN); + return CreateViewErrorNoTitle(std::move(return_button)); +} + +std::unique_ptr<views::View> TranslateBubbleView::CreateViewErrorGM2() { + auto advanced_button = views::MdTextButton::CreateSecondaryUiButton( + this, l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_ADVANCED_BUTTON)); + advanced_button->SetID(BUTTON_ID_ADVANCED); + return CreateViewErrorNoTitle(std::move(advanced_button)); +} + +std::unique_ptr<views::View> TranslateBubbleView::CreateViewErrorNoTitle( + std::unique_ptr<views::Button> advanced_button) { + auto view = std::make_unique<views::View>(); + views::GridLayout* layout = + view->SetLayoutManager(std::make_unique<views::GridLayout>()); + + ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); + + enum { COLUMN_SET_ID_TITLE, COLUMN_SET_ID_BUTTONS }; + + views::ColumnSet* cs = layout->AddColumnSet(COLUMN_SET_ID_TITLE); + cs->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, + views::GridLayout::kFixedSize, views::GridLayout::USE_PREF, 0, + 0); + + cs = layout->AddColumnSet(COLUMN_SET_ID_BUTTONS); + cs->AddPaddingColumn(1.0, 0); + cs->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, + views::GridLayout::kFixedSize, views::GridLayout::USE_PREF, 0, + 0); + cs->AddPaddingColumn( + views::GridLayout::kFixedSize, + provider->GetDistanceMetric(views::DISTANCE_RELATED_BUTTON_HORIZONTAL)); + cs->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, + views::GridLayout::kFixedSize, views::GridLayout::USE_PREF, 0, + 0); + + layout->StartRow(views::GridLayout::kFixedSize, COLUMN_SET_ID_TITLE); + + int error_message_id = IDS_TRANSLATE_BUBBLE_COULD_NOT_TRANSLATE_TITLE; + auto error_message_label = std::make_unique<views::Label>( + l10n_util::GetStringUTF16(error_message_id), + views::style::CONTEXT_DIALOG_TITLE, views::style::STYLE_PRIMARY); + layout->AddView(std::move(error_message_label)); + + layout->StartRowWithPadding( + views::GridLayout::kFixedSize, COLUMN_SET_ID_BUTTONS, + views::GridLayout::kFixedSize, + provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL)); + auto try_again_button = views::MdTextButton::CreateSecondaryUiButton( + this, l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_TRY_AGAIN)); + try_again_button->SetID(BUTTON_ID_TRY_AGAIN); + layout->AddView(std::move(try_again_button)); + + layout->AddView(std::move(advanced_button)); + Layout(); + return view; +} + // TODO(hajimehoshi): Revice this later to show a specific message for each // error. (crbug/307350) std::unique_ptr<views::View> TranslateBubbleView::CreateViewAdvanced() { @@ -1576,8 +1660,8 @@ TranslateBubbleModel::ViewState view_state) { TranslateBubbleModel::ViewState current_state = model_->GetViewState(); if ((bubble_ui_model_ == language::TranslateUIBubbleModel::TAB && - !TabUiIsAdvancedState(view_state) && - !TabUiIsAdvancedState(current_state)) || + TabUiIsEquivalentState(view_state) && + TabUiIsEquivalentState(current_state)) || current_state == view_state) { return; } @@ -1596,11 +1680,11 @@ model_->ShowError(error_type); } -bool TranslateBubbleView::TabUiIsAdvancedState( +bool TranslateBubbleView::TabUiIsEquivalentState( TranslateBubbleModel::ViewState view_state) { - return !(view_state == TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE || - view_state == TranslateBubbleModel::VIEW_STATE_TRANSLATING || - view_state == TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE); + return view_state == TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE || + view_state == TranslateBubbleModel::VIEW_STATE_TRANSLATING || + view_state == TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE; } void TranslateBubbleView::UpdateAdvancedView() {
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view.h b/chrome/browser/ui/views/translate/translate_bubble_view.h index a2dabed..0cc9092 100644 --- a/chrome/browser/ui/views/translate/translate_bubble_view.h +++ b/chrome/browser/ui/views/translate/translate_bubble_view.h
@@ -144,7 +144,8 @@ BUTTON_ID_OPTIONS_MENU, BUTTON_ID_OPTIONS_MENU_TAB, BUTTON_ID_CLOSE, - BUTTON_ID_RESET + BUTTON_ID_RESET, + BUTTON_ID_RETURN }; enum ComboboxID { @@ -251,10 +252,19 @@ // Creates the 'after translate' view. std::unique_ptr<views::View> CreateViewAfterTranslate(); - // Creates the 'error' view. Caller takes ownership of the returned view. - // Three options depending on UI selection in kUseButtonTranslateBubbleUI. + // Creates the 'error' view for Button UI. Caller takes ownership of the + // returned view. std::unique_ptr<views::View> CreateViewError(); + // Creates the 'error' view skeleton UI with no title. Caller takes ownership + // of the returned view. + std::unique_ptr<views::View> CreateViewErrorNoTitle( + std::unique_ptr<views::Button> advanced_button); + + // Creates the 'error' view for Tab and Button_GM2 UI. + std::unique_ptr<views::View> CreateViewErrorTab(); + std::unique_ptr<views::View> CreateViewErrorGM2(); + // Creates the 'advanced' view. Caller takes ownership of the returned view. // Three options depending on UI selection in kUseButtonTranslateBubbleUI. std::unique_ptr<views::View> CreateViewAdvanced(); @@ -306,7 +316,7 @@ void ConfirmAdvancedOptions(); // Return true if the current state is in advanced state for TAB UI. - bool TabUiIsAdvancedState(TranslateBubbleModel::ViewState view_state); + bool TabUiIsEquivalentState(TranslateBubbleModel::ViewState view_state); // Handles the reset button in advanced view under Tab UI. void ResetLanguage();
diff --git a/chrome/browser/ui/webui/favicon_source.cc b/chrome/browser/ui/webui/favicon_source.cc index 0153c7e..0299e976 100644 --- a/chrome/browser/ui/webui/favicon_source.cc +++ b/chrome/browser/ui/webui/favicon_source.cc
@@ -10,15 +10,15 @@ #include "base/bind_helpers.h" #include "base/metrics/histogram_macros.h" #include "base/strings/string_number_conversions.h" -#include "chrome/browser/favicon/favicon_request_handler_factory.h" #include "chrome/browser/favicon/favicon_service_factory.h" +#include "chrome/browser/favicon/history_ui_favicon_request_handler_factory.h" #include "chrome/browser/history/top_sites_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/search/instant_io_context.h" #include "chrome/browser/sync/session_sync_service_factory.h" #include "chrome/common/url_constants.h" #include "chrome/common/webui_url_constants.h" -#include "components/favicon/core/favicon_request_handler.h" +#include "components/favicon/core/history_ui_favicon_request_handler.h" #include "components/favicon_base/favicon_url_parser.h" #include "components/history/core/browser/top_sites.h" #include "components/sync_sessions/open_tabs_ui_delegate.h" @@ -142,9 +142,11 @@ } } } - favicon::FaviconRequestHandler* favicon_request_handler = - FaviconRequestHandlerFactory::GetForBrowserContext(profile_); - if (!favicon_request_handler) { + favicon::HistoryUiFaviconRequestHandler* + history_ui_favicon_request_handler = + HistoryUiFaviconRequestHandlerFactory::GetForBrowserContext( + profile_); + if (!history_ui_favicon_request_handler) { SendDefaultResponse(callback); return; } @@ -152,7 +154,7 @@ SessionSyncServiceFactory::GetInstance()->GetForProfile(profile_); sync_sessions::OpenTabsUIDelegate* open_tabs = session_sync_service->GetOpenTabsUIDelegate(); - favicon_request_handler->GetRawFaviconForPageURL( + history_ui_favicon_request_handler->GetRawFaviconForPageURL( url, desired_size_in_pixel, base::BindOnce(&FaviconSource::OnFaviconDataAvailable, base::Unretained(this),
diff --git a/chrome/browser/vr/metrics/session_metrics_helper.cc b/chrome/browser/vr/metrics/session_metrics_helper.cc index ed0203c..47638a7 100644 --- a/chrome/browser/vr/metrics/session_metrics_helper.cc +++ b/chrome/browser/vr/metrics/session_metrics_helper.cc
@@ -262,8 +262,6 @@ std::make_unique<ukm::builders::XR_WebXR_Session>( ukm::GetSourceIdForWebContentsDocument(web_contents())))); - // TODO(https://crbug.com/968648): Use chain notation to set values for - // metrics. // TODO(https://crbug.com/968546): StartAction is currently not present in // XR.WebXR.Session event. Remove this & change the below code with // replacement metrics once they are designed: @@ -271,8 +269,7 @@ // PresentationStartAction::kOther); // WebVR does not come through this path as it does not have a separate // concept of inline sessions. - result.first->second->ukm_entry()->SetIsLegacyWebVR(false); - result.first->second->ukm_entry()->SetMode( + result.first->second->ukm_entry()->SetIsLegacyWebVR(false).SetMode( static_cast<int64_t>(device::SessionMode::kInline)); } @@ -354,16 +351,13 @@ UMA_HISTOGRAM_ENUMERATION("XR.WebXR.PresentationSession", action); - // TODO(https://crbug.com/968648): Use chain notation to set values for - // metrics. // TODO(https://crbug.com/968546): StartAction is currently not present in // XR.WebXR.Session event. Remove this & change the below code with // replacement metrics once they are designed: // webxr_immersive_session_tracker_->ukm_entry()->SetStartAction(action); - webxr_immersive_session_tracker_->ukm_entry()->SetIsLegacyWebVR( - is_legacy_webvr); - webxr_immersive_session_tracker_->ukm_entry()->SetMode( - static_cast<int64_t>(xr_session_mode)); + webxr_immersive_session_tracker_->ukm_entry() + ->SetIsLegacyWebVR(is_legacy_webvr) + .SetMode(static_cast<int64_t>(xr_session_mode)); } void SessionMetricsHelper::SetWebVREnabled(bool is_webvr_presenting) { @@ -688,17 +682,16 @@ std::make_unique<ukm::builders::XR_WebXR_Session>( ukm::GetSourceIdForWebContentsDocument(web_contents()))); if (pending_immersive_session_start_info_) { - // TODO(https://crbug.com/968648): Use chain notation to set values for - // metrics. // TODO(https://crbug.com/968546): StartAction is currently not present // in XR.WebXR.Session event. Remove this & change the below code with // replacement metrics once they are designed: // webxr_immersive_session_tracker_->ukm_entry()->SetStartAction( // pending_immersive_session_start_info_->action); - webxr_immersive_session_tracker_->ukm_entry()->SetIsLegacyWebVR( - pending_immersive_session_start_info_->is_legacy_webvr); - webxr_immersive_session_tracker_->ukm_entry()->SetMode( - static_cast<int64_t>(pending_immersive_session_start_info_->mode)); + webxr_immersive_session_tracker_->ukm_entry() + ->SetIsLegacyWebVR( + pending_immersive_session_start_info_->is_legacy_webvr) + .SetMode(static_cast<int64_t>( + pending_immersive_session_start_info_->mode)); pending_immersive_session_start_info_ = base::nullopt; } }
diff --git a/chrome/browser/vr/service/xr_device_impl.cc b/chrome/browser/vr/service/xr_device_impl.cc index 72bb987..a8bb327 100644 --- a/chrome/browser/vr/service/xr_device_impl.cc +++ b/chrome/browser/vr/service/xr_device_impl.cc
@@ -24,7 +24,6 @@ #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "content/public/common/origin_util.h" -#include "device/vr/vr_display_impl.h" #if defined(OS_WIN) #include "chrome/browser/vr/service/xr_session_request_consent_manager.h"
diff --git a/chrome/browser/vr/service/xr_device_impl.h b/chrome/browser/vr/service/xr_device_impl.h index 9f1fb0f..dad22da 100644 --- a/chrome/browser/vr/service/xr_device_impl.h +++ b/chrome/browser/vr/service/xr_device_impl.h
@@ -23,16 +23,12 @@ class WebContents; } // namespace content -namespace device { -class VRDisplayImpl; -} // namespace device - namespace vr { class XRRuntimeManager; class BrowserXRRuntime; -// The browser-side host for a device::VRDisplayImpl. Controls access to VR +// The browser-side host for VR services. Controls access to VR // APIs like poses and presentation. class XRDeviceImpl : public device::mojom::XRDevice { public:
diff --git a/chrome/browser/wake_lock/wake_lock_browsertest.cc b/chrome/browser/wake_lock/wake_lock_browsertest.cc new file mode 100644 index 0000000..0753014 --- /dev/null +++ b/chrome/browser/wake_lock/wake_lock_browsertest.cc
@@ -0,0 +1,138 @@ +// Copyright (c) 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 <string> + +#include "base/command_line.h" +#include "chrome/browser/permissions/permission_request_manager.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/content_switches.h" +#include "content/public/test/browser_test_utils.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "testing/gmock/include/gmock/gmock-matchers.h" + +namespace { + +// Trimmed down version of the class found in geolocation_browsertest.cc. +// Used to observe the creation of a single permission request without +// responding. +class PermissionRequestObserver : public PermissionRequestManager::Observer { + public: + explicit PermissionRequestObserver(content::WebContents* web_contents) + : request_manager_( + PermissionRequestManager::FromWebContents(web_contents)), + request_shown_(false) { + request_manager_->AddObserver(this); + } + ~PermissionRequestObserver() override { + // Safe to remove twice if it happens. + request_manager_->RemoveObserver(this); + } + + bool request_shown() { return request_shown_; } + + private: + // PermissionRequestManager::Observer + void OnBubbleAdded() override { + request_shown_ = true; + request_manager_->RemoveObserver(this); + } + + PermissionRequestManager* request_manager_; + bool request_shown_; + + DISALLOW_COPY_AND_ASSIGN(PermissionRequestObserver); +}; + +} // namespace + +class WakeLockBrowserTest : public InProcessBrowserTest { + protected: + // InProcessBrowserTest: + void SetUpCommandLine(base::CommandLine* command_line) override; + void SetUpOnMainThread() override; +}; + +void WakeLockBrowserTest::SetUpCommandLine(base::CommandLine* command_line) { + command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures, "WakeLock"); +} + +void WakeLockBrowserTest::SetUpOnMainThread() { + // Navigate to a secure context. + embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data"); + ASSERT_TRUE(embedded_test_server()->Start()); + ui_test_utils::NavigateToURL( + browser(), + embedded_test_server()->GetURL("localhost", "/simple_page.html")); + auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + EXPECT_THAT( + web_contents->GetMainFrame()->GetLastCommittedOrigin().Serialize(), + testing::StartsWith("http://localhost:")); +} + +IN_PROC_BROWSER_TEST_F(WakeLockBrowserTest, RequestPermissionScreen) { + // Requests for a screen lock should always be granted, and there should be no + // permission prompt. + PermissionRequestObserver observer( + browser()->tab_strip_model()->GetActiveWebContents()); + std::string response; + EXPECT_TRUE(content::ExecuteScriptAndExtractString( + browser()->tab_strip_model()->GetActiveWebContents(), + "WakeLock.requestPermission('screen').then(status => " + " domAutomationController.send(status));", + &response)); + EXPECT_EQ(response, "granted"); + EXPECT_EQ(observer.request_shown(), false); +} + +IN_PROC_BROWSER_TEST_F(WakeLockBrowserTest, + RequestPermissionScreenNoUserGesture) { + // Requests for a screen lock should always be granted, and there should be no + // permission prompt. + PermissionRequestObserver observer( + browser()->tab_strip_model()->GetActiveWebContents()); + std::string response; + EXPECT_TRUE(content::ExecuteScriptWithoutUserGestureAndExtractString( + browser()->tab_strip_model()->GetActiveWebContents(), + "WakeLock.requestPermission('screen').then(status => " + " domAutomationController.send(status));", + &response)); + EXPECT_EQ(response, "granted"); + EXPECT_EQ(observer.request_shown(), false); +} + +IN_PROC_BROWSER_TEST_F(WakeLockBrowserTest, RequestPermissionSystem) { + // Requests for a system lock should always be denied, and there should be no + // permission prompt. + PermissionRequestObserver observer( + browser()->tab_strip_model()->GetActiveWebContents()); + std::string response; + EXPECT_TRUE(content::ExecuteScriptAndExtractString( + browser()->tab_strip_model()->GetActiveWebContents(), + "WakeLock.requestPermission('system').then(status => " + " domAutomationController.send(status));", + &response)); + EXPECT_EQ(response, "denied"); + EXPECT_EQ(observer.request_shown(), false); +} + +IN_PROC_BROWSER_TEST_F(WakeLockBrowserTest, + RequestPermissionSystemNoUserGesture) { + // Requests for a system lock should always be denied, and there should be no + // permission prompt. + PermissionRequestObserver observer( + browser()->tab_strip_model()->GetActiveWebContents()); + std::string response; + EXPECT_TRUE(content::ExecuteScriptWithoutUserGestureAndExtractString( + browser()->tab_strip_model()->GetActiveWebContents(), + "WakeLock.requestPermission('system').then(status => " + " domAutomationController.send(status));", + &response)); + EXPECT_EQ(response, "denied"); + EXPECT_EQ(observer.request_shown(), false); +}
diff --git a/chrome/browser/web_applications/extensions/install_manager_bookmark_app_browsertest.cc b/chrome/browser/web_applications/extensions/install_manager_bookmark_app_browsertest.cc index 1969213..55abee6 100644 --- a/chrome/browser/web_applications/extensions/install_manager_bookmark_app_browsertest.cc +++ b/chrome/browser/web_applications/extensions/install_manager_bookmark_app_browsertest.cc
@@ -19,6 +19,11 @@ #include "extensions/browser/extension_registry.h" #include "testing/gtest/include/gtest/gtest.h" +#if defined(OS_CHROMEOS) +#include "ash/public/cpp/shelf_model.h" +#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" +#endif // defined(OS_CHROMEOS) + namespace extensions { class InstallManagerBookmarkAppDialogTest : public DialogBrowserTest { @@ -80,6 +85,14 @@ chrome::SetAutoAcceptBookmarkAppDialogForTesting(true); ShowAndVerifyUi(); chrome::SetAutoAcceptBookmarkAppDialogForTesting(false); + +#if defined(OS_CHROMEOS) + const ash::ShelfID shelf_id(installed_app_id()); + EXPECT_TRUE(ChromeLauncherController::instance()->IsPinned(shelf_id)); + EXPECT_EQ( + shelf_id, + ChromeLauncherController::instance()->shelf_model()->active_shelf_id()); +#endif // defined(OS_CHROMEOS) } IN_PROC_BROWSER_TEST_F(InstallManagerBookmarkAppDialogTest,
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index d4bbb09..9db1c715 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -1732,14 +1732,6 @@ // launches. const char kRegisteredBackgroundContents[] = "background_contents.registered"; -#if defined(OS_WIN) -// Boolean that specifies whether or not showing the welcome page following an -// OS upgrade is enabled. True by default. May be set by master_preferences or -// overridden by the WelcomePageOnOSUpgradeEnabled policy setting. -const char kWelcomePageOnOSUpgradeEnabled[] = - "browser.welcome_page_on_os_upgrade_enabled"; -#endif - // String that lists supported HTTP authentication schemes. const char kAuthSchemes[] = "auth.schemes";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 01f42dc48..7bb25ef 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -691,10 +691,6 @@ extern const char kRegisteredBackgroundContents[]; -#if defined(OS_WIN) -extern const char kWelcomePageOnOSUpgradeEnabled[]; -#endif - extern const char kAuthSchemes[]; extern const char kDisableAuthNegotiateCnameLookup[]; extern const char kEnableAuthNegotiatePort[];
diff --git a/chrome/common/search.mojom b/chrome/common/search.mojom index 92b70609..0812afc 100644 --- a/chrome/common/search.mojom +++ b/chrome/common/search.mojom
@@ -75,8 +75,9 @@ // Tells InstantExtended to toggle between most visited items or custom links. ToggleMostVisitedOrCustomLinks(int32 page_seq_no); - // Tells InstantExtended to toggle visibility of the shortcuts. - ToggleShortcutsVisibility(int32 page_seq_no); + // Tells InstantExtended to toggle visibility of the shortcuts and notify + // observers if |do_notify|. + ToggleShortcutsVisibility(int32 page_seq_no, bool do_notify); // Logs events from InstantExtended New Tab Pages. LogEvent(int32 page_seq_no,
diff --git a/chrome/installer/util/master_preferences.h b/chrome/installer/util/master_preferences.h index 1883271..53d56bd 100644 --- a/chrome/installer/util/master_preferences.h +++ b/chrome/installer/util/master_preferences.h
@@ -46,8 +46,7 @@ // "require_eula": true, // "skip_first_run_ui": true, // "system_level": false, -// "verbose_logging": true, -// "welcome_page_on_os_upgrade_enabled": false +// "verbose_logging": true // }, // "browser": { // "show_home_button": true
diff --git a/chrome/installer/util/master_preferences_constants.cc b/chrome/installer/util/master_preferences_constants.cc index 7ce48427..3ab961a 100644 --- a/chrome/installer/util/master_preferences_constants.cc +++ b/chrome/installer/util/master_preferences_constants.cc
@@ -12,8 +12,6 @@ "import_bookmarks_from_file"; const char kDistroSuppressDefaultBrowserPromptPref[] = "suppress_default_browser_prompt_for_version"; - const char kDistroWelcomePageOnOSUpgradeEnabled[] = - "welcome_page_on_os_upgrade_enabled"; const char kDoNotCreateAnyShortcuts[] = "do_not_create_any_shortcuts"; const char kDoNotCreateDesktopShortcut[] = "do_not_create_desktop_shortcut"; const char kDoNotCreateQuickLaunchShortcut[] =
diff --git a/chrome/installer/util/master_preferences_constants.h b/chrome/installer/util/master_preferences_constants.h index a115f01..832e59e0 100644 --- a/chrome/installer/util/master_preferences_constants.h +++ b/chrome/installer/util/master_preferences_constants.h
@@ -25,10 +25,6 @@ // String of Chrome version for which the "set as default browser" infobar will // never be shown. extern const char kDistroSuppressDefaultBrowserPromptPref[]; -// Boolean that specifies whether or not showing the welcome page following an -// OS upgrade is enabled. True by default. May be overridden by the -// WelcomePageOnOSUpgradeEnabled policy setting. -extern const char kDistroWelcomePageOnOSUpgradeEnabled[]; // Boolean. Prevent creation of all shortcuts to chrome, including the // desktop, quick launch, taskbar and the start menu shortcuts. extern const char kDoNotCreateAnyShortcuts[];
diff --git a/chrome/installer/util/master_preferences_unittest.cc b/chrome/installer/util/master_preferences_unittest.cc index 887f143..9c58b94e 100644 --- a/chrome/installer/util/master_preferences_unittest.cc +++ b/chrome/installer/util/master_preferences_unittest.cc
@@ -76,7 +76,6 @@ " \"distribution\": { \n" " \"show_welcome_page\": true,\n" " \"import_bookmarks_from_file\": \"c:\\\\foo\",\n" - " \"welcome_page_on_os_upgrade_enabled\": true,\n" " \"do_not_create_any_shortcuts\": true,\n" " \"do_not_create_desktop_shortcut\": true,\n" " \"do_not_create_quick_launch_shortcut\": true,\n" @@ -99,7 +98,6 @@ EXPECT_TRUE(prefs.read_from_file()); const char* const expected_true[] = { - installer::master_preferences::kDistroWelcomePageOnOSUpgradeEnabled, installer::master_preferences::kDoNotCreateAnyShortcuts, installer::master_preferences::kDoNotCreateDesktopShortcut, installer::master_preferences::kDoNotCreateQuickLaunchShortcut, @@ -154,7 +152,6 @@ } const char* const missing_bools[] = { - installer::master_preferences::kDistroWelcomePageOnOSUpgradeEnabled, installer::master_preferences::kDoNotRegisterForUpdateLaunch, installer::master_preferences::kMakeChromeDefault, installer::master_preferences::kMakeChromeDefaultForUser,
diff --git a/chrome/renderer/chromeos_delayed_callback_group.h b/chrome/renderer/chromeos_delayed_callback_group.h index 5fd8ae8..e878546 100644 --- a/chrome/renderer/chromeos_delayed_callback_group.h +++ b/chrome/renderer/chromeos_delayed_callback_group.h
@@ -6,6 +6,7 @@ #define CHROME_RENDERER_CHROMEOS_DELAYED_CALLBACK_GROUP_H_ #include <functional> +#include <list> #include <queue> #include "base/cancelable_callback.h" @@ -81,7 +82,8 @@ // Call all remaining callbacks with the RunReason::TIMEOUT parameter value. void ExpireAllCallbacks() EXCLUSIVE_LOCKS_REQUIRED(callbacks_lock_); - std::queue<CallbackEntry> callbacks_ GUARDED_BY(callbacks_lock_); + std::queue<CallbackEntry, std::list<CallbackEntry>> callbacks_ + GUARDED_BY(callbacks_lock_); base::TimeDelta expiration_delay_ GUARDED_BY(callbacks_lock_); base::CancelableOnceClosure expiration_timeout_; mutable base::Lock callbacks_lock_;
diff --git a/chrome/renderer/page_load_metrics/page_resource_data_use.cc b/chrome/renderer/page_load_metrics/page_resource_data_use.cc index ad71297..fb6f326 100644 --- a/chrome/renderer/page_load_metrics/page_resource_data_use.cc +++ b/chrome/renderer/page_load_metrics/page_resource_data_use.cc
@@ -118,7 +118,7 @@ total_received_bytes_ += received_data_length; } -bool PageResourceDataUse::DidCompleteResponse( +void PageResourceDataUse::DidCompleteResponse( const network::URLLoaderCompletionStatus& status) { // Report the difference in received bytes. is_complete_ = true; @@ -126,9 +126,7 @@ int64_t delta_bytes = status.encoded_data_length - total_received_bytes_; if (delta_bytes > 0) { total_received_bytes_ += delta_bytes; - return true; } - return false; } void PageResourceDataUse::DidCancelResponse() {
diff --git a/chrome/renderer/page_load_metrics/page_resource_data_use.h b/chrome/renderer/page_load_metrics/page_resource_data_use.h index cb94a90d..e11e7c9 100644 --- a/chrome/renderer/page_load_metrics/page_resource_data_use.h +++ b/chrome/renderer/page_load_metrics/page_resource_data_use.h
@@ -37,8 +37,8 @@ // Updates received bytes. void DidReceiveTransferSizeUpdate(int received_data_length); - // Updates received bytes from encoded length, returns whether it was updated. - bool DidCompleteResponse(const network::URLLoaderCompletionStatus& status); + // Updates received bytes from encoded length. + void DidCompleteResponse(const network::URLLoaderCompletionStatus& status); // Flags the resource as canceled. void DidCancelResponse();
diff --git a/chrome/renderer/page_load_metrics/page_timing_metrics_sender.cc b/chrome/renderer/page_load_metrics/page_timing_metrics_sender.cc index d3f7e20..8a1a692 100644 --- a/chrome/renderer/page_load_metrics/page_timing_metrics_sender.cc +++ b/chrome/renderer/page_load_metrics/page_timing_metrics_sender.cc
@@ -168,9 +168,8 @@ resource_it = new_resource_it.first; } - if (resource_it->second->DidCompleteResponse(status)) { - EnsureSendTimer(); - } + resource_it->second->DidCompleteResponse(status); + EnsureSendTimer(); modified_resources_.insert(resource_it->second.get()); }
diff --git a/chrome/renderer/searchbox/searchbox.cc b/chrome/renderer/searchbox/searchbox.cc index cedc7d9d..d9511411 100644 --- a/chrome/renderer/searchbox/searchbox.cc +++ b/chrome/renderer/searchbox/searchbox.cc
@@ -370,8 +370,8 @@ embedded_search_service_->ToggleMostVisitedOrCustomLinks(page_seq_no_); } -void SearchBox::ToggleShortcutsVisibility() { - embedded_search_service_->ToggleShortcutsVisibility(page_seq_no_); +void SearchBox::ToggleShortcutsVisibility(bool do_notify) { + embedded_search_service_->ToggleShortcutsVisibility(page_seq_no_, do_notify); } std::string SearchBox::FixupAndValidateUrl(const std::string& url) const {
diff --git a/chrome/renderer/searchbox/searchbox.h b/chrome/renderer/searchbox/searchbox.h index 049eb541..396bc447 100644 --- a/chrome/renderer/searchbox/searchbox.h +++ b/chrome/renderer/searchbox/searchbox.h
@@ -140,7 +140,7 @@ void ToggleMostVisitedOrCustomLinks(); // Sends ToggleShortcutsVisibility to the browser. - void ToggleShortcutsVisibility(); + void ToggleShortcutsVisibility(bool do_notify); // Attempts to fix obviously invalid URLs. Uses the "https" scheme unless // otherwise specified. Returns the fixed URL if valid, otherwise returns an
diff --git a/chrome/renderer/searchbox/searchbox_extension.cc b/chrome/renderer/searchbox/searchbox_extension.cc index 3a9e576..6990408 100644 --- a/chrome/renderer/searchbox/searchbox_extension.cc +++ b/chrome/renderer/searchbox/searchbox_extension.cc
@@ -667,7 +667,7 @@ static void UndoCustomLinkAction(); static void ResetCustomLinks(); static void ToggleMostVisitedOrCustomLinks(); - static void ToggleShortcutsVisibility(); + static void ToggleShortcutsVisibility(bool do_notify); static std::string FixupAndValidateUrl(const std::string& url); static void LogEvent(int event); static void LogSuggestionEventWithValue(int event, int data); @@ -1008,11 +1008,11 @@ } // static -void NewTabPageBindings::ToggleShortcutsVisibility() { +void NewTabPageBindings::ToggleShortcutsVisibility(bool do_notify) { SearchBox* search_box = GetSearchBoxForCurrentContext(); if (!search_box) return; - search_box->ToggleShortcutsVisibility(); + search_box->ToggleShortcutsVisibility(do_notify); } // static
diff --git a/chrome/service/service_process.cc b/chrome/service/service_process.cc index ba4dbd0..dba3432 100644 --- a/chrome/service/service_process.cc +++ b/chrome/service/service_process.cc
@@ -48,7 +48,6 @@ #include "components/prefs/json_pref_store.h" #include "mojo/core/embedder/embedder.h" #include "mojo/core/embedder/scoped_ipc_support.h" -#include "mojo/public/cpp/platform/features.h" #include "net/base/network_change_notifier.h" #include "net/url_request/url_fetcher.h" #include "services/network/public/cpp/network_switches.h" @@ -350,11 +349,7 @@ mojo::PlatformChannelServerEndpoint server_endpoint; #if defined(OS_MACOSX) // Mach receive rights (named server channels) are not Clone-able. - if (base::FeatureList::IsEnabled(mojo::features::kMojoChannelMac)) { - server_endpoint = std::move(server_endpoint_); - } else { - server_endpoint = server_endpoint_.Clone(); - } + server_endpoint = std::move(server_endpoint_); #elif defined(OS_POSIX) server_endpoint = server_endpoint_.Clone(); #elif defined(OS_WIN)
diff --git a/chrome/services/cups_proxy/cups_proxy_service_delegate.h b/chrome/services/cups_proxy/cups_proxy_service_delegate.h index 0db3263..61837815 100644 --- a/chrome/services/cups_proxy/cups_proxy_service_delegate.h +++ b/chrome/services/cups_proxy/cups_proxy_service_delegate.h
@@ -13,6 +13,8 @@ #include "base/memory/weak_ptr.h" #include "chromeos/printing/printer_configuration.h" +#include "base/task/post_task.h" + namespace chromeos { namespace printing { @@ -34,6 +36,7 @@ virtual base::Optional<chromeos::Printer> GetPrinter( const std::string& id) = 0; virtual bool IsPrinterInstalled(const Printer& printer) = 0; + virtual scoped_refptr<base::SingleThreadTaskRunner> GetIOTaskRunner() = 0; // |cb| will be run on this delegate's sequenced context. virtual void SetupPrinter(const Printer& printer,
diff --git a/chrome/services/cups_proxy/fake_cups_proxy_service_delegate.cc b/chrome/services/cups_proxy/fake_cups_proxy_service_delegate.cc index 7685271..aee7401 100644 --- a/chrome/services/cups_proxy/fake_cups_proxy_service_delegate.cc +++ b/chrome/services/cups_proxy/fake_cups_proxy_service_delegate.cc
@@ -20,6 +20,11 @@ return false; } +scoped_refptr<base::SingleThreadTaskRunner> +FakeCupsProxyServiceDelegate::GetIOTaskRunner() { + return nullptr; +} + void FakeCupsProxyServiceDelegate::SetupPrinter(const Printer& printer, PrinterSetupCallback cb) {}
diff --git a/chrome/services/cups_proxy/fake_cups_proxy_service_delegate.h b/chrome/services/cups_proxy/fake_cups_proxy_service_delegate.h index c6a2085..7ef8e84b 100644 --- a/chrome/services/cups_proxy/fake_cups_proxy_service_delegate.h +++ b/chrome/services/cups_proxy/fake_cups_proxy_service_delegate.h
@@ -25,6 +25,7 @@ std::vector<chromeos::Printer> GetPrinters() override; base::Optional<chromeos::Printer> GetPrinter(const std::string& id) override; bool IsPrinterInstalled(const Printer& printer) override; + scoped_refptr<base::SingleThreadTaskRunner> GetIOTaskRunner() override; void SetupPrinter(const Printer& printer, PrinterSetupCallback cb) override; };
diff --git a/chrome/services/cups_proxy/socket_manager.cc b/chrome/services/cups_proxy/socket_manager.cc index db4a11b..b2f8bc7c 100644 --- a/chrome/services/cups_proxy/socket_manager.cc +++ b/chrome/services/cups_proxy/socket_manager.cc
@@ -83,7 +83,8 @@ class SocketManagerImpl : public SocketManager { public: explicit SocketManagerImpl( - std::unique_ptr<net::UnixDomainClientSocket> socket); + std::unique_ptr<net::UnixDomainClientSocket> socket, + base::WeakPtr<chromeos::printing::CupsProxyServiceDelegate> delegate); ~SocketManagerImpl() override; void ProxyToCups(std::vector<uint8_t> request, @@ -106,10 +107,10 @@ void Fail(const char* error_message); // Sequence this manager runs on, |in_flight_->cb_| is posted here. - scoped_refptr<base::SequencedTaskRunner> main_runner_; + const scoped_refptr<base::SequencedTaskRunner> main_runner_; // Single thread task runner the thread-affine |socket_| runs on. - scoped_refptr<base::SingleThreadTaskRunner> socket_runner_; + const scoped_refptr<base::SingleThreadTaskRunner> socket_runner_; // Created in sequence but accessed and deleted on IO thread. std::unique_ptr<SocketRequest> in_flight_; @@ -125,13 +126,12 @@ SocketRequest::~SocketRequest() = default; SocketManagerImpl::SocketManagerImpl( - std::unique_ptr<net::UnixDomainClientSocket> socket) - : socket_(std::move(socket)), weak_factory_(this) { - socket_runner_ = - base::CreateSingleThreadTaskRunnerWithTraits(base::TaskTraits()); - DETACH_FROM_SEQUENCE(sequence_checker_); -} - + std::unique_ptr<net::UnixDomainClientSocket> socket, + base::WeakPtr<chromeos::printing::CupsProxyServiceDelegate> delegate) + : main_runner_(base::SequencedTaskRunnerHandle::Get()), + socket_runner_(delegate->GetIOTaskRunner()), + socket_(std::move(socket)), + weak_factory_(this) {} SocketManagerImpl::~SocketManagerImpl() {} void SocketManagerImpl::ProxyToCups(std::vector<uint8_t> request, @@ -139,11 +139,6 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!in_flight_); // Only handles one request at a time. - // Lazily save the main runner, needed to post |cb| to. - if (!main_runner_) { - main_runner_ = base::SequencedTaskRunnerHandle::Get(); - } - // Save request. in_flight_ = std::make_unique<SocketRequest>(); in_flight_->cb = std::move(cb); @@ -286,15 +281,19 @@ } // namespace -std::unique_ptr<SocketManager> SocketManager::Create() { +std::unique_ptr<SocketManager> SocketManager::Create( + base::WeakPtr<chromeos::printing::CupsProxyServiceDelegate> delegate) { return std::make_unique<SocketManagerImpl>( std::make_unique<net::UnixDomainClientSocket>( - kCupsSocketPath, false /* not abstract namespace */)); + kCupsSocketPath, false /* not abstract namespace */), + std::move(delegate)); } std::unique_ptr<SocketManager> SocketManager::CreateForTesting( - std::unique_ptr<net::UnixDomainClientSocket> socket) { - return std::make_unique<SocketManagerImpl>(std::move(socket)); + std::unique_ptr<net::UnixDomainClientSocket> socket, + base::WeakPtr<chromeos::printing::CupsProxyServiceDelegate> delegate) { + return std::make_unique<SocketManagerImpl>(std::move(socket), + std::move(delegate)); } } // namespace cups_proxy
diff --git a/chrome/services/cups_proxy/socket_manager.h b/chrome/services/cups_proxy/socket_manager.h index 04d98d80e..3221fe35 100644 --- a/chrome/services/cups_proxy/socket_manager.h +++ b/chrome/services/cups_proxy/socket_manager.h
@@ -11,6 +11,8 @@ #include "base/callback.h" #include "base/optional.h" +#include "chrome/services/cups_proxy/cups_proxy_service_delegate.h" + namespace net { class UnixDomainClientSocket; } // namespace net @@ -21,16 +23,18 @@ base::OnceCallback<void(base::Optional<std::vector<uint8_t>>)>; // This manager proxies IPP requests to the CUPS daemon and asynchronously -// responds with the IPP response. This class can be created anywhere but must -// be accessed from a sequenced context. +// responds with the IPP response. This class must be created and accessed +// from a sequenced context. class SocketManager { public: // Factory function. - static std::unique_ptr<SocketManager> Create(); + static std::unique_ptr<SocketManager> Create( + base::WeakPtr<chromeos::printing::CupsProxyServiceDelegate> delegate); // Factory function that allows injected dependencies, for testing. static std::unique_ptr<SocketManager> CreateForTesting( - std::unique_ptr<net::UnixDomainClientSocket> socket); + std::unique_ptr<net::UnixDomainClientSocket> socket, + base::WeakPtr<chromeos::printing::CupsProxyServiceDelegate> delegate); virtual ~SocketManager() = default;
diff --git a/chrome/services/cups_proxy/socket_manager_unittest.cc b/chrome/services/cups_proxy/socket_manager_unittest.cc index 0ef2175c..b79b38d 100644 --- a/chrome/services/cups_proxy/socket_manager_unittest.cc +++ b/chrome/services/cups_proxy/socket_manager_unittest.cc
@@ -8,14 +8,15 @@ #include "base/files/file_util.h" #include "base/path_service.h" +#include "base/test/scoped_task_environment.h" #include "base/threading/sequenced_task_runner_handle.h" #include "base/threading/thread_restrictions.h" #include "chrome/common/chrome_paths.h" +#include "chrome/services/cups_proxy/fake_cups_proxy_service_delegate.h" #include "chrome/services/cups_proxy/public/cpp/type_conversions.h" #include "chrome/services/cups_proxy/socket_manager.h" #include "net/base/io_buffer.h" #include "net/socket/unix_domain_client_socket_posix.h" -#include "net/test/test_with_scoped_task_environment.h" #include "testing/gtest/include/gtest/gtest.h" namespace cups_proxy { @@ -50,6 +51,20 @@ } // namespace +// Fake delegate granting handle to an IO-thread task runner. +class FakeServiceDelegate + : public chromeos::printing::FakeCupsProxyServiceDelegate { + public: + FakeServiceDelegate() = default; + ~FakeServiceDelegate() override = default; + + // Note: Can't simulate actual IO thread in unit_tests, so we serve an + // arbitrary SingleThreadTaskRunner. + scoped_refptr<base::SingleThreadTaskRunner> GetIOTaskRunner() override { + return base::CreateSingleThreadTaskRunner({}); + } +}; + // Gives full control over the "CUPS daemon" in this test. class FakeSocket : public net::UnixDomainClientSocket { public: @@ -158,11 +173,14 @@ class SocketManagerTest : public testing::Test { public: - SocketManagerTest() : weak_factory_(this) { + SocketManagerTest() { + delegate_ = std::make_unique<FakeServiceDelegate>(); + std::unique_ptr<FakeSocket> socket = std::make_unique<FakeSocket>(); socket_ = socket.get(); - manager_ = SocketManager::CreateForTesting(std::move(socket)); + manager_ = SocketManager::CreateForTesting(std::move(socket), + delegate_->GetWeakPtr()); } base::Optional<std::vector<uint8_t>> ProxyToCups(std::string request) { @@ -190,11 +208,14 @@ std::move(finish_cb).Run(); } + // Fake injected service delegate. + std::unique_ptr<FakeServiceDelegate> delegate_; + // Not owned. FakeSocket* socket_; std::unique_ptr<SocketManager> manager_; - base::WeakPtrFactory<SocketManagerTest> weak_factory_; + base::WeakPtrFactory<SocketManagerTest> weak_factory_{this}; }; // "basic_handshake" test file contains a simple HTTP request sent by libCUPS,
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index fbeca9e..8fcd94db 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1058,6 +1058,7 @@ "../browser/ui/passwords/google_password_manager_navigation_throttle_browsertest.cc", "../browser/ui/tabs/pinned_tab_service_browsertest.cc", "../browser/ui/views/tabs/tab_hover_card_bubble_view_browsertest.cc", + "../browser/wake_lock/wake_lock_browsertest.cc", # If this list is used on Android in the future, these browser / speech/* # files will probably not be applicable. @@ -1534,7 +1535,6 @@ "../browser/extensions/api/metrics_private/metrics_apitest.cc", "../browser/extensions/api/module/module_apitest.cc", "../browser/extensions/api/networking_config_chromeos_apitest_chromeos.cc", - "../browser/extensions/api/omnibox/omnibox_api_browsertest.cc", "../browser/extensions/api/page_capture/page_capture_apitest.cc", "../browser/extensions/api/passwords_private/passwords_private_apitest.cc", "../browser/extensions/api/permissions/permissions_apitest.cc", @@ -1811,6 +1811,7 @@ "../browser/ui/views/payments/payment_request_debit_browsertest.cc", "../browser/ui/views/payments/payment_request_has_enrolled_instrument_browsertest.cc", "../browser/ui/views/payments/payment_request_journey_logger_browsertest.cc", + "../browser/ui/views/payments/payment_request_missing_fields_metrics_browsertest.cc", "../browser/ui/views/payments/payment_request_no_update_with_browsertest.cc", "../browser/ui/views/payments/payment_request_payment_app_browsertest.cc", "../browser/ui/views/payments/payment_request_payment_response_browsertest.cc", @@ -3395,6 +3396,7 @@ if (enable_offline_pages) { sources += [ "../browser/offline_pages/android/auto_fetch_page_load_watcher_unittest.cc", + "../browser/offline_pages/android/offline_page_archive_publisher_impl_unittest.cc", "../browser/offline_pages/android/offline_page_auto_fetcher_service_unittest.cc", "../browser/offline_pages/background_loader_offliner_unittest.cc", "../browser/offline_pages/download_archive_manager_unittest.cc", @@ -5294,7 +5296,6 @@ ldflags = [] deps = [ - ":captured_sites_interactive_tests", ":test_support", ":test_support_ui", "//chrome:packed_resources",
diff --git a/chrome/test/android/BUILD.gn b/chrome/test/android/BUILD.gn index f0c64b2a0..a55994b4 100644 --- a/chrome/test/android/BUILD.gn +++ b/chrome/test/android/BUILD.gn
@@ -7,12 +7,21 @@ android_library("chrome_java_test_pagecontroller") { testonly = true java_files = [ + "javatests/src/org/chromium/chrome/test/pagecontroller/controllers/ElementController.java", + "javatests/src/org/chromium/chrome/test/pagecontroller/controllers/PageController.java", + "javatests/src/org/chromium/chrome/test/pagecontroller/controllers/first_run/DataSaverController.java", + "javatests/src/org/chromium/chrome/test/pagecontroller/controllers/first_run/SyncController.java", + "javatests/src/org/chromium/chrome/test/pagecontroller/controllers/first_run/TOSController.java", + "javatests/src/org/chromium/chrome/test/pagecontroller/controllers/ntp/NewTabPageController.java", + "javatests/src/org/chromium/chrome/test/pagecontroller/rules/ChromeUiApplicationTestRule.java", + "javatests/src/org/chromium/chrome/test/pagecontroller/rules/ChromeUiAutomatorTestRule.java", "javatests/src/org/chromium/chrome/test/pagecontroller/utils/BySelectorIndexUi2Locator.java", "javatests/src/org/chromium/chrome/test/pagecontroller/utils/BySelectorUi2Locator.java", "javatests/src/org/chromium/chrome/test/pagecontroller/utils/ChildIndexUi2Locator.java", "javatests/src/org/chromium/chrome/test/pagecontroller/utils/IUi2Locator.java", "javatests/src/org/chromium/chrome/test/pagecontroller/utils/PathUi2Locator.java", "javatests/src/org/chromium/chrome/test/pagecontroller/utils/Ui2Locators.java", + "javatests/src/org/chromium/chrome/test/pagecontroller/utils/UiAutomatorUtils.java", "javatests/src/org/chromium/chrome/test/pagecontroller/utils/UiLocationException.java", "javatests/src/org/chromium/chrome/test/pagecontroller/utils/UiLocatorHelper.java", "javatests/src/org/chromium/chrome/test/pagecontroller/utils/Utils.java", @@ -21,10 +30,32 @@ "//base:base_java", "//base:base_java_test_support", "//third_party/android_support_test_runner:runner_java", + "//third_party/junit", "//third_party/ub-uiautomator:ub_uiautomator_java", ] } +instrumentation_test_apk("chrome_java_test_pagecontroller_tests") { + apk_name = "ChromePageControllerTests" + apk_under_test = "//chrome/android:chrome_public_apk" + android_manifest = "javatests/src/org/chromium/chrome/test/pagecontroller/tests/AndroidManifest.xml" + target_sdk_version = 28 + testonly = true + java_files = [ + "javatests/src/org/chromium/chrome/test/pagecontroller/tests/ExampleTest.java", + "javatests/src/org/chromium/chrome/test/pagecontroller/tests/FirstRunControllerTest.java", + ] + deps = [ + ":chrome_java_test_pagecontroller", + "//third_party/junit", + ] + + if (!is_java_debug) { + proguard_enabled = true + proguard_configs = [ "//chrome/android/java/apk_for_test.flags" ] + } +} + junit_binary("chrome_java_test_pagecontroller_unit_tests") { testonly = true java_files = [
diff --git a/chrome/test/android/browsertests_apk/src/org/chromium/android_browsertests_apk/PaymentRequestTestBridge.java b/chrome/test/android/browsertests_apk/src/org/chromium/android_browsertests_apk/PaymentRequestTestBridge.java index 0bbb440..2bf6d89 100644 --- a/chrome/test/android/browsertests_apk/src/org/chromium/android_browsertests_apk/PaymentRequestTestBridge.java +++ b/chrome/test/android/browsertests_apk/src/org/chromium/android_browsertests_apk/PaymentRequestTestBridge.java
@@ -28,13 +28,16 @@ private final boolean mIsIncognito; private final boolean mIsValidSsl; private final boolean mIsWebContentsActive; + private final boolean mPrefsCanMakePayment; private final boolean mSkipUiForBasicCard; PaymentRequestDelegateForTest(boolean isIncognito, boolean isValidSsl, - boolean isWebContentsActive, boolean skipUiForBasicCard) { + boolean isWebContentsActive, boolean prefsCanMakePayment, + boolean skipUiForBasicCard) { mIsIncognito = isIncognito; mIsValidSsl = isValidSsl; mIsWebContentsActive = isWebContentsActive; + mPrefsCanMakePayment = prefsCanMakePayment; mSkipUiForBasicCard = skipUiForBasicCard; } @@ -55,6 +58,11 @@ } @Override + public boolean prefsCanMakePayment() { + return mPrefsCanMakePayment; + } + + @Override public boolean skipUiForBasicCard() { return false; } @@ -122,10 +130,11 @@ @CalledByNative public static void setUseDelegateForTest(boolean useDelegate, boolean isIncognito, - boolean isValidSsl, boolean isWebContentsActive, boolean skipUiForBasicCard) { + boolean isValidSsl, boolean isWebContentsActive, boolean prefsCanMakePayment, + boolean skipUiForBasicCard) { if (useDelegate) { - PaymentRequestFactory.sDelegateForTest = new PaymentRequestDelegateForTest( - isIncognito, isValidSsl, isWebContentsActive, skipUiForBasicCard); + PaymentRequestFactory.sDelegateForTest = new PaymentRequestDelegateForTest(isIncognito, + isValidSsl, isWebContentsActive, prefsCanMakePayment, skipUiForBasicCard); } else { PaymentRequestFactory.sDelegateForTest = null; }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/README.md b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/README.md new file mode 100644 index 0000000..cf0468c --- /dev/null +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/README.md
@@ -0,0 +1,62 @@ +# Chrome's Page Controller Test Library + +## Introduction + +Page Controllers simplify the task of writing and maintaining integration tests +by organizing the logic to interact with the various application UI components +into re-usable classes. Learn how to write and use Page Controllers to solve +your testing needs. + +## File Organization + +[controllers](https://cs.chromium.org/chromium/src/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/controllers/): Contains all the Page Controllers.<br/> +[rules](https://cs.chromium.org/chromium/src/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/rules/): Junit Test Rules that provide access to the Page Controllers in a +test case.<br/> +[tests](https://cs.chromium.org/chromium/src/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/tests/): Tests for the Page Controllers themselves.<br/> +[utils](https://cs.chromium.org/chromium/src/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/utils/): Utility classes that are useful for writing Page Controllers.<br/> + +## Writing Testcases + +See the [ExampleTest](https://cs.chromium.org/chromium/src/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/tests/ExampleTest.java) + +## Creating + Updating Page Controllers + +Currently the Page Controllers use UIAutomator under-the-hood. But it is +entirely possible to write methods or whole page controllers using Espresso or +some other driver framework. + +``` +/** + * Page controller for CoolNewPage + */ +class CoolNewPageController extends PageController { + // Locators allow the controller to find UI elements on the page + // It is preferred to use Resource Ids to find elements since they are + // stable across minor UI changes. + private static final IUi2Locator LOCATOR_COOL_PAGE = Ui2Locators.withResIds("cool_page"); + // Any of the resource ids in the list will result in a match. + private static final IUi2Locator LOCATOR_COOL_BUTTON = Ui2Locators.withResIds("cool_button_v1", "cool_button_v2"); + + public CoolerPageController clickButton() { + // [UiAutomatorUtils.click](https://cs.chromium.org/chromium/src/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/utils/UiAutomatorUtils.java?q=click) operates on UI elements via IUi2Locators. + // In general, methods that operate on IUi2Locators will throw if that + // locator could not find an UI elements on the page. + // UiAutomatorUtils has retry functionality with a configurable timeout, + // so that flakiness can be drastically reduced. + mUtils.click(LOCATOR_SOME_BUTTON); + + // If clicking on cool button should always result in the app going + // to the EvenCoolerPage, then the action method should return an + // instance of that controller via its assertIsCurrentPage() method. + // This ensures the UI state is synced upon the return of the method. + return EvenCoolerPageController.getInstance().assertIsCurrentPage(); + } + + // All page controllers must implement this method. + @Override + public SomePageController assertIsCurrentPage() { + mLocatorHelper.get(LOCATOR_SOME_PAGE); // Throws if not found + return this; + } +} +```
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/controllers/ElementController.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/controllers/ElementController.java new file mode 100644 index 0000000..68344e2 --- /dev/null +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/controllers/ElementController.java
@@ -0,0 +1,22 @@ +// 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.chrome.test.pagecontroller.controllers; + +import org.chromium.chrome.test.pagecontroller.utils.UiAutomatorUtils; +import org.chromium.chrome.test.pagecontroller.utils.UiLocatorHelper; + +/** + * Base class for a Page Controller or Page Element Controller. + * Allows Controllers to perform UI actions and verify UI state. + */ +public class ElementController { + protected final UiAutomatorUtils mUtils; + protected final UiLocatorHelper mLocatorHelper; + + public ElementController() { + mUtils = UiAutomatorUtils.getInstance(); + mLocatorHelper = mUtils.getLocatorHelper(); + } +}
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/controllers/PageController.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/controllers/PageController.java new file mode 100644 index 0000000..db4e676 --- /dev/null +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/controllers/PageController.java
@@ -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. + +package org.chromium.chrome.test.pagecontroller.controllers; + +import android.os.RemoteException; + +/** + * Base class for page controllers. + * A page controller allows tests to interact with a single page (think Android activity) + * in the app-under-test. + */ +public abstract class PageController extends ElementController { + public void pressAndroidBackButton() { + mUtils.pressBack(); + } + + public void pressAndroidHomeButton() { + mUtils.pressHome(); + } + + public void pressAndroidOverviewButton() { + try { + // UiDevice (used by UiAutomatorUtils) calls this the recent apps button, + // Android UI seems to prefer the overview button name (as evidenced by talkback's + // readout) + mUtils.pressRecentApps(); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * Checks if the current page displayed corresponds to this page controller. + * @return True if current page can be controlled by this controller, else false. + */ + public abstract boolean isCurrentPageThis(); +}
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/controllers/first_run/DataSaverController.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/controllers/first_run/DataSaverController.java new file mode 100644 index 0000000..2fb8e1d2 --- /dev/null +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/controllers/first_run/DataSaverController.java
@@ -0,0 +1,33 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.test.pagecontroller.controllers.first_run; + +import org.chromium.chrome.test.pagecontroller.controllers.PageController; +import org.chromium.chrome.test.pagecontroller.utils.IUi2Locator; +import org.chromium.chrome.test.pagecontroller.utils.Ui2Locators; + +/** + * Data Saver Dialog (part of the First Run Experience) Page Controller. + */ +public class DataSaverController extends PageController { + private static final IUi2Locator LOCATOR_DATA_SAVER = + Ui2Locators.withResIds("enable_data_saver_switch"); + private static final IUi2Locator LOCATOR_NEXT = Ui2Locators.withResIds("next_button"); + + private static DataSaverController sInstance = new DataSaverController(); + private DataSaverController() {} + public static DataSaverController getInstance() { + return sInstance; + } + + public void clickNext() { + mUtils.click(LOCATOR_NEXT); + } + + @Override + public boolean isCurrentPageThis() { + return mLocatorHelper.isOnScreen(LOCATOR_DATA_SAVER); + } +}
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/controllers/first_run/SyncController.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/controllers/first_run/SyncController.java new file mode 100644 index 0000000..f4b818b --- /dev/null +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/controllers/first_run/SyncController.java
@@ -0,0 +1,33 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.test.pagecontroller.controllers.first_run; + +import org.chromium.chrome.test.pagecontroller.controllers.PageController; +import org.chromium.chrome.test.pagecontroller.utils.IUi2Locator; +import org.chromium.chrome.test.pagecontroller.utils.Ui2Locators; + +/** + * Sync Dialog (part of First Run Experience) Page Controller. + */ +public class SyncController extends PageController { + private final static IUi2Locator LOCATOR_SYNC_CONTROLLER = + Ui2Locators.withResIds("signin_sync_title"); + private final static IUi2Locator LOCATOR_NO_THANKS = Ui2Locators.withResIds("negative_button"); + + private static SyncController sInstance = new SyncController(); + private SyncController() {} + public static SyncController getInstance() { + return sInstance; + } + + public void clickNoThanks() { + mUtils.click(LOCATOR_NO_THANKS); + } + + @Override + public boolean isCurrentPageThis() { + return mLocatorHelper.isOnScreen(LOCATOR_SYNC_CONTROLLER); + } +}
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/controllers/first_run/TOSController.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/controllers/first_run/TOSController.java new file mode 100644 index 0000000..f4965abf --- /dev/null +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/controllers/first_run/TOSController.java
@@ -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. + +package org.chromium.chrome.test.pagecontroller.controllers.first_run; + +import org.chromium.chrome.test.pagecontroller.controllers.PageController; +import org.chromium.chrome.test.pagecontroller.utils.IUi2Locator; +import org.chromium.chrome.test.pagecontroller.utils.Ui2Locators; + +/** + * TOS Dialog (part of the First Run Experience) Page Controller. + */ +public class TOSController extends PageController { + private static final IUi2Locator LOCATOR_TOS = Ui2Locators.withResIds("tos_and_privacy"); + private static final IUi2Locator LOCATOR_SEND_REPORT_CHECKBOX = + Ui2Locators.withResIds("send_report_checkbox"); + private static final IUi2Locator LOCATOR_ACCEPT = Ui2Locators.withResIds("terms_accept"); + + private static TOSController sInstance = new TOSController(); + private TOSController() {} + public static TOSController getInstance() { + return sInstance; + } + + @Override + public boolean isCurrentPageThis() { + return mLocatorHelper.isOnScreen(LOCATOR_TOS); + } + + public boolean isSendingReports() { + return mLocatorHelper.getOneChecked(LOCATOR_SEND_REPORT_CHECKBOX); + } + + public TOSController toggleSendReports() { + mUtils.click(LOCATOR_SEND_REPORT_CHECKBOX, LOCATOR_TOS); + return this; + } + + public void acceptAndContinue() { + mUtils.click(LOCATOR_ACCEPT); + } +}
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/controllers/ntp/NewTabPageController.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/controllers/ntp/NewTabPageController.java new file mode 100644 index 0000000..8d028b8 --- /dev/null +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/controllers/ntp/NewTabPageController.java
@@ -0,0 +1,28 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.test.pagecontroller.controllers.ntp; + +import org.chromium.chrome.test.pagecontroller.controllers.PageController; +import org.chromium.chrome.test.pagecontroller.utils.IUi2Locator; +import org.chromium.chrome.test.pagecontroller.utils.Ui2Locators; + +/** + * New Tab Page Page Controller, handles either Feed or Zine implementations. + */ +public class NewTabPageController extends PageController { + private static final IUi2Locator LOCATOR_NEW_TAB_PAGE = + Ui2Locators.withResIds("ntp_content", "feed_stream_recycler_view", "card_contents"); + + private static NewTabPageController sInstance = new NewTabPageController(); + private NewTabPageController() {} + public static NewTabPageController getInstance() { + return sInstance; + } + + @Override + public boolean isCurrentPageThis() { + return mLocatorHelper.isOnScreen(LOCATOR_NEW_TAB_PAGE); + } +}
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/rules/ChromeUiApplicationTestRule.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/rules/ChromeUiApplicationTestRule.java new file mode 100644 index 0000000..68b39b5 --- /dev/null +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/rules/ChromeUiApplicationTestRule.java
@@ -0,0 +1,59 @@ +// 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.chrome.test.pagecontroller.rules; + +import android.support.test.InstrumentationRegistry; + +import org.junit.rules.ExternalResource; + +import org.chromium.chrome.test.pagecontroller.controllers.PageController; +import org.chromium.chrome.test.pagecontroller.utils.UiAutomatorUtils; +import org.chromium.chrome.test.pagecontroller.utils.UiLocationException; + +/** + * Test rule that provides access to a Chrome application. + */ +public class ChromeUiApplicationTestRule extends ExternalResource { + // TODO(aluo): Adjust according to https://crrev.com/c/1585142. + private static final String PACKAGE_NAME_ARG = "PackageUnderTest"; + + private String mPackageName; + + /** + * Returns an instance of the page controller that corresponds to the current page. + * @param controllers List of possible page controller instances to search among. + * @return The detected page controller. + * @throws UiLocationError If page can't be determined. + */ + public static PageController detectPageAmong(PageController... controllers) { + for (PageController instance : controllers) { + if (instance.isCurrentPageThis()) return instance; + } + throw UiLocationException.newInstance("Could not detect current Page"); + } + + /** + * Launch the Chrome application. + */ + public void launchApplication() { + UiAutomatorUtils utils = UiAutomatorUtils.getInstance(); + utils.launchApplication(mPackageName); + } + + public String getApplicationPackage() { + return mPackageName; + } + + @Override + protected void before() throws Throwable { + super.before(); + mPackageName = InstrumentationRegistry.getArguments().getString(PACKAGE_NAME_ARG); + // If the runner didn't pass the package name under test to us, then we can assume + // that the target package name provided in the AndroidManifest is the app-under-test. + if (mPackageName == null) { + mPackageName = InstrumentationRegistry.getTargetContext().getPackageName(); + } + } +}
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/rules/ChromeUiAutomatorTestRule.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/rules/ChromeUiAutomatorTestRule.java new file mode 100644 index 0000000..06836e3 --- /dev/null +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/rules/ChromeUiAutomatorTestRule.java
@@ -0,0 +1,27 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.test.pagecontroller.rules; + +import org.junit.rules.TestWatcher; +import org.junit.runner.Description; + +import org.chromium.base.Log; +import org.chromium.chrome.test.pagecontroller.utils.UiAutomatorUtils; + +/** + * Custom Rule that logs useful information for debugging UiAutomator + * related issues in the event of a test failure. + */ +public class ChromeUiAutomatorTestRule extends TestWatcher { + private static final String TAG = "ChromeUiAutomatorTR"; + + @Override + protected void failed(Throwable e, Description description) { + super.failed(e, description); + Log.e(TAG, description.toString() + " failed", e); + UiAutomatorUtils utils = UiAutomatorUtils.getInstance(); + utils.printWindowHierarchy("UI hierarchy when " + description.toString() + " failed"); + } +}
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/tests/AndroidManifest.xml b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/tests/AndroidManifest.xml new file mode 100644 index 0000000..f66dde0 --- /dev/null +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/tests/AndroidManifest.xml
@@ -0,0 +1,24 @@ +<!-- + * Copyright 2019 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. +--> + +<manifest + xmlns:android="http://schemas.android.com/apk/res/android" + package="org.chromium.chrome.test.pagecontroller.tests"> + + <uses-permission android:name="android.permission.RUN_INSTRUMENTATION" /> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + + <!-- We add an application tag here just so that we can indicate that this + package needs to link against the android.test library, which is + needed when building test cases. --> + <application> + <uses-library android:name="android.test.runner" /> + </application> + + <instrumentation android:name="org.chromium.base.test.BaseChromiumAndroidJUnitRunner" + android:targetPackage="org.chromium.chrome" + android:label="Runner for org.chromium.chrome.test.pagecontroller"/> +</manifest>
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/tests/ExampleTest.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/tests/ExampleTest.java new file mode 100644 index 0000000..451b3625 --- /dev/null +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/tests/ExampleTest.java
@@ -0,0 +1,81 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.test.pagecontroller.tests; + +import android.support.test.filters.SmallTest; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.RuleChain; +import org.junit.rules.TestRule; +import org.junit.runner.RunWith; + +import org.chromium.base.test.BaseJUnit4ClassRunner; +import org.chromium.chrome.test.pagecontroller.controllers.PageController; +import org.chromium.chrome.test.pagecontroller.rules.ChromeUiApplicationTestRule; +import org.chromium.chrome.test.pagecontroller.rules.ChromeUiAutomatorTestRule; +import org.chromium.chrome.test.pagecontroller.utils.IUi2Locator; +import org.chromium.chrome.test.pagecontroller.utils.Ui2Locators; + +/** + * An example test that demonstrates how to use Page Controllers. + */ +@SmallTest +@RunWith(BaseJUnit4ClassRunner.class) +public class ExampleTest { + // ChromeUiAutomatorTestRule will capture a screen shot and UI Hierarchy info in the event + // of a test failure to aid test debugging. + public ChromeUiAutomatorTestRule mUiAutomatorRule = new ChromeUiAutomatorTestRule(); + + // ChromeUiApplicationTestRule provides a way to launch the Chrome Application under test + // and access to the Page Controllers. + public ChromeUiApplicationTestRule mChromeUiRule = new ChromeUiApplicationTestRule(); + + // The rule chain allows deterministic ordering of test rules so that the + // UiAutomatorRule will print debugging information in case of errors + // before the application is shut-down. + @Rule + public final TestRule mChain = RuleChain.outerRule(mChromeUiRule).around(mUiAutomatorRule); + + @Before + public void setUp() { + // Do any common setup here. + mChromeUiRule.launchApplication(); + } + + @After + public void tearDown() { + // Do any common cleanup here. + } + + @Test + public void testPageFound() { + PageController controller = new PageController() { + @Override + public boolean isCurrentPageThis() { + IUi2Locator packageLocator = + Ui2Locators.withPackageName(mChromeUiRule.getApplicationPackage()); + return mLocatorHelper.isOnScreen(packageLocator); + } + }; + Assert.assertTrue("Application should have loaded", controller.isCurrentPageThis()); + } + + @Test + public void testPageNotFound() { + PageController controller = new PageController() { + @Override + public boolean isCurrentPageThis() { + IUi2Locator packageLocator = Ui2Locators.withPackageName("wrong.package.name"); + return mLocatorHelper.isOnScreen(packageLocator); + } + }; + Assert.assertFalse( + "Wrong package should not have been detected", controller.isCurrentPageThis()); + } +}
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/tests/FirstRunControllerTest.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/tests/FirstRunControllerTest.java new file mode 100644 index 0000000..92a2d1f --- /dev/null +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/tests/FirstRunControllerTest.java
@@ -0,0 +1,46 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.test.pagecontroller.tests; + +import android.support.test.filters.SmallTest; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.RuleChain; +import org.junit.rules.TestRule; +import org.junit.runner.RunWith; + +import org.chromium.base.test.BaseJUnit4ClassRunner; +import org.chromium.chrome.test.pagecontroller.controllers.first_run.TOSController; +import org.chromium.chrome.test.pagecontroller.rules.ChromeUiApplicationTestRule; +import org.chromium.chrome.test.pagecontroller.rules.ChromeUiAutomatorTestRule; + +/** + * Test the First Run Experience. + */ +@SmallTest +@RunWith(BaseJUnit4ClassRunner.class) +public class FirstRunControllerTest { + public ChromeUiAutomatorTestRule mUiAutomatorRule = new ChromeUiAutomatorTestRule(); + public ChromeUiApplicationTestRule mChromeUiRule = new ChromeUiApplicationTestRule(); + + @Rule + public final TestRule mChain = RuleChain.outerRule(mChromeUiRule).around(mUiAutomatorRule); + + private TOSController mTOSController; + + @Before + public void setUp() { + mChromeUiRule.launchApplication(); + mTOSController = TOSController.getInstance(); + } + + @Test + public void testFirstRunIsShown() { + Assert.assertTrue("TOS page should be shown", mTOSController.isCurrentPageThis()); + } +}
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/utils/UiAutomatorUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/utils/UiAutomatorUtils.java new file mode 100644 index 0000000..547dfb66 --- /dev/null +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/utils/UiAutomatorUtils.java
@@ -0,0 +1,492 @@ +// 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.chrome.test.pagecontroller.utils; + +import android.content.Context; +import android.content.Intent; +import android.graphics.Point; +import android.graphics.Rect; +import android.os.Environment; +import android.os.ParcelFileDescriptor; +import android.os.Process; +import android.os.RemoteException; +import android.support.annotation.NonNull; +import android.support.test.InstrumentationRegistry; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject2; + +import org.chromium.base.Log; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Allows tests to perform UI actions. + */ +public class UiAutomatorUtils { + private static final String TAG = "UiAutomatorUtils"; + private static final int SWIPE_STEPS_PER_SECOND = 200; + private static final int MAX_SWIPES = 30; + private static final float DEFAULT_SWIPE_SECONDS_PER_PAGE = 0.2f; + private static final float DEFAULT_SWIPE_SCREEN_FRACTION = 0.6f; + private static final long SHORT_CLICK_DURATION = 10L; + private static final long LONG_CLICK_DURATION = 1000L; + // Give applications more time to launch. + private static final long LAUNCH_TIMEOUT_MULTIPLIER = 3L; + // 100 steps corresponds to ~1 secs, this was determined + // experimentally. Internally uses UiDevice.drag to simulate + // clicking, steps is one of the parameters to drag. + public static final int CLICK_STEPS_PER_SECOND = 100; + + private UiDevice mDevice; + private UiLocatorHelper mLocatorHelper; + + private static class LazyHolder { + static final UiAutomatorUtils sInstance = new UiAutomatorUtils(); + } + + public static UiAutomatorUtils getInstance() { + return LazyHolder.sInstance; + } + + private UiAutomatorUtils() { + mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); + mLocatorHelper = new UiLocatorHelper(); + } + + public String getText(UiObject2 root) { + return root.getText(); + } + + /** + * Returns the timeout used for location operations. + * @return Timeout in milliseconds. + */ + public long getTimeout() { + return mLocatorHelper.getTimeout(); + } + + /** + * Set the timeout used for location operations. + * @param timeout Timeout in milliseconds. + */ + public void setTimeout(long timeout) { + mLocatorHelper.setTimeout(timeout); + } + + /** + * Launch application. + * @param packageName Package name of the application. + */ + public void launchApplication(String packageName) { + Log.d(TAG, "Launching " + packageName); + launchApplication(packageName, mLocatorHelper.getTimeout() * LAUNCH_TIMEOUT_MULTIPLIER); + } + + /** + * Stops the application. + * @param packageName Package name of the application to stop. + */ + public void stopApplication(String packageName) { + Log.d(TAG, "Stopping " + packageName); + try { + executeShellCommand("am force-stop " + packageName); + } catch (IOException e) { + Log.d(TAG, "Failed to stop " + packageName); + e.printStackTrace(); + } + } + + public void pressBack() { + mDevice.pressBack(); + } + + public void pressHome() { + mDevice.pressHome(); + } + + public void pressRecentApps() throws RemoteException { + mDevice.pressRecentApps(); + } + + /** + * Takes device screenshot and saves it to screenShotFile. + * @param screenShotFile Where the screenshot should be saved. + */ + public void takeScreenShot(@NonNull File screenShotFile) { + if (mDevice.takeScreenshot(screenShotFile)) { + Log.d(TAG, "Screenshot successfully saved to " + screenShotFile.getAbsolutePath()); + } else { + Log.e(TAG, "Screenshot unsuccessful " + screenShotFile.getAbsolutePath()); + } + } + + /** + * Performs click outside of the UI element found using locator. + * The click will be centered in the rectangular screen area with the greatest + * width or height that does not overlap with the UI element. + * @param locator Locator to use to find the element. + */ + public void clickOutsideOf(@NonNull IUi2Locator locator) { + Rect bounds = getBounds(locator); + Log.d(TAG, + "Clicking outside of bounds with Bottom:" + bounds.bottom + " Top:" + bounds.top + + " Left:" + bounds.left + " Right:" + bounds.right); + clickOutsideOfArea(bounds.left, bounds.top, bounds.right, bounds.bottom); + } + + public UiLocatorHelper getLocatorHelper() { + return mLocatorHelper; + } + + /** + * Performs a long click on node. + * @param locator Locator to use to find the node. + */ + public void longClick(@NonNull IUi2Locator locator) { + clickDurationInternal(locator, LONG_CLICK_DURATION); + } + + /** + * Perform a click. + * @param locator Locator to find the UI element to click on. + * @param duration Milliseconds that the click should last for. + */ + private void clickDurationInternal(IUi2Locator locator, long duration) { + UiObject2 object2 = mLocatorHelper.getOne(locator); + Point center = object2.getVisibleCenter(); + mDevice.swipe(center.x, center.y, center.x, center.y, + (int) (CLICK_STEPS_PER_SECOND * duration / 1000L)); + } + + /** + * Get the rectangular bounds of the first UI element found using locator. + * @param locator Locator used to find the UI element. + * @return Bounds of the UI element. + */ + private Rect getBounds(@NonNull IUi2Locator locator) { + UiObject2 object2 = mLocatorHelper.getOne(locator); + return object2.getVisibleBounds(); + } + + /** + * Copied over from UiAutomator UiDevice v18.0.1, it was removed for some reason, but is useful. + * Executes a shell command using shell user identity, and return the standard output in string. + * <p> + * Calling function with large amount of output will have memory impacts, and the function call + * will block if the command executed is blocking. + * <p>Note: calling this function requires API level 21 or above + * @param cmd Command to run + * @return The standard output of the command + * @throws IOException + * @since API Level 21 + */ + public String executeShellCommand(@NonNull String cmd) throws IOException { + ParcelFileDescriptor pfd = + InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand( + cmd); + byte[] buf = new byte[512]; + int bytesRead; + FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd); + StringBuilder stdout = new StringBuilder(); + while ((bytesRead = fis.read(buf)) != -1) { + stdout.append(new String(buf, 0, bytesRead)); + } + fis.close(); + return stdout.toString(); + } + + /** + * Click on a node. + * @param locator Locator used to find the node. + * @throws UiLocationError If locator didn't find any nodes within timeout interval. + */ + public void click(@NonNull IUi2Locator locator) { + clickDurationInternal(locator, SHORT_CLICK_DURATION); + } + + /** + * Click on a node and checks for an expected outcome. + * @param locator Locator used to find the node to click on. + * @param outcomeLocator Locator to check for existence after the click. + * @throws UiLocationError If locator didn't find any nodes within timeout interval or if + * provided outcomeLocator didn't find any nodes after the click. + */ + public void click(@NonNull IUi2Locator locator, @NonNull IUi2Locator outcomeLocator) { + clickInternal(locator, outcomeLocator); + } + + /** + * Enters text in a node and press enter. + * @param locator Locator used to find the node. + * @param text The text to enter. + * @throws UiLocationError If locator didn't find any nodes within timeout interval. + */ + public void setTextAndEnter(@NonNull IUi2Locator locator, @NonNull String text) { + click(locator); + UiObject2 root = mLocatorHelper.getOne(locator); + root.setText(text); + mDevice.pressEnter(); + } + + /** + * Performs the swipe up gesture repeatedly until a locator is found. + * @param locator locator that will stop the swipe if found on screen. + * @param stopLocator locator that will cause an UiLocationError if found before locator. + * @throws UiLocationError + */ + public void swipeUpVerticallyUntilFound(IUi2Locator locator, IUi2Locator stopLocator) { + swipeVerticallyUntilFound(locator, stopLocator, DEFAULT_SWIPE_SCREEN_FRACTION); + } + + /** + * Performs the swipe down gesture repeatedly until a locator is found. + * @param locator locator that will stop the swipe if found on screen. + * @param stopLocator locator that will cause an UiLocationError if found before locator. + * @throws UiLocationError + */ + public void swipeDownVerticallyUntilFound(IUi2Locator locator, IUi2Locator stopLocator) { + swipeVerticallyUntilFound(locator, stopLocator, -DEFAULT_SWIPE_SCREEN_FRACTION); + } + + /** + * Performs a swipe down gesture that's centered on the screen. + * If the intention is to scroll to an element, consider using swipeDownVerticallyUntilFound. + * @param fractionOfScreen The length of the swipe as a fraction of the screen, with 1 being + * the max. + */ + public void swipeDownVertically(float fractionOfScreen) { + if (fractionOfScreen > 1 || fractionOfScreen <= 0) { + throw new IllegalArgumentException("fractionOfScreen must be in the interval [0,1]"); + } + swipeVertically(-fractionOfScreen); + } + + /** + * Performs a swipe up gesture that's centered on the screen. + * If the intention is to scroll to an element, consider using swipeUpVerticallyUntilFound. + * @param fractionOfScreen The length of the swipe as a fraction of the screen, with 1 being + * the max. + */ + public void swipeUpVertically(float fractionOfScreen) { + if (fractionOfScreen > 1 || fractionOfScreen <= 0) { + throw new IllegalArgumentException("fractionOfScreen must be in the interval [0,1]"); + } + swipeVertically(fractionOfScreen); + } + + /** + * Performs a swipe gesture between 2 locators. + * @param beginLocator Center the start of swipe on beginLocator. + * @param endLocator Center the end of swipe on endLocator. + * @param duration Time the swipe should take in milliseconds. + */ + public void swipe(IUi2Locator beginLocator, IUi2Locator endLocator, float duration) { + UiObject2 begin = mLocatorHelper.getOne(beginLocator); + UiObject2 end = mLocatorHelper.getOne(endLocator); + Point beginPoint = begin.getVisibleCenter(); + Point endPoint = end.getVisibleCenter(); + int steps = (int) (duration * SWIPE_STEPS_PER_SECOND / 1000); + steps = steps > 0 ? steps : 1; + mDevice.swipe(beginPoint.x, beginPoint.y, endPoint.x, endPoint.y, steps); + } + + /** + * Prints the UiAutomator window hierarchy to logcat. + * @param message A leading message for the debug log. + */ + public void printWindowHierarchy(String message) { + try { + List<String> hierarchy = getWindowHierarchy(); + Log.d(TAG, message); + for (String line : hierarchy) { + Log.d(TAG, line); + } + } catch (IOException e) { + // Just log any errors and move on, testing can still continue. + Log.e(TAG, "Printing hierarchy", e); + } + } + + private void launchApplication(String packageName, long timeout) { + Context context = InstrumentationRegistry.getContext(); + final Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName); + if (intent == null) { + throw new IllegalStateException("Could not get intent to launch " + packageName + + ", please ensure that it is installed"); + } + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + + IUi2Locator packageLocator = Ui2Locators.withPackageName(packageName); + long oldTimeout = getTimeout(); + try { + setTimeout(timeout); + mLocatorHelper.getOne(packageLocator); + } finally { + setTimeout(oldTimeout); + } + } + + // positive fraction indicates swipe up + private void swipeVerticallyUntilFound( + IUi2Locator locator, IUi2Locator stopLocator, float fractionOfScreen) { + if (mLocatorHelper.isOnScreen(locator)) return; + Utils.sleep(UiLocatorHelper.UI_CHECK_INTERVAL_MS); + int iterationsLeft = MAX_SWIPES; + while (!mLocatorHelper.isOnScreen(locator) && iterationsLeft-- > 0) { + if (mLocatorHelper.isOnScreen(stopLocator)) + throw UiLocationException.newInstance( + "Did not find locator while swiping to " + stopLocator, locator, null); + swipeVertically(fractionOfScreen); + Utils.sleep(UiLocatorHelper.UI_CHECK_INTERVAL_MS); + } + if (!mLocatorHelper.isOnScreen(locator)) { + throw UiLocationException.newInstance( + "Did not find locator after swiping for " + MAX_SWIPES + " times", locator, + null); + } + } + + private List<String> getWindowHierarchy() throws IOException { + File tempFile = null; + try { + tempFile = getTempFile("temp_window_hierarchy", ".txt"); + mDevice.dumpWindowHierarchy(tempFile.getAbsolutePath()); + List<String> hierarchy = readAllFromFile(tempFile); + List<String> formattedHiearchy = formatXml(hierarchy, 2); + return formattedHiearchy; + } finally { + if (tempFile != null) { + tempFile.delete(); + } + } + } + + // TODO(aluo): Refactor this to use standard libraries, see if Apache + // xml-commons can be used for this. + // Formats one-liner xml hierarchy dump into properly indented list of tags + // to ease readability in logs. + private List<String> formatXml(List<String> inputs, int indentSpaces) { + StringBuilder inputBuilder = new StringBuilder(); + List<String> output = new ArrayList<>(); + + for (String line : inputs) { + inputBuilder.append(line.trim()); + } + + String xmlLine = inputBuilder.toString(); + int indent = 0; + StringBuilder lineBuilder = new StringBuilder(); + int i; + for (i = 0; i < xmlLine.length() - 1; i++) { + char c = xmlLine.charAt(i); + char nextC = xmlLine.charAt(i + 1); + if (c == '<') { + if (nextC == '/') { + indent--; + } + lineBuilder.append(new String(new char[indent * indentSpaces]).replace("\0", " ")); + lineBuilder.append(c); + if (nextC != '/') { + indent++; + } + } else if (c == '>') { + lineBuilder.append(c); + output.add(lineBuilder.toString()); + lineBuilder.delete(0, lineBuilder.length()); + } else if (c == '/' && nextC == '>') { + indent--; + lineBuilder.append(c); + } else { + lineBuilder.append(c); + } + } + if (xmlLine.length() > 0) { + lineBuilder.append(xmlLine.charAt(i)); + output.add(lineBuilder.toString()); + } + return output; + } + + /** + * Swipe screen vertically by fractions of screen height. + * @param fractionOfScreen Amount to swipe by, -1 to 1. + * Negative value swipes down, positive up. + */ + private void swipeVertically(float fractionOfScreen) { + int x = mDevice.getDisplayWidth() / 2; + int h = mDevice.getDisplayHeight(); + int startY = h / 2 - (int) (fractionOfScreen / 2f * h); + int stopY = startY + (int) (fractionOfScreen * h); + int steps = (int) (DEFAULT_SWIPE_SECONDS_PER_PAGE * Math.abs(fractionOfScreen) + * SWIPE_STEPS_PER_SECOND); + Log.d(TAG, + "Swiping vertically from " + stopY + " to " + startY + " in " + steps + " steps"); + mDevice.swipe(x, stopY, x, startY, steps); + } + + private void clickOutsideOfArea(int minX, int minY, int maxX, int maxY) { + int screenHeight = mDevice.getDisplayHeight(); + int screenWidth = mDevice.getDisplayWidth(); + // Calculate horizontal and vertical margins from rect to screen's edge + int leftMargin = minX; + int rightMargin = screenWidth - maxX; + int topMargin = minY; + int bottomMargin = screenHeight - maxY; + // Find the biggest margin value (widest or tallest) + int maxMargin = + Collections.max(Arrays.asList(rightMargin, leftMargin, topMargin, bottomMargin)); + // Click on the center of the area with the biggest margin value, + // the order chosen here is arbitrary in case of a tie. + if (maxMargin == rightMargin) { + mDevice.click(maxX + rightMargin / 2, screenHeight / 2); + } else if (maxMargin == leftMargin) { + mDevice.click(leftMargin / 2, screenHeight / 2); + } else if (maxMargin == topMargin) { + mDevice.click(screenWidth / 2, topMargin / 2); + } else if (maxMargin == bottomMargin) { + mDevice.click(screenWidth / 2, screenHeight - bottomMargin / 2); + } + } + + private File getTempFile(String prefix, String suffix) throws IOException { + File cacheDir = Environment.getExternalStorageDirectory(); + Log.d(TAG, "Create temp file in: " + cacheDir); + Log.d(TAG, "My user id: " + Process.myUid()); + return File.createTempFile(prefix, suffix, cacheDir); + } + + private void clickInternal(IUi2Locator locator, IUi2Locator outcomeLocator) { + clickDurationInternal(locator, SHORT_CLICK_DURATION); + if (outcomeLocator != null) { + mLocatorHelper.getOne(outcomeLocator); + } + // If outcomeLocator is not specified, then caller intended not to check the + // effect of the click here. + } + + private List<String> readAllFromFile(File file) throws IOException { + List<String> strings = new ArrayList<>(); + try (FileInputStream fileStream = new FileInputStream(file); + InputStreamReader inputStream = new InputStreamReader(fileStream); + BufferedReader streamReader = new BufferedReader(inputStream)) { + String line; + while ((line = streamReader.readLine()) != null) { + strings.add(line); + } + } + Log.d(TAG, + "readAllFromFile read " + strings.size() + " lines from " + file.getAbsolutePath()); + return strings; + } +}
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/utils/UiLocatorHelper.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/utils/UiLocatorHelper.java index fcae32e..53d78b27 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/utils/UiLocatorHelper.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/utils/UiLocatorHelper.java
@@ -11,8 +11,6 @@ import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.UiObject2; -import org.chromium.base.Log; - import java.util.ArrayList; import java.util.List; @@ -27,10 +25,10 @@ public class UiLocatorHelper { private static final String TAG = "UiLocatorHelper"; private static final long DEFAULT_TIMEOUT_MS = 3000L; - private static final long DEFAULT_MAX_UI_SETTLE_TIME_MS = 200L; // UI_CHECK_INTERVAL_MS is intentionally not modifiable so that longer timeouts // don't lead to slowness due to the checking interval being too coarse. - private static final long UI_CHECK_INTERVAL_MS = DEFAULT_TIMEOUT_MS / 4L; + static final long UI_CHECK_INTERVAL_MS = DEFAULT_TIMEOUT_MS / 4L; + private static final long DEFAULT_MAX_UI_SETTLE_TIME_MS = 200L; private static final ElementConverter<String> CONVERTER_TEXT = object2 -> { return object2.getText(); @@ -51,7 +49,7 @@ private final UiDevice mDevice; private long mTimeout; - public UiLocatorHelper() { + UiLocatorHelper() { mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); mTimeout = DEFAULT_TIMEOUT_MS; } @@ -74,7 +72,6 @@ /** * Checks and waits if a node is found on the screen. - * * @param locator Locator used to find the node. * @return true if node is found, false otherwise. */ @@ -89,7 +86,6 @@ /** * Checks if a node is found on the screen, does not retry. - * * @param locator Locator used to find the node. * @param root Node to search under, or null if all the nodes should be searched. * Possible root staleness will make retries ineffective, this means @@ -238,7 +234,6 @@ /** * Returns the first element found using locator. - * * Throws UiLocationError if not found. * @param locator Locator to use to find the element. * @return UiObject2 @@ -250,7 +245,6 @@ /** * Returns the first element found using locator. - * * Could return null but does not throw. * @param locator Locator to use to find the element. * @param root Search for elements within root, or on the device if null. @@ -292,7 +286,7 @@ if (elapsedTime >= mTimeout) { break; } - sleep(UI_CHECK_INTERVAL_MS); + Utils.sleep(UI_CHECK_INTERVAL_MS); } while (true); throw UiLocationException.newInstance("Could not find any objects after " + elapsedTime + " ms and " + attempts + " attempts", @@ -319,7 +313,6 @@ /** * Delegate to be used with getCustomElements. - * * @param <T> The type of the element. */ static public interface CustomElementMaker<T> { @@ -381,7 +374,7 @@ // makeElement could throw while going through the list of roots, // so clear out any elements to avoid duplicates and stale ones. elements.clear(); - sleep(UI_CHECK_INTERVAL_MS); + Utils.sleep(UI_CHECK_INTERVAL_MS); // If the next interaction will cause timeout to be exceeded, then // flag isLastAttempt so client can choose to perform a work-around // instead of throwing an exception again. @@ -432,18 +425,15 @@ return allT; } - /** Could return empty list or throw StaleObject exception or throw NullPointerException*/ + /** + * Returns all nodes that matched the locator. + * Note that StaleObject or NPE may be thrown from this if the UI has gotten into an + * inconsistent state, this usually means the caller should retry the operation. + * @param locator Locator to use. + * @param root Root node to match under, or null to match on any node. + * @return List of matched nodes, possibly empty. + */ private List<UiObject2> getAllInternal(@NonNull IUi2Locator locator, UiObject2 root) { return root == null ? locator.locateAll(mDevice) : locator.locateAll(root); } - - private void sleep(long ms) { - try { - Thread.sleep(ms); - } catch (InterruptedException e) { - for (StackTraceElement elem : e.getStackTrace()) { - Log.e(TAG, elem.toString()); - } - } - } }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/utils/Utils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/utils/Utils.java index 1cb197b..03092b87 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/utils/Utils.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/utils/Utils.java
@@ -8,6 +8,8 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import org.chromium.base.Log; + import java.util.Collections; import java.util.List; @@ -16,6 +18,8 @@ */ public final class Utils { + private static final String TAG = "PageController Utils"; + /** * Calculates the time interval from previousTime to now. * @param previousTime The previousTime, as returned from a previous call to currentTime(). @@ -33,12 +37,33 @@ return SystemClock.uptimeMillis(); } - // Return empty list if t is null, else return a singleton list containing t. + /** + * Sleeps for ms, logs but does not throw exceptions. + * @param ms Milliseconds to sleep for. + */ + public static void sleep(long ms) { + try { + Thread.sleep(ms); + } catch (InterruptedException e) { + Log.e(TAG, "Sleep interrupted", e); + } + } + + /** + * Convert singleton to list. + * @param t Possibly null singleton. + * @return Empty list if t is null, else return a singleton list containing t. + */ public static <T> List<T> nullableIntoList(@Nullable T t) { return t == null ? Collections.<T>emptyList() : Collections.singletonList(t); } - // Returns the index-th item in the list or null if it's out of bounds. + /** + * Convert list and index into singleton. + * @param list List to be traversed. + * @param index 0-based index into the list. + * @return The index-th item in the list or null if it's out of bounds. + */ public static @Nullable<T> T nullableGet(@NonNull List<T> list, int index) { return index >= list.size() ? null : list.get(index); }
diff --git a/chrome/test/base/android/payment_request_test_bridge.cc b/chrome/test/base/android/payment_request_test_bridge.cc index b9ead57..e10bded4 100644 --- a/chrome/test/base/android/payment_request_test_bridge.cc +++ b/chrome/test/base/android/payment_request_test_bridge.cc
@@ -13,11 +13,12 @@ bool is_incognito, bool is_valid_ssl, bool is_web_contents_active, + bool prefs_can_make_payment, bool skip_ui_for_basic_card) { JNIEnv* env = base::android::AttachCurrentThread(); Java_PaymentRequestTestBridge_setUseDelegateForTest( env, use_delegate, is_incognito, is_valid_ssl, is_web_contents_active, - skip_ui_for_basic_card); + prefs_can_make_payment, skip_ui_for_basic_card); } struct NativeObserverCallbacks {
diff --git a/chrome/test/base/android/payment_request_test_bridge.h b/chrome/test/base/android/payment_request_test_bridge.h index e83571c..10a4e9f 100644 --- a/chrome/test/base/android/payment_request_test_bridge.h +++ b/chrome/test/base/android/payment_request_test_bridge.h
@@ -16,6 +16,7 @@ bool is_incognito, bool is_valid_ssl, bool is_web_contents_active, + bool prefs_can_make_payment, bool skip_ui_for_basic_card); // Sets an observer on future Java PaymentRequests that will call these
diff --git a/chrome/test/base/ui_test_utils.cc b/chrome/test/base/ui_test_utils.cc index 89de1bd..09b8418f 100644 --- a/chrome/test/base/ui_test_utils.cc +++ b/chrome/test/base/ui_test_utils.cc
@@ -17,6 +17,8 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/path_service.h" +#include "base/run_loop.h" +#include "base/scoped_observer.h" #include "base/strings/utf_string_conversions.h" #include "base/test/bind_test_util.h" #include "base/test/test_timeouts.h" @@ -33,6 +35,7 @@ #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/browser_navigator_params.h" +#include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/find_bar/find_notification_details.h" #include "chrome/browser/ui/find_bar/find_tab_helper.h" #include "chrome/browser/ui/location_bar/location_bar.h" @@ -46,7 +49,10 @@ #include "components/download/public/common/download_item.h" #include "components/history/core/browser/history_service_observer.h" #include "components/omnibox/browser/autocomplete_controller.h" +#include "components/omnibox/browser/omnibox_controller_emitter.h" #include "components/omnibox/browser/omnibox_edit_model.h" +#include "components/omnibox/browser/omnibox_popup_model.h" +#include "components/omnibox/browser/omnibox_view.h" #include "components/prefs/pref_service.h" #include "content/public/browser/download_manager.h" #include "content/public/browser/navigation_controller.h" @@ -150,6 +156,34 @@ DISALLOW_COPY_AND_ASSIGN(AppModalDialogWaiter); }; +class AutocompleteChangeObserver : public OmniboxControllerEmitter::Observer { + public: + explicit AutocompleteChangeObserver(Profile* profile) { + scoped_observer_.Add( + OmniboxControllerEmitter::GetForBrowserContext(profile)); + } + + ~AutocompleteChangeObserver() override = default; + + void Wait() { run_loop_.Run(); } + + // OmniboxControllerEmitter::Observer: + void OnOmniboxQuery(AutocompleteController* controller, + const base::string16& input_text) override {} + void OnOmniboxResultChanged(bool default_match_changed, + AutocompleteController* controller) override { + if (run_loop_.running()) + run_loop_.Quit(); + } + + private: + base::RunLoop run_loop_; + ScopedObserver<OmniboxControllerEmitter, OmniboxControllerEmitter::Observer> + scoped_observer_{this}; + + DISALLOW_COPY_AND_ASSIGN(AutocompleteChangeObserver); +}; + } // namespace bool GetCurrentTabTitle(const Browser* browser, base::string16* title) { @@ -367,19 +401,26 @@ observer->WaitForFinished(); } -void SendToOmniboxAndSubmit(LocationBar* location_bar, +void WaitForAutocompleteDone(Browser* browser) { + auto* controller = browser->window() + ->GetLocationBar() + ->GetOmniboxView() + ->model() + ->autocomplete_controller(); + while (!controller->done()) + AutocompleteChangeObserver(browser->profile()).Wait(); +} + +void SendToOmniboxAndSubmit(Browser* browser, const std::string& input, base::TimeTicks match_selection_timestamp) { + LocationBar* location_bar = browser->window()->GetLocationBar(); OmniboxView* omnibox = location_bar->GetOmniboxView(); omnibox->model()->OnSetFocus(false); omnibox->SetUserText(base::ASCIIToUTF16(input)); location_bar->AcceptInput(match_selection_timestamp); - while (!omnibox->model()->autocomplete_controller()->done()) { - content::WindowedNotificationObserver observer( - chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY, - content::NotificationService::AllSources()); - observer.Wait(); - } + + WaitForAutocompleteDone(browser); } Browser* GetBrowserNotInSet(const std::set<Browser*>& excluded_browsers) {
diff --git a/chrome/test/base/ui_test_utils.h b/chrome/test/base/ui_test_utils.h index 3febc41..2556432 100644 --- a/chrome/test/base/ui_test_utils.h +++ b/chrome/test/base/ui_test_utils.h
@@ -26,7 +26,6 @@ #include "url/gurl.h" class Browser; -class LocationBar; class Profile; namespace app_modal { @@ -182,9 +181,12 @@ // Download the given file and waits for the download to complete. void DownloadURL(Browser* browser, const GURL& download_url); +// Waits until the autocomplete controller reaches its done state. +void WaitForAutocompleteDone(Browser* browser); + // Send the given text to the omnibox and wait until it's updated. void SendToOmniboxAndSubmit( - LocationBar* location_bar, + Browser* browser, const std::string& input, base::TimeTicks match_selection_timestamp = base::TimeTicks());
diff --git a/chrome/test/chromedriver/capabilities.cc b/chrome/test/chromedriver/capabilities.cc index 89de48a..014a1fa1 100644 --- a/chrome/test/chromedriver/capabilities.cc +++ b/chrome/test/chromedriver/capabilities.cc
@@ -591,6 +591,25 @@ return Status(kOk); } +Status ParseSeleniumOptions( + const base::Value& capability, + Capabilities* capabilities) { + const base::DictionaryValue* selenium_options = NULL; + if (!capability.GetAsDictionary(&selenium_options)) + return Status(kInvalidArgument, "must be a dictionary"); + std::map<std::string, Parser> parser_map; + parser_map["loggingPrefs"] = base::Bind(&ParseLoggingPrefs); + + for (base::DictionaryValue::Iterator it(*selenium_options); !it.IsAtEnd(); + it.Advance()) { + if (parser_map.find(it.key()) == parser_map.end()) + continue; + Status status = parser_map[it.key()].Run(it.value(), capabilities); + if (status.IsError()) + return Status(kInvalidArgument, "cannot parse " + it.key(), status); + } + return Status(kOk); +} } // namespace Switches::Switches() {} @@ -763,10 +782,12 @@ } else { parser_map["chromeOptions"] = base::BindRepeating(&ParseChromeOptions); } - // goog:loggingPrefs is spec-compliant name, but loggingPrefs is still - // supported in legacy mode. - if (w3c_compliant || - desired_caps.GetDictionary("goog:loggingPrefs", nullptr)) { + // se:options.loggingPrefs and goog:loggingPrefs is spec-compliant name, + // but loggingPrefs is still supported in legacy mode. + if (desired_caps.GetDictionary("se:options.loggingPrefs", nullptr)) { + parser_map["se:options"] = base::BindRepeating(&ParseSeleniumOptions); + } else if (w3c_compliant || + desired_caps.GetDictionary("goog:loggingPrefs", nullptr)) { parser_map["goog:loggingPrefs"] = base::BindRepeating(&ParseLoggingPrefs); } else { parser_map["loggingPrefs"] = base::BindRepeating(&ParseLoggingPrefs);
diff --git a/chrome/test/chromedriver/client/chromedriver.py b/chrome/test/chromedriver/client/chromedriver.py index e1e5dab..f2712fe 100644 --- a/chrome/test/chromedriver/client/chromedriver.py +++ b/chrome/test/chromedriver/client/chromedriver.py
@@ -231,7 +231,9 @@ params = { 'goog:chromeOptions': options, - 'goog:loggingPrefs': logging_prefs + 'se:options': { + 'loggingPrefs': logging_prefs + } } if page_load_strategy:
diff --git a/chrome/test/data/android/render_tests/BookmarkTest.bookmark_manager_folder_selected.Nexus_5-19.png.sha1 b/chrome/test/data/android/render_tests/BookmarkTest.bookmark_manager_folder_selected.Nexus_5-19.png.sha1 index 66570f6..0963b67c 100644 --- a/chrome/test/data/android/render_tests/BookmarkTest.bookmark_manager_folder_selected.Nexus_5-19.png.sha1 +++ b/chrome/test/data/android/render_tests/BookmarkTest.bookmark_manager_folder_selected.Nexus_5-19.png.sha1
@@ -1 +1 @@ -e577a1a908010f2929d6f47bab823c5ec45cd386 \ No newline at end of file +c92eb683b85f26c37ff0cdcb1a2e95bdeee137a9 \ No newline at end of file
diff --git a/chrome/test/data/android/render_tests/BookmarkTest.bookmark_manager_one_folder.Nexus_5-19.png.sha1 b/chrome/test/data/android/render_tests/BookmarkTest.bookmark_manager_one_folder.Nexus_5-19.png.sha1 index ae7e783e..d35f3d8 100644 --- a/chrome/test/data/android/render_tests/BookmarkTest.bookmark_manager_one_folder.Nexus_5-19.png.sha1 +++ b/chrome/test/data/android/render_tests/BookmarkTest.bookmark_manager_one_folder.Nexus_5-19.png.sha1
@@ -1 +1 @@ -235755b6e2ecb0b5bcc493ee24cac5bd1186edaa \ No newline at end of file +498c2ad61394be8b7bdf4e003e7dc995cf789a7c \ No newline at end of file
diff --git a/chrome/test/data/extensions/api_test/management/launch_app_panel/launch.html b/chrome/test/data/extensions/api_test/management/launch_app_panel/launch.html index 33687a2..b3fb631 100644 --- a/chrome/test/data/extensions/api_test/management/launch_app_panel/launch.html +++ b/chrome/test/data/extensions/api_test/management/launch_app_panel/launch.html
@@ -11,4 +11,6 @@ <body> App launch page </body> + + <script src="launch.js"></script> </html>
diff --git a/chrome/test/data/extensions/api_test/management/launch_app_panel/launch.js b/chrome/test/data/extensions/api_test/management/launch_app_panel/launch.js new file mode 100644 index 0000000..2e4c2e4 --- /dev/null +++ b/chrome/test/data/extensions/api_test/management/launch_app_panel/launch.js
@@ -0,0 +1,5 @@ +// 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. + +chrome.test.sendMessage('launched app');
diff --git a/chrome/test/data/extensions/api_test/management/launch_app_tab/launch.html b/chrome/test/data/extensions/api_test/management/launch_app_tab/launch.html index 33687a2..90df5dd 100644 --- a/chrome/test/data/extensions/api_test/management/launch_app_tab/launch.html +++ b/chrome/test/data/extensions/api_test/management/launch_app_tab/launch.html
@@ -11,4 +11,5 @@ <body> App launch page </body> + <script src="launch.js"></script> </html>
diff --git a/chrome/test/data/extensions/api_test/management/launch_app_tab/launch.js b/chrome/test/data/extensions/api_test/management/launch_app_tab/launch.js new file mode 100644 index 0000000..2e4c2e4 --- /dev/null +++ b/chrome/test/data/extensions/api_test/management/launch_app_tab/launch.js
@@ -0,0 +1,5 @@ +// 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. + +chrome.test.sendMessage('launched app');
diff --git a/chrome/test/data/extensions/api_test/management/launch_on_install/background.js b/chrome/test/data/extensions/api_test/management/launch_on_install/background.js index d021ada..1f976f0 100644 --- a/chrome/test/data/extensions/api_test/management/launch_on_install/background.js +++ b/chrome/test/data/extensions/api_test/management/launch_on_install/background.js
@@ -11,10 +11,7 @@ console.log("Launch " + extensionInfo.name + " (" + extensionInfo.id + ")"); - chrome.management.launchApp(extensionInfo.id, function() { - chrome.test.sendMessage("launched app"); - }); - + chrome.management.launchApp(extensionInfo.id); }); chrome.test.sendMessage("launcher loaded");
diff --git a/chrome/test/data/local_ntp/customize_menu_browsertest.js b/chrome/test/data/local_ntp/customize_menu_browsertest.js index f5975cd..5874f55 100644 --- a/chrome/test/data/local_ntp/customize_menu_browsertest.js +++ b/chrome/test/data/local_ntp/customize_menu_browsertest.js
@@ -17,6 +17,7 @@ * @const */ test.customizeMenu.IDS = { + BACKGROUNDS_BUTTON: 'backgrounds-button', BACKGROUNDS_MENU: 'backgrounds-menu', BACKGROUNDS_IMAGE_MENU: 'backgrounds-image-menu', COLORS_BUTTON: 'colors-button', @@ -28,6 +29,7 @@ MENU_BACK: 'menu-back', MENU_CANCEL: 'menu-cancel', MENU_DONE: 'menu-done', + MENU_TITLE: 'menu-title', SHORTCUTS_BUTTON: 'shortcuts-button', SHORTCUTS_HIDE_TOGGLE: 'sh-hide-toggle', SHORTCUTS_MENU: 'shortcuts-menu', @@ -41,8 +43,8 @@ * @const */ test.customizeMenu.CLASSES = { + COLLECTION_TILE: 'bg-sel-tile', ENTRY_POINT_ENHANCED: 'ep-enhanced', - MENU_SHOWN: 'menu-shown', SELECTED: 'selected', }; @@ -66,6 +68,27 @@ /** * The number of times + * chrome.embeddedSearch.newTabPage.applyAutogeneratedTheme is called. + * @type {number} + */ +test.customizeMenu.applyAutogeneratedThemeCount = 0; + +/** + * The number of times + * chrome.embeddedSearch.newTabPage.confirmThemeChanges is called. + * @type {number} + */ +test.customizeMenu.confirmThemeChangesCount = 0; + +/** + * The number of times + * chrome.embeddedSearch.newTabPage.revertThemeChanges is called. + * @type {number} + */ +test.customizeMenu.revertThemeChangesCount = 0; + +/** + * The number of times * chrome.embeddedSearch.newTabPage.toggleMostVisitedOrCustomLinks is called. * @type {number} */ @@ -102,6 +125,9 @@ test.customizeMenu.stubs.reset(); test.customizeMenu.isUsingMostVisited = false; test.customizeMenu.areShortcutsVisible = true; + test.customizeMenu.applyAutogeneratedThemeCount = 0; + test.customizeMenu.confirmThemeChangesCount = 0; + test.customizeMenu.revertThemeChangesCount = 0; test.customizeMenu.toggleMostVisitedOrCustomLinksCount = 0; test.customizeMenu.toggleShortcutsVisibilityCount = 0; test.customizeMenu.timesCustomBackgroundWasSet = 0; @@ -112,9 +138,9 @@ // Functions from test_utils.js are automatically imported. /** - * Tests that the richer picker opens to the default submenu (Background). + * Tests that the richer picker opens. */ -test.customizeMenu.testOpenCustomizeMenu = function() { +test.customizeMenu.testMenu_Open = function() { init(); const menuButton = $(test.customizeMenu.IDS.EDIT_BG); @@ -127,28 +153,170 @@ const menuDialog = $(test.customizeMenu.IDS.CUSTOMIZATION_MENU); assertTrue(menuDialog.open); assertTrue(elementIsVisible(menuDialog)); - - // The default submenu (Background) should be shown. - const backgroundSubmenu = $(test.customizeMenu.IDS.BACKGROUNDS_MENU); - assertTrue(backgroundSubmenu.classList.contains( - test.customizeMenu.CLASSES.MENU_SHOWN)); }; /** - * Tests that the Shortcuts submenu can be opened. + * Tests that the richer picker submenus open. */ -test.customizeMenu.testShortcuts_OpenSubmenu = function() { +test.customizeMenu.testMenu_OpenSubmenus = function() { init(); - // Open the Shortcuts submenu. + // Open the richer picker. The default submenu (Background) should be shown. $(test.customizeMenu.IDS.EDIT_BG).click(); - $(test.customizeMenu.IDS.SHORTCUTS_BUTTON).click(); + const backgroundSubmenu = $(test.customizeMenu.IDS.BACKGROUNDS_MENU); + const shortcutsSubmenu = $(test.customizeMenu.IDS.SHORTCUTS_MENU); + const colorSubmenu = $(test.customizeMenu.IDS.COLORS_MENU); + assertTrue(elementIsVisible(backgroundSubmenu)); + assertFalse(elementIsVisible(shortcutsSubmenu)); + assertFalse(elementIsVisible(colorSubmenu)); - assertTrue($(test.customizeMenu.IDS.SHORTCUTS_MENU) - .classList.contains(test.customizeMenu.CLASSES.MENU_SHOWN)); + // Open the Shortcuts submenu. All other submenus should be hidden. + $(test.customizeMenu.IDS.SHORTCUTS_BUTTON).click(); + assertFalse(elementIsVisible(backgroundSubmenu)); + assertTrue(elementIsVisible(shortcutsSubmenu)); + assertFalse(elementIsVisible(colorSubmenu)); + + // Open the Color submenu. + $(test.customizeMenu.IDS.COLORS_BUTTON).click(); + assertFalse(elementIsVisible(backgroundSubmenu)); + assertFalse(elementIsVisible(shortcutsSubmenu)); + assertTrue(elementIsVisible(colorSubmenu)); + + // Open the Background submenu. + $(test.customizeMenu.IDS.BACKGROUNDS_BUTTON).click(); + assertTrue(elementIsVisible(backgroundSubmenu)); + assertFalse(elementIsVisible(shortcutsSubmenu)); + assertFalse(elementIsVisible(colorSubmenu)); }; /** + * Tests that user selections are saved across submenus. + */ +test.customizeMenu.testMenu_SaveUserSelections = function() { + setupFakeAsyncCollectionLoad(); + init(); + + $(test.customizeMenu.IDS.EDIT_BG).click(); + + // Select a background. + setupFakeAsyncImageLoad('coll_tile_0'); + $('coll_tile_0').click(); + const background = $('img_tile_0'); + background.click(); + assertTrue(background.parentElement.classList.contains( + test.customizeMenu.CLASSES.SELECTED)); + // The submenu's title should be the image collection's. + assertEquals( + 'Collection 1', $(test.customizeMenu.IDS.MENU_TITLE).textContent); + + // Select some shortcut options. + $(test.customizeMenu.IDS.SHORTCUTS_BUTTON).click(); + assertShortcutOptionsSelected( + /*clSelected=*/ true, /*mvSelected=*/ false, /*isHidden=*/ false); + $(test.customizeMenu.IDS.SHORTCUTS_OPTION_MOST_VISITED).click(); + $(test.customizeMenu.IDS.SHORTCUTS_HIDE_TOGGLE).click(); + assertShortcutOptionsSelected( + /*clSelected=*/ false, /*mvSelected=*/ true, /*isHidden=*/ true); + + // Select a color. + $(test.customizeMenu.IDS.COLORS_BUTTON).click(); + const colorOptions = + $(test.customizeMenu.IDS.COLORS_MENU) + .getElementsByClassName(test.customizeMenu.CLASSES.COLLECTION_TILE); + const color = colorOptions[1]; // Skip the default theme option. + color.click(); + assertTrue(color.parentElement.classList.contains( + test.customizeMenu.CLASSES.SELECTED)); + + // Open the Background submenu and check that it's still selected. + $(test.customizeMenu.IDS.BACKGROUNDS_BUTTON).click(); + assertTrue(background.parentElement.classList.contains( + test.customizeMenu.CLASSES.SELECTED)); + // The image collection should still be open. + assertEquals( + 'Collection 1', $(test.customizeMenu.IDS.MENU_TITLE).textContent); + + // Open the Shortcuts submenu and check that they're still selected. + $(test.customizeMenu.IDS.SHORTCUTS_BUTTON).click(); + assertShortcutOptionsSelected( + /*clSelected=*/ false, /*mvSelected=*/ true, /*isHidden=*/ true); + + // Open the Color submenu and check that it's still selected. + $(test.customizeMenu.IDS.COLORS_BUTTON).click(); + assertTrue(color.parentElement.classList.contains( + test.customizeMenu.CLASSES.SELECTED)); +}; + +/** + * Tests that user selections across submenus are applied on "done". + */ +test.customizeMenu.testMenu_ApplyUserSelections = function() { + setupFakeAsyncCollectionLoad(); + init(); + + $(test.customizeMenu.IDS.EDIT_BG).click(); + + // Select a background. + setupFakeAsyncImageLoad('coll_tile_0'); + $('coll_tile_0').click(); + $('img_tile_0').click(); + + // Select a shortcut option. + $(test.customizeMenu.IDS.SHORTCUTS_BUTTON).click(); + $(test.customizeMenu.IDS.SHORTCUTS_OPTION_MOST_VISITED).click(); + + // Select a color. + $(test.customizeMenu.IDS.COLORS_BUTTON).click(); + const colorOptions = + $(test.customizeMenu.IDS.COLORS_MENU) + .getElementsByClassName(test.customizeMenu.CLASSES.COLLECTION_TILE); + colorOptions[1].click(); // Skip the default theme option. + + // Click done and check that all selections have applied. + $(test.customizeMenu.IDS.MENU_DONE).click(); + assertEquals(1, test.customizeMenu.timesCustomBackgroundWasSet); + assertEquals(1, test.customizeMenu.toggleMostVisitedOrCustomLinksCount); + assertEquals(1, test.customizeMenu.applyAutogeneratedThemeCount); + assertEquals(1, test.customizeMenu.confirmThemeChangesCount); +}; + +/** + * Tests that user selections across submenus are not applied on "cancel". + */ +test.customizeMenu.testMenu_CancelUserSelections = function() { + setupFakeAsyncCollectionLoad(); + init(); + + $(test.customizeMenu.IDS.EDIT_BG).click(); + + // Select a background. + setupFakeAsyncImageLoad('coll_tile_0'); + $('coll_tile_0').click(); + $('img_tile_0').click(); + + // Select a shortcut option. + $(test.customizeMenu.IDS.SHORTCUTS_BUTTON).click(); + $(test.customizeMenu.IDS.SHORTCUTS_OPTION_MOST_VISITED).click(); + + // Select a color. + $(test.customizeMenu.IDS.COLORS_BUTTON).click(); + const colorOptions = + $(test.customizeMenu.IDS.COLORS_MENU) + .getElementsByClassName(test.customizeMenu.CLASSES.COLLECTION_TILE); + const color = colorOptions[1]; // Skip the default theme option. + color.click(); + + // Click cancel and check that all changes have been reverted. + $(test.customizeMenu.IDS.MENU_CANCEL).click(); + assertEquals(0, test.customizeMenu.timesCustomBackgroundWasSet); + assertEquals(0, test.customizeMenu.toggleMostVisitedOrCustomLinksCount); + assertEquals(1, test.customizeMenu.applyAutogeneratedThemeCount); + assertEquals(1, test.customizeMenu.revertThemeChangesCount); +}; + +//// SHORTCUT SUBMENU TESTS //// + +/** * Tests that the custom link option will be preselected. */ test.customizeMenu.testShortcuts_CustomLinksPreselected = function() { @@ -319,6 +487,8 @@ assertEquals(1, test.customizeMenu.toggleShortcutsVisibilityCount); }; +//// COLOR SUBMENU TESTS //// + /** * Test that Customization dialog doesn't have Colors option when Colors are * disabled. @@ -341,23 +511,6 @@ assertTrue(elementIsVisible($(test.customizeMenu.IDS.COLORS_BUTTON))); }; -/** - * Test that Colors menu is visible after Colors button is clicked. - */ -test.customizeMenu.testColors_MenuVisibility = function() { - init(); - - $(test.customizeMenu.IDS.EDIT_BG).click(); - assertTrue(elementIsVisible($(test.customizeMenu.IDS.COLORS_BUTTON))); - assertFalse(elementIsVisible($(test.customizeMenu.IDS.COLORS_MENU))); - - $(test.customizeMenu.IDS.COLORS_BUTTON).click(); - assertTrue(elementIsVisible($(test.customizeMenu.IDS.COLORS_MENU))); - - $(test.customizeMenu.IDS.SHORTCUTS_BUTTON).click(); - assertFalse(elementIsVisible($(test.customizeMenu.IDS.COLORS_MENU))); -}; - /** * Test that default tile is visible. @@ -383,6 +536,8 @@ assertTrue(!!$('color_0').style.backgroundImage); }; +//// BACKGROUND SUBMENU TESTS //// + /* * Tests that a custom background can be set through the menu. */ @@ -397,8 +552,7 @@ const backgroundSubmenu = $(test.customizeMenu.IDS.BACKGROUNDS_MENU); const backgroundImageSubmenu = $(test.customizeMenu.IDS.BACKGROUNDS_IMAGE_MENU); - assertTrue(backgroundSubmenu.classList.contains( - test.customizeMenu.CLASSES.MENU_SHOWN)); + assertTrue(elementIsVisible(backgroundSubmenu)); // 5 total tiles: upload, default, and the 3 collection tiles. assertTrue( @@ -410,10 +564,8 @@ $('coll_tile_0').click(); // The open menu is now the images menu with 4 tiles. - assertFalse(backgroundSubmenu.classList.contains( - test.customizeMenu.CLASSES.MENU_SHOWN)); - assertTrue(backgroundImageSubmenu.classList.contains( - test.customizeMenu.CLASSES.MENU_SHOWN)); + assertFalse(elementIsVisible(backgroundSubmenu)); + assertTrue(elementIsVisible(backgroundImageSubmenu)); assertTrue( $(test.customizeMenu.IDS.BACKGROUNDS_IMAGE_MENU) .getElementsByClassName('bg-sel-tile') @@ -423,10 +575,8 @@ $(test.customizeMenu.IDS.MENU_DONE).click(); // No menu should be open, and setCustomBackground should have been called. - assertFalse(backgroundSubmenu.classList.contains( - test.customizeMenu.CLASSES.MENU_SHOWN)); - assertFalse(backgroundImageSubmenu.classList.contains( - test.customizeMenu.CLASSES.MENU_SHOWN)); + assertFalse(elementIsVisible(backgroundSubmenu)); + assertFalse(elementIsVisible(backgroundImageSubmenu)); assertEquals(1, test.customizeMenu.timesCustomBackgroundWasSet); }; @@ -446,8 +596,7 @@ const backgroundSubmenu = $(test.customizeMenu.IDS.BACKGROUNDS_MENU); const backgroundImageSubmenu = $(test.customizeMenu.IDS.BACKGROUNDS_IMAGE_MENU); - assertTrue(backgroundSubmenu.classList.contains( - test.customizeMenu.CLASSES.MENU_SHOWN)); + assertTrue(elementIsVisible(backgroundSubmenu)); // 5 total tiles: upload, default, and the 3 collection tiles. assertTrue( @@ -459,10 +608,8 @@ $('coll_tile_0').click(); // The open menu is now the images menu with 4 tiles. - assertFalse(backgroundSubmenu.classList.contains( - test.customizeMenu.CLASSES.MENU_SHOWN)); - assertTrue(backgroundImageSubmenu.classList.contains( - test.customizeMenu.CLASSES.MENU_SHOWN)); + assertFalse(elementIsVisible(backgroundSubmenu)); + assertTrue(elementIsVisible(backgroundImageSubmenu)); assertTrue( $(test.customizeMenu.IDS.BACKGROUNDS_IMAGE_MENU) .getElementsByClassName('bg-sel-tile') @@ -473,10 +620,8 @@ // No menu should be open, and setCustomBackground should NOT have been // called. - assertFalse(backgroundSubmenu.classList.contains( - test.customizeMenu.CLASSES.MENU_SHOWN)); - assertFalse(backgroundImageSubmenu.classList.contains( - test.customizeMenu.CLASSES.MENU_SHOWN)); + assertFalse(elementIsVisible(backgroundSubmenu)); + assertFalse(elementIsVisible(backgroundImageSubmenu)); assertEquals(0, test.customizeMenu.timesCustomBackgroundWasSet); }; @@ -494,8 +639,7 @@ const backgroundSubmenu = $(test.customizeMenu.IDS.BACKGROUNDS_MENU); const backgroundImageSubmenu = $(test.customizeMenu.IDS.BACKGROUNDS_IMAGE_MENU); - assertTrue(backgroundSubmenu.classList.contains( - test.customizeMenu.CLASSES.MENU_SHOWN)); + assertTrue(elementIsVisible(backgroundSubmenu)); // 5 total tiles: upload, default, and the 3 collection tiles. assertTrue( @@ -507,10 +651,8 @@ $('coll_tile_0').click(); // The open menu is now the images menu with 4 tiles. - assertFalse(backgroundSubmenu.classList.contains( - test.customizeMenu.CLASSES.MENU_SHOWN)); - assertTrue(backgroundImageSubmenu.classList.contains( - test.customizeMenu.CLASSES.MENU_SHOWN)); + assertFalse(elementIsVisible(backgroundSubmenu)); + assertTrue(elementIsVisible(backgroundImageSubmenu)); assertTrue( $(test.customizeMenu.IDS.BACKGROUNDS_IMAGE_MENU) .getElementsByClassName('bg-sel-tile') @@ -520,19 +662,15 @@ $(test.customizeMenu.IDS.MENU_BACK).click(); // The main backgrounds menu should be open, and no custom background set. - assertTrue(backgroundSubmenu.classList.contains( - test.customizeMenu.CLASSES.MENU_SHOWN)); - assertFalse(backgroundImageSubmenu.classList.contains( - test.customizeMenu.CLASSES.MENU_SHOWN)); + assertTrue(elementIsVisible(backgroundSubmenu)); + assertFalse(elementIsVisible(backgroundImageSubmenu)); assertEquals(0, test.customizeMenu.timesCustomBackgroundWasSet); // Reopen the images menu, the selection should be cleared. $('coll_tile_0').click(); - assertFalse(backgroundSubmenu.classList.contains( - test.customizeMenu.CLASSES.MENU_SHOWN)); - assertTrue(backgroundImageSubmenu.classList.contains( - test.customizeMenu.CLASSES.MENU_SHOWN)); + assertFalse(elementIsVisible(backgroundSubmenu)); + assertTrue(elementIsVisible(backgroundImageSubmenu)); assertTrue( $(test.customizeMenu.IDS.BACKGROUNDS_IMAGE_MENU) .getElementsByClassName('bg-sel-tile') @@ -551,10 +689,19 @@ init = function() { // Mock chrome.embeddedSearch functions. This must be done right before // initializing the local NTP. + const applyAutogeneratedTheme = () => { + test.customizeMenu.applyAutogeneratedThemeCount++ + }; + const confirmThemeChanges = () => { + test.customizeMenu.confirmThemeChangesCount++ + }; + const revertThemeChanges = () => { + test.customizeMenu.revertThemeChangesCount++ + }; const toggleMostVisitedOrCustomLinks = () => { test.customizeMenu.toggleMostVisitedOrCustomLinksCount++ }; - const toggleShortcutsVisibility = () => { + const toggleShortcutsVisibility = (doNotify) => { test.customizeMenu.toggleShortcutsVisibilityCount++ }; const timesCustomBackgroundWasSet = () => { @@ -567,17 +714,20 @@ chrome.embeddedSearch.newTabPage.themeBackgroundInfo; test.customizeMenu.stubs.replace(chrome.embeddedSearch, 'newTabPage', { - toggleMostVisitedOrCustomLinks: toggleMostVisitedOrCustomLinks, - toggleShortcutsVisibility: toggleShortcutsVisibility, - isUsingMostVisited: test.customizeMenu.isUsingMostVisited, + applyAutogeneratedTheme: applyAutogeneratedTheme, areShortcutsVisible: test.customizeMenu.areShortcutsVisible, - setBackgroundURLWithAttributions: timesCustomBackgroundWasSet, + confirmThemeChanges: confirmThemeChanges, + getColorsInfo: getColorsInfo, + isUsingMostVisited: test.customizeMenu.isUsingMostVisited, + logEvent: (a) => {}, resetCustomLinks: () => {}, + revertThemeChanges: revertThemeChanges, selectLocalBackgroundImage: () => {}, setBackgroundURL: timesCustomBackgroundWasSet, - logEvent: (a) => {}, - getColorsInfo: getColorsInfo, + setBackgroundURLWithAttributions: timesCustomBackgroundWasSet, themeBackgroundInfo: themeBackgroundInfo, + toggleMostVisitedOrCustomLinks: toggleMostVisitedOrCustomLinks, + toggleShortcutsVisibility: toggleShortcutsVisibility, }); initLocalNTP(/*isGooglePage=*/ true);
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index cd351bbe..51a6cc2 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -2563,13 +2563,7 @@ }, "WelcomePageOnOSUpgradeEnabled": { - "os": ["win"], - "test_policy": { "WelcomePageOnOSUpgradeEnabled": false }, - "pref_mappings": [ - { "pref": "browser.welcome_page_on_os_upgrade_enabled", - "local_state": true - } - ] + "note": "This policy is retired, see https://crbug.com/978349." }, "SuppressUnsupportedOSWarning": {
diff --git a/chrome/test/data/webui/cr_elements/cr_slider_test.js b/chrome/test/data/webui/cr_elements/cr_slider_test.js index 200cecc..7510fc3 100644 --- a/chrome/test/data/webui/cr_elements/cr_slider_test.js +++ b/chrome/test/data/webui/cr_elements/cr_slider_test.js
@@ -10,6 +10,7 @@ document.body.innerHTML = '<cr-slider min="0" max="100"></cr-slider>'; crSlider = document.body.querySelector('cr-slider'); + crSlider.value = 0; return PolymerTest.flushTasks(); }); @@ -77,7 +78,6 @@ } test('key events', () => { - crSlider.value = 0; pressArrowRight(); assertEquals(1, crSlider.value); pressPageUp(); @@ -110,7 +110,6 @@ test('no-keybindings', () => { crSlider.noKeybindings = true; - crSlider.value = 0; pressArrowRight(); assertEquals(0, crSlider.value); crSlider.noKeybindings = false; @@ -125,7 +124,6 @@ }); test('mouse events', () => { - crSlider.value = 0; pointerMove(.25); assertEquals(0, crSlider.value); pointerDown(.5); @@ -171,7 +169,6 @@ }); test('markers', () => { - crSlider.value = 0; assertTrue(crSlider.$.markers.hidden); crSlider.markerCount = 10; assertFalse(crSlider.$.markers.hidden); @@ -386,4 +383,12 @@ crSlider.max = 50; assertEquals(50, crSlider.value); }); + + test('container hidden until value set', () => { + document.body.innerHTML = '<cr-slider></cr-slider>'; + crSlider = document.body.querySelector('cr-slider'); + assertTrue(crSlider.$.container.hidden); + crSlider.value = 0; + assertFalse(crSlider.$.container.hidden); + }); });
diff --git a/chrome/test/data/webui/settings/appearance_fonts_page_test.js b/chrome/test/data/webui/settings/appearance_fonts_page_test.js index a998bcd..f691324 100644 --- a/chrome/test/data/webui/settings/appearance_fonts_page_test.js +++ b/chrome/test/data/webui/settings/appearance_fonts_page_test.js
@@ -67,4 +67,13 @@ button.click(); return fontsBrowserProxy.whenCalled('openAdvancedFontSettings'); }); + + test('minimum font size sample', async () => { + fontsPage.prefs = {webkit: {webprefs: {minimum_font_size: {value: 0}}}}; + assertTrue(fontsPage.$.minimumSizeSample.hidden); + fontsPage.set('prefs.webkit.webprefs.minimum_font_size.value', 6); + assertFalse(fontsPage.$.minimumSizeSample.hidden); + fontsPage.set('prefs.webkit.webprefs.minimum_font_size.value', 0); + assertTrue(fontsPage.$.minimumSizeSample.hidden); + }); });
diff --git a/chromecast/base/BUILD.gn b/chromecast/base/BUILD.gn index a36b681..ab01e6a2 100644 --- a/chromecast/base/BUILD.gn +++ b/chromecast/base/BUILD.gn
@@ -42,6 +42,8 @@ sources = [ "alarm_manager.cc", "alarm_manager.h", + "android/cast_settings_manager.cc", + "android/cast_settings_manager.h", "android/dumpstate_writer.cc", "android/dumpstate_writer.h", "android/system_time_change_notifier_android.cc", @@ -350,6 +352,7 @@ if (is_android) { generate_jni("jni_headers") { sources = [ + "java/src/org/chromium/chromecast/base/CastSettingsManager.java", "java/src/org/chromium/chromecast/base/DumpstateWriter.java", "java/src/org/chromium/chromecast/base/SystemTimeChangeNotifierAndroid.java", ] @@ -407,6 +410,7 @@ java_test_dir = "//chromecast/base/java/test" java_files = [ "$java_test_dir/org/chromium/chromecast/base/BothTest.java", + "$java_test_dir/org/chromium/chromecast/base/CastSettingsManagerTest.java", "$java_test_dir/org/chromium/chromecast/base/ControllerTest.java", "$java_test_dir/org/chromium/chromecast/base/ItertoolsTest.java", "$java_test_dir/org/chromium/chromecast/base/ObservableAndTest.java", @@ -423,6 +427,7 @@ deps = [ ":base_java", ":cast_base_test_utils_java", + "//base:base_junit_test_support", "//third_party/hamcrest:hamcrest_java", ] }
diff --git a/chromecast/base/android/cast_settings_manager.cc b/chromecast/base/android/cast_settings_manager.cc new file mode 100644 index 0000000..d72ff44 --- /dev/null +++ b/chromecast/base/android/cast_settings_manager.cc
@@ -0,0 +1,25 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromecast/base/android/cast_settings_manager.h" + +#include "base/android/jni_android.h" +#include "base/android/jni_string.h" +#include "chromecast/base/jni_headers/CastSettingsManager_jni.h" + +namespace chromecast { + +bool CastSettingsManager::UpdateGlobalDeviceName( + const std::string& deviceName) { + JNIEnv* env = base::android::AttachCurrentThread(); + return Java_CastSettingsManager_updateGlobalDeviceName( + env, base::android::ConvertUTF8ToJavaString(env, deviceName)); +} + +bool CastSettingsManager::HasWriteSecureSettingsPermission() { + JNIEnv* env = base::android::AttachCurrentThread(); + return Java_CastSettingsManager_hasWriteSecureSettingsPermission(env); +} + +} // namespace chromecast
diff --git a/chromecast/base/android/cast_settings_manager.h b/chromecast/base/android/cast_settings_manager.h new file mode 100644 index 0000000..109d057 --- /dev/null +++ b/chromecast/base/android/cast_settings_manager.h
@@ -0,0 +1,22 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMECAST_BASE_ANDROID_CAST_SETTINGS_MANAGER_H_ +#define CHROMECAST_BASE_ANDROID_CAST_SETTINGS_MANAGER_H_ + +#include <string> + +namespace chromecast { + +class CastSettingsManager { + public: + CastSettingsManager() {} + + static bool UpdateGlobalDeviceName(const std::string& deviceName); + static bool HasWriteSecureSettingsPermission(); +}; + +} // namespace chromecast + +#endif // CHROMECAST_BASE_ANDROID_CAST_SETTINGS_MANAGER_H_
diff --git a/chromecast/base/java/src/org/chromium/chromecast/base/CastSettingsManager.java b/chromecast/base/java/src/org/chromium/chromecast/base/CastSettingsManager.java index 28d1e23d..5bcf4fa 100644 --- a/chromecast/base/java/src/org/chromium/chromecast/base/CastSettingsManager.java +++ b/chromecast/base/java/src/org/chromium/chromecast/base/CastSettingsManager.java
@@ -4,6 +4,9 @@ package org.chromium.chromecast.base; +import static android.Manifest.permission.WRITE_SECURE_SETTINGS; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; + import android.annotation.SuppressLint; import android.content.ContentResolver; import android.content.Context; @@ -11,12 +14,17 @@ import android.os.Build; import android.os.Handler; import android.provider.Settings; +import android.support.annotation.VisibleForTesting; +import org.chromium.base.ContextUtils; import org.chromium.base.Log; +import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.annotations.JNINamespace; /** * Manager for Cast settings. */ +@JNINamespace("chromecast") public final class CastSettingsManager { private static final String TAG = "cr_CastSettingsManager"; @@ -25,14 +33,15 @@ /** The default device name, which is the model name. */ private static final String DEFAULT_DEVICE_NAME = Build.MODEL; - // TODO(gunsch): Switch to Settings.Global.DEVICE_NAME once it's in public SDK. - // private static final String DEVICE_NAME_SETTING_KEY = Settings.Global.DEVICE_NAME; - private static final String DEVICE_NAME_SETTING_KEY = "device_name"; + private static final String DEVICE_NAME_SETTING_KEY = Settings.Global.DEVICE_NAME; private static final String DEVICE_PROVISIONED_SETTING_KEY = Settings.Global.DEVICE_PROVISIONED; private final ContentResolver mContentResolver; - private ContentObserver mDeviceNameObserver; - private ContentObserver mIsDeviceProvisionedObserver; + + @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) + protected ContentObserver mDeviceNameObserver; + @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) + protected ContentObserver mIsDeviceProvisionedObserver; /** * Can be implemented to receive notifications from a CastSettingsManager instance when @@ -111,4 +120,38 @@ return (deviceName != null) ? deviceName : DEFAULT_DEVICE_NAME; } + /** + * Updates Settings.Global DEVICE_NAME to desired string. Returns true if + * successful, false otherwise. Requires the application to have + * android.permission.WRITE_SECURE_SETTINGS permission + */ + @CalledByNative + public static boolean updateGlobalDeviceName(String deviceName) { + if (deviceName == null || deviceName.isEmpty()) { + Log.e(TAG, "deviceName must not be null or empty"); + return false; + } + Context context = ContextUtils.getApplicationContext(); + if (!hasWriteSecureSettingsPermission()) { + Log.e(TAG, "PERMISSION DENIED while attempting to update deviceName"); + return false; + } + return Settings.Global.putString( + context.getContentResolver(), DEVICE_NAME_SETTING_KEY, deviceName); + } + + /** + * Indicates whether or not the application has the necessary permission + * to update the deviceName. + */ + @CalledByNative + private static boolean hasWriteSecureSettingsPermission() { + // checkSelfPermission only available in API Version >= 23 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Context context = ContextUtils.getApplicationContext(); + return context.checkSelfPermission(WRITE_SECURE_SETTINGS) == PERMISSION_GRANTED; + } else { + return false; + } + } }
diff --git a/chromecast/base/java/test/org/chromium/chromecast/base/CastSettingsManagerTest.java b/chromecast/base/java/test/org/chromium/chromecast/base/CastSettingsManagerTest.java new file mode 100644 index 0000000..9f65cb6 --- /dev/null +++ b/chromecast/base/java/test/org/chromium/chromecast/base/CastSettingsManagerTest.java
@@ -0,0 +1,119 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chromecast.base; + +import static android.Manifest.permission.WRITE_SECURE_SETTINGS; +import static android.content.pm.PackageManager.PERMISSION_DENIED; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static android.provider.Settings.Global.DEVICE_NAME; +import static android.provider.Settings.Global.DEVICE_PROVISIONED; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.ContentResolver; +import android.content.Context; +import android.os.Build; +import android.provider.Settings; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; + +import org.chromium.base.ContextUtils; +import org.chromium.base.test.BaseRobolectricTestRunner; + +/** + * Unit Tests for CastSettingsManager + */ +@RunWith(BaseRobolectricTestRunner.class) +public class CastSettingsManagerTest { + private CastSettingsManager mCastSettingsManager; + + @Mock + private ContentResolver mContentResolver; + @Mock + private Context mContext; + @Mock + private CastSettingsManager.OnSettingChangedListener mListener; + + @Before + public void before() { + mContext = mock(Context.class); + mContentResolver = mock(ContentResolver.class); + mListener = mock(CastSettingsManager.OnSettingChangedListener.class); + ContextUtils.initApplicationContextForTests(mContext); + when(mContext.getContentResolver()).thenReturn(mContentResolver); + mCastSettingsManager = CastSettingsManager.createCastSettingsManager(mContext, mListener); + } + + @After + public void after() { + mCastSettingsManager.dispose(); + } + + @Test + public void testGetDeviceNameReturnsBuildModelWhenNotSet() { + assertTrue(Settings.Global.putString(mContentResolver, DEVICE_NAME, null)); + assertEquals(Build.MODEL, mCastSettingsManager.getDeviceName()); + } + + @Test + public void testGetDeviceNameReturnsExpectedName() { + assertTrue(Settings.Global.putString(mContentResolver, DEVICE_NAME, "fooDevice")); + assertEquals("fooDevice", mCastSettingsManager.getDeviceName()); + } + + @Test + public void testIsCastEnabled() { + assertTrue(Settings.Global.putInt(mContentResolver, DEVICE_PROVISIONED, 0)); + assertFalse(mCastSettingsManager.isCastEnabled()); + assertTrue(Settings.Global.putInt(mContentResolver, DEVICE_PROVISIONED, 1)); + assertTrue(mCastSettingsManager.isCastEnabled()); + } + + @Test + public void testUpdateGlobalDeviceNameUpdatesDeviceNameWithPermission() { + when(mContext.checkSelfPermission(WRITE_SECURE_SETTINGS)).thenReturn(PERMISSION_GRANTED); + assertTrue(CastSettingsManager.updateGlobalDeviceName("newName")); + assertEquals("newName", mCastSettingsManager.getDeviceName()); + } + + @Test + public void testUpdateGlobalDeviceNameReturnsFalseWithoutPermission() { + when(mContext.checkSelfPermission(WRITE_SECURE_SETTINGS)).thenReturn(PERMISSION_DENIED); + assertFalse(CastSettingsManager.updateGlobalDeviceName("newName2")); + assertNotEquals("newName2", mCastSettingsManager.getDeviceName()); + } + + @Test + public void testSettingsListenersRegistered() { + verify(mContentResolver) + .registerContentObserver(Settings.Global.getUriFor(DEVICE_NAME), true, + mCastSettingsManager.mDeviceNameObserver); + verify(mContentResolver) + .registerContentObserver(Settings.Global.getUriFor(DEVICE_PROVISIONED), true, + mCastSettingsManager.mIsDeviceProvisionedObserver); + } + + @Test + public void testDeviceNameListenerMethodCalledWhenObserverTriggered() { + mCastSettingsManager.mDeviceNameObserver.onChange(true); + verify(mListener).onDeviceNameChanged(mCastSettingsManager.getDeviceName()); + } + + @Test + public void testCastEnabledListenerMethodCalledWhenObserverTriggered() { + mCastSettingsManager.mIsDeviceProvisionedObserver.onChange(true); + verify(mListener).onCastEnabledChanged(mCastSettingsManager.isCastEnabled()); + } +}
diff --git a/chromecast/browser/cast_memory_pressure_monitor.cc b/chromecast/browser/cast_memory_pressure_monitor.cc index 69277d1..f8af2818 100644 --- a/chromecast/browser/cast_memory_pressure_monitor.cc +++ b/chromecast/browser/cast_memory_pressure_monitor.cc
@@ -61,7 +61,7 @@ CastMemoryPressureMonitor::~CastMemoryPressureMonitor() {} CastMemoryPressureMonitor::MemoryPressureLevel -CastMemoryPressureMonitor::GetCurrentPressureLevel() { +CastMemoryPressureMonitor::GetCurrentPressureLevel() const { return current_level_; }
diff --git a/chromecast/browser/cast_memory_pressure_monitor.h b/chromecast/browser/cast_memory_pressure_monitor.h index 3b44c81..14262a0 100644 --- a/chromecast/browser/cast_memory_pressure_monitor.h +++ b/chromecast/browser/cast_memory_pressure_monitor.h
@@ -19,7 +19,7 @@ ~CastMemoryPressureMonitor() override; // base::MemoryPressureMonitor implementation: - MemoryPressureLevel GetCurrentPressureLevel() override; + MemoryPressureLevel GetCurrentPressureLevel() const override; void SetDispatchCallback(const DispatchCallback& callback) override; private:
diff --git a/chromecast/net/connectivity_checker_impl.cc b/chromecast/net/connectivity_checker_impl.cc index f7c02192..22bd00d 100644 --- a/chromecast/net/connectivity_checker_impl.cc +++ b/chromecast/net/connectivity_checker_impl.cc
@@ -159,7 +159,8 @@ DVLOG(1) << "Connectivity check: url=" << *connectivity_check_url_; url_request_ = url_request_context_->CreateRequest( - *connectivity_check_url_, net::MAXIMUM_PRIORITY, this); + *connectivity_check_url_, net::MAXIMUM_PRIORITY, this, + MISSING_TRAFFIC_ANNOTATION); url_request_->set_method("HEAD"); url_request_->Start();
diff --git a/chromecast/net/small_message_socket.cc b/chromecast/net/small_message_socket.cc index 329d576e..63cefb60 100644 --- a/chromecast/net/small_message_socket.cc +++ b/chromecast/net/small_message_socket.cc
@@ -83,7 +83,7 @@ socket_->Write(write_buffer_.get(), write_buffer_->BytesRemaining(), base::BindRepeating(&SmallMessageSocket::OnWriteComplete, base::Unretained(this)), - NO_TRAFFIC_ANNOTATION_YET); + MISSING_TRAFFIC_ANNOTATION); if (!HandleWriteResult(result)) { return; }
diff --git a/chromeos/BUILD.gn b/chromeos/BUILD.gn index 18369f10..d4947c69 100644 --- a/chromeos/BUILD.gn +++ b/chromeos/BUILD.gn
@@ -62,6 +62,8 @@ "printing/printer_translator.h", "printing/uri_components.cc", "printing/uri_components.h", + "printing/usb_printer_id.cc", + "printing/usb_printer_id.h", "process_proxy/process_output_watcher.cc", "process_proxy/process_output_watcher.h", "process_proxy/process_proxy.cc", @@ -182,6 +184,7 @@ "printing/ppd_provider_unittest.cc", "printing/printer_configuration_unittest.cc", "printing/printer_translator_unittest.cc", + "printing/usb_printer_id_unittest.cc", "process_proxy/process_output_watcher_unittest.cc", "process_proxy/process_proxy_unittest.cc", "test/run_all_unittests.cc",
diff --git a/chromeos/printing/epson_driver_matching.cc b/chromeos/printing/epson_driver_matching.cc index d25b5a6..8f1bd00d 100644 --- a/chromeos/printing/epson_driver_matching.cc +++ b/chromeos/printing/epson_driver_matching.cc
@@ -34,7 +34,7 @@ "application/octet-stream"); case PrinterSearchData::PrinterDiscoveryType::kUsb: - return base::Contains(sd.usb_command_set, "ESC/P-R"); + return base::Contains(sd.printer_id.command_set(), "ESC/P-R"); case PrinterSearchData::PrinterDiscoveryType::kZeroconf: // For printers found through mDNS/DNS-SD discovery,
diff --git a/chromeos/printing/epson_driver_matching_unittest.cc b/chromeos/printing/epson_driver_matching_unittest.cc index 42d274a..8bf627a 100644 --- a/chromeos/printing/epson_driver_matching_unittest.cc +++ b/chromeos/printing/epson_driver_matching_unittest.cc
@@ -5,6 +5,7 @@ #include "chromeos/printing/epson_driver_matching.h" #include <string> +#include <vector> #include "chromeos/printing/ppd_provider.h" #include "testing/gtest/include/gtest/gtest.h" @@ -31,7 +32,7 @@ case PrinterDiscoveryType::kUsb: sd.discovery_type = PrinterDiscoveryType::kUsb; - sd.usb_command_set.push_back(kEscPr); + sd.printer_id.set_command_set({kEscPr}); break; case PrinterDiscoveryType::kZeroconf: @@ -96,7 +97,7 @@ sd.supported_document_formats.push_back(std::string(kOctetStream) + "afds"); EXPECT_FALSE(CanUseEpsonGenericPPD(sd)); - sd.usb_command_set.push_back(kOctetStream); + sd.printer_id.set_command_set({kOctetStream}); EXPECT_FALSE(CanUseEpsonGenericPPD(sd)); sd.supported_document_formats.push_back(kOctetStream); @@ -106,18 +107,21 @@ // Simple PrinterDiscoveryType::kUsb checks. TEST(EpsonDriverMatchingTest, UsbDiscovery) { PrinterSearchData sd(GetTestPrinterSearchData(PrinterDiscoveryType::kUsb)); - sd.usb_command_set.clear(); + std::vector<std::string> command_set; - sd.usb_command_set.push_back("ESC"); + command_set.push_back("ESC"); + sd.printer_id.set_command_set(command_set); EXPECT_FALSE(CanUseEpsonGenericPPD(sd)); - sd.usb_command_set.push_back(std::string(kEscPr) + ":asfd"); + command_set.push_back(std::string(kEscPr) + ":asfd"); + sd.printer_id.set_command_set(command_set); EXPECT_FALSE(CanUseEpsonGenericPPD(sd)); sd.supported_document_formats.push_back(kEscPr); EXPECT_FALSE(CanUseEpsonGenericPPD(sd)); - sd.usb_command_set.push_back(kEscPr); + command_set.push_back(kEscPr); + sd.printer_id.set_command_set(command_set); EXPECT_TRUE(CanUseEpsonGenericPPD(sd)); } @@ -132,7 +136,7 @@ sd.supported_document_formats.push_back(std::string(kEpsonEscpr) + ":asfd"); EXPECT_FALSE(CanUseEpsonGenericPPD(sd)); - sd.usb_command_set.push_back(kEpsonEscpr); + sd.printer_id.set_command_set({kEpsonEscpr}); EXPECT_FALSE(CanUseEpsonGenericPPD(sd)); sd.supported_document_formats.push_back(kEpsonEscpr);
diff --git a/chromeos/printing/ppd_provider.h b/chromeos/printing/ppd_provider.h index 51baa82a..b5110b03 100644 --- a/chromeos/printing/ppd_provider.h +++ b/chromeos/printing/ppd_provider.h
@@ -16,6 +16,7 @@ #include "base/version.h" #include "chromeos/chromeos_export.h" #include "chromeos/printing/printer_configuration.h" +#include "chromeos/printing/usb_printer_id.h" namespace network { namespace mojom { @@ -58,9 +59,9 @@ // Set of MIME types supported by this printer. std::vector<std::string> supported_document_formats; - // Stripped from IEEE1284 signaling method(from the device ID key 'CMD'). - // Details a set of languages this printer understands. - std::vector<std::string> usb_command_set; + // Representation of IEEE1284 standard printing device ID. + // Contains a set of languages this printer understands. + UsbPrinterId printer_id; }; // PpdProvider is responsible for mapping printer descriptions to
diff --git a/chromeos/printing/usb_printer_id.cc b/chromeos/printing/usb_printer_id.cc new file mode 100644 index 0000000..5c7a81e --- /dev/null +++ b/chromeos/printing/usb_printer_id.cc
@@ -0,0 +1,88 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/printing/usb_printer_id.h" + +#include <algorithm> +#include <utility> + +#include "base/stl_util.h" +#include "base/strings/string_split.h" + +namespace chromeos { + +// Device ID keys pulled from IEEE Standard 1284. +const char kManufacturer[] = "MANUFACTURER"; +const char kManufacturerAbbr[] = "MFG"; +const char kModel[] = "MODEL"; +const char kModelAbbr[] = "MDL"; +const char kCommandSet[] = "COMMAND SET"; +const char kCommandSetAbbr[] = "CMD"; + +UsbPrinterId::UsbPrinterId(const std::vector<uint8_t>& device_id_data) { + // Build mapping. + id_mappings_ = BuildDeviceIdMapping(device_id_data); + + // Save required mappings. + // Save make_. + if (base::Contains(id_mappings_, kManufacturer)) { + make_ = id_mappings_[kManufacturer].front(); + } else if (base::Contains(id_mappings_, kManufacturerAbbr)) { + make_ = id_mappings_[kManufacturerAbbr].front(); + } + + // Save model_. + if (base::Contains(id_mappings_, kModel)) { + model_ = id_mappings_[kModel].front(); + } else if (base::Contains(id_mappings_, kModelAbbr)) { + model_ = id_mappings_[kModelAbbr].front(); + } + + // Save command_set_. + if (base::Contains(id_mappings_, kCommandSet)) { + command_set_ = id_mappings_[kCommandSet]; + } else if (base::Contains(id_mappings_, kCommandSetAbbr)) { + command_set_ = id_mappings_[kCommandSetAbbr]; + } +} + +UsbPrinterId::UsbPrinterId() = default; +UsbPrinterId::UsbPrinterId(const UsbPrinterId& other) = default; +UsbPrinterId::~UsbPrinterId() = default; + +std::map<std::string, std::vector<std::string>> BuildDeviceIdMapping( + const std::vector<uint8_t>& data) { + // Must contain at least the length information. + if (data.size() < 2) { + return {}; + } + + std::map<std::string, std::vector<std::string>> ret; + + // Convert to string to work on. + // Note: First two bytes contain the length, so we skip those. + std::string printer_id; + std::copy(data.begin() + 2, data.end(), std::back_inserter(printer_id)); + + // We filter out terms with empty keys or values. + base::StringPairs terms; + base::SplitStringIntoKeyValuePairs(printer_id, ':', ';', &terms); + for (const auto& term : terms) { + if (term.first.empty()) { + continue; + } + + std::vector<std::string> values = base::SplitString( + term.second, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + if (values.empty()) { + continue; + } + + ret[term.first] = values; + } + + return ret; +} + +} // namespace chromeos
diff --git a/chromeos/printing/usb_printer_id.h b/chromeos/printing/usb_printer_id.h new file mode 100644 index 0000000..3df4257 --- /dev/null +++ b/chromeos/printing/usb_printer_id.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_PRINTING_USB_PRINTER_ID_H_ +#define CHROMEOS_PRINTING_USB_PRINTER_ID_H_ + +#include <map> +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#include "chromeos/chromeos_export.h" + +namespace chromeos { + +// This class parses and holds the IEEE 1284 Device ID string as queried +// from a USB-connected printer. +class CHROMEOS_EXPORT UsbPrinterId { + public: + UsbPrinterId(); + UsbPrinterId(const UsbPrinterId& other); + ~UsbPrinterId(); + + // Expects |printer_id_data| to contain the data portion response to a USB + // Printer Class-Specific GET_DEVICE_ID Request. + explicit UsbPrinterId(const std::vector<uint8_t>& printer_id_data); + + // Accessors. + std::string make() const { return make_; } + std::string model() const { return model_; } + std::vector<std::string> command_set() const { return command_set_; } + + // Setters (only used in testing). + void set_make(std::string make) { make_ = make; } + void set_model(std::string model) { model_ = model; } + void set_command_set(std::vector<std::string> command_set) { + command_set_ = std::move(command_set); + } + + private: + std::string make_; + std::string model_; + + // List of supported document formats (MIME types). + std::vector<std::string> command_set_; + + // Holds the fully parsed IEEE 1284 Device ID. + std::map<std::string, std::vector<std::string>> id_mappings_; +}; + +// Expects data to hold a IEEE 1284 Device ID. Parses |data| and returns the +// resulting key-value(s) pairs. +CHROMEOS_EXPORT std::map<std::string, std::vector<std::string>> +BuildDeviceIdMapping(const std::vector<uint8_t>& data); + +} // namespace chromeos + +#endif // CHROMEOS_PRINTING_USB_PRINTER_ID_H_
diff --git a/chromeos/printing/usb_printer_id_unittest.cc b/chromeos/printing/usb_printer_id_unittest.cc new file mode 100644 index 0000000..7ad21a1 --- /dev/null +++ b/chromeos/printing/usb_printer_id_unittest.cc
@@ -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. + +#include "chromeos/printing/usb_printer_id.h" + +#include <algorithm> +#include <map> +#include <string> + +#include "base/strings/string_util.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromeos { +namespace { + +using testing::IsEmpty; + +using MapType = std::map<std::string, std::vector<std::string>>; + +MapType GetDefaultDeviceId() { + MapType ret; + + // Make. + ret["MFG"].push_back("EPSON"); + + // Model. + ret["MDL"].push_back("ET-2700"); + + // Command set. + ret["CMD"].push_back("ESCPL2"); + ret["CMD"].push_back("BDC"); + ret["CMD"].push_back("D4"); + ret["CMD"].push_back("END4"); + ret["CMD"].push_back("GENEP"); + + return ret; +} + +std::string MapToString(const MapType& map) { + std::vector<std::string> terms; + for (auto& term : map) { + std::string values = base::JoinString(term.second, ","); + terms.push_back(base::JoinString({term.first, values}, ":")); + } + + std::string device_id_str = "xx"; // Two unused bytes for the length. + device_id_str += base::JoinString(terms, ";") + ";"; + return device_id_str; +} + +std::vector<uint8_t> MapToBuffer(const MapType& map) { + std::string device_id_str = MapToString(map); + + std::vector<uint8_t> ret; + std::copy(device_id_str.begin(), device_id_str.end(), + std::back_inserter(ret)); + return ret; +} + +TEST(UsbPrinterIdTest, EmptyDeviceId) { + EXPECT_THAT(BuildDeviceIdMapping({}), IsEmpty()); +} + +// Tests that we get the same map back after parsing. +TEST(UsbPrinterIdTest, SimpleSanityTest) { + MapType mapping = GetDefaultDeviceId(); + std::vector<uint8_t> buffer = MapToBuffer(mapping); + EXPECT_EQ(mapping, BuildDeviceIdMapping(buffer)); +} + +} // namespace +} // namespace chromeos
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.cc b/chromeos/services/assistant/assistant_manager_service_impl.cc index 1da8f63..fb9c0f7 100644 --- a/chromeos/services/assistant/assistant_manager_service_impl.cc +++ b/chromeos/services/assistant/assistant_manager_service_impl.cc
@@ -1098,6 +1098,12 @@ void AssistantManagerServiceImpl::OnStartFinished() { ENSURE_MAIN_THREAD(&AssistantManagerServiceImpl::OnStartFinished); + // It is possible the |assistant_manager_| was destructed before the + // rescheduled main thread task got a chance to run. We check this and also + // try to avoid double run by check |start_finished_|. + if (!assistant_manager_ || start_finished_) + return; + // TODO(b/129896357): find a better place for additional setups. start_finished_ = true;
diff --git a/chromeos/services/device_sync/cryptauth_ecies_encryptor.cc b/chromeos/services/device_sync/cryptauth_ecies_encryptor.cc index 30d79a5..ec31a131 100644 --- a/chromeos/services/device_sync/cryptauth_ecies_encryptor.cc +++ b/chromeos/services/device_sync/cryptauth_ecies_encryptor.cc
@@ -34,6 +34,11 @@ const std::string& key) : payload(payload), key(key) {} +bool CryptAuthEciesEncryptor::PayloadAndKey::operator==( + const PayloadAndKey& other) const { + return payload == other.payload && key == other.key; +} + CryptAuthEciesEncryptor::CryptAuthEciesEncryptor() = default; CryptAuthEciesEncryptor::~CryptAuthEciesEncryptor() = default;
diff --git a/chromeos/services/device_sync/cryptauth_ecies_encryptor.h b/chromeos/services/device_sync/cryptauth_ecies_encryptor.h index 51bfc45..e86e4a69 100644 --- a/chromeos/services/device_sync/cryptauth_ecies_encryptor.h +++ b/chromeos/services/device_sync/cryptauth_ecies_encryptor.h
@@ -27,6 +27,7 @@ struct PayloadAndKey { PayloadAndKey(); PayloadAndKey(const std::string& payload, const std::string& key); + bool operator==(const PayloadAndKey& other) const; // Unencrypted/Encrypted payload to be encrypted/decrypted. std::string payload;
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn index 7bdab54..0ebd5f2 100644 --- a/components/arc/BUILD.gn +++ b/components/arc/BUILD.gn
@@ -32,6 +32,7 @@ "intent_helper/arc_intent_helper_bridge.cc", "intent_helper/arc_intent_helper_bridge.h", "intent_helper/arc_intent_helper_observer.h", + "intent_helper/factory_reset_delegate.h", "intent_helper/font_size_util.cc", "intent_helper/font_size_util.h", "intent_helper/intent_constants.cc",
diff --git a/components/arc/common/intent_helper.mojom b/components/arc/common/intent_helper.mojom index a5d94012..675db19 100644 --- a/components/arc/common/intent_helper.mojom +++ b/components/arc/common/intent_helper.mojom
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Next MinVersion: 27 +// Next MinVersion: 28 module arc.mojom; @@ -173,7 +173,7 @@ // Handles intents from ARC in Chrome. // Deprecated method ID: 4 -// Next method ID: 11 +// Next method ID: 12 interface IntentHelperHost { // Called when icons associated with the package are no longer up to date. [MinVersion=3] OnIconInvalidated@1(string package_name); @@ -220,6 +220,10 @@ // Records Sharing files feature's metrics via Chrome. [MinVersion=24] RecordShareFilesMetrics@9(ShareFiles flag); + + // Does a reset of ARC; this wipes /data, and then re-calls on OOBE for + // account binding to happen again, as if the user just went through OOBE. + [MinVersion=27] FactoryResetArc@11(); }; // Sends intents to ARC on behalf of Chrome.
diff --git a/components/arc/intent_helper/arc_intent_helper_bridge.cc b/components/arc/intent_helper/arc_intent_helper_bridge.cc index 251884d..6a38030 100644 --- a/components/arc/intent_helper/arc_intent_helper_bridge.cc +++ b/components/arc/intent_helper/arc_intent_helper_bridge.cc
@@ -18,6 +18,7 @@ #include "components/arc/arc_browser_context_keyed_service_factory_base.h" #include "components/arc/arc_service_manager.h" #include "components/arc/audio/arc_audio_bridge.h" +#include "components/arc/intent_helper/factory_reset_delegate.h" #include "components/arc/intent_helper/open_url_delegate.h" #include "components/arc/session/arc_bridge_service.h" #include "components/url_formatter/url_fixer.h" @@ -76,6 +77,7 @@ // Not owned. Must outlive all ArcIntentHelperBridge instances. Typically this // is ChromeNewWindowClient in the browser. OpenUrlDelegate* g_open_url_delegate = nullptr; +FactoryResetDelegate* g_factory_reset_delegate = nullptr; // Singleton factory for ArcIntentHelperBridge. class ArcIntentHelperBridgeFactory @@ -146,6 +148,12 @@ g_open_url_delegate = delegate; } +// static +void ArcIntentHelperBridge::SetFactoryResetDelegate( + FactoryResetDelegate* delegate) { + g_factory_reset_delegate = delegate; +} + ArcIntentHelperBridge::ArcIntentHelperBridge(content::BrowserContext* context, ArcBridgeService* bridge_service) : context_(context), @@ -225,6 +233,10 @@ } } +void ArcIntentHelperBridge::FactoryResetArc() { + g_factory_reset_delegate->ResetArc(); +} + void ArcIntentHelperBridge::OpenWallpaperPicker() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); RecordOpenType(ArcIntentHelperOpenType::WALLPAPER_PICKER);
diff --git a/components/arc/intent_helper/arc_intent_helper_bridge.h b/components/arc/intent_helper/arc_intent_helper_bridge.h index 8cdf2c3..2286c48 100644 --- a/components/arc/intent_helper/arc_intent_helper_bridge.h +++ b/components/arc/intent_helper/arc_intent_helper_bridge.h
@@ -29,6 +29,7 @@ namespace arc { class ArcBridgeService; +class FactoryResetDelegate; class IntentFilter; class OpenUrlDelegate; @@ -51,6 +52,8 @@ static void SetOpenUrlDelegate(OpenUrlDelegate* delegate); + static void SetFactoryResetDelegate(FactoryResetDelegate* delegate); + ArcIntentHelperBridge(content::BrowserContext* context, ArcBridgeService* bridge_service); ~ArcIntentHelperBridge() override; @@ -74,6 +77,7 @@ void OpenWallpaperPicker() override; void SetWallpaperDeprecated(const std::vector<uint8_t>& jpeg_data) override; void OpenVolumeControl() override; + void FactoryResetArc() override; void OnOpenWebApp(const std::string& url) override; void RecordShareFilesMetrics(mojom::ShareFiles flag) override;
diff --git a/components/arc/intent_helper/factory_reset_delegate.h b/components/arc/intent_helper/factory_reset_delegate.h new file mode 100644 index 0000000..edddbe3 --- /dev/null +++ b/components/arc/intent_helper/factory_reset_delegate.h
@@ -0,0 +1,23 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_ARC_INTENT_HELPER_FACTORY_RESET_DELEGATE_H_ +#define COMPONENTS_ARC_INTENT_HELPER_FACTORY_RESET_DELEGATE_H_ + +#include "components/arc/common/intent_helper.mojom.h" + +namespace arc { + +class FactoryResetDelegate { + public: + virtual ~FactoryResetDelegate() = default; + + // Does a reset of ARC; this wipes /data, and then re-calls on OOBE for + // account binding to happen again, as if the user just went through OOBE. + virtual void ResetArc() = 0; +}; + +} // namespace arc + +#endif // COMPONENTS_ARC_INTENT_HELPER_FACTORY_RESET_DELEGATE_H_
diff --git a/components/autofill/content/browser/BUILD.gn b/components/autofill/content/browser/BUILD.gn index 0d8a0b4..1a228a58 100644 --- a/components/autofill/content/browser/BUILD.gn +++ b/components/autofill/content/browser/BUILD.gn
@@ -49,6 +49,10 @@ "//ui/gfx/geometry", "//url", ] + + if (!is_android) { + deps += [ "//components/autofill/content/browser/webauthn" ] + } } proto_library("risk_proto") {
diff --git a/components/autofill/content/browser/content_autofill_driver.cc b/components/autofill/content/browser/content_autofill_driver.cc index 080139b..30a66ee 100644 --- a/components/autofill/content/browser/content_autofill_driver.cc +++ b/components/autofill/content/browser/content_autofill_driver.cc
@@ -7,12 +7,14 @@ #include <utility> #include <vector> +#include "build/build_config.h" #include "components/autofill/content/browser/content_autofill_driver_factory.h" #include "components/autofill/core/browser/autofill_client.h" #include "components/autofill/core/browser/autofill_external_delegate.h" #include "components/autofill/core/browser/autofill_handler_proxy.h" #include "components/autofill/core/browser/autofill_manager.h" #include "components/autofill/core/browser/form_structure.h" +#include "components/autofill/core/browser/payments/payments_service_url.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_handle.h" @@ -24,8 +26,10 @@ #include "content/public/browser/storage_partition.h" #include "content/public/browser/web_contents.h" #include "content/public/common/origin_util.h" +#include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "ui/gfx/geometry/size_f.h" +#include "url/origin.h" namespace autofill { @@ -96,6 +100,17 @@ return render_frame_host_->GetRenderViewHost() != nullptr; } +void ContentAutofillDriver::ConnectToAuthenticator( + blink::mojom::InternalAuthenticatorRequest request) { +#if defined(OS_ANDROID) + render_frame_host_->GetJavaInterfaces()->GetInterface(std::move(request)); +#else + authenticator_impl_ = std::make_unique<content::InternalAuthenticatorImpl>( + render_frame_host_, url::Origin::Create(payments::GetBaseSecureUrl())); + authenticator_impl_->Bind(std::move(request)); +#endif +} + void ContentAutofillDriver::SendFormDataToRenderer( int query_id, RendererFormDataAction action,
diff --git a/components/autofill/content/browser/content_autofill_driver.h b/components/autofill/content/browser/content_autofill_driver.h index 18e5fa1..cb81f63f 100644 --- a/components/autofill/content/browser/content_autofill_driver.h +++ b/components/autofill/content/browser/content_autofill_driver.h
@@ -9,7 +9,9 @@ #include <string> #include "base/supports_user_data.h" +#include "build/build_config.h" #include "components/autofill/content/browser/key_press_handler_manager.h" +#include "components/autofill/content/browser/webauthn/internal_authenticator_impl.h" #include "components/autofill/content/common/autofill_agent.mojom.h" #include "components/autofill/content/common/autofill_driver.mojom.h" #include "components/autofill/core/browser/autofill_driver.h" @@ -54,6 +56,8 @@ net::URLRequestContextGetter* GetURLRequestContext() override; scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override; bool RendererIsAvailable() override; + void ConnectToAuthenticator( + blink::mojom::InternalAuthenticatorRequest request) override; void SendFormDataToRenderer(int query_id, RendererFormDataAction action, const FormData& data) override; @@ -155,6 +159,11 @@ // a common root. AutofillManager* autofill_manager_; +#if !defined(OS_ANDROID) + // Implementation of the InternalAuthenticator mojom. + std::unique_ptr<content::InternalAuthenticatorImpl> authenticator_impl_; +#endif + // AutofillExternalDelegate instance that this object instantiates in the // case where the Autofill native UI is enabled. std::unique_ptr<AutofillExternalDelegate> autofill_external_delegate_;
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn index b3395cd82..8630436 100644 --- a/components/autofill/core/browser/BUILD.gn +++ b/components/autofill/core/browser/BUILD.gn
@@ -150,8 +150,6 @@ "payments/credit_card_access_manager.h", "payments/credit_card_cvc_authenticator.cc", "payments/credit_card_cvc_authenticator.h", - "payments/credit_card_fido_authenticator.cc", - "payments/credit_card_fido_authenticator.h", "payments/credit_card_save_manager.cc", "payments/credit_card_save_manager.h", "payments/credit_card_save_strike_database.cc", @@ -303,6 +301,8 @@ "autofill_credit_card_policy_handler.h", "autofill_policy_handler.cc", "autofill_policy_handler.h", + "payments/credit_card_fido_authenticator.cc", + "payments/credit_card_fido_authenticator.h", ] } @@ -361,6 +361,7 @@ deps += [ "//components/policy/core/browser", "//components/policy/core/common", + "//third_party/blink/public/common", ] } @@ -387,8 +388,6 @@ "mock_autocomplete_history_manager.h", "payments/test_authentication_requester.cc", "payments/test_authentication_requester.h", - "payments/test_credit_card_fido_authenticator.cc", - "payments/test_credit_card_fido_authenticator.h", "payments/test_credit_card_save_manager.cc", "payments/test_credit_card_save_manager.h", "payments/test_credit_card_save_strike_database.cc", @@ -463,6 +462,15 @@ "//ui/gfx:test_support", "//ui/gfx/geometry", ] + + if (!is_ios) { + sources += [ + "payments/test_credit_card_fido_authenticator.cc", + "payments/test_credit_card_fido_authenticator.h", + ] + + deps += [ "//third_party/blink/public/common" ] + } } bundle_data("unit_tests_bundle_data") { @@ -535,7 +543,6 @@ "payments/autofill_wallet_data_type_controller_unittest.cc", "payments/credit_card_access_manager_unittest.cc", "payments/credit_card_cvc_authenticator_unittest.cc", - "payments/credit_card_fido_authenticator_unittest.cc", "payments/credit_card_save_manager_unittest.cc", "payments/full_card_request_unittest.cc", "payments/legal_message_line_unittest.cc", @@ -578,6 +585,7 @@ "autofill_address_policy_handler_unittest.cc", "autofill_credit_card_policy_handler_unittest.cc", "autofill_policy_handler_unittest.cc", + "payments/credit_card_fido_authenticator_unittest.cc", ] } @@ -639,7 +647,10 @@ ] if (!is_ios) { - deps += [ "//components/policy/core/common" ] + deps += [ + "//components/policy/core/common", + "//third_party/blink/public/common", + ] } }
diff --git a/components/autofill/core/browser/DEPS b/components/autofill/core/browser/DEPS index d668f841..7cca31e 100644 --- a/components/autofill/core/browser/DEPS +++ b/components/autofill/core/browser/DEPS
@@ -59,6 +59,13 @@ "autofill_metrics_unittest\.cc": [ "+components/ukm", ], + "(test_)?credit_card_fido_authenticator\.(cc|h)": [ + "+third_party/blink/public/mojom/webauthn/authenticator.mojom.h", + "+third_party/blink/public/mojom/webauthn/internal_authenticator.mojom.h", + ], + "autofill_driver\.h": [ + "+third_party/blink/public/mojom/webauthn/internal_authenticator.mojom.h" + ], "credit_card_save_manager_unittest\.cc": [ "+components/ukm", ],
diff --git a/components/autofill/core/browser/autofill_driver.h b/components/autofill/core/browser/autofill_driver.h index e57ceed..dca5305 100644 --- a/components/autofill/core/browser/autofill_driver.h +++ b/components/autofill/core/browser/autofill_driver.h
@@ -8,8 +8,13 @@ #include <vector> #include "base/memory/scoped_refptr.h" +#include "build/build_config.h" #include "components/autofill/core/common/form_data.h" +#if !defined(OS_IOS) +#include "third_party/blink/public/mojom/webauthn/internal_authenticator.mojom.h" +#endif + namespace net { class URLRequestContextGetter; } @@ -57,6 +62,12 @@ // Returns true iff the renderer is available for communication. virtual bool RendererIsAvailable() = 0; +#if !defined(OS_IOS) + // Binds the mojom request in order to facilitate WebAuthn flows. + virtual void ConnectToAuthenticator( + blink::mojom::InternalAuthenticatorRequest request) = 0; +#endif + // Forwards |data| to the renderer. |query_id| is the id of the renderer's // original request for the data. |action| is the action the renderer should // perform with the |data|. This method is a no-op if the renderer is not
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc index e92a5e6e..a2964b1 100644 --- a/components/autofill/core/browser/autofill_manager.cc +++ b/components/autofill/core/browser/autofill_manager.cc
@@ -1262,7 +1262,7 @@ driver()->IsInMainFrame(), form_interactions_ukm_logger_.get(), personal_data_, client_)); credit_card_access_manager_.reset(new CreditCardAccessManager( - client_, personal_data_, credit_card_form_event_logger_.get())); + driver(), client_, personal_data_, credit_card_form_event_logger_.get())); #if defined(OS_ANDROID) || defined(OS_IOS) autofill_assistant_.Reset(); #endif @@ -1310,6 +1310,7 @@ personal_data_, client_)), credit_card_access_manager_(std::make_unique<CreditCardAccessManager>( + driver, client_, personal_data_, credit_card_form_event_logger_.get())),
diff --git a/components/autofill/core/browser/autofill_test_utils.cc b/components/autofill/core/browser/autofill_test_utils.cc index ebaee70..9ff57ce1 100644 --- a/components/autofill/core/browser/autofill_test_utils.cc +++ b/components/autofill/core/browser/autofill_test_utils.cc
@@ -399,6 +399,20 @@ return credit_card; } +CreditCard GetExpiredCreditCard() { + CreditCard credit_card(base::GenerateGUID(), kEmptyOrigin); + SetCreditCardInfo(&credit_card, "Test User", "4111111111111111" /* Visa */, + "11", "2002", "1"); + return credit_card; +} + +CreditCard GetIncompleteCreditCard() { + CreditCard credit_card(base::GenerateGUID(), kEmptyOrigin); + SetCreditCardInfo(&credit_card, "", "4111111111111111" /* Visa */, "11", + "2022", "1"); + return credit_card; +} + CreditCard GetVerifiedCreditCard() { CreditCard credit_card(GetCreditCard()); credit_card.set_origin(kSettingsOrigin);
diff --git a/components/autofill/core/browser/autofill_test_utils.h b/components/autofill/core/browser/autofill_test_utils.h index f8e34221..678a211 100644 --- a/components/autofill/core/browser/autofill_test_utils.h +++ b/components/autofill/core/browser/autofill_test_utils.h
@@ -124,6 +124,13 @@ // Returns a credit card full of dummy info, different to the above. CreditCard GetCreditCard2(); +// Returns an expired credit card full of fake info. +CreditCard GetExpiredCreditCard(); + +// Returns an incomplete credit card full of fake info with card holder's name +// missing. +CreditCard GetIncompleteCreditCard(); + // Returns a masked server card full of dummy info. CreditCard GetMaskedServerCard(); CreditCard GetMaskedServerCardAmex();
diff --git a/components/autofill/core/browser/payments/credit_card_access_manager.cc b/components/autofill/core/browser/payments/credit_card_access_manager.cc index 05f87c3..87adc19 100644 --- a/components/autofill/core/browser/payments/credit_card_access_manager.cc +++ b/components/autofill/core/browser/payments/credit_card_access_manager.cc
@@ -17,6 +17,7 @@ #include "base/task/post_task.h" #include "base/task/task_traits.h" #include "base/time/time.h" +#include "build/build_config.h" #include "components/autofill/core/browser/autofill_client.h" #include "components/autofill/core/browser/autofill_driver.h" #include "components/autofill/core/browser/autofill_manager.h" @@ -41,16 +42,20 @@ } // namespace CreditCardAccessManager::CreditCardAccessManager( + AutofillDriver* driver, AutofillManager* autofill_manager) : CreditCardAccessManager( + driver, autofill_manager->client(), autofill_manager->client()->GetPersonalDataManager()) {} CreditCardAccessManager::CreditCardAccessManager( + AutofillDriver* driver, AutofillClient* client, PersonalDataManager* personal_data_manager, CreditCardFormEventLogger* form_event_logger) - : client_(client), + : driver_(driver), + client_(client), payments_client_(client_->GetPaymentsClient()), personal_data_manager_(personal_data_manager), form_event_logger_(form_event_logger), @@ -147,16 +152,26 @@ void CreditCardAccessManager::PrepareToFetchCreditCard() { // Reset in case a late response was ignored. ready_to_start_authentication_.Reset(); +#if !defined(OS_IOS) + GetOrCreateFIDOAuthenticator()->IsUserVerifiable(base::BindOnce( + &CreditCardAccessManager::GetUnmaskDetailsIfUserIsVerifiable, + weak_ptr_factory_.GetWeakPtr())); +#endif +} - // If user is not verifiable, the only option is to perform CVC Auth, which - // does not require unmask details. - if (!GetOrCreateFIDOAuthenticator()->IsUserVerifiable()) - return; +void CreditCardAccessManager::GetUnmaskDetailsIfUserIsVerifiable( + bool is_user_verifiable) { + is_user_verifiable_ = is_user_verifiable; - payments_client_->GetUnmaskDetails( - base::BindOnce(&CreditCardAccessManager::OnDidGetUnmaskDetails, - weak_ptr_factory_.GetWeakPtr()), - personal_data_manager_->app_locale()); + // If user is verifiable, then make preflight call to payments to fetch unmask + // details, otherwise the only option is to perform CVC Auth, which does not + // require any. + if (is_user_verifiable_) { + payments_client_->GetUnmaskDetails( + base::BindOnce(&CreditCardAccessManager::OnDidGetUnmaskDetails, + weak_ptr_factory_.GetWeakPtr()), + personal_data_manager_->app_locale()); + } } void CreditCardAccessManager::OnDidGetUnmaskDetails( @@ -218,10 +233,14 @@ unmask_details_.fido_eligible_card_ids.end(); if (card_is_eligible_for_fido) { +#if defined(OS_IOS) + NOTREACHED(); +#else DCHECK(unmask_details_.fido_request_options.is_dict()); GetOrCreateFIDOAuthenticator()->Authenticate( - card_, weak_ptr_factory_.GetWeakPtr(), + card_, weak_ptr_factory_.GetWeakPtr(), form_parsed_timestamp_, std::move(unmask_details_.fido_request_options)); +#endif } else { GetOrCreateCVCAuthenticator()->Authenticate( card_, weak_ptr_factory_.GetWeakPtr(), personal_data_manager_, @@ -236,13 +255,15 @@ return cvc_authenticator_.get(); } +#if !defined(OS_IOS) CreditCardFIDOAuthenticator* CreditCardAccessManager::GetOrCreateFIDOAuthenticator() { if (!fido_authenticator_) fido_authenticator_ = - std::make_unique<CreditCardFIDOAuthenticator>(client_); + std::make_unique<CreditCardFIDOAuthenticator>(driver_, client_); return fido_authenticator_.get(); } +#endif void CreditCardAccessManager::OnCVCAuthenticationComplete( bool did_succeed, @@ -252,6 +273,7 @@ accessor_->OnCreditCardFetched(did_succeed, card, cvc); } +#if !defined(OS_IOS) void CreditCardAccessManager::OnFIDOAuthenticationComplete( bool did_succeed, const CreditCard* card) { @@ -266,10 +288,15 @@ form_parsed_timestamp_); } } +#endif bool CreditCardAccessManager::AuthenticationRequiresUnmaskDetails() { - return GetOrCreateFIDOAuthenticator()->IsUserVerifiable() && +#if defined(OS_IOS) + return false; +#else + return is_user_verifiable_.value_or(false) && GetOrCreateFIDOAuthenticator()->IsUserOptedIn(); +#endif } bool CreditCardAccessManager::IsLocalCard(const CreditCard* card) {
diff --git a/components/autofill/core/browser/payments/credit_card_access_manager.h b/components/autofill/core/browser/payments/credit_card_access_manager.h index 84ff78e..71b63791 100644 --- a/components/autofill/core/browser/payments/credit_card_access_manager.h +++ b/components/autofill/core/browser/payments/credit_card_access_manager.h
@@ -13,23 +13,31 @@ #include "base/strings/string16.h" #include "base/synchronization/waitable_event.h" +#include "build/build_config.h" #include "components/autofill/core/browser/autofill_client.h" #include "components/autofill/core/browser/autofill_driver.h" #include "components/autofill/core/browser/data_model/credit_card.h" #include "components/autofill/core/browser/metrics/credit_card_form_event_logger.h" #include "components/autofill/core/browser/payments/credit_card_cvc_authenticator.h" -#include "components/autofill/core/browser/payments/credit_card_fido_authenticator.h" #include "components/autofill/core/browser/payments/payments_client.h" #include "components/autofill/core/browser/personal_data_manager.h" +#if !defined(OS_IOS) +#include "components/autofill/core/browser/payments/credit_card_fido_authenticator.h" +#endif + namespace autofill { class AutofillManager; // Manages logic for accessing credit cards either stored locally or stored // with Google Payments. Owned by AutofillManager. +#if defined(OS_IOS) +class CreditCardAccessManager : public CreditCardCVCAuthenticator::Requester { +#else class CreditCardAccessManager : public CreditCardCVCAuthenticator::Requester, public CreditCardFIDOAuthenticator::Requester { +#endif public: class Accessor { public: @@ -40,8 +48,10 @@ const base::string16& cvc = base::string16()) = 0; }; - explicit CreditCardAccessManager(AutofillManager* autofill_manager); + explicit CreditCardAccessManager(AutofillDriver* driver, + AutofillManager* autofill_manager); CreditCardAccessManager( + AutofillDriver* driver, AutofillClient* client, PersonalDataManager* personal_data_manager, CreditCardFormEventLogger* credit_card_form_event_logger = nullptr); @@ -79,7 +89,9 @@ CreditCardCVCAuthenticator* GetOrCreateCVCAuthenticator(); +#if !defined(OS_IOS) CreditCardFIDOAuthenticator* GetOrCreateFIDOAuthenticator(); +#endif private: friend class AutofillAssistantTest; @@ -87,10 +99,19 @@ friend class AutofillMetricsTest; friend class CreditCardAccessManagerTest; +#if !defined(OS_IOS) void set_fido_authenticator_for_testing( std::unique_ptr<CreditCardFIDOAuthenticator> fido_authenticator) { fido_authenticator_ = std::move(fido_authenticator); } +#endif + + // Invoked from CreditCardFIDOAuthenticator::IsUserVerifiable(). + // |is_user_verifiable| is set to true only if user has a verifying platform + // authenticator. e.g. Touch/Face ID, Windows Hello, Android fingerprint, + // etc., is available and enabled. If set to true, then an Unmask Details + // request will be sent to Google Payments. + void GetUnmaskDetailsIfUserIsVerifiable(bool is_user_verifiable); // Sets |unmask_details_|. May be ignored if response is too late and user is // not opted-in for FIDO auth, or if user does not select a card. @@ -108,9 +129,11 @@ const CreditCard* card = nullptr, const base::string16& cvc = base::string16()) override; +#if !defined(OS_IOS) // CreditCardFIDOAuthenticator::Requester: void OnFIDOAuthenticationComplete(bool did_succeed, const CreditCard* card = nullptr) override; +#endif bool is_authentication_in_progress() { return is_authentication_in_progress_; @@ -128,6 +151,9 @@ // OnCVCAuthenticationComplete() to be executed. bool is_authentication_in_progress_ = false; + // The associated autofill driver. Weak reference. + AutofillDriver* const driver_; + // The associated autofill client. Weak reference. AutofillClient* const client_; @@ -148,7 +174,9 @@ // Authenticators for card unmasking. std::unique_ptr<CreditCardCVCAuthenticator> cvc_authenticator_; +#if !defined(OS_IOS) std::unique_ptr<CreditCardFIDOAuthenticator> fido_authenticator_; +#endif // Suggested authentication method and other information to facilitate card // unmasking. @@ -162,6 +190,11 @@ // The credit card being accessed. const CreditCard* card_; + // Set to true only if user has a verifying platform authenticator. + // e.g. Touch/Face ID, Windows Hello, Android fingerprint, etc., is available + // and enabled. + base::Optional<bool> is_user_verifiable_; + // The object attempting to access a card. base::WeakPtr<Accessor> accessor_;
diff --git a/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc b/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc index 6b6fb9f..10b154d 100644 --- a/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc +++ b/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc
@@ -39,7 +39,6 @@ #include "components/autofill/core/browser/data_model/credit_card.h" #include "components/autofill/core/browser/form_structure.h" #include "components/autofill/core/browser/metrics/form_events.h" -#include "components/autofill/core/browser/payments/test_credit_card_fido_authenticator.h" #include "components/autofill/core/browser/payments/test_payments_client.h" #include "components/autofill/core/browser/personal_data_manager.h" #include "components/autofill/core/browser/test_autofill_client.h" @@ -70,6 +69,10 @@ #include "ui/gfx/geometry/rect.h" #include "url/gurl.h" +#if !defined(OS_IOS) +#include "components/autofill/core/browser/payments/test_credit_card_fido_authenticator.h" +#endif + using base::ASCIIToUTF16; namespace autofill { @@ -154,9 +157,13 @@ autofill_client_.set_test_payments_client( std::unique_ptr<payments::TestPaymentsClient>(payments_client_)); credit_card_access_manager_ = std::make_unique<CreditCardAccessManager>( - &autofill_client_, &personal_data_manager_, nullptr); + autofill_driver_.get(), &autofill_client_, &personal_data_manager_, + nullptr); +#if !defined(OS_IOS) credit_card_access_manager_->set_fido_authenticator_for_testing( - std::make_unique<TestCreditCardFIDOAuthenticator>(&autofill_client_)); + std::make_unique<TestCreditCardFIDOAuthenticator>( + autofill_driver_.get(), &autofill_client_)); +#endif } void TearDown() override { @@ -197,6 +204,10 @@ personal_data_manager_.AddServerCreditCard(masked_server_card); } + CreditCardCVCAuthenticator* GetCVCAuthenticator() { + return credit_card_access_manager_->GetOrCreateCVCAuthenticator(); + } + // Returns true if full card request was sent from CVC auth. bool GetRealPanForCVCAuth(AutofillClient::PaymentsRpcResult result, const std::string& real_pan) { @@ -210,6 +221,7 @@ return true; } +#if !defined(OS_IOS) // Returns true if full card request was sent from FIDO auth. bool GetRealPanForFIDOAuth(AutofillClient::PaymentsRpcResult result, const std::string& real_pan) { @@ -223,10 +235,6 @@ return true; } - CreditCardCVCAuthenticator* GetCVCAuthenticator() { - return credit_card_access_manager_->GetOrCreateCVCAuthenticator(); - } - TestCreditCardFIDOAuthenticator* GetFIDOAuthenticator() { return static_cast<TestCreditCardFIDOAuthenticator*>( credit_card_access_manager_->GetOrCreateFIDOAuthenticator()); @@ -237,6 +245,7 @@ // default. Once implemented, update this function along with // TestCreditCardFIDOAuthenticator to mock a user verification gesture. } +#endif void InvokeUnmaskDetailsTimeout() { credit_card_access_manager_->ready_to_start_authentication_.Signal(); @@ -331,6 +340,9 @@ CreateLocalCard(kTestGUID, kTestNumber); CreditCard* card = credit_card_access_manager_->GetCreditCard(kTestGUID); + credit_card_access_manager_->PrepareToFetchCreditCard(); + WaitForCallbacks(); + credit_card_access_manager_->FetchCreditCard(card, accessor_->GetWeakPtr()); EXPECT_TRUE(accessor_->did_succeed()); @@ -341,6 +353,9 @@ TEST_F(CreditCardAccessManagerTest, FetchNullptrFailure) { personal_data_manager_.ClearCreditCards(); + credit_card_access_manager_->PrepareToFetchCreditCard(); + WaitForCallbacks(); + credit_card_access_manager_->FetchCreditCard(nullptr, accessor_->GetWeakPtr()); EXPECT_FALSE(accessor_->did_succeed()); @@ -352,6 +367,9 @@ CreateServerCard(kTestGUID, kTestNumber); CreditCard* card = credit_card_access_manager_->GetCreditCard(kTestGUID); + credit_card_access_manager_->PrepareToFetchCreditCard(); + WaitForCallbacks(); + credit_card_access_manager_->FetchCreditCard(card, accessor_->GetWeakPtr()); EXPECT_TRUE(GetRealPanForCVCAuth(AutofillClient::SUCCESS, kTestNumber)); @@ -365,6 +383,9 @@ CreateServerCard(kTestGUID, kTestNumber); CreditCard* card = credit_card_access_manager_->GetCreditCard(kTestGUID); + credit_card_access_manager_->PrepareToFetchCreditCard(); + WaitForCallbacks(); + credit_card_access_manager_->FetchCreditCard(card, accessor_->GetWeakPtr()); EXPECT_TRUE( @@ -378,6 +399,9 @@ CreateServerCard(kTestGUID, kTestNumber); CreditCard* card = credit_card_access_manager_->GetCreditCard(kTestGUID); + credit_card_access_manager_->PrepareToFetchCreditCard(); + WaitForCallbacks(); + credit_card_access_manager_->FetchCreditCard(card, accessor_->GetWeakPtr()); EXPECT_TRUE( @@ -401,6 +425,7 @@ EXPECT_EQ(ASCIIToUTF16(kTestNumber), accessor_->number()); } +#if !defined(OS_IOS) // Ensures that CVC prompt is invoked after WebAuthn fails. TEST_F(CreditCardAccessManagerTest, FetchServerCardFIDOFailureCVCFallback) { CreateServerCard(kTestGUID, kTestNumber); @@ -442,6 +467,7 @@ EXPECT_TRUE(accessor_->did_succeed()); EXPECT_EQ(ASCIIToUTF16(kTestNumber), accessor_->number()); } +#endif // Ensures that |is_authentication_in_progress_| is set correctly. TEST_F(CreditCardAccessManagerTest, AuthenticationInProgress) {
diff --git a/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc b/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc index 584e03b06..a8893baa 100644 --- a/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc +++ b/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc
@@ -4,16 +4,24 @@ #include "components/autofill/core/browser/payments/credit_card_fido_authenticator.h" +#include <string> +#include <utility> +#include <vector> + #include "base/strings/string16.h" #include "components/autofill/core/browser/autofill_client.h" #include "components/autofill/core/browser/data_model/credit_card.h" #include "components/autofill/core/browser/payments/payments_client.h" #include "components/autofill/core/common/autofill_payments_features.h" +#include "third_party/blink/public/mojom/webauthn/authenticator.mojom.h" +#include "third_party/blink/public/mojom/webauthn/internal_authenticator.mojom.h" namespace autofill { -CreditCardFIDOAuthenticator::CreditCardFIDOAuthenticator(AutofillClient* client) - : autofill_client_(client), +CreditCardFIDOAuthenticator::CreditCardFIDOAuthenticator(AutofillDriver* driver, + AutofillClient* client) + : autofill_driver_(driver), + autofill_client_(client), payments_client_(client->GetPaymentsClient()), weak_ptr_factory_(this) {} @@ -22,18 +30,26 @@ void CreditCardFIDOAuthenticator::Authenticate( const CreditCard* card, base::WeakPtr<Requester> requester, + base::TimeTicks form_parsed_timestamp, base::Value request_options) { - // TODO(crbug/949269): Add call to InternalAuthenticatorImpl::GetAssertion. + card_ = card; requester_ = requester; - requester_->OnFIDOAuthenticationComplete(false); + form_parsed_timestamp_ = form_parsed_timestamp; + + requester_->OnFIDOAuthenticationComplete(/*did_succeed=*/false); } -bool CreditCardFIDOAuthenticator::IsUserVerifiable() { - // TODO(crbug/949269): Add call to - // InternalAuthenticatorImpl::IsUserVerifyingPlatformAuthenticatorAvailable. - return base::FeatureList::IsEnabled( - features::kAutofillCreditCardAuthentication) && - false; +void CreditCardFIDOAuthenticator::IsUserVerifiable( + base::OnceCallback<void(bool)> callback) { + if (base::FeatureList::IsEnabled( + features::kAutofillCreditCardAuthentication)) { + autofill_driver_->ConnectToAuthenticator( + mojo::MakeRequest(&authenticator_)); + authenticator_->IsUserVerifyingPlatformAuthenticatorAvailable( + std::move(callback)); + } else { + std::move(callback).Run(false); + } } bool CreditCardFIDOAuthenticator::IsUserOptedIn() {
diff --git a/components/autofill/core/browser/payments/credit_card_fido_authenticator.h b/components/autofill/core/browser/payments/credit_card_fido_authenticator.h index 2078016..3fed058 100644 --- a/components/autofill/core/browser/payments/credit_card_fido_authenticator.h +++ b/components/autofill/core/browser/payments/credit_card_fido_authenticator.h
@@ -9,12 +9,16 @@ #include "base/strings/string16.h" #include "components/autofill/core/browser/autofill_client.h" +#include "components/autofill/core/browser/autofill_driver.h" #include "components/autofill/core/browser/data_model/credit_card.h" #include "components/autofill/core/browser/payments/full_card_request.h" #include "components/autofill/core/browser/payments/payments_client.h" +#include "third_party/blink/public/mojom/webauthn/internal_authenticator.mojom.h" namespace autofill { +using blink::mojom::InternalAuthenticatorPtr; + // Authenticates credit card unmasking through FIDO authentication, using the // WebAuthn specification, standardized by the FIDO alliance. The Webauthn // specification defines an API to cryptographically bind a server and client, @@ -30,18 +34,19 @@ bool did_succeed, const CreditCard* card = nullptr) = 0; }; - explicit CreditCardFIDOAuthenticator(AutofillClient* client); + CreditCardFIDOAuthenticator(AutofillDriver* driver, AutofillClient* client); virtual ~CreditCardFIDOAuthenticator(); // Authentication void Authenticate(const CreditCard* card, base::WeakPtr<Requester> requester, + base::TimeTicks form_parsed_timestamp, base::Value request_options); - // Returns true only if user has a verifying platform authenticator. - // e.g. Touch/Face ID, Windows Hello, Android Fingerprint etc is available and - // enabled. - virtual bool IsUserVerifiable(); + // Invokes callback with true if user has a verifying platform authenticator. + // e.g. Touch/Face ID, Windows Hello, Android fingerprint, etc., is available + // and enabled. Otherwise invokes callback with false. + virtual void IsUserVerifiable(base::OnceCallback<void(bool)> callback); // Returns true only if the user has opted-in to use WebAuthn for autofill. virtual bool IsUserOptedIn(); @@ -51,12 +56,24 @@ friend class CreditCardAccessManagerTest; friend class CreditCardFIDOAuthenticatorTest; + // Card being unmasked. + const CreditCard* card_; + + // Meant for histograms recorded in FullCardRequest. + base::TimeTicks form_parsed_timestamp_; + + // The associated autofill driver. Weak reference. + AutofillDriver* const autofill_driver_; + // The associated autofill client. Weak reference. AutofillClient* const autofill_client_; // Payments client to make requests to Google Payments. payments::PaymentsClient* const payments_client_; + // Authenticator pointer to facilitate WebAuthn. + InternalAuthenticatorPtr authenticator_; + // Responsible for getting the full card details, including the PAN and the // CVC. std::unique_ptr<payments::FullCardRequest> full_card_request_;
diff --git a/components/autofill/core/browser/payments/credit_card_fido_authenticator_unittest.cc b/components/autofill/core/browser/payments/credit_card_fido_authenticator_unittest.cc index 92e41dd..e3a0c5a8 100644 --- a/components/autofill/core/browser/payments/credit_card_fido_authenticator_unittest.cc +++ b/components/autofill/core/browser/payments/credit_card_fido_authenticator_unittest.cc
@@ -38,6 +38,7 @@ #include "components/autofill/core/browser/data_model/credit_card.h" #include "components/autofill/core/browser/metrics/form_events.h" #include "components/autofill/core/browser/payments/test_authentication_requester.h" +#include "components/autofill/core/browser/payments/test_credit_card_fido_authenticator.h" #include "components/autofill/core/browser/payments/test_payments_client.h" #include "components/autofill/core/browser/personal_data_manager.h" #include "components/autofill/core/browser/test_autofill_client.h" @@ -113,8 +114,8 @@ autofill_client_.GetIdentityManager(), &personal_data_manager_); autofill_client_.set_test_payments_client( std::unique_ptr<payments::TestPaymentsClient>(payments_client)); - fido_authenticator_ = - std::make_unique<CreditCardFIDOAuthenticator>(&autofill_client_); + fido_authenticator_ = std::make_unique<CreditCardFIDOAuthenticator>( + autofill_driver_.get(), &autofill_client_); } void TearDown() override { @@ -156,14 +157,17 @@ } TEST_F(CreditCardFIDOAuthenticatorTest, IsUserVerifiableFalse) { - EXPECT_FALSE(fido_authenticator_->IsUserVerifiable()); + fido_authenticator_->IsUserVerifiable( + base::BindOnce(&TestAuthenticationRequester::IsUserVerifiableCallback, + requester_->GetWeakPtr())); + EXPECT_FALSE(requester_->is_user_verifiable().value()); } TEST_F(CreditCardFIDOAuthenticatorTest, AuthenticateCardFailure) { CreditCard card = CreateServerCard(kTestGUID, kTestNumber); fido_authenticator_->Authenticate(&card, requester_->GetWeakPtr(), - base::Value()); + base::TimeTicks::Now(), base::Value()); EXPECT_FALSE(requester_->did_succeed()); }
diff --git a/components/autofill/core/browser/payments/test_authentication_requester.cc b/components/autofill/core/browser/payments/test_authentication_requester.cc index b6afed0..4a17806 100644 --- a/components/autofill/core/browser/payments/test_authentication_requester.cc +++ b/components/autofill/core/browser/payments/test_authentication_requester.cc
@@ -30,6 +30,7 @@ } } +#if !defined(OS_IOS) void TestAuthenticationRequester::OnFIDOAuthenticationComplete( bool did_succeed, const CreditCard* card) { @@ -40,4 +41,10 @@ } } +void TestAuthenticationRequester::IsUserVerifiableCallback( + bool is_user_verifiable) { + is_user_verifiable_ = is_user_verifiable; +} +#endif + } // namespace autofill
diff --git a/components/autofill/core/browser/payments/test_authentication_requester.h b/components/autofill/core/browser/payments/test_authentication_requester.h index a57a3cd..cc97c70 100644 --- a/components/autofill/core/browser/payments/test_authentication_requester.h +++ b/components/autofill/core/browser/payments/test_authentication_requester.h
@@ -6,18 +6,31 @@ #define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_TEST_AUTHENTICATION_REQUESTER_H_ #include <memory> +#include <string> +#include <utility> +#include <vector> #include "base/strings/string16.h" +#include "build/build_config.h" #include "components/autofill/core/browser/data_model/credit_card.h" #include "components/autofill/core/browser/payments/credit_card_cvc_authenticator.h" + +#if !defined(OS_IOS) #include "components/autofill/core/browser/payments/credit_card_fido_authenticator.h" +#endif namespace autofill { -// Test class for requesting authentication from CreditCardCVCAuthenticator. +// Test class for requesting authentication from CreditCardCVCAuthenticator or +// CreditCardFIDOAuthenticator. +#if defined(OS_IOS) +class TestAuthenticationRequester + : public CreditCardCVCAuthenticator::Requester { +#else class TestAuthenticationRequester : public CreditCardCVCAuthenticator::Requester, public CreditCardFIDOAuthenticator::Requester { +#endif public: TestAuthenticationRequester(); ~TestAuthenticationRequester() override; @@ -28,17 +41,26 @@ const CreditCard* card = nullptr, const base::string16& cvc = base::string16()) override; +#if !defined(OS_IOS) // CreditCardFIDOAuthenticator::Requester: void OnFIDOAuthenticationComplete(bool did_succeed, const CreditCard* card = nullptr) override; + void IsUserVerifiableCallback(bool is_user_verifiable); +#endif + base::WeakPtr<TestAuthenticationRequester> GetWeakPtr(); - base::string16 number() { return number_; } + base::Optional<bool> is_user_verifiable() { return is_user_verifiable_; } bool did_succeed() { return did_succeed_; } + base::string16 number() { return number_; } + private: + // Set when CreditCardFIDOAuthenticator invokes IsUserVerifiableCallback(). + base::Optional<bool> is_user_verifiable_; + // Is set to true if authentication was successful. bool did_succeed_ = false;
diff --git a/components/autofill/core/browser/payments/test_credit_card_fido_authenticator.cc b/components/autofill/core/browser/payments/test_credit_card_fido_authenticator.cc index ee60ad7..192047c 100644 --- a/components/autofill/core/browser/payments/test_credit_card_fido_authenticator.cc +++ b/components/autofill/core/browser/payments/test_credit_card_fido_authenticator.cc
@@ -4,19 +4,25 @@ #include "components/autofill/core/browser/payments/test_credit_card_fido_authenticator.h" +#include <utility> + #include "base/strings/string16.h" #include "components/autofill/core/browser/autofill_client.h" +#include "components/autofill/core/browser/autofill_driver.h" +#include "third_party/blink/public/mojom/webauthn/authenticator.mojom.h" namespace autofill { TestCreditCardFIDOAuthenticator::TestCreditCardFIDOAuthenticator( + AutofillDriver* driver, AutofillClient* client) - : CreditCardFIDOAuthenticator(client) {} + : CreditCardFIDOAuthenticator(driver, client) {} TestCreditCardFIDOAuthenticator::~TestCreditCardFIDOAuthenticator() {} -bool TestCreditCardFIDOAuthenticator::IsUserVerifiable() { - return is_user_verifiable_; +void TestCreditCardFIDOAuthenticator::IsUserVerifiable( + base::OnceCallback<void(bool)> callback) { + return std::move(callback).Run(is_user_verifiable_); } bool TestCreditCardFIDOAuthenticator::IsUserOptedIn() {
diff --git a/components/autofill/core/browser/payments/test_credit_card_fido_authenticator.h b/components/autofill/core/browser/payments/test_credit_card_fido_authenticator.h index bf326792..eb462f3 100644 --- a/components/autofill/core/browser/payments/test_credit_card_fido_authenticator.h +++ b/components/autofill/core/browser/payments/test_credit_card_fido_authenticator.h
@@ -6,19 +6,24 @@ #define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_TEST_CREDIT_CARD_FIDO_AUTHENTICATOR_H_ #include <memory> +#include <string> +#include <vector> #include "base/strings/string16.h" #include "components/autofill/core/browser/autofill_client.h" +#include "components/autofill/core/browser/autofill_driver.h" #include "components/autofill/core/browser/data_model/credit_card.h" #include "components/autofill/core/browser/payments/credit_card_fido_authenticator.h" #include "components/autofill/core/browser/payments/payments_client.h" +#include "third_party/blink/public/mojom/webauthn/authenticator.mojom.h" namespace autofill { // Test class for CreditCardFIDOAuthenticator. class TestCreditCardFIDOAuthenticator : public CreditCardFIDOAuthenticator { public: - explicit TestCreditCardFIDOAuthenticator(AutofillClient* client); + explicit TestCreditCardFIDOAuthenticator(AutofillDriver* driver, + AutofillClient* client); ~TestCreditCardFIDOAuthenticator() override; void SetUserVerifiable(bool is_user_verifiable) { @@ -30,7 +35,7 @@ } // CreditCardFIDOAuthenticator: - bool IsUserVerifiable() override; + void IsUserVerifiable(base::OnceCallback<void(bool)> callback) override; bool IsUserOptedIn() override; private:
diff --git a/components/autofill/core/browser/test_autofill_driver.cc b/components/autofill/core/browser/test_autofill_driver.cc index 2a1da042..92426282 100644 --- a/components/autofill/core/browser/test_autofill_driver.cc +++ b/components/autofill/core/browser/test_autofill_driver.cc
@@ -3,6 +3,8 @@ // found in the LICENSE file. #include "components/autofill/core/browser/test_autofill_driver.h" + +#include "build/build_config.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/test/test_url_loader_factory.h" @@ -40,6 +42,11 @@ return true; } +#if !defined(OS_IOS) +void TestAutofillDriver::ConnectToAuthenticator( + blink::mojom::InternalAuthenticatorRequest request) {} +#endif + void TestAutofillDriver::SendFormDataToRenderer(int query_id, RendererFormDataAction action, const FormData& form_data) {
diff --git a/components/autofill/core/browser/test_autofill_driver.h b/components/autofill/core/browser/test_autofill_driver.h index 52aba333..86fbd4e0 100644 --- a/components/autofill/core/browser/test_autofill_driver.h +++ b/components/autofill/core/browser/test_autofill_driver.h
@@ -8,6 +8,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "base/memory/scoped_refptr.h" +#include "build/build_config.h" #include "components/autofill/core/browser/autofill_driver.h" #include "services/network/test/test_url_loader_factory.h" @@ -27,6 +28,10 @@ net::URLRequestContextGetter* GetURLRequestContext() override; scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override; bool RendererIsAvailable() override; +#if !defined(OS_IOS) + void ConnectToAuthenticator( + blink::mojom::InternalAuthenticatorRequest request) override; +#endif void SendFormDataToRenderer(int query_id, RendererFormDataAction action, const FormData& data) override;
diff --git a/components/cronet/cronet_url_request.cc b/components/cronet/cronet_url_request.cc index ef8ce2fd..b0476e53 100644 --- a/components/cronet/cronet_url_request.cc +++ b/components/cronet/cronet_url_request.cc
@@ -24,6 +24,7 @@ #include "net/http/http_util.h" #include "net/ssl/ssl_info.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" +#include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/redirect_info.h" #include "net/url_request/url_request_context.h" @@ -277,7 +278,7 @@ << initial_url_.possibly_invalid_spec().c_str() << " priority: " << RequestPriorityToString(initial_priority_); url_request_ = context->GetURLRequestContext()->CreateRequest( - initial_url_, net::DEFAULT_PRIORITY, this); + initial_url_, net::DEFAULT_PRIORITY, this, MISSING_TRAFFIC_ANNOTATION); url_request_->SetLoadFlags(initial_load_flags_); url_request_->set_method(method); url_request_->SetExtraRequestHeaders(*request_headers);
diff --git a/components/favicon/core/BUILD.gn b/components/favicon/core/BUILD.gn index b9e3a01..f3acac1 100644 --- a/components/favicon/core/BUILD.gn +++ b/components/favicon/core/BUILD.gn
@@ -14,8 +14,6 @@ "favicon_driver_observer.h", "favicon_handler.cc", "favicon_handler.h", - "favicon_request_handler.cc", - "favicon_request_handler.h", "favicon_server_fetcher_params.cc", "favicon_server_fetcher_params.h", "favicon_service.h", @@ -28,6 +26,9 @@ "favicon_util.h", "features.cc", "features.h", + "history_ui_favicon_request_handler.h", + "history_ui_favicon_request_handler_impl.cc", + "history_ui_favicon_request_handler_impl.h", "large_icon_service.h", "large_icon_service_impl.cc", "large_icon_service_impl.h", @@ -53,8 +54,8 @@ sources = [ "fallback_url_util_unittest.cc", "favicon_handler_unittest.cc", - "favicon_request_handler_unittest.cc", "favicon_service_impl_unittest.cc", + "history_ui_favicon_request_handler_impl_unittest.cc", "large_icon_service_impl_unittest.cc", ]
diff --git a/components/favicon/core/history_ui_favicon_request_handler.h b/components/favicon/core/history_ui_favicon_request_handler.h new file mode 100644 index 0000000..e0fa7167 --- /dev/null +++ b/components/favicon/core/history_ui_favicon_request_handler.h
@@ -0,0 +1,80 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_FAVICON_CORE_HISTORY_UI_FAVICON_REQUEST_HANDLER_H_ +#define COMPONENTS_FAVICON_CORE_HISTORY_UI_FAVICON_REQUEST_HANDLER_H_ + +#include "components/favicon_base/favicon_callback.h" +#include "components/keyed_service/core/keyed_service.h" + +namespace base { +class CancelableTaskTracker; +} + +class GURL; + +namespace favicon { + +// The UI origin of an icon request. +// TODO(victorvianna): Adopt same naming style used in the platform enum. +// TODO(victorvianna): Rename enum to mention history UIs. +enum class FaviconRequestOrigin { + // Unknown origin. + UNKNOWN, + // History page. + HISTORY, + // History synced tabs page (desktop only). + HISTORY_SYNCED_TABS, + // Recently closed tabs menu. + RECENTLY_CLOSED_TABS, +}; + +// Platform making the request. +enum class FaviconRequestPlatform { + kMobile, + kDesktop, +}; + +// Keyed service for handling favicon requests made by a history UI, forwarding +// them to local storage, sync or Google server accordingly. This service should +// only be used by the UIs listed in the FaviconRequestOrigin enum. Requests +// must be made by page url, as opposed to icon url. +// TODO(victorvianna): Use a more natural order for the parameters in the API. +// TODO(victorvianna): Remove |icon_url_for_uma| when we have access to the +// FaviconUrlMapper. +class HistoryUiFaviconRequestHandler : public KeyedService { + public: + // Requests favicon bitmap at |page_url| of size |desired_size_in_pixel|. + // Tries to fetch the icon from local storage and falls back to sync, or to + // Google favicon server if |favicon::kEnableHistoryFaviconsGoogleServerQuery| + // is enabled. If a non-empty |icon_url_for_uma| (optional) is passed, it will + // be used to record UMA about the grouping of requests to the favicon server. + // |request_platform| specifies whether the caller is mobile or desktop code. + virtual void GetRawFaviconForPageURL( + const GURL& page_url, + int desired_size_in_pixel, + favicon_base::FaviconRawBitmapCallback callback, + FaviconRequestOrigin request_origin, + FaviconRequestPlatform request_platform, + const GURL& icon_url_for_uma, + base::CancelableTaskTracker* tracker) = 0; + + // Requests favicon image at |page_url|. + // Tries to fetch the icon from local storage and falls back to sync, or to + // Google favicon server if |favicon::kEnableHistoryFaviconsGoogleServerQuery| + // is enabled. + // If a non-empty |icon_url_for_uma| (optional) is passed, it will be used to + // record UMA about the grouping of requests to the favicon server. + // This method is only called by desktop code. + virtual void GetFaviconImageForPageURL( + const GURL& page_url, + favicon_base::FaviconImageCallback callback, + FaviconRequestOrigin request_origin, + const GURL& icon_url_for_uma, + base::CancelableTaskTracker* tracker) = 0; +}; + +} // namespace favicon + +#endif // COMPONENTS_FAVICON_CORE_HISTORY_UI_FAVICON_REQUEST_HANDLER_H_
diff --git a/components/favicon/core/favicon_request_handler.cc b/components/favicon/core/history_ui_favicon_request_handler_impl.cc similarity index 88% rename from components/favicon/core/favicon_request_handler.cc rename to components/favicon/core/history_ui_favicon_request_handler_impl.cc index 05f7a0b..3ca9cf3cf 100644 --- a/components/favicon/core/favicon_request_handler.cc +++ b/components/favicon/core/history_ui_favicon_request_handler_impl.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/favicon/core/favicon_request_handler.h" +#include "components/favicon/core/history_ui_favicon_request_handler_impl.h" #include <utility> @@ -11,6 +11,7 @@ #include "base/metrics/field_trial_params.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" +#include "base/task/cancelable_task_tracker.h" #include "components/favicon/core/favicon_server_fetcher_params.h" #include "components/favicon/core/favicon_service.h" #include "components/favicon/core/features.h" @@ -19,6 +20,7 @@ #include "components/favicon_base/favicon_util.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "ui/gfx/image/image_png_rep.h" +#include "url/gurl.h" namespace favicon { @@ -95,7 +97,7 @@ } // namespace -FaviconRequestHandler::FaviconRequestHandler( +HistoryUiFaviconRequestHandlerImpl::HistoryUiFaviconRequestHandlerImpl( const SyncedFaviconGetter& synced_favicon_getter, const CanSendHistoryDataGetter& can_send_history_data_getter, FaviconService* favicon_service, @@ -108,9 +110,9 @@ DCHECK(large_icon_service); } -FaviconRequestHandler::~FaviconRequestHandler() {} +HistoryUiFaviconRequestHandlerImpl::~HistoryUiFaviconRequestHandlerImpl() {} -void FaviconRequestHandler::GetRawFaviconForPageURL( +void HistoryUiFaviconRequestHandlerImpl::GetRawFaviconForPageURL( const GURL& page_url, int desired_size_in_pixel, favicon_base::FaviconRawBitmapCallback callback, @@ -122,16 +124,16 @@ favicon_service_->GetRawFaviconForPageURL( page_url, GetIconTypesForLocalQuery(), desired_size_in_pixel, kFallbackToHost, - base::BindOnce(&FaviconRequestHandler::OnBitmapLocalDataAvailable, - weak_ptr_factory_.GetWeakPtr(), page_url, - desired_size_in_pixel, - /*response_callback=*/std::move(callback), request_origin, - request_platform, icon_url_for_uma, - CanQueryGoogleServer(request_origin), tracker), + base::BindOnce( + &HistoryUiFaviconRequestHandlerImpl::OnBitmapLocalDataAvailable, + weak_ptr_factory_.GetWeakPtr(), page_url, desired_size_in_pixel, + /*response_callback=*/std::move(callback), request_origin, + request_platform, icon_url_for_uma, + CanQueryGoogleServer(request_origin), tracker), tracker); } -void FaviconRequestHandler::GetFaviconImageForPageURL( +void HistoryUiFaviconRequestHandlerImpl::GetFaviconImageForPageURL( const GURL& page_url, favicon_base::FaviconImageCallback callback, FaviconRequestOrigin request_origin, @@ -140,15 +142,15 @@ // First attempt to find the icon locally. favicon_service_->GetFaviconImageForPageURL( page_url, - base::BindOnce(&FaviconRequestHandler::OnImageLocalDataAvailable, - weak_ptr_factory_.GetWeakPtr(), page_url, - /*response_callback=*/std::move(callback), request_origin, - icon_url_for_uma, CanQueryGoogleServer(request_origin), - tracker), + base::BindOnce( + &HistoryUiFaviconRequestHandlerImpl::OnImageLocalDataAvailable, + weak_ptr_factory_.GetWeakPtr(), page_url, + /*response_callback=*/std::move(callback), request_origin, + icon_url_for_uma, CanQueryGoogleServer(request_origin), tracker), tracker); } -void FaviconRequestHandler::OnBitmapLocalDataAvailable( +void HistoryUiFaviconRequestHandlerImpl::OnBitmapLocalDataAvailable( const GURL& page_url, int desired_size_in_pixel, favicon_base::FaviconRawBitmapCallback response_callback, @@ -210,7 +212,7 @@ std::move(response_callback).Run(favicon_base::FaviconRawBitmapResult()); } -void FaviconRequestHandler::OnImageLocalDataAvailable( +void HistoryUiFaviconRequestHandlerImpl::OnImageLocalDataAvailable( const GURL& page_url, favicon_base::FaviconImageCallback response_callback, FaviconRequestOrigin origin, @@ -266,7 +268,7 @@ std::move(response_callback).Run(favicon_base::FaviconImageResult()); } -void FaviconRequestHandler::RequestFromGoogleServer( +void HistoryUiFaviconRequestHandlerImpl::RequestFromGoogleServer( const GURL& page_url, std::unique_ptr<FaviconServerFetcherParams> server_parameters, base::OnceClosure empty_response_callback, @@ -274,8 +276,9 @@ const GURL& icon_url_for_uma, FaviconRequestOrigin origin) { net::NetworkTrafficAnnotationTag traffic_annotation = - net::DefineNetworkTrafficAnnotation("favicon_request_handler_get_favicon", - R"( + net::DefineNetworkTrafficAnnotation( + "history_ui_favicon_request_handler_get_favicon", + R"( semantics { sender: "Favicon Request Handler" description: @@ -320,14 +323,14 @@ std::move(server_parameters), /*may_page_url_be_private=*/true, should_trim_url_path, traffic_annotation, - base::BindOnce(&FaviconRequestHandler::OnGoogleServerDataAvailable, - weak_ptr_factory_.GetWeakPtr(), - std::move(empty_response_callback), - std::move(local_lookup_callback), origin, - group_to_clear)); + base::BindOnce( + &HistoryUiFaviconRequestHandlerImpl::OnGoogleServerDataAvailable, + weak_ptr_factory_.GetWeakPtr(), + std::move(empty_response_callback), + std::move(local_lookup_callback), origin, group_to_clear)); } -void FaviconRequestHandler::OnGoogleServerDataAvailable( +void HistoryUiFaviconRequestHandlerImpl::OnGoogleServerDataAvailable( base::OnceClosure empty_response_callback, base::OnceClosure local_lookup_callback, FaviconRequestOrigin origin, @@ -358,7 +361,7 @@ } } -bool FaviconRequestHandler::CanQueryGoogleServer( +bool HistoryUiFaviconRequestHandlerImpl::CanQueryGoogleServer( FaviconRequestOrigin origin) const { // TODO(victorvianna): Remove origin check once extensions don't talk to this // layer anymore.
diff --git a/components/favicon/core/favicon_request_handler.h b/components/favicon/core/history_ui_favicon_request_handler_impl.h similarity index 69% rename from components/favicon/core/favicon_request_handler.h rename to components/favicon/core/history_ui_favicon_request_handler_impl.h index 9e03d6b..1b302193 100644 --- a/components/favicon/core/favicon_request_handler.h +++ b/components/favicon/core/history_ui_favicon_request_handler_impl.h
@@ -2,19 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_FAVICON_CORE_FAVICON_REQUEST_HANDLER_H_ -#define COMPONENTS_FAVICON_CORE_FAVICON_REQUEST_HANDLER_H_ +#ifndef COMPONENTS_FAVICON_CORE_HISTORY_UI_FAVICON_REQUEST_HANDLER_IMPL_H_ +#define COMPONENTS_FAVICON_CORE_HISTORY_UI_FAVICON_REQUEST_HANDLER_IMPL_H_ #include <map> #include <memory> -#include "base/memory/ref_counted_memory.h" #include "base/memory/weak_ptr.h" -#include "base/task/cancelable_task_tracker.h" -#include "components/favicon_base/favicon_callback.h" +#include "components/favicon/core/history_ui_favicon_request_handler.h" #include "components/favicon_base/favicon_types.h" -#include "components/keyed_service/core/keyed_service.h" -#include "url/gurl.h" namespace favicon { @@ -22,19 +18,6 @@ class FaviconService; class LargeIconService; -// The UI origin of an icon request. -// TODO(victorvianna): Rename to agree with the naming style of the other enums. -enum class FaviconRequestOrigin { - // Unknown origin. - UNKNOWN, - // History page. - HISTORY, - // History synced tabs page (desktop only). - HISTORY_SYNCED_TABS, - // Recently closed tabs menu. - RECENTLY_CLOSED_TABS, -}; - // Where the icon sent in the response is coming from. Used for metrics. enum class FaviconAvailability { // Icon recovered from local storage (but may originally come from server). @@ -46,18 +29,9 @@ kMaxValue = kNotAvailable, }; -// Platform making the request. -enum class FaviconRequestPlatform { - kMobile, - kDesktop, -}; - -// Keyed service for handling favicon requests by page url, forwarding them to -// local storage, sync or Google server accordingly. -// TODO(victorvianna): Use a more natural order for the parameters in the API. -// TODO(victorvianna): Remove |icon_url_for_uma| when we have access to the -// FaviconUrlMapper. -class FaviconRequestHandler : public KeyedService { +// Implementation class for HistoryUiFaviconRequestHandler. +class HistoryUiFaviconRequestHandlerImpl + : public HistoryUiFaviconRequestHandler { public: // Callback that requests the synced bitmap for a page url. using SyncedFaviconGetter = @@ -69,40 +43,27 @@ // enabled and no custom passphrase is set). using CanSendHistoryDataGetter = base::RepeatingCallback<bool()>; - FaviconRequestHandler( + HistoryUiFaviconRequestHandlerImpl( const SyncedFaviconGetter& synced_favicon_getter, const CanSendHistoryDataGetter& can_send_history_data_getter, FaviconService* favicon_service, LargeIconService* large_icon_service); - ~FaviconRequestHandler() override; + ~HistoryUiFaviconRequestHandlerImpl() override; - // Requests favicon bitmap at |page_url| of size |desired_size_in_pixel|. - // Tries to fetch the icon from local storage and falls back to sync, or to - // Google favicon server if |favicon::kEnableHistoryFaviconsGoogleServerQuery| - // is enabled. If a non-empty |icon_url_for_uma| (optional) is passed, it will - // be used to record UMA about the grouping of requests to the favicon server. - // |request_platform| specifies whether the caller is mobile or desktop code. void GetRawFaviconForPageURL(const GURL& page_url, int desired_size_in_pixel, favicon_base::FaviconRawBitmapCallback callback, FaviconRequestOrigin request_origin, FaviconRequestPlatform request_platform, const GURL& icon_url_for_uma, - base::CancelableTaskTracker* tracker); + base::CancelableTaskTracker* tracker) override; - // Requests favicon image at |page_url|. - // Tries to fetch the icon from local storage and falls back to sync, or to - // Google favicon server if |favicon::kEnableHistoryFaviconsGoogleServerQuery| - // is enabled. - // If a non-empty |icon_url_for_uma| (optional) is passed, it will be used to - // record UMA about the grouping of requests to the favicon server. - // This method is only called by desktop code. void GetFaviconImageForPageURL(const GURL& page_url, favicon_base::FaviconImageCallback callback, FaviconRequestOrigin request_origin, const GURL& icon_url_for_uma, - base::CancelableTaskTracker* tracker); + base::CancelableTaskTracker* tracker) override; private: // Called after the first attempt to retrieve the icon bitmap from local @@ -173,11 +134,12 @@ // benefit of grouping. std::map<GURL, int> group_callbacks_count_; - base::WeakPtrFactory<FaviconRequestHandler> weak_ptr_factory_{this}; + base::WeakPtrFactory<HistoryUiFaviconRequestHandlerImpl> weak_ptr_factory_{ + this}; - DISALLOW_COPY_AND_ASSIGN(FaviconRequestHandler); + DISALLOW_COPY_AND_ASSIGN(HistoryUiFaviconRequestHandlerImpl); }; } // namespace favicon -#endif // COMPONENTS_FAVICON_CORE_FAVICON_REQUEST_HANDLER_H_ +#endif // COMPONENTS_FAVICON_CORE_HISTORY_UI_FAVICON_REQUEST_HANDLER_IMPL_H_
diff --git a/components/favicon/core/favicon_request_handler_unittest.cc b/components/favicon/core/history_ui_favicon_request_handler_impl_unittest.cc similarity index 88% rename from components/favicon/core/favicon_request_handler_unittest.cc rename to components/favicon/core/history_ui_favicon_request_handler_impl_unittest.cc index 17b4dfc..55cf72f 100644 --- a/components/favicon/core/favicon_request_handler_unittest.cc +++ b/components/favicon/core/history_ui_favicon_request_handler_impl_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/favicon/core/favicon_request_handler.h" +#include "components/favicon/core/history_ui_favicon_request_handler_impl.h" #include <utility> @@ -120,32 +120,32 @@ MOCK_METHOD1(TouchIconFromGoogleServer, void(const GURL& icon_url)); }; -class FaviconRequestHandlerTest : public ::testing::Test { +class HistoryUiFaviconRequestHandlerImplTest : public ::testing::Test { public: - FaviconRequestHandlerTest() - : favicon_request_handler_(synced_favicon_getter_.Get(), - can_send_history_data_getter_.Get(), - &mock_favicon_service_, - &mock_large_icon_service_) { + HistoryUiFaviconRequestHandlerImplTest() + : history_ui_favicon_request_handler_(synced_favicon_getter_.Get(), + can_send_history_data_getter_.Get(), + &mock_favicon_service_, + &mock_large_icon_service_) { ON_CALL(can_send_history_data_getter_, Run()).WillByDefault(Return(true)); } protected: testing::NiceMock<MockFaviconService> mock_favicon_service_; testing::NiceMock<MockLargeIconService> mock_large_icon_service_; - testing::NiceMock< - base::MockCallback<FaviconRequestHandler::SyncedFaviconGetter>> + testing::NiceMock<base::MockCallback< + HistoryUiFaviconRequestHandlerImpl::SyncedFaviconGetter>> synced_favicon_getter_; - testing::NiceMock< - base::MockCallback<FaviconRequestHandler::CanSendHistoryDataGetter>> + testing::NiceMock<base::MockCallback< + HistoryUiFaviconRequestHandlerImpl::CanSendHistoryDataGetter>> can_send_history_data_getter_; base::CancelableTaskTracker tracker_; base::HistogramTester histogram_tester_; base::test::ScopedFeatureList scoped_feature_list_; - FaviconRequestHandler favicon_request_handler_; + HistoryUiFaviconRequestHandlerImpl history_ui_favicon_request_handler_; }; -TEST_F(FaviconRequestHandlerTest, ShouldGetEmptyBitmap) { +TEST_F(HistoryUiFaviconRequestHandlerImplTest, ShouldGetEmptyBitmap) { scoped_feature_list_.InitAndDisableFeature( kEnableHistoryFaviconsGoogleServerQuery); EXPECT_CALL( @@ -160,7 +160,7 @@ EXPECT_CALL(synced_favicon_getter_, Run(GURL(kDummyPageUrl))) .WillOnce([](auto) { return favicon_base::FaviconRawBitmapResult(); }); favicon_base::FaviconRawBitmapResult result; - favicon_request_handler_.GetRawFaviconForPageURL( + history_ui_favicon_request_handler_.GetRawFaviconForPageURL( GURL(kDummyPageUrl), kDefaultDesiredSizeInPixel, base::BindOnce(&StoreBitmap, &result), FaviconRequestOrigin::UNKNOWN, kDummyPlatform, @@ -170,7 +170,7 @@ FaviconAvailability::kNotAvailable, 1); } -TEST_F(FaviconRequestHandlerTest, ShouldGetSyncBitmap) { +TEST_F(HistoryUiFaviconRequestHandlerImplTest, ShouldGetSyncBitmap) { scoped_feature_list_.InitAndDisableFeature( kEnableHistoryFaviconsGoogleServerQuery); EXPECT_CALL( @@ -185,7 +185,7 @@ EXPECT_CALL(synced_favicon_getter_, Run(GURL(kDummyPageUrl))) .WillOnce([](auto) { return CreateTestBitmapResult(); }); favicon_base::FaviconRawBitmapResult result; - favicon_request_handler_.GetRawFaviconForPageURL( + history_ui_favicon_request_handler_.GetRawFaviconForPageURL( GURL(kDummyPageUrl), kDefaultDesiredSizeInPixel, base::BindOnce(&StoreBitmap, &result), FaviconRequestOrigin::UNKNOWN, kDummyPlatform, @@ -195,7 +195,7 @@ FaviconAvailability::kSync, 1); } -TEST_F(FaviconRequestHandlerTest, ShouldGetLocalBitmap) { +TEST_F(HistoryUiFaviconRequestHandlerImplTest, ShouldGetLocalBitmap) { scoped_feature_list_.InitAndDisableFeature( kEnableHistoryFaviconsGoogleServerQuery); EXPECT_CALL( @@ -211,7 +211,7 @@ TouchIconFromGoogleServer(GURL(kDummyIconUrl))); EXPECT_CALL(synced_favicon_getter_, Run(_)).Times(0); favicon_base::FaviconRawBitmapResult result; - favicon_request_handler_.GetRawFaviconForPageURL( + history_ui_favicon_request_handler_.GetRawFaviconForPageURL( GURL(kDummyPageUrl), kDefaultDesiredSizeInPixel, base::BindOnce(&StoreBitmap, &result), FaviconRequestOrigin::UNKNOWN, kDummyPlatform, @@ -221,7 +221,8 @@ FaviconAvailability::kLocal, 1); } -TEST_F(FaviconRequestHandlerTest, ShouldGetGoogleServerBitmapForFullUrl) { +TEST_F(HistoryUiFaviconRequestHandlerImplTest, + ShouldGetGoogleServerBitmapForFullUrl) { scoped_feature_list_.InitAndEnableFeatureWithParameters( kEnableHistoryFaviconsGoogleServerQuery, {{"trim_url_path", "false"}}); EXPECT_CALL(can_send_history_data_getter_, Run()); @@ -249,7 +250,7 @@ }); EXPECT_CALL(synced_favicon_getter_, Run(_)).Times(0); favicon_base::FaviconRawBitmapResult result; - favicon_request_handler_.GetRawFaviconForPageURL( + history_ui_favicon_request_handler_.GetRawFaviconForPageURL( GURL(kDummyPageUrl), kDefaultDesiredSizeInPixel, base::BindOnce(&StoreBitmap, &result), FaviconRequestOrigin::HISTORY, kDummyPlatform, @@ -257,7 +258,8 @@ EXPECT_TRUE(result.is_valid()); } -TEST_F(FaviconRequestHandlerTest, ShouldGetGoogleServerBitmapForTrimmedUrl) { +TEST_F(HistoryUiFaviconRequestHandlerImplTest, + ShouldGetGoogleServerBitmapForTrimmedUrl) { scoped_feature_list_.InitAndEnableFeatureWithParameters( kEnableHistoryFaviconsGoogleServerQuery, {{"trim_url_path", "true"}}); EXPECT_CALL(can_send_history_data_getter_, Run()); @@ -285,7 +287,7 @@ }); EXPECT_CALL(synced_favicon_getter_, Run(_)).Times(0); favicon_base::FaviconRawBitmapResult result; - favicon_request_handler_.GetRawFaviconForPageURL( + history_ui_favicon_request_handler_.GetRawFaviconForPageURL( GURL(kDummyPageUrl), kDefaultDesiredSizeInPixel, base::BindOnce(&StoreBitmap, &result), FaviconRequestOrigin::HISTORY, kDummyPlatform, @@ -297,7 +299,7 @@ "Sync.SizeOfFaviconServerRequestGroup.HISTORY", 1, 1); } -TEST_F(FaviconRequestHandlerTest, ShouldGetEmptyImage) { +TEST_F(HistoryUiFaviconRequestHandlerImplTest, ShouldGetEmptyImage) { scoped_feature_list_.InitAndDisableFeature( kEnableHistoryFaviconsGoogleServerQuery); EXPECT_CALL(mock_favicon_service_, @@ -309,7 +311,7 @@ EXPECT_CALL(synced_favicon_getter_, Run(GURL(kDummyPageUrl))) .WillOnce([](auto) { return favicon_base::FaviconRawBitmapResult(); }); favicon_base::FaviconImageResult result; - favicon_request_handler_.GetFaviconImageForPageURL( + history_ui_favicon_request_handler_.GetFaviconImageForPageURL( GURL(kDummyPageUrl), base::BindOnce(&StoreImage, &result), FaviconRequestOrigin::UNKNOWN, /*icon_url_for_uma=*/GURL(), &tracker_); @@ -318,7 +320,7 @@ FaviconAvailability::kNotAvailable, 1); } -TEST_F(FaviconRequestHandlerTest, ShouldGetSyncImage) { +TEST_F(HistoryUiFaviconRequestHandlerImplTest, ShouldGetSyncImage) { scoped_feature_list_.InitAndDisableFeature( kEnableHistoryFaviconsGoogleServerQuery); EXPECT_CALL(mock_favicon_service_, @@ -330,7 +332,7 @@ EXPECT_CALL(synced_favicon_getter_, Run(GURL(kDummyPageUrl))) .WillOnce([](auto) { return CreateTestBitmapResult(); }); favicon_base::FaviconImageResult result; - favicon_request_handler_.GetFaviconImageForPageURL( + history_ui_favicon_request_handler_.GetFaviconImageForPageURL( GURL(kDummyPageUrl), base::BindOnce(&StoreImage, &result), FaviconRequestOrigin::UNKNOWN, /*icon_url_for_uma=*/GURL(), &tracker_); @@ -339,7 +341,7 @@ FaviconAvailability::kSync, 1); } -TEST_F(FaviconRequestHandlerTest, ShouldGetLocalImage) { +TEST_F(HistoryUiFaviconRequestHandlerImplTest, ShouldGetLocalImage) { scoped_feature_list_.InitAndDisableFeature( kEnableHistoryFaviconsGoogleServerQuery); EXPECT_CALL(mock_favicon_service_, @@ -352,7 +354,7 @@ TouchIconFromGoogleServer(GURL(kDummyIconUrl))); EXPECT_CALL(synced_favicon_getter_, Run(_)).Times(0); favicon_base::FaviconImageResult result; - favicon_request_handler_.GetFaviconImageForPageURL( + history_ui_favicon_request_handler_.GetFaviconImageForPageURL( GURL(kDummyPageUrl), base::BindOnce(&StoreImage, &result), FaviconRequestOrigin::UNKNOWN, /*icon_url_for_uma=*/GURL(), &tracker_); @@ -361,7 +363,8 @@ FaviconAvailability::kLocal, 1); } -TEST_F(FaviconRequestHandlerTest, ShouldGetGoogleServerImageForFullUrl) { +TEST_F(HistoryUiFaviconRequestHandlerImplTest, + ShouldGetGoogleServerImageForFullUrl) { scoped_feature_list_.InitAndEnableFeatureWithParameters( kEnableHistoryFaviconsGoogleServerQuery, {{"trim_url_path", "false"}}); EXPECT_CALL(can_send_history_data_getter_, Run()); @@ -385,7 +388,7 @@ }); EXPECT_CALL(synced_favicon_getter_, Run(_)).Times(0); favicon_base::FaviconImageResult result; - favicon_request_handler_.GetFaviconImageForPageURL( + history_ui_favicon_request_handler_.GetFaviconImageForPageURL( GURL(kDummyPageUrl), base::BindOnce(&StoreImage, &result), FaviconRequestOrigin::RECENTLY_CLOSED_TABS, /*icon_url_for_uma=*/GURL(), &tracker_); @@ -397,7 +400,8 @@ "Sync.SizeOfFaviconServerRequestGroup.RECENTLY_CLOSED_TABS", 1, 1); } -TEST_F(FaviconRequestHandlerTest, ShouldGetGoogleServerImageForTrimmedUrl) { +TEST_F(HistoryUiFaviconRequestHandlerImplTest, + ShouldGetGoogleServerImageForTrimmedUrl) { scoped_feature_list_.InitAndEnableFeatureWithParameters( kEnableHistoryFaviconsGoogleServerQuery, {{"trim_url_path", "true"}}); EXPECT_CALL(can_send_history_data_getter_, Run()); @@ -421,7 +425,7 @@ }); EXPECT_CALL(synced_favicon_getter_, Run(_)).Times(0); favicon_base::FaviconImageResult result; - favicon_request_handler_.GetFaviconImageForPageURL( + history_ui_favicon_request_handler_.GetFaviconImageForPageURL( GURL(kDummyPageUrl), base::BindOnce(&StoreImage, &result), FaviconRequestOrigin::RECENTLY_CLOSED_TABS, /*icon_url_for_uma=*/GURL(), @@ -429,7 +433,8 @@ EXPECT_FALSE(result.image.IsEmpty()); } -TEST_F(FaviconRequestHandlerTest, ShouldNotQueryGoogleServerIfCannotSendData) { +TEST_F(HistoryUiFaviconRequestHandlerImplTest, + ShouldNotQueryGoogleServerIfCannotSendData) { scoped_feature_list_.InitAndEnableFeature( kEnableHistoryFaviconsGoogleServerQuery); EXPECT_CALL(can_send_history_data_getter_, Run()).WillOnce([]() { @@ -449,14 +454,14 @@ _, _, _, _, _)) .Times(0); favicon_base::FaviconRawBitmapResult result; - favicon_request_handler_.GetRawFaviconForPageURL( + history_ui_favicon_request_handler_.GetRawFaviconForPageURL( GURL(kDummyPageUrl), kDefaultDesiredSizeInPixel, base::BindOnce(&StoreBitmap, &result), FaviconRequestOrigin::HISTORY, kDummyPlatform, /*icon_url_for_uma=*/GURL(), &tracker_); } -TEST_F(FaviconRequestHandlerTest, ShouldResizeSyncBitmap) { +TEST_F(HistoryUiFaviconRequestHandlerImplTest, ShouldResizeSyncBitmap) { const int kDesiredSizeInPixel = 32; base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list_.InitAndDisableFeature( @@ -473,7 +478,7 @@ EXPECT_CALL(synced_favicon_getter_, Run(GURL(kDummyPageUrl))) .WillOnce([](auto) { return CreateTestBitmapResult(16); }); favicon_base::FaviconRawBitmapResult result; - favicon_request_handler_.GetRawFaviconForPageURL( + history_ui_favicon_request_handler_.GetRawFaviconForPageURL( GURL(kDummyPageUrl), kDesiredSizeInPixel, base::BindOnce(&StoreBitmap, &result), FaviconRequestOrigin::UNKNOWN, kDummyPlatform,
diff --git a/components/feedback/anonymizer_tool_unittest.cc b/components/feedback/anonymizer_tool_unittest.cc index 4bb2faa..4f490481 100644 --- a/components/feedback/anonymizer_tool_unittest.cc +++ b/components/feedback/anonymizer_tool_unittest.cc
@@ -209,145 +209,153 @@ } TEST_F(AnonymizerToolTest, AnonymizeChunk) { - std::string data = - "aaaaaaaa [SSID=123aaaaaa]aaaaa\n" // SSID. - "aaaaaaaahttp://tets.comaaaaaaa\n" // URL. - "aaaaaemail@example.comaaa\n" // Email address. - "example@@1234\n" // No PII, it is not valid email address. - "255.255.155.2\n" // IP address. - "255.255.155.255\n" // IP address. - "127.0.0.1\n" // IPv4 loopback. - "127.255.0.1\n" // IPv4 loopback. - "0.0.0.0\n" // Any IPv4. - "0.255.255.255\n" // Any IPv4. - "10.10.10.100\n" // IPv4 private class A. - "10.10.10.100\n" // Intentional duplicate. - "10.10.10.101\n" // IPv4 private class A. - "10.255.255.255\n" // IPv4 private class A. - "172.16.0.0\n" // IPv4 private class B. - "172.31.255.255\n" // IPv4 private class B. - "172.11.5.5\n" // IP address. - "172.111.5.5\n" // IP address. - "192.168.0.0\n" // IPv4 private class C. - "192.168.255.255\n" // IPv4 private class C. - "192.169.2.120\n" // IP address. - "169.254.0.1\n" // Link local. - "169.200.0.1\n" // IP address. - "fe80::\n" // Link local. - "fe80::ffff\n" // Link local. - "febf:ffff::ffff\n" // Link local. - "fecc::1111\n" // IP address. - "224.0.0.24\n" // Multicast. - "240.0.0.0\n" // IP address. - "255.255.255.255\n" // Broadcast. - "100.115.92.92\n" // ChromeOS. - "100.115.91.92\n" // IP address. - "1.1.1.1\n" // DNS - "8.8.8.8\n" // DNS - "8.8.4.4\n" // DNS - "8.8.8.4\n" // IP address. - "255.255.259.255\n" // Not an IP address. - "255.300.255.255\n" // Not an IP address. - "aaaa123.123.45.4aaa\n" // IP address. - "11:11;11::11\n" // IP address. - "11::11\n" // IP address. - "11:11:abcdef:0:0:0:0:0\n" // No PII. - "::\n" // Unspecified. - "::1\n" // Local host. - "Instance::Set\n" // Ignore match, no PII. - "Instant::ff\n" // Ignore match, no PII. - "net::ERR_CONN_TIMEOUT\n" // Ignore match, no PII. - "ff01::1\n" // All nodes address (interface local). - "ff01::2\n" // All routers (interface local). - "ff01::3\n" // Multicast (interface local). - "ff02::1\n" // All nodes address (link local). - "ff02::2\n" // All routers (link local). - "ff02::3\n" // Multicast (link local). - "ff02::fb\n" // mDNSv6 (link local). - "ff08::fb\n" // mDNSv6. - "ff0f::101\n" // All NTP servers. - "::ffff:cb0c:10ea\n" // IPv4-mapped IPV6 (IP address). - "::ffff:a0a:a0a\n" // IPv4-mapped IPV6 (private class A). - "::ffff:a0a:a0a\n" // Intentional duplicate. - "::ffff:ac1e:1e1e\n" // IPv4-mapped IPV6 (private class B). - "::ffff:c0a8:640a\n" // IPv4-mapped IPV6 (private class C). - "::ffff:6473:5c01\n" // IPv4-mapped IPV6 (Chrome). - "64:ff9b::a0a:a0a\n" // IPv4-translated 6to4 IPV6 (private class A). - "64:ff9b::6473:5c01\n" // IPv4-translated 6to4 IPV6 (Chrome). - "::0101:ffff:c0a8:640a\n" // IP address. - "aa:aa:aa:aa:aa:aa\n" // MAC address (BSSID). - "chrome://resources/foo\n" // Secure chrome resource, whitelisted. - "chrome://resources/f?user=bar"; // Potentially PII in parameter. - std::string result = - "aaaaaaaa [SSID=1]aaaaa\n" - "aaaaaaaa<URL: 1>\n" - "<email: 1>\n" - "example@@1234\n" - "<IPv4: 1>\n" - "<IPv4: 2>\n" - "<127.0.0.0/8: 3>\n" - "<127.0.0.0/8: 4>\n" - "<0.0.0.0/8: 5>\n" - "<0.0.0.0/8: 6>\n" - "<10.0.0.0/8: 7>\n" - "<10.0.0.0/8: 7>\n" - "<10.0.0.0/8: 8>\n" - "<10.0.0.0/8: 9>\n" - "<172.16.0.0/12: 10>\n" - "<172.16.0.0/12: 11>\n" - "<IPv4: 12>\n" - "<IPv4: 13>\n" - "<192.168.0.0/16: 14>\n" - "<192.168.0.0/16: 15>\n" - "<IPv4: 16>\n" - "<169.254.0.0/16: 17>\n" - "<IPv4: 18>\n" - "<fe80::/10: 1>\n" - "<fe80::/10: 2>\n" - "<fe80::/10: 3>\n" - "<IPv6: 4>\n" - "<224.0.0.0/4: 19>\n" - "<IPv4: 20>\n" - "255.255.255.255\n" - "100.115.92.92\n" - "<IPv4: 23>\n" - "1.1.1.1\n" - "8.8.8.8\n" - "8.8.4.4\n" - "<IPv4: 27>\n" - "255.255.259.255\n" - "255.300.255.255\n" - "aaaa<IPv4: 28>aaa\n" - "11:11;<IPv6: 5>\n" - "<IPv6: 5>\n" - "11:11:abcdef:0:0:0:0:0\n" - "::\n" - "::1\n" - "Instance::Set\n" - "Instant::ff\n" - "net::ERR_CONN_TIMEOUT\n" - "ff01::1\n" - "ff01::2\n" - "<ff01::/16: 13>\n" - "ff02::1\n" - "ff02::2\n" - "<ff02::/16: 16>\n" - "<ff02::/16: 17>\n" - "<IPv6: 18>\n" - "<IPv6: 19>\n" - "<IPv6: 20>\n" - "<M 10.0.0.0/8: 21>\n" - "<M 10.0.0.0/8: 21>\n" - "<M 172.16.0.0/12: 22>\n" - "<M 192.168.0.0/16: 23>\n" - "<M 100.115.92.1: 24>\n" - "<T 10.0.0.0/8: 25>\n" - "<T 100.115.92.1: 26>\n" - "<IPv6: 27>\n" - "aa:aa:aa:00:00:01\n" - "chrome://resources/foo\n" - "<URL: 2>"; - EXPECT_EQ(result, anonymizer_.Anonymize(data)); + // For better readability, put all the pre/post redaction strings in an array + // of pairs, and then convert that to two strings which become the input and + // output of the anonymizer. + std::pair<std::string, std::string> data[] = { + {"aaaaaaaa [SSID=123aaaaaa]aaaaa", // SSID. + "aaaaaaaa [SSID=1]aaaaa"}, + {"aaaaaaaahttp://tets.comaaaaaaa", // URL. + "aaaaaaaa<URL: 1>"}, + {"aaaaaemail@example.comaaa", // Email address. + "<email: 1>"}, + {"example@@1234", // No PII, it is not invalid email address. + "example@@1234"}, + {"255.255.155.2", // IP address. + "<IPv4: 1>"}, + {"255.255.155.255", // IP address. + "<IPv4: 2>"}, + {"127.0.0.1", // IPv4 loopback. + "<127.0.0.0/8: 3>"}, + {"127.255.0.1", // IPv4 loopback. + "<127.0.0.0/8: 4>"}, + {"0.0.0.0", // Any IPv4. + "<0.0.0.0/8: 5>"}, + {"0.255.255.255", // Any IPv4. + "<0.0.0.0/8: 6>"}, + {"10.10.10.100", // IPv4 private class A. + "<10.0.0.0/8: 7>"}, + {"10.10.10.100", // Intentional duplicate. + "<10.0.0.0/8: 7>"}, + {"10.10.10.101", // IPv4 private class A. + "<10.0.0.0/8: 8>"}, + {"10.255.255.255", // IPv4 private class A. + "<10.0.0.0/8: 9>"}, + {"172.16.0.0", // IPv4 private class B. + "<172.16.0.0/12: 10>"}, + {"172.31.255.255", // IPv4 private class B. + "<172.16.0.0/12: 11>"}, + {"172.11.5.5", // IP address. + "<IPv4: 12>"}, + {"172.111.5.5", // IP address. + "<IPv4: 13>"}, + {"192.168.0.0", // IPv4 private class C. + "<192.168.0.0/16: 14>"}, + {"192.168.255.255", // IPv4 private class C. + "<192.168.0.0/16: 15>"}, + {"192.169.2.120", // IP address. + "<IPv4: 16>"}, + {"169.254.0.1", // Link local. + "<169.254.0.0/16: 17>"}, + {"169.200.0.1", // IP address. + "<IPv4: 18>"}, + {"fe80::", // Link local. + "<fe80::/10: 1>"}, + {"fe80::ffff", // Link local. + "<fe80::/10: 2>"}, + {"febf:ffff::ffff", // Link local. + "<fe80::/10: 3>"}, + {"fecc::1111", // IP address. + "<IPv6: 4>"}, + {"224.0.0.24", // Multicast. + "<224.0.0.0/4: 19>"}, + {"240.0.0.0", // IP address. + "<IPv4: 20>"}, + {"255.255.255.255", // Broadcast. + "255.255.255.255"}, + {"100.115.92.92", // ChromeOS. + "100.115.92.92"}, + {"100.115.91.92", // IP address. + "<IPv4: 23>"}, + {"1.1.1.1", // DNS + "1.1.1.1"}, + {"8.8.8.8", // DNS + "8.8.8.8"}, + {"8.8.4.4", // DNS + "8.8.4.4"}, + {"8.8.8.4", // IP address. + "<IPv4: 27>"}, + {"255.255.259.255", // Not an IP address. + "255.255.259.255"}, + {"255.300.255.255", // Not an IP address. + "255.300.255.255"}, + {"aaaa123.123.45.4aaa", // IP address. + "aaaa<IPv4: 28>aaa"}, + {"11:11;11::11", // IP address. + "11:11;<IPv6: 5>"}, + {"11::11", // IP address. + "<IPv6: 5>"}, + {"11:11:abcdef:0:0:0:0:0", // No PII. + "11:11:abcdef:0:0:0:0:0"}, + {"::", // Unspecified. + "::"}, + {"::1", // Local host. + "::1"}, + {"Instance::Set", // Ignore match, no PII. + "Instance::Set"}, + {"Instant::ff", // Ignore match, no PII. + "Instant::ff"}, + {"net::ERR_CONN_TIMEOUT", // Ignore match, no PII. + "net::ERR_CONN_TIMEOUT"}, + {"ff01::1", // All nodes address (interface local). + "ff01::1"}, + {"ff01::2", // All routers (interface local). + "ff01::2"}, + {"ff01::3", // Multicast (interface local). + "<ff01::/16: 13>"}, + {"ff02::1", // All nodes address (link local). + "ff02::1"}, + {"ff02::2", // All routers (link local). + "ff02::2"}, + {"ff02::3", // Multicast (link local). + "<ff02::/16: 16>"}, + {"ff02::fb", // mDNSv6 (link local). + "<ff02::/16: 17>"}, + {"ff08::fb", // mDNSv6. + "<IPv6: 18>"}, + {"ff0f::101", // All NTP servers. + "<IPv6: 19>"}, + {"::ffff:cb0c:10ea", // IPv4-mapped IPV6 (IP address). + "<IPv6: 20>"}, + {"::ffff:a0a:a0a", // IPv4-mapped IPV6 (private class A). + "<M 10.0.0.0/8: 21>"}, + {"::ffff:a0a:a0a", // Intentional duplicate. + "<M 10.0.0.0/8: 21>"}, + {"::ffff:ac1e:1e1e", // IPv4-mapped IPV6 (private class B). + "<M 172.16.0.0/12: 22>"}, + {"::ffff:c0a8:640a", // IPv4-mapped IPV6 (private class C). + "<M 192.168.0.0/16: 23>"}, + {"::ffff:6473:5c01", // IPv4-mapped IPV6 (Chrome). + "<M 100.115.92.1: 24>"}, + {"64:ff9b::a0a:a0a", // IPv4-translated 6to4 IPV6 (private class A). + "<T 10.0.0.0/8: 25>"}, + {"64:ff9b::6473:5c01", // IPv4-translated 6to4 IPV6 (Chrome). + "<T 100.115.92.1: 26>"}, + {"::0101:ffff:c0a8:640a", // IP address. + "<IPv6: 27>"}, + {"aa:aa:aa:aa:aa:aa", // MAC address (BSSID). + "aa:aa:aa:00:00:01"}, + {"chrome://resources/foo", // Secure chrome resource, whitelisted. + "chrome://resources/foo"}, + {"chrome://resources/f?user=bar", // Potentially PII in parameter. + "<URL: 2>"}}; + std::string anon_input; + std::string anon_output; + for (const auto& s : data) { + anon_input.append(s.first).append("\n"); + anon_output.append(s.second).append("\n"); + } + EXPECT_EQ(anon_output, anonymizer_.Anonymize(anon_input)); } } // namespace feedback
diff --git a/components/gwp_asan/BUILD.gn b/components/gwp_asan/BUILD.gn index 5176c8c..3359d70e 100644 --- a/components/gwp_asan/BUILD.gn +++ b/components/gwp_asan/BUILD.gn
@@ -7,7 +7,7 @@ deps = [ "//components/gwp_asan/common:unit_tests", ] - if (is_win || is_mac) { + if (is_win || is_mac || is_linux) { deps += [ "//components/gwp_asan/client:unit_tests", "//components/gwp_asan/crash_handler:unit_tests",
diff --git a/components/gwp_asan/client/sampling_malloc_shims_unittest.cc b/components/gwp_asan/client/sampling_malloc_shims_unittest.cc index a42f7a4..d7b6660 100644 --- a/components/gwp_asan/client/sampling_malloc_shims_unittest.cc +++ b/components/gwp_asan/client/sampling_malloc_shims_unittest.cc
@@ -41,8 +41,6 @@ static size_t GetAllocatedSize(void* mem) { return malloc_usable_size(mem); } -#else -#error "Needs to be implemented for platform." #endif namespace gwp_asan {
diff --git a/components/image_fetcher/core/cache/image_cache.cc b/components/image_fetcher/core/cache/image_cache.cc index 6a60788..52103c0 100644 --- a/components/image_fetcher/core/cache/image_cache.cc +++ b/components/image_fetcher/core/cache/image_cache.cc
@@ -71,7 +71,9 @@ ImageCache::~ImageCache() = default; -void ImageCache::SaveImage(std::string url, std::string image_data) { +void ImageCache::SaveImage(std::string url, + std::string image_data, + bool needs_transcoding) { // If the image data is larger than the cache's max size, bail out. if (image_data.length() > kCacheMaxSize) { return; @@ -79,7 +81,7 @@ base::OnceClosure request = base::BindOnce(&ImageCache::SaveImageImpl, weak_ptr_factory_.GetWeakPtr(), - url, std::move(image_data)); + url, std::move(image_data), needs_transcoding); QueueOrStartRequest(std::move(request)); } @@ -149,23 +151,45 @@ weak_ptr_factory_.GetWeakPtr())); } -void ImageCache::SaveImageImpl(const std::string& url, std::string image_data) { +void ImageCache::SaveImageImpl(const std::string& url, + std::string image_data, + bool needs_transcoding) { std::string key = ImageCache::HashUrlToKey(url); // If the cache is full, evict some stuff. RunEvictionWhenFull(); size_t length = image_data.length(); - data_store_->SaveImage(key, std::move(image_data)); - metadata_store_->SaveImageMetadata(key, length); + data_store_->SaveImage(key, std::move(image_data), needs_transcoding); + metadata_store_->SaveImageMetadata(key, length, needs_transcoding); } void ImageCache::LoadImageImpl(bool read_only, const std::string& url, ImageDataCallback callback) { std::string key = ImageCache::HashUrlToKey(url); + metadata_store_->LoadImageMetadata( + key, base::BindOnce(&ImageCache::OnImageMetadataLoadedForLoadImage, + weak_ptr_factory_.GetWeakPtr(), read_only, key, + std::move(callback), base::TimeTicks::Now())); +} - data_store_->LoadImage(key, std::move(callback)); +void ImageCache::OnImageMetadataLoadedForLoadImage( + bool read_only, + const std::string& key, + ImageDataCallback callback, + base::TimeTicks start_time, + base::Optional<CachedImageMetadataProto> metadata) { + // Record time spent to load metadata. + ImageFetcherMetricsReporter::ReportLoadImageMetadata(start_time); + + if (!metadata.has_value()) { + std::move(callback).Run(/* needs_transcoding */ false, ""); + return; + } + + data_store_->LoadImage(key, metadata->needs_transcoding(), + std::move(callback)); if (!read_only) { metadata_store_->UpdateImageMetadata(key); }
diff --git a/components/image_fetcher/core/cache/image_cache.h b/components/image_fetcher/core/cache/image_cache.h index f6e4017..2f06ad6 100644 --- a/components/image_fetcher/core/cache/image_cache.h +++ b/components/image_fetcher/core/cache/image_cache.h
@@ -11,7 +11,9 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "base/optional.h" #include "components/image_fetcher/core/cache/image_store_types.h" +#include "components/image_fetcher/core/cache/proto/cached_image_metadata.pb.h" class PrefRegistrySimple; class PrefService; @@ -42,7 +44,9 @@ // Adds or updates the image data for the |url|. If the class hasn't been // initialized yet, the call is queued. - void SaveImage(std::string url, std::string image_data); + void SaveImage(std::string url, + std::string image_data, + bool needs_transcoding); // Loads the image data for the |url| and passes it to |callback|. If there's // no image in the cache, then an empty string is returned. If |read_only| @@ -67,11 +71,21 @@ void OnDependencyInitialized(); // Saves the |image_data| for |url|. - void SaveImageImpl(const std::string& url, std::string image_data); + void SaveImageImpl(const std::string& url, + std::string image_data, + bool needs_transcoding); // Loads the data for |url|, calls the user back before updating metadata. void LoadImageImpl(bool read_only, const std::string& url, ImageDataCallback callback); + // Loads the image metadata for the given |url|, used to inspect if there's + // data available on disk that's in need of transcoding. + void OnImageMetadataLoadedForLoadImage( + bool read_only, + const std::string& key, + ImageDataCallback callback, + base::TimeTicks start_time, + base::Optional<CachedImageMetadataProto> metadata); // Deletes the data for |url|. void DeleteImageImpl(const std::string& url);
diff --git a/components/image_fetcher/core/cache/image_cache_unittest.cc b/components/image_fetcher/core/cache/image_cache_unittest.cc index b4349d4..19347e2 100644 --- a/components/image_fetcher/core/cache/image_cache_unittest.cc +++ b/components/image_fetcher/core/cache/image_cache_unittest.cc
@@ -72,11 +72,11 @@ ASSERT_TRUE(metadata_store()->IsInitialized()); } - void PrepareImageCache() { + void PrepareImageCache(bool needs_transcoding) { CreateImageCache(); InitializeImageCache(); - image_cache()->SaveImage(kImageUrl, kImageData); + image_cache()->SaveImage(kImageUrl, kImageData, needs_transcoding); RunUntilIdle(); ASSERT_TRUE(IsMetadataPresent(kImageUrlHashed)); @@ -139,12 +139,12 @@ RunUntilIdle(); } - void InjectMetadata(std::string key, int data_size) { - metadata_store_->SaveImageMetadata(key, data_size); + void InjectMetadata(std::string key, int data_size, bool needs_transcoding) { + metadata_store_->SaveImageMetadata(key, data_size, needs_transcoding); } - void InjectData(std::string key, std::string data) { - data_store_->SaveImage(key, data); + void InjectData(std::string key, std::string data, bool needs_transcoding) { + data_store_->SaveImage(key, data, needs_transcoding); RunUntilIdle(); } @@ -158,7 +158,7 @@ FakeDB<CachedImageMetadataProto>* db() { return db_; } base::HistogramTester& histogram_tester() { return histogram_tester_; } - MOCK_METHOD1(DataCallback, void(std::string)); + MOCK_METHOD2(DataCallback, void(bool, std::string)); private: scoped_refptr<ImageCache> image_cache_; @@ -186,24 +186,27 @@ CreateImageCache(); InitializeImageCache(); - image_cache()->SaveImage(kImageUrl, kImageData); + image_cache()->SaveImage(kImageUrl, kImageData, + /* needs_transcoding */ false); RunUntilIdle(); - EXPECT_CALL(*this, DataCallback(kImageData)); + EXPECT_CALL(*this, DataCallback(false, kImageData)); image_cache()->LoadImage( false, kImageUrl, base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback, base::Unretained(this))); + db()->LoadCallback(true); RunUntilIdle(); image_cache()->DeleteImage(kImageUrl); RunUntilIdle(); - EXPECT_CALL(*this, DataCallback(std::string())); + EXPECT_CALL(*this, DataCallback(false, std::string())); image_cache()->LoadImage( false, kImageUrl, base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback, base::Unretained(this))); + db()->LoadCallback(true); RunUntilIdle(); } @@ -211,7 +214,8 @@ CreateImageCache(); ASSERT_FALSE(IsCacheInitialized()); - image_cache()->SaveImage(kImageUrl, kImageData); + image_cache()->SaveImage(kImageUrl, kImageData, + /* needs_transcoding */ false); db()->InitStatusCallback(leveldb_proto::Enums::InitStatus::kOK); RunUntilIdle(); @@ -222,27 +226,29 @@ CreateImageCache(); InitializeImageCache(); - image_cache()->SaveImage(kImageUrl, kImageData); - RunUntilIdle(); + image_cache()->SaveImage(kImageUrl, kImageData, + /* needs_transcoding */ false); - EXPECT_CALL(*this, DataCallback(kImageData)); + EXPECT_CALL(*this, DataCallback(false, kImageData)); image_cache()->LoadImage( false, kImageUrl, base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback, base::Unretained(this))); + db()->LoadCallback(true); RunUntilIdle(); } TEST_F(CachedImageFetcherImageCacheTest, Load) { - PrepareImageCache(); + PrepareImageCache(false); auto metadata_before = GetMetadata(kImageUrlHashed); clock()->SetNow(clock()->Now() + base::TimeDelta::FromHours(1)); - EXPECT_CALL(*this, DataCallback(kImageData)); + EXPECT_CALL(*this, DataCallback(false, kImageData)); image_cache()->LoadImage( false, kImageUrl, base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback, base::Unretained(this))); + db()->LoadCallback(true); RunUntilIdle(); db()->LoadCallback(true); db()->UpdateCallback(true); @@ -253,15 +259,16 @@ } TEST_F(CachedImageFetcherImageCacheTest, LoadReadOnly) { - PrepareImageCache(); + PrepareImageCache(false); auto metadata_before = GetMetadata(kImageUrlHashed); clock()->SetNow(clock()->Now() + base::TimeDelta::FromHours(1)); - EXPECT_CALL(*this, DataCallback(kImageData)); + EXPECT_CALL(*this, DataCallback(false, kImageData)); image_cache()->LoadImage( true, kImageUrl, base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback, base::Unretained(this))); + db()->LoadCallback(true); RunUntilIdle(); auto metadata_after = GetMetadata(kImageUrlHashed); @@ -269,38 +276,41 @@ } TEST_F(CachedImageFetcherImageCacheTest, Delete) { - PrepareImageCache(); + PrepareImageCache(false); - EXPECT_CALL(*this, DataCallback(kImageData)); + EXPECT_CALL(*this, DataCallback(false, kImageData)); image_cache()->LoadImage( false, kImageUrl, base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback, base::Unretained(this))); + db()->LoadCallback(true); RunUntilIdle(); image_cache()->DeleteImage(kImageUrl); RunUntilIdle(); - EXPECT_CALL(*this, DataCallback(std::string())); + EXPECT_CALL(*this, DataCallback(false, std::string())); image_cache()->LoadImage( false, kImageUrl, base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback, base::Unretained(this))); + db()->LoadCallback(true); RunUntilIdle(); } TEST_F(CachedImageFetcherImageCacheTest, Eviction) { - PrepareImageCache(); + PrepareImageCache(false); clock()->SetNow(clock()->Now() + base::TimeDelta::FromDays(7)); RunEvictionOnStartup(/* success */ true); ASSERT_EQ(clock()->Now(), prefs()->GetTime(kPrefLastStartupEviction)); - EXPECT_CALL(*this, DataCallback(std::string())); + EXPECT_CALL(*this, DataCallback(false, std::string())); image_cache()->LoadImage( false, kImageUrl, base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback, base::Unretained(this))); + db()->LoadCallback(true); RunUntilIdle(); histogram_tester().ExpectBucketCount( @@ -312,47 +322,50 @@ } TEST_F(CachedImageFetcherImageCacheTest, EvictionWhenFull) { - PrepareImageCache(); - InjectMetadata(kImageUrl, kOverMaxCacheSize); + PrepareImageCache(false); + InjectMetadata(kImageUrl, kOverMaxCacheSize, /* needs_transcoding */ false); clock()->SetNow(clock()->Now() + base::TimeDelta::FromDays(6)); RunEvictionWhenFull(/* success */ true); // The data should be removed because it's over the allowed limit. - EXPECT_CALL(*this, DataCallback("")); + EXPECT_CALL(*this, DataCallback(false, "")); image_cache()->LoadImage( false, kImageUrl, base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback, base::Unretained(this))); + db()->LoadCallback(true); RunUntilIdle(); } TEST_F(CachedImageFetcherImageCacheTest, EvictionTooSoon) { - PrepareImageCache(); + PrepareImageCache(false); clock()->SetNow(clock()->Now() + base::TimeDelta::FromDays(6)); RunEvictionOnStartup(/* success */ true); - EXPECT_CALL(*this, DataCallback(kImageData)); + EXPECT_CALL(*this, DataCallback(false, kImageData)); image_cache()->LoadImage( false, kImageUrl, base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback, base::Unretained(this))); + db()->LoadCallback(true); RunUntilIdle(); } TEST_F(CachedImageFetcherImageCacheTest, EvictionWhenEvictionAlreadyPerformed) { - PrepareImageCache(); + PrepareImageCache(false); prefs()->SetTime("cached_image_fetcher_last_startup_eviction_time", clock()->Now()); clock()->SetNow(clock()->Now() + base::TimeDelta::FromHours(23)); RunEvictionOnStartup(/* success */ false); - EXPECT_CALL(*this, DataCallback(kImageData)); + EXPECT_CALL(*this, DataCallback(false, kImageData)); image_cache()->LoadImage( false, kImageUrl, base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback, base::Unretained(this))); + db()->LoadCallback(true); RunUntilIdle(); } @@ -361,16 +374,17 @@ InitializeImageCache(); // Inject differing keys so they mismatch, then run reconciliation. - InjectData("foo", "z"); - InjectMetadata("bar", 10); + InjectData("foo", "z", /* needs_transcoding */ false); + InjectMetadata("bar", 10, /* needs_transcoding */ false); RunReconciliation(); // Data should be gone. - EXPECT_CALL(*this, DataCallback(std::string())); + EXPECT_CALL(*this, DataCallback(false, std::string())); image_cache()->LoadImage( false, "foo", base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback, base::Unretained(this))); + db()->LoadCallback(true); RunUntilIdle(); // Metadata should be gone. @@ -382,17 +396,18 @@ InitializeImageCache(); // Inject differing keys so they mismatch, then run reconciliation. - InjectData("foo", "z"); - InjectData("bar", "z"); - InjectMetadata("foo", 10); + InjectData("foo", "z", /* needs_transcoding */ false); + InjectData("bar", "z", /* needs_transcoding */ false); + InjectMetadata("foo", 10, /* needs_transcoding */ false); RunReconciliation(); // Data should be gone. - EXPECT_CALL(*this, DataCallback(std::string())); + EXPECT_CALL(*this, DataCallback(false, std::string())); image_cache()->LoadImage( false, "bar", base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback, base::Unretained(this))); + db()->LoadCallback(true); RunUntilIdle(); } @@ -401,9 +416,9 @@ InitializeImageCache(); // Inject differing keys so they mismatch, then run reconciliation. - InjectData("foo", "z"); - InjectMetadata("foo", 10); - InjectMetadata("bar", 10); + InjectData("foo", "z", /* needs_transcoding */ false); + InjectMetadata("foo", 10, /* needs_transcoding */ false); + InjectMetadata("bar", 10, /* needs_transcoding */ false); RunReconciliation(); // Metadata should be gone.
diff --git a/components/image_fetcher/core/cache/image_data_store.h b/components/image_fetcher/core/cache/image_data_store.h index 9ad58c28..f27ee0c8 100644 --- a/components/image_fetcher/core/cache/image_data_store.h +++ b/components/image_fetcher/core/cache/image_data_store.h
@@ -27,11 +27,14 @@ virtual bool IsInitialized() = 0; // Adds or updates the image data for the |key|. - virtual void SaveImage(const std::string& key, std::string image_data) = 0; + virtual void SaveImage(const std::string& key, + std::string image_data, + bool needs_transcoding) = 0; // Loads the image data for the |key| and passes it to |callback|. If the // image isn't available, empty data will be returned. virtual void LoadImage(const std::string& key, + bool needs_transcoding, ImageDataCallback callback) = 0; // Deletes the image data for the |key|.
diff --git a/components/image_fetcher/core/cache/image_data_store_disk.cc b/components/image_fetcher/core/cache/image_data_store_disk.cc index 04909f0..43acd5a 100644 --- a/components/image_fetcher/core/cache/image_data_store_disk.cc +++ b/components/image_fetcher/core/cache/image_data_store_disk.cc
@@ -25,6 +25,9 @@ namespace { +// The prefix of the file names for images that need transcoding before use. +constexpr char kNeedsTranscodingPrefix[] = "ntr_"; + const FilePath::CharType kPathPostfix[] = FILE_PATH_LITERAL("image_data_storage"); @@ -40,19 +43,39 @@ return InitializationStatus::INIT_FAILURE; } +base::FilePath BuildFilePath(const FilePath& storage_path, + const std::string& key, + bool needs_transcoding) { + if (needs_transcoding) + return storage_path.AppendASCII(kNeedsTranscodingPrefix + key); + return storage_path.AppendASCII(key); +} + void SaveImageImpl(FilePath storage_path, const std::string& key, - std::string data) { - FilePath file_path = storage_path.AppendASCII(key); + std::string data, + bool needs_transcoding) { + FilePath file_path = BuildFilePath(storage_path, key, needs_transcoding); int len = base::WriteFile(file_path, data.c_str(), data.length()); if (len == -1 || (size_t)len != data.length()) { DVLOG(1) << "WriteFile failed."; } + + if (!needs_transcoding) { + // Attempt to delete the image data there that needs transcoding. + bool success = base::DeleteFile( + BuildFilePath(storage_path, key, /* needs_transcoding */ true), false); + if (!success) { + DVLOG(1) << "Deleting the transcoded file failed."; + } + } } -std::string LoadImageImpl(FilePath storage_path, const std::string& key) { - FilePath file_path = storage_path.AppendASCII(key); +std::string LoadImageImpl(FilePath storage_path, + const std::string& key, + bool needs_transcoding) { + FilePath file_path = BuildFilePath(storage_path, key, needs_transcoding); if (!base::PathExists(file_path)) { return ""; @@ -64,10 +87,19 @@ } void DeleteImageImpl(FilePath storage_path, const std::string& key) { - FilePath file_path = storage_path.AppendASCII(key); - + FilePath file_path = + BuildFilePath(storage_path, key, /* needs_transcoding */ false); bool success = base::DeleteFile(file_path, false); - if (!success) { + if (success) { + // We don't know if this image came from network or from an untranscoded + // file. Instead of checking, we can simply blindly delete the untranscoded + // file. + if (!base::DeleteFile( + BuildFilePath(storage_path, key, /* needs_transcoding */ true), + false)) { + DVLOG(1) << "Attempting to delete " << kNeedsTranscodingPrefix << "."; + } + } else { DVLOG(1) << "DeleteFile failed."; } } @@ -111,25 +143,31 @@ } void ImageDataStoreDisk::SaveImage(const std::string& key, - std::string image_data) { + std::string image_data, + bool needs_transcoding) { if (!IsInitialized()) { return; } - task_runner_->PostTask(FROM_HERE, base::BindOnce(SaveImageImpl, storage_path_, - key, std::move(image_data))); + task_runner_->PostTask( + FROM_HERE, base::BindOnce(SaveImageImpl, storage_path_, key, + std::move(image_data), needs_transcoding)); } void ImageDataStoreDisk::LoadImage(const std::string& key, + bool needs_transcoding, ImageDataCallback callback) { if (!IsInitialized()) { - std::move(callback).Run(std::string()); + std::move(callback).Run(/* needs_transcoding */ false, std::string()); return; } base::PostTaskAndReplyWithResult( task_runner_.get(), FROM_HERE, - base::BindOnce(LoadImageImpl, storage_path_, key), std::move(callback)); + base::BindOnce(LoadImageImpl, storage_path_, key, needs_transcoding), + base::BindOnce(&ImageDataStoreDisk::OnImageLoaded, + weak_ptr_factory_.GetWeakPtr(), needs_transcoding, + std::move(callback))); } void ImageDataStoreDisk::DeleteImage(const std::string& key) { @@ -159,4 +197,10 @@ std::move(callback).Run(); } +void ImageDataStoreDisk::OnImageLoaded(bool needs_transcoding, + ImageDataCallback callback, + std::string data) { + std::move(callback).Run(needs_transcoding, std::move(data)); +} + } // namespace image_fetcher
diff --git a/components/image_fetcher/core/cache/image_data_store_disk.h b/components/image_fetcher/core/cache/image_data_store_disk.h index 0e6a69e..ca8293b 100644 --- a/components/image_fetcher/core/cache/image_data_store_disk.h +++ b/components/image_fetcher/core/cache/image_data_store_disk.h
@@ -31,8 +31,12 @@ // ImageDataStorage: void Initialize(base::OnceClosure callback) override; bool IsInitialized() override; - void SaveImage(const std::string& key, std::string data) override; - void LoadImage(const std::string& key, ImageDataCallback callback) override; + void SaveImage(const std::string& key, + std::string data, + bool needs_transcoding) override; + void LoadImage(const std::string& key, + bool needs_transcoding, + ImageDataCallback callback) override; void DeleteImage(const std::string& key) override; void GetAllKeys(KeysCallback callback) override; @@ -41,6 +45,11 @@ void OnInitializationComplete(base::OnceClosure callback, InitializationStatus initialization_status); + // Called when data is loaded from disk. + void OnImageLoaded(bool needs_transcoding, + ImageDataCallback callback, + std::string data); + // Set to be INITIALIZED if a directory exists, or can be created under // |storage_path|. If initialization fails, there's no need to retry. InitializationStatus initialization_status_;
diff --git a/components/image_fetcher/core/cache/image_data_store_disk_unittest.cc b/components/image_fetcher/core/cache/image_data_store_disk_unittest.cc index cd18e10..fecf8bb1 100644 --- a/components/image_fetcher/core/cache/image_data_store_disk_unittest.cc +++ b/components/image_fetcher/core/cache/image_data_store_disk_unittest.cc
@@ -45,31 +45,33 @@ RunUntilIdle(); } - void PrepareDataStore(bool initialize) { + void PrepareDataStore(bool initialize, bool setup_for_needs_transcoding) { CreateDataStore(); InitializeDataStore(); - SaveData(kImageKey); + SaveData(kImageKey, setup_for_needs_transcoding); if (!initialize) { CreateDataStore(); } } - void AssertDataPresent(const std::string& key) { - AssertDataPresent(key, kImageData); + void AssertDataPresent(const std::string& key, bool needs_transcoding) { + AssertDataPresent(key, kImageData, needs_transcoding); } - void AssertDataPresent(const std::string& key, const std::string& data) { - EXPECT_CALL(*this, DataCallback(data)); + void AssertDataPresent(const std::string& key, + const std::string& data, + bool needs_transcoding) { + EXPECT_CALL(*this, DataCallback(needs_transcoding, data)); data_store()->LoadImage( - key, + key, needs_transcoding, base::BindOnce(&CachedImageFetcherImageDataStoreDiskTest::DataCallback, base::Unretained(this))); RunUntilIdle(); } - void SaveData(const std::string& key) { - data_store()->SaveImage(key, kImageData); + void SaveData(const std::string& key, bool needs_transcoding) { + data_store()->SaveImage(key, kImageData, needs_transcoding); RunUntilIdle(); } @@ -82,7 +84,7 @@ ImageDataStore* data_store() { return data_store_.get(); } MOCK_METHOD0(OnInitialized, void()); - MOCK_METHOD1(DataCallback, void(std::string)); + MOCK_METHOD2(DataCallback, void(bool, std::string)); MOCK_METHOD1(KeysCallback, void(std::vector<std::string>)); private: @@ -99,11 +101,11 @@ CreateDataStore(); InitializeDataStore(); - SaveData(kImageKey); - AssertDataPresent(kImageKey); + SaveData(kImageKey, /* needs_transcoding */ false); + AssertDataPresent(kImageKey, /* needs_transcoding */ false); DeleteData(kImageKey); - AssertDataPresent(kImageKey, ""); + AssertDataPresent(kImageKey, "", /* needs_transcoding */ false); } TEST_F(CachedImageFetcherImageDataStoreDiskTest, Init) { @@ -115,47 +117,50 @@ } TEST_F(CachedImageFetcherImageDataStoreDiskTest, InitWithExistingDirectory) { - PrepareDataStore(/* initialize */ true); + PrepareDataStore(/* initialize */ true, /* needs_transcoding */ false); // Recreating the data store shouldn't wipe the directory. CreateDataStore(); InitializeDataStore(); - AssertDataPresent(kImageKey); + AssertDataPresent(kImageKey, /* needs_transcoding */ false); } TEST_F(CachedImageFetcherImageDataStoreDiskTest, SaveBeforeInit) { - PrepareDataStore(/* initialize */ false); + PrepareDataStore(/* initialize */ false, /* needs_transcoding */ false); // No data should be present (empty string). - AssertDataPresent(kImageKey, ""); + AssertDataPresent(kImageKey, "", /* needs_transcoding */ false); } TEST_F(CachedImageFetcherImageDataStoreDiskTest, Save) { - PrepareDataStore(/* initialize */ true); - AssertDataPresent(kImageKey); + PrepareDataStore(/* initialize */ true, /* needs_transcoding */ false); + AssertDataPresent(kImageKey, /* needs_transcoding */ false); + + PrepareDataStore(/* initialize */ true, /* needs_transcoding */ true); + AssertDataPresent(kImageKey, /* needs_transcoding */ true); } TEST_F(CachedImageFetcherImageDataStoreDiskTest, DeleteBeforeInit) { - PrepareDataStore(/* initialize */ false); + PrepareDataStore(/* initialize */ false, /* needs_transcoding */ false); DeleteData(kImageKey); InitializeDataStore(); // Delete should have failed, data still there. - AssertDataPresent(kImageKey); + AssertDataPresent(kImageKey, /* needs_transcoding */ false); } TEST_F(CachedImageFetcherImageDataStoreDiskTest, Delete) { - PrepareDataStore(/* initialize */ true); + PrepareDataStore(/* initialize */ true, /* needs_transcoding */ false); DeleteData(kImageKey); // Should be empty string (not present). - AssertDataPresent(kImageKey, ""); + AssertDataPresent(kImageKey, "", /* needs_transcoding */ false); } TEST_F(CachedImageFetcherImageDataStoreDiskTest, GetAllKeysBeforeInit) { - PrepareDataStore(/* initialize */ false); + PrepareDataStore(/* initialize */ false, /* needs_transcoding */ false); // Should return empty vector even though there is a file present. EXPECT_CALL(*this, KeysCallback(std::vector<std::string>())); @@ -166,7 +171,7 @@ } TEST_F(CachedImageFetcherImageDataStoreDiskTest, GetAllKeys) { - PrepareDataStore(/* initialize */ true); + PrepareDataStore(/* initialize */ true, /* needs_transcoding */ false); // Should return empty vector even though there is a file present. EXPECT_CALL(*this, KeysCallback(std::vector<std::string>({kImageKey}))); @@ -181,10 +186,11 @@ CreateDataStore(); InitializeDataStore(); - SaveData(kImageKey); - EXPECT_CALL(*this, DataCallback(kImageData)); + SaveData(kImageKey, /* needs_transcoding */ false); + EXPECT_CALL(*this, DataCallback(false, kImageData)); data_store()->LoadImage( kImageKey, + /* needs_transcoding */ false, base::BindOnce(&CachedImageFetcherImageDataStoreDiskTest::DataCallback, base::Unretained(this))); DeleteData(kImageKey);
diff --git a/components/image_fetcher/core/cache/image_metadata_store.h b/components/image_fetcher/core/cache/image_metadata_store.h index b14d381..3f9d88e9 100644 --- a/components/image_fetcher/core/cache/image_metadata_store.h +++ b/components/image_fetcher/core/cache/image_metadata_store.h
@@ -27,9 +27,16 @@ // While this is false, initialization may have already started. virtual bool IsInitialized() = 0; - // Adds or updates the image metadata for the |key|. + // Loads the image metadata for the |key|. + virtual void LoadImageMetadata(const std::string& key, + ImageMetadataCallback) = 0; + + // Adds or updates the image metadata for the |key|. If metadata exists for an + // image and the |needs_transcoding| is still true, we don't need to update + // the existing metadata. virtual void SaveImageMetadata(const std::string& key, - const size_t data_size) = 0; + const size_t data_size, + bool needs_transcoding) = 0; // Deletes the image metadata for the |key|. virtual void DeleteImageMetadata(const std::string& key) = 0;
diff --git a/components/image_fetcher/core/cache/image_metadata_store_leveldb.cc b/components/image_fetcher/core/cache/image_metadata_store_leveldb.cc index 11a669b..32bfa3a 100644 --- a/components/image_fetcher/core/cache/image_metadata_store_leveldb.cc +++ b/components/image_fetcher/core/cache/image_metadata_store_leveldb.cc
@@ -98,8 +98,21 @@ initialization_status_ == InitializationStatus::INIT_FAILURE; } +void ImageMetadataStoreLevelDB::LoadImageMetadata( + const std::string& key, + ImageMetadataCallback callback) { + DCHECK(IsInitialized()); + + database_->LoadEntriesWithFilter( + base::BindRepeating(&KeyMatcherFilter, key), CreateReadOptions(), + /* target_prefix */ "", + base::BindOnce(&ImageMetadataStoreLevelDB::LoadImageMetadataImpl, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); +} + void ImageMetadataStoreLevelDB::SaveImageMetadata(const std::string& key, - const size_t data_size) { + const size_t data_size, + bool needs_transcoding) { // If the database is not initialized yet, ignore the request. if (!IsInitialized()) { return; @@ -112,6 +125,7 @@ metadata_proto.set_data_size(data_size); metadata_proto.set_creation_time(current_time); metadata_proto.set_last_used_time(current_time); + metadata_proto.set_needs_transcoding(needs_transcoding); auto entries_to_save = std::make_unique<MetadataKeyEntryVector>(); entries_to_save->emplace_back(key, metadata_proto); @@ -188,6 +202,19 @@ std::move(callback).Run(); } +void ImageMetadataStoreLevelDB::LoadImageMetadataImpl( + ImageMetadataCallback callback, + bool success, + std::unique_ptr<std::vector<CachedImageMetadataProto>> entries) { + if (!success || entries->size() == 0) { + std::move(callback).Run(CachedImageMetadataProto()); + return; + } + + DCHECK(entries->size() == 1); + std::move(callback).Run(std::move(entries->at(0))); +} + void ImageMetadataStoreLevelDB::OnImageUpdated(bool success) { DVLOG_IF(1, !success) << "ImageMetadataStoreLevelDB update failed."; }
diff --git a/components/image_fetcher/core/cache/image_metadata_store_leveldb.h b/components/image_fetcher/core/cache/image_metadata_store_leveldb.h index e5189a8d..a08d422 100644 --- a/components/image_fetcher/core/cache/image_metadata_store_leveldb.h +++ b/components/image_fetcher/core/cache/image_metadata_store_leveldb.h
@@ -49,8 +49,11 @@ // ImageMetadataStorage: void Initialize(base::OnceClosure callback) override; bool IsInitialized() override; + void LoadImageMetadata(const std::string& key, + ImageMetadataCallback callback) override; void SaveImageMetadata(const std::string& key, - const size_t data_size) override; + const size_t data_size, + bool needs_transcoding) override; void DeleteImageMetadata(const std::string& key) override; void UpdateImageMetadata(const std::string& key) override; void GetAllKeys(KeysCallback callback) override; @@ -68,6 +71,10 @@ private: void OnDatabaseInitialized(base::OnceClosure callback, leveldb_proto::Enums::InitStatus status); + void LoadImageMetadataImpl( + ImageMetadataCallback callback, + bool success, + std::unique_ptr<std::vector<CachedImageMetadataProto>> entries); void OnImageUpdated(bool success); void UpdateImageMetadataImpl( bool success,
diff --git a/components/image_fetcher/core/cache/image_metadata_store_leveldb_unittest.cc b/components/image_fetcher/core/cache/image_metadata_store_leveldb_unittest.cc index 52d68dfeb..402bb75c 100644 --- a/components/image_fetcher/core/cache/image_metadata_store_leveldb_unittest.cc +++ b/components/image_fetcher/core/cache/image_metadata_store_leveldb_unittest.cc
@@ -64,7 +64,8 @@ void PrepareDatabase(bool initialize) { CreateDatabase(); InitializeDatabase(); - metadata_store()->SaveImageMetadata(kImageKey, kImageDataLength); + metadata_store()->SaveImageMetadata(kImageKey, kImageDataLength, + /* needs_transcoding */ false); ASSERT_TRUE(IsDataPresent(kImageKey)); if (!initialize) { @@ -103,7 +104,8 @@ void AssertDataPresent(const std::string& key, int64_t data_size, base::Time creation_time, - base::Time last_used_time) { + base::Time last_used_time, + bool needs_transcoding) { if (!IsDataPresent(key)) { ASSERT_TRUE(false); } @@ -114,6 +116,7 @@ creation_time.since_origin().InMicroseconds()); ASSERT_EQ(entry.last_used_time(), last_used_time.since_origin().InMicroseconds()); + ASSERT_EQ(entry.needs_transcoding(), needs_transcoding); } void RunUntilIdle() { scoped_task_environment_.RunUntilIdle(); } @@ -124,6 +127,8 @@ MOCK_METHOD0(OnInitialized, void()); MOCK_METHOD1(OnKeysReturned, void(std::vector<std::string>)); MOCK_METHOD1(OnStoreOperationComplete, void(bool)); + MOCK_METHOD1(OnImageMetadataLoaded, + void(base::Optional<CachedImageMetadataProto>)); private: std::unique_ptr<base::SimpleTestClock> clock_; @@ -148,7 +153,8 @@ CreateDatabase(); EXPECT_FALSE(metadata_store()->IsInitialized()); // Start an image load before the database is initialized. - metadata_store()->SaveImageMetadata(kImageKey, kImageDataLength); + metadata_store()->SaveImageMetadata(kImageKey, kImageDataLength, + /* needs_transcoding */ false); InitializeDatabase(); EXPECT_TRUE(metadata_store()->IsInitialized()); @@ -160,9 +166,14 @@ CreateDatabase(); InitializeDatabase(); - metadata_store()->SaveImageMetadata(kImageKey, kImageDataLength); - AssertDataPresent(kImageKey, kImageDataLength, clock()->Now(), - clock()->Now()); + metadata_store()->SaveImageMetadata(kImageKey, kImageDataLength, + /* needs_transcoding */ false); + AssertDataPresent(kImageKey, kImageDataLength, clock()->Now(), clock()->Now(), + /* needs_transcoding */ false); + metadata_store()->SaveImageMetadata(kImageKey, kImageDataLength, + /* needs_transcoding */ true); + AssertDataPresent(kImageKey, kImageDataLength, clock()->Now(), clock()->Now(), + /* needs_transcoding */ true); } TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest, DeleteBeforeInit) { @@ -177,7 +188,8 @@ // Put some data in the database to start. CreateDatabase(); InitializeDatabase(); - metadata_store()->SaveImageMetadata(kImageKey, kImageDataLength); + metadata_store()->SaveImageMetadata(kImageKey, kImageDataLength, + /* needs_transcoding */ false); ASSERT_TRUE(IsDataPresent(kImageKey)); // Delete the data. @@ -191,7 +203,8 @@ // Put some data in the database to start. CreateDatabase(); InitializeDatabase(); - metadata_store()->SaveImageMetadata(kImageKey, kImageDataLength); + metadata_store()->SaveImageMetadata(kImageKey, kImageDataLength, + /* needs_transcoding */ false); ASSERT_TRUE(IsDataPresent(kImageKey)); // Delete the data. @@ -210,8 +223,8 @@ RunUntilIdle(); InitializeDatabase(); - AssertDataPresent(kImageKey, kImageDataLength, clock()->Now(), - clock()->Now()); + AssertDataPresent(kImageKey, kImageDataLength, clock()->Now(), clock()->Now(), + /* needs_transcoding */ false); } TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest, UpdateImageMetadata) { @@ -225,7 +238,7 @@ AssertDataPresent(kImageKey, kImageDataLength, clock()->Now() - base::TimeDelta::FromHours(1), - clock()->Now()); + clock()->Now(), /* needs_transcoding */ false); } TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest, @@ -237,8 +250,8 @@ db()->UpdateCallback(true); RunUntilIdle(); - AssertDataPresent(kImageKey, kImageDataLength, clock()->Now(), - clock()->Now()); + AssertDataPresent(kImageKey, kImageDataLength, clock()->Now(), clock()->Now(), + /* needs_transcoding */ false); } TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest, @@ -249,8 +262,8 @@ db()->LoadCallback(true); RunUntilIdle(); - AssertDataPresent(kImageKey, kImageDataLength, clock()->Now(), - clock()->Now()); + AssertDataPresent(kImageKey, kImageDataLength, clock()->Now(), clock()->Now(), + /* needs_transcoding */ false); } TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest, GetAllKeysBeforeInit) { @@ -266,7 +279,8 @@ TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest, GetAllKeys) { PrepareDatabase(true); - metadata_store()->SaveImageMetadata(kOtherImageKey, kImageDataLength); + metadata_store()->SaveImageMetadata(kOtherImageKey, kImageDataLength, + /* needs_transcoding */ false); // A GC call before the db is initialized should be ignore. EXPECT_CALL( @@ -280,7 +294,8 @@ TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest, GetAllKeysLoadFailed) { PrepareDatabase(true); - metadata_store()->SaveImageMetadata(kOtherImageKey, kImageDataLength); + metadata_store()->SaveImageMetadata(kOtherImageKey, kImageDataLength, + /* needs_transcoding */ false); // A GC call before the db is initialized should be ignore. EXPECT_CALL(*this, OnKeysReturned(std::vector<std::string>({}))); @@ -350,7 +365,8 @@ // Insert an item one our later. clock()->SetNow(clock()->Now() + base::TimeDelta::FromHours(1)); - metadata_store()->SaveImageMetadata(kOtherImageKey, kImageDataLength); + metadata_store()->SaveImageMetadata(kOtherImageKey, kImageDataLength, + /* needs_transcoding */ false); clock()->SetNow(clock()->Now() - base::TimeDelta::FromHours(1)); ASSERT_TRUE(IsDataPresent(kOtherImageKey)); @@ -416,7 +432,21 @@ base::Unretained(this))); db()->LoadCallback(true); db()->UpdateCallback(false); - // Update failed only simlulates the callback, not the actual data behavior. + // Update failed only simulates the callback, not the actual data behavior. +} + +TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest, LoadImageMetadata) { + PrepareDatabase(true); + metadata_store()->SaveImageMetadata(kOtherImageKey, kImageDataLength, + /* needs_transcoding */ true); + + EXPECT_CALL(*this, OnImageMetadataLoaded(_)); + metadata_store()->LoadImageMetadata( + kOtherImageKey, + base::BindOnce(&CachedImageFetcherImageMetadataStoreLevelDBTest:: + OnImageMetadataLoaded, + base::Unretained(this))); + db()->LoadCallback(true); } } // namespace image_fetcher
diff --git a/components/image_fetcher/core/cache/image_store_types.h b/components/image_fetcher/core/cache/image_store_types.h index fa64ae8..66737a51 100644 --- a/components/image_fetcher/core/cache/image_store_types.h +++ b/components/image_fetcher/core/cache/image_store_types.h
@@ -9,6 +9,8 @@ #include <vector> #include "base/callback.h" +#include "base/optional.h" +#include "components/image_fetcher/core/cache/proto/cached_image_metadata.pb.h" namespace image_fetcher { @@ -20,12 +22,19 @@ }; // Returns the resulting raw image data as a std::string. Data will be returned -// using move semantics. -using ImageDataCallback = base::OnceCallback<void(std::string)>; +// using move semantics. If |needs_transcoding| is true, this data must be +// decoded in a sandbox process. +using ImageDataCallback = + base::OnceCallback<void(bool needs_transcoding, std::string)>; // Returns bool success when the underlying storage completes an operation. using ImageStoreOperationCallback = base::OnceCallback<void(bool)>; +// CachedImageMetadataProto will be returned if image metadata is loaded +// successfully. +using ImageMetadataCallback = + base::OnceCallback<void(base::Optional<CachedImageMetadataProto>)>; + // Returns a vector of keys. using KeysCallback = base::OnceCallback<void(std::vector<std::string>)>;
diff --git a/components/image_fetcher/core/cache/proto/cached_image_metadata.proto b/components/image_fetcher/core/cache/proto/cached_image_metadata.proto index 901adf3..407050c 100644 --- a/components/image_fetcher/core/cache/proto/cached_image_metadata.proto +++ b/components/image_fetcher/core/cache/proto/cached_image_metadata.proto
@@ -23,4 +23,7 @@ // certain amount of space has been freed. Is not used to decide the order in // which images are evicted. optional int64 data_size = 4; + + // True if the image data needs transcoding before it can be trusted. + optional bool needs_transcoding = 5; }
diff --git a/components/image_fetcher/core/cached_image_fetcher.cc b/components/image_fetcher/core/cached_image_fetcher.cc index b07e41f..04bd8dd4 100644 --- a/components/image_fetcher/core/cached_image_fetcher.cc +++ b/components/image_fetcher/core/cached_image_fetcher.cc
@@ -127,6 +127,7 @@ CachedImageFetcherRequest request, ImageDataFetcherCallback image_data_callback, ImageFetcherCallback image_callback, + bool cache_result_needs_transcoding, std::string image_data) { if (image_data.empty()) { ImageFetcherMetricsReporter::ReportEvent(request.params.uma_client_name(), @@ -142,14 +143,16 @@ ImageFetcherMetricsReporter::ReportEvent(request.params.uma_client_name(), ImageFetcherEvent::kCacheHit); - // Only continue with decoding if the user actually asked for an image. - if (!image_callback.is_null()) { + // Only continue with decoding if the user actually asked for an image, or + // the image hasn't been transcoded yet. + if (!image_callback.is_null() || cache_result_needs_transcoding) { GetImageDecoder()->DecodeImage( image_data, gfx::Size(), base::BindOnce(&CachedImageFetcher::OnImageDecodedFromCache, weak_ptr_factory_.GetWeakPtr(), std::move(request), std::move(image_data_callback), - std::move(image_callback))); + std::move(image_callback), + cache_result_needs_transcoding)); } } } @@ -158,6 +161,7 @@ CachedImageFetcherRequest request, ImageDataFetcherCallback image_data_callback, ImageFetcherCallback image_callback, + bool cache_result_needs_transcoding, const gfx::Image& image) { if (image.IsEmpty()) { // Upon failure, fetch from the network. @@ -173,6 +177,16 @@ ImageCallbackIfPresent(std::move(image_callback), image, RequestMetadata()); ImageFetcherMetricsReporter::ReportImageLoadFromCacheTime( request.params.uma_client_name(), request.start_time); + + // If cache_result_needs_transcoding is true, then this should be stored + // again to replace the image data already on disk with the transcoded data. + if (cache_result_needs_transcoding) { + EncodeAndStoreData(/* cache_result_needs_transcoding */ true, + std::move(request), image); + ImageFetcherMetricsReporter::ReportEvent( + request.params.uma_client_name(), + ImageFetcherEvent::kImageQueuedForTranscodingDecoded); + } } } @@ -200,7 +214,7 @@ bool skip_transcoding = request.params.skip_transcoding(); if (skip_transcoding) { wrapper_data_callback = - base::BindOnce(&CachedImageFetcher::StoreImageDataWithoutTranscoding, + base::BindOnce(&CachedImageFetcher::OnImageFetchedWithoutTranscoding, weak_ptr_factory_.GetWeakPtr(), std::move(request), std::move(image_data_callback)); } else { @@ -211,7 +225,7 @@ // 3. Cache the result. wrapper_data_callback = std::move(image_data_callback); wrapper_image_callback = - base::BindOnce(&CachedImageFetcher::StoreImageDataWithTranscoding, + base::BindOnce(&CachedImageFetcher::OnImageFetchedForTranscoding, weak_ptr_factory_.GetWeakPtr(), std::move(request), std::move(image_callback)); } @@ -220,7 +234,7 @@ std::move(request.params)); } -void CachedImageFetcher::StoreImageDataWithoutTranscoding( +void CachedImageFetcher::OnImageFetchedWithoutTranscoding( CachedImageFetcherRequest request, ImageDataFetcherCallback image_data_callback, const std::string& image_data, @@ -233,10 +247,11 @@ ImageFetcherEvent::kTotalFailure); } - StoreData(std::move(request), image_data); + StoreData(/* cache_result_needs_transcoding */ false, std::move(request), + image_data); } -void CachedImageFetcher::StoreImageDataWithTranscoding( +void CachedImageFetcher::OnImageFetchedForTranscoding( CachedImageFetcherRequest request, ImageFetcherCallback image_callback, const gfx::Image& image, @@ -252,13 +267,21 @@ request.params.uma_client_name(), request.start_time); } + EncodeAndStoreData(/* cache_result_needs_transcoding */ false, + std::move(request), image); +} + +void CachedImageFetcher::EncodeAndStoreData(bool cache_result_needs_transcoding, + CachedImageFetcherRequest request, + const gfx::Image& image) { // Copy the image data out and store it on disk. const SkBitmap* bitmap = image.IsEmpty() ? nullptr : image.ToSkBitmap(); // If the bitmap is null or otherwise not ready, skip encoding. if (bitmap == nullptr || bitmap->isNull() || !bitmap->readyToDraw()) { ImageFetcherMetricsReporter::ReportEvent(request.params.uma_client_name(), ImageFetcherEvent::kTotalFailure); - StoreData(std::move(request), ""); + + image_cache_->DeleteImage(request.url.spec()); } else { std::string uma_client_name = request.params.uma_client_name(); // Post a task to another thread to encode the image data downloaded. @@ -266,11 +289,13 @@ FROM_HERE, base::BindOnce(&EncodeSkBitmapToPNG, uma_client_name, *bitmap), base::BindOnce(&CachedImageFetcher::StoreData, - weak_ptr_factory_.GetWeakPtr(), std::move(request))); + weak_ptr_factory_.GetWeakPtr(), + cache_result_needs_transcoding, std::move(request))); } } -void CachedImageFetcher::StoreData(CachedImageFetcherRequest request, +void CachedImageFetcher::StoreData(bool cache_result_needs_transcoding, + CachedImageFetcherRequest request, std::string image_data) { std::string url = request.url.spec(); // If the image is empty, delete the image. @@ -280,7 +305,14 @@ } if (!read_only_) { - image_cache_->SaveImage(std::move(url), std::move(image_data)); + if (cache_result_needs_transcoding) { + ImageFetcherMetricsReporter::ReportEvent( + request.params.uma_client_name(), + ImageFetcherEvent::kImageQueuedForTranscodingStoredBack); + } + + image_cache_->SaveImage(std::move(url), std::move(image_data), + /* needs_transcoding */ false); } }
diff --git a/components/image_fetcher/core/cached_image_fetcher.h b/components/image_fetcher/core/cached_image_fetcher.h index df911d12..c273b9df 100644 --- a/components/image_fetcher/core/cached_image_fetcher.h +++ b/components/image_fetcher/core/cached_image_fetcher.h
@@ -46,16 +46,16 @@ private: // Cache - void OnImageFetchedFromCache( - CachedImageFetcherRequest request, - ImageDataFetcherCallback image_data_callback, - ImageFetcherCallback image_callback, - std::string image_data); - void OnImageDecodedFromCache( - CachedImageFetcherRequest request, - ImageDataFetcherCallback image_data_callback, - ImageFetcherCallback image_callback, - const gfx::Image& image); + void OnImageFetchedFromCache(CachedImageFetcherRequest request, + ImageDataFetcherCallback image_data_callback, + ImageFetcherCallback image_callback, + bool cache_result_needs_transcoding, + std::string image_data); + void OnImageDecodedFromCache(CachedImageFetcherRequest request, + ImageDataFetcherCallback image_data_callback, + ImageFetcherCallback image_callback, + bool cache_result_needs_transcoding, + const gfx::Image& image); // Network void EnqueueFetchImageFromNetwork( @@ -66,16 +66,25 @@ CachedImageFetcherRequest request, ImageDataFetcherCallback image_data_callback, ImageFetcherCallback image_callback); - void StoreImageDataWithoutTranscoding( + void OnImageFetchedWithoutTranscoding( CachedImageFetcherRequest request, ImageDataFetcherCallback image_data_callback, const std::string& image_data, const RequestMetadata& request_metadata); - void StoreImageDataWithTranscoding(CachedImageFetcherRequest request, - ImageFetcherCallback image_data_callback, - const gfx::Image& image, - const RequestMetadata& request_metadata); - void StoreData(CachedImageFetcherRequest request, std::string image_data); + void OnImageFetchedForTranscoding(CachedImageFetcherRequest request, + ImageFetcherCallback image_data_callback, + const gfx::Image& image, + const RequestMetadata& request_metadata); + // Encode the given |image_data| and store it. + // |cache_result_needs_transcoding| is passed along for metrics purposes. + void EncodeAndStoreData(bool cache_result_needs_transcoding, + CachedImageFetcherRequest request, + const gfx::Image& image); + // Store the given |image_data| in the cache. |cache_result_needs_transcoding| + // is passed along for metrics purposes. + void StoreData(bool cache_result_needs_transcoding, + CachedImageFetcherRequest request, + std::string image_data); // Owned by ImageFetcherService. ImageFetcher* image_fetcher_;
diff --git a/components/image_fetcher/core/cached_image_fetcher_unittest.cc b/components/image_fetcher/core/cached_image_fetcher_unittest.cc index b1fb203..a6f6448 100644 --- a/components/image_fetcher/core/cached_image_fetcher_unittest.cc +++ b/components/image_fetcher/core/cached_image_fetcher_unittest.cc
@@ -92,7 +92,8 @@ base::SequencedTaskRunnerHandle::Get()); // Use an initial request to start the cache up. - image_cache_->SaveImage(kImageUrl.spec(), kImageData); + image_cache_->SaveImage(kImageUrl.spec(), kImageData, + /* needs_transcoding */ false); RunUntilIdle(); db_->InitStatusCallback(leveldb_proto::Enums::InitStatus::kOK); image_cache_->DeleteImage(kImageUrl.spec()); @@ -124,8 +125,9 @@ return &test_url_loader_factory_; } base::HistogramTester& histogram_tester() { return histogram_tester_; } + FakeDB<CachedImageMetadataProto>* db() { return db_; } - MOCK_METHOD1(OnImageLoaded, void(std::string)); + MOCK_METHOD2(OnImageLoaded, void(bool, std::string)); private: std::unique_ptr<ImageFetcher> image_fetcher_; @@ -163,7 +165,8 @@ // that they both can use what's inside. TEST_F(CachedImageFetcherTest, FetchImageFromCache) { // Save the image in the database. - image_cache()->SaveImage(kImageUrl.spec(), kImageData); + image_cache()->SaveImage(kImageUrl.spec(), kImageData, + /* needs_transcoding */ false); RunUntilIdle(); base::MockCallback<ImageDataFetcherCallback> data_callback; @@ -174,7 +177,7 @@ cached_image_fetcher()->FetchImageAndData( kImageUrl, data_callback.Get(), image_callback.Get(), ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kUmaClientName)); - + db()->LoadCallback(true); RunUntilIdle(); histogram_tester().ExpectTotalCount(kCacheLoadHistogramName, 1); @@ -184,10 +187,36 @@ ImageFetcherEvent::kCacheHit, 1); } +TEST_F(CachedImageFetcherTest, FetchImageFromCacheNeedsTranscoding) { + // Save the image in the database. + image_cache()->SaveImage(kImageUrl.spec(), kImageData, + /* needs_transcoding */ true); + RunUntilIdle(); + + base::MockCallback<ImageDataFetcherCallback> data_callback; + base::MockCallback<ImageFetcherCallback> image_callback; + + EXPECT_CALL(data_callback, Run(kImageData, _)); + EXPECT_CALL(image_callback, Run(NonEmptyImage(), _)); + cached_image_fetcher()->FetchImageAndData( + kImageUrl, data_callback.Get(), image_callback.Get(), + ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kUmaClientName)); + db()->LoadCallback(true); + RunUntilIdle(); + + histogram_tester().ExpectBucketCount( + kImageFetcherEventHistogramName, + ImageFetcherEvent::kImageQueuedForTranscodingDecoded, 1); + histogram_tester().ExpectBucketCount( + kImageFetcherEventHistogramName, + ImageFetcherEvent::kImageQueuedForTranscodingStoredBack, 1); +} + TEST_F(CachedImageFetcherTest, FetchImageFromCacheReadOnly) { CreateCachedImageFetcher(/* read_only */ true); // Save the image in the database. - image_cache()->SaveImage(kImageUrl.spec(), kImageData); + image_cache()->SaveImage(kImageUrl.spec(), kImageData, + /* needs_transcoding */ false); test_url_loader_factory()->AddResponse(kImageUrl.spec(), kImageData); RunUntilIdle(); { @@ -200,6 +229,7 @@ cached_image_fetcher()->FetchImageAndData( kImageUrl, data_callback.Get(), image_callback.Get(), ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kUmaClientName)); + db()->LoadCallback(true); RunUntilIdle(); histogram_tester().ExpectBucketCount(kImageFetcherEventHistogramName, @@ -219,6 +249,7 @@ cached_image_fetcher()->FetchImageAndData( kImageUrl, data_callback.Get(), image_callback.Get(), ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kUmaClientName)); + db()->LoadCallback(true); RunUntilIdle(); } } @@ -236,7 +267,7 @@ cached_image_fetcher()->FetchImageAndData( kImageUrl, data_callback.Get(), image_callback.Get(), ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kUmaClientName)); - + db()->LoadCallback(true); RunUntilIdle(); histogram_tester().ExpectTotalCount(kNetworkLoadHistogramName, 1); @@ -247,11 +278,12 @@ } // Make sure the image data is in the database. { - EXPECT_CALL(*this, OnImageLoaded(NonEmptyString())); + EXPECT_CALL(*this, OnImageLoaded(false, NonEmptyString())); image_cache()->LoadImage( /* read_only */ false, kImageUrl.spec(), base::BindOnce(&CachedImageFetcherTest::OnImageLoaded, base::Unretained(this))); + db()->LoadCallback(true); RunUntilIdle(); } // Fetch again. The cache should be populated, no network request is needed. @@ -266,7 +298,7 @@ cached_image_fetcher()->FetchImageAndData( kImageUrl, data_callback.Get(), image_callback.Get(), ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kUmaClientName)); - + db()->LoadCallback(true); RunUntilIdle(); } } @@ -285,7 +317,7 @@ cached_image_fetcher()->FetchImageAndData( kImageUrl, data_callback.Get(), image_callback.Get(), ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kUmaClientName)); - + db()->LoadCallback(true); RunUntilIdle(); histogram_tester().ExpectTotalCount(kNetworkLoadHistogramName, 1); @@ -296,11 +328,12 @@ } // Make sure the image data is not in the database. { - EXPECT_CALL(*this, OnImageLoaded(std::string())); + EXPECT_CALL(*this, OnImageLoaded(false, std::string())); image_cache()->LoadImage( /* read_only */ false, kImageUrl.spec(), base::BindOnce(&CachedImageFetcherTest::OnImageLoaded, base::Unretained(this))); + db()->LoadCallback(true); RunUntilIdle(); } } @@ -317,7 +350,7 @@ params.set_skip_transcoding_for_testing(true); cached_image_fetcher()->FetchImageAndData(kImageUrl, data_callback.Get(), ImageFetcherCallback(), params); - + db()->LoadCallback(true); RunUntilIdle(); } { @@ -327,14 +360,15 @@ cached_image_fetcher()->FetchImageAndData( kImageUrl, data_callback.Get(), ImageFetcherCallback(), ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kUmaClientName)); - + db()->LoadCallback(true); RunUntilIdle(); } } TEST_F(CachedImageFetcherTest, FetchImageWithSkipDiskCache) { // Save the image in the database. - image_cache()->SaveImage(kImageUrl.spec(), kImageDataOther); + image_cache()->SaveImage(kImageUrl.spec(), kImageDataOther, + /* needs_transcoding */ false); RunUntilIdle(); test_url_loader_factory()->AddResponse(kImageUrl.spec(), kImageData);
diff --git a/components/image_fetcher/core/image_fetcher_metrics_reporter.cc b/components/image_fetcher/core/image_fetcher_metrics_reporter.cc index b2a4a4a7..9779f5b1 100644 --- a/components/image_fetcher/core/image_fetcher_metrics_reporter.cc +++ b/components/image_fetcher/core/image_fetcher_metrics_reporter.cc
@@ -29,6 +29,7 @@ "CachedImageFetcher.ImageLoadFromNetworkTime"; constexpr char kImageLoadFromNetworkAfterCacheHitHistogram[] = "CachedImageFetcher.ImageLoadFromNetworkAfterCacheHit"; +constexpr char kLoadImageMetadata[] = "CachedImageFetcher.LoadImageMetadata"; // Returns a raw pointer to a histogram which is owned base::HistogramBase* GetTimeHistogram(const std::string& histogram_name, @@ -118,4 +119,11 @@ time_delta); } +// static +void ImageFetcherMetricsReporter::ReportLoadImageMetadata( + base::TimeTicks start_time) { + base::TimeDelta time_delta = base::TimeTicks::Now() - start_time; + UMA_HISTOGRAM_TIMES(kLoadImageMetadata, time_delta); +} + } // namespace image_fetcher
diff --git a/components/image_fetcher/core/image_fetcher_metrics_reporter.h b/components/image_fetcher/core/image_fetcher_metrics_reporter.h index 45c08b8..f09432b 100644 --- a/components/image_fetcher/core/image_fetcher_metrics_reporter.h +++ b/components/image_fetcher/core/image_fetcher_metrics_reporter.h
@@ -27,7 +27,10 @@ kCacheStartupEvictionFinished = 7, kJavaInMemoryCacheHit = 8, kJavaDiskCacheHit = 9, - kMaxValue = kJavaDiskCacheHit, + kImageQueuedForTranscodingDecoded = 10, + kImageQueuedForTranscodingStoredBack = 11, + kLoadImageMetadata = 12, + kMaxValue = kLoadImageMetadata, }; class ImageFetcherMetricsReporter { @@ -63,6 +66,9 @@ // Report the time between cache evictions. static void ReportTimeSinceLastCacheLRUEviction(base::Time start_time); + + // Report the time it takes to load metadata. + static void ReportLoadImageMetadata(base::TimeTicks start_time); }; } // namespace image_fetcher
diff --git a/components/nacl/browser/nacl_process_host.cc b/components/nacl/browser/nacl_process_host.cc index 30dbc8c6..0fd53ebb 100644 --- a/components/nacl/browser/nacl_process_host.cc +++ b/components/nacl/browser/nacl_process_host.cc
@@ -17,7 +17,6 @@ #include "base/feature_list.h" #include "base/files/file_util.h" #include "base/location.h" -#include "base/metrics/field_trial.h" #include "base/metrics/histogram_macros.h" #include "base/path_service.h" #include "base/process/launch.h" @@ -540,12 +539,6 @@ if (NaClBrowser::GetDelegate()->DialogsAreSuppressed()) cmd_line->AppendSwitch(switches::kNoErrorDialogs); - // TODO(crbug.com/932175): Remove this after field trials no longer need to - // be consulted for the MojoChannelMac launch. - base::FieldTrialList::CopyFieldTrialStateToFlags( - switches::kFieldTrialHandle, switches::kEnableFeatures, - switches::kDisableFeatures, cmd_line.get()); - #if defined(OS_WIN) cmd_line->AppendArg(switches::kPrefetchArgumentOther); #endif // defined(OS_WIN)
diff --git a/components/nacl/common/nacl_service.cc b/components/nacl/common/nacl_service.cc index 4648333..0763a6c 100644 --- a/components/nacl/common/nacl_service.cc +++ b/components/nacl/common/nacl_service.cc
@@ -29,7 +29,6 @@ #if defined(OS_MACOSX) #include "base/mac/mach_port_rendezvous.h" -#include "mojo/public/cpp/platform/features.h" #endif namespace { @@ -39,22 +38,16 @@ #if defined(OS_WIN) endpoint = mojo::PlatformChannel::RecoverPassedEndpointFromCommandLine( *base::CommandLine::ForCurrentProcess()); -#else -#if defined(OS_MACOSX) - if (base::FeatureList::IsEnabled(mojo::features::kMojoChannelMac)) { - auto* client = base::MachPortRendezvousClient::GetInstance(); - if (client) { - endpoint = mojo::PlatformChannelEndpoint( - mojo::PlatformHandle(client->TakeReceiveRight('mojo'))); - } - } else { -#endif // defined(OS_MACOSX) - endpoint = mojo::PlatformChannelEndpoint(mojo::PlatformHandle( - base::ScopedFD(base::GlobalDescriptors::GetInstance()->Get( - service_manager::kMojoIPCChannel)))); -#if defined(OS_MACOSX) +#elif defined(OS_MACOSX) + auto* client = base::MachPortRendezvousClient::GetInstance(); + if (client) { + endpoint = mojo::PlatformChannelEndpoint( + mojo::PlatformHandle(client->TakeReceiveRight('mojo'))); } -#endif // defined(OS_MACOSX) +#else + endpoint = mojo::PlatformChannelEndpoint(mojo::PlatformHandle( + base::ScopedFD(base::GlobalDescriptors::GetInstance()->Get( + service_manager::kMojoIPCChannel)))); #endif // !defined(OS_WIN) DCHECK(endpoint.is_valid()); return mojo::IncomingInvitation::Accept(std::move(endpoint));
diff --git a/components/offline_pages/core/BUILD.gn b/components/offline_pages/core/BUILD.gn index 12ecaa4..36655d4 100644 --- a/components/offline_pages/core/BUILD.gn +++ b/components/offline_pages/core/BUILD.gn
@@ -56,7 +56,6 @@ "offline_clock.h", "offline_event_logger.cc", "offline_event_logger.h", - "offline_page_archive_publisher.cc", "offline_page_archive_publisher.h", "offline_page_archiver.cc", "offline_page_archiver.h", @@ -82,7 +81,6 @@ "page_criteria.h", "snapshot_controller.cc", "snapshot_controller.h", - "system_download_manager.h", "visuals_decoder.h", ] @@ -117,8 +115,6 @@ "offline_page_test_archiver.h", "stub_offline_page_model.cc", "stub_offline_page_model.h", - "stub_system_download_manager.cc", - "stub_system_download_manager.h", "test_scoped_offline_clock.cc", "test_scoped_offline_clock.h", ] @@ -177,7 +173,6 @@ "model/update_file_path_task_unittest.cc", "model/visuals_availability_task_unittest.cc", "offline_event_logger_unittest.cc", - "offline_page_archive_publisher_unittest.cc", "offline_page_feature_unittest.cc", "offline_page_item_utils_unittest.cc", "offline_page_metadata_store_unittest.cc",
diff --git a/components/offline_pages/core/model/offline_page_model_taskified.cc b/components/offline_pages/core/model/offline_page_model_taskified.cc index 7606e7da..871a40e 100644 --- a/components/offline_pages/core/model/offline_page_model_taskified.cc +++ b/components/offline_pages/core/model/offline_page_model_taskified.cc
@@ -35,7 +35,6 @@ #include "components/offline_pages/core/offline_page_metadata_store.h" #include "components/offline_pages/core/offline_page_model.h" #include "components/offline_pages/core/offline_store_utils.h" -#include "components/offline_pages/core/system_download_manager.h" #include "url/gurl.h" namespace offline_pages { @@ -172,12 +171,10 @@ OfflinePageModelTaskified::OfflinePageModelTaskified( std::unique_ptr<OfflinePageMetadataStore> store, std::unique_ptr<ArchiveManager> archive_manager, - std::unique_ptr<SystemDownloadManager> download_manager, std::unique_ptr<OfflinePageArchivePublisher> archive_publisher, const scoped_refptr<base::SequencedTaskRunner>& task_runner) : store_(std::move(store)), archive_manager_(std::move(archive_manager)), - download_manager_(std::move(download_manager)), archive_publisher_(std::move(archive_publisher)), policy_controller_(new ClientPolicyController()), task_queue_(this), @@ -587,9 +584,8 @@ // Remove the page from the system download manager. We don't need to wait for // completion before calling the delete page callback. task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&OfflinePageModelTaskified::RemoveFromDownloadManager, - download_manager_.get(), system_download_ids)); + FROM_HERE, base::BindOnce(&OfflinePageModelTaskified::Unpublish, + archive_publisher_.get(), system_download_ids)); if (!callback.is_null()) std::move(callback).Run(result); @@ -613,11 +609,11 @@ } } -void OfflinePageModelTaskified::RemoveFromDownloadManager( - SystemDownloadManager* download_manager, +void OfflinePageModelTaskified::Unpublish( + OfflinePageArchivePublisher* publisher, const std::vector<int64_t>& system_download_ids) { if (system_download_ids.size() > 0) - download_manager->Remove(system_download_ids); + publisher->UnpublishArchives(system_download_ids); } void OfflinePageModelTaskified::ScheduleMaintenanceTasks() { @@ -668,11 +664,9 @@ void OfflinePageModelTaskified::OnPersistentPageConsistencyCheckDone( bool success, const std::vector<int64_t>& pages_deleted) { - // If there's no persistent page expired, save some effort by exiting early. // TODO(https://crbug.com/834909): Use the temporary hidden bit in - // DownloadUIAdapter instead of calling remove directly. - if (pages_deleted.size() > 0) - download_manager_->Remove(pages_deleted); + // DownloadUIAdapter instead of removing directly. + Unpublish(archive_publisher_.get(), pages_deleted); } void OfflinePageModelTaskified::OnClearCachedPagesDone(
diff --git a/components/offline_pages/core/model/offline_page_model_taskified.h b/components/offline_pages/core/model/offline_page_model_taskified.h index f064418..026a9d23 100644 --- a/components/offline_pages/core/model/offline_page_model_taskified.h +++ b/components/offline_pages/core/model/offline_page_model_taskified.h
@@ -17,6 +17,7 @@ #include "base/observer_list.h" #include "components/keyed_service/core/keyed_service.h" #include "components/offline_pages/core/model/clear_storage_task.h" +#include "components/offline_pages/core/offline_page_archive_publisher.h" #include "components/offline_pages/core/offline_page_archiver.h" #include "components/offline_pages/core/offline_page_model.h" #include "components/offline_pages/core/offline_page_model_event_logger.h" @@ -39,10 +40,8 @@ class ArchiveManager; class ClientPolicyController; -class OfflinePageArchivePublisher; class OfflinePageArchiver; class OfflinePageMetadataStore; -class SystemDownloadManager; // Implementaion of OfflinePageModel, which is a service for saving pages // offline. It's an entry point to get information about Offline Pages and the @@ -66,7 +65,6 @@ OfflinePageModelTaskified( std::unique_ptr<OfflinePageMetadataStore> store, std::unique_ptr<ArchiveManager> archive_manager, - std::unique_ptr<SystemDownloadManager> download_manager, std::unique_ptr<OfflinePageArchivePublisher> archive_publisher, const scoped_refptr<base::SequencedTaskRunner>& task_runner); ~OfflinePageModelTaskified() override; @@ -185,10 +183,9 @@ const OfflinePageItem& offline_page, PublishArchiveResult publish_results); - // Method for unpublishing the page from the system download manager. - static void RemoveFromDownloadManager( - SystemDownloadManager* download_manager, - const std::vector<int64_t>& system_download_ids); + // Method for unpublishing the page from downloads. + static void Unpublish(OfflinePageArchivePublisher* publisher, + const std::vector<int64_t>& system_download_ids); // Other utility methods. void RemovePagesMatchingUrlAndNamespace(const OfflinePageItem& page); @@ -200,9 +197,6 @@ // Manager for the offline archive files and directory. std::unique_ptr<ArchiveManager> archive_manager_; - // Manages interaction with the OS download manager, if present. - std::unique_ptr<SystemDownloadManager> download_manager_; - // Used for moving archives into public storage. std::unique_ptr<OfflinePageArchivePublisher> archive_publisher_;
diff --git a/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc b/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc index c799d59..d57291a 100644 --- a/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc +++ b/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc
@@ -34,7 +34,6 @@ #include "components/offline_pages/core/offline_page_test_archiver.h" #include "components/offline_pages/core/offline_page_types.h" #include "components/offline_pages/core/offline_store_utils.h" -#include "components/offline_pages/core/stub_system_download_manager.h" #include "components/offline_pages/core/test_scoped_offline_clock.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -141,8 +140,9 @@ ArchiverResult result); void CheckTaskQueueIdle(); - void SetArchivePublisher( - std::unique_ptr<OfflinePageArchivePublisher> publisher) { + void SetTestArchivePublisher( + std::unique_ptr<OfflinePageTestArchivePublisher> publisher) { + publisher_ = publisher.get(); model()->archive_publisher_ = std::move(publisher); } @@ -156,9 +156,6 @@ } ArchiveManager* archive_manager() { return archive_manager_; } - StubSystemDownloadManager* download_manager_stub() { - return download_manager_stub_; - } OfflinePageItemGenerator* page_generator() { return &generator_; } TaskQueue* task_queue() { return &model_->task_queue_; } base::HistogramTester* histogram_tester() { return histogram_tester_.get(); } @@ -182,16 +179,17 @@ base::Time last_maintenance_tasks_schedule_time() { return model_->last_maintenance_tasks_schedule_time_; } + OfflinePageTestArchivePublisher* publisher() { return publisher_; } private: scoped_refptr<base::TestMockTimeTaskRunner> task_runner_; base::ThreadTaskRunnerHandle task_runner_handle_; std::unique_ptr<OfflinePageModelTaskified> model_; OfflinePageMetadataStoreTestUtil store_test_util_; - StubSystemDownloadManager* download_manager_stub_; ArchiveManager* archive_manager_; OfflinePageItemGenerator generator_; std::unique_ptr<base::HistogramTester> histogram_tester_; + OfflinePageTestArchivePublisher* publisher_; base::ScopedTempDir temporary_dir_; base::ScopedTempDir private_archive_dir_; base::ScopedTempDir public_archive_dir_; @@ -257,17 +255,14 @@ temporary_dir_path(), private_archive_dir_path(), public_archive_dir_path(), base::ThreadTaskRunnerHandle::Get()); archive_manager_ = archive_manager.get(); - auto download_manager = - std::make_unique<StubSystemDownloadManager>(kDownloadId, true); - download_manager_stub_ = download_manager.get(); auto publisher = std::make_unique<OfflinePageTestArchivePublisher>( - archive_manager.get(), download_manager.get()); + archive_manager.get(), kDownloadId); + publisher_ = publisher.get(); model_ = std::make_unique<OfflinePageModelTaskified>( store_test_util()->ReleaseStore(), std::move(archive_manager), - std::move(download_manager), std::move(publisher), - base::ThreadTaskRunnerHandle::Get()); + std::move(publisher), base::ThreadTaskRunnerHandle::Get()); model_->AddObserver(this); histogram_tester_ = std::make_unique<base::HistogramTester>(); ResetResults(); @@ -887,8 +882,7 @@ EXPECT_EQ(last_deleted_page().offline_id, page1.offline_id); EXPECT_EQ(1UL, test_utils::GetFileCountInDirectory(temporary_dir_path())); EXPECT_EQ(1LL, store_test_util()->GetPageCount()); - EXPECT_EQ(page1.system_download_id, - download_manager_stub()->last_removed_id()); + EXPECT_EQ(page1.system_download_id, publisher()->last_removed_id()); histogram_tester()->ExpectUniqueSample( "OfflinePages.DeletePageCount", static_cast<int>( @@ -1171,10 +1165,10 @@ // Expect that PublishArchive is called and force returning FILE_MOVE_FAILED. auto publisher = std::make_unique<OfflinePageTestArchivePublisher>( - archive_manager(), download_manager_stub()); + archive_manager(), kDownloadId); publisher->expect_publish_archive_called(true); publisher->set_archive_attempt_failure(true); - SetArchivePublisher(std::move(publisher)); + SetTestArchivePublisher(std::move(publisher)); SavePageWithFileMoveFailure(kTestUrl, kTestUserRequestedClientId, GURL(), kEmptyRequestOrigin, std::move(archiver)); @@ -1499,8 +1493,7 @@ EXPECT_EQ(0UL, test_utils::GetFileCountInDirectory(public_archive_dir_path())); EXPECT_EQ(1LL, store_test_util()->GetPageCount()); - EXPECT_EQ(page.system_download_id, - download_manager_stub()->last_removed_id()); + EXPECT_EQ(page.system_download_id, publisher()->last_removed_id()); histogram_tester()->ExpectTotalCount( "OfflinePages.ConsistencyCheck.Persistent.Result", 3); }
diff --git a/components/offline_pages/core/offline_page_archive_publisher.cc b/components/offline_pages/core/offline_page_archive_publisher.cc deleted file mode 100644 index e616869..0000000 --- a/components/offline_pages/core/offline_page_archive_publisher.cc +++ /dev/null
@@ -1,107 +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 "components/offline_pages/core/offline_page_archive_publisher.h" - -#include <errno.h> -#include <utility> - -#include "base/bind.h" -#include "base/files/file_util.h" -#include "base/sequenced_task_runner.h" -#include "base/strings/utf_string_conversions.h" -#include "base/task_runner_util.h" -#include "components/offline_pages/core/archive_manager.h" -#include "components/offline_pages/core/model/offline_page_model_utils.h" -#include "components/offline_pages/core/offline_store_utils.h" -#include "components/offline_pages/core/system_download_manager.h" - -namespace offline_pages { - -namespace { - -using offline_pages::SavePageResult; - -// Helper function to do the move and register synchronously. Make sure this is -// called from a background thread. -PublishArchiveResult MoveAndRegisterArchive( - const offline_pages::OfflinePageItem& offline_page, - const base::FilePath& publish_directory, - offline_pages::SystemDownloadManager* download_manager) { - PublishArchiveResult archive_result; - // Calculate the new file name. - base::FilePath new_file_path = - offline_pages::model_utils::GenerateUniqueFilenameForOfflinePage( - offline_page.title, offline_page.url, publish_directory); - - // Create the destination directory if it does not already exist. - if (!publish_directory.empty() && !base::DirectoryExists(publish_directory)) { - base::File::Error file_error; - base::CreateDirectoryAndGetError(publish_directory, &file_error); - } - - // Move the file. - bool moved = base::Move(offline_page.file_path, new_file_path); - if (!moved) { - archive_result.move_result = SavePageResult::FILE_MOVE_FAILED; - DVPLOG(0) << "OfflinePage publishing file move failure " << __func__; - - if (!base::PathExists(offline_page.file_path)) { - DVLOG(0) << "Can't copy from non-existent path, from " - << offline_page.file_path << " " << __func__; - } - if (!base::PathExists(publish_directory)) { - DVLOG(0) << "Target directory does not exist, " << publish_directory - << " " << __func__; - } - return archive_result; - } - - // Tell the download manager about our file, get back an id. - if (!download_manager->IsDownloadManagerInstalled()) { - archive_result.move_result = SavePageResult::ADD_TO_DOWNLOAD_MANAGER_FAILED; - return archive_result; - } - - // TODO(petewil): Handle empty page title. - std::string page_title = base::UTF16ToUTF8(offline_page.title); - // We use the title for a description, since the add to the download manager - // fails without a description, and we don't have anything better to use. - int64_t download_id = download_manager->AddCompletedDownload( - page_title, page_title, - offline_pages::store_utils::ToDatabaseFilePath(new_file_path), - offline_page.file_size, offline_page.url.spec(), std::string()); - if (download_id == 0LL) { - archive_result.move_result = SavePageResult::ADD_TO_DOWNLOAD_MANAGER_FAILED; - return archive_result; - } - - // Put results into the result object. - archive_result.move_result = SavePageResult::SUCCESS; - archive_result.new_file_path = new_file_path; - archive_result.download_id = download_id; - - return archive_result; -} - -} // namespace - -OfflinePageArchivePublisher::OfflinePageArchivePublisher( - ArchiveManager* archive_manager, - SystemDownloadManager* download_manager) - : archive_manager_(archive_manager), download_manager_(download_manager) {} - -void OfflinePageArchivePublisher::PublishArchive( - const OfflinePageItem& offline_page, - const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, - PublishArchiveDoneCallback publish_done_callback) const { - base::PostTaskAndReplyWithResult( - background_task_runner.get(), FROM_HERE, - base::BindOnce(&MoveAndRegisterArchive, offline_page, - archive_manager_->GetPublicArchivesDir(), - download_manager_), - base::BindOnce(std::move(publish_done_callback), offline_page)); -} - -} // namespace offline_pages
diff --git a/components/offline_pages/core/offline_page_archive_publisher.h b/components/offline_pages/core/offline_page_archive_publisher.h index 76c31fd1..364f2aa 100644 --- a/components/offline_pages/core/offline_page_archive_publisher.h +++ b/components/offline_pages/core/offline_page_archive_publisher.h
@@ -10,7 +10,6 @@ #include "base/callback.h" #include "base/files/file_path.h" -#include "base/strings/string16.h" #include "components/offline_pages/core/offline_page_item.h" #include "components/offline_pages/core/offline_page_types.h" @@ -20,9 +19,6 @@ namespace offline_pages { -class ArchiveManager; -class SystemDownloadManager; - // The result of publishing an offline page to Downloads. struct PublishArchiveResult { SavePageResult move_result; @@ -38,23 +34,18 @@ base::OnceCallback<void(const OfflinePageItem& /* offline_page */, PublishArchiveResult /* archive_result */)>; - OfflinePageArchivePublisher(ArchiveManager* archive_manager, - SystemDownloadManager* download_manager); virtual ~OfflinePageArchivePublisher() {} // Publishes the page on a background thread, then returns to the // OfflinePageModelTaskified's done callback. - // - // A default implementation publishing the file via SystemDownloadManager is - // provided but embedders may implement it themselves. virtual void PublishArchive( const OfflinePageItem& offline_page, const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, - PublishArchiveDoneCallback publish_done_callback) const; + PublishArchiveDoneCallback publish_done_callback) const = 0; - protected: - ArchiveManager* archive_manager_; - SystemDownloadManager* download_manager_; + // Removes the archives identified by |download_manager_ids| from downloads. + virtual void UnpublishArchives( + const std::vector<int64_t>& download_manager_ids) const = 0; }; } // namespace offline_pages
diff --git a/components/offline_pages/core/offline_page_archive_publisher_unittest.cc b/components/offline_pages/core/offline_page_archive_publisher_unittest.cc deleted file mode 100644 index 3b20141..0000000 --- a/components/offline_pages/core/offline_page_archive_publisher_unittest.cc +++ /dev/null
@@ -1,129 +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 "components/offline_pages/core/offline_page_archive_publisher.h" - -#include "base/bind.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/files/scoped_temp_dir.h" -#include "base/memory/weak_ptr.h" -#include "base/sequenced_task_runner.h" -#include "base/test/test_simple_task_runner.h" -#include "base/threading/thread_task_runner_handle.h" -#include "components/offline_pages/core/archive_manager.h" -#include "components/offline_pages/core/model/offline_page_item_generator.h" -#include "components/offline_pages/core/stub_system_download_manager.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace { -const int64_t kDownloadId = 42LL; -} // namespace - -namespace offline_pages { - -class OfflinePageArchivePublisherTest - : public testing::Test, - public base::SupportsWeakPtr<OfflinePageArchivePublisherTest> { - public: - OfflinePageArchivePublisherTest() - : task_runner_(new base::TestSimpleTaskRunner), - task_runner_handle_(task_runner_), - weak_ptr_factory_(this) {} - ~OfflinePageArchivePublisherTest() override {} - - SavePageCallback save_page_callback; - - void SetUp() override; - void PumpLoop(); - - OfflinePageItemGenerator* page_generator() { return &page_generator_; } - - const base::FilePath& temporary_dir_path() { - return temporary_dir_.GetPath(); - } - const base::FilePath& private_archive_dir_path() { - return private_archive_dir_.GetPath(); - } - const base::FilePath& public_archive_dir_path() { - return public_archive_dir_.GetPath(); - } - const PublishArchiveResult& publish_archive_result() { - return publish_archive_result_; - } - scoped_refptr<base::SequencedTaskRunner> task_runner() { - return task_runner_; - } - base::WeakPtr<OfflinePageArchivePublisherTest> get_weak_ptr() { - return weak_ptr_factory_.GetWeakPtr(); - } - - void PublishArchiveDone(SavePageCallback save_page_callback, - const OfflinePageItem& offline_page, - PublishArchiveResult archive_result); - - private: - base::ScopedTempDir temporary_dir_; - base::ScopedTempDir private_archive_dir_; - base::ScopedTempDir public_archive_dir_; - OfflinePageItemGenerator page_generator_; - PublishArchiveResult publish_archive_result_; - scoped_refptr<base::TestSimpleTaskRunner> task_runner_; - base::ThreadTaskRunnerHandle task_runner_handle_; - base::WeakPtrFactory<OfflinePageArchivePublisherTest> weak_ptr_factory_; -}; - -void OfflinePageArchivePublisherTest::SetUp() { - ASSERT_TRUE(temporary_dir_.CreateUniqueTempDir()); - ASSERT_TRUE(private_archive_dir_.CreateUniqueTempDir()); - ASSERT_TRUE(public_archive_dir_.CreateUniqueTempDir()); -} - -void OfflinePageArchivePublisherTest::PublishArchiveDone( - SavePageCallback save_page_callback, - const OfflinePageItem& offline_page, - PublishArchiveResult archive_result) { - publish_archive_result_ = archive_result; -} - -void OfflinePageArchivePublisherTest::PumpLoop() { - task_runner_->RunUntilIdle(); -} - -TEST_F(OfflinePageArchivePublisherTest, PublishArchive) { - auto archive_manager = std::make_unique<ArchiveManager>( - temporary_dir_path(), private_archive_dir_path(), - public_archive_dir_path(), task_runner()); - auto download_manager = - std::make_unique<StubSystemDownloadManager>(kDownloadId, true); - - OfflinePageArchivePublisher archiver(archive_manager.get(), - download_manager.get()); - - // Put an offline page into the private dir, adjust the FilePath. - page_generator()->SetArchiveDirectory(temporary_dir_path()); - OfflinePageItem offline_page = page_generator()->CreateItemWithTempFile(); - base::FilePath old_file_path = offline_page.file_path; - base::FilePath new_file_path = - public_archive_dir_path().Append(offline_page.file_path.BaseName()); - - archiver.PublishArchive( - offline_page, base::ThreadTaskRunnerHandle::Get(), - base::BindOnce(&OfflinePageArchivePublisherTest::PublishArchiveDone, - get_weak_ptr(), std::move(save_page_callback))); - PumpLoop(); - - EXPECT_EQ(SavePageResult::SUCCESS, publish_archive_result().move_result); - EXPECT_EQ(kDownloadId, publish_archive_result().download_id); - // Check there is a file in the new location. - EXPECT_TRUE(public_archive_dir_path().IsParent( - publish_archive_result().new_file_path)); - EXPECT_TRUE(base::PathExists(publish_archive_result().new_file_path)); - // Check there is no longer a file in the old location. - EXPECT_FALSE(base::PathExists(old_file_path)); -} - -// TODO(petewil): Add test cases for move failed, and adding to ADM failed. - -} // namespace offline_pages
diff --git a/components/offline_pages/core/offline_page_test_archive_publisher.cc b/components/offline_pages/core/offline_page_test_archive_publisher.cc index 54b884a..895b264 100644 --- a/components/offline_pages/core/offline_page_test_archive_publisher.cc +++ b/components/offline_pages/core/offline_page_test_archive_publisher.cc
@@ -19,12 +19,14 @@ OfflinePageTestArchivePublisher::OfflinePageTestArchivePublisher( ArchiveManager* archive_manager, - SystemDownloadManager* download_manager) - : OfflinePageArchivePublisher(archive_manager, download_manager), - expect_publish_archive_called_(false), + int64_t download_id_to_use) + : expect_publish_archive_called_(false), publish_archive_called_(false), archive_attempt_failure_(false), - use_verbatim_archive_path_(false) {} + use_verbatim_archive_path_(false), + download_id_(download_id_to_use), + last_removed_id_(0LL), + archive_manager_(archive_manager) {} OfflinePageTestArchivePublisher::~OfflinePageTestArchivePublisher() { if (expect_publish_archive_called_) @@ -40,6 +42,7 @@ if (archive_attempt_failure_) { publish_archive_result.move_result = SavePageResult::FILE_MOVE_FAILED; + publish_archive_result.download_id = 0LL; } else { publish_archive_result.move_result = SavePageResult::SUCCESS; @@ -54,7 +57,7 @@ archive_manager_->GetPublicArchivesDir().Append( offline_page.file_path.BaseName()); } - publish_archive_result.download_id = 0; + publish_archive_result.download_id = download_id_; } background_task_runner->PostTask( @@ -62,4 +65,10 @@ std::move(publish_archive_result))); } +void OfflinePageTestArchivePublisher::UnpublishArchives( + const std::vector<int64_t>& download_manager_ids) const { + if (!download_manager_ids.empty()) + last_removed_id_ = download_manager_ids.back(); +} + } // namespace offline_pages
diff --git a/components/offline_pages/core/offline_page_test_archive_publisher.h b/components/offline_pages/core/offline_page_test_archive_publisher.h index 9a8eb75..a570038 100644 --- a/components/offline_pages/core/offline_page_test_archive_publisher.h +++ b/components/offline_pages/core/offline_page_test_archive_publisher.h
@@ -22,12 +22,11 @@ namespace offline_pages { class ArchiveManager; -class SystemDownloadManager; class OfflinePageTestArchivePublisher : public OfflinePageArchivePublisher { public: OfflinePageTestArchivePublisher(ArchiveManager* archive_manager, - SystemDownloadManager* download_manager); + int64_t download_id_to_use); ~OfflinePageTestArchivePublisher() override; void PublishArchive( @@ -35,6 +34,9 @@ const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, PublishArchiveDoneCallback publish_done_callback) const override; + void UnpublishArchives( + const std::vector<int64_t>& download_manager_ids) const override; + void set_archive_attempt_failure(bool fail) { archive_attempt_failure_ = fail; } @@ -45,11 +47,17 @@ void use_verbatim_archive_path(bool use) { use_verbatim_archive_path_ = use; } + int64_t last_removed_id() const { return last_removed_id_; } + private: bool expect_publish_archive_called_; mutable bool publish_archive_called_; bool archive_attempt_failure_; bool use_verbatim_archive_path_; + int64_t download_id_; + mutable int64_t last_removed_id_; + + ArchiveManager* archive_manager_; }; } // namespace offline_pages
diff --git a/components/offline_pages/core/stub_system_download_manager.cc b/components/offline_pages/core/stub_system_download_manager.cc deleted file mode 100644 index 2b8562f..0000000 --- a/components/offline_pages/core/stub_system_download_manager.cc +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/offline_pages/core/stub_system_download_manager.h" - -namespace offline_pages { - -StubSystemDownloadManager::StubSystemDownloadManager(int64_t id_to_use, - bool installed) - : download_id_(id_to_use), last_removed_id_(0), installed_(installed) {} - -StubSystemDownloadManager::~StubSystemDownloadManager() {} - -bool StubSystemDownloadManager::IsDownloadManagerInstalled() { - return installed_; -} - -int64_t StubSystemDownloadManager::AddCompletedDownload( - const std::string& title, - const std::string& description, - const std::string& path, - int64_t length, - const std::string& uri, - const std::string& referer) { - title_ = title; - description_ = description; - path_ = path; - length_ = length; - uri_ = uri; - referer_ = referer; - - return download_id_; -} - -int StubSystemDownloadManager::Remove( - const std::vector<int64_t>& android_download_manager_ids) { - int count = static_cast<int>(android_download_manager_ids.size()); - if (count > 0) - last_removed_id_ = android_download_manager_ids[count - 1]; - return count; -} - -} // namespace offline_pages
diff --git a/components/offline_pages/core/stub_system_download_manager.h b/components/offline_pages/core/stub_system_download_manager.h deleted file mode 100644 index dab2194..0000000 --- a/components/offline_pages/core/stub_system_download_manager.h +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_OFFLINE_PAGES_CORE_STUB_SYSTEM_DOWNLOAD_MANAGER_H_ -#define COMPONENTS_OFFLINE_PAGES_CORE_STUB_SYSTEM_DOWNLOAD_MANAGER_H_ - -#include "components/offline_pages/core/system_download_manager.h" - -namespace offline_pages { - -// Stub replacement for the DownloadManager to be used by unit tests. -class StubSystemDownloadManager : public SystemDownloadManager { - public: - StubSystemDownloadManager(int64_t download_id, bool installed); - ~StubSystemDownloadManager() override; - - bool IsDownloadManagerInstalled() override; - - int64_t AddCompletedDownload(const std::string& title, - const std::string& description, - const std::string& path, - int64_t length, - const std::string& uri, - const std::string& referer) override; - - int Remove(const std::vector<int64_t>& android_download_manager_ids) override; - - // Accessors for the test to use to check passed parameters. - std::string title() { return title_; } - std::string description() { return description_; } - std::string path() { return path_; } - std::string uri() { return uri_; } - std::string referer() { return referer_; } - long length() { return length_; } - void set_installed(bool installed) { installed_ = installed; } - void set_download_id(int64_t download_id) { download_id_ = download_id; } - int64_t last_removed_id() { return last_removed_id_; } - - private: - int64_t download_id_; - int64_t last_removed_id_; - std::string title_; - std::string description_; - std::string path_; - std::string uri_; - std::string referer_; - long length_; - bool installed_; -}; - -} // namespace offline_pages - -#endif // COMPONENTS_OFFLINE_PAGES_CORE_STUB_SYSTEM_DOWNLOAD_MANAGER_H_
diff --git a/components/offline_pages/core/system_download_manager.h b/components/offline_pages/core/system_download_manager.h deleted file mode 100644 index b6520ac..0000000 --- a/components/offline_pages/core/system_download_manager.h +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_OFFLINE_PAGES_CORE_SYSTEM_DOWNLOAD_MANAGER_H_ -#define COMPONENTS_OFFLINE_PAGES_CORE_SYSTEM_DOWNLOAD_MANAGER_H_ - -#include <string> -#include <vector> - -namespace offline_pages { - -// Interface of a class responsible for interacting with the Android download -// manager -class SystemDownloadManager { - public: - SystemDownloadManager() = default; - virtual ~SystemDownloadManager() = default; - - // Returns true if a system download manager is available on this platform. - virtual bool IsDownloadManagerInstalled() = 0; - - // Returns the download manager ID of the download, which we will place in the - // offline pages database as part of the offline page item. - // TODO(petewil): it might make sense to move all these params into a struct. - virtual int64_t AddCompletedDownload(const std::string& title, - const std::string& description, - const std::string& path, - int64_t length, - const std::string& uri, - const std::string& referer) = 0; - - // Returns the number of pages removed. - virtual int Remove( - const std::vector<int64_t>& android_download_manager_ids) = 0; -}; - -} // namespace offline_pages - -#endif // COMPONENTS_OFFLINE_PAGES_CORE_SYSTEM_DOWNLOAD_MANAGER_H_
diff --git a/components/omnibox/browser/autocomplete_classifier.cc b/components/omnibox/browser/autocomplete_classifier.cc index 5147aed..b81537d 100644 --- a/components/omnibox/browser/autocomplete_classifier.cc +++ b/components/omnibox/browser/autocomplete_classifier.cc
@@ -47,6 +47,9 @@ (base::FeatureList::IsEnabled(omnibox::kDocumentProvider) ? AutocompleteProvider::TYPE_DOCUMENT : 0) | + (base::FeatureList::IsEnabled(omnibox::kOnDeviceHeadProvider) + ? AutocompleteProvider::TYPE_ON_DEVICE_HEAD + : 0) | AutocompleteProvider::TYPE_BOOKMARK | AutocompleteProvider::TYPE_BUILTIN | AutocompleteProvider::TYPE_HISTORY_QUICK | AutocompleteProvider::TYPE_HISTORY_URL |
diff --git a/components/omnibox/browser/autocomplete_controller.cc b/components/omnibox/browser/autocomplete_controller.cc index 40100e56..304f3c82 100644 --- a/components/omnibox/browser/autocomplete_controller.cc +++ b/components/omnibox/browser/autocomplete_controller.cc
@@ -34,6 +34,7 @@ #include "components/omnibox/browser/history_quick_provider.h" #include "components/omnibox/browser/history_url_provider.h" #include "components/omnibox/browser/keyword_provider.h" +#include "components/omnibox/browser/on_device_head_provider.h" #include "components/omnibox/browser/search_provider.h" #include "components/omnibox/browser/shortcuts_provider.h" #include "components/omnibox/browser/zero_suggest_provider.h" @@ -222,6 +223,7 @@ keyword_provider_(nullptr), search_provider_(nullptr), zero_suggest_provider_(nullptr), + on_device_head_provider_(nullptr), stop_timer_duration_(OmniboxFieldTrial::StopTimerFieldTrialDuration()), done_(true), in_start_(false), @@ -278,6 +280,11 @@ document_provider_ = DocumentProvider::Create(provider_client_.get(), this); providers_.push_back(document_provider_); } + if (provider_types & AutocompleteProvider::TYPE_ON_DEVICE_HEAD) { + on_device_head_provider_ = + OnDeviceHeadProvider::Create(provider_client_.get(), this); + providers_.push_back(on_device_head_provider_); + } if (provider_types & AutocompleteProvider::TYPE_CLIPBOARD) { #if !defined(OS_IOS) // On iOS, a global ClipboardRecentContent should've been created by now
diff --git a/components/omnibox/browser/autocomplete_controller.h b/components/omnibox/browser/autocomplete_controller.h index 1e34feb1..691fffd 100644 --- a/components/omnibox/browser/autocomplete_controller.h +++ b/components/omnibox/browser/autocomplete_controller.h
@@ -29,6 +29,7 @@ class SearchProvider; class TemplateURLService; class ZeroSuggestProvider; +class OnDeviceHeadProvider; // The AutocompleteController is the center of the autocomplete system. A // class creates an instance of the controller, which in turn creates a set of @@ -237,6 +238,8 @@ ZeroSuggestProvider* zero_suggest_provider_; + OnDeviceHeadProvider* on_device_head_provider_; + // Input passed to Start. AutocompleteInput input_;
diff --git a/components/omnibox/browser/autocomplete_provider.h b/components/omnibox/browser/autocomplete_provider.h index 064273e..e862204 100644 --- a/components/omnibox/browser/autocomplete_provider.h +++ b/components/omnibox/browser/autocomplete_provider.h
@@ -65,7 +65,8 @@ // Search Secondary Provider (past query in history) | 200* // Search Secondary Provider (navigational suggestion) | 150++ // Search Secondary Provider (suggestion) | 100++ -// Non Personalized On Device Head Suggest Provider | 99-- +// Non Personalized On Device Head Suggest Provider | * +// (default value 99--, can be changed by Finch) // Document Suggestions (*experimental): value controlled by Finch | * // // URL input type: @@ -86,6 +87,7 @@ // Search Secondary Provider (past query in history) | 200* // Search Secondary Provider (navigational suggestion) | 150++ // Search Secondary Provider (suggestion) | 100++ +// Non Personalized On Device Head Suggest Provider | 99-- // // QUERY input type: // --------------------------------------------------------------------|----- @@ -104,7 +106,8 @@ // Search Secondary Provider (past query in history) | 200* // Search Secondary Provider (navigational suggestion) | 150++ // Search Secondary Provider (suggestion) | 100++ -// Non Personalized On Device Head Suggest Provider | 99-- +// Non Personalized On Device Head Suggest Provider | * +// (default value 99--, can be changed by Finch) // // (A search keyword is a keyword with a replacement string; a bookmark keyword // is a keyword with no replacement string, that is, a shortcut for a URL.)
diff --git a/components/omnibox/browser/autocomplete_provider_client.h b/components/omnibox/browser/autocomplete_provider_client.h index 6e175c2..9dccc0b 100644 --- a/components/omnibox/browser/autocomplete_provider_client.h +++ b/components/omnibox/browser/autocomplete_provider_client.h
@@ -145,12 +145,8 @@ virtual void StartServiceWorker(const GURL& destination_url) {} // Called by |controller| when its results have changed and all providers are - // done processing the autocomplete request. At the //chrome level, this - // callback results in firing the - // NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY notification. - // TODO(blundell): Remove the //chrome-level notification entirely in favor of - // having AutocompleteController expose a CallbackList that //chrome-level - // listeners add themselves to, and then kill this method. + // done processing the autocomplete request. Chrome ignores this. It's only + // used in components unit tests. TODO(blundell): remove it. virtual void OnAutocompleteControllerResultReady( AutocompleteController* controller) {}
diff --git a/components/omnibox/browser/document_provider.cc b/components/omnibox/browser/document_provider.cc index 95df411..4782b32 100644 --- a/components/omnibox/browser/document_provider.cc +++ b/components/omnibox/browser/document_provider.cc
@@ -551,7 +551,7 @@ // https://docs.google.com/[a/domain.tld/]document/d/(id)/[...] // https://docs.google.com/[a/domain.tld/]spreadsheets/d/(id)/edit#gid=12345 // https://docs.google.com/[a/domain.tld/]presentation/d/(id)/edit#slide=id.g12345a_0_26 - // https://www.google.com/url?[...]url=https://drive.google.com/a/domain.tld/open?id%3D1fkxx6KYRYnSqljThxShJVliQJLdKzuJBnzogzL3n8rE&[...] + // https://www.google.com/url?[...]url=https://drive.google.com/a/domain.tld/open?id%3D(id)[&...] // where id is comprised of characters in [0-9A-Za-z\-_] = [\w\-] std::string id;
diff --git a/components/omnibox/browser/document_provider_unittest.cc b/components/omnibox/browser/document_provider_unittest.cc index 9106d0a..5f6b5eacf 100644 --- a/components/omnibox/browser/document_provider_unittest.cc +++ b/components/omnibox/browser/document_provider_unittest.cc
@@ -5,6 +5,7 @@ #include "components/omnibox/browser/document_provider.h" #include "base/json/json_reader.h" +#include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/test/scoped_feature_list.h" #include "base/time/time_to_iso8601.h" @@ -23,6 +24,18 @@ namespace { +const std::string SAMPLE_ORIGINAL_URL = + "https://www.google.com/url?_placeholder_url=https://drive.google.com/a/" + "domain.tld/open?id%3D_0123_ID_4567_&_placeholder_"; + +const std::string SAMPLE_STRIPPED_URL = +#if defined(OS_IOS) || defined(OS_ANDROID) + SAMPLE_ORIGINAL_URL +#else + "https://drive.google.com/open?id=_0123_ID_4567_" +#endif + ; + using testing::Return; class FakeAutocompleteProviderClient : public MockAutocompleteProviderClient { @@ -228,20 +241,22 @@ } TEST_F(DocumentProviderTest, ParseDocumentSearchResults) { - const char kGoodJSONResponse[] = R"({ + const std::string kGoodJSONResponse = base::StringPrintf( + R"({ "results": [ { "title": "Document 1", "url": "https://documentprovider.tld/doc?id=1", "score": 1234, - "originalUrl": "https://shortened.url" + "originalUrl": "%s" }, { "title": "Document 2", "url": "https://documentprovider.tld/doc?id=2" } ] - })"; + })", + SAMPLE_ORIGINAL_URL.c_str()); base::Optional<base::Value> response = base::JSONReader::Read(kGoodJSONResponse); @@ -256,7 +271,7 @@ EXPECT_EQ(matches[0].destination_url, GURL("https://documentprovider.tld/doc?id=1")); EXPECT_EQ(matches[0].relevance, 1234); // Server-specified. - EXPECT_EQ(matches[0].stripped_destination_url, GURL("https://shortened.url")); + EXPECT_EQ(matches[0].stripped_destination_url, GURL(SAMPLE_STRIPPED_URL)); EXPECT_EQ(matches[1].contents, base::ASCIIToUTF16("Document 2")); EXPECT_EQ(matches[1].destination_url, @@ -270,13 +285,14 @@ TEST_F(DocumentProviderTest, ProductDescriptionStringsAndAccessibleLabels) { // Dates are kept > 1 year in the past since // See comments for GenerateLastModifiedString in this file for references. - const char kGoodJSONResponseWithMimeTypes[] = R"({ + const std::string kGoodJSONResponseWithMimeTypes = base::StringPrintf( + R"({ "results": [ { "title": "My Google Doc", "url": "https://documentprovider.tld/doc?id=1", "score": 999, - "originalUrl": "https://shortened.url", + "originalUrl": "%s", "metadata": { "mimeType": "application/vnd.google-apps.document", "updateTime": "Mon, 15 Oct 2007 19:45:00 GMT" @@ -300,7 +316,8 @@ } } ] - })"; + })", + SAMPLE_ORIGINAL_URL.c_str()); base::Optional<base::Value> response = base::JSONReader::Read(kGoodJSONResponseWithMimeTypes); @@ -335,13 +352,14 @@ } TEST_F(DocumentProviderTest, ParseDocumentSearchResultsBreakTies) { - const char kGoodJSONResponseWithTies[] = R"({ + const std::string kGoodJSONResponseWithTies = base::StringPrintf( + R"({ "results": [ { "title": "Document 1", "url": "https://documentprovider.tld/doc?id=1", "score": 1234, - "originalUrl": "https://shortened.url" + "originalUrl": "%s" }, { "title": "Document 2", @@ -354,7 +372,8 @@ "url": "https://documentprovider.tld/doc?id=3" } ] - })"; + })", + SAMPLE_ORIGINAL_URL.c_str()); base::Optional<base::Value> response = base::JSONReader::Read(kGoodJSONResponseWithTies); @@ -371,7 +390,7 @@ EXPECT_EQ(matches[0].destination_url, GURL("https://documentprovider.tld/doc?id=1")); EXPECT_EQ(matches[0].relevance, 1234); // As the server specified. - EXPECT_EQ(matches[0].stripped_destination_url, GURL("https://shortened.url")); + EXPECT_EQ(matches[0].stripped_destination_url, GURL(SAMPLE_STRIPPED_URL)); EXPECT_EQ(matches[1].contents, base::ASCIIToUTF16("Document 2")); EXPECT_EQ(matches[1].destination_url, @@ -389,13 +408,14 @@ } TEST_F(DocumentProviderTest, ParseDocumentSearchResultsBreakTiesCascade) { - const char kGoodJSONResponseWithTies[] = R"({ + const std::string kGoodJSONResponseWithTies = base::StringPrintf( + R"({ "results": [ { "title": "Document 1", "url": "https://documentprovider.tld/doc?id=1", "score": 1234, - "originalUrl": "https://shortened.url" + "originalUrl": "%s" }, { "title": "Document 2", @@ -408,7 +428,8 @@ "url": "https://documentprovider.tld/doc?id=3" } ] - })"; + })", + SAMPLE_ORIGINAL_URL.c_str()); base::Optional<base::Value> response = base::JSONReader::Read(kGoodJSONResponseWithTies); @@ -425,7 +446,7 @@ EXPECT_EQ(matches[0].destination_url, GURL("https://documentprovider.tld/doc?id=1")); EXPECT_EQ(matches[0].relevance, 1234); // As the server specified. - EXPECT_EQ(matches[0].stripped_destination_url, GURL("https://shortened.url")); + EXPECT_EQ(matches[0].stripped_destination_url, GURL(SAMPLE_STRIPPED_URL)); EXPECT_EQ(matches[1].contents, base::ASCIIToUTF16("Document 2")); EXPECT_EQ(matches[1].destination_url, @@ -445,13 +466,14 @@ } TEST_F(DocumentProviderTest, ParseDocumentSearchResultsBreakTiesZeroLimit) { - const char kGoodJSONResponseWithTies[] = R"({ + const std::string kGoodJSONResponseWithTies = base::StringPrintf( + R"({ "results": [ { "title": "Document 1", "url": "https://documentprovider.tld/doc?id=1", "score": 1, - "originalUrl": "https://shortened.url" + "originalUrl": "%s" }, { "title": "Document 2", @@ -464,7 +486,8 @@ "url": "https://documentprovider.tld/doc?id=3" } ] - })"; + })", + SAMPLE_ORIGINAL_URL.c_str()); base::Optional<base::Value> response = base::JSONReader::Read(kGoodJSONResponseWithTies); @@ -481,7 +504,7 @@ EXPECT_EQ(matches[0].destination_url, GURL("https://documentprovider.tld/doc?id=1")); EXPECT_EQ(matches[0].relevance, 1); // As the server specified. - EXPECT_EQ(matches[0].stripped_destination_url, GURL("https://shortened.url")); + EXPECT_EQ(matches[0].stripped_destination_url, GURL(SAMPLE_STRIPPED_URL)); EXPECT_EQ(matches[1].contents, base::ASCIIToUTF16("Document 2")); EXPECT_EQ(matches[1].destination_url,
diff --git a/components/omnibox/browser/on_device_head_provider.cc b/components/omnibox/browser/on_device_head_provider.cc index 68328ee1..c4d9d0a 100644 --- a/components/omnibox/browser/on_device_head_provider.cc +++ b/components/omnibox/browser/on_device_head_provider.cc
@@ -9,13 +9,16 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/i18n/case_conversion.h" +#include "base/metrics/field_trial_params.h" #include "base/strings/utf_string_conversions.h" #include "base/task/post_task.h" #include "base/trace_event/trace_event.h" #include "components/omnibox/browser/autocomplete_provider_listener.h" #include "components/omnibox/browser/base_search_provider.h" +#include "components/omnibox/common/omnibox_features.h" #include "components/search_engines/search_terms_data.h" #include "components/search_engines/template_url_service.h" +#include "third_party/metrics_proto/omnibox_input_type.pb.h" namespace { const int kBaseRelevance = 99; @@ -127,10 +130,21 @@ // request. std::unique_ptr<OnDeviceHeadProviderParams> params = base::WrapUnique( new OnDeviceHeadProviderParams(on_device_search_request_id_, input)); - task_runner_->PostTask( + + // Since the On Device provider usually runs much faster than online + // providers, it will be very likely users will see on device suggestions + // first and then the Omnibox UI gets refreshed to show suggestions fetched + // from server, if we issue both requests simultaneously. + // Therefore, we might want to delay the On Device suggest requests (and + // also apply a timeout to search default loader) to mitigate this issue. + int delay = base::GetFieldTrialParamByFeatureAsInt( + omnibox::kOnDeviceHeadProvider, "DelayOnDeviceHeadSuggestRequestMs", 0); + task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&OnDeviceHeadProvider::DoSearch, - weak_ptr_factory_.GetWeakPtr(), std::move(params))); + weak_ptr_factory_.GetWeakPtr(), std::move(params)), + delay > 0 ? base::TimeDelta::FromMilliseconds(delay) + : base::TimeDelta()); } } @@ -196,7 +210,12 @@ if (IsDefaultSearchProviderGoogle(template_url_service) && !params->failed) { matches_.clear(); - int relevance = kBaseRelevance; + int relevance = + (params->input.type() != metrics::OmniboxInputType::URL) + ? base::GetFieldTrialParamByFeatureAsInt( + omnibox::kOnDeviceHeadProvider, + "OnDeviceSuggestMaxScoreForNonUrlInput", kBaseRelevance) + : kBaseRelevance; for (const auto& item : params->suggestions) { matches_.push_back(BaseSearchProvider::CreateOnDeviceSearchSuggestion( /*autocomplete_provider=*/this, /*input=*/params->input,
diff --git a/components/omnibox/browser/search_provider.cc b/components/omnibox/browser/search_provider.cc index cea23458..0e2520b 100644 --- a/components/omnibox/browser/search_provider.cc +++ b/components/omnibox/browser/search_provider.cc
@@ -16,6 +16,7 @@ #include "base/i18n/break_iterator.h" #include "base/i18n/case_conversion.h" #include "base/json/json_string_value_serializer.h" +#include "base/metrics/field_trial_params.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" #include "base/rand_util.h" @@ -96,6 +97,14 @@ return false; } +bool IsSearchEngineGoogle(const TemplateURL* template_url, + const AutocompleteProviderClient* client) { + return template_url && client && + template_url->GetEngineType( + client->GetTemplateURLService()->search_terms_data()) == + SEARCH_ENGINE_GOOGLE; +} + } // namespace // SearchProvider::Providers -------------------------------------------------- @@ -502,11 +511,8 @@ // Record response time for suggest requests sent to Google. We care // only about the common case: the Google default provider used in // non-keyword mode. - const TemplateURL* default_url = providers_.GetDefaultProviderURL(); - if (!is_keyword && default_url && - (default_url->GetEngineType( - client()->GetTemplateURLService()->search_terms_data()) == - SEARCH_ENGINE_GOOGLE)) { + if (!is_keyword && + IsSearchEngineGoogle(providers_.GetDefaultProviderURL(), client())) { const base::TimeDelta elapsed_time = base::TimeTicks::Now() - time_suggest_request_sent_; if (success) { @@ -615,11 +621,21 @@ time_suggest_request_sent_ = base::TimeTicks::Now(); if (!query_is_private) { - default_loader_ = - CreateSuggestLoader(providers_.GetDefaultProviderURL(), input_); + int timeout_ms = 0; + // Consider explicitly setting a timeout for requests sent to Google when + // On Device Head provider is enabled. + if (IsSearchEngineGoogle(providers_.GetDefaultProviderURL(), client())) { + timeout_ms = base::GetFieldTrialParamByFeatureAsInt( + omnibox::kOnDeviceHeadProvider, + "SearchProviderDefaultLoaderTimeoutMs", 0); + } + default_loader_ = CreateSuggestLoader( + providers_.GetDefaultProviderURL(), input_, + timeout_ms > 0 ? base::TimeDelta::FromMilliseconds(timeout_ms) + : base::TimeDelta()); } - keyword_loader_ = - CreateSuggestLoader(providers_.GetKeywordProviderURL(), keyword_input_); + keyword_loader_ = CreateSuggestLoader(providers_.GetKeywordProviderURL(), + keyword_input_, base::TimeDelta()); // Both the above can fail if the providers have been modified or deleted // since the query began. @@ -865,7 +881,8 @@ std::unique_ptr<network::SimpleURLLoader> SearchProvider::CreateSuggestLoader( const TemplateURL* template_url, - const AutocompleteInput& input) { + const AutocompleteInput& input, + const base::TimeDelta& timeout) { if (!template_url || template_url->suggestions_url().empty()) return nullptr; @@ -968,6 +985,8 @@ std::unique_ptr<network::SimpleURLLoader> loader = network::SimpleURLLoader::Create(std::move(request), traffic_annotation); + if (timeout > base::TimeDelta()) + loader->SetTimeoutDuration(timeout); loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie( client()->GetURLLoaderFactory().get(), base::BindOnce(&SearchProvider::OnURLLoadComplete, base::Unretained(this),
diff --git a/components/omnibox/browser/search_provider.h b/components/omnibox/browser/search_provider.h index f4f9090..3f8a679 100644 --- a/components/omnibox/browser/search_provider.h +++ b/components/omnibox/browser/search_provider.h
@@ -264,10 +264,12 @@ // Starts a new SimpleURLLoader requesting suggest results from // |template_url|; callers own the returned SimpleURLLoader, which is NULL for - // invalid providers. + // invalid providers. Note the request will never time out unless the given + // |timeout| is greater than 0. std::unique_ptr<network::SimpleURLLoader> CreateSuggestLoader( const TemplateURL* template_url, - const AutocompleteInput& input); + const AutocompleteInput& input, + const base::TimeDelta& timeout); // Converts the parsed results to a set of AutocompleteMatches, |matches_|. void ConvertResultsToAutocompleteMatches();
diff --git a/components/omnibox/common/omnibox_features.cc b/components/omnibox/common/omnibox_features.cc index d2dc995..8ac55bf 100644 --- a/components/omnibox/common/omnibox_features.cc +++ b/components/omnibox/common/omnibox_features.cc
@@ -4,6 +4,8 @@ #include "components/omnibox/common/omnibox_features.h" +#include "build/build_config.h" + namespace omnibox { // Feature used to hide the scheme from steady state URLs displayed in the @@ -255,8 +257,14 @@ // Feature used to dedupe Google Drive URLs between different formats. // OmniboxDocumentProvider arms may wish to enable this, though it may also be // run on its own. -const base::Feature kDedupeGoogleDriveURLs{"OmniboxDedupeGoogleDriveURLs", - base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kDedupeGoogleDriveURLs { + "OmniboxDedupeGoogleDriveURLs", +#if defined(OS_IOS) || defined(OS_ANDROID) + base::FEATURE_DISABLED_BY_DEFAULT +#else + base::FEATURE_ENABLED_BY_DEFAULT +#endif +}; // Feature to replace the standard ZeroSuggest with icons for most visited sites // and collections (bookmarks, history, recent tabs, reading list). Only @@ -288,4 +296,9 @@ const base::Feature kZeroSuggestionsOnNTP{"OmniboxZeroSuggestionsOnNTP", base::FEATURE_DISABLED_BY_DEFAULT}; +// Feature to provide non personalized head search suggestion from a compact +// on device model. +const base::Feature kOnDeviceHeadProvider{"OmniboxOnDeviceHeadProvider", + base::FEATURE_DISABLED_BY_DEFAULT}; + } // namespace omnibox
diff --git a/components/omnibox/common/omnibox_features.h b/components/omnibox/common/omnibox_features.h index d5323a4..d95912c 100644 --- a/components/omnibox/common/omnibox_features.h +++ b/components/omnibox/common/omnibox_features.h
@@ -46,6 +46,7 @@ extern const base::Feature kUIExperimentShowPlaceholderWhenCaretShowing; extern const base::Feature kSpeculativeServiceWorkerStartOnQueryInput; extern const base::Feature kDocumentProvider; +extern const base::Feature kOnDeviceHeadProvider; extern const base::Feature kDedupeGoogleDriveURLs; extern const base::Feature kOmniboxPopupShortcutIconsInZeroState; extern const base::Feature kOmniboxMaterialDesignWeatherIcons;
diff --git a/components/payments/content/payment_event_response_util.cc b/components/payments/content/payment_event_response_util.cc index eff4a35..b7de46a 100644 --- a/components/payments/content/payment_event_response_util.cc +++ b/components/payments/content/payment_event_response_util.cc
@@ -36,6 +36,8 @@ return errors::kPaymentEventBrowserError; case mojom::PaymentEventResponseType::PAYMENT_EVENT_TIMEOUT: return errors::kPaymentEventTimeout; + case mojom::PaymentEventResponseType::PAYMENT_HANDLER_INSECURE_NAVIGATION: + return errors::kPaymentHandlerInsecureNavigation; } }
diff --git a/components/payments/content/payment_request_state.cc b/components/payments/content/payment_request_state.cc index 1304726..361769d 100644 --- a/components/payments/content/payment_request_state.cc +++ b/components/payments/content/payment_request_state.cc
@@ -10,12 +10,14 @@ #include "base/bind.h" #include "base/feature_list.h" +#include "base/metrics/histogram_functions.h" #include "base/strings/utf_string_conversions.h" #include "components/autofill/core/browser/autofill_data_util.h" #include "components/autofill/core/browser/data_model/autofill_profile.h" #include "components/autofill/core/browser/data_model/credit_card.h" #include "components/autofill/core/browser/geo/autofill_country.h" #include "components/autofill/core/browser/personal_data_manager.h" +#include "components/autofill/core/browser/validation.h" #include "components/payments/content/content_payment_request_delegate.h" #include "components/payments/content/payment_manifest_web_data_service.h" #include "components/payments/content/payment_response_helper.h" @@ -514,7 +516,10 @@ profile_comparator()->IsShippingComplete(shipping_profiles_[0])) { selected_shipping_profile_ = shipping_profiles()[0]; } - + // Record the missing required fields (if any) of the most complete shipping + // profile. + profile_comparator()->RecordMissingFieldsOfShippingProfile( + shipping_profiles().empty() ? nullptr : shipping_profiles()[0]); UpdateIsReadyToPayAndNotifyObservers(); } @@ -578,6 +583,11 @@ profile_comparator()->IsContactInfoComplete(contact_profiles_[0])) selected_contact_profile_ = contact_profiles()[0]; + // Record the missing required fields (if any) of the most complete contact + // profile. + profile_comparator()->RecordMissingFieldsOfContactProfile( + contact_profiles().empty() ? nullptr : contact_profiles()[0]); + // TODO(crbug.com/702063): Change this code to prioritize instruments by use // count and other means, and implement a way to modify this function's return // value. @@ -593,16 +603,33 @@ ? nullptr : first_complete_instrument->get(); - SelectDefaultShippingAddressAndNotifyObservers(); + // Record the missing required payment fields when no complete payment + // info exists. + if (instruments.empty()) { + if (spec_->supports_basic_card()) { + // All fields are missing when basic-card is requested but no card exits. + base::UmaHistogramSparse("PaymentRequest.MissingPaymentFields", + autofill::CREDIT_CARD_EXPIRED | + autofill::CREDIT_CARD_NO_CARDHOLDER | + autofill::CREDIT_CARD_NO_NUMBER | + autofill::CREDIT_CARD_NO_BILLING_ADDRESS); + } + } else if (!selected_instrument_) { + // selected_instrument_ == false means no complete payment instrument is + // added to the available_instruments list. Since SW based payment + // instruments are always complete, selected_instrument_ == false also means + // all instruments added to the list are autofill based. + DCHECK_EQ(instruments[0]->type(), PaymentInstrument::Type::AUTOFILL); + // Record the missing info of the first available autofill instrument. + static_cast<const AutofillPaymentInstrument*>(instruments[0].get()) + ->RecordMissingFieldsForInstrument(); + } - bool has_complete_instrument = - available_instruments().empty() - ? false - : available_instruments()[0]->IsCompleteForPayment(); + SelectDefaultShippingAddressAndNotifyObservers(); journey_logger_->SetNumberOfSuggestionsShown( JourneyLogger::Section::SECTION_PAYMENT_METHOD, - available_instruments().size(), has_complete_instrument); + available_instruments().size(), selected_instrument_); } void PaymentRequestState::UpdateIsReadyToPayAndNotifyObservers() {
diff --git a/components/payments/content/service_worker_payment_instrument.cc b/components/payments/content/service_worker_payment_instrument.cc index d94620d..484eba9 100644 --- a/components/payments/content/service_worker_payment_instrument.cc +++ b/components/payments/content/service_worker_payment_instrument.cc
@@ -248,7 +248,8 @@ void ServiceWorkerPaymentInstrument::OnPaymentAppWindowClosed() { delegate_ = nullptr; content::PaymentAppProvider::GetInstance()->OnClosingOpenedWindow( - browser_context_); + browser_context_, + mojom::PaymentEventResponseType::PAYMENT_HANDLER_WINDOW_CLOSING); } mojom::PaymentRequestEventDataPtr
diff --git a/components/payments/core/autofill_payment_instrument.cc b/components/payments/core/autofill_payment_instrument.cc index b5cb8b6..8aecac5 100644 --- a/components/payments/core/autofill_payment_instrument.cc +++ b/components/payments/core/autofill_payment_instrument.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/json/json_writer.h" +#include "base/metrics/histogram_functions.h" #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" @@ -85,6 +86,15 @@ autofill::CREDIT_CARD_EXPIRED; } +void AutofillPaymentInstrument::RecordMissingFieldsForInstrument() const { + if (IsCompleteForPayment()) + return; + + base::UmaHistogramSparse("PaymentRequest.MissingPaymentFields", + autofill::GetCompletionStatusForCard( + credit_card_, app_locale_, billing_profiles_)); +} + bool AutofillPaymentInstrument::IsExactlyMatchingMerchantRequest() const { return matches_merchant_card_type_exactly_; }
diff --git a/components/payments/core/autofill_payment_instrument.h b/components/payments/core/autofill_payment_instrument.h index b73b560..b39a01ac 100644 --- a/components/payments/core/autofill_payment_instrument.h +++ b/components/payments/core/autofill_payment_instrument.h
@@ -64,6 +64,8 @@ const base::string16& cvc) override; void OnFullCardRequestFailed() override; + void RecordMissingFieldsForInstrument() const; + autofill::CreditCard* credit_card() { return &credit_card_; } const std::string& method_name() const { return method_name_; }
diff --git a/components/payments/core/error_strings.cc b/components/payments/core/error_strings.cc index 4c8831a..b228932 100644 --- a/components/payments/core/error_strings.cc +++ b/components/payments/core/error_strings.cc
@@ -45,6 +45,7 @@ const char kPaymentEventRejected[] = "Payment handler rejected the promise passed into PaymentRequestEvent.respondWith(). This is how payment handlers close their own window programmatically."; const char kPaymentEventServiceWorkerError[] = "Payment handler failed to provide a response because either the \"paymentrequest\" event took too long or the service worker stopped for some reason or was killed before the request finished."; const char kPaymentEventTimeout[] = "The \"paymentrequest\" event timed out after 5 minutes."; +const char kPaymentHandlerInsecureNavigation[] = "The payment handler navigated to a page with insecure context, invalid certificate state, or malicious content."; const char kProhibitedOrigin[] = "Only localhost, file://, and cryptographic scheme origins allowed."; const char kProhibitedOriginOrInvalidSslExplanation[] = "No UI will be shown. CanMakePayment and hasEnrolledInstrument will always return false. Show will be rejected with NotSupportedError."; const char kSinglePaymentMethodNotSupportedFormat[] = "The payment method $ is not supported.";
diff --git a/components/payments/core/error_strings.h b/components/payments/core/error_strings.h index 1be03dd..a60c2558 100644 --- a/components/payments/core/error_strings.h +++ b/components/payments/core/error_strings.h
@@ -122,6 +122,10 @@ // Service worker timed out while responding to "paymentrequest" event. extern const char kPaymentEventTimeout[]; +// Payment handler navigated to a page with insecure context, invalid SSL, or +// malicious content. +extern const char kPaymentHandlerInsecureNavigation[]; + // Payment handler encountered an internal error when handling the // "paymentrequest" event. extern const char kPaymentEventInternalError[];
diff --git a/components/payments/core/journey_logger.cc b/components/payments/core/journey_logger.cc index 4f31801..50e0cb6 100644 --- a/components/payments/core/journey_logger.cc +++ b/components/payments/core/journey_logger.cc
@@ -11,6 +11,7 @@ #include "base/debug/dump_without_crashing.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" +#include "base/numerics/safe_conversions.h" #include "base/strings/stringprintf.h" #include "services/metrics/public/cpp/ukm_builders.h" #include "services/metrics/public/cpp/ukm_recorder.h" @@ -111,6 +112,22 @@ sections_[section].has_complete_suggestion_ = has_complete_suggestion; } +void JourneyLogger::SetSectionNeedsCompletion(const Section section) { + switch (section) { + case SECTION_CONTACT_INFO: + events_ |= EVENT_NEEDS_COMPLETION_CONTACT_INFO; + break; + case SECTION_PAYMENT_METHOD: + events_ |= EVENT_NEEDS_COMPLETION_PAYMENT; + break; + case SECTION_SHIPPING_ADDRESS: + events_ |= EVENT_NEEDS_COMPLETION_SHIPPING; + break; + default: + NOTREACHED(); + } +} + void JourneyLogger::SetCanMakePaymentValue(bool value) { // Do not log the outcome of canMakePayment in incognito mode. if (is_incognito_) @@ -267,6 +284,7 @@ if (sections_[i].number_suggestions_shown_ == 0 || !sections_[i].has_complete_suggestion_) { user_had_complete_suggestions_for_requested_information = false; + SetSectionNeedsCompletion(static_cast<const Section>(i)); } } }
diff --git a/components/payments/core/journey_logger.h b/components/payments/core/journey_logger.h index e136013..82c463c5 100644 --- a/components/payments/core/journey_logger.h +++ b/components/payments/core/journey_logger.h
@@ -99,7 +99,10 @@ EVENT_HAS_ENROLLED_INSTRUMENT_FALSE = 1 << 22, // True when a NotShownReason is set. EVENT_COULD_NOT_SHOW = 1 << 23, - EVENT_ENUM_MAX = 2097152, + EVENT_NEEDS_COMPLETION_CONTACT_INFO = 1 << 24, + EVENT_NEEDS_COMPLETION_PAYMENT = 1 << 25, + EVENT_NEEDS_COMPLETION_SHIPPING = 1 << 26, + EVENT_ENUM_MAX = 1 << 27, }; // The reason why the Payment Request was aborted. @@ -234,6 +237,9 @@ // Returns whether this Payment Request was triggered (shown or skipped show). bool WasPaymentRequestTriggered(); + // Sets needs completion bit in events_ bit field for the given section. + void SetSectionNeedsCompletion(Section section); + SectionStats sections_[NUMBER_OF_SECTIONS]; bool has_recorded_ = false; bool is_incognito_;
diff --git a/components/payments/core/payments_profile_comparator.cc b/components/payments/core/payments_profile_comparator.cc index 548e6ed2..b104f4d 100644 --- a/components/payments/core/payments_profile_comparator.cc +++ b/components/payments/core/payments_profile_comparator.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include <memory> +#include "base/metrics/histogram_functions.h" #include "base/strings/utf_string_conversions.h" #include "components/autofill/core/browser/autofill_data_util.h" #include "components/autofill/core/browser/data_model/autofill_profile.h" @@ -177,6 +178,37 @@ GetRequiredProfileFieldsForShipping()); } +void PaymentsProfileComparator::RecordMissingFieldsOfShippingProfile( + const autofill::AutofillProfile* profile) const { + // We should not record anything when no shipping fields is required. + if (!GetRequiredProfileFieldsForShipping()) + return; + + // Record any required fields that are missing. + PaymentsProfileComparator::ProfileFields missing_fields = + GetMissingProfileFields(profile) & GetRequiredProfileFieldsForShipping(); + if (missing_fields != kNone) { + base::UmaHistogramSparse("PaymentRequest.MissingShippingFields", + missing_fields); + } +} + +void PaymentsProfileComparator::RecordMissingFieldsOfContactProfile( + const autofill::AutofillProfile* profile) const { + // We should not record anything when no contact fields is required. + if (GetRequiredProfileFieldsForContact() == kNone) + return; + + // Record any required fields that are missing. + PaymentsProfileComparator::ProfileFields missing_fields = + GetMissingProfileFields(profile) & GetRequiredProfileFieldsForContact(); + if (missing_fields != kNone) { + base::UmaHistogramSparse("PaymentRequest.MissingContactFields", + missing_fields); + return; + } +} + base::string16 PaymentsProfileComparator::GetStringForMissingContactFields( const autofill::AutofillProfile& profile) const { return GetStringForMissingFields(GetMissingProfileFields(&profile) & @@ -209,7 +241,7 @@ PaymentsProfileComparator::ProfileFields PaymentsProfileComparator::ComputeMissingFields( const autofill::AutofillProfile& profile) const { - ProfileFields missing = 0; + ProfileFields missing = kNone; if (!profile.HasInfo(autofill::NAME_FULL)) missing |= kName; @@ -242,7 +274,7 @@ PaymentsProfileComparator::ProfileFields PaymentsProfileComparator::GetRequiredProfileFieldsForContact() const { - ProfileFields required = 0; + ProfileFields required = kNone; if (options_.request_payer_name()) required |= kName; if (options_.request_payer_phone()) @@ -254,13 +286,13 @@ PaymentsProfileComparator::ProfileFields PaymentsProfileComparator::GetRequiredProfileFieldsForShipping() const { - return options_.request_shipping() ? (kAddress | kName | kPhone) : 0; + return options_.request_shipping() ? (kAddress | kName | kPhone) : kNone; } base::string16 PaymentsProfileComparator::GetStringForMissingFields( PaymentsProfileComparator::ProfileFields fields) const { switch (fields) { - case 0: + case kNone: // No bits are set, so no fields are missing. return base::string16(); case kName:
diff --git a/components/payments/core/payments_profile_comparator.h b/components/payments/core/payments_profile_comparator.h index 3efea9c..6395d69f 100644 --- a/components/payments/core/payments_profile_comparator.h +++ b/components/payments/core/payments_profile_comparator.h
@@ -33,6 +33,7 @@ public: // Bitmask of potentially-required fields used in evaluating completeness. using ProfileFields = uint32_t; + const static ProfileFields kNone = 0; const static ProfileFields kName = 1 << 0; const static ProfileFields kPhone = 1 << 1; const static ProfileFields kEmail = 1 << 2; @@ -107,6 +108,11 @@ base::string16 GetTitleForMissingShippingFields( const autofill::AutofillProfile& profile) const; + void RecordMissingFieldsOfShippingProfile( + const autofill::AutofillProfile* profile) const; + void RecordMissingFieldsOfContactProfile( + const autofill::AutofillProfile* profile) const; + // Clears the cached evaluation result for |profile|. Must be called when a // profile is modified and saved during the course of a PaymentRequest. virtual void Invalidate(const autofill::AutofillProfile& profile);
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index a9f38de..93dc2a2 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -10729,7 +10729,7 @@ }, { 'name': 'WelcomePageOnOSUpgradeEnabled', - 'supported_on': ['chrome.win:45-'], + 'supported_on': ['chrome.win:45-62'], 'type': 'main', 'schema': { 'type': 'boolean' }, 'id': 303,
diff --git a/components/safe_browsing/db/v4_update_protocol_manager_unittest.cc b/components/safe_browsing/db/v4_update_protocol_manager_unittest.cc index 07445051..fa27844e 100644 --- a/components/safe_browsing/db/v4_update_protocol_manager_unittest.cc +++ b/components/safe_browsing/db/v4_update_protocol_manager_unittest.cc
@@ -27,6 +27,10 @@ #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" +#if !defined(FULL_SAFE_BROWSING) +#include "base/system/sys_info.h" +#endif + using base::Time; using base::TimeDelta; @@ -283,11 +287,13 @@ std::string encoded_request_with_minus = pm->GetBase64SerializedUpdateRequestProto(); - const std::string expected = -#if defined(FULL_SAFE_BROWSING) + std::string expected = "Cg8KCHVuaXR0ZXN0EgMxLjAaGAgBEAIaCmg4eGZZcVk-OlIiBCABIAIoASICCAE="; -#else - "Cg8KCHVuaXR0ZXN0EgMxLjAaGwgBEAIaCmg4eGZZcVk-OlIiBxCAICABIAIoASICCAE="; +#if !defined(FULL_SAFE_BROWSING) + if (base::SysInfo::IsLowEndDevice()) { + expected = + "Cg8KCHVuaXR0ZXN0EgMxLjAaGwgBEAIaCmg4eGZZcVk-OlIiBxCAICABIAIoASICCAE="; + } #endif EXPECT_EQ(expected, encoded_request_with_minus); @@ -353,11 +359,11 @@ store_state_map_->clear(); (*store_state_map_)[ListIdentifier(LINUX_PLATFORM, URL, MALWARE_THREAT)] = "state"; - const std::string base = -#if defined(FULL_SAFE_BROWSING) - "Cg8KCHVuaXR0ZXN0EgMxLjAaEwgBEAIaBXN0YXRlIgQgASACKAEiAgg"; -#else - "Cg8KCHVuaXR0ZXN0EgMxLjAaFggBEAIaBXN0YXRlIgcQgCAgASACKAEiAgg"; + std::string base = "Cg8KCHVuaXR0ZXN0EgMxLjAaEwgBEAIaBXN0YXRlIgQgASACKAEiAgg"; +#if !defined(FULL_SAFE_BROWSING) + if (base::SysInfo::IsLowEndDevice()) { + base = "Cg8KCHVuaXR0ZXN0EgMxLjAaFggBEAIaBXN0YXRlIgcQgCAgASACKAEiAgg"; + } #endif std::unique_ptr<V4UpdateProtocolManager> pm_with_off(CreateProtocolManager(
diff --git a/components/safe_browsing/password_protection/password_protection_request.cc b/components/safe_browsing/password_protection/password_protection_request.cc index da9214a..1fdaf94a 100644 --- a/components/safe_browsing/password_protection/password_protection_request.cc +++ b/components/safe_browsing/password_protection/password_protection_request.cc
@@ -266,7 +266,9 @@ void PasswordProtectionRequest::OnGetDomFeatures(const std::string& verdict) { ClientPhishingRequest dom_features_request; - if (dom_features_request.ParseFromString(verdict)) { + bool parsed = dom_features_request.ParseFromString(verdict); + UMA_HISTOGRAM_BOOLEAN("PasswordProtection.DomFeatureParsing", parsed); + if (parsed) { for (const ClientPhishingRequest::Feature& feature : dom_features_request.feature_map()) { DomFeatures::Feature* new_feature =
diff --git a/components/signin/core/browser/fake_profile_oauth2_token_service.cc b/components/signin/core/browser/fake_profile_oauth2_token_service.cc index 30654f6..a38940a 100644 --- a/components/signin/core/browser/fake_profile_oauth2_token_service.cc +++ b/components/signin/core/browser/fake_profile_oauth2_token_service.cc
@@ -6,20 +6,9 @@ #include <memory> -#include "base/bind.h" -#include "base/location.h" -#include "base/single_thread_task_runner.h" -#include "base/threading/thread_task_runner_handle.h" #include "google_apis/gaia/fake_oauth2_token_service_delegate.h" #include "services/network/public/cpp/shared_url_loader_factory.h" -FakeProfileOAuth2TokenService::PendingRequest::PendingRequest() {} - -FakeProfileOAuth2TokenService::PendingRequest::PendingRequest( - const PendingRequest& other) = default; - -FakeProfileOAuth2TokenService::PendingRequest::~PendingRequest() {} - FakeProfileOAuth2TokenService::FakeProfileOAuth2TokenService( PrefService* user_prefs) : FakeProfileOAuth2TokenService( @@ -29,9 +18,12 @@ FakeProfileOAuth2TokenService::FakeProfileOAuth2TokenService( PrefService* user_prefs, std::unique_ptr<OAuth2TokenServiceDelegate> delegate) - : ProfileOAuth2TokenService(user_prefs, std::move(delegate)), - auto_post_fetch_response_on_message_loop_(false), - weak_ptr_factory_(this) {} + : ProfileOAuth2TokenService(user_prefs, std::move(delegate)) { + OverrideAccessTokenManagerForTesting( + std::make_unique<FakeOAuth2AccessTokenManager>( + this /* OAuth2TokenService* */, + this /* OAuth2AccessTokenManager::Delegate* */)); +} FakeProfileOAuth2TokenService::~FakeProfileOAuth2TokenService() {} @@ -39,137 +31,79 @@ const std::string& account_id, const std::string& access_token, const base::Time& expiration) { - DCHECK(!auto_post_fetch_response_on_message_loop_); - CompleteRequests(account_id, true, OAuth2AccessTokenManager::ScopeSet(), - GoogleServiceAuthError::AuthErrorNone(), - OAuth2AccessTokenConsumer::TokenResponse( - access_token, expiration, std::string() /* id_token */)); + GetFakeAccessTokenManager()->IssueAllTokensForAccount( + account_id, access_token, expiration); } void FakeProfileOAuth2TokenService::IssueAllTokensForAccount( const std::string& account_id, const OAuth2AccessTokenConsumer::TokenResponse& token_response) { - DCHECK(!auto_post_fetch_response_on_message_loop_); - CompleteRequests(account_id, true, OAuth2AccessTokenManager::ScopeSet(), - GoogleServiceAuthError::AuthErrorNone(), token_response); + GetFakeAccessTokenManager()->IssueAllTokensForAccount(account_id, + token_response); } void FakeProfileOAuth2TokenService::IssueErrorForAllPendingRequestsForAccount( const std::string& account_id, const GoogleServiceAuthError& error) { - DCHECK(!auto_post_fetch_response_on_message_loop_); - CompleteRequests(account_id, true, OAuth2AccessTokenManager::ScopeSet(), - error, OAuth2AccessTokenConsumer::TokenResponse()); + GetFakeAccessTokenManager()->IssueErrorForAllPendingRequestsForAccount( + account_id, error); } void FakeProfileOAuth2TokenService::IssueTokenForScope( const OAuth2AccessTokenManager::ScopeSet& scope, const std::string& access_token, const base::Time& expiration) { - DCHECK(!auto_post_fetch_response_on_message_loop_); - CompleteRequests("", false, scope, GoogleServiceAuthError::AuthErrorNone(), - OAuth2AccessTokenConsumer::TokenResponse( - access_token, expiration, std::string() /* id_token */)); + GetFakeAccessTokenManager()->IssueTokenForScope(scope, access_token, + expiration); } void FakeProfileOAuth2TokenService::IssueTokenForScope( const OAuth2AccessTokenManager::ScopeSet& scope, const OAuth2AccessTokenConsumer::TokenResponse& token_response) { - DCHECK(!auto_post_fetch_response_on_message_loop_); - CompleteRequests("", false, scope, GoogleServiceAuthError::AuthErrorNone(), - token_response); + GetFakeAccessTokenManager()->IssueTokenForScope(scope, token_response); } void FakeProfileOAuth2TokenService::IssueErrorForScope( const OAuth2AccessTokenManager::ScopeSet& scope, const GoogleServiceAuthError& error) { - DCHECK(!auto_post_fetch_response_on_message_loop_); - CompleteRequests("", false, scope, error, - OAuth2AccessTokenConsumer::TokenResponse()); + GetFakeAccessTokenManager()->IssueErrorForScope(scope, error); } void FakeProfileOAuth2TokenService::IssueErrorForAllPendingRequests( const GoogleServiceAuthError& error) { - DCHECK(!auto_post_fetch_response_on_message_loop_); - CompleteRequests("", true, OAuth2AccessTokenManager::ScopeSet(), error, - OAuth2AccessTokenConsumer::TokenResponse()); + GetFakeAccessTokenManager()->IssueErrorForAllPendingRequests(error); +} + +void FakeProfileOAuth2TokenService:: + set_auto_post_fetch_response_on_message_loop(bool auto_post_response) { + GetFakeAccessTokenManager()->set_auto_post_fetch_response_on_message_loop( + auto_post_response); } void FakeProfileOAuth2TokenService::IssueTokenForAllPendingRequests( const std::string& access_token, const base::Time& expiration) { - DCHECK(!auto_post_fetch_response_on_message_loop_); - CompleteRequests("", true, OAuth2AccessTokenManager::ScopeSet(), - GoogleServiceAuthError::AuthErrorNone(), - OAuth2AccessTokenConsumer::TokenResponse( - access_token, expiration, std::string() /* id_token */)); + GetFakeAccessTokenManager()->IssueTokenForAllPendingRequests(access_token, + expiration); } void FakeProfileOAuth2TokenService::IssueTokenForAllPendingRequests( const OAuth2AccessTokenConsumer::TokenResponse& token_response) { - DCHECK(!auto_post_fetch_response_on_message_loop_); - CompleteRequests("", true, OAuth2AccessTokenManager::ScopeSet(), - GoogleServiceAuthError::AuthErrorNone(), token_response); + GetFakeAccessTokenManager()->IssueTokenForAllPendingRequests(token_response); } -void FakeProfileOAuth2TokenService::CompleteRequests( - const std::string& account_id, - bool all_scopes, - const OAuth2AccessTokenManager::ScopeSet& scope, - const GoogleServiceAuthError& error, - const OAuth2AccessTokenConsumer::TokenResponse& token_response) { - std::vector<FakeProfileOAuth2TokenService::PendingRequest> requests = - GetPendingRequests(); - - // Walk the requests and notify the callbacks. - for (auto it = requests.begin(); it != requests.end(); ++it) { - // Consumers can drop requests in response to callbacks on other requests - // (e.g., OAuthMultiloginFetcher clears all of its requests when it gets an - // error on any of them). - if (!it->request) - continue; - - bool scope_matches = all_scopes || it->scopes == scope; - bool account_matches = account_id.empty() || account_id == it->account_id; - if (account_matches && scope_matches) { - for (auto& diagnostic_observer : GetAccessTokenDiagnosticsObservers()) { - diagnostic_observer.OnFetchAccessTokenComplete( - account_id, it->request->GetConsumerId(), scope, error, - base::Time()); - } - - it->request->InformConsumer( - error, OAuth2AccessTokenConsumer::TokenResponse( - token_response.access_token, - token_response.expiration_time, token_response.id_token)); - } - } -} - -std::vector<FakeProfileOAuth2TokenService::PendingRequest> +std::vector<FakeOAuth2AccessTokenManager::PendingRequest> FakeProfileOAuth2TokenService::GetPendingRequests() { - std::vector<PendingRequest> valid_requests; - for (auto it = pending_requests_.begin(); it != pending_requests_.end(); - ++it) { - if (it->request) - valid_requests.push_back(*it); - } - return valid_requests; + return GetFakeAccessTokenManager()->GetPendingRequests(); } void FakeProfileOAuth2TokenService::CancelAllRequests() { - CompleteRequests( - "", true, OAuth2AccessTokenManager::ScopeSet(), - GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED), - OAuth2AccessTokenConsumer::TokenResponse()); + GetFakeAccessTokenManager()->CancelAllRequests(); } void FakeProfileOAuth2TokenService::CancelRequestsForAccount( const CoreAccountId& account_id) { - CompleteRequests( - account_id, true, OAuth2AccessTokenManager::ScopeSet(), - GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED), - OAuth2AccessTokenConsumer::TokenResponse()); + GetFakeAccessTokenManager()->CancelRequestsForAccount(account_id); } void FakeProfileOAuth2TokenService::FetchOAuth2Token( @@ -179,25 +113,9 @@ const std::string& client_id, const std::string& client_secret, const OAuth2AccessTokenManager::ScopeSet& scopes) { - PendingRequest pending_request; - pending_request.account_id = account_id; - pending_request.client_id = client_id; - pending_request.client_secret = client_secret; - pending_request.url_loader_factory = url_loader_factory; - pending_request.scopes = scopes; - pending_request.request = request->AsWeakPtr(); - pending_requests_.push_back(pending_request); - - if (auto_post_fetch_response_on_message_loop_) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindOnce(&FakeProfileOAuth2TokenService::CompleteRequests, - weak_ptr_factory_.GetWeakPtr(), account_id, - /*all_scoped=*/true, scopes, - GoogleServiceAuthError::AuthErrorNone(), - OAuth2AccessTokenConsumer::TokenResponse( - "access_token", base::Time::Max(), std::string()))); - } + GetFakeAccessTokenManager()->FetchOAuth2Token(request, account_id, + url_loader_factory, client_id, + client_secret, scopes); } void FakeProfileOAuth2TokenService::InvalidateAccessTokenImpl( @@ -205,5 +123,11 @@ const std::string& client_id, const OAuth2AccessTokenManager::ScopeSet& scopes, const std::string& access_token) { - // Do nothing, as we don't have a cache from which to remove the token. + GetFakeAccessTokenManager()->InvalidateAccessTokenImpl(account_id, client_id, + scopes, access_token); +} + +FakeOAuth2AccessTokenManager* +FakeProfileOAuth2TokenService::GetFakeAccessTokenManager() { + return static_cast<FakeOAuth2AccessTokenManager*>(GetAccessTokenManager()); }
diff --git a/components/signin/core/browser/fake_profile_oauth2_token_service.h b/components/signin/core/browser/fake_profile_oauth2_token_service.h index 18bb90aa..9208162 100644 --- a/components/signin/core/browser/fake_profile_oauth2_token_service.h +++ b/components/signin/core/browser/fake_profile_oauth2_token_service.h
@@ -10,8 +10,8 @@ #include "base/compiler_specific.h" #include "base/macros.h" -#include "base/memory/weak_ptr.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" +#include "google_apis/gaia/fake_oauth2_access_token_manager.h" namespace network { class SharedURLLoaderFactory; @@ -39,19 +39,6 @@ // class FakeProfileOAuth2TokenService : public ProfileOAuth2TokenService { public: - struct PendingRequest { - PendingRequest(); - PendingRequest(const PendingRequest& other); - ~PendingRequest(); - - std::string account_id; - std::string client_id; - std::string client_secret; - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory; - OAuth2AccessTokenManager::ScopeSet scopes; - base::WeakPtr<OAuth2AccessTokenManager::RequestImpl> request; - }; - explicit FakeProfileOAuth2TokenService(PrefService* user_prefs); FakeProfileOAuth2TokenService( PrefService* user_prefs, @@ -60,7 +47,8 @@ // Gets a list of active requests (can be used by tests to validate that the // correct request has been issued). - std::vector<PendingRequest> GetPendingRequests(); + std::vector<FakeOAuth2AccessTokenManager::PendingRequest> + GetPendingRequests(); // Helper routines to issue tokens for pending requests. void IssueAllTokensForAccount(const std::string& account_id, @@ -95,9 +83,7 @@ void IssueErrorForAllPendingRequests(const GoogleServiceAuthError& error); - void set_auto_post_fetch_response_on_message_loop(bool auto_post_response) { - auto_post_fetch_response_on_message_loop_ = auto_post_response; - } + void set_auto_post_fetch_response_on_message_loop(bool auto_post_response); protected: // OAuth2TokenService overrides. @@ -120,26 +106,7 @@ const std::string& access_token) override; private: - // Helper function to complete pending requests - if |all_scopes| is true, - // then all pending requests are completed, otherwise, only those requests - // matching |scopes| are completed. If |account_id| is empty, then pending - // requests for all accounts are completed, otherwise only requests for the - // given account. - void CompleteRequests( - const std::string& account_id, - bool all_scopes, - const OAuth2AccessTokenManager::ScopeSet& scopes, - const GoogleServiceAuthError& error, - const OAuth2AccessTokenConsumer::TokenResponse& token_response); - - std::vector<PendingRequest> pending_requests_; - - // If true, then this fake service will post responses to - // |FetchOAuth2Token| on the current run loop. There is no need to call - // |IssueTokenForScope| in this case. - bool auto_post_fetch_response_on_message_loop_; - - base::WeakPtrFactory<FakeProfileOAuth2TokenService> weak_ptr_factory_; + FakeOAuth2AccessTokenManager* GetFakeAccessTokenManager(); DISALLOW_COPY_AND_ASSIGN(FakeProfileOAuth2TokenService); };
diff --git a/components/signin/ios/browser/device_accounts_provider.h b/components/signin/ios/browser/device_accounts_provider.h index 1d9268ac..522ee3f 100644 --- a/components/signin/ios/browser/device_accounts_provider.h +++ b/components/signin/ios/browser/device_accounts_provider.h
@@ -47,9 +47,8 @@ std::string email; }; - typedef base::Callback< - void(NSString* token, NSDate* expiration, NSError* error)> - AccessTokenCallback; + using AccessTokenCallback = base::OnceCallback< + void(NSString* token, NSDate* expiration, NSError* error)>; DeviceAccountsProvider() {} virtual ~DeviceAccountsProvider() {} @@ -62,7 +61,7 @@ virtual void GetAccessToken(const std::string& gaia_id, const std::string& client_id, const std::set<std::string>& scopes, - const AccessTokenCallback& callback); + AccessTokenCallback callback); // Returns the authentication error category of |error| associated with the // account with id |gaia_id|.
diff --git a/components/signin/ios/browser/device_accounts_provider.mm b/components/signin/ios/browser/device_accounts_provider.mm index 38d9c60..df675fd1 100644 --- a/components/signin/ios/browser/device_accounts_provider.mm +++ b/components/signin/ios/browser/device_accounts_provider.mm
@@ -13,11 +13,10 @@ return std::vector<DeviceAccountsProvider::AccountInfo>(); } -void DeviceAccountsProvider::GetAccessToken( - const std::string& gaia_id, - const std::string& client_id, - const std::set<std::string>& scopes, - const AccessTokenCallback& callback) {} +void DeviceAccountsProvider::GetAccessToken(const std::string& gaia_id, + const std::string& client_id, + const std::set<std::string>& scopes, + AccessTokenCallback callback) {} AuthenticationErrorCategory DeviceAccountsProvider::GetAuthenticationErrorCategory(
diff --git a/components/signin/ios/browser/fake_device_accounts_provider.h b/components/signin/ios/browser/fake_device_accounts_provider.h index 15342a8e..a93947d 100644 --- a/components/signin/ios/browser/fake_device_accounts_provider.h +++ b/components/signin/ios/browser/fake_device_accounts_provider.h
@@ -23,7 +23,7 @@ void GetAccessToken(const std::string& account_id, const std::string& client_id, const std::set<std::string>& scopes, - const AccessTokenCallback& callback) override; + AccessTokenCallback callback) override; std::vector<AccountInfo> GetAllAccounts() const override; AuthenticationErrorCategory GetAuthenticationErrorCategory( const std::string& gaia_id, @@ -38,7 +38,7 @@ void IssueAccessTokenErrorForAllRequests(); private: - typedef std::pair<std::string, AccessTokenCallback> AccessTokenRequest; + using AccessTokenRequest = std::pair<std::string, AccessTokenCallback>; std::vector<AccountInfo> accounts_; std::vector<AccessTokenRequest> requests_;
diff --git a/components/signin/ios/browser/fake_device_accounts_provider.mm b/components/signin/ios/browser/fake_device_accounts_provider.mm index d313875..63bcbb0e 100644 --- a/components/signin/ios/browser/fake_device_accounts_provider.mm +++ b/components/signin/ios/browser/fake_device_accounts_provider.mm
@@ -21,8 +21,8 @@ const std::string& account_id, const std::string& client_id, const std::set<std::string>& scopes, - const AccessTokenCallback& callback) { - requests_.push_back(AccessTokenRequest(account_id, callback)); + AccessTokenCallback callback) { + requests_.push_back(AccessTokenRequest(account_id, std::move(callback))); } std::vector<DeviceAccountsProvider::AccountInfo> @@ -45,25 +45,21 @@ } void FakeDeviceAccountsProvider::IssueAccessTokenForAllRequests() { - for (auto i = requests_.begin(); i != requests_.end(); ++i) { - std::string account_id = i->first; - AccessTokenCallback callback = i->second; + for (auto& pair : requests_) { NSString* access_token = [NSString - stringWithFormat:@"fake_access_token [account=%s]", account_id.c_str()]; + stringWithFormat:@"fake_access_token [account=%s]", pair.first.c_str()]; NSDate* one_hour_from_now = [NSDate dateWithTimeIntervalSinceNow:3600]; - callback.Run(access_token, one_hour_from_now, nil); + std::move(pair.second).Run(access_token, one_hour_from_now, nil); } requests_.clear(); } void FakeDeviceAccountsProvider::IssueAccessTokenErrorForAllRequests() { - for (auto i = requests_.begin(); i != requests_.end(); ++i) { - std::string account_id = i->first; - AccessTokenCallback callback = i->second; + for (auto& pair : requests_) { NSError* error = [[NSError alloc] initWithDomain:@"fake_access_token_error" code:-1 userInfo:nil]; - callback.Run(nil, nil, error); + std::move(pair.second).Run(nil, nil, error); } requests_.clear(); }
diff --git a/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.mm b/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.mm index 5f6da62..f53294b 100644 --- a/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.mm +++ b/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.mm
@@ -118,8 +118,8 @@ std::set<std::string> scopes_set(scopes.begin(), scopes.end()); provider_->GetAccessToken( account_.gaia, client_id, scopes_set, - base::Bind(&SSOAccessTokenFetcher::OnAccessTokenResponse, - weak_factory_.GetWeakPtr())); + base::BindOnce(&SSOAccessTokenFetcher::OnAccessTokenResponse, + weak_factory_.GetWeakPtr())); } void SSOAccessTokenFetcher::CancelRequest() {
diff --git a/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.cc b/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.cc index e10618a..523cdbbb 100644 --- a/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.cc +++ b/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.cc
@@ -9,9 +9,7 @@ #include "base/bind.h" #include "base/callback.h" #include "base/memory/ptr_util.h" -#include "base/metrics/histogram_macros.h" #include "components/subresource_filter/content/browser/async_document_subresource_filter.h" -#include "components/subresource_filter/core/common/time_measurements.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" @@ -95,13 +93,12 @@ // finish, or start a new check now if there was no previous speculative // check. if (async_filter_ && async_filter_->has_activation_state()) { - LogDelayMetrics(base::TimeDelta::FromMilliseconds(0)); if (navigation_handle()->IsInMainFrame()) UpdateWithMoreAccurateState(); return content::NavigationThrottle::PROCEED; } - DCHECK(!defer_timer_); - defer_timer_ = std::make_unique<base::ElapsedTimer>(); + DCHECK(!deferred_); + deferred_ = true; if (!async_filter_) { DCHECK(navigation_handle()->IsInMainFrame()); CheckActivationState(); @@ -138,8 +135,7 @@ void ActivationStateComputingNavigationThrottle::OnActivationStateComputed( mojom::ActivationState state) { - if (defer_timer_) { - LogDelayMetrics(defer_timer_->Elapsed()); + if (deferred_) { if (navigation_handle()->IsInMainFrame()) UpdateWithMoreAccurateState(); Resume(); @@ -156,20 +152,6 @@ async_filter_->UpdateWithMoreAccurateState(*parent_activation_state_); } -void ActivationStateComputingNavigationThrottle::LogDelayMetrics( - base::TimeDelta delay) const { - UMA_HISTOGRAM_CUSTOM_MICRO_TIMES( - "SubresourceFilter.DocumentLoad.ActivationComputingDelay", delay, - base::TimeDelta::FromMicroseconds(1), base::TimeDelta::FromSeconds(10), - 50); - if (navigation_handle()->IsInMainFrame()) { - UMA_HISTOGRAM_CUSTOM_MICRO_TIMES( - "SubresourceFilter.DocumentLoad.ActivationComputingDelay.MainFrame", - delay, base::TimeDelta::FromMicroseconds(1), - base::TimeDelta::FromSeconds(10), 50); - } -} - AsyncDocumentSubresourceFilter* ActivationStateComputingNavigationThrottle::filter() const { // TODO(csharrison): This should not really be necessary, as we should be
diff --git a/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.h b/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.h index fc89ea4..20ba9abb 100644 --- a/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.h +++ b/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.h
@@ -10,8 +10,6 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/optional.h" -#include "base/time/time.h" -#include "base/timer/elapsed_timer.h" #include "components/subresource_filter/content/browser/verified_ruleset_dealer.h" #include "components/subresource_filter/core/mojom/subresource_filter.mojom.h" #include "content/public/browser/navigation_throttle.h" @@ -97,8 +95,6 @@ // This must be called at the end of the WillProcessResponse stage. void UpdateWithMoreAccurateState(); - void LogDelayMetrics(base::TimeDelta delay) const; - ActivationStateComputingNavigationThrottle( content::NavigationHandle* navigation_handle, const base::Optional<mojom::ActivationState> parent_activation_state, @@ -113,9 +109,8 @@ // nullptr until NotifyPageActivationWithRuleset is called. VerifiedRuleset::Handle* ruleset_handle_; - // Will be set when DEFER is called in WillProcessResponse. If nullptr, not - // deferred. - std::unique_ptr<base::ElapsedTimer> defer_timer_; + // Will be set to true when DEFER is called in WillProcessResponse. + bool deferred_ = false; // Will become true when the throttle manager reaches ReadyToCommitNavigation. // Makes sure a caller cannot take ownership of the subresource filter unless
diff --git a/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle_unittest.cc b/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle_unittest.cc index 27282df..eeb44643 100644 --- a/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle_unittest.cc +++ b/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle_unittest.cc
@@ -483,45 +483,6 @@ EXPECT_TRUE(state.generic_blocking_rules_disabled); } -TEST_P(ActivationStateComputingThrottleSubFrameTest, DelayMetrics) { - base::HistogramTester histogram_tester; - NavigateAndCommitMainFrameWithPageActivationState( - GURL("http://example.test/"), mojom::ActivationLevel::kEnabled); - mojom::ActivationState state = last_activation_state(); - EXPECT_EQ(mojom::ActivationLevel::kEnabled, state.activation_level); - EXPECT_FALSE(state.filtering_disabled_for_document); - - const char kActivationDelay[] = - "SubresourceFilter.DocumentLoad.ActivationComputingDelay"; - const char kActivationDelayMainFrame[] = - "SubresourceFilter.DocumentLoad.ActivationComputingDelay.MainFrame"; - histogram_tester.ExpectTotalCount(kActivationDelay, 1); - histogram_tester.ExpectTotalCount(kActivationDelayMainFrame, 1); - - // Subframe activation should not log main frame metrics. - CreateSubframeAndInitTestNavigation(GURL("http://example.test/"), - last_committed_frame_host(), - last_activation_state()); - SimulateStartAndExpectToProceed(); - SimulateCommitAndExpectToProceed(); - histogram_tester.ExpectTotalCount(kActivationDelay, 2); - histogram_tester.ExpectTotalCount(kActivationDelayMainFrame, 1); - - // No page activation should imply no delay. - CreateTestNavigationForMainFrame(GURL("http://example.test2/")); - SimulateStartAndExpectToProceed(); - SimulateCommitAndExpectToProceed(); - - state = last_activation_state(); - EXPECT_EQ(dryrun_speculation() ? mojom::ActivationLevel::kDryRun - : mojom::ActivationLevel::kDisabled, - state.activation_level); - int extra_activation = dryrun_speculation() ? 1 : 0; - histogram_tester.ExpectTotalCount(kActivationDelay, 2 + extra_activation); - histogram_tester.ExpectTotalCount(kActivationDelayMainFrame, - 1 + extra_activation); -} - TEST_P(ActivationStateComputingThrottleSubFrameTest, Speculation) { // Use the activation performance metric as a proxy for how many times // activation computation occurred.
diff --git a/components/translate/core/browser/translate_manager.cc b/components/translate/core/browser/translate_manager.cc index 46fa3d2..8a83711 100644 --- a/components/translate/core/browser/translate_manager.cc +++ b/components/translate/core/browser/translate_manager.cc
@@ -16,6 +16,7 @@ #include "base/strings/string_split.h" #include "base/strings/stringprintf.h" #include "base/time/time.h" +#include "build/build_config.h" #include "components/language/core/browser/language_model.h" #include "components/language/core/common/language_experiments.h" #include "components/language/core/common/language_util.h" @@ -282,13 +283,12 @@ TranslateErrors::IDENTICAL_LANGUAGES, triggered_from_menu); NotifyTranslateError(TranslateErrors::IDENTICAL_LANGUAGES); return; - } else { - // Trigger the "translating now" UI. - translate_client_->ShowTranslateUI( - translate::TRANSLATE_STEP_TRANSLATING, source_lang, target_lang, - TranslateErrors::NONE, triggered_from_menu); } + translate_client_->ShowTranslateUI( + translate::TRANSLATE_STEP_TRANSLATING, source_lang, target_lang, + TranslateErrors::NONE, triggered_from_menu); + TranslateScript* script = TranslateDownloadManager::GetInstance()->script(); DCHECK(script != nullptr);
diff --git a/components/viz/service/display/display.cc b/components/viz/service/display/display.cc index 766c36b..ca61367 100644 --- a/components/viz/service/display/display.cc +++ b/components/viz/service/display/display.cc
@@ -10,6 +10,7 @@ #include "base/debug/dump_without_crashing.h" #include "base/metrics/histogram_macros.h" #include "base/numerics/checked_math.h" +#include "base/optional.h" #include "base/timer/elapsed_timer.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" @@ -486,6 +487,7 @@ bool should_draw = have_copy_requests || (have_damage && size_matches); client_->DisplayWillDrawAndSwap(should_draw, &frame.render_pass_list); + base::Optional<base::ElapsedTimer> draw_timer; if (should_draw) { TRACE_EVENT_ASYNC_STEP_INTO0("viz,benchmark", "Graphics.Pipeline.DrawAndSwap", @@ -506,16 +508,16 @@ DCHECK(!disable_image_filtering); } - base::ElapsedTimer draw_timer; + draw_timer.emplace(); renderer_->DecideRenderPassAllocationsForFrame(frame.render_pass_list); renderer_->DrawFrame(&frame.render_pass_list, device_scale_factor_, current_surface_size); if (software_renderer_) { UMA_HISTOGRAM_COUNTS_1M("Compositing.DirectRenderer.Software.DrawFrameUs", - draw_timer.Elapsed().InMicroseconds()); + draw_timer->Elapsed().InMicroseconds()); } else { UMA_HISTOGRAM_COUNTS_1M("Compositing.DirectRenderer.GL.DrawFrameUs", - draw_timer.Elapsed().InMicroseconds()); + draw_timer->Elapsed().InMicroseconds()); } } else { TRACE_EVENT_INSTANT0("viz", "Draw skipped.", TRACE_EVENT_SCOPE_THREAD); @@ -526,6 +528,7 @@ TRACE_EVENT_ASYNC_STEP_INTO0("viz,benchmark", "Graphics.Pipeline.DrawAndSwap", swapped_trace_id_, "Swap"); + draw_start_times_pending_swap_ack_.emplace_back(draw_timer->Begin()); swapped_since_resize_ = true; if (scheduler_) { @@ -597,6 +600,8 @@ } void Display::DidReceiveSwapBuffersAck(const gfx::SwapTimings& timings) { + DCHECK(!draw_start_times_pending_swap_ack_.empty()); + if (scheduler_) { scheduler_->DidReceiveSwapBuffersAck(); if (no_pending_swaps_callback_ && scheduler_->pending_swaps() == 0) @@ -616,8 +621,16 @@ // the swap was triggered. Note that not all output surfaces provide timing // information, hence the check for a valid swap_start. const auto swap_time = pending_presented_callbacks_.front().first; - if (!timings.swap_start.is_null()) + if (!timings.swap_start.is_null()) { DCHECK_LE(swap_time, timings.swap_start); + base::TimeDelta delta = + timings.swap_start - draw_start_times_pending_swap_ack_.front(); + UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES( + "Compositing.Display.DrawToSwapUs", delta, + base::TimeDelta::FromMicroseconds(100), + base::TimeDelta::FromMilliseconds(100), 50); + } + draw_start_times_pending_swap_ack_.pop_front(); } void Display::DidReceiveTextureInUseResponses(
diff --git a/components/viz/service/display/display.h b/components/viz/service/display/display.h index 289e775..cf97b87f 100644 --- a/components/viz/service/display/display.h +++ b/components/viz/service/display/display.h
@@ -211,6 +211,8 @@ int64_t swapped_trace_id_ = 0; int64_t last_presented_trace_id_ = 0; + base::circular_deque<base::TimeTicks> draw_start_times_pending_swap_ack_; + DISALLOW_COPY_AND_ASSIGN(Display); };
diff --git a/components/viz/service/display_embedder/buffer_queue.cc b/components/viz/service/display_embedder/buffer_queue.cc index 83545a7..e874cd7 100644 --- a/components/viz/service/display_embedder/buffer_queue.cc +++ b/components/viz/service/display_embedder/buffer_queue.cc
@@ -137,40 +137,6 @@ return true; } -unsigned BufferQueue::RecreateBuffers() { - // We need to recreate the buffers, for whatever reason the old ones are not - // presentable on the device anymore. - // Unused buffers can be freed directly, they will be re-allocated as needed. - // Any in flight, current or displayed surface must be replaced. - available_surfaces_.clear(); - - // Recreate all in-flight surfaces and put the recreated copies in the queue. - for (auto& surface : in_flight_surfaces_) - surface = RecreateBuffer(std::move(surface)); - - current_surface_ = RecreateBuffer(std::move(current_surface_)); - displayed_surface_ = RecreateBuffer(std::move(displayed_surface_)); - - return current_surface_ ? current_surface_->texture : 0u; -} - -std::unique_ptr<BufferQueue::AllocatedSurface> BufferQueue::RecreateBuffer( - std::unique_ptr<AllocatedSurface> surface) { - if (!surface) - return nullptr; - - std::unique_ptr<AllocatedSurface> new_surface(GetNextSurface()); - if (!new_surface) - return nullptr; - - new_surface->damage = surface->damage; - - // Copy the entire texture. - CopyBufferDamage(new_surface->texture, surface->texture, gfx::Rect(), - gfx::Rect(size_)); - return new_surface; -} - void BufferQueue::PageFlipComplete() { DCHECK(!in_flight_surfaces_.empty()); if (in_flight_surfaces_.front()) { @@ -227,7 +193,7 @@ } // We don't want to allow anything more than triple buffering. - DCHECK_LT(allocated_count_, 4U); + DCHECK_LT(allocated_count_, 3U); std::unique_ptr<gfx::GpuMemoryBuffer> buffer( gpu_memory_buffer_manager_->CreateGpuMemoryBuffer( size_, format_, gfx::BufferUsage::SCANOUT, surface_handle_));
diff --git a/components/viz/service/display_embedder/buffer_queue.h b/components/viz/service/display_embedder/buffer_queue.h index 2abf9dca..4baa6acb 100644 --- a/components/viz/service/display_embedder/buffer_queue.h +++ b/components/viz/service/display_embedder/buffer_queue.h
@@ -66,6 +66,10 @@ // be marked as displayed. void PageFlipComplete(); + // Destroys all the buffers (useful if for some reason, the buffers are no + // longer presentable). + void FreeAllSurfaces(); + // Frees all buffers if |size|, |color_space|, or |use_stencil| correspond to // a change of state. Otherwise, it's a no-op. Returns true if there was a // change of state, false otherwise. @@ -74,11 +78,6 @@ const gfx::ColorSpace& color_space, bool use_stencil); - // Recreates all the buffers (useful if for some reason, the old buffers are - // no longer presentable). Returns the name of the texture corresponding to - // the current buffer or 0u if there is no current buffer. - unsigned RecreateBuffers(); - // Copies the damage from the most recently swapped available buffer into the // current buffer. void CopyDamageForCurrentSurface(const gfx::Rect& damage); @@ -107,8 +106,6 @@ gfx::Rect damage; // This is the damage for this frame from the previous. }; - void FreeAllSurfaces(); - void FreeSurfaceResources(AllocatedSurface* surface); // Copy everything that is in |copy_rect|, except for what is in @@ -123,9 +120,6 @@ // Return a surface, available to be drawn into. std::unique_ptr<AllocatedSurface> GetNextSurface(); - std::unique_ptr<AllocatedSurface> RecreateBuffer( - std::unique_ptr<AllocatedSurface> surface); - gpu::gles2::GLES2Interface* const gl_; gfx::Size size_; gfx::ColorSpace color_space_;
diff --git a/components/viz/service/display_embedder/buffer_queue_unittest.cc b/components/viz/service/display_embedder/buffer_queue_unittest.cc index c4602db..edd31791 100644 --- a/components/viz/service/display_embedder/buffer_queue_unittest.cc +++ b/components/viz/service/display_embedder/buffer_queue_unittest.cc
@@ -586,79 +586,6 @@ gpu_memory_buffer_manager_->set_color_space_count()); } -TEST_F(BufferQueueMockedContextTest, RecreateBuffers) { - // This setup is to easily get one frame in each of: - // - currently bound for drawing. - // - in flight to GPU. - // - currently displayed. - // - free frame. - // This tests buffers in all states. - // Bind/swap pushes frames into the in flight list, then the PageFlipComplete - // calls pull one frame into displayed and another into the free list. - EXPECT_TRUE( - output_surface_->Reshape(screen_size, 1.0f, gfx::ColorSpace(), false)); - // TODO(andrescj): fix a bunch of uninteresting mock function calls. - unsigned stencil; - EXPECT_GT(output_surface_->GetCurrentBuffer(&stencil), 0u); - SwapBuffers(); - EXPECT_GT(output_surface_->GetCurrentBuffer(&stencil), 0u); - SwapBuffers(); - EXPECT_GT(output_surface_->GetCurrentBuffer(&stencil), 0u); - SwapBuffers(); - EXPECT_GT(output_surface_->GetCurrentBuffer(&stencil), 0u); - output_surface_->PageFlipComplete(); - output_surface_->PageFlipComplete(); - // We should have one buffer in each possible state right now, including one - // being drawn to. - ASSERT_EQ(1U, in_flight_surfaces().size()); - ASSERT_EQ(1U, available_surfaces().size()); - EXPECT_TRUE(displayed_frame()); - EXPECT_TRUE(current_frame()); - - auto* current = current_frame(); - auto* displayed = displayed_frame(); - auto* in_flight = in_flight_surfaces().front().get(); - auto* available = available_surfaces().front().get(); - - // Expect all 4 images to be destroyed, 3 of the existing textures to be - // copied from and 3 new images to be created. - EXPECT_CALL(*context_, - CreateImageCHROMIUM(_, screen_size.width(), screen_size.height(), - kBufferQueueInternalformat)) - .Times(3); - Expectation copy1 = EXPECT_CALL(*mock_output_surface_, - CopyBufferDamage(_, displayed->texture, _, _)) - .Times(1); - Expectation copy2 = EXPECT_CALL(*mock_output_surface_, - CopyBufferDamage(_, current->texture, _, _)) - .Times(1); - Expectation copy3 = EXPECT_CALL(*mock_output_surface_, - CopyBufferDamage(_, in_flight->texture, _, _)) - .Times(1); - - EXPECT_CALL(*context_, DestroyImageCHROMIUM(displayed->image)) - .Times(1) - .After(copy1); - EXPECT_CALL(*context_, DestroyImageCHROMIUM(current->image)) - .Times(1) - .After(copy2); - EXPECT_CALL(*context_, DestroyImageCHROMIUM(in_flight->image)) - .Times(1) - .After(copy3); - EXPECT_CALL(*context_, DestroyImageCHROMIUM(available->image)).Times(1); - - output_surface_->RecreateBuffers(); - testing::Mock::VerifyAndClearExpectations(context_); - testing::Mock::VerifyAndClearExpectations(mock_output_surface_); - - // All free buffers should be destroyed, the remaining buffers should all - // be replaced but still valid. - EXPECT_EQ(1U, in_flight_surfaces().size()); - EXPECT_EQ(0U, available_surfaces().size()); - EXPECT_TRUE(displayed_frame()); - EXPECT_TRUE(current_frame()); -} - TEST_F(BufferQueueTest, AllocateFails) { EXPECT_TRUE( output_surface_->Reshape(screen_size, 1.0f, gfx::ColorSpace(), false));
diff --git a/components/viz/service/display_embedder/gl_output_surface_buffer_queue.cc b/components/viz/service/display_embedder/gl_output_surface_buffer_queue.cc index 8ab97f3e..01db6191 100644 --- a/components/viz/service/display_embedder/gl_output_surface_buffer_queue.cc +++ b/components/viz/service/display_embedder/gl_output_surface_buffer_queue.cc
@@ -144,9 +144,7 @@ if (response.result == gfx::SwapResult::SWAP_NAK_RECREATE_BUFFERS) { // Even through the swap failed, this is a fixable error so we can pretend // it succeeded to the rest of the system. - unsigned current_surface_texture = buffer_queue_->RecreateBuffers(); - if (current_surface_texture) - BindFramebuffer(); + buffer_queue_->FreeAllSurfaces(); force_swap = true; }
diff --git a/components/viz/service/display_embedder/skia_output_device.cc b/components/viz/service/display_embedder/skia_output_device.cc index a07b5b1..5d778e4 100644 --- a/components/viz/service/display_embedder/skia_output_device.cc +++ b/components/viz/service/display_embedder/skia_output_device.cc
@@ -21,11 +21,10 @@ gfx::SwapResponse SkiaOutputDevice::PostSubBuffer( const gfx::Rect& rect, - const GrBackendSemaphore& semaphore, BufferPresentedCallback feedback) { NOTREACHED(); StartSwapBuffers(std::move(feedback)); - return FinishSwapBuffers(gfx::SwapResult::SWAP_FAILED); + return FinishSwapBuffers(gfx::SwapResult::SWAP_FAILED, gfx::Size()); } void SkiaOutputDevice::SetDrawRectangle(const gfx::Rect& draw_rectangle) {} @@ -41,13 +40,13 @@ params_->swap_response.timings.swap_start = base::TimeTicks::Now(); } -gfx::SwapResponse SkiaOutputDevice::FinishSwapBuffers(gfx::SwapResult result) { +gfx::SwapResponse SkiaOutputDevice::FinishSwapBuffers(gfx::SwapResult result, + const gfx::Size& size) { DCHECK(params_); params_->swap_response.result = result; params_->swap_response.timings.swap_end = base::TimeTicks::Now(); - did_swap_buffer_complete_callback_.Run( - *params_, gfx::Size(draw_surface_->width(), draw_surface_->height())); + did_swap_buffer_complete_callback_.Run(*params_, size); if (feedback_) { std::move(*feedback_)
diff --git a/components/viz/service/display_embedder/skia_output_device.h b/components/viz/service/display_embedder/skia_output_device.h index 0c49d762..75c91d9 100644 --- a/components/viz/service/display_embedder/skia_output_device.h +++ b/components/viz/service/display_embedder/skia_output_device.h
@@ -11,9 +11,9 @@ #include "components/viz/service/display/output_surface.h" #include "gpu/command_buffer/common/swap_buffers_complete_params.h" #include "third_party/skia/include/core/SkRefCnt.h" +#include "third_party/skia/src/gpu/GrSemaphore.h" #include "ui/gfx/swap_result.h" -class GrBackendSemaphore; class SkSurface; namespace gfx { @@ -27,6 +27,29 @@ class SkiaOutputDevice { public: + // A helper class for defining a BeginPaint() and EndPaint() scope. + class ScopedPaint { + public: + explicit ScopedPaint(SkiaOutputDevice* device) + : device_(device), sk_surface_(device->BeginPaint()) { + DCHECK(sk_surface_); + } + ~ScopedPaint() { device_->EndPaint(semaphore_); } + + SkSurface* sk_surface() const { return sk_surface_; } + void set_semaphore(const GrBackendSemaphore& semaphore) { + DCHECK(!semaphore_.isInitialized()); + semaphore_ = semaphore; + } + + private: + SkiaOutputDevice* const device_; + SkSurface* const sk_surface_; + GrBackendSemaphore semaphore_; + + DISALLOW_COPY_AND_ASSIGN(ScopedPaint); + }; + using BufferPresentedCallback = base::OnceCallback<void(const gfx::PresentationFeedback& feedback)>; using DidSwapBufferCompleteCallback = @@ -37,20 +60,15 @@ DidSwapBufferCompleteCallback did_swap_buffer_complete_callback); virtual ~SkiaOutputDevice(); - // SkSurface that can be drawn to. - SkSurface* draw_surface() const { return draw_surface_.get(); } - // Changes the size of draw surface and invalidates it's contents. virtual void Reshape(const gfx::Size& size, float device_scale_factor, const gfx::ColorSpace& color_space, bool has_alpha) = 0; - // Presents DrawSurface. - virtual gfx::SwapResponse SwapBuffers(const GrBackendSemaphore& semaphore, - BufferPresentedCallback feedback) = 0; + // Presents the back buffer. + virtual gfx::SwapResponse SwapBuffers(BufferPresentedCallback feedback) = 0; virtual gfx::SwapResponse PostSubBuffer(const gfx::Rect& rect, - const GrBackendSemaphore& semaphore, BufferPresentedCallback feedback); // Set the rectangle that will be drawn into on the surface. @@ -69,13 +87,23 @@ bool need_swap_semaphore() const { return need_swap_semaphore_; } protected: - void StartSwapBuffers(base::Optional<BufferPresentedCallback> feedback); - gfx::SwapResponse FinishSwapBuffers(gfx::SwapResult result); + // Begin paint the back buffer. + virtual SkSurface* BeginPaint() = 0; - sk_sp<SkSurface> draw_surface_; + // End paint the back buffer. + virtual void EndPaint(const GrBackendSemaphore& semaphore) = 0; + + // Helper method for SwapBuffers() and PostSubBuffer(). It should be called + // at the beginning of SwapBuffers() and PostSubBuffer() implementations + void StartSwapBuffers(base::Optional<BufferPresentedCallback> feedback); + + // Helper method for SwapBuffers() and PostSubBuffer(). It should be called + // at the end of SwapBuffers() and PostSubBuffer() implementations + gfx::SwapResponse FinishSwapBuffers(gfx::SwapResult result, + const gfx::Size& size); + OutputSurface::Capabilities capabilities_; - private: const bool need_swap_semaphore_; uint64_t swap_id_ = 0; DidSwapBufferCompleteCallback did_swap_buffer_complete_callback_;
diff --git a/components/viz/service/display_embedder/skia_output_device_gl.cc b/components/viz/service/display_embedder/skia_output_device_gl.cc index ad4d1cfb7..d31721a8 100644 --- a/components/viz/service/display_embedder/skia_output_device_gl.cc +++ b/components/viz/service/display_embedder/skia_output_device_gl.cc
@@ -94,28 +94,30 @@ : kBottomLeft_GrSurfaceOrigin; auto color_type = supports_alpha_ ? kRGBA_8888_SkColorType : kRGB_888x_SkColorType; - draw_surface_ = SkSurface::MakeFromBackendRenderTarget( + sk_surface_ = SkSurface::MakeFromBackendRenderTarget( gr_context_, render_target, origin, color_type, color_space.ToSkColorSpace(), &surface_props); - DCHECK(draw_surface_); + DCHECK(sk_surface_); } gfx::SwapResponse SkiaOutputDeviceGL::SwapBuffers( - const GrBackendSemaphore& semaphore, BufferPresentedCallback feedback) { // TODO(backer): Support SwapBuffersAsync StartSwapBuffers({}); - return FinishSwapBuffers(gl_surface_->SwapBuffers(std::move(feedback))); + return FinishSwapBuffers( + gl_surface_->SwapBuffers(std::move(feedback)), + gfx::Size(sk_surface_->width(), sk_surface_->height())); } gfx::SwapResponse SkiaOutputDeviceGL::PostSubBuffer( const gfx::Rect& rect, - const GrBackendSemaphore& semaphore, BufferPresentedCallback feedback) { // TODO(backer): Support PostSubBufferAsync StartSwapBuffers({}); - return FinishSwapBuffers(gl_surface_->PostSubBuffer( - rect.x(), rect.y(), rect.width(), rect.height(), std::move(feedback))); + return FinishSwapBuffers( + gl_surface_->PostSubBuffer(rect.x(), rect.y(), rect.width(), + rect.height(), std::move(feedback)), + gfx::Size(sk_surface_->width(), sk_surface_->height())); } void SkiaOutputDeviceGL::SetDrawRectangle(const gfx::Rect& draw_rectangle) { @@ -130,6 +132,13 @@ gl_surface_->SetBackbufferAllocation(false); } +SkSurface* SkiaOutputDeviceGL::BeginPaint() { + DCHECK(sk_surface_); + return sk_surface_.get(); +} + +void SkiaOutputDeviceGL::EndPaint(const GrBackendSemaphore& semaphore) {} + #if defined(OS_WIN) void SkiaOutputDeviceGL::DidCreateAcceleratedSurfaceChildWindow( gpu::SurfaceHandle parent_window,
diff --git a/components/viz/service/display_embedder/skia_output_device_gl.h b/components/viz/service/display_embedder/skia_output_device_gl.h index 2263b8b..e640e36 100644 --- a/components/viz/service/display_embedder/skia_output_device_gl.h +++ b/components/viz/service/display_embedder/skia_output_device_gl.h
@@ -53,14 +53,14 @@ float device_scale_factor, const gfx::ColorSpace& color_space, bool has_alpha) override; - gfx::SwapResponse SwapBuffers(const GrBackendSemaphore& semaphore, - BufferPresentedCallback feedback) override; + gfx::SwapResponse SwapBuffers(BufferPresentedCallback feedback) override; gfx::SwapResponse PostSubBuffer(const gfx::Rect& rect, - const GrBackendSemaphore& semaphore, BufferPresentedCallback feedback) override; void SetDrawRectangle(const gfx::Rect& draw_rectangle) override; void EnsureBackbuffer() override; void DiscardBackbuffer() override; + SkSurface* BeginPaint() override; + void EndPaint(const GrBackendSemaphore& semaphore) override; // gpu::ImageTransportSurfaceDelegate implementation: #if defined(OS_WIN) @@ -82,6 +82,8 @@ scoped_refptr<gl::GLSurface> gl_surface_; GrContext* gr_context_ = nullptr; + sk_sp<SkSurface> sk_surface_; + bool supports_alpha_ = false; base::WeakPtrFactory<SkiaOutputDeviceGL> weak_ptr_factory_{this};
diff --git a/components/viz/service/display_embedder/skia_output_device_offscreen.cc b/components/viz/service/display_embedder/skia_output_device_offscreen.cc index e676c698..8cd89133 100644 --- a/components/viz/service/display_embedder/skia_output_device_offscreen.cc +++ b/components/viz/service/display_embedder/skia_output_device_offscreen.cc
@@ -35,40 +35,40 @@ SkImageInfo::Make(size.width(), size.height(), kRGBA_8888_SkColorType, has_alpha_ ? kPremul_SkAlphaType : kOpaque_SkAlphaType, color_space.ToSkColorSpace()); - draw_surface_ = SkSurface::MakeRenderTarget( + sk_surface_ = SkSurface::MakeRenderTarget( gr_context_, SkBudgeted::kNo, image_info_, 0 /* sampleCount */, capabilities_.flipped_output_surface ? kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin, nullptr /* surfaceProps */); - DCHECK(!!draw_surface_); + DCHECK(!!sk_surface_); // Initialize alpha channel to opaque. if (!has_alpha_) { - auto* canvas = draw_surface_->getCanvas(); + auto* canvas = sk_surface_->getCanvas(); canvas->clear(SkColorSetARGB(255, 0, 0, 0)); } } -gfx::SwapResponse SkiaOutputDeviceOffscreen::PostSubBuffer( - const gfx::Rect& rect, - const GrBackendSemaphore& semaphore, - BufferPresentedCallback feedback) { - return SwapBuffers(semaphore, std::move(feedback)); -} - gfx::SwapResponse SkiaOutputDeviceOffscreen::SwapBuffers( - const GrBackendSemaphore& semaphore, BufferPresentedCallback feedback) { // Reshape should have been called first. - DCHECK(draw_surface_); + DCHECK(sk_surface_); StartSwapBuffers(std::move(feedback)); - return FinishSwapBuffers(gfx::SwapResult::SWAP_ACK); + return FinishSwapBuffers( + gfx::SwapResult::SWAP_ACK, + gfx::Size(sk_surface_->width(), sk_surface_->height())); +} + +gfx::SwapResponse SkiaOutputDeviceOffscreen::PostSubBuffer( + const gfx::Rect& rect, + BufferPresentedCallback feedback) { + return SwapBuffers(std::move(feedback)); } void SkiaOutputDeviceOffscreen::EnsureBackbuffer() { - if (!image_info_.isEmpty() && !draw_surface_) { - draw_surface_ = SkSurface::MakeRenderTarget( + if (!image_info_.isEmpty() && !sk_surface_) { + sk_surface_ = SkSurface::MakeRenderTarget( gr_context_, SkBudgeted::kNo, image_info_, 0 /* sampleCount */, capabilities_.flipped_output_surface ? kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin, @@ -77,7 +77,13 @@ } void SkiaOutputDeviceOffscreen::DiscardBackbuffer() { - draw_surface_.reset(); + sk_surface_.reset(); } +SkSurface* SkiaOutputDeviceOffscreen::BeginPaint() { + return sk_surface_.get(); +} + +void SkiaOutputDeviceOffscreen::EndPaint(const GrBackendSemaphore& semaphore) {} + } // namespace viz
diff --git a/components/viz/service/display_embedder/skia_output_device_offscreen.h b/components/viz/service/display_embedder/skia_output_device_offscreen.h index a1f38d7..bebd366 100644 --- a/components/viz/service/display_embedder/skia_output_device_offscreen.h +++ b/components/viz/service/display_embedder/skia_output_device_offscreen.h
@@ -27,18 +27,18 @@ float device_scale_factor, const gfx::ColorSpace& color_space, bool has_alpha) override; - gfx::SwapResponse SwapBuffers(const GrBackendSemaphore& semaphore, - BufferPresentedCallback feedback) override; + gfx::SwapResponse SwapBuffers(BufferPresentedCallback feedback) override; gfx::SwapResponse PostSubBuffer(const gfx::Rect& rect, - const GrBackendSemaphore& semaphore, - BufferPresentedCallback feedback) override; void EnsureBackbuffer() override; void DiscardBackbuffer() override; + SkSurface* BeginPaint() override; + void EndPaint(const GrBackendSemaphore& semaphore) override; protected: GrContext* const gr_context_; const bool has_alpha_; + sk_sp<SkSurface> sk_surface_; private: SkImageInfo image_info_;
diff --git a/components/viz/service/display_embedder/skia_output_device_vulkan.cc b/components/viz/service/display_embedder/skia_output_device_vulkan.cc index 403f3ca..c9f1f1f 100644 --- a/components/viz/service/display_embedder/skia_output_device_vulkan.cc +++ b/components/viz/service/display_embedder/skia_output_device_vulkan.cc
@@ -32,7 +32,7 @@ } SkiaOutputDeviceVulkan::~SkiaOutputDeviceVulkan() { - scoped_write_.reset(); + DCHECK(!scoped_write_); if (vulkan_surface_) { auto* fence_helper = context_provider_->GetDeviceQueue()->GetFenceHelper(); fence_helper->EnqueueVulkanObjectCleanupForSubmittedWork( @@ -44,75 +44,45 @@ float device_scale_factor, const gfx::ColorSpace& color_space, bool has_alpha) { - if (!vulkan_surface_) - CreateVulkanSurface(); + DCHECK(!scoped_write_); - scoped_write_.reset(); - auto old_size = vulkan_surface_->size(); + uint32_t generation = 0; + if (!vulkan_surface_) { + CreateVulkanSurface(); + } else { + generation = vulkan_surface_->swap_chain_generation(); + } + vulkan_surface_->SetSize(size); - if (vulkan_surface_->size() != old_size) { - // Size has been changed, we need to clear all surfaces which will be - // recreated later. + + if (vulkan_surface_->swap_chain_generation() != generation) { + // swapchain is changed, we need recreate all cached sk surfaces. sk_surfaces_.clear(); sk_surfaces_.resize(vulkan_surface_->GetSwapChain()->num_images()); } - - UpdateDrawSurface(); } gfx::SwapResponse SkiaOutputDeviceVulkan::SwapBuffers( - const GrBackendSemaphore& semaphore, BufferPresentedCallback feedback) { // Reshape should have been called first. DCHECK(vulkan_surface_); - DCHECK(draw_surface_); - DCHECK(scoped_write_); + DCHECK(!scoped_write_); StartSwapBuffers(std::move(feedback)); - auto backend = draw_surface_->getBackendRenderTarget( - SkSurface::kFlushRead_BackendHandleAccess); - GrVkImageInfo vk_image_info; - if (!backend.getVkImageInfo(&vk_image_info)) - NOTREACHED() << "Failed to get the image info."; - scoped_write_->set_image_layout(vk_image_info.fImageLayout); - scoped_write_->SetEndSemaphore(semaphore.vkSemaphore()); - scoped_write_.reset(); - - auto response = FinishSwapBuffers(vulkan_surface_->SwapBuffers()); - UpdateDrawSurface(); - + auto size = vulkan_surface_->size(); + auto response = FinishSwapBuffers(vulkan_surface_->SwapBuffers(), size); return response; } -void SkiaOutputDeviceVulkan::CreateVulkanSurface() { - gfx::AcceleratedWidget accelerated_widget = gfx::kNullAcceleratedWidget; -#if defined(OS_ANDROID) - bool can_be_used_with_surface_control = false; - accelerated_widget = - gpu::GpuSurfaceLookup::GetInstance()->AcquireNativeWidget( - surface_handle_, &can_be_used_with_surface_control); -#else - accelerated_widget = surface_handle_; -#endif - auto vulkan_surface = - context_provider_->GetVulkanImplementation()->CreateViewSurface( - accelerated_widget); - if (!vulkan_surface) - LOG(FATAL) << "Failed to create vulkan surface."; - if (!vulkan_surface->Initialize(context_provider_->GetDeviceQueue(), - gpu::VulkanSurface::FORMAT_RGBA_32)) { - LOG(FATAL) << "Failed to initialize vulkan surface."; - } - vulkan_surface_ = std::move(vulkan_surface); - sk_surfaces_.resize(vulkan_surface_->GetSwapChain()->num_images()); -} - -void SkiaOutputDeviceVulkan::UpdateDrawSurface() { +SkSurface* SkiaOutputDeviceVulkan::BeginPaint() { DCHECK(vulkan_surface_); DCHECK(!scoped_write_); scoped_write_.emplace(vulkan_surface_->GetSwapChain()); - + if (!scoped_write_->success()) { + scoped_write_.reset(); + return nullptr; + } auto& sk_surface = sk_surfaces_[scoped_write_->image_index()]; if (!sk_surface) { @@ -140,11 +110,51 @@ SkSurface::kFlushRead_BackendHandleAccess); backend.setVkImageLayout(scoped_write_->image_layout()); } - GrBackendSemaphore semaphore; - semaphore.initVulkan(scoped_write_->TakeBeginSemaphore()); - auto result = sk_surface->wait(1, &semaphore); - DCHECK(result); - draw_surface_ = sk_surface; + VkSemaphore vk_semaphore = scoped_write_->TakeBeginSemaphore(); + if (vk_semaphore != VK_NULL_HANDLE) { + GrBackendSemaphore semaphore; + semaphore.initVulkan(vk_semaphore); + auto result = sk_surface->wait(1, &semaphore); + DCHECK(result); + } + return sk_surface.get(); +} + +void SkiaOutputDeviceVulkan::EndPaint(const GrBackendSemaphore& semaphore) { + DCHECK(scoped_write_); + + auto& sk_surface = sk_surfaces_[scoped_write_->image_index()]; + auto backend = sk_surface->getBackendRenderTarget( + SkSurface::kFlushRead_BackendHandleAccess); + GrVkImageInfo vk_image_info; + if (!backend.getVkImageInfo(&vk_image_info)) + NOTREACHED() << "Failed to get the image info."; + scoped_write_->set_image_layout(vk_image_info.fImageLayout); + if (semaphore.isInitialized()) + scoped_write_->SetEndSemaphore(semaphore.vkSemaphore()); + scoped_write_.reset(); +} + +void SkiaOutputDeviceVulkan::CreateVulkanSurface() { + gfx::AcceleratedWidget accelerated_widget = gfx::kNullAcceleratedWidget; +#if defined(OS_ANDROID) + bool can_be_used_with_surface_control = false; + accelerated_widget = + gpu::GpuSurfaceLookup::GetInstance()->AcquireNativeWidget( + surface_handle_, &can_be_used_with_surface_control); +#else + accelerated_widget = surface_handle_; +#endif + auto vulkan_surface = + context_provider_->GetVulkanImplementation()->CreateViewSurface( + accelerated_widget); + if (!vulkan_surface) + LOG(FATAL) << "Failed to create vulkan surface."; + if (!vulkan_surface->Initialize(context_provider_->GetDeviceQueue(), + gpu::VulkanSurface::FORMAT_RGBA_32)) { + LOG(FATAL) << "Failed to initialize vulkan surface."; + } + vulkan_surface_ = std::move(vulkan_surface); } } // namespace viz
diff --git a/components/viz/service/display_embedder/skia_output_device_vulkan.h b/components/viz/service/display_embedder/skia_output_device_vulkan.h index cc35ef7..1c45ecb 100644 --- a/components/viz/service/display_embedder/skia_output_device_vulkan.h +++ b/components/viz/service/display_embedder/skia_output_device_vulkan.h
@@ -35,12 +35,13 @@ float device_scale_factor, const gfx::ColorSpace& color_space, bool has_alpha) override; - gfx::SwapResponse SwapBuffers(const GrBackendSemaphore& semaphore, - BufferPresentedCallback feedback) override; + gfx::SwapResponse SwapBuffers(BufferPresentedCallback feedback) override; + SkSurface* BeginPaint() override; + void EndPaint(const GrBackendSemaphore& semaphore) override; private: void CreateVulkanSurface(); - void UpdateDrawSurface(); + void CreateSkSurface(); VulkanContextProvider* const context_provider_;
diff --git a/components/viz/service/display_embedder/skia_output_device_x11.cc b/components/viz/service/display_embedder/skia_output_device_x11.cc index 9f20972..777348d1 100644 --- a/components/viz/service/display_embedder/skia_output_device_x11.cc +++ b/components/viz/service/display_embedder/skia_output_device_x11.cc
@@ -53,16 +53,14 @@ } gfx::SwapResponse SkiaOutputDeviceX11::SwapBuffers( - const GrBackendSemaphore& semaphore, BufferPresentedCallback feedback) { return PostSubBuffer( - gfx::Rect(0, 0, draw_surface_->width(), draw_surface_->height()), - semaphore, std::move(feedback)); + gfx::Rect(0, 0, sk_surface_->width(), sk_surface_->height()), + std::move(feedback)); } gfx::SwapResponse SkiaOutputDeviceX11::PostSubBuffer( const gfx::Rect& rect, - const GrBackendSemaphore& semaphore, BufferPresentedCallback feedback) { StartSwapBuffers(std::move(feedback)); @@ -70,7 +68,7 @@ SkImageInfo::MakeN32(rect.width(), rect.height(), kOpaque_SkAlphaType); DCHECK_GE(pixels_.capacity(), ii.computeMinByteSize()); SkPixmap sk_pixmap(ii, pixels_.data(), ii.minRowBytes()); - bool result = draw_surface_->readPixels(sk_pixmap, rect.x(), rect.y()); + bool result = sk_surface_->readPixels(sk_pixmap, rect.x(), rect.y()); LOG_IF(FATAL, !result) << "Failed to read pixels from offscreen SkSurface."; if (bpp_ == 32 || bpp_ == 16) { @@ -131,7 +129,9 @@ NOTIMPLEMENTED(); } XFlush(display_); - return FinishSwapBuffers(gfx::SwapResult::SWAP_ACK); + return FinishSwapBuffers( + gfx::SwapResult::SWAP_ACK, + gfx::Size(sk_surface_->width(), sk_surface_->height())); } } // namespace viz
diff --git a/components/viz/service/display_embedder/skia_output_device_x11.h b/components/viz/service/display_embedder/skia_output_device_x11.h index f599b7a..a82d72e7 100644 --- a/components/viz/service/display_embedder/skia_output_device_x11.h +++ b/components/viz/service/display_embedder/skia_output_device_x11.h
@@ -27,10 +27,8 @@ float device_scale_factor, const gfx::ColorSpace& color_space, bool has_alpha) override; - gfx::SwapResponse SwapBuffers(const GrBackendSemaphore& semaphore, - BufferPresentedCallback feedback) override; + gfx::SwapResponse SwapBuffers(BufferPresentedCallback feedback) override; gfx::SwapResponse PostSubBuffer(const gfx::Rect& rect, - const GrBackendSemaphore& semaphore, BufferPresentedCallback feedback) override; private:
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc index d0f0cef..6539529 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -621,8 +621,11 @@ output_device_->Reshape(size_, device_scale_factor, color_space, has_alpha); if (characterization) { + // Start a paint temporarily for getting sk surface characterization. + scoped_output_device_paint_.emplace(output_device_.get()); output_sk_surface()->characterize(characterization); DCHECK(characterization->isValid()); + scoped_output_device_paint_.reset(); } } @@ -635,6 +638,12 @@ base::OnceClosure on_finished) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(ddl); + DCHECK(!scoped_output_device_paint_); + + // We do not reset scoped_output_device_paint_ after drawing the ddl until + // SwapBuffers() is called, because we may need access to output_sk_surface() + // for CopyOutput(). + scoped_output_device_paint_.emplace(output_device_.get()); DCHECK(output_sk_surface()); if (!MakeCurrent(true /* need_fbo0 */)) @@ -660,7 +669,8 @@ DCHECK(result); } - output_sk_surface()->draw(ddl.get()); + if (!output_sk_surface()->draw(ddl.get())) + DLOG(ERROR) << "output_sk_surface()->draw() failed."; ddl = nullptr; if (overdraw_ddl) { @@ -704,10 +714,9 @@ return; } if (output_device_->need_swap_semaphore()) { - DCHECK(!swap_buffers_semaphore_.isInitialized()); - swap_buffers_semaphore_ = - scoped_promise_image_access.end_semaphores().back(); - DCHECK(swap_buffers_semaphore_.isInitialized()); + auto& semaphore = scoped_promise_image_access.end_semaphores().back(); + DCHECK(semaphore.isInitialized()); + scoped_output_device_paint_->set_semaphore(std::move(semaphore)); } } ReleaseFenceSyncAndPushTextureUpdates(sync_fence_release); @@ -715,11 +724,14 @@ void SkiaOutputSurfaceImplOnGpu::SwapBuffers(OutputSurfaceFrame frame) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - DCHECK(output_sk_surface()); + DCHECK(scoped_output_device_paint_); + DCHECK(output_device_); + + scoped_output_device_paint_.reset(); + if (!MakeCurrent(!dependency_->IsOffscreen() /* need_fbo0 */)) return; - DCHECK(output_device_); gfx::SwapResponse response; if (frame.sub_buffer_rect && frame.sub_buffer_rect->IsEmpty()) { // TODO(https://crbug.com/898680): Maybe do something for overlays here. @@ -730,13 +742,10 @@ frame.sub_buffer_rect->set_y(size_.height() - frame.sub_buffer_rect->y() - frame.sub_buffer_rect->height()); response = output_device_->PostSubBuffer(*frame.sub_buffer_rect, - swap_buffers_semaphore_, buffer_presented_callback_); } else { - response = output_device_->SwapBuffers(swap_buffers_semaphore_, - buffer_presented_callback_); + response = output_device_->SwapBuffers(buffer_presented_callback_); } - swap_buffers_semaphore_ = GrBackendSemaphore(); for (auto& latency : frame.latency_info) { latency.AddLatencyNumberWithTimestamp( @@ -831,6 +840,8 @@ // TODO(crbug.com/898595): Do this on the GPU instead of CPU with Vulkan. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); bool from_fbo0 = !id; + DCHECK(scoped_output_device_paint_ || !from_fbo0); + if (!MakeCurrent(true /* need_fbo0 */)) return;
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h index a1146d65..f06fa850 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
@@ -175,7 +175,7 @@ bool is_using_vulkan() const { return !!vulkan_context_provider_; } SkSurface* output_sk_surface() const { - return output_device_->draw_surface(); + return scoped_output_device_paint_->sk_surface(); } void CreateFallbackImage(ImageContext* context); @@ -187,9 +187,9 @@ shared_image_representation_factory_; VulkanContextProvider* const vulkan_context_provider_; const RendererSettings renderer_settings_; - DidSwapBufferCompleteCallback did_swap_buffer_complete_callback_; - BufferPresentedCallback buffer_presented_callback_; - ContextLostCallback context_lost_callback_; + const DidSwapBufferCompleteCallback did_swap_buffer_complete_callback_; + const BufferPresentedCallback buffer_presented_callback_; + const ContextLostCallback context_lost_callback_; #if defined(USE_OZONE) // This should outlive gl_surface_ and vulkan_surface_. @@ -205,9 +205,7 @@ size_t max_resource_cache_bytes_ = 0u; std::unique_ptr<SkiaOutputDevice> output_device_; - - // Semaphore for SkiaOutputDevice::SwapBuffers() to wait on. - GrBackendSemaphore swap_buffers_semaphore_; + base::Optional<SkiaOutputDevice::ScopedPaint> scoped_output_device_paint_; // Offscreen surfaces for render passes. It can only be accessed on GPU // thread.
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 53852f76..87618062 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -306,8 +306,8 @@ "../common/service_manager/child_connection.h", "about_url_loader_factory.cc", "about_url_loader_factory.h", - "accessibility/accessibility_tree_formatter.cc", - "accessibility/accessibility_tree_formatter.h", + "accessibility/accessibility_tree_formatter_base.cc", + "accessibility/accessibility_tree_formatter_base.h", "accessibility/accessibility_tree_formatter_blink.cc", "accessibility/accessibility_tree_formatter_blink.h", "accessibility/accessibility_tree_formatter_browser.cc",
diff --git a/content/browser/accessibility/accessibility_tree_formatter.cc b/content/browser/accessibility/accessibility_tree_formatter_base.cc similarity index 78% rename from content/browser/accessibility/accessibility_tree_formatter.cc rename to content/browser/accessibility/accessibility_tree_formatter_base.cc index 81d2a74..6734ee8 100644 --- a/content/browser/accessibility/accessibility_tree_formatter.cc +++ b/content/browser/accessibility/accessibility_tree_formatter_base.cc
@@ -1,8 +1,8 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2019 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/browser/accessibility/accessibility_tree_formatter.h" +#include "content/browser/accessibility/accessibility_tree_formatter_base.h" #include <stddef.h> @@ -32,23 +32,6 @@ } // namespace -AccessibilityTreeFormatter::AccessibilityTreeFormatter() : show_ids_(false) {} - -AccessibilityTreeFormatter::~AccessibilityTreeFormatter() {} - -void AccessibilityTreeFormatter::FormatAccessibilityTree( - BrowserAccessibility* root, - base::string16* contents) { - std::unique_ptr<base::DictionaryValue> dict = BuildAccessibilityTree(root); - RecursiveFormatAccessibilityTree(*(dict.get()), contents); -} - -void AccessibilityTreeFormatter::FormatAccessibilityTree( - const base::DictionaryValue& dict, - base::string16* contents) { - RecursiveFormatAccessibilityTree(dict, contents); -} - base::string16 AccessibilityTreeFormatter::DumpAccessibilityTreeFromManager( BrowserAccessibilityManager* ax_mgr, bool internal) { @@ -67,77 +50,6 @@ return accessibility_contents_utf16; } -std::unique_ptr<base::DictionaryValue> -AccessibilityTreeFormatter::FilterAccessibilityTree( - const base::DictionaryValue& dict) { - auto filtered_dict = std::make_unique<base::DictionaryValue>(); - ProcessTreeForOutput(dict, filtered_dict.get()); - const base::ListValue* children; - if (dict.GetList(kChildrenDictAttr, &children) && !children->empty()) { - const base::DictionaryValue* child_dict; - auto filtered_children = std::make_unique<base::ListValue>(); - for (size_t i = 0; i < children->GetSize(); i++) { - children->GetDictionary(i, &child_dict); - auto filtered_child = FilterAccessibilityTree(*child_dict); - filtered_children->Append(std::move(filtered_child)); - } - filtered_dict->Set(kChildrenDictAttr, std::move(filtered_children)); - } - return filtered_dict; -} - -void AccessibilityTreeFormatter::RecursiveFormatAccessibilityTree( - const base::DictionaryValue& dict, - base::string16* contents, - int depth) { - // Check dictionary against node filters, may require us to skip this node - // and its children. - if (MatchesNodeFilters(dict)) - return; - - base::string16 indent = - base::string16(depth * kIndentSymbolCount, kIndentSymbol); - base::string16 line = indent + ProcessTreeForOutput(dict); - if (line.find(base::ASCIIToUTF16(kSkipString)) != base::string16::npos) - return; - - // Normalize any Windows-style line endings by removing \r. - base::RemoveChars(line, base::ASCIIToUTF16("\r"), &line); - - // Replace literal newlines with "<newline>" - base::ReplaceChars(line, base::ASCIIToUTF16("\n"), - base::ASCIIToUTF16("<newline>"), &line); - - *contents += line + base::ASCIIToUTF16("\n"); - if (line.find(base::ASCIIToUTF16(kSkipChildren)) != base::string16::npos) - return; - - const base::ListValue* children; - if (!dict.GetList(kChildrenDictAttr, &children)) - return; - const base::DictionaryValue* child_dict; - for (size_t i = 0; i < children->GetSize(); i++) { - children->GetDictionary(i, &child_dict); - RecursiveFormatAccessibilityTree(*child_dict, contents, depth + 1); - } -} - -void AccessibilityTreeFormatter::SetPropertyFilters( - const std::vector<PropertyFilter>& property_filters) { - property_filters_ = property_filters; -} - -void AccessibilityTreeFormatter::SetNodeFilters( - const std::vector<NodeFilter>& node_filters) { - node_filters_ = node_filters; -} - -const base::FilePath::StringType -AccessibilityTreeFormatter::GetVersionSpecificExpectedFileSuffix() { - return FILE_PATH_LITERAL(""); -} - -// static bool AccessibilityTreeFormatter::MatchesPropertyFilters( const std::vector<PropertyFilter>& property_filters, const base::string16& text, @@ -176,18 +88,111 @@ return false; } -bool AccessibilityTreeFormatter::MatchesPropertyFilters( +AccessibilityTreeFormatterBase::AccessibilityTreeFormatterBase() + : show_ids_(false) {} + +AccessibilityTreeFormatterBase::~AccessibilityTreeFormatterBase() {} + +void AccessibilityTreeFormatterBase::FormatAccessibilityTree( + BrowserAccessibility* root, + base::string16* contents) { + std::unique_ptr<base::DictionaryValue> dict = BuildAccessibilityTree(root); + RecursiveFormatAccessibilityTree(*(dict.get()), contents); +} + +void AccessibilityTreeFormatterBase::FormatAccessibilityTree( + const base::DictionaryValue& dict, + base::string16* contents) { + RecursiveFormatAccessibilityTree(dict, contents); +} + +std::unique_ptr<base::DictionaryValue> +AccessibilityTreeFormatterBase::FilterAccessibilityTree( + const base::DictionaryValue& dict) { + auto filtered_dict = std::make_unique<base::DictionaryValue>(); + ProcessTreeForOutput(dict, filtered_dict.get()); + const base::ListValue* children; + if (dict.GetList(kChildrenDictAttr, &children) && !children->empty()) { + const base::DictionaryValue* child_dict; + auto filtered_children = std::make_unique<base::ListValue>(); + for (size_t i = 0; i < children->GetSize(); i++) { + children->GetDictionary(i, &child_dict); + auto filtered_child = FilterAccessibilityTree(*child_dict); + filtered_children->Append(std::move(filtered_child)); + } + filtered_dict->Set(kChildrenDictAttr, std::move(filtered_children)); + } + return filtered_dict; +} + +void AccessibilityTreeFormatterBase::RecursiveFormatAccessibilityTree( + const base::DictionaryValue& dict, + base::string16* contents, + int depth) { + // Check dictionary against node filters, may require us to skip this node + // and its children. + if (MatchesNodeFilters(dict)) + return; + + base::string16 indent = + base::string16(depth * kIndentSymbolCount, kIndentSymbol); + base::string16 line = indent + ProcessTreeForOutput(dict); + if (line.find(base::ASCIIToUTF16(kSkipString)) != base::string16::npos) + return; + + // Normalize any Windows-style line endings by removing \r. + base::RemoveChars(line, base::ASCIIToUTF16("\r"), &line); + + // Replace literal newlines with "<newline>" + base::ReplaceChars(line, base::ASCIIToUTF16("\n"), + base::ASCIIToUTF16("<newline>"), &line); + + *contents += line + base::ASCIIToUTF16("\n"); + if (line.find(base::ASCIIToUTF16(kSkipChildren)) != base::string16::npos) + return; + + const base::ListValue* children; + if (!dict.GetList(kChildrenDictAttr, &children)) + return; + const base::DictionaryValue* child_dict; + for (size_t i = 0; i < children->GetSize(); i++) { + children->GetDictionary(i, &child_dict); + RecursiveFormatAccessibilityTree(*child_dict, contents, depth + 1); + } +} + +void AccessibilityTreeFormatterBase::SetPropertyFilters( + const std::vector<PropertyFilter>& property_filters) { + property_filters_ = property_filters; +} + +void AccessibilityTreeFormatterBase::SetNodeFilters( + const std::vector<NodeFilter>& node_filters) { + node_filters_ = node_filters; +} + +void AccessibilityTreeFormatterBase::set_show_ids(bool show_ids) { + show_ids_ = show_ids; +} + +const base::FilePath::StringType +AccessibilityTreeFormatterBase::GetVersionSpecificExpectedFileSuffix() { + return FILE_PATH_LITERAL(""); +} + +bool AccessibilityTreeFormatterBase::MatchesPropertyFilters( const base::string16& text, bool default_result) const { - return MatchesPropertyFilters(property_filters_, text, default_result); + return AccessibilityTreeFormatter::MatchesPropertyFilters( + property_filters_, text, default_result); } -bool AccessibilityTreeFormatter::MatchesNodeFilters( +bool AccessibilityTreeFormatterBase::MatchesNodeFilters( const base::DictionaryValue& dict) const { - return MatchesNodeFilters(node_filters_, dict); + return AccessibilityTreeFormatter::MatchesNodeFilters(node_filters_, dict); } -base::string16 AccessibilityTreeFormatter::FormatCoordinates( +base::string16 AccessibilityTreeFormatterBase::FormatCoordinates( const char* name, const char* x_name, const char* y_name, @@ -200,15 +205,15 @@ return base::UTF8ToUTF16(xy_str); } -bool AccessibilityTreeFormatter::WriteAttribute(bool include_by_default, - const std::string& attr, - base::string16* line) { +bool AccessibilityTreeFormatterBase::WriteAttribute(bool include_by_default, + const std::string& attr, + base::string16* line) { return WriteAttribute(include_by_default, base::UTF8ToUTF16(attr), line); } -bool AccessibilityTreeFormatter::WriteAttribute(bool include_by_default, - const base::string16& attr, - base::string16* line) { +bool AccessibilityTreeFormatterBase::WriteAttribute(bool include_by_default, + const base::string16& attr, + base::string16* line) { if (attr.empty()) return false; if (!MatchesPropertyFilters(attr, include_by_default)) @@ -219,13 +224,13 @@ return true; } -void AccessibilityTreeFormatter::AddPropertyFilter( +void AccessibilityTreeFormatterBase::AddPropertyFilter( std::vector<PropertyFilter>* property_filters, std::string filter, PropertyFilter::Type type) { property_filters->push_back(PropertyFilter(base::ASCIIToUTF16(filter), type)); } -void AccessibilityTreeFormatter::AddDefaultFilters( +void AccessibilityTreeFormatterBase::AddDefaultFilters( std::vector<PropertyFilter>* property_filters) {} } // namespace content
diff --git a/content/browser/accessibility/accessibility_tree_formatter_base.h b/content/browser/accessibility/accessibility_tree_formatter_base.h new file mode 100644 index 0000000..d2430c04 --- /dev/null +++ b/content/browser/accessibility/accessibility_tree_formatter_base.h
@@ -0,0 +1,124 @@ +// 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_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_BASE_H_ +#define CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_BASE_H_ + +#include <stdint.h> + +#include <vector> + +#include "base/files/file_path.h" +#include "base/macros.h" +#include "base/process/process_handle.h" +#include "base/strings/string16.h" +#include "base/strings/string_piece.h" +#include "base/strings/utf_string_conversions.h" +#include "base/values.h" +#include "content/browser/accessibility/browser_accessibility.h" +#include "content/common/content_export.h" +#include "content/public/browser/accessibility_tree_formatter.h" +#include "ui/gfx/native_widget_types.h" + +namespace { +const char kChildrenDictAttr[] = "children"; +} + +namespace content { + +// A utility class for formatting platform-specific accessibility information, +// for use in testing, debugging, and developer tools. +// This is extended by a subclass for each platform where accessibility is +// implemented. +class CONTENT_EXPORT AccessibilityTreeFormatterBase + : public AccessibilityTreeFormatter { + public: + explicit AccessibilityTreeFormatterBase(); + ~AccessibilityTreeFormatterBase() override; + + // AccessibilityTreeFormatter overrides. + void AddDefaultFilters( + std::vector<PropertyFilter>* property_filters) override; + std::unique_ptr<base::DictionaryValue> FilterAccessibilityTree( + const base::DictionaryValue& dict) override; + void FormatAccessibilityTree(BrowserAccessibility* root, + base::string16* contents) override; + void FormatAccessibilityTree(const base::DictionaryValue& tree_node, + base::string16* contents) override; + void SetPropertyFilters( + const std::vector<PropertyFilter>& property_filters) override; + void SetNodeFilters(const std::vector<NodeFilter>& node_filters) override; + void set_show_ids(bool show_ids) override; + const base::FilePath::StringType GetVersionSpecificExpectedFileSuffix() + override; + + protected: + // + // Overridden by platform subclasses. + // + + // Process accessibility tree with filters for output. + // Given a dictionary that contains a platform-specific dictionary + // representing an accessibility tree, and utilizing property_filters_ and + // node_filters_: + // - Returns a filtered text view as one large string. + // - Provides a filtered version of the dictionary in an out param, + // (only if the out param is provided). + virtual base::string16 ProcessTreeForOutput( + const base::DictionaryValue& node, + base::DictionaryValue* filtered_dict_result = nullptr) = 0; + + // + // Utility functions to be used by each platform. + // + + base::string16 FormatCoordinates(const char* name, + const char* x_name, + const char* y_name, + const base::DictionaryValue& value); + + // Writes the given attribute string out to |line| if it matches the property + // filters. + // Returns false if the attribute was filtered out. + bool WriteAttribute(bool include_by_default, + const base::string16& attr, + base::string16* line); + bool WriteAttribute(bool include_by_default, + const std::string& attr, + base::string16* line); + void AddPropertyFilter(std::vector<PropertyFilter>* property_filters, + std::string filter, + PropertyFilter::Type type = PropertyFilter::ALLOW); + bool show_ids() { return show_ids_; } + + private: + void RecursiveFormatAccessibilityTree(const BrowserAccessibility& node, + base::string16* contents, + int indent); + void RecursiveFormatAccessibilityTree(const base::DictionaryValue& tree_node, + base::string16* contents, + int depth = 0); + + bool MatchesPropertyFilters(const base::string16& text, + bool default_result) const; + bool MatchesNodeFilters(const base::DictionaryValue& dict) const; + + // Property filters used when formatting the accessibility tree as text. + // Any property which matches a property filter will be skipped. + std::vector<PropertyFilter> property_filters_; + + // Node filters used when formatting the accessibility tree as text. + // Any node which matches a node wilder will be skipped, along with all its + // children. + std::vector<NodeFilter> node_filters_; + + // Whether or not node ids should be included in the dump. + bool show_ids_; + + DISALLOW_COPY_AND_ASSIGN(AccessibilityTreeFormatterBase); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_BASE_H_
diff --git a/content/browser/accessibility/accessibility_tree_formatter_browser.h b/content/browser/accessibility/accessibility_tree_formatter_browser.h index c5713fd..62535d3 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_browser.h +++ b/content/browser/accessibility/accessibility_tree_formatter_browser.h
@@ -5,7 +5,7 @@ #ifndef CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_BROWSER_H_ #define CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_BROWSER_H_ -#include "content/browser/accessibility/accessibility_tree_formatter.h" +#include "content/browser/accessibility/accessibility_tree_formatter_base.h" #include "base/macros.h" #include "base/strings/string16.h" @@ -20,7 +20,7 @@ // walking the tree and getting properties. Tree formatters that walk native // objects should not inherit from this class. class CONTENT_EXPORT AccessibilityTreeFormatterBrowser - : public AccessibilityTreeFormatter { + : public AccessibilityTreeFormatterBase { public: std::unique_ptr<base::DictionaryValue> BuildAccessibilityTree( BrowserAccessibility* root) override;
diff --git a/content/browser/accessibility/accessibility_tree_formatter_uia_win.h b/content/browser/accessibility/accessibility_tree_formatter_uia_win.h index 577e96b3..e6abfb7 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_uia_win.h +++ b/content/browser/accessibility/accessibility_tree_formatter_uia_win.h
@@ -3,7 +3,7 @@ // found in the LICENSE file. #ifndef CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_UIA_WIN_H_ #define CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_UIA_WIN_H_ -#include "content/browser/accessibility/accessibility_tree_formatter.h" +#include "content/browser/accessibility/accessibility_tree_formatter_base.h" #include <ole2.h> #include <stdint.h> @@ -16,7 +16,7 @@ #include "base/win/scoped_variant.h" namespace content { -class AccessibilityTreeFormatterUia : public AccessibilityTreeFormatter { +class AccessibilityTreeFormatterUia : public AccessibilityTreeFormatterBase { public: AccessibilityTreeFormatterUia();
diff --git a/content/browser/accessibility/accessibility_tree_formatter_win.cc b/content/browser/accessibility/accessibility_tree_formatter_win.cc index e8330f43..41e4ba70 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_win.cc +++ b/content/browser/accessibility/accessibility_tree_formatter_win.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/browser/accessibility/accessibility_tree_formatter.h" +#include "content/browser/accessibility/accessibility_tree_formatter_base.h" #include <math.h> #include <oleacc.h> @@ -37,7 +37,7 @@ namespace content { -class AccessibilityTreeFormatterWin : public AccessibilityTreeFormatter { +class AccessibilityTreeFormatterWin : public AccessibilityTreeFormatterBase { public: AccessibilityTreeFormatterWin(); ~AccessibilityTreeFormatterWin() override;
diff --git a/content/browser/accessibility/accessibility_win_browsertest.cc b/content/browser/accessibility/accessibility_win_browsertest.cc index ba10463..3b76d86 100644 --- a/content/browser/accessibility/accessibility_win_browsertest.cc +++ b/content/browser/accessibility/accessibility_win_browsertest.cc
@@ -23,7 +23,6 @@ #include "build/build_config.h" #include "content/browser/accessibility/accessibility_browsertest.h" #include "content/browser/accessibility/accessibility_event_recorder.h" -#include "content/browser/accessibility/accessibility_tree_formatter.h" #include "content/browser/accessibility/accessibility_tree_formatter_utils_win.h" #include "content/browser/accessibility/browser_accessibility_manager_win.h" #include "content/browser/accessibility/browser_accessibility_win.h" @@ -31,6 +30,7 @@ #include "content/browser/renderer_host/render_widget_host_view_aura.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/browser/web_contents/web_contents_view_aura.h" +#include "content/public/browser/accessibility_tree_formatter.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" #include "content/public/browser/render_frame_host.h"
diff --git a/content/browser/accessibility/dump_accessibility_browsertest_base.cc b/content/browser/accessibility/dump_accessibility_browsertest_base.cc index 965f4ac9..9fa59908 100644 --- a/content/browser/accessibility/dump_accessibility_browsertest_base.cc +++ b/content/browser/accessibility/dump_accessibility_browsertest_base.cc
@@ -20,7 +20,6 @@ #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "content/browser/accessibility/accessibility_event_recorder.h" -#include "content/browser/accessibility/accessibility_tree_formatter.h" #include "content/browser/accessibility/browser_accessibility.h" #include "content/browser/accessibility/browser_accessibility_manager.h" #include "content/browser/accessibility/browser_accessibility_state_impl.h"
diff --git a/content/browser/accessibility/dump_accessibility_browsertest_base.h b/content/browser/accessibility/dump_accessibility_browsertest_base.h index 42154c5d..a97efe3 100644 --- a/content/browser/accessibility/dump_accessibility_browsertest_base.h +++ b/content/browser/accessibility/dump_accessibility_browsertest_base.h
@@ -13,7 +13,7 @@ #include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "content/browser/accessibility/accessibility_event_recorder.h" -#include "content/browser/accessibility/accessibility_tree_formatter.h" +#include "content/public/browser/accessibility_tree_formatter.h" #include "content/public/test/content_browser_test.h" namespace content {
diff --git a/content/browser/accessibility/dump_accessibility_events_browsertest.cc b/content/browser/accessibility/dump_accessibility_events_browsertest.cc index 21e6f18..820193e 100644 --- a/content/browser/accessibility/dump_accessibility_events_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_events_browsertest.cc
@@ -16,11 +16,11 @@ #include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "content/browser/accessibility/accessibility_event_recorder.h" -#include "content/browser/accessibility/accessibility_tree_formatter.h" #include "content/browser/accessibility/browser_accessibility.h" #include "content/browser/accessibility/browser_accessibility_manager.h" #include "content/browser/accessibility/dump_accessibility_browsertest_base.h" #include "content/browser/web_contents/web_contents_impl.h" +#include "content/public/browser/accessibility_tree_formatter.h" #include "content/public/common/content_paths.h" #include "content/public/test/content_browser_test_utils.h" #include "content/public/test/test_utils.h"
diff --git a/content/browser/accessibility/dump_accessibility_test_helper.cc b/content/browser/accessibility/dump_accessibility_test_helper.cc index 8d6dc4d..c6eed89 100644 --- a/content/browser/accessibility/dump_accessibility_test_helper.cc +++ b/content/browser/accessibility/dump_accessibility_test_helper.cc
@@ -10,7 +10,7 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/threading/thread_restrictions.h" -#include "content/browser/accessibility/accessibility_tree_formatter.h" +#include "content/public/browser/accessibility_tree_formatter.h" #include "content/public/common/content_switches.h" namespace content {
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc index ebedcf5..063e42e 100644 --- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -14,7 +14,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_restrictions.h" #include "build/build_config.h" -#include "content/browser/accessibility/accessibility_tree_formatter.h" #include "content/browser/accessibility/accessibility_tree_formatter_blink.h" #include "content/browser/accessibility/browser_accessibility.h" #include "content/browser/accessibility/browser_accessibility_manager.h"
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index d4426f9..777e9ccf6 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -602,15 +602,17 @@ return pre_early_init_error_code; } -#if defined(OS_ANDROID) || defined(OS_CHROMEOS) || defined(USE_OZONE) - // Up the priority of the UI thread unless it was already high (since recent - // versions of Android (O+) do this automatically). - if (base::PlatformThread::GetCurrentThreadPriority() < - base::ThreadPriority::DISPLAY) { + // Up the priority of the UI thread unless it was already high (since Mac + // and recent versions of Android (O+) do this automatically). +#if !defined(OS_MACOSX) + if (base::FeatureList::IsEnabled( + features::kBrowserUseDisplayThreadPriority) && + base::PlatformThread::GetCurrentThreadPriority() < + base::ThreadPriority::DISPLAY) { base::PlatformThread::SetCurrentThreadPriority( base::ThreadPriority::DISPLAY); } -#endif // defined(OS_ANDROID) || defined(OS_CHROMEOS) +#endif // !defined(OS_MACOSX) #if defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \ defined(OS_ANDROID)
diff --git a/content/browser/child_process_launcher_helper_mac.cc b/content/browser/child_process_launcher_helper_mac.cc index 8a46b585..d3b86f50 100644 --- a/content/browser/child_process_launcher_helper_mac.cc +++ b/content/browser/child_process_launcher_helper_mac.cc
@@ -21,7 +21,6 @@ #include "content/public/common/content_switches.h" #include "content/public/common/result_codes.h" #include "content/public/common/sandboxed_process_launcher_delegate.h" -#include "mojo/public/cpp/platform/features.h" #include "sandbox/mac/seatbelt_exec.h" #include "services/service_manager/embedder/result_codes.h" #include "services/service_manager/sandbox/mac/sandbox_mac.h" @@ -61,12 +60,11 @@ base::FieldTrialList::InsertFieldTrialHandleIfNeeded( &options->mach_ports_for_rendezvous); - if (base::FeatureList::IsEnabled(mojo::features::kMojoChannelMac)) { - options->mach_ports_for_rendezvous.insert(std::make_pair( - 'mojo', base::MachRendezvousPort(mojo_channel_->TakeRemoteEndpoint() - .TakePlatformHandle() - .TakeMachReceiveRight()))); - } + mojo::PlatformHandle endpoint = + mojo_channel_->TakeRemoteEndpoint().TakePlatformHandle(); + DCHECK(endpoint.is_valid_mach_receive()); + options->mach_ports_for_rendezvous.insert(std::make_pair( + 'mojo', base::MachRendezvousPort(endpoint.TakeMachReceiveRight()))); options->environment = delegate_->GetEnvironment();
diff --git a/content/browser/child_process_launcher_helper_posix.cc b/content/browser/child_process_launcher_helper_posix.cc index c18406f..d52a508 100644 --- a/content/browser/child_process_launcher_helper_posix.cc +++ b/content/browser/child_process_launcher_helper_posix.cc
@@ -15,7 +15,6 @@ #include "content/public/common/content_client.h" #include "content/public/common/content_descriptors.h" #include "content/public/common/content_switches.h" -#include "mojo/public/cpp/platform/features.h" #include "mojo/public/cpp/platform/platform_channel_endpoint.h" #include "services/service_manager/embedder/shared_file_util.h" #include "services/service_manager/embedder/switches.h" @@ -87,22 +86,13 @@ DCHECK_NE(fd, -1); files_to_register->Share(service_manager::kFieldTrialDescriptor, fd); - const bool mojo_channel_mac = false; -#else - const bool mojo_channel_mac = - base::FeatureList::IsEnabled(mojo::features::kMojoChannelMac); -#endif - - if (!mojo_channel_mac) { - DCHECK(mojo_channel_remote_endpoint.is_valid()); - files_to_register->Share( - service_manager::kMojoIPCChannel, - mojo_channel_remote_endpoint.platform_handle().GetFD().get()); - } + DCHECK(mojo_channel_remote_endpoint.is_valid()); + files_to_register->Share( + service_manager::kMojoIPCChannel, + mojo_channel_remote_endpoint.platform_handle().GetFD().get()); // TODO(jcivelli): remove this "if defined" by making // GetAdditionalMappedFilesForChildProcess a no op on Mac. -#if !defined(OS_MACOSX) GetContentClient()->browser()->GetAdditionalMappedFilesForChildProcess( *command_line, child_process_id, files_to_register.get()); #endif
diff --git a/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc b/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc index b48fe688..f695189 100644 --- a/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc +++ b/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc
@@ -157,9 +157,7 @@ // Even through the swap failed, this is a fixable error so we can pretend // it succeeded to the rest of the system. modified_params.swap_response.result = gfx::SwapResult::SWAP_ACK; - unsigned current_surface_texture = buffer_queue_->RecreateBuffers(); - if (current_surface_texture) - BindFramebuffer(); + buffer_queue_->FreeAllSurfaces(); force_swap = true; } buffer_queue_->PageFlipComplete();
diff --git a/content/browser/devtools/devtools_protocol_encoding_cbor_fuzzer.cc b/content/browser/devtools/devtools_protocol_encoding_cbor_fuzzer.cc index ad57032..4ffa6bf 100644 --- a/content/browser/devtools/devtools_protocol_encoding_cbor_fuzzer.cc +++ b/content/browser/devtools/devtools_protocol_encoding_cbor_fuzzer.cc
@@ -19,8 +19,8 @@ } // namespace extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - std::string cbor; - content::ConvertJSONToCBOR(span<uint8_t>(data, size), &cbor); + std::string json; + content::ConvertCBORToJSON(span<uint8_t>(data, size), &json); return 0; } } // namespace content
diff --git a/content/browser/devtools/devtools_protocol_encoding_json_fuzzer.cc b/content/browser/devtools/devtools_protocol_encoding_json_fuzzer.cc index b20782b..cb9ba6b2 100644 --- a/content/browser/devtools/devtools_protocol_encoding_json_fuzzer.cc +++ b/content/browser/devtools/devtools_protocol_encoding_json_fuzzer.cc
@@ -13,8 +13,8 @@ } // namespace extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - std::string json; - content::ConvertJSONToCBOR(span<uint8_t>(data, size), &json); + std::string cbor; + content::ConvertJSONToCBOR(span<uint8_t>(data, size), &cbor); return 0; } } // namespace content
diff --git a/content/browser/network_service_restart_browsertest.cc b/content/browser/network_service_restart_browsertest.cc index 3eac522f..84de870 100644 --- a/content/browser/network_service_restart_browsertest.cc +++ b/content/browser/network_service_restart_browsertest.cc
@@ -482,7 +482,7 @@ return; base::ScopedAllowBlockingForTesting allow_blocking; std::unique_ptr<ShellBrowserContext> browser_context = - std::make_unique<ShellBrowserContext>(true, nullptr); + std::make_unique<ShellBrowserContext>(true); auto* partition = static_cast<StoragePartitionImpl*>( BrowserContext::GetDefaultStoragePartition(browser_context.get())); auto factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create( @@ -572,7 +572,7 @@ return; base::ScopedAllowBlockingForTesting allow_blocking; std::unique_ptr<ShellBrowserContext> browser_context = - std::make_unique<ShellBrowserContext>(true, nullptr); + std::make_unique<ShellBrowserContext>(true); auto* partition = BrowserContext::GetDefaultStoragePartition(browser_context.get()); scoped_refptr<network::SharedURLLoaderFactory> factory(
diff --git a/content/browser/payments/payment_app_provider_impl.cc b/content/browser/payments/payment_app_provider_impl.cc index 9941db8..dbb172c 100644 --- a/content/browser/payments/payment_app_provider_impl.cc +++ b/content/browser/payments/payment_app_provider_impl.cc
@@ -206,12 +206,11 @@ int request_id() { return request_id_; } - void AbortPaymentSinceOpennedWindowClosing() { + void AbortPaymentSinceOpennedWindowClosing(PaymentEventResponseType reason) { DCHECK_CURRENTLY_ON(BrowserThread::IO); service_worker_version_->FinishRequest(request_id_, false); - RespondWithErrorAndDeleteSelf( - PaymentEventResponseType::PAYMENT_HANDLER_WINDOW_CLOSING); + RespondWithErrorAndDeleteSelf(reason); } private: @@ -440,14 +439,15 @@ std::move(callback).Run(std::move(permitted_apps)); } -void AbortInvokePaymentApp(BrowserContext* browser_context) { +void AbortInvokePaymentApp(BrowserContext* browser_context, + PaymentEventResponseType reason) { DCHECK_CURRENTLY_ON(BrowserThread::IO); RespondWithCallbacks* callback = InvokePaymentAppCallbackRepository::GetInstance()->GetCallback( browser_context); if (callback) - callback->AbortPaymentSinceOpennedWindowClosing(); + callback->AbortPaymentSinceOpennedWindowClosing(reason); } } // namespace @@ -584,12 +584,13 @@ } void PaymentAppProviderImpl::OnClosingOpenedWindow( - BrowserContext* browser_context) { + BrowserContext* browser_context, + PaymentEventResponseType reason) { DCHECK_CURRENTLY_ON(BrowserThread::UI); base::PostTaskWithTraits( FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&AbortInvokePaymentApp, browser_context)); + base::BindOnce(&AbortInvokePaymentApp, browser_context, reason)); } bool PaymentAppProviderImpl::IsValidInstallablePaymentApp(
diff --git a/content/browser/payments/payment_app_provider_impl.h b/content/browser/payments/payment_app_provider_impl.h index cd7d6956..9908948 100644 --- a/content/browser/payments/payment_app_provider_impl.h +++ b/content/browser/payments/payment_app_provider_impl.h
@@ -44,7 +44,9 @@ PaymentEventResultCallback callback) override; void SetOpenedWindow(WebContents* web_contents) override; void CloseOpenedWindow(BrowserContext* browser_context) override; - void OnClosingOpenedWindow(BrowserContext* browser_context) override; + void OnClosingOpenedWindow( + BrowserContext* browser_context, + payments::mojom::PaymentEventResponseType reason) override; bool IsValidInstallablePaymentApp(const GURL& manifest_url, const GURL& sw_js_url, const GURL& sw_scope,
diff --git a/content/browser/payments/payment_app_provider_impl_unittest.cc b/content/browser/payments/payment_app_provider_impl_unittest.cc index 9aa7ef7..8b46f9b6 100644 --- a/content/browser/payments/payment_app_provider_impl_unittest.cc +++ b/content/browser/payments/payment_app_provider_impl_unittest.cc
@@ -113,7 +113,8 @@ void OnClosingOpenedWindow() { PaymentAppProviderImpl::GetInstance()->OnClosingOpenedWindow( - browser_context()); + browser_context(), payments::mojom::PaymentEventResponseType:: + PAYMENT_HANDLER_WINDOW_CLOSING); base::RunLoop().RunUntilIdle(); }
diff --git a/content/browser/pointer_lock_browsertest.cc b/content/browser/pointer_lock_browsertest.cc index 0afb41fe..2f639b7 100644 --- a/content/browser/pointer_lock_browsertest.cc +++ b/content/browser/pointer_lock_browsertest.cc
@@ -9,6 +9,7 @@ #include "content/browser/renderer_host/render_widget_host_input_event_router.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/web_contents_delegate.h" +#include "content/public/common/content_features.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" @@ -172,7 +173,9 @@ blink::WebMouseEvent mouse_event( blink::WebInputEvent::kMouseMove, blink::WebInputEvent::kNoModifiers, blink::WebInputEvent::GetStaticTimeStampForTests()); + mouse_event.pointer_type = blink::WebPointerProperties::PointerType::kMouse; mouse_event.SetPositionInWidget(6, 7); + mouse_event.SetPositionInScreen(6, 7); mouse_event.movement_x = 8; mouse_event.movement_y = 9; router->RouteMouseEvent(root_view, &mouse_event, ui::LatencyInfo()); @@ -181,7 +184,10 @@ MainThreadFrameObserver root_observer(root_view->GetRenderWidgetHost()); root_observer.Wait(); - EXPECT_EQ("[6,7,8,9]", EvalJs(root, "JSON.stringify([x,y,mX,mY])")); + if (base::FeatureList::IsEnabled(features::kConsolidatedMovementXY)) + EXPECT_EQ("[6,7,0,0]", EvalJs(root, "JSON.stringify([x,y,mX,mY])")); + else + EXPECT_EQ("[6,7,8,9]", EvalJs(root, "JSON.stringify([x,y,mX,mY])")); // Request a pointer lock on the root frame's body. EXPECT_TRUE(ExecJs(root, "document.body.requestPointerLock()")); @@ -189,7 +195,8 @@ // Root frame should have been granted pointer lock. EXPECT_EQ(true, EvalJs(root, "document.pointerLockElement == document.body")); - mouse_event.SetPositionInWidget(10, 11); + mouse_event.SetPositionInWidget(10, 12); + mouse_event.SetPositionInScreen(10, 12); mouse_event.movement_x = 12; mouse_event.movement_y = 13; router->RouteMouseEvent(root_view, &mouse_event, ui::LatencyInfo()); @@ -198,7 +205,10 @@ root_observer.Wait(); // Locked event has same coordinates as before locked. - EXPECT_EQ("[6,7,12,13]", EvalJs(root, "JSON.stringify([x,y,mX,mY])")); + if (base::FeatureList::IsEnabled(features::kConsolidatedMovementXY)) + EXPECT_EQ("[6,7,4,5]", EvalJs(root, "JSON.stringify([x,y,mX,mY])")); + else + EXPECT_EQ("[6,7,12,13]", EvalJs(root, "JSON.stringify([x,y,mX,mY])")); // Release pointer lock on root frame. EXPECT_TRUE(ExecJs(root, "document.exitPointerLock()")); @@ -222,6 +232,8 @@ mouse_event.SetPositionInWidget(-transformed_point.x() + 14, -transformed_point.y() + 15); + mouse_event.SetPositionInScreen(-transformed_point.x() + 14, + -transformed_point.y() + 15); mouse_event.movement_x = 16; mouse_event.movement_y = 17; // We use root_view intentionally as the RenderWidgetHostInputEventRouter is @@ -233,7 +245,10 @@ child_observer.Wait(); // This is the first event to child render, so the coordinates is (0, 0) - EXPECT_EQ("[0,0,16,17]", EvalJs(child, "JSON.stringify([x,y,mX,mY])")); + if (base::FeatureList::IsEnabled(features::kConsolidatedMovementXY)) + EXPECT_EQ("[0,0,0,0]", EvalJs(child, "JSON.stringify([x,y,mX,mY])")); + else + EXPECT_EQ("[0,0,16,17]", EvalJs(child, "JSON.stringify([x,y,mX,mY])")); } // Tests that the browser will not unlock the pointer if a RenderWidgetHostView @@ -404,7 +419,9 @@ blink::WebMouseEvent mouse_event( blink::WebInputEvent::kMouseMove, blink::WebInputEvent::kNoModifiers, blink::WebInputEvent::GetStaticTimeStampForTests()); + mouse_event.pointer_type = blink::WebPointerProperties::PointerType::kMouse; mouse_event.SetPositionInWidget(6, 7); + mouse_event.SetPositionInScreen(6, 7); mouse_event.movement_x = 8; mouse_event.movement_y = 9; router->RouteMouseEvent(root_view, &mouse_event, ui::LatencyInfo()); @@ -413,7 +430,10 @@ MainThreadFrameObserver root_observer(root_view->GetRenderWidgetHost()); root_observer.Wait(); - EXPECT_EQ("[6,7,8,9]", EvalJs(root, "JSON.stringify([x,y,mX,mY])")); + if (base::FeatureList::IsEnabled(features::kConsolidatedMovementXY)) + EXPECT_EQ("[6,7,0,0]", EvalJs(root, "JSON.stringify([x,y,mX,mY])")); + else + EXPECT_EQ("[6,7,8,9]", EvalJs(root, "JSON.stringify([x,y,mX,mY])")); // Request a pointer lock on the root frame's body. EXPECT_TRUE(ExecJs(root, "document.body.requestPointerLock()")); @@ -431,7 +451,7 @@ blink::WebMouseWheelEvent wheel_event( blink::WebInputEvent::kMouseWheel, blink::WebInputEvent::kNoModifiers, blink::WebInputEvent::GetStaticTimeStampForTests()); - wheel_event.SetPositionInWidget(10, 11); + wheel_event.SetPositionInScreen(10, 11); wheel_event.delta_x = -12; wheel_event.delta_y = -13; wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan; @@ -478,6 +498,8 @@ wheel_event.SetPositionInWidget(-transformed_point.x() + 14, -transformed_point.y() + 15); + wheel_event.SetPositionInScreen(-transformed_point.x() + 14, + -transformed_point.y() + 15); wheel_event.delta_x = -16; wheel_event.delta_y = -17; wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
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 4e2075b..21f93de0 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
@@ -124,6 +124,8 @@ 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), host_view_(host_view), popup_child_host_view_(nullptr), @@ -184,9 +186,9 @@ cursor_client->LockCursor(); } - if (ShouldMoveToCenter()) { - MoveCursorToCenter(); - } + if (ShouldMoveToCenter(unlocked_global_mouse_position_)) + MoveCursorToCenter(nullptr); + delegate_->SetTooltipsEnabled(false); return true; } @@ -214,6 +216,8 @@ // ModifyEventMovementAndCoords function. global_mouse_position_ = unlocked_global_mouse_position_; window_->MoveCursorTo(gfx::ToFlooredPoint(unlocked_mouse_position_)); + synthetic_move_position_ = + gfx::ToFlooredPoint(unlocked_global_mouse_position_); aura::client::CursorClient* cursor_client = aura::client::GetCursorClient(root_window); @@ -749,7 +753,7 @@ if (event->flags() & ui::EF_IS_NON_CLIENT) { // TODO(jonross): ideally this would not be done for mus // (crbug.com/621412) - MoveCursorToCenter(); + MoveCursorToCenter(event); return; } @@ -780,15 +784,13 @@ } } + bool should_not_forward = is_move_to_center_event && synthetic_move_sent_; + ModifyEventMovementAndCoords(*event, &mouse_event); - bool should_not_forward = is_move_to_center_event && synthetic_move_sent_; - if (should_not_forward) { + if (!enable_consolidated_movement_ && should_not_forward) { synthetic_move_sent_ = false; } else { - // Check if the mouse has reached the border and needs to be centered. - if (ShouldMoveToCenter()) - MoveCursorToCenter(); bool is_selection_popup = NeedsInputGrab(popup_child_host_view_); // Forward event to renderer. if (CanRendererHandleEvent(event, mouse_locked_, is_selection_popup) && @@ -804,6 +806,14 @@ if (event->type() == ui::ET_MOUSE_PRESSED) SetKeyboardFocus(); } + + // Check if the mouse has reached the border and needs to be centered. + // Use event position if consolidated_movement_ is enabled, otherwise use + // stored global_mouse_position_. + if (ShouldMoveToCenter(enable_consolidated_movement_ + ? gfx::PointF(mouse_event.PositionInScreen()) + : global_mouse_position_)) + MoveCursorToCenter(event); } } if (!ShouldGenerateAppCommand(event)) @@ -813,39 +823,56 @@ void RenderWidgetHostViewEventHandler::ModifyEventMovementAndCoords( const ui::MouseEvent& ui_mouse_event, blink::WebMouseEvent* event) { - // If the mouse has just entered, we must report zero movementX/Y. Hence we - // reset any global_mouse_position set previously. - if (ui_mouse_event.type() == ui::ET_MOUSE_ENTERED || - ui_mouse_event.type() == ui::ET_MOUSE_EXITED) { + if (!enable_consolidated_movement_) { + // If the mouse has just entered, we must report zero movementX/Y. Hence we + // reset any global_mouse_position set previously. + if (ui_mouse_event.type() == ui::ET_MOUSE_ENTERED || + ui_mouse_event.type() == ui::ET_MOUSE_EXITED) { + global_mouse_position_.SetPoint(event->PositionInScreen().x, + event->PositionInScreen().y); + } + + // Movement is computed by taking the difference of the new cursor position + // and the previous. Under mouse lock the cursor will be warped back to the + // center so that we are not limited by clipping boundaries. + // We do not measure movement as the delta from cursor to center because + // we may receive more mouse movement events before our warp has taken + // effect. + // TODO(crbug.com/802067): We store event coordinates as pointF but + // movement_x/y are integer. In order not to lose fractional part, we need + // to keep the movement calculation as "floor(cur_pos) - floor(last_pos)". + // Remove the floor here when movement_x/y is changed to double. + event->movement_x = gfx::ToFlooredInt(event->PositionInScreen().x) - + gfx::ToFlooredInt(global_mouse_position_.x()); + event->movement_y = gfx::ToFlooredInt(event->PositionInScreen().y) - + gfx::ToFlooredInt(global_mouse_position_.y()); + global_mouse_position_.SetPoint(event->PositionInScreen().x, event->PositionInScreen().y); } - // Movement is computed by taking the difference of the new cursor position - // and the previous. Under mouse lock the cursor will be warped back to the - // center so that we are not limited by clipping boundaries. - // We do not measure movement as the delta from cursor to center because - // we may receive more mouse movement events before our warp has taken - // effect. - // TODO(crbug.com/802067): We store event coordinates as pointF but - // movement_x/y are integer. In order not to lose fractional part, we need - // to keep the movement calculation as "floor(cur_pos) - floor(last_pos)". - // Remove the floor here when movement_x/y is changed to double. - event->movement_x = gfx::ToFlooredInt(event->PositionInScreen().x) - - gfx::ToFlooredInt(global_mouse_position_.x()); - event->movement_y = gfx::ToFlooredInt(event->PositionInScreen().y) - - gfx::ToFlooredInt(global_mouse_position_.y()); - - global_mouse_position_.SetPoint(event->PositionInScreen().x, - event->PositionInScreen().y); + // This logic is similar to |is_move_to_center_event| check when + // 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())) { + event->SetModifiers(event->GetModifiers() | + blink::WebInputEvent::Modifiers::kRelativeMotionEvent); + synthetic_move_position_.reset(); + return; + } // Under mouse lock, coordinates of mouse are locked to what they were when // mouse lock was entered. if (mouse_locked_) { - event->SetPositionInWidget(unlocked_mouse_position_.x(), - unlocked_mouse_position_.y()); - event->SetPositionInScreen(unlocked_global_mouse_position_.x(), - unlocked_global_mouse_position_.y()); + if (!enable_consolidated_movement_) { + event->SetPositionInWidget(unlocked_mouse_position_.x(), + unlocked_mouse_position_.y()); + event->SetPositionInScreen(unlocked_global_mouse_position_.x(), + unlocked_global_mouse_position_.y()); + } } else { unlocked_mouse_position_.SetPoint(event->PositionInWidget().x, event->PositionInWidget().y); @@ -854,19 +881,35 @@ } } -void RenderWidgetHostViewEventHandler::MoveCursorToCenter() { +void RenderWidgetHostViewEventHandler::MoveCursorToCenter( + ui::MouseEvent* event) { + gfx::PointF center_in_screen(window_->GetBoundsInScreen().CenterPoint()); #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. - gfx::PointF center_in_screen(window_->GetBoundsInScreen().CenterPoint()); + // 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; + 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); + if (ShouldRouteEvents()) { + host_->delegate()->GetInputEventRouter()->RouteMouseEvent( + host_view_, &mouse_event, *event->latency()); + } else { + ProcessMouseEvent(mouse_event, *event->latency()); + } + } #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); } void RenderWidgetHostViewEventHandler::SetKeyboardFocus() { @@ -887,16 +930,17 @@ } } -bool RenderWidgetHostViewEventHandler::ShouldMoveToCenter() { +bool RenderWidgetHostViewEventHandler::ShouldMoveToCenter( + gfx::PointF mouse_screen_position) { gfx::Rect rect = window_->bounds(); rect = delegate_->ConvertRectToScreen(rect); float border_x = rect.width() * kMouseLockBorderPercentage / 100.0; float border_y = rect.height() * kMouseLockBorderPercentage / 100.0; - return global_mouse_position_.x() < rect.x() + border_x || - global_mouse_position_.x() > rect.right() - border_x || - global_mouse_position_.y() < rect.y() + border_y || - global_mouse_position_.y() > rect.bottom() - border_y; + return mouse_screen_position.x() < rect.x() + border_x || + mouse_screen_position.x() > rect.right() - border_x || + mouse_screen_position.y() < rect.y() + border_y || + mouse_screen_position.y() > rect.bottom() - border_y; } bool RenderWidgetHostViewEventHandler::ShouldRouteEvents() const {
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 19c945b..9d620c8 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
@@ -206,14 +206,16 @@ blink::WebMouseEvent* event); // This method moves cursor to window center for pointer lock. - void MoveCursorToCenter(); + // In Windows, a non-null |event| is used for creating the synthesize move to + // update blink side states. + void MoveCursorToCenter(ui::MouseEvent* event); // Helper function to set keyboard focus to the main window. void SetKeyboardFocus(); // Helper method to determine if, in mouse locked mode, the cursor should be // moved to center. - bool ShouldMoveToCenter(); + bool ShouldMoveToCenter(gfx::PointF mouse_screen_position); // Returns true when we can hit test input events with location data to be // sent to the targeted RenderWidgetHost. @@ -269,6 +271,10 @@ // This flag is used to differentiate between these synthetic mouse move // events vs. normal mouse move events. bool synthetic_move_sent_; + + bool enable_consolidated_movement_; + base::Optional<gfx::Point> synthetic_move_position_; + // Stores the current state of the active pointers targeting this // object. ui::MotionEventAura pointer_state_;
diff --git a/content/browser/scheduler/browser_task_executor.cc b/content/browser/scheduler/browser_task_executor.cc index 15ae24ad..a0a22330 100644 --- a/content/browser/scheduler/browser_task_executor.cc +++ b/content/browser/scheduler/browser_task_executor.cc
@@ -15,6 +15,7 @@ #include "content/browser/browser_process_sub_thread.h" #include "content/browser/browser_thread_impl.h" #include "content/public/browser/browser_task_traits.h" +#include "content/public/common/content_features.h" #if defined(OS_ANDROID) #include "base/android/task_scheduler/post_task_android.h" @@ -278,11 +279,10 @@ options.message_loop_type = base::MessagePump::Type::IO; options.task_environment = g_browser_task_executor->browser_io_task_environment_.release(); -#if defined(OS_ANDROID) || defined(OS_CHROMEOS) || defined(USE_OZONE) // Up the priority of the |io_thread_| as some of its IPCs relate to // display tasks. - options.priority = base::ThreadPriority::DISPLAY; -#endif + if (base::FeatureList::IsEnabled(features::kBrowserUseDisplayThreadPriority)) + options.priority = base::ThreadPriority::DISPLAY; if (!io_thread->StartWithOptions(options)) LOG(FATAL) << "Failed to start BrowserThread:IO"; return io_thread;
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.cc b/content/browser/service_worker/service_worker_fetch_dispatcher.cc index d027d892..148ec3ac 100644 --- a/content/browser/service_worker/service_worker_fetch_dispatcher.cc +++ b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
@@ -18,6 +18,7 @@ #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/devtools/service_worker_devtools_agent_host.h" #include "content/browser/devtools/service_worker_devtools_manager.h" +#include "content/browser/frame_host/frame_tree_node.h" #include "content/browser/loader/navigation_url_loader_impl.h" #include "content/browser/loader/resource_dispatcher_host_impl.h" #include "content/browser/loader/resource_request_info_impl.h" @@ -292,15 +293,16 @@ // Creates the network URLLoaderFactory for the navigation preload request. void CreateNetworkFactoryForNavigationPreloadOnUI( - const ServiceWorkerFetchDispatcher::WebContentsGetter& web_contents_getter, + int frame_tree_node_id, scoped_refptr<ServiceWorkerContextWrapper> context_wrapper, network::mojom::URLLoaderFactoryRequest request) { DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService)); - WebContents* web_contents = web_contents_getter.Run(); + FrameTreeNode* frame_tree_node = + FrameTreeNode::GloballyFindByID(frame_tree_node_id); StoragePartitionImpl* partition = context_wrapper->storage_partition(); - if (!web_contents || !partition) { + if (!frame_tree_node || !partition) { // The navigation was cancelled or we are in shutdown. Just drop the // request. Otherwise, we might go to network without consulting the // embedder first, which would break guarantees. @@ -314,7 +316,7 @@ // origin instead. url::Origin initiator = url::Origin(); - // We ignore the value of |bypass_redirect_checks_unused| since a redirects is + // We ignore the value of |bypass_redirect_checks_unused| since a redirect is // just relayed to the service worker where preloadResponse is resolved as // redirect. bool bypass_redirect_checks_unused; @@ -322,9 +324,9 @@ // Consult the embedder. network::mojom::TrustedURLLoaderHeaderClientPtrInfo header_client; GetContentClient()->browser()->WillCreateURLLoaderFactory( - web_contents->GetBrowserContext(), web_contents->GetMainFrame(), - web_contents->GetMainFrame()->GetProcess()->GetID(), - true /* is_navigation */, false /* is_download */, initiator, &request, + partition->browser_context(), frame_tree_node->current_frame_host(), + frame_tree_node->current_frame_host()->GetProcess()->GetID(), + /*is_navigation=*/true, /*is_download=*/false, initiator, &request, &header_client, &bypass_redirect_checks_unused); // Make the network factory. @@ -645,7 +647,7 @@ const network::ResourceRequest& original_request, URLLoaderFactoryGetter* url_loader_factory_getter, scoped_refptr<ServiceWorkerContextWrapper> context_wrapper, - const WebContentsGetter& web_contents_getter) { + int frame_tree_node_id) { if (resource_type_ != ResourceType::kMainFrame && resource_type_ != ResourceType::kSubFrame) { return false; @@ -680,7 +682,7 @@ base::PostTaskWithTraits( FROM_HERE, {BrowserThread::UI}, base::BindOnce(&CreateNetworkFactoryForNavigationPreloadOnUI, - web_contents_getter, std::move(context_wrapper), + frame_tree_node_id, std::move(context_wrapper), mojo::MakeRequest(&network_factory))); factory = base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>( std::move(network_factory));
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.h b/content/browser/service_worker/service_worker_fetch_dispatcher.h index 14222de..a7940e04 100644 --- a/content/browser/service_worker/service_worker_fetch_dispatcher.h +++ b/content/browser/service_worker/service_worker_fetch_dispatcher.h
@@ -66,7 +66,7 @@ const network::ResourceRequest& original_request, URLLoaderFactoryGetter* url_loader_factory_getter, scoped_refptr<ServiceWorkerContextWrapper> context_wrapper, - const WebContentsGetter& web_contents_getter); + int frame_tree_node_id); // Dispatches a fetch event to the |version| given in ctor, and fires // |fetch_callback_| (also given in ctor) once a response is received from the
diff --git a/content/browser/service_worker/service_worker_navigation_loader.cc b/content/browser/service_worker/service_worker_navigation_loader.cc index 0b0ebb5..4a1699b 100644 --- a/content/browser/service_worker/service_worker_navigation_loader.cc +++ b/content/browser/service_worker/service_worker_navigation_loader.cc
@@ -223,7 +223,7 @@ weak_factory_.GetWeakPtr())); did_navigation_preload_ = fetch_dispatcher_->MaybeStartNavigationPreload( resource_request_, url_loader_factory_getter_.get(), std::move(context), - provider_host_->web_contents_getter()); + provider_host_->frame_tree_node_id()); // Record worker start time here as |fetch_dispatcher_| will start a service // worker if there is no running service worker.
diff --git a/content/browser/service_worker/service_worker_provider_host.h b/content/browser/service_worker/service_worker_provider_host.h index 5a62b7c..7911b526 100644 --- a/content/browser/service_worker/service_worker_provider_host.h +++ b/content/browser/service_worker/service_worker_provider_host.h
@@ -164,6 +164,7 @@ const WebContentsGetter& web_contents_getter() const { return web_contents_getter_; } + int frame_tree_node_id() const { return frame_tree_node_id_; } bool is_parent_frame_secure() const { return is_parent_frame_secure_; }
diff --git a/content/browser/storage_partition_impl_browsertest.cc b/content/browser/storage_partition_impl_browsertest.cc index d1f5c03..0d232a9 100644 --- a/content/browser/storage_partition_impl_browsertest.cc +++ b/content/browser/storage_partition_impl_browsertest.cc
@@ -160,7 +160,7 @@ base::ScopedAllowBlockingForTesting allow_blocking; std::unique_ptr<ShellBrowserContext> browser_context = - std::make_unique<ShellBrowserContext>(true, nullptr); + std::make_unique<ShellBrowserContext>(true); auto* partition = BrowserContext::GetDefaultStoragePartition(browser_context.get()); auto shared_url_loader_factory_info = @@ -184,7 +184,7 @@ base::ScopedAllowBlockingForTesting allow_blocking; std::unique_ptr<ShellBrowserContext> browser_context = - std::make_unique<ShellBrowserContext>(true, nullptr); + std::make_unique<ShellBrowserContext>(true); auto* partition = BrowserContext::GetDefaultStoragePartition(browser_context.get()); auto factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create( @@ -207,7 +207,7 @@ base::ScopedAllowBlockingForTesting allow_blocking; std::unique_ptr<ShellBrowserContext> browser_context = - std::make_unique<ShellBrowserContext>(true, nullptr); + std::make_unique<ShellBrowserContext>(true); auto* partition = BrowserContext::GetDefaultStoragePartition(browser_context.get());
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index b504f37..ba964827 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -40,7 +40,6 @@ #include "components/download/public/common/download_stats.h" #include "components/rappor/public/rappor_utils.h" #include "components/url_formatter/url_formatter.h" -#include "content/browser/accessibility/accessibility_tree_formatter.h" #include "content/browser/accessibility/accessibility_tree_formatter_blink.h" #include "content/browser/bad_message.h" #include "content/browser/browser_main_loop.h"
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc index e75ece1..7a540c1 100644 --- a/content/browser/web_contents/web_contents_impl_browsertest.cc +++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -977,33 +977,35 @@ } protected: - bool TestResourceLoadFromDedicatedWorker(const GURL& url, - const GURL& worker) { - // Do a cross-process navigation to clear the in-memory cache. - // We assume that we don't start this call from "chrome://gpu", as - // otherwise it won't be a cross-process navigation. We are relying - // on this navigation to discard the old process. - EXPECT_TRUE(NavigateToURL(shell(), GetWebUIURL("gpu"))); - - // Observe network requests. - ResourceLoadObserver observer(shell()); - - EXPECT_TRUE(NavigateToURL(shell(), url)); - - const char kLoadWorkerScript[] = "let w = new Worker('%s');"; - std::string create_worker_script = - base::StringPrintf(kLoadWorkerScript, worker.spec().c_str()); - - EXPECT_TRUE(ExecuteScript(shell(), create_worker_script)); - - GURL resource = GenURL("3p.com", "/script"); - observer.WaitForResourceCompletion(resource); - return (*observer.FindResource(resource))->was_cached; + // Loads 3p.com/script on page |url|, optionally from |sub_frame| if it's + // valid, and returns whether the script was cached or not. + bool TestResourceLoad(const GURL& url, const GURL& sub_frame) { + return TestResourceLoadHelper(url, sub_frame, GURL()); } - // Loads 3p.com/script on page |url|, optionally from |sub_frame| if it's - // valid and return if the script was cached or not. - bool TestResourceLoad(const GURL& url, const GURL& sub_frame) { + // Loads 3p.com/script on page |url| from |worker| and returns whether + // the script was cached or not. + bool TestResourceLoadFromDedicatedWorker(const GURL& url, + const GURL& worker) { + DCHECK(worker.is_valid()); + return TestResourceLoadHelper(url, GURL(), worker); + } + + // Loads 3p.com/script on page |url| from |worker| inside |sub_frame| + // and returns whether the script was cached or not. + bool TestResourceLoadFromDedicatedWorkerInIframe(const GURL& url, + const GURL& sub_frame, + const GURL& worker) { + DCHECK(sub_frame.is_valid()); + DCHECK(worker.is_valid()); + return TestResourceLoadHelper(url, sub_frame, worker); + } + + bool TestResourceLoadHelper(const GURL& url, + const GURL& sub_frame, + const GURL& worker) { + DCHECK(url.is_valid()); + // Do a cross-process navigation to clear the in-memory cache. // We assume that we don't start this call from "chrome://gpu", as // otherwise it won't be a cross-process navigation. We are relying @@ -1027,13 +1029,13 @@ // If there is supposed to be a sub-frame, create it. if (sub_frame.is_valid()) { - const char kLoadIframeScript[] = - "var iframe = document.createElement('iframe');" - "iframe.src='%s';" - "document.body.appendChild(iframe);"; - std::string create_iframe_script = - base::StringPrintf(kLoadIframeScript, sub_frame.spec().c_str()); - EXPECT_TRUE(ExecuteScript(shell(), create_iframe_script)); + const char kLoadIframeScript[] = R"( + let iframe = document.createElement('iframe'); + iframe.src = $1; + document.body.appendChild(iframe); + )"; + EXPECT_TRUE( + ExecuteScript(shell(), JsReplace(kLoadIframeScript, sub_frame))); EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); host_to_load_resource = @@ -1044,16 +1046,22 @@ ->current_frame_host(); } - const char kLoadResourceScript[] = R"( - var script = document.createElement("script"); - script.src = '%s'; - document.body.appendChild(script); - )"; GURL resource = GenURL("3p.com", "/script"); - std::string loader_script = - base::StringPrintf(kLoadResourceScript, resource.spec().c_str()); - EXPECT_TRUE(ExecuteScript(host_to_load_resource, loader_script)); + if (worker.is_valid()) { + const char kLoadWorkerScript[] = R"(let w = new Worker($1);)"; + EXPECT_TRUE(ExecuteScript(host_to_load_resource, + JsReplace(kLoadWorkerScript, worker))); + } else { + const char kLoadResourceScript[] = R"( + let script = document.createElement('script'); + script.src = $1; + document.body.appendChild(script); + )"; + EXPECT_TRUE(ExecuteScript(host_to_load_resource, + JsReplace(kLoadResourceScript, resource))); + } + observer.WaitForResourceCompletion(resource); // Test the network isolation key. @@ -1189,7 +1197,7 @@ EXPECT_TRUE(TestResourceLoadFromDedicatedWorker( GenURL("a.com", "/title1.html"), GenURL("a.com", "/worker.js"))); - // Load 3p.com/script from a worker with a new top frame origin. Due to split + // Load 3p.com/script from a worker with a new top-frame origin. Due to split // caching it's a cache miss. EXPECT_FALSE(TestResourceLoadFromDedicatedWorker( GenURL("b.com", "/title1.html"), GenURL("b.com", "/worker.js"))); @@ -1204,6 +1212,24 @@ EXPECT_TRUE(TestResourceLoadFromDedicatedWorker( GenURL("c.com", "/title1.html"), GenURL("c.com", "/embedding_worker.js?c"))); + + // Load 3p.com/script from a worker with a new top-frame origin and nested in + // a cross-origin iframe. Due to split caching it's a cache miss. + EXPECT_FALSE(TestResourceLoadFromDedicatedWorkerInIframe( + GenURL("d.com", "/title1.html"), GenURL("e.com", "/title1.html"), + GenURL("e.com", "/worker.js"))); + EXPECT_TRUE(TestResourceLoadFromDedicatedWorkerInIframe( + GenURL("d.com", "/title1.html"), GenURL("e.com", "/title1.html"), + GenURL("e.com", "/worker.js"))); + + // Load 3p.com/script from a worker with a new top-frame origin and nested in + // a cross-origin iframe whose URL has previously been loaded. + EXPECT_FALSE(TestResourceLoadFromDedicatedWorkerInIframe( + GenURL("f.com", "/title1.html"), GenURL("e.com", "/title1.html"), + GenURL("e.com", "/worker.js"))); + EXPECT_TRUE(TestResourceLoadFromDedicatedWorkerInIframe( + GenURL("f.com", "/title1.html"), GenURL("e.com", "/title1.html"), + GenURL("e.com", "/worker.js"))); } IN_PROC_BROWSER_TEST_F(WebContentsSplitCacheBrowserTestDisabled, @@ -1215,16 +1241,26 @@ EXPECT_TRUE(TestResourceLoadFromDedicatedWorker( GenURL("a.com", "/title1.html"), GenURL("a.com", "/worker.js"))); - // Load 3p.com/script from b.com's worker. The cache isn't split by top frame + // Load 3p.com/script from b.com's worker. The cache isn't split by top-frame // origin so the resource is already cached. EXPECT_TRUE(TestResourceLoadFromDedicatedWorker( GenURL("b.com", "/title1.html"), GenURL("b.com", "/worker.js"))); // Load 3p.com/script from a nested worker with a new top-frame origin. The - // cache isn't split by top frame origin so the resource is already cached. + // cache isn't split by top-frame origin so the resource is already cached. EXPECT_TRUE(TestResourceLoadFromDedicatedWorker( GenURL("c.com", "/title1.html"), GenURL("c.com", "/embedding_worker.js?c"))); + + // Load 3p.com/script from a worker with a new top-frame origin and nested in + // a cross-origin iframe. The cache isn't split by top-frame origin so the + // resource is already cached. + EXPECT_TRUE(TestResourceLoadFromDedicatedWorkerInIframe( + GenURL("d.com", "/title1.html"), GenURL("e.com", "/title1.html"), + GenURL("e.com", "/worker.js"))); + EXPECT_TRUE(TestResourceLoadFromDedicatedWorkerInIframe( + GenURL("f.com", "/title1.html"), GenURL("e.com", "/title1.html"), + GenURL("e.com", "/worker.js"))); } IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc index a17f373..7954f085 100644 --- a/content/browser/web_contents/web_contents_impl_unittest.cc +++ b/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -3001,7 +3001,8 @@ // Navigate the frame to another URL, which will send again // DidStartLoading and DidStopLoading messages. - NavigationSimulator::NavigateAndCommitFromDocument(foo_url, subframe); + subframe = static_cast<TestRenderFrameHost*>( + NavigationSimulator::NavigateAndCommitFromDocument(foo_url, subframe)); subframe->OnMessageReceived( FrameHostMsg_DidStopLoading(subframe->GetRoutingID())); @@ -3017,10 +3018,11 @@ { auto navigation = NavigationSimulatorImpl::CreateBrowserInitiated(bar_url, contents()); + NavigationController::LoadURLParams load_params(bar_url); load_params.referrer = Referrer(GURL("http://referrer"), network::mojom::ReferrerPolicy::kDefault); - load_params.transition_type = ui::PAGE_TRANSITION_GENERATED; + load_params.transition_type = ui::PAGE_TRANSITION_MANUAL_SUBFRAME; load_params.extra_headers = "content-type: text/plain"; load_params.load_type = NavigationController::LOAD_TYPE_DEFAULT; load_params.is_renderer_initiated = false; @@ -3028,14 +3030,11 @@ load_params.frame_tree_node_id = subframe->frame_tree_node()->frame_tree_node_id(); navigation->SetLoadURLParams(&load_params); - navigation->Start(); - entry_id = controller().GetPendingEntry()->GetUniqueID(); - // Commit the navigation in the child frame and send the DidStopLoading - // message. - subframe->PrepareForCommit(); - contents()->TestDidNavigate(subframe, entry_id, true, bar_url, - ui::PAGE_TRANSITION_MANUAL_SUBFRAME); + navigation->Commit(); + subframe = static_cast<TestRenderFrameHost*>( + navigation->GetFinalRenderFrameHost()); + subframe->OnMessageReceived( FrameHostMsg_DidStopLoading(subframe->GetRoutingID())); }
diff --git a/content/child/child_thread_impl.cc b/content/child/child_thread_impl.cc index 691259ba..979c895 100644 --- a/content/child/child_thread_impl.cc +++ b/content/child/child_thread_impl.cc
@@ -58,7 +58,6 @@ #include "ipc/ipc_sync_channel.h" #include "ipc/ipc_sync_message_filter.h" #include "mojo/core/embedder/scoped_ipc_support.h" -#include "mojo/public/cpp/platform/features.h" #include "mojo/public/cpp/platform/named_platform_channel.h" #include "mojo/public/cpp/platform/platform_channel.h" #include "mojo/public/cpp/platform/platform_channel_endpoint.h" @@ -197,31 +196,23 @@ #elif defined(OS_FUCHSIA) endpoint = mojo::PlatformChannel::RecoverPassedEndpointFromCommandLine( *base::CommandLine::ForCurrentProcess()); -#elif defined(OS_POSIX) - -#if defined(OS_MACOSX) - if (base::FeatureList::IsEnabled(mojo::features::kMojoChannelMac)) { - auto* client = base::MachPortRendezvousClient::GetInstance(); - if (!client) { - LOG(ERROR) << "Mach rendezvous failed."; - return base::nullopt; - } - auto receive = client->TakeReceiveRight('mojo'); - if (!receive.is_valid()) { - LOG(ERROR) << "Invalid PlatformChannel receive right"; - return base::nullopt; - } - endpoint = - mojo::PlatformChannelEndpoint(mojo::PlatformHandle(std::move(receive))); - } else { -#endif // defined(OS_MACOSX) - endpoint = mojo::PlatformChannelEndpoint(mojo::PlatformHandle( - base::ScopedFD(base::GlobalDescriptors::GetInstance()->Get( - service_manager::kMojoIPCChannel)))); -#if defined(OS_MACOSX) +#elif defined(OS_MACOSX) + auto* client = base::MachPortRendezvousClient::GetInstance(); + if (!client) { + LOG(ERROR) << "Mach rendezvous failed."; + return base::nullopt; } -#endif - + auto receive = client->TakeReceiveRight('mojo'); + if (!receive.is_valid()) { + LOG(ERROR) << "Invalid PlatformChannel receive right"; + return base::nullopt; + } + endpoint = + mojo::PlatformChannelEndpoint(mojo::PlatformHandle(std::move(receive))); +#elif defined(OS_POSIX) + endpoint = mojo::PlatformChannelEndpoint(mojo::PlatformHandle( + base::ScopedFD(base::GlobalDescriptors::GetInstance()->Get( + service_manager::kMojoIPCChannel)))); #endif // Mojo isn't supported on all child process types. // TODO(crbug.com/604282): Support Mojo in the remaining processes.
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index de68f01..831ca5d 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -66,9 +66,6 @@ WebRuntimeFeatures::EnableBlinkHeapIncrementalMarking( base::FeatureList::IsEnabled(features::kBlinkHeapIncrementalMarking)); - if (base::FeatureList::IsEnabled(features::kBloatedRendererDetection)) - WebRuntimeFeatures::EnableBloatedRendererDetection(true); - if (base::FeatureList::IsEnabled( blink::features::kBlockingFocusWithoutUserActivation)) { WebRuntimeFeatures::EnableBlockingFocusWithoutUserActivation(true);
diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc index 35be2f6..5433738 100644 --- a/content/gpu/gpu_main.cc +++ b/content/gpu/gpu_main.cc
@@ -296,11 +296,13 @@ base::PlatformThread::SetName("CrGpuMain"); +#if !defined(OS_MACOSX) if (base::FeatureList::IsEnabled(features::kGpuUseDisplayThreadPriority)) { // Set thread priority before sandbox initialization. base::PlatformThread::SetCurrentThreadPriority( base::ThreadPriority::DISPLAY); } +#endif auto gpu_init = std::make_unique<gpu::GpuInit>(); ContentSandboxHelper sandbox_helper;
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn index b3a677c..37d805b 100644 --- a/content/public/browser/BUILD.gn +++ b/content/public/browser/BUILD.gn
@@ -24,6 +24,7 @@ # External code should depend on via ":browser" above. visibility = [ "//content/*" ] sources = [ + "accessibility_tree_formatter.h", "android/android_overlay_provider.h", "android/child_process_importance.h", "android/compositor.h",
diff --git a/content/browser/accessibility/accessibility_tree_formatter.h b/content/public/browser/accessibility_tree_formatter.h similarity index 61% rename from content/browser/accessibility/accessibility_tree_formatter.h rename to content/public/browser/accessibility_tree_formatter.h index 45d934c..0a94707 100644 --- a/content/browser/accessibility/accessibility_tree_formatter.h +++ b/content/public/browser/accessibility_tree_formatter.h
@@ -1,9 +1,9 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2019 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_H_ -#define CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_H_ +#ifndef CONTENT_PUBLIC_BROWSER_ACCESSIBILITY_TREE_FORMATTER_H_ +#define CONTENT_PUBLIC_BROWSER_ACCESSIBILITY_TREE_FORMATTER_H_ #include <stdint.h> @@ -16,28 +16,25 @@ #include "base/strings/string_piece.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" -#include "content/browser/accessibility/browser_accessibility.h" #include "content/common/content_export.h" #include "ui/gfx/native_widget_types.h" -namespace { -const char kChildrenDictAttr[] = "children"; -} - namespace base { class CommandLine; } namespace content { +class BrowserAccessibility; +class BrowserAccessibilityManager; + // A utility class for formatting platform-specific accessibility information, // for use in testing, debugging, and developer tools. // This is extended by a subclass for each platform where accessibility is // implemented. class CONTENT_EXPORT AccessibilityTreeFormatter { public: - explicit AccessibilityTreeFormatter(); - virtual ~AccessibilityTreeFormatter(); + virtual ~AccessibilityTreeFormatter() = default; // A single property filter specification. See GetAllowString() and // GetDenyString() for more information. @@ -79,7 +76,8 @@ }; static std::vector<TestPass> GetTestPasses(); - virtual void AddDefaultFilters(std::vector<PropertyFilter>* property_filters); + virtual void AddDefaultFilters( + std::vector<PropertyFilter>* property_filters) = 0; static bool MatchesPropertyFilters( const std::vector<PropertyFilter>& property_filters, @@ -129,14 +127,14 @@ // Returns a filtered accesibility tree using the current property and node // filters. - std::unique_ptr<base::DictionaryValue> FilterAccessibilityTree( - const base::DictionaryValue& dict); + virtual std::unique_ptr<base::DictionaryValue> FilterAccessibilityTree( + const base::DictionaryValue& dict) = 0; // Dumps a BrowserAccessibility tree into a string. - void FormatAccessibilityTree(BrowserAccessibility* root, - base::string16* contents); - void FormatAccessibilityTree(const base::DictionaryValue& tree_node, - base::string16* contents); + virtual void FormatAccessibilityTree(BrowserAccessibility* root, + base::string16* contents) = 0; + virtual void FormatAccessibilityTree(const base::DictionaryValue& tree_node, + base::string16* contents) = 0; static base::string16 DumpAccessibilityTreeFromManager( BrowserAccessibilityManager* ax_mgr, @@ -144,14 +142,15 @@ // Set regular expression filters that apply to each property of every node // before it's output. - void SetPropertyFilters(const std::vector<PropertyFilter>& property_filters); + virtual void SetPropertyFilters( + const std::vector<PropertyFilter>& property_filters) = 0; // Set regular expression filters that apply to every node before output. - void SetNodeFilters(const std::vector<NodeFilter>& node_filters); + virtual void SetNodeFilters(const std::vector<NodeFilter>& node_filters) = 0; // If true, the internal accessibility id of each node will be included // in its output. - void set_show_ids(bool show_ids) { show_ids_ = show_ids; } + virtual void set_show_ids(bool show_ids) = 0; // Suffix of the expectation file corresponding to html file. // Overridden by each platform subclass. @@ -163,7 +162,7 @@ // Most test outputs are identical but this allows a version specific // expected file to be used. virtual const base::FilePath::StringType - GetVersionSpecificExpectedFileSuffix(); + GetVersionSpecificExpectedFileSuffix() = 0; // A string that indicates a given line in a file is an allow-empty, // allow or deny filter. Overridden by each platform subclass. Example: @@ -184,71 +183,6 @@ virtual const std::string GetAllowString() = 0; virtual const std::string GetDenyString() = 0; virtual const std::string GetDenyNodeString() = 0; - - protected: - // - // Overridden by platform subclasses. - // - - // Process accessibility tree with filters for output. - // Given a dictionary that contains a platform-specific dictionary - // representing an accessibility tree, and utilizing property_filters_ and - // node_filters_: - // - Returns a filtered text view as one large string. - // - Provides a filtered version of the dictionary in an out param, - // (only if the out param is provided). - virtual base::string16 ProcessTreeForOutput( - const base::DictionaryValue& node, - base::DictionaryValue* filtered_dict_result = nullptr) = 0; - - // - // Utility functions to be used by each platform. - // - - base::string16 FormatCoordinates(const char* name, - const char* x_name, - const char* y_name, - const base::DictionaryValue& value); - - // Writes the given attribute string out to |line| if it matches the property - // filters. - // Returns false if the attribute was filtered out. - bool WriteAttribute(bool include_by_default, - const base::string16& attr, - base::string16* line); - bool WriteAttribute(bool include_by_default, - const std::string& attr, - base::string16* line); - void AddPropertyFilter(std::vector<PropertyFilter>* property_filters, - std::string filter, - PropertyFilter::Type type = PropertyFilter::ALLOW); - bool show_ids() { return show_ids_; } - - private: - void RecursiveFormatAccessibilityTree(const BrowserAccessibility& node, - base::string16* contents, - int indent); - void RecursiveFormatAccessibilityTree(const base::DictionaryValue& tree_node, - base::string16* contents, - int depth = 0); - - bool MatchesPropertyFilters(const base::string16& text, - bool default_result) const; - bool MatchesNodeFilters(const base::DictionaryValue& dict) const; - - // Property filters used when formatting the accessibility tree as text. - // Any property which matches a property filter will be skipped. - std::vector<PropertyFilter> property_filters_; - - // Node filters used when formatting the accessibility tree as text. - // Any node which matches a node wilder will be skipped, along with all its - // children. - std::vector<NodeFilter> node_filters_; - - // Whether or not node ids should be included in the dump. - bool show_ids_; - - DISALLOW_COPY_AND_ASSIGN(AccessibilityTreeFormatter); }; } // namespace content
diff --git a/content/public/browser/payment_app_provider.h b/content/public/browser/payment_app_provider.h index 4cfb416..34546bba 100644 --- a/content/public/browser/payment_app_provider.h +++ b/content/public/browser/payment_app_provider.h
@@ -77,7 +77,9 @@ // Notify the opened payment handler window is closing or closed by user so as // to abort payment request. - virtual void OnClosingOpenedWindow(BrowserContext* browser_context) = 0; + virtual void OnClosingOpenedWindow( + BrowserContext* browser_context, + payments::mojom::PaymentEventResponseType reason) = 0; // Check whether given |sw_js_url| from |manifest_url| is allowed to register // with |sw_scope|.
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 630b3ac..813136ca 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -42,10 +42,10 @@ // Creates audio output and input streams using the audio service. const base::Feature kAudioServiceAudioStreams{ "AudioServiceAudioStreams", -#if defined(OS_MACOSX) || defined(OS_LINUX) - base::FEATURE_ENABLED_BY_DEFAULT -#else +#if defined(OS_WIN) base::FEATURE_DISABLED_BY_DEFAULT +#else + base::FEATURE_ENABLED_BY_DEFAULT #endif }; @@ -76,10 +76,6 @@ const base::Feature kBlinkHeapIncrementalMarking{ "BlinkHeapIncrementalMarking", base::FEATURE_ENABLED_BY_DEFAULT}; -// Enable bloated renderer detection. -const base::Feature kBloatedRendererDetection{ - "BloatedRendererDetection", base::FEATURE_DISABLED_BY_DEFAULT}; - // Allows swipe left/right from touchpad change browser navigation. Currently // only enabled by default on CrOS. const base::Feature kTouchpadOverscrollHistoryNavigation { @@ -736,6 +732,15 @@ const base::Feature kTrustedDOMTypes{"TrustedDOMTypes", base::FEATURE_DISABLED_BY_DEFAULT}; +// Use ThreadPriority::DISPLAY for browser UI and IO threads. +#if defined(OS_ANDROID) || defined(OS_CHROMEOS) +const base::Feature kBrowserUseDisplayThreadPriority{ + "BrowserUseDisplayThreadPriority", base::FEATURE_ENABLED_BY_DEFAULT}; +#else +const base::Feature kBrowserUseDisplayThreadPriority{ + "BrowserUseDisplayThreadPriority", base::FEATURE_DISABLED_BY_DEFAULT}; +#endif + #if defined(OS_ANDROID) // Autofill Accessibility in Android. // crbug.com/627860
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index 88262cda..7b7ceb56 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -29,7 +29,6 @@ CONTENT_EXPORT extern const base::Feature kBackgroundFetch; CONTENT_EXPORT extern const base::Feature kBackForwardCache; CONTENT_EXPORT extern const base::Feature kBlinkHeapIncrementalMarking; -CONTENT_EXPORT extern const base::Feature kBloatedRendererDetection; CONTENT_EXPORT extern const base::Feature kBlockCredentialedSubresources; CONTENT_EXPORT extern const base::Feature kBundledHTTPExchanges; CONTENT_EXPORT extern const base::Feature kCacheInlineScriptCode; @@ -154,6 +153,7 @@ CONTENT_EXPORT extern const base::Feature kWebXrPlaneDetection; CONTENT_EXPORT extern const base::Feature kScriptStreamingOnPreload; CONTENT_EXPORT extern const base::Feature kTrustedDOMTypes; +CONTENT_EXPORT extern const base::Feature kBrowserUseDisplayThreadPriority; #if defined(OS_ANDROID) CONTENT_EXPORT extern const base::Feature kAndroidAutofillAccessibility;
diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc index 5bbfd2f..34769f4 100644 --- a/content/renderer/browser_plugin/browser_plugin.cc +++ b/content/renderer/browser_plugin/browser_plugin.cc
@@ -587,6 +587,8 @@ if (blink::WebInputEvent::IsGestureEventType(event.GetType())) { auto gesture_event = static_cast<const blink::WebGestureEvent&>(event); DCHECK(blink::WebInputEvent::kGestureTapDown == event.GetType() || + blink::WebInputEvent::kGestureScrollBegin == event.GetType() || + blink::WebInputEvent::kGestureScrollEnd == event.GetType() || gesture_event.resending_plugin_id == browser_plugin_instance_id_); // We shouldn't be forwarding GestureEvents to the Guest anymore. Indicate
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 03ad3a2..4217051 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -7025,29 +7025,6 @@ commit_params.current_history_list_length; } -namespace { -std::unique_ptr<base::DictionaryValue> GetDevToolsInitiator( - const WebString& initiator_str) { - if (initiator_str.IsNull()) - return nullptr; - std::unique_ptr<base::DictionaryValue> initiator = - base::DictionaryValue::From( - base::JSONReader::ReadDeprecated(initiator_str.Utf8())); - if (!initiator) - return nullptr; - // TODO(kozy,caseq): the hack below is due to the fact that initiators include - // the chain of async callstacks that results in a tree of Values so deep - // that it triggers mojo structure nesting limit upon deserialization. - // See https://crbug.com/809996 for more details. - // We trim async stacks here, but it should be possible to capture locations - // without async stacks (or with custom limit on their number) instead. - base::Value* parent = initiator->FindPath({"stack", "parent"}); - if (parent && parent->is_dict()) - parent->RemoveKey("parent"); - return initiator; -} -} // namespace - void RenderFrameImpl::BeginNavigationInternal( std::unique_ptr<blink::WebNavigationInfo> info, bool is_history_navigation_in_new_child_frame) { @@ -7135,8 +7112,11 @@ CloneBlobURLToken(info->blob_url_token.get())); int load_flags = info->url_request.GetLoadFlagsForWebUrlRequest(); - std::unique_ptr<base::DictionaryValue> initiator = - GetDevToolsInitiator(info->devtools_initiator_info); + std::unique_ptr<base::DictionaryValue> initiator; + if (!info->devtools_initiator_info.IsNull()) { + initiator = base::DictionaryValue::From( + base::JSONReader::ReadDeprecated(info->devtools_initiator_info.Utf8())); + } mojom::BeginNavigationParamsPtr begin_navigation_params = mojom::BeginNavigationParams::New( GetWebURLRequestHeadersAsString(info->url_request), load_flags,
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn index 08d7b85..bb3b556 100644 --- a/content/shell/BUILD.gn +++ b/content/shell/BUILD.gn
@@ -137,8 +137,6 @@ "browser/shell_javascript_dialog_manager.h", "browser/shell_javascript_dialog_win.cc", "browser/shell_mac.mm", - "browser/shell_net_log.cc", - "browser/shell_net_log.h", "browser/shell_network_delegate.cc", "browser/shell_network_delegate.h", "browser/shell_permission_manager.cc",
diff --git a/content/shell/browser/shell_browser_context.cc b/content/shell/browser/shell_browser_context.cc index 226d5b3..12bbe1e 100644 --- a/content/shell/browser/shell_browser_context.cc +++ b/content/shell/browser/shell_browser_context.cc
@@ -48,12 +48,10 @@ } ShellBrowserContext::ShellBrowserContext(bool off_the_record, - net::NetLog* net_log, bool delay_services_creation) : resource_context_(new ShellResourceContext), ignore_certificate_errors_(false), off_the_record_(off_the_record), - net_log_(net_log), guest_manager_(nullptr) { InitWhileIOAllowed(); if (!delay_services_creation) { @@ -179,7 +177,7 @@ return new ShellURLRequestContextGetter( ignore_certificate_errors_, off_the_record_, GetPath(), base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}), - protocol_handlers, std::move(request_interceptors), net_log_); + protocol_handlers, std::move(request_interceptors)); } net::URLRequestContextGetter* ShellBrowserContext::CreateRequestContext(
diff --git a/content/shell/browser/shell_browser_context.h b/content/shell/browser/shell_browser_context.h index 14919de..abadbde 100644 --- a/content/shell/browser/shell_browser_context.h +++ b/content/shell/browser/shell_browser_context.h
@@ -20,10 +20,6 @@ class SimpleFactoryKey; -namespace net { -class NetLog; -} - namespace content { class BackgroundSyncController; @@ -39,7 +35,6 @@ // If |delay_services_creation| is true, the owner is responsible for calling // CreateBrowserContextServices() for this BrowserContext. ShellBrowserContext(bool off_the_record, - net::NetLog* net_log, bool delay_services_creation = false); ~ShellBrowserContext() override; @@ -97,7 +92,6 @@ } bool ignore_certificate_errors() const { return ignore_certificate_errors_; } - net::NetLog* net_log() const { return net_log_; } std::unique_ptr<ShellResourceContext> resource_context_; std::unique_ptr<ShellDownloadManagerDelegate> download_manager_delegate_; @@ -112,7 +106,6 @@ bool ignore_certificate_errors_; bool off_the_record_; - net::NetLog* net_log_; base::FilePath path_; BrowserPluginGuestManager* guest_manager_; scoped_refptr<ShellURLRequestContextGetter> url_request_getter_;
diff --git a/content/shell/browser/shell_browser_main_parts.cc b/content/shell/browser/shell_browser_main_parts.cc index 266b1e0..09d0eac 100644 --- a/content/shell/browser/shell_browser_main_parts.cc +++ b/content/shell/browser/shell_browser_main_parts.cc
@@ -24,7 +24,6 @@ #include "content/shell/browser/shell.h" #include "content/shell/browser/shell_browser_context.h" #include "content/shell/browser/shell_devtools_manager_delegate.h" -#include "content/shell/browser/shell_net_log.h" #include "content/shell/common/shell_switches.h" #include "device/bluetooth/bluetooth_adapter_factory.h" #include "net/base/filename_util.h" @@ -137,9 +136,8 @@ } void ShellBrowserMainParts::InitializeBrowserContexts() { - set_browser_context(new ShellBrowserContext(false, net_log_.get())); - set_off_the_record_browser_context( - new ShellBrowserContext(true, net_log_.get())); + set_browser_context(new ShellBrowserContext(false)); + set_off_the_record_browser_context(new ShellBrowserContext(true)); } void ShellBrowserMainParts::InitializeMessageLoopContext() { @@ -158,8 +156,6 @@ std::make_unique<crash_reporter::ChildProcessCrashObserver>()); } #endif - - net_log_ = std::make_unique<ShellNetLog>("content_shell"); return 0; }
diff --git a/content/shell/browser/shell_browser_main_parts.h b/content/shell/browser/shell_browser_main_parts.h index 09de5a0..17ed638a 100644 --- a/content/shell/browser/shell_browser_main_parts.h +++ b/content/shell/browser/shell_browser_main_parts.h
@@ -14,10 +14,6 @@ #include "content/public/common/main_function_params.h" #include "content/shell/browser/shell_browser_context.h" -namespace net { -class NetLog; -} - namespace content { class ShellBrowserMainParts : public BrowserMainParts { @@ -41,8 +37,6 @@ return off_the_record_browser_context_.get(); } - net::NetLog* net_log() { return net_log_.get(); } - protected: virtual void InitializeBrowserContexts(); virtual void InitializeMessageLoopContext(); @@ -56,7 +50,6 @@ private: - std::unique_ptr<net::NetLog> net_log_; std::unique_ptr<ShellBrowserContext> browser_context_; std::unique_ptr<ShellBrowserContext> off_the_record_browser_context_;
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc index 22624464..47d16f6 100644 --- a/content/shell/browser/shell_content_browser_client.cc +++ b/content/shell/browser/shell_content_browser_client.cc
@@ -38,7 +38,6 @@ #include "content/shell/browser/shell_browser_context.h" #include "content/shell/browser/shell_browser_main_parts.h" #include "content/shell/browser/shell_devtools_manager_delegate.h" -#include "content/shell/browser/shell_net_log.h" #include "content/shell/browser/shell_quota_permission_context.h" #include "content/shell/browser/shell_url_request_context_getter.h" #include "content/shell/browser/shell_web_contents_view_delegate_creator.h"
diff --git a/content/shell/browser/shell_net_log.cc b/content/shell/browser/shell_net_log.cc deleted file mode 100644 index 8837dd14..0000000 --- a/content/shell/browser/shell_net_log.cc +++ /dev/null
@@ -1,67 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/shell/browser/shell_net_log.h" - -#include <stdio.h> - -#include <utility> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/command_line.h" -#include "base/files/file_path.h" -#include "base/values.h" -#include "build/build_config.h" -#include "content/public/common/content_switches.h" -#include "net/log/file_net_log_observer.h" -#include "net/log/net_log_util.h" -#include "services/network/public/cpp/network_switches.h" - -namespace content { - -namespace { - -std::unique_ptr<base::DictionaryValue> GetShellConstants( - const std::string& app_name) { - std::unique_ptr<base::DictionaryValue> constants_dict = - net::GetNetConstants(); - - // Add a dictionary with client information - auto dict = std::make_unique<base::DictionaryValue>(); - - dict->SetString("name", app_name); - dict->SetString( - "command_line", - base::CommandLine::ForCurrentProcess()->GetCommandLineString()); - - constants_dict->Set("clientInfo", std::move(dict)); - - return constants_dict; -} - -} // namespace - -ShellNetLog::ShellNetLog(const std::string& app_name) { - const base::CommandLine* command_line = - base::CommandLine::ForCurrentProcess(); - - if (command_line->HasSwitch(network::switches::kLogNetLog)) { - base::FilePath log_path = - command_line->GetSwitchValuePath(network::switches::kLogNetLog); - net::NetLogCaptureMode capture_mode = net::NetLogCaptureMode::Default(); - - file_net_log_observer_ = net::FileNetLogObserver::CreateUnbounded( - log_path, GetShellConstants(app_name)); - file_net_log_observer_->StartObserving(this, capture_mode); - } -} - -ShellNetLog::~ShellNetLog() { - // Remove the observer we own before we're destroyed. - if (file_net_log_observer_) - file_net_log_observer_->StopObserving(nullptr, base::OnceClosure()); -} - -} // namespace content
diff --git a/content/shell/browser/shell_net_log.h b/content/shell/browser/shell_net_log.h deleted file mode 100644 index 13ac91b..0000000 --- a/content/shell/browser/shell_net_log.h +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_SHELL_BROWSER_SHELL_NET_LOG_H_ -#define CONTENT_SHELL_BROWSER_SHELL_NET_LOG_H_ - -#include <memory> -#include <string> - -#include "base/macros.h" -#include "net/log/net_log.h" - -namespace net { -class FileNetLogObserver; -} - -namespace content { - -class ShellNetLog : public net::NetLog { - public: - explicit ShellNetLog(const std::string& app_name); - ~ShellNetLog() override; - - private: - std::unique_ptr<net::FileNetLogObserver> file_net_log_observer_; - - DISALLOW_COPY_AND_ASSIGN(ShellNetLog); -}; - -} // namespace content - -#endif // CONTENT_SHELL_BROWSER_SHELL_NET_LOG_H_
diff --git a/content/shell/browser/shell_url_request_context_getter.cc b/content/shell/browser/shell_url_request_context_getter.cc index a461c866..fc37df047 100644 --- a/content/shell/browser/shell_url_request_context_getter.cc +++ b/content/shell/browser/shell_url_request_context_getter.cc
@@ -87,14 +87,12 @@ const base::FilePath& base_path, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, ProtocolHandlerMap* protocol_handlers, - URLRequestInterceptorScopedVector request_interceptors, - net::NetLog* net_log) + URLRequestInterceptorScopedVector request_interceptors) : ignore_certificate_errors_(ignore_certificate_errors), off_the_record_(off_the_record), shut_down_(false), base_path_(base_path), io_task_runner_(std::move(io_task_runner)), - net_log_(net_log), request_interceptors_(std::move(request_interceptors)) { // Must first be created on the UI thread. DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -160,10 +158,10 @@ *base::CommandLine::ForCurrentProcess(); net::URLRequestContextBuilder builder; - builder.set_net_log(net_log_); + net::NetLog* net_log = nullptr; builder.set_network_delegate(CreateNetworkDelegate()); std::unique_ptr<net::CookieStore> cookie_store = - CreateCookieStore(CookieStoreConfig(), net_log_); + CreateCookieStore(CookieStoreConfig(), net_log); builder.SetCookieStore(std::move(cookie_store)); builder.set_accept_language(GetAcceptLanguages()); builder.set_user_agent(GetShellUserAgent());
diff --git a/content/shell/browser/shell_url_request_context_getter.h b/content/shell/browser/shell_url_request_context_getter.h index fa20e77..eec78ad 100644 --- a/content/shell/browser/shell_url_request_context_getter.h +++ b/content/shell/browser/shell_url_request_context_getter.h
@@ -21,7 +21,6 @@ namespace net { class CertVerifier; -class NetLog; class NetworkDelegate; class ProxyConfigService; class ProxyResolutionService; @@ -38,8 +37,7 @@ const base::FilePath& base_path, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, ProtocolHandlerMap* protocol_handlers, - URLRequestInterceptorScopedVector request_interceptors, - net::NetLog* net_log); + URLRequestInterceptorScopedVector request_interceptors); // net::URLRequestContextGetter implementation. net::URLRequestContext* GetURLRequestContext() override; @@ -75,7 +73,6 @@ bool shut_down_; base::FilePath base_path_; scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; - net::NetLog* net_log_; std::unique_ptr<net::ProxyConfigService> proxy_config_service_; std::unique_ptr<net::URLRequestContext> url_request_context_;
diff --git a/content/shell/browser/web_test/web_test_browser_context.cc b/content/shell/browser/web_test/web_test_browser_context.cc index 7fed044d..0635ec4d 100644 --- a/content/shell/browser/web_test/web_test_browser_context.cc +++ b/content/shell/browser/web_test/web_test_browser_context.cc
@@ -36,9 +36,8 @@ namespace content { -WebTestBrowserContext::WebTestBrowserContext(bool off_the_record, - net::NetLog* net_log) - : ShellBrowserContext(off_the_record, net_log) { +WebTestBrowserContext::WebTestBrowserContext(bool off_the_record) + : ShellBrowserContext(off_the_record) { // Overrides geolocation coordinates for testing. geolocation_overrider_ = std::make_unique<device::ScopedGeolocationOverrider>(0, 0); @@ -55,7 +54,7 @@ return new WebTestURLRequestContextGetter( ignore_certificate_errors(), IsOffTheRecord(), GetPath(), base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}), - protocol_handlers, std::move(request_interceptors), net_log()); + protocol_handlers, std::move(request_interceptors)); } DownloadManagerDelegate* WebTestBrowserContext::GetDownloadManagerDelegate() {
diff --git a/content/shell/browser/web_test/web_test_browser_context.h b/content/shell/browser/web_test/web_test_browser_context.h index ea98b141..22e140d8 100644 --- a/content/shell/browser/web_test/web_test_browser_context.h +++ b/content/shell/browser/web_test/web_test_browser_context.h
@@ -13,10 +13,6 @@ class ScopedGeolocationOverrider; } -namespace net { -class NetLog; -} - namespace content { class BackgroundSyncController; @@ -29,7 +25,7 @@ class WebTestBrowserContext final : public ShellBrowserContext { public: - WebTestBrowserContext(bool off_the_record, net::NetLog* net_log); + WebTestBrowserContext(bool off_the_record); ~WebTestBrowserContext() override; // BrowserContext implementation.
diff --git a/content/shell/browser/web_test/web_test_browser_main_parts.cc b/content/shell/browser/web_test/web_test_browser_main_parts.cc index 694b1ef4..8309fcfe 100644 --- a/content/shell/browser/web_test/web_test_browser_main_parts.cc +++ b/content/shell/browser/web_test/web_test_browser_main_parts.cc
@@ -19,7 +19,6 @@ #include "content/shell/browser/shell.h" #include "content/shell/browser/shell_browser_context.h" #include "content/shell/browser/shell_devtools_manager_delegate.h" -#include "content/shell/browser/shell_net_log.h" #include "content/shell/browser/web_test/web_test_browser_context.h" #include "content/shell/common/shell_switches.h" #include "net/base/filename_util.h" @@ -50,7 +49,7 @@ WebTestBrowserMainParts::~WebTestBrowserMainParts() {} void WebTestBrowserMainParts::InitializeBrowserContexts() { - set_browser_context(new WebTestBrowserContext(false, net_log())); + set_browser_context(new WebTestBrowserContext(false)); set_off_the_record_browser_context(nullptr); }
diff --git a/content/shell/browser/web_test/web_test_url_request_context_getter.cc b/content/shell/browser/web_test/web_test_url_request_context_getter.cc index 78aea74..f97bdf9 100644 --- a/content/shell/browser/web_test/web_test_url_request_context_getter.cc +++ b/content/shell/browser/web_test/web_test_url_request_context_getter.cc
@@ -24,15 +24,13 @@ const base::FilePath& base_path, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, ProtocolHandlerMap* protocol_handlers, - URLRequestInterceptorScopedVector request_interceptors, - net::NetLog* net_log) + URLRequestInterceptorScopedVector request_interceptors) : ShellURLRequestContextGetter(ignore_certificate_errors, off_the_record, base_path, std::move(io_task_runner), protocol_handlers, - std::move(request_interceptors), - net_log) { + std::move(request_interceptors)) { // Must first be created on the UI thread. DCHECK_CURRENTLY_ON(BrowserThread::UI); }
diff --git a/content/shell/browser/web_test/web_test_url_request_context_getter.h b/content/shell/browser/web_test/web_test_url_request_context_getter.h index ccf0f53..825742a 100644 --- a/content/shell/browser/web_test/web_test_url_request_context_getter.h +++ b/content/shell/browser/web_test/web_test_url_request_context_getter.h
@@ -18,7 +18,6 @@ namespace net { class NetworkDelegate; -class NetLog; class ProxyConfigService; } // namespace net @@ -32,8 +31,7 @@ const base::FilePath& base_path, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, ProtocolHandlerMap* protocol_handlers, - URLRequestInterceptorScopedVector request_interceptors, - net::NetLog* net_log); + URLRequestInterceptorScopedVector request_interceptors); protected: ~WebTestURLRequestContextGetter() override;
diff --git a/content/test/fuzzer/BUILD.gn b/content/test/fuzzer/BUILD.gn index d34ca44..4d58db5 100644 --- a/content/test/fuzzer/BUILD.gn +++ b/content/test/fuzzer/BUILD.gn
@@ -259,7 +259,6 @@ "../../browser/speech/audio_encoder.cc", "../../browser/speech/audio_encoder.h", "../../browser/speech/audio_encoder_fuzzer.cc", - "//base/test/fuzzed_data_provider.h", "//content/common/content_export.h", ]
diff --git a/content/test/gpu/gpu_tests/cloud_storage_integration_test_base.py b/content/test/gpu/gpu_tests/cloud_storage_integration_test_base.py index affdd6e..154479d 100644 --- a/content/test/gpu/gpu_tests/cloud_storage_integration_test_base.py +++ b/content/test/gpu/gpu_tests/cloud_storage_integration_test_base.py
@@ -141,12 +141,6 @@ help='For Skia Gold integration. Always report that the test passed even ' 'if the Skia Gold image comparison reported a failure, but ' 'otherwise perform the same steps as usual.') - parser.add_option( - '--stream-goldctl-output', - action='store_true', default=False, - help='When running goldctl commands, always show the stdout/stderr from ' - 'the subprocess instead of only on failure, and stream the output ' - 'instead of collecting it at the end.') def _CompareScreenshotSamples(self, tab, screenshot, expected_colors, tolerance, device_pixel_ratio, @@ -459,8 +453,9 @@ json.dump(gpu_keys, f) try: if not self.GetParsedCommandLineOptions().no_luci_auth: - self._RunGoldctlCommand([goldctl_bin, 'auth', '--luci', - '--work-dir', self._skia_gold_temp_dir]) + subprocess.check_output([goldctl_bin, 'auth', '--luci', + '--work-dir', self._skia_gold_temp_dir], + stderr=subprocess.STDOUT) cmd = ([goldctl_bin, 'imgtest', 'add'] + mode + ['--test-name', image_name, '--instance', SKIA_GOLD_INSTANCE, @@ -469,7 +464,7 @@ '--work-dir', self._skia_gold_temp_dir, '--failure-file', failure_file] + build_id_args) - self._RunGoldctlCommand(cmd) + subprocess.check_output(cmd, stderr=subprocess.STDOUT) except CalledProcessError as e: contents = '' try: @@ -481,26 +476,6 @@ if not self.GetParsedCommandLineOptions().no_skia_gold_failure: raise Exception('goldctl command failed: ' + contents) - def _RunGoldctlCommand(self, command): - if self.GetParsedCommandLineOptions().stream_goldctl_output: - process = subprocess.Popen( - command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - full_output = "" - while True: - line = process.stdout.readline() - if not line and process.poll() is not None: - break - if line: - full_output += line - logging.info(line.rstrip()) - rc = process.returncode - # Emulate what subprocess.check_output would do so that callers don't - # have to care how the command is being run. - if rc != 0: - raise subprocess.CalledProcessError(rc, command, full_output) - else: - subprocess.check_output(command, stderr=subprocess.STDOUT) - def _ValidateScreenshotSamplesWithSkiaGold(self, tab, page, screenshot, expectations, tolerance, device_pixel_ratio,
diff --git a/content/test/navigation_simulator_impl.cc b/content/test/navigation_simulator_impl.cc index e45554c..c9c1eda 100644 --- a/content/test/navigation_simulator_impl.cc +++ b/content/test/navigation_simulator_impl.cc
@@ -899,6 +899,11 @@ void NavigationSimulatorImpl::SetLoadURLParams( NavigationController::LoadURLParams* load_url_params) { load_url_params_ = load_url_params; + + // Make sure the internal attributes of NavigationSimulatorImpl match the + // LoadURLParams that is going to be sent. + referrer_ = load_url_params->referrer; + transition_ = load_url_params->transition_type; } void NavigationSimulatorImpl::SetAutoAdvance(bool auto_advance) {
diff --git a/device/BUILD.gn b/device/BUILD.gn index 4e35e957..8bc2a11 100644 --- a/device/BUILD.gn +++ b/device/BUILD.gn
@@ -323,7 +323,6 @@ "vr/util/fps_meter_unittest.cc", "vr/util/sliding_average_unittest.cc", "vr/vr_device_base_unittest.cc", - "vr/vr_display_impl_unittest.cc", ] if (is_android) {
diff --git a/device/vr/orientation/orientation_device.cc b/device/vr/orientation/orientation_device.cc index 49be329..dc1a98e 100644 --- a/device/vr/orientation/orientation_device.cc +++ b/device/vr/orientation/orientation_device.cc
@@ -9,6 +9,7 @@ #include "base/numerics/math_constants.h" #include "base/time/time.h" #include "device/vr/orientation/orientation_device.h" +#include "device/vr/vr_display_impl.h" #include "services/device/public/cpp/generic_sensor/sensor_reading.h" #include "services/device/public/cpp/generic_sensor/sensor_reading_shared_buffer_reader.h" #include "services/device/public/mojom/sensor_provider.mojom.h" @@ -134,13 +135,38 @@ mojom::XRRuntimeSessionOptionsPtr options, mojom::XRRuntime::RequestSessionCallback callback) { DCHECK(!options->immersive); + // TODO(http://crbug.com/695937): Perform a check to see if sensors are // available when RequestSession is called for non-immersive sessions. - ReturnNonImmersiveSession(std::move(callback)); + + mojom::XRFrameDataProviderPtr data_provider; + mojom::XRSessionControllerPtr controller; + magic_window_sessions_.push_back(std::make_unique<VRDisplayImpl>( + this, mojo::MakeRequest(&data_provider), mojo::MakeRequest(&controller))); + + auto session = mojom::XRSession::New(); + session->data_provider = data_provider.PassInterface(); + if (display_info_) { + session->display_info = display_info_.Clone(); + } + + std::move(callback).Run(std::move(session), std::move(controller)); } -void VROrientationDevice::OnGetInlineFrameData( +void VROrientationDevice::EndMagicWindowSession(VRDisplayImpl* session) { + base::EraseIf(magic_window_sessions_, + [session](const std::unique_ptr<VRDisplayImpl>& item) { + return item.get() == session; + }); +} + +void VROrientationDevice::GetInlineFrameData( mojom::XRFrameDataProvider::GetFrameDataCallback callback) { + if (!inline_poses_enabled_) { + std::move(callback).Run(nullptr); + return; + } + mojom::VRPosePtr pose = mojom::VRPose::New(); SensorReading latest_reading;
diff --git a/device/vr/orientation/orientation_device.h b/device/vr/orientation/orientation_device.h index 04459c92..10de2602 100644 --- a/device/vr/orientation/orientation_device.h +++ b/device/vr/orientation/orientation_device.h
@@ -20,6 +20,7 @@ namespace device { class SensorReadingSharedBufferReader; +class VRDisplayImpl; // Use RELATIVE_ORIENTATION_QUATERNION rather than // ABSOLUTE_ORIENTATION_QUATERNION because compass readings can be inacurate @@ -47,13 +48,13 @@ mojom::XRRuntimeSessionOptionsPtr options, mojom::XRRuntime::RequestSessionCallback callback) override; - // VRDeviceBase - void OnGetInlineFrameData( - mojom::XRFrameDataProvider::GetFrameDataCallback callback) override; - // Indicates whether the device was able to connect to orientation events. bool IsAvailable() const { return available_; } + void EndMagicWindowSession(VRDisplayImpl* session); + virtual void GetInlineFrameData( + mojom::XRFrameDataProvider::GetFrameDataCallback callback); + private: // SensorClient Functions. void RaiseError() override; @@ -78,6 +79,8 @@ mojom::SensorPtr sensor_; std::unique_ptr<SensorReadingSharedBufferReader> shared_buffer_reader_; mojo::Binding<mojom::SensorClient> binding_; + + std::vector<std::unique_ptr<VRDisplayImpl>> magic_window_sessions_; }; } // namespace device
diff --git a/device/vr/orientation/orientation_device_unittest.cc b/device/vr/orientation/orientation_device_unittest.cc index c5368f6..e7aaf4c 100644 --- a/device/vr/orientation/orientation_device_unittest.cc +++ b/device/vr/orientation/orientation_device_unittest.cc
@@ -15,6 +15,7 @@ #include "device/vr/orientation/orientation_device.h" #include "device/vr/test/fake_orientation_provider.h" #include "device/vr/test/fake_sensor_provider.h" +#include "device/vr/vr_display_impl.h" #include "services/device/public/cpp/generic_sensor/sensor_reading.h" #include "services/device/public/cpp/generic_sensor/sensor_reading_shared_buffer_reader.h" #include "services/device/public/cpp/generic_sensor/sensor_traits.h" @@ -135,7 +136,7 @@ base::RunLoop loop; - device_->OnGetInlineFrameData(base::BindOnce( + device_->GetInlineFrameData(base::BindOnce( [](base::OnceClosure quit_closure, base::OnceCallback<void(mojom::VRPosePtr)> callback, mojom::XRFrameDataPtr ptr) { @@ -150,6 +151,43 @@ loop.Run(); } + void AssertInlineFrameDataAvailable(bool expect_available) { + if (expect_available) { + device_->GetInlineFrameData(base::BindOnce( + [](device::mojom::XRFrameDataPtr data) { EXPECT_TRUE(data); })); + } else { + device_->GetInlineFrameData(base::BindOnce( + [](device::mojom::XRFrameDataPtr data) { EXPECT_FALSE(data); })); + } + } + + void SetInlinePosesEnabled(bool enabled) { + device_->SetInlinePosesEnabled(enabled); + } + + std::unique_ptr<VRDisplayImpl> MakeDisplay() { + mojom::XRFrameDataProviderPtr data_provider; + mojom::XRSessionControllerPtr controller; + return std::make_unique<VRDisplayImpl>(device_.get(), + mojo::MakeRequest(&data_provider), + mojo::MakeRequest(&controller)); + } + + void TryGetFrameData(VRDisplayImpl* display, bool expect_null) { + bool was_called = false; + auto callback = [](bool expect_null, bool* was_called, + mojom::XRFrameDataPtr data) { + *was_called = true; + EXPECT_EQ(expect_null, !data); + }; + + static_cast<mojom::XRFrameDataProvider*>(display)->GetFrameData( + nullptr, base::BindOnce(callback, expect_null, &was_called)); + + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(was_called); + } + mojom::SensorInitParamsPtr FakeInitParams() { auto init_params = mojom::SensorInitParams::New(); init_params->sensor = std::move(sensor_ptr_); @@ -342,4 +380,26 @@ })); } +TEST_F(VROrientationDeviceTest, NoMagicWindowPosesWhileBrowsing) { + InitializeDevice(FakeInitParams()); + + AssertInlineFrameDataAvailable(true); + SetInlinePosesEnabled(false); + AssertInlineFrameDataAvailable(false); +} + +TEST_F(VROrientationDeviceTest, GetFrameDataHelper) { + InitializeDevice(FakeInitParams()); + + // 1) create display impl with restricted frame data + // 2) call GetFrameData and check behavior + // 3) unrestrict frame data + // 4) call GetFrameData and check behavior + std::unique_ptr<VRDisplayImpl> display = MakeDisplay(); + TryGetFrameData(display.get(), true); + static_cast<mojom::XRSessionController*>(display.get()) + ->SetFrameDataRestricted(false); + TryGetFrameData(display.get(), false); +} + } // namespace device
diff --git a/device/vr/test/fake_vr_device.cc b/device/vr/test/fake_vr_device.cc index 39a7e536..3eb2eaf 100644 --- a/device/vr/test/fake_vr_device.cc +++ b/device/vr/test/fake_vr_device.cc
@@ -61,11 +61,4 @@ controller_binding_.Close(); } -void FakeVRDevice::OnGetInlineFrameData( - mojom::XRFrameDataProvider::GetFrameDataCallback callback) { - mojom::XRFrameDataPtr frame_data = mojom::XRFrameData::New(); - frame_data->pose = pose_.Clone(); - std::move(callback).Run(std::move(frame_data)); -} - } // namespace device
diff --git a/device/vr/test/fake_vr_device.h b/device/vr/test/fake_vr_device.h index fa01b3a..e519b8a 100644 --- a/device/vr/test/fake_vr_device.h +++ b/device/vr/test/fake_vr_device.h
@@ -34,9 +34,6 @@ private: void OnPresentingControllerMojoConnectionError(); - void OnGetInlineFrameData( - mojom::XRFrameDataProvider::GetFrameDataCallback callback) override; - mojom::VRDisplayInfoPtr InitBasicDevice(); mojom::VREyeParametersPtr InitEye(float fov, float offset, uint32_t size);
diff --git a/device/vr/vr_device_base.cc b/device/vr/vr_device_base.cc index e88e257..f0be39e 100644 --- a/device/vr/vr_device_base.cc +++ b/device/vr/vr_device_base.cc
@@ -6,7 +6,6 @@ #include "base/metrics/histogram_functions.h" #include "device/vr/vr_device_provider.h" -#include "device/vr/vr_display_impl.h" namespace device { @@ -48,16 +47,6 @@ std::move(callback).Run(display_info_.Clone()); } -void VRDeviceBase::GetInlineFrameData( - mojom::XRFrameDataProvider::GetFrameDataCallback callback) { - if (!inline_poses_enabled_) { - std::move(callback).Run(nullptr); - return; - } - - OnGetInlineFrameData(std::move(callback)); -} - void VRDeviceBase::SetVRDisplayInfo(mojom::VRDisplayInfoPtr display_info) { DCHECK(display_info); DCHECK(display_info->id == id_); @@ -79,17 +68,8 @@ return runtime; } -bool VRDeviceBase::ShouldPauseTrackingWhenFrameDataRestricted() { - return false; -} - void VRDeviceBase::OnListeningForActivate(bool listening) {} -void VRDeviceBase::OnGetInlineFrameData( - mojom::XRFrameDataProvider::GetFrameDataCallback callback) { - std::move(callback).Run(nullptr); -} - void VRDeviceBase::SetListeningForActivate(bool is_listening) { OnListeningForActivate(is_listening); } @@ -111,32 +91,8 @@ std::move(callback).Run(base::nullopt); } -void VRDeviceBase::ReturnNonImmersiveSession( - mojom::XRRuntime::RequestSessionCallback callback) { - mojom::XRFrameDataProviderPtr data_provider; - mojom::XREnvironmentIntegrationProviderPtr environment_provider; - mojom::XRSessionControllerPtr controller; - magic_window_sessions_.push_back(std::make_unique<VRDisplayImpl>( - this, mojo::MakeRequest(&data_provider), mojo::MakeRequest(&controller))); - - auto session = mojom::XRSession::New(); - session->data_provider = data_provider.PassInterface(); - if (display_info_) { - session->display_info = display_info_.Clone(); - } - - std::move(callback).Run(std::move(session), std::move(controller)); -} - void LogViewerType(VrViewerType type) { base::UmaHistogramSparse("VRViewerType", static_cast<int>(type)); } -void VRDeviceBase::EndMagicWindowSession(VRDisplayImpl* session) { - base::EraseIf(magic_window_sessions_, - [&](const std::unique_ptr<VRDisplayImpl>& item) { - return item.get() == session; - }); -} - } // namespace device
diff --git a/device/vr/vr_device_base.h b/device/vr/vr_device_base.h index f145511..1815026 100644 --- a/device/vr/vr_device_base.h +++ b/device/vr/vr_device_base.h
@@ -15,8 +15,6 @@ namespace device { -class VRDisplayImpl; - // Represents one of the platform's VR devices. Owned by the respective // VRDeviceProvider. // TODO(mthiesse, crbug.com/769373): Remove DEVICE_VR_EXPORT. @@ -35,25 +33,14 @@ EnsureInitializedCallback callback) override; void SetInlinePosesEnabled(bool enable) override; - void GetInlineFrameData( - mojom::XRFrameDataProvider::GetFrameDataCallback callback); - virtual void RequestHitTest( mojom::XRRayPtr ray, mojom::XREnvironmentIntegrationProvider::RequestHitTestCallback callback); device::mojom::XRDeviceId GetId() const; bool HasExclusiveSession(); - void EndMagicWindowSession(VRDisplayImpl* session); - // TODO(https://crbug.com/845283): This method is a temporary solution - // until a XR related refactor lands. It allows to keep using the - // existing PauseTracking/ResumeTracking while not changing the - // existing VR functionality. - virtual bool ShouldPauseTrackingWhenFrameDataRestricted(); - - // Devices may be paused/resumed when focus changes by VRDisplayImpl or - // GVR delegate. + // Devices may be paused/resumed when focus changes by GVR delegate. virtual void PauseTracking(); virtual void ResumeTracking(); @@ -78,24 +65,19 @@ void OnActivate(mojom::VRDisplayEventReason reason, base::Callback<void(bool)> on_handled); - void ReturnNonImmersiveSession( - mojom::XRRuntime::RequestSessionCallback callback); - mojom::VRDisplayInfoPtr display_info_; - std::vector<std::unique_ptr<VRDisplayImpl>> magic_window_sessions_; + + bool inline_poses_enabled_ = true; private: // TODO(https://crbug.com/842227): Rename methods to HandleOnXXX virtual void OnListeningForActivate(bool listening); - virtual void OnGetInlineFrameData( - mojom::XRFrameDataProvider::GetFrameDataCallback callback); mojom::XRRuntimeEventListenerAssociatedPtr listener_; bool presenting_ = false; device::mojom::XRDeviceId id_; - bool inline_poses_enabled_ = true; mojo::Binding<mojom::XRRuntime> runtime_binding_;
diff --git a/device/vr/vr_device_base_unittest.cc b/device/vr/vr_device_base_unittest.cc index ba7e549b..d1e3697 100644 --- a/device/vr/vr_device_base_unittest.cc +++ b/device/vr/vr_device_base_unittest.cc
@@ -12,7 +12,6 @@ #include "base/test/scoped_task_environment.h" #include "device/vr/public/mojom/vr_service.mojom.h" #include "device/vr/test/fake_vr_device.h" -#include "device/vr/test/fake_vr_service_client.h" #include "device/vr/vr_device_base.h" #include "mojo/public/cpp/bindings/associated_binding.h" #include "testing/gmock/include/gmock/gmock.h" @@ -94,11 +93,6 @@ ~VRDeviceTest() override {} protected: - void SetUp() override { - mojom::VRServiceClientPtr proxy; - client_ = std::make_unique<FakeVRServiceClient>(mojo::MakeRequest(&proxy)); - } - std::unique_ptr<VRDeviceBaseForTesting> MakeVRDevice() { std::unique_ptr<VRDeviceBaseForTesting> device = std::make_unique<VRDeviceBaseForTesting>(); @@ -113,9 +107,6 @@ return display_info; } - FakeVRServiceClient* client() { return client_.get(); } - - std::unique_ptr<FakeVRServiceClient> client_; base::test::ScopedTaskEnvironment scoped_task_environment_; DISALLOW_COPY_AND_ASSIGN(VRDeviceTest); @@ -157,16 +148,4 @@ base::RunLoop().RunUntilIdle(); } -TEST_F(VRDeviceTest, NoMagicWindowPosesWhileBrowsing) { - auto device = - std::make_unique<FakeVRDevice>(static_cast<device::mojom::XRDeviceId>(1)); - device->SetPose(mojom::VRPose::New()); - - device->GetInlineFrameData(base::BindOnce( - [](device::mojom::XRFrameDataPtr data) { EXPECT_TRUE(data); })); - device->SetInlinePosesEnabled(false); - device->GetInlineFrameData(base::BindOnce( - [](device::mojom::XRFrameDataPtr data) { EXPECT_FALSE(data); })); -} - } // namespace device
diff --git a/device/vr/vr_display_impl.cc b/device/vr/vr_display_impl.cc index 98921904..c7c6dfae 100644 --- a/device/vr/vr_display_impl.cc +++ b/device/vr/vr_display_impl.cc
@@ -7,12 +7,12 @@ #include <utility> #include "base/bind.h" -#include "device/vr/vr_device_base.h" +#include "device/vr/orientation/orientation_device.h" namespace device { VRDisplayImpl::VRDisplayImpl( - VRDeviceBase* device, + VROrientationDevice* device, mojom::XRFrameDataProviderRequest magic_window_request, mojom::XRSessionControllerRequest session_request) : magic_window_binding_(this, std::move(magic_window_request)), @@ -30,7 +30,11 @@ void VRDisplayImpl::GetFrameData( mojom::XRFrameDataRequestOptionsPtr options, mojom::XRFrameDataProvider::GetFrameDataCallback callback) { - if (device_->HasExclusiveSession() || restrict_frame_data_) { + // VRDisplayImpl is only used by VROrientationDevice, which should never have + // an exclusive session / be presenting. + DCHECK(!device_->HasExclusiveSession()); + + if (restrict_frame_data_) { std::move(callback).Run(nullptr); return; } @@ -56,13 +60,6 @@ // XRSessionController void VRDisplayImpl::SetFrameDataRestricted(bool frame_data_restricted) { restrict_frame_data_ = frame_data_restricted; - if (device_->ShouldPauseTrackingWhenFrameDataRestricted()) { - if (restrict_frame_data_) { - device_->PauseTracking(); - } else { - device_->ResumeTracking(); - } - } } void VRDisplayImpl::OnMojoConnectionError() {
diff --git a/device/vr/vr_display_impl.h b/device/vr/vr_display_impl.h index 2494214..ca244f1 100644 --- a/device/vr/vr_display_impl.h +++ b/device/vr/vr_display_impl.h
@@ -19,7 +19,7 @@ namespace device { -class VRDeviceBase; +class VROrientationDevice; // VR device process implementation of a XRFrameDataProvider within a WebVR // or WebXR site session. @@ -28,7 +28,7 @@ class DEVICE_VR_EXPORT VRDisplayImpl : public mojom::XRFrameDataProvider, public mojom::XRSessionController { public: - VRDisplayImpl(VRDeviceBase* device, + VRDisplayImpl(VROrientationDevice* device, mojom::XRFrameDataProviderRequest, mojom::XRSessionControllerRequest); ~VRDisplayImpl() override; @@ -39,11 +39,6 @@ void SetInputSourceButtonListener( mojom::XRInputSourceButtonListenerAssociatedPtrInfo) override; - gfx::Size sessionFrameSize() { return session_frame_size_; } - display::Display::Rotation sessionRotation() { return session_rotation_; } - - device::VRDeviceBase* device() { return device_; } - // Accessible to tests. protected: // mojom::XRFrameDataProvider @@ -51,17 +46,14 @@ GetFrameDataCallback callback) override; // mojom::XRSessionController - void SetFrameDataRestricted(bool paused) override; + void SetFrameDataRestricted(bool frame_data_restricted) override; void OnMojoConnectionError(); mojo::Binding<mojom::XRFrameDataProvider> magic_window_binding_; mojo::Binding<mojom::XRSessionController> session_controller_binding_; - device::VRDeviceBase* device_; + device::VROrientationDevice* device_; bool restrict_frame_data_ = true; - - gfx::Size session_frame_size_ = gfx::Size(0, 0); - display::Display::Rotation session_rotation_ = display::Display::ROTATE_0; }; } // namespace device
diff --git a/device/vr/vr_display_impl_unittest.cc b/device/vr/vr_display_impl_unittest.cc deleted file mode 100644 index e03cc1b3..0000000 --- a/device/vr/vr_display_impl_unittest.cc +++ /dev/null
@@ -1,143 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "device/vr/vr_display_impl.h" - -#include <memory> - -#include "base/bind.h" -#include "base/memory/ptr_util.h" -#include "base/run_loop.h" -#include "base/test/scoped_task_environment.h" -#include "device/vr/public/mojom/vr_service.mojom.h" -#include "device/vr/test/fake_vr_device.h" -#include "device/vr/test/fake_vr_service_client.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace device { - -class VRDisplayImplTest : public testing::Test { - public: - VRDisplayImplTest() {} - ~VRDisplayImplTest() override {} - void onDisplaySynced() {} - - protected: - void SetUp() override { - device_ = std::make_unique<FakeVRDevice>(static_cast<mojom::XRDeviceId>(1)); - device_->SetPose(mojom::VRPose::New()); - mojom::VRServiceClientPtr proxy; - client_ = std::make_unique<FakeVRServiceClient>(mojo::MakeRequest(&proxy)); - } - - std::unique_ptr<VRDisplayImpl> MakeDisplay( - mojom::XRSessionControllerPtr* controller) { - mojom::XRFrameDataProviderPtr data_provider; - auto display = std::make_unique<VRDisplayImpl>( - device(), mojo::MakeRequest(&data_provider), - mojo::MakeRequest(controller)); - static_cast<mojom::XRSessionController*>(display.get()) - ->SetFrameDataRestricted(true); - return display; - } - - void RequestSession(VRDisplayImpl* display_impl) { - device_->RequestSession( - mojom::XRRuntimeSessionOptionsPtr(), - base::BindOnce( - [](device::mojom::XRSessionPtr session, - mojom::XRSessionControllerPtr immersive_session_controller) {})); - } - - void ExitPresent() { device_->StopSession(); } - - bool presenting() { return device_->IsPresenting(); } - VRDeviceBase* device() { return device_.get(); } - FakeVRServiceClient* client() { return client_.get(); } - - base::test::ScopedTaskEnvironment scoped_task_environment_; - std::unique_ptr<FakeVRDevice> device_; - std::unique_ptr<FakeVRServiceClient> client_; - - DISALLOW_COPY_AND_ASSIGN(VRDisplayImplTest); -}; - -TEST_F(VRDisplayImplTest, DevicePresentationIsolation) { - mojom::XRSessionControllerPtr controller1; - std::unique_ptr<VRDisplayImpl> display_1 = MakeDisplay(&controller1); - static_cast<mojom::XRSessionController*>(display_1.get()) - ->SetFrameDataRestricted(false); - - mojom::XRSessionControllerPtr controller2; - std::unique_ptr<VRDisplayImpl> display_2 = MakeDisplay(&controller2); - static_cast<mojom::XRSessionController*>(display_2.get()) - ->SetFrameDataRestricted(false); - - // When not presenting either service should be able to access the device. - EXPECT_FALSE(device()->HasExclusiveSession()); - - bool was_called = false; - auto callback = [](bool expect_null, bool* was_called, - mojom::XRFrameDataPtr data) { - *was_called = true; - EXPECT_EQ(expect_null, !data); - }; - - static_cast<mojom::XRFrameDataProvider*>(display_1.get()) - ->GetFrameData(nullptr, base::BindOnce(callback, false, &was_called)); - - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(was_called); - was_called = false; - - static_cast<mojom::XRFrameDataProvider*>(display_2.get()) - ->GetFrameData(nullptr, base::BindOnce(callback, false, &was_called)); - - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(was_called); - was_called = false; - - // Attempt to present. - RequestSession(display_1.get()); - EXPECT_TRUE(presenting()); - EXPECT_TRUE(device()->HasExclusiveSession()); - - // While a device is presenting, no one should have access to magic window. - static_cast<mojom::XRFrameDataProvider*>(display_1.get()) - ->GetFrameData(nullptr, base::BindOnce(callback, true, &was_called)); - - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(was_called); - was_called = false; - - static_cast<mojom::XRFrameDataProvider*>(display_2.get()) - ->GetFrameData(nullptr, base::BindOnce(callback, true, &was_called)); - - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(was_called); - was_called = false; - - // Service 1 should be able to exit the presentation it initiated. - ExitPresent(); - EXPECT_FALSE(presenting()); - EXPECT_FALSE(device()->HasExclusiveSession()); - - // Once presentation had ended both services should be able to access the - // device. - static_cast<mojom::XRFrameDataProvider*>(display_1.get()) - ->GetFrameData(nullptr, base::BindOnce(callback, false, &was_called)); - - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(was_called); - was_called = false; - - static_cast<mojom::XRFrameDataProvider*>(display_2.get()) - ->GetFrameData(nullptr, base::BindOnce(callback, false, &was_called)); - - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(was_called); - was_called = false; -} - -} // namespace device
diff --git a/docs/android_debugging_instructions.md b/docs/android_debugging_instructions.md index 3c69e40..5658a40 100644 --- a/docs/android_debugging_instructions.md +++ b/docs/android_debugging_instructions.md
@@ -192,6 +192,19 @@ etc. ``` +When debugging a failing test on the build waterfall, you can find the mapping +file as follows: + +1. Open buildbot page for the failing build (e.g., + https://ci.chromium.org/p/chrome/builders/ci/android-go-perf/1234). +2. Open the swarming page for the failing shard (e.g., shard #3). +3. Click on "Isolated Inputs" to locate the files the shard used to run the + test. +4. Download the `.mapping` file for the APK used by the test (e.g., + `ChromePublic.apk.mapping`). Note that you may need to use the + `tools/swarming_client/isolateserver.py` script to download the mapping + file if it's too big. The viewer will provide instructions for this. + Build the `java_deobfuscate` tool: ```shell
diff --git a/docs/fuchsia_build_instructions.md b/docs/fuchsia_build_instructions.md index 46d5605..fdd839ce 100644 --- a/docs/fuchsia_build_instructions.md +++ b/docs/fuchsia_build_instructions.md
@@ -188,16 +188,15 @@ 3. Add users to the "kvm" group, and have them login again, to pick-up the new group. -### Run test target +### Running test suites + +Building test suites generate a launcher script to run them on a QEMU instance +or a physical device. These scripts are generated at `out/fuchsia/bin`. For +instance,to run the `base_unittests` target, launch: ```shell $ out/fuchsia/bin/run_base_unittests ``` -This packages the built binary and test data into a disk image, and runs a QEMU -instance from the Fuchsia SDK, outputting to the console. - Common gtest arguments such as `--gtest_filter=...` are supported by the run -script. - -The run script also symbolizes backtraces. +script. The launcher script also symbolizes backtraces.
diff --git a/docs/threading_and_tasks.md b/docs/threading_and_tasks.md index 6fe31f4..5e85d2a 100644 --- a/docs/threading_and_tasks.md +++ b/docs/threading_and_tasks.md
@@ -142,7 +142,7 @@ at a time on any thread. * [Single Threaded](#Posting-Multiple-Tasks-to-the-Same-Thread): Tasks executed in posting order, one at a time on a single thread. - * [COM Single Threaded](#Posting-Tasks-to-a-COM-Single-Thread-Apartment-STA_Thread-Windows_): + * [COM Single Threaded](#Posting-Tasks-to-a-COM-Single_Thread-Apartment-STA_Thread-Windows): A variant of single threaded with COM initialized. ### Prefer Sequences to Physical Threads
diff --git a/extensions/browser/content_verifier.cc b/extensions/browser/content_verifier.cc index 0c402d1b..ea89a51 100644 --- a/extensions/browser/content_verifier.cc +++ b/extensions/browser/content_verifier.cc
@@ -391,10 +391,7 @@ ContentVerifier::ContentVerifier( content::BrowserContext* context, std::unique_ptr<ContentVerifierDelegate> delegate) - : context_(context), - delegate_(std::move(delegate)), - observer_(this), - io_data_(new ContentVerifierIOData) {} + : context_(context), delegate_(std::move(delegate)), observer_(this) {} ContentVerifier::~ContentVerifier() { } @@ -416,7 +413,7 @@ void ContentVerifier::ShutdownOnIO() { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); shutdown_on_io_ = true; - io_data_->Clear(); + io_data_.Clear(); hash_helper_.reset(); } @@ -427,7 +424,7 @@ DCHECK_CURRENTLY_ON(content::BrowserThread::IO); const ContentVerifierIOData::ExtensionData* data = - io_data_->GetData(extension_id); + io_data_.GetData(extension_id); // The absence of |data| generally means that we don't have to verify the // extension resource. However, it could also mean that // OnExtensionLoadedOnIO didn't get a chance to fire yet. @@ -557,7 +554,7 @@ if (shutdown_on_io_) return; - io_data_->AddData(extension_id, std::move(data)); + io_data_.AddData(extension_id, std::move(data)); GetContentHash(extension_id, extension_root, extension_version, false /* force_missing_computed_hashes_creation */, // HashHelper will respond directly to OnFetchComplete(). @@ -593,7 +590,7 @@ const base::Version& extension_version) { if (shutdown_on_io_) return; - io_data_->RemoveData(extension_id); + io_data_.RemoveData(extension_id); // Remove all possible cache entries for this extension version. cache_.erase(CacheKey(extension_id, extension_version, true)); @@ -669,7 +666,7 @@ const std::set<base::FilePath>& relative_unix_paths) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); const ContentVerifierIOData::ExtensionData* data = - io_data_->GetData(extension_id); + io_data_.GetData(extension_id); if (!data) return false; @@ -751,7 +748,7 @@ } void ContentVerifier::ResetIODataForTesting(const Extension* extension) { - io_data_->AddData(extension->id(), CreateIOData(extension, delegate_.get())); + io_data_.AddData(extension->id(), CreateIOData(extension, delegate_.get())); } base::FilePath ContentVerifier::NormalizeRelativePathForTesting(
diff --git a/extensions/browser/content_verifier.h b/extensions/browser/content_verifier.h index 1b6601b..c2b5b91 100644 --- a/extensions/browser/content_verifier.h +++ b/extensions/browser/content_verifier.h
@@ -177,7 +177,7 @@ ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> observer_; // Data that should only be used on the IO thread. - scoped_refptr<ContentVerifierIOData> io_data_; + ContentVerifierIOData io_data_; DISALLOW_COPY_AND_ASSIGN(ContentVerifier); };
diff --git a/extensions/browser/content_verifier_io_data.h b/extensions/browser/content_verifier_io_data.h index ecba0b4..4937394c 100644 --- a/extensions/browser/content_verifier_io_data.h +++ b/extensions/browser/content_verifier_io_data.h
@@ -18,8 +18,7 @@ // A helper class for keeping track of data for the ContentVerifier that should // only be accessed on the IO thread. -class ContentVerifierIOData - : public base::RefCountedThreadSafe<ContentVerifierIOData> { +class ContentVerifierIOData { public: struct ExtensionData { // Set of images file paths used within the browser process. @@ -36,6 +35,7 @@ }; ContentVerifierIOData(); + ~ContentVerifierIOData(); void AddData(const std::string& extension_id, std::unique_ptr<ExtensionData> data); @@ -46,11 +46,10 @@ // be retained or used on other threads. const ExtensionData* GetData(const std::string& extension_id); - protected: - friend class base::RefCountedThreadSafe<ContentVerifierIOData>; - virtual ~ContentVerifierIOData(); - + private: std::map<std::string, std::unique_ptr<ExtensionData>> data_map_; + + DISALLOW_COPY_AND_ASSIGN(ContentVerifierIOData); }; } // namespace extensions
diff --git a/extensions/shell/browser/shell_browser_context.cc b/extensions/shell/browser/shell_browser_context.cc index abd8742..abeb37f 100644 --- a/extensions/shell/browser/shell_browser_context.cc +++ b/extensions/shell/browser/shell_browser_context.cc
@@ -17,7 +17,6 @@ // then app_shell would also have to create a normal context and manage both. ShellBrowserContext::ShellBrowserContext() : content::ShellBrowserContext(false /* off_the_record */, - nullptr /* net_log */, true /* delay_services_creation */), storage_policy_(new ShellSpecialStoragePolicy) {}
diff --git a/fuchsia/BUILD.gn b/fuchsia/BUILD.gn index 3082ec3..ecc9681 100644 --- a/fuchsia/BUILD.gn +++ b/fuchsia/BUILD.gn
@@ -100,6 +100,7 @@ "engine:web_engine_browsertests", "engine:web_engine_unittests", "http:http_service_tests", + "mojo:fuchsia_mojo_unittests", "runners:cast_runner", "runners:cast_runner_browsertests", "runners:web_runner",
diff --git a/fuchsia/README.md b/fuchsia/README.md index 99db56b..df342bf5 100644 --- a/fuchsia/README.md +++ b/fuchsia/README.md
@@ -1,6 +1,7 @@ # Chromium-based Fuchsia services This directory contains implementation code for various Fuchsia services living -in the Chromium repository. +in the Chromium repository. To build Chromium on Fuchsia, check this +[documentation](../docs/fuchsia_build_instructions.md). [TOC] @@ -24,29 +25,38 @@ The `./cipd` and `./fidl` subdirectories contain CIPD definitions and FIDL interface definitions, respectfully. -### Test-only code - -Test-only code should live in the same directory as the code under test. -There is one exception to this rule for fake implementations of interfaces and -shared test fixtures. When the number of source files containing code related -to these has reached a certain threshold, they should be moved to a `test` -subdirectory. For instance, see the `//fuchsia/engine/test` directory. - ### Namespacing Code that is not shared across multiple targets should live in the global namespace. Code that is shared across multiple targets should live in the `cr_fuchsia` namespace. -### Running test suites +### Test code -Building test suites generate a launcher script to run them on a QEMU instance. -These scripts are generated at `out/fuchsia/bin`. For instance,to run the -`base_unittests` target, launch: +Under the `//fuchsia` directory , there are 3 major types of tests: +* Unit tests: Exercises a single class in isolation, allowing full control + over the external environment of this class. +* Browser tests: Spawns a full browser process along child processes. The test + code is run inside the browser process, allowing for full access to the + browser code, but not other processes. +* Integration tests: they exercise the published API of a Fuchsia component. For + instance, `//fuchsia/engine:web_engine_integration_tests` make use of the + `//fuchsia/engine:web_engine` component. The test code is run in a separate + process in a separate component, allowing only access to the published API of + the component under test. -```bash -$ out/fuchsia/bin/run_base_unittests -``` +Integration tests are more resource-intensive than browser tests, which are in +turn more expensive than unit tests. Therefore, when writing new tests, it is +preferred to write unit tests over browser tests over integration tests. + +As a general rule, test-only code should live in the same directory as the code +under test with an explicit file name, either `fake_*`, `test_*`, +`*_unittest.cc`, `*_ browser_test.cc` or `*_integration_test.cc`. + +Test code that is shared across components should live in a dedicated `test` +directory, under the `cr_fuchsia` namespace. For instance, see the +`//fuchsia/engine/test` directory, which contains code shared by all browser +tests. ## Building and deploying the WebRunner service
diff --git a/fuchsia/mojo/BUILD.gn b/fuchsia/mojo/BUILD.gn new file mode 100644 index 0000000..c797103 --- /dev/null +++ b/fuchsia/mojo/BUILD.gn
@@ -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. + +assert(is_fuchsia) + +import("//mojo/public/tools/bindings/mojom.gni") +import("//testing/test.gni") + +mojom("example_interfaces") { + testonly = true + sources = [ + "example.mojom", + ] +} + +source_set("traits") { + sources = [ + "fidl_interface_request_mojom_traits.h", + ] + + public_deps = [ + "//mojo/public/cpp/platform", + "//mojo/public/cpp/system", + ] +} + +test("fuchsia_mojo_unittests") { + sources = [ + "fidl_interface_request_mojom_traits_unittest.cc", + "test_interface_request_mojom_traits.h", + ] + + deps = [ + ":example_interfaces", + "//base:testfidl", + "//mojo/core/test:run_all_unittests", + "//mojo/public/cpp/test_support:test_utils", + "//testing/gtest", + ] +}
diff --git a/fuchsia/mojo/DEPS b/fuchsia/mojo/DEPS new file mode 100644 index 0000000..ef8ad28 --- /dev/null +++ b/fuchsia/mojo/DEPS
@@ -0,0 +1,3 @@ +include_rules = [ + "+mojo/public", +]
diff --git a/fuchsia/mojo/OWNERS b/fuchsia/mojo/OWNERS new file mode 100644 index 0000000..ae29a36aa --- /dev/null +++ b/fuchsia/mojo/OWNERS
@@ -0,0 +1,6 @@ +per-file *.mojom=set noparent +per-file *.mojom=file://ipc/SECURITY_OWNERS +per-file *_mojom_traits*.*=set noparent +per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS +per-file *.typemap=set noparent +per-file *.typemap=file://ipc/SECURITY_OWNERS
diff --git a/fuchsia/mojo/example.mojom b/fuchsia/mojo/example.mojom new file mode 100644 index 0000000..a27c9561 --- /dev/null +++ b/fuchsia/mojo/example.mojom
@@ -0,0 +1,11 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module fuchsia.test.mojom; + +// Mojo struct of fidl::InterfaceRequest<TestInterface>. |request| is a +// channel handle. +struct TestInterfaceRequest { + handle request; +};
diff --git a/fuchsia/mojo/example.typemap b/fuchsia/mojo/example.typemap new file mode 100644 index 0000000..b1d1512 --- /dev/null +++ b/fuchsia/mojo/example.typemap
@@ -0,0 +1,16 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +mojom = "//fuchsia/mojo/example.mojom" +os_whitelist = [ "fuchsia" ] +public_headers = [ "base/fuchsia/testfidl/cpp/fidl.h" ] +traits_headers = [ "//fuchsia/mojo/test_interface_request_mojom_traits.h" ] +sources = [ + "//fuchsia/mojo/test_interface_request_mojom_traits.h", +] +public_deps = [ + "//base:testfidl", + "//fuchsia/mojo:traits", +] +type_mappings = [ "fuchsia.test.mojom.TestInterfaceRequest=fidl::InterfaceRequest<base::fuchsia::testfidl::TestInterface>[move_only]" ]
diff --git a/fuchsia/mojo/fidl_interface_request_mojom_traits.h b/fuchsia/mojo/fidl_interface_request_mojom_traits.h new file mode 100644 index 0000000..2c38438 --- /dev/null +++ b/fuchsia/mojo/fidl_interface_request_mojom_traits.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 FUCHSIA_MOJO_FIDL_INTERFACE_REQUEST_MOJOM_TRAITS_H_ +#define FUCHSIA_MOJO_FIDL_INTERFACE_REQUEST_MOJOM_TRAITS_H_ + +#include <lib/fidl/cpp/interface_request.h> + +#include "mojo/public/cpp/platform/platform_handle.h" +#include "mojo/public/cpp/system/platform_handle.h" + +namespace mojo { + +// Implementation of StructTratis<DataView, fidl::InterfaceRequest<Interface>>. +// Different Interface still needs to define its own StructTraits by subclassing +// this struct. Read test_request_interface_mojom_traits.h for an example. +template <typename DataView, typename Interface> +struct FidlInterfaceRequestStructTraits { + static ScopedHandle request(fidl::InterfaceRequest<Interface>& request) { + DCHECK(request.is_valid()); + PlatformHandle handle(request.TakeChannel()); + return WrapPlatformHandle(std::move(handle)); + } + + static bool Read(DataView input, fidl::InterfaceRequest<Interface>* output) { + ScopedHandle input_request = input.TakeRequest(); + if (!input_request.is_valid()) + return false; + + PlatformHandle handle = + mojo::UnwrapPlatformHandle(std::move(input_request)); + if (!handle.is_valid_handle()) + return false; + + output->set_channel(zx::channel(handle.TakeHandle())); + return true; + } +}; + +} // namespace mojo + +#endif // FUCHSIA_MOJO_FIDL_INTERFACE_REQUEST_MOJOM_TRAITS_H_
diff --git a/fuchsia/mojo/fidl_interface_request_mojom_traits_unittest.cc b/fuchsia/mojo/fidl_interface_request_mojom_traits_unittest.cc new file mode 100644 index 0000000..8e34582c --- /dev/null +++ b/fuchsia/mojo/fidl_interface_request_mojom_traits_unittest.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 "base/fuchsia/testfidl/cpp/fidl.h" +#include "base/message_loop/message_loop.h" +#include "fuchsia/mojo/example.mojom.h" +#include "fuchsia/mojo/test_interface_request_mojom_traits.h" +#include "mojo/public/cpp/test_support/test_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace fuchsia { + +using base::fuchsia::testfidl::TestInterface; +using base::fuchsia::testfidl::TestInterfacePtr; + +TEST(InterfaceRequestStructTraitsTest, Serialization) { + base::MessageLoopForIO message_loop; + TestInterfacePtr test_ptr; + fidl::InterfaceRequest<TestInterface> input_request = test_ptr.NewRequest(); + fidl::InterfaceRequest<TestInterface> output_request; + + EXPECT_TRUE(mojo::test::SerializeAndDeserialize< + fuchsia::test::mojom::TestInterfaceRequest>(&input_request, + &output_request)); + EXPECT_TRUE(output_request.is_valid()); +} + +} // namespace fuchsia
diff --git a/fuchsia/mojo/test_interface_request_mojom_traits.h b/fuchsia/mojo/test_interface_request_mojom_traits.h new file mode 100644 index 0000000..0f0aeb6 --- /dev/null +++ b/fuchsia/mojo/test_interface_request_mojom_traits.h
@@ -0,0 +1,22 @@ +// 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 FUCHSIA_MOJO_TEST_INTERFACE_REQUEST_MOJOM_TRAITS_H_ +#define FUCHSIA_MOJO_TEST_INTERFACE_REQUEST_MOJOM_TRAITS_H_ + +#include "fuchsia/mojo/fidl_interface_request_mojom_traits.h" + +namespace mojo { + +template <> +struct StructTraits< + fuchsia::test::mojom::TestInterfaceRequestDataView, + fidl::InterfaceRequest<base::fuchsia::testfidl::TestInterface>> + : public FidlInterfaceRequestStructTraits< + fuchsia::test::mojom::TestInterfaceRequestDataView, + base::fuchsia::testfidl::TestInterface> {}; + +} // namespace mojo + +#endif // FUCHSIA_MOJO_TEST_INTERFACE_REQUEST_MOJOM_TRAITS_H_
diff --git a/fuchsia/mojo/test_typemaps.gni b/fuchsia/mojo/test_typemaps.gni new file mode 100644 index 0000000..0fb662f --- /dev/null +++ b/fuchsia/mojo/test_typemaps.gni
@@ -0,0 +1,5 @@ +# 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. + +typemaps = [ "//fuchsia/mojo/example.typemap" ]
diff --git a/google_apis/BUILD.gn b/google_apis/BUILD.gn index 9560f53..199cab7 100644 --- a/google_apis/BUILD.gn +++ b/google_apis/BUILD.gn
@@ -177,6 +177,8 @@ sources = [ "gaia/fake_gaia.cc", "gaia/fake_gaia.h", + "gaia/fake_oauth2_access_token_manager.cc", + "gaia/fake_oauth2_access_token_manager.h", "gaia/fake_oauth2_token_service.cc", "gaia/fake_oauth2_token_service.h", "gaia/fake_oauth2_token_service_delegate.cc",
diff --git a/google_apis/gaia/fake_oauth2_access_token_manager.cc b/google_apis/gaia/fake_oauth2_access_token_manager.cc new file mode 100644 index 0000000..65df882 --- /dev/null +++ b/google_apis/gaia/fake_oauth2_access_token_manager.cc
@@ -0,0 +1,202 @@ +// 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 "google_apis/gaia/fake_oauth2_access_token_manager.h" + +#include <memory> + +#include "base/bind.h" +#include "base/location.h" +#include "base/single_thread_task_runner.h" +#include "base/threading/thread_task_runner_handle.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" + +FakeOAuth2AccessTokenManager::PendingRequest::PendingRequest() {} + +FakeOAuth2AccessTokenManager::PendingRequest::PendingRequest( + const PendingRequest& other) = default; + +FakeOAuth2AccessTokenManager::PendingRequest::~PendingRequest() {} + +FakeOAuth2AccessTokenManager::FakeOAuth2AccessTokenManager( + OAuth2TokenService* token_service, + OAuth2AccessTokenManager::Delegate* delegate) + : OAuth2AccessTokenManager(token_service, delegate), + auto_post_fetch_response_on_message_loop_(false), + weak_ptr_factory_(this) {} + +FakeOAuth2AccessTokenManager::~FakeOAuth2AccessTokenManager() {} + +void FakeOAuth2AccessTokenManager::IssueAllTokensForAccount( + const std::string& account_id, + const std::string& access_token, + const base::Time& expiration) { + DCHECK(!auto_post_fetch_response_on_message_loop_); + CompleteRequests(account_id, true, FakeOAuth2AccessTokenManager::ScopeSet(), + GoogleServiceAuthError::AuthErrorNone(), + OAuth2AccessTokenConsumer::TokenResponse( + access_token, expiration, std::string() /* id_token */)); +} + +void FakeOAuth2AccessTokenManager::IssueAllTokensForAccount( + const std::string& account_id, + const OAuth2AccessTokenConsumer::TokenResponse& token_response) { + DCHECK(!auto_post_fetch_response_on_message_loop_); + CompleteRequests(account_id, true, FakeOAuth2AccessTokenManager::ScopeSet(), + GoogleServiceAuthError::AuthErrorNone(), token_response); +} + +void FakeOAuth2AccessTokenManager::IssueErrorForAllPendingRequestsForAccount( + const std::string& account_id, + const GoogleServiceAuthError& error) { + DCHECK(!auto_post_fetch_response_on_message_loop_); + CompleteRequests(account_id, true, FakeOAuth2AccessTokenManager::ScopeSet(), + error, OAuth2AccessTokenConsumer::TokenResponse()); +} + +void FakeOAuth2AccessTokenManager::IssueTokenForScope( + const FakeOAuth2AccessTokenManager::ScopeSet& scope, + const std::string& access_token, + const base::Time& expiration) { + DCHECK(!auto_post_fetch_response_on_message_loop_); + CompleteRequests("", false, scope, GoogleServiceAuthError::AuthErrorNone(), + OAuth2AccessTokenConsumer::TokenResponse( + access_token, expiration, std::string() /* id_token */)); +} + +void FakeOAuth2AccessTokenManager::IssueTokenForScope( + const FakeOAuth2AccessTokenManager::ScopeSet& scope, + const OAuth2AccessTokenConsumer::TokenResponse& token_response) { + DCHECK(!auto_post_fetch_response_on_message_loop_); + CompleteRequests("", false, scope, GoogleServiceAuthError::AuthErrorNone(), + token_response); +} + +void FakeOAuth2AccessTokenManager::IssueErrorForScope( + const FakeOAuth2AccessTokenManager::ScopeSet& scope, + const GoogleServiceAuthError& error) { + DCHECK(!auto_post_fetch_response_on_message_loop_); + CompleteRequests("", false, scope, error, + OAuth2AccessTokenConsumer::TokenResponse()); +} + +void FakeOAuth2AccessTokenManager::IssueErrorForAllPendingRequests( + const GoogleServiceAuthError& error) { + DCHECK(!auto_post_fetch_response_on_message_loop_); + CompleteRequests("", true, FakeOAuth2AccessTokenManager::ScopeSet(), error, + OAuth2AccessTokenConsumer::TokenResponse()); +} + +void FakeOAuth2AccessTokenManager::IssueTokenForAllPendingRequests( + const std::string& access_token, + const base::Time& expiration) { + DCHECK(!auto_post_fetch_response_on_message_loop_); + CompleteRequests("", true, FakeOAuth2AccessTokenManager::ScopeSet(), + GoogleServiceAuthError::AuthErrorNone(), + OAuth2AccessTokenConsumer::TokenResponse( + access_token, expiration, std::string() /* id_token */)); +} + +void FakeOAuth2AccessTokenManager::IssueTokenForAllPendingRequests( + const OAuth2AccessTokenConsumer::TokenResponse& token_response) { + DCHECK(!auto_post_fetch_response_on_message_loop_); + CompleteRequests("", true, FakeOAuth2AccessTokenManager::ScopeSet(), + GoogleServiceAuthError::AuthErrorNone(), token_response); +} + +void FakeOAuth2AccessTokenManager::CompleteRequests( + const std::string& account_id, + bool all_scopes, + const FakeOAuth2AccessTokenManager::ScopeSet& scope, + const GoogleServiceAuthError& error, + const OAuth2AccessTokenConsumer::TokenResponse& token_response) { + std::vector<FakeOAuth2AccessTokenManager::PendingRequest> requests = + GetPendingRequests(); + + // Walk the requests and notify the callbacks. + for (auto it = requests.begin(); it != requests.end(); ++it) { + // Consumers can drop requests in response to callbacks on other requests + // (e.g., OAuthMultiloginFetcher clears all of its requests when it gets an + // error on any of them). + if (!it->request) + continue; + + bool scope_matches = all_scopes || it->scopes == scope; + bool account_matches = account_id.empty() || account_id == it->account_id; + if (account_matches && scope_matches) { + for (auto& diagnostic_observer : GetDiagnosticsObserversForTesting()) { + diagnostic_observer.OnFetchAccessTokenComplete( + account_id, it->request->GetConsumerId(), scope, error, + base::Time()); + } + + it->request->InformConsumer( + error, OAuth2AccessTokenConsumer::TokenResponse( + token_response.access_token, + token_response.expiration_time, token_response.id_token)); + } + } +} + +std::vector<FakeOAuth2AccessTokenManager::PendingRequest> +FakeOAuth2AccessTokenManager::GetPendingRequests() { + std::vector<PendingRequest> valid_requests; + for (auto it = pending_requests_.begin(); it != pending_requests_.end(); + ++it) { + if (it->request) + valid_requests.push_back(*it); + } + return valid_requests; +} + +void FakeOAuth2AccessTokenManager::CancelAllRequests() { + CompleteRequests( + "", true, FakeOAuth2AccessTokenManager::ScopeSet(), + GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED), + OAuth2AccessTokenConsumer::TokenResponse()); +} + +void FakeOAuth2AccessTokenManager::CancelRequestsForAccount( + const CoreAccountId& account_id) { + CompleteRequests( + account_id, true, FakeOAuth2AccessTokenManager::ScopeSet(), + GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED), + OAuth2AccessTokenConsumer::TokenResponse()); +} + +void FakeOAuth2AccessTokenManager::FetchOAuth2Token( + FakeOAuth2AccessTokenManager::RequestImpl* request, + const CoreAccountId& account_id, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + const std::string& client_id, + const std::string& client_secret, + const FakeOAuth2AccessTokenManager::ScopeSet& scopes) { + PendingRequest pending_request; + pending_request.account_id = account_id; + pending_request.client_id = client_id; + pending_request.client_secret = client_secret; + pending_request.url_loader_factory = url_loader_factory; + pending_request.scopes = scopes; + pending_request.request = request->AsWeakPtr(); + pending_requests_.push_back(pending_request); + + if (auto_post_fetch_response_on_message_loop_) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(&FakeOAuth2AccessTokenManager::CompleteRequests, + weak_ptr_factory_.GetWeakPtr(), account_id, + /*all_scoped=*/true, scopes, + GoogleServiceAuthError::AuthErrorNone(), + OAuth2AccessTokenConsumer::TokenResponse( + "access_token", base::Time::Max(), std::string()))); + } +} + +void FakeOAuth2AccessTokenManager::InvalidateAccessTokenImpl( + const CoreAccountId& account_id, + const std::string& client_id, + const FakeOAuth2AccessTokenManager::ScopeSet& scopes, + const std::string& access_token) { + // Do nothing, as we don't have a cache from which to remove the token. +}
diff --git a/google_apis/gaia/fake_oauth2_access_token_manager.h b/google_apis/gaia/fake_oauth2_access_token_manager.h new file mode 100644 index 0000000..fed88c1 --- /dev/null +++ b/google_apis/gaia/fake_oauth2_access_token_manager.h
@@ -0,0 +1,124 @@ +// 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 GOOGLE_APIS_GAIA_FAKE_OAUTH2_ACCESS_TOKEN_MANAGER_H_ +#define GOOGLE_APIS_GAIA_FAKE_OAUTH2_ACCESS_TOKEN_MANAGER_H_ + +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "google_apis/gaia/oauth2_access_token_manager.h" + +namespace network { +class SharedURLLoaderFactory; +} + +// Helper class to simplify writing unittests that depend on an instance of +// OAuth2AccessTokenManager. +class FakeOAuth2AccessTokenManager : public OAuth2AccessTokenManager { + public: + struct PendingRequest { + PendingRequest(); + PendingRequest(const PendingRequest& other); + ~PendingRequest(); + + std::string account_id; + std::string client_id; + std::string client_secret; + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory; + OAuth2AccessTokenManager::ScopeSet scopes; + base::WeakPtr<OAuth2AccessTokenManager::RequestImpl> request; + }; + + explicit FakeOAuth2AccessTokenManager( + OAuth2TokenService* token_service, + OAuth2AccessTokenManager::Delegate* delegate); + ~FakeOAuth2AccessTokenManager() override; + + // Gets a list of active requests (can be used by tests to validate that the + // correct request has been issued). + std::vector<PendingRequest> GetPendingRequests(); + + // Helper routines to issue tokens for pending requests. + void IssueAllTokensForAccount(const std::string& account_id, + const std::string& access_token, + const base::Time& expiration); + + // Helper routines to issue token for pending requests based on TokenResponse. + void IssueAllTokensForAccount( + const std::string& account_id, + const OAuth2AccessTokenConsumer::TokenResponse& token_response); + + void IssueErrorForAllPendingRequestsForAccount( + const std::string& account_id, + const GoogleServiceAuthError& error); + + void IssueTokenForScope(const OAuth2AccessTokenManager::ScopeSet& scopes, + const std::string& access_token, + const base::Time& expiration); + + void IssueTokenForScope( + const OAuth2AccessTokenManager::ScopeSet& scopes, + const OAuth2AccessTokenConsumer::TokenResponse& token_response); + + void IssueErrorForScope(const OAuth2AccessTokenManager::ScopeSet& scopes, + const GoogleServiceAuthError& error); + + void IssueTokenForAllPendingRequests(const std::string& access_token, + const base::Time& expiration); + + void IssueTokenForAllPendingRequests( + const OAuth2AccessTokenConsumer::TokenResponse& token_response); + + void IssueErrorForAllPendingRequests(const GoogleServiceAuthError& error); + + void set_auto_post_fetch_response_on_message_loop(bool auto_post_response) { + auto_post_fetch_response_on_message_loop_ = auto_post_response; + } + + // OAuth2AccessTokenManager overrides. + void CancelAllRequests() override; + + void CancelRequestsForAccount(const CoreAccountId& account_id) override; + + void FetchOAuth2Token( + OAuth2AccessTokenManager::RequestImpl* request, + const CoreAccountId& account_id, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + const std::string& client_id, + const std::string& client_secret, + const OAuth2AccessTokenManager::ScopeSet& scopes) override; + + void InvalidateAccessTokenImpl( + const CoreAccountId& account_id, + const std::string& client_id, + const OAuth2AccessTokenManager::ScopeSet& scopes, + const std::string& access_token) override; + + private: + // Helper function to complete pending requests - if |all_scopes| is true, + // then all pending requests are completed, otherwise, only those requests + // matching |scopes| are completed. If |account_id| is empty, then pending + // requests for all accounts are completed, otherwise only requests for the + // given account. + void CompleteRequests( + const std::string& account_id, + bool all_scopes, + const OAuth2AccessTokenManager::ScopeSet& scopes, + const GoogleServiceAuthError& error, + const OAuth2AccessTokenConsumer::TokenResponse& token_response); + + std::vector<PendingRequest> pending_requests_; + + // If true, then this fake manager will post responses to + // |FetchOAuth2Token| on the current run loop. There is no need to call + // |IssueTokenForScope| in this case. + bool auto_post_fetch_response_on_message_loop_; + + base::WeakPtrFactory<FakeOAuth2AccessTokenManager> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(FakeOAuth2AccessTokenManager); +}; + +#endif // GOOGLE_APIS_GAIA_FAKE_OAUTH2_ACCESS_TOKEN_MANAGER_H_
diff --git a/google_apis/gaia/fake_oauth2_token_service.cc b/google_apis/gaia/fake_oauth2_token_service.cc index 0fede583..988f5e3 100644 --- a/google_apis/gaia/fake_oauth2_token_service.cc +++ b/google_apis/gaia/fake_oauth2_token_service.cc
@@ -6,17 +6,13 @@ #include <memory> -FakeOAuth2TokenService::PendingRequest::PendingRequest() { -} - -FakeOAuth2TokenService::PendingRequest::PendingRequest( - const PendingRequest& other) = default; - -FakeOAuth2TokenService::PendingRequest::~PendingRequest() { -} - FakeOAuth2TokenService::FakeOAuth2TokenService() - : OAuth2TokenService(std::make_unique<FakeOAuth2TokenServiceDelegate>()) {} + : OAuth2TokenService(std::make_unique<FakeOAuth2TokenServiceDelegate>()) { + OverrideAccessTokenManagerForTesting( + std::make_unique<FakeOAuth2AccessTokenManager>( + this /* OAuth2TokenService* */, + this /* OAuth2AccessTokenManager::Delegate* */)); +} FakeOAuth2TokenService::~FakeOAuth2TokenService() { } @@ -28,13 +24,9 @@ const std::string& client_id, const std::string& client_secret, const OAuth2AccessTokenManager::ScopeSet& scopes) { - PendingRequest pending_request; - pending_request.account_id = account_id; - pending_request.client_id = client_id; - pending_request.client_secret = client_secret; - pending_request.scopes = scopes; - pending_request.request = request->AsWeakPtr(); - pending_requests_.push_back(pending_request); + GetFakeAccessTokenManager()->FetchOAuth2Token(request, account_id, + url_loader_factory, client_id, + client_secret, scopes); } void FakeOAuth2TokenService::AddAccount(const CoreAccountId& account_id) { @@ -48,38 +40,23 @@ void FakeOAuth2TokenService::IssueAllTokensForAccount( const CoreAccountId& account_id, const OAuth2AccessTokenConsumer::TokenResponse& token_response) { - // Walk the requests and notify the callbacks. - // Using a copy of pending requests to make sure a new token request triggered - // from the handling code does not invalidate the iterator. - std::vector<PendingRequest> pending_requests_copy = pending_requests_; - for (std::vector<PendingRequest>::iterator it = pending_requests_copy.begin(); - it != pending_requests_copy.end(); - ++it) { - if (it->request && (account_id == it->account_id)) { - it->request->InformConsumer(GoogleServiceAuthError::AuthErrorNone(), - token_response); - } - } + GetFakeAccessTokenManager()->IssueAllTokensForAccount(account_id, + token_response); } void FakeOAuth2TokenService::IssueErrorForAllPendingRequestsForAccount( const CoreAccountId& account_id, const GoogleServiceAuthError& auth_error) { - // Walk the requests and notify the callbacks. - // Using a copy of pending requests to make sure retrying a request in - // response to the error does not invalidate the iterator. - std::vector<PendingRequest> pending_requests_copy = pending_requests_; - for (std::vector<PendingRequest>::iterator it = pending_requests_copy.begin(); - it != pending_requests_copy.end(); - ++it) { - if (it->request && (account_id == it->account_id)) { - it->request->InformConsumer(auth_error, - OAuth2AccessTokenConsumer::TokenResponse()); - } - } + GetFakeAccessTokenManager()->IssueErrorForAllPendingRequestsForAccount( + account_id, auth_error); } FakeOAuth2TokenServiceDelegate* FakeOAuth2TokenService::GetFakeOAuth2TokenServiceDelegate() { return static_cast<FakeOAuth2TokenServiceDelegate*>(GetDelegate()); } + +FakeOAuth2AccessTokenManager* +FakeOAuth2TokenService::GetFakeAccessTokenManager() { + return static_cast<FakeOAuth2AccessTokenManager*>(GetAccessTokenManager()); +}
diff --git a/google_apis/gaia/fake_oauth2_token_service.h b/google_apis/gaia/fake_oauth2_token_service.h index 9d5df0c..1a35d91 100644 --- a/google_apis/gaia/fake_oauth2_token_service.h +++ b/google_apis/gaia/fake_oauth2_token_service.h
@@ -7,8 +7,8 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "google_apis/gaia/fake_oauth2_access_token_manager.h" #include "google_apis/gaia/fake_oauth2_token_service_delegate.h" -#include "google_apis/gaia/oauth2_access_token_manager.h" #include "google_apis/gaia/oauth2_token_service.h" namespace network { @@ -55,19 +55,7 @@ const std::string& access_token) override {} private: - struct PendingRequest { - PendingRequest(); - PendingRequest(const PendingRequest& other); - ~PendingRequest(); - - CoreAccountId account_id; - std::string client_id; - std::string client_secret; - OAuth2AccessTokenManager::ScopeSet scopes; - base::WeakPtr<OAuth2AccessTokenManager::RequestImpl> request; - }; - - std::vector<PendingRequest> pending_requests_; + FakeOAuth2AccessTokenManager* GetFakeAccessTokenManager(); DISALLOW_COPY_AND_ASSIGN(FakeOAuth2TokenService); };
diff --git a/google_apis/gaia/gaia_auth_fetcher_unittest.cc b/google_apis/gaia/gaia_auth_fetcher_unittest.cc index 291e38d3..579a52f6 100644 --- a/google_apis/gaia/gaia_auth_fetcher_unittest.cc +++ b/google_apis/gaia/gaia_auth_fetcher_unittest.cc
@@ -29,6 +29,7 @@ #include "net/base/net_errors.h" #include "net/http/http_response_headers.h" #include "net/http/http_status_code.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/test/test_url_loader_factory.h" #include "testing/gmock/include/gmock/gmock.h" @@ -441,7 +442,7 @@ TestGaiaAuthFetcher auth(&consumer, GetURLLoaderFactory()); auth.CreateAndStartGaiaFetcherForTesting(/*body=*/"", /*headers=*/"", oauth_login_gurl_, /*load_flags=*/0, - NO_TRAFFIC_ANNOTATION_YET); + TRAFFIC_ANNOTATION_FOR_TESTS); auth.TestOnURLLoadCompleteInternal(net::OK, net::HTTP_OK, data); } @@ -462,7 +463,7 @@ /*body=*/"", /*headers=*/"", GaiaUrls::GetInstance()->ListAccountsURLWithSource( GaiaConstants::kChromeSource), - /*load_flags=*/0, NO_TRAFFIC_ANNOTATION_YET); + /*load_flags=*/0, TRAFFIC_ANNOTATION_FOR_TESTS); ASSERT_EQ(received_requests_.size(), 1U); EXPECT_EQ(net::LOAD_NORMAL, received_requests_.at(0).load_flags); EXPECT_EQ(GaiaUrls::GetInstance()->gaia_url(), @@ -479,7 +480,7 @@ /*body=*/"", /*headers=*/"", GaiaUrls::GetInstance()->LogOutURLWithSource( GaiaConstants::kChromeSource), - /*load_flags=*/0, NO_TRAFFIC_ANNOTATION_YET); + /*load_flags=*/0, TRAFFIC_ANNOTATION_FOR_TESTS); auth.TestOnURLLoadCompleteInternal(net::OK); } @@ -497,7 +498,7 @@ /*body=*/"", /*headers=*/"", GaiaUrls::GetInstance()->LogOutURLWithSource( GaiaConstants::kChromeSource), - /*load_flags=*/0, NO_TRAFFIC_ANNOTATION_YET); + /*load_flags=*/0, TRAFFIC_ANNOTATION_FOR_TESTS); auth.TestOnURLLoadCompleteInternal(error_no); } @@ -513,7 +514,7 @@ /*body=*/"", /*headers=*/"", GaiaUrls::GetInstance()->GetCheckConnectionInfoURLWithSource( GaiaConstants::kChromeSource), - /*load_flags=*/0, NO_TRAFFIC_ANNOTATION_YET); + /*load_flags=*/0, TRAFFIC_ANNOTATION_FOR_TESTS); auth.TestOnURLLoadCompleteInternal(net::OK, net::HTTP_OK, data); } @@ -527,7 +528,7 @@ TestGaiaAuthFetcher auth(&consumer, GetURLLoaderFactory()); auth.CreateAndStartGaiaFetcherForTesting( /*body=*/"", /*headers=*/"", GaiaUrls::GetInstance()->oauth2_revoke_url(), - /*load_flags=*/0, NO_TRAFFIC_ANNOTATION_YET); + /*load_flags=*/0, TRAFFIC_ANNOTATION_FOR_TESTS); auth.TestOnURLLoadCompleteInternal(net::OK, net::HTTP_OK, data); } @@ -541,7 +542,7 @@ TestGaiaAuthFetcher auth(&consumer, GetURLLoaderFactory()); auth.CreateAndStartGaiaFetcherForTesting( /*body=*/"", /*headers=*/"", GaiaUrls::GetInstance()->oauth2_revoke_url(), - /*load_flags=*/0, NO_TRAFFIC_ANNOTATION_YET); + /*load_flags=*/0, TRAFFIC_ANNOTATION_FOR_TESTS); auth.TestOnURLLoadCompleteInternal(net::ERR_ABORTED); } @@ -555,7 +556,7 @@ TestGaiaAuthFetcher auth(&consumer, GetURLLoaderFactory()); auth.CreateAndStartGaiaFetcherForTesting( /*body=*/"", /*headers=*/"", GaiaUrls::GetInstance()->oauth2_revoke_url(), - /*load_flags=*/0, NO_TRAFFIC_ANNOTATION_YET); + /*load_flags=*/0, TRAFFIC_ANNOTATION_FOR_TESTS); auth.TestOnURLLoadCompleteInternal(net::ERR_CERT_CONTAINS_ERRORS); } @@ -569,7 +570,7 @@ TestGaiaAuthFetcher auth(&consumer, GetURLLoaderFactory()); auth.CreateAndStartGaiaFetcherForTesting( /*body=*/"", /*headers=*/"", GaiaUrls::GetInstance()->oauth2_revoke_url(), - /*load_flags=*/0, NO_TRAFFIC_ANNOTATION_YET); + /*load_flags=*/0, TRAFFIC_ANNOTATION_FOR_TESTS); auth.TestOnURLLoadCompleteInternal(net::ERR_TIMED_OUT); } @@ -584,7 +585,7 @@ TestGaiaAuthFetcher auth(&consumer, GetURLLoaderFactory()); auth.CreateAndStartGaiaFetcherForTesting( /*body=*/"", /*headers=*/"", GaiaUrls::GetInstance()->oauth2_revoke_url(), - /*load_flags=*/0, NO_TRAFFIC_ANNOTATION_YET); + /*load_flags=*/0, TRAFFIC_ANNOTATION_FOR_TESTS); auth.TestOnURLLoadCompleteInternal(net::OK, net::HTTP_BAD_REQUEST, data); } @@ -599,7 +600,7 @@ TestGaiaAuthFetcher auth(&consumer, GetURLLoaderFactory()); auth.CreateAndStartGaiaFetcherForTesting( /*body=*/"", /*headers=*/"", GaiaUrls::GetInstance()->oauth2_revoke_url(), - /*load_flags=*/0, NO_TRAFFIC_ANNOTATION_YET); + /*load_flags=*/0, TRAFFIC_ANNOTATION_FOR_TESTS); auth.TestOnURLLoadCompleteInternal(net::OK, net::HTTP_BAD_REQUEST, data); } @@ -614,7 +615,7 @@ TestGaiaAuthFetcher auth(&consumer, GetURLLoaderFactory()); auth.CreateAndStartGaiaFetcherForTesting( /*body=*/"", /*headers=*/"", GaiaUrls::GetInstance()->oauth2_revoke_url(), - /*load_flags=*/0, NO_TRAFFIC_ANNOTATION_YET); + /*load_flags=*/0, TRAFFIC_ANNOTATION_FOR_TESTS); auth.TestOnURLLoadCompleteInternal(net::OK, net::HTTP_INTERNAL_SERVER_ERROR, data); }
diff --git a/google_apis/gaia/oauth2_access_token_manager.cc b/google_apis/gaia/oauth2_access_token_manager.cc index 202e36c..3b932c0 100644 --- a/google_apis/gaia/oauth2_access_token_manager.cc +++ b/google_apis/gaia/oauth2_access_token_manager.cc
@@ -580,6 +580,12 @@ : iter->second->GetWaitingRequestCount(); } +const base::ObserverList<OAuth2AccessTokenManager::DiagnosticsObserver, + true>::Unchecked& +OAuth2AccessTokenManager::GetDiagnosticsObserversForTesting() { + return diagnostics_observer_list_; +} + std::unique_ptr<OAuth2AccessTokenFetcher> OAuth2AccessTokenManager::CreateAccessTokenFetcher( const CoreAccountId& account_id,
diff --git a/google_apis/gaia/oauth2_access_token_manager.h b/google_apis/gaia/oauth2_access_token_manager.h index 61aab64..36cdbed 100644 --- a/google_apis/gaia/oauth2_access_token_manager.h +++ b/google_apis/gaia/oauth2_access_token_manager.h
@@ -203,8 +203,10 @@ const ScopeSet& scopes, Consumer* consumer); - // Fetches an OAuth token for the specified client/scopes. - void FetchOAuth2Token( + // Fetches an OAuth token for the specified client/scopes. Virtual so it can + // be overridden for tests. + // TODO(https://crbug.com/967598): Move this to protected. + virtual void FetchOAuth2Token( RequestImpl* request, const CoreAccountId& account_id, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, @@ -234,11 +236,15 @@ // used to request the tokens. void ClearCacheForAccount(const CoreAccountId& account_id); - // Cancels all requests that are currently in progress. - void CancelAllRequests(); + // Cancels all requests that are currently in progress. Virtual so it can be + // overridden for tests. + // TODO(https://crbug.com/967598): Move this to protected. + virtual void CancelAllRequests(); - // Cancels all requests related to a given |account_id|. - void CancelRequestsForAccount(const CoreAccountId& account_id); + // Cancels all requests related to a given |account_id|. Virtual so it can be + // overridden for tests. + // TODO(https://crbug.com/967598): Move this to protected. + virtual void CancelRequestsForAccount(const CoreAccountId& account_id); // Mark an OAuth2 |access_token| issued for |account_id| and |scopes| as // invalid. This should be done if the token was received from this class, @@ -250,11 +256,12 @@ const std::string& access_token); // Invalidates the |access_token| issued for |account_id|, |client_id| and - // |scopes|. - void InvalidateAccessTokenImpl(const CoreAccountId& account_id, - const std::string& client_id, - const ScopeSet& scopes, - const std::string& access_token); + // |scopes|. Virtual so it can be overridden for tests. + // TODO(https://crbug.com/967598): Move this to protected. + virtual void InvalidateAccessTokenImpl(const CoreAccountId& account_id, + const std::string& client_id, + const ScopeSet& scopes, + const std::string& access_token); void set_max_authorization_token_fetch_retries_for_testing(int max_retries); @@ -263,6 +270,10 @@ const CoreAccountId& account_id, const ScopeSet& scopes) const; + // Returns a list of DiagnosticsObservers. + const base::ObserverList<DiagnosticsObserver, true>::Unchecked& + GetDiagnosticsObserversForTesting(); + private: // TODO(https://crbug.com/967598): Remove this once |token_cache_| management // is moved to OAuth2AccessTokenManager.
diff --git a/gpu/config/gpu_finch_features.cc b/gpu/config/gpu_finch_features.cc index c5a7732b..66675ae1 100644 --- a/gpu/config/gpu_finch_features.cc +++ b/gpu/config/gpu_finch_features.cc
@@ -75,7 +75,7 @@ "DirectCompositionUnderlays", base::FEATURE_ENABLED_BY_DEFAULT}; // Use ThreadPriority::DISPLAY for GPU main, viz compositor and IO threads. -#if defined(OS_ANDROID) || defined(OS_CHROMEOS) || defined(USE_OZONE) +#if defined(OS_ANDROID) || defined(OS_CHROMEOS) const base::Feature kGpuUseDisplayThreadPriority{ "GpuUseDisplayThreadPriority", base::FEATURE_ENABLED_BY_DEFAULT}; #else
diff --git a/gpu/config/gpu_info.cc b/gpu/config/gpu_info.cc index 963884c..7b9fddb 100644 --- a/gpu/config/gpu_info.cc +++ b/gpu/config/gpu_info.cc
@@ -326,6 +326,7 @@ enumerator->AddInt64("rgbaVisual", rgba_visual); #endif enumerator->AddBool("oopRasterizationSupported", oop_rasterization_supported); + enumerator->EndAuxAttributes(); } } // namespace gpu
diff --git a/gpu/vulkan/vulkan_surface.cc b/gpu/vulkan/vulkan_surface.cc index 339a0b5..a4a1e05 100644 --- a/gpu/vulkan/vulkan_surface.cc +++ b/gpu/vulkan/vulkan_surface.cc
@@ -113,12 +113,13 @@ void VulkanSurface::Destroy() { swap_chain_->Destroy(); + swap_chain_ = nullptr; vkDestroySurfaceKHR(vk_instance_, surface_, nullptr); surface_ = VK_NULL_HANDLE; } gfx::SwapResult VulkanSurface::SwapBuffers() { - return swap_chain_->SwapBuffers(); + return swap_chain_->PresentBuffer(); } VulkanSwapChain* VulkanSurface::GetSwapChain() { @@ -133,7 +134,7 @@ return CreateSwapChain(size); } -bool VulkanSurface::CreateSwapChain(const gfx::Size& size) { +bool VulkanSurface::CreateSwapChain(const gfx::Size& new_size) { // Get Surface Information. VkSurfaceCapabilitiesKHR surface_caps; VkResult result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR( @@ -144,19 +145,19 @@ return false; } - // If width and height of the surface are 0xFFFFFFFF, it means the surface - // size will be determined by the extent of a swapchain targeting the surface. - // In that case, we will use the |size| which is the window size for the - // swapchain. Otherwise, we just use the current surface size for the - // swapchian. - const uint32_t kUndefinedExtent = 0xFFFFFFFF; - if (surface_caps.currentExtent.width == kUndefinedExtent && - surface_caps.currentExtent.height == kUndefinedExtent) { - surface_caps.currentExtent.width = std::max( - surface_caps.minImageExtent.width, static_cast<uint32_t>(size.width())); - surface_caps.currentExtent.height = - std::max(surface_caps.minImageExtent.height, - static_cast<uint32_t>(size.height())); + // For Android, the current vulkan surface size may not match the new_size + // (the current window size), in that case, we will create a swapchain with + // the requested new_size, and vulkan surface size should match the swapchain + // images size soon. + if (!new_size.IsEmpty()) { + DLOG_IF(ERROR, + base::checked_cast<int>(surface_caps.currentExtent.width) != + new_size.width() || + base::checked_cast<int>(surface_caps.currentExtent.height) != + new_size.height()) + << "Requested new size doesn't match vulkan surface size."; + surface_caps.currentExtent.width = new_size.width(); + surface_caps.currentExtent.height = new_size.height(); } DCHECK_GE(surface_caps.currentExtent.width, @@ -170,14 +171,12 @@ DCHECK_GT(surface_caps.currentExtent.width, 0u); DCHECK_GT(surface_caps.currentExtent.height, 0u); - gfx::Size new_size( - base::checked_cast<int>(surface_caps.currentExtent.width), - base::checked_cast<int>(surface_caps.currentExtent.height)); if (size_ == new_size) return true; size_ = new_size; auto swap_chain = std::make_unique<VulkanSwapChain>(); + // Create Swapchain. if (!swap_chain->Initialize(device_queue_, surface_, surface_caps, surface_format_, std::move(swap_chain_))) { @@ -185,6 +184,7 @@ } swap_chain_ = std::move(swap_chain); + ++swap_chain_generation_; return true; }
diff --git a/gpu/vulkan/vulkan_surface.h b/gpu/vulkan/vulkan_surface.h index 8bae0235..c33a7387 100644 --- a/gpu/vulkan/vulkan_surface.h +++ b/gpu/vulkan/vulkan_surface.h
@@ -42,6 +42,7 @@ gfx::SwapResult SwapBuffers(); VulkanSwapChain* GetSwapChain(); + uint32_t swap_chain_generation() const { return swap_chain_generation_; } void Finish(); @@ -51,13 +52,17 @@ VkSurfaceFormatKHR surface_format() const { return surface_format_; } private: - bool CreateSwapChain(const gfx::Size& size); + bool CreateSwapChain(const gfx::Size& new_size); const VkInstance vk_instance_; gfx::Size size_; VkSurfaceKHR surface_ = VK_NULL_HANDLE; VkSurfaceFormatKHR surface_format_ = {}; VulkanDeviceQueue* device_queue_ = nullptr; + + // The generation of |swap_chain_|, it will be increasted if a new + // |swap_chain_| is created due to resizing, etec. + uint32_t swap_chain_generation_ = 0u; std::unique_ptr<VulkanSwapChain> swap_chain_; DISALLOW_COPY_AND_ASSIGN(VulkanSurface);
diff --git a/gpu/vulkan/vulkan_swap_chain.cc b/gpu/vulkan/vulkan_swap_chain.cc index 552d892..c73853c 100644 --- a/gpu/vulkan/vulkan_swap_chain.cc +++ b/gpu/vulkan/vulkan_swap_chain.cc
@@ -56,7 +56,8 @@ DestroySwapChain(); } -gfx::SwapResult VulkanSwapChain::SwapBuffers() { +gfx::SwapResult VulkanSwapChain::PresentBuffer() { + DCHECK(acquired_image_); DCHECK(end_write_semaphore_ != VK_NULL_HANDLE); VkResult result = VK_SUCCESS; @@ -64,7 +65,7 @@ VkQueue queue = device_queue_->GetVulkanQueue(); auto* fence_helper = device_queue_->GetFenceHelper(); - auto& current_image_data = images_[current_image_]; + auto& current_image_data = images_[*acquired_image_]; if (current_image_data.layout != VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) { { current_image_data.command_buffer->Clear(); @@ -96,31 +97,17 @@ present_info.pWaitSemaphores = &end_write_semaphore_; present_info.swapchainCount = 1; present_info.pSwapchains = &swap_chain_; - present_info.pImageIndices = ¤t_image_; + present_info.pImageIndices = &acquired_image_.value(); result = vkQueuePresentKHR(queue, &present_info); - if (VK_SUCCESS != result) { + if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) { + DLOG(ERROR) << "vkQueuePresentKHR() failed: " << result; return gfx::SwapResult::SWAP_FAILED; } + acquired_image_.reset(); fence_helper->EnqueueSemaphoreCleanupForSubmittedWork(end_write_semaphore_); end_write_semaphore_ = VK_NULL_HANDLE; - VkSemaphore vk_semaphore = CreateSemaphore(device); - DCHECK(vk_semaphore != VK_NULL_HANDLE); - - uint32_t next_image = 0; - // Acquire then next image. - result = vkAcquireNextImageKHR(device, swap_chain_, UINT64_MAX, vk_semaphore, - VK_NULL_HANDLE, &next_image); - if (VK_SUCCESS != result) { - vkDestroySemaphore(device, vk_semaphore, nullptr /* pAllocator */); - DLOG(ERROR) << "vkAcquireNextImageKHR() failed: " << result; - return gfx::SwapResult::SWAP_FAILED; - } - - current_image_ = next_image; - DCHECK(begin_write_semaphore_ == VK_NULL_HANDLE); - begin_write_semaphore_ = vk_semaphore; return gfx::SwapResult::SWAP_ACK; } @@ -143,7 +130,14 @@ swap_chain_create_info.imageArrayLayers = 1; swap_chain_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; swap_chain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; - swap_chain_create_info.preTransform = surface_caps.currentTransform; + // Always set preTransform to VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR (which is + // relative to the presentation engine's natural orientation), if it does not + // match the currentTransform value returned by + // vkGetPhysicalDeviceSurfaceCapabilitiesKHR, the presentation engine will + // transform the image content as part of the presentation operation. + // TODO(penghuang): Support preTransform for better performance. + // https://crbug.com/957485 + swap_chain_create_info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; swap_chain_create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; swap_chain_create_info.presentMode = VK_PRESENT_MODE_FIFO_KHR; swap_chain_create_info.clipped = true; @@ -212,27 +206,10 @@ // Initialize the command buffer for this buffer data. image_data.command_buffer = command_pool_->CreatePrimaryCommandBuffer(); } - - VkSemaphore vk_semaphore = CreateSemaphore(device); - DCHECK(vk_semaphore != VK_NULL_HANDLE); - - // Acquire the initial buffer. - result = vkAcquireNextImageKHR(device, swap_chain_, UINT64_MAX, vk_semaphore, - VK_NULL_HANDLE, ¤t_image_); - if (VK_SUCCESS != result) { - DLOG(ERROR) << "vkAcquireNextImageKHR() failed: " << result; - return false; - } - begin_write_semaphore_ = vk_semaphore; return true; } void VulkanSwapChain::DestroySwapImages() { - if (begin_write_semaphore_) - vkDestroySemaphore(device_queue_->GetVulkanDevice(), begin_write_semaphore_, - nullptr /* pAllocator */); - begin_write_semaphore_ = VK_NULL_HANDLE; - if (end_write_semaphore_) vkDestroySemaphore(device_queue_->GetVulkanDevice(), end_write_semaphore_, nullptr /* pAllocator */); @@ -250,7 +227,7 @@ command_pool_ = nullptr; } -void VulkanSwapChain::BeginWriteCurrentImage(VkImage* image, +bool VulkanSwapChain::BeginWriteCurrentImage(VkImage* image, uint32_t* image_index, VkImageLayout* image_layout, VkSemaphore* semaphore) { @@ -259,25 +236,52 @@ DCHECK(image_layout); DCHECK(semaphore); DCHECK(!is_writing_); - DCHECK(begin_write_semaphore_ != VK_NULL_HANDLE); - DCHECK(end_write_semaphore_ == VK_NULL_HANDLE); - auto& current_image_data = images_[current_image_]; + VkSemaphore vk_semaphore = VK_NULL_HANDLE; + + if (!acquired_image_) { + DCHECK(end_write_semaphore_ == VK_NULL_HANDLE); + + VkDevice device = device_queue_->GetVulkanDevice(); + vk_semaphore = CreateSemaphore(device); + DCHECK(vk_semaphore != VK_NULL_HANDLE); + + uint32_t next_image = 0; + // Acquire then next image. + auto result = + vkAcquireNextImageKHR(device, swap_chain_, UINT64_MAX, vk_semaphore, + VK_NULL_HANDLE, &next_image); + if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) { + vkDestroySemaphore(device, vk_semaphore, nullptr /* pAllocator */); + DLOG(ERROR) << "vkAcquireNextImageKHR() failed: " << result; + return false; + } + acquired_image_.emplace(next_image); + } else { + // In this case, PresentBuffer() is not called after + // {Begin,End}WriteCurrentImage pairs, |end_write_semaphore_| should be + // waited on before writing the image again. + vk_semaphore = end_write_semaphore_; + end_write_semaphore_ = VK_NULL_HANDLE; + } + + auto& current_image_data = images_[*acquired_image_]; *image = current_image_data.image; - *image_index = current_image_; + *image_index = *acquired_image_; *image_layout = current_image_data.layout; - *semaphore = begin_write_semaphore_; - begin_write_semaphore_ = VK_NULL_HANDLE; + *semaphore = vk_semaphore; is_writing_ = true; + + return true; } void VulkanSwapChain::EndWriteCurrentImage(VkImageLayout image_layout, VkSemaphore semaphore) { DCHECK(is_writing_); - DCHECK(begin_write_semaphore_ == VK_NULL_HANDLE); + DCHECK(acquired_image_); DCHECK(end_write_semaphore_ == VK_NULL_HANDLE); - auto& current_image_data = images_[current_image_]; + auto& current_image_data = images_[*acquired_image_]; current_image_data.layout = image_layout; end_write_semaphore_ = semaphore; is_writing_ = false; @@ -285,17 +289,17 @@ VulkanSwapChain::ScopedWrite::ScopedWrite(VulkanSwapChain* swap_chain) : swap_chain_(swap_chain) { - swap_chain_->BeginWriteCurrentImage(&image_, &image_index_, &image_layout_, - &begin_semaphore_); + success_ = swap_chain_->BeginWriteCurrentImage( + &image_, &image_index_, &image_layout_, &begin_semaphore_); } VulkanSwapChain::ScopedWrite::~ScopedWrite() { DCHECK(begin_semaphore_ == VK_NULL_HANDLE); - swap_chain_->EndWriteCurrentImage(image_layout_, end_semaphore_); + if (success_) + swap_chain_->EndWriteCurrentImage(image_layout_, end_semaphore_); } VkSemaphore VulkanSwapChain::ScopedWrite::TakeBeginSemaphore() { - DCHECK(begin_semaphore_ != VK_NULL_HANDLE); VkSemaphore semaphore = begin_semaphore_; begin_semaphore_ = VK_NULL_HANDLE; return semaphore;
diff --git a/gpu/vulkan/vulkan_swap_chain.h b/gpu/vulkan/vulkan_swap_chain.h index c073c50..11f8996a 100644 --- a/gpu/vulkan/vulkan_swap_chain.h +++ b/gpu/vulkan/vulkan_swap_chain.h
@@ -10,6 +10,7 @@ #include <vulkan/vulkan.h> #include "base/logging.h" +#include "base/optional.h" #include "gpu/vulkan/vulkan_export.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/swap_result.h" @@ -27,6 +28,7 @@ explicit ScopedWrite(VulkanSwapChain* swap_chain); ~ScopedWrite(); + bool success() const { return success_; } VkImage image() const { return image_; } uint32_t image_index() const { return image_index_; } VkImageLayout image_layout() const { return image_layout_; } @@ -42,6 +44,7 @@ private: VulkanSwapChain* const swap_chain_; + bool success_ = false; VkImage image_ = VK_NULL_HANDLE; uint32_t image_index_ = 0; VkImageLayout image_layout_ = VK_IMAGE_LAYOUT_UNDEFINED; @@ -61,10 +64,11 @@ std::unique_ptr<VulkanSwapChain> old_swap_chain); // Destroy() should be called when all related GPU tasks have been finished. void Destroy(); - gfx::SwapResult SwapBuffers(); + + // Present the current buffer. + gfx::SwapResult PresentBuffer(); uint32_t num_images() const { return static_cast<uint32_t>(images_.size()); } - uint32_t current_image() const { return current_image_; } const gfx::Size& size() const { return size_; } private: @@ -77,7 +81,7 @@ bool InitializeSwapImages(const VkSurfaceCapabilitiesKHR& surface_caps, const VkSurfaceFormatKHR& surface_format); void DestroySwapImages(); - void BeginWriteCurrentImage(VkImage* image, + bool BeginWriteCurrentImage(VkImage* image, uint32_t* image_index, VkImageLayout* layout, VkSemaphore* semaphore); @@ -102,9 +106,10 @@ std::unique_ptr<VulkanCommandBuffer> command_buffer; }; std::vector<ImageData> images_; - uint32_t current_image_ = 0; + + // Acquired image index. + base::Optional<uint32_t> acquired_image_; bool is_writing_ = false; - VkSemaphore begin_write_semaphore_ = VK_NULL_HANDLE; VkSemaphore end_write_semaphore_ = VK_NULL_HANDLE; DISALLOW_COPY_AND_ASSIGN(VulkanSwapChain);
diff --git a/infra/config/luci-milo.cfg b/infra/config/luci-milo.cfg index 45acd85a..f469948b 100644 --- a/infra/config/luci-milo.cfg +++ b/infra/config/luci-milo.cfg
@@ -189,7 +189,7 @@ } links { text: "chrome" - url: "/p/chrome/g/tryserver.chromium.chrome/builders" + url: "/p/chrome/g/tryserver.chrome/builders" alt: "Chrome" } links {
diff --git a/infra/config/tricium-prod.cfg b/infra/config/tricium-prod.cfg index 6a82b50..88027e2 100644 --- a/infra/config/tricium-prod.cfg +++ b/infra/config/tricium-prod.cfg
@@ -25,6 +25,11 @@ } selections { + function: "MojomCommentator" + platform: UBUNTU +} + +selections { function: "SpellChecker" platform: UBUNTU }
diff --git a/ios/chrome/app/application_delegate/metrics_mediator.mm b/ios/chrome/app/application_delegate/metrics_mediator.mm index 41042f89..276e123 100644 --- a/ios/chrome/app/application_delegate/metrics_mediator.mm +++ b/ios/chrome/app/application_delegate/metrics_mediator.mm
@@ -23,9 +23,9 @@ #import "ios/chrome/browser/net/connection_type_observer_bridge.h" #include "ios/chrome/browser/pref_names.h" #include "ios/chrome/browser/system_flags.h" -#import "ios/chrome/browser/tabs/tab.h" #import "ios/chrome/browser/tabs/tab_model.h" #import "ios/chrome/browser/ui/main/browser_interface_provider.h" +#import "ios/chrome/browser/web_state_list/web_state_list.h" #include "ios/chrome/common/app_group/app_group_metrics_mainapp.h" #include "ios/public/provider/chrome/browser/chrome_browser_provider.h" #include "ios/public/provider/chrome/browser/distribution/app_distribution_provider.h" @@ -142,9 +142,10 @@ [startupInformation activateFirstUserActionRecorderWithBackgroundTime:interval]; - Tab* currentTab = interfaceProvider.currentInterface.tabModel.currentTab; - if (currentTab.webState && - currentTab.webState->GetLastCommittedURL() == kChromeUINewTabURL) { + web::WebState* currentWebState = interfaceProvider.currentInterface.tabModel + .webStateList->GetActiveWebState(); + if (currentWebState && + currentWebState->GetLastCommittedURL() == kChromeUINewTabURL) { startupInformation.firstUserActionRecorder->RecordStartOnNTP(); [startupInformation resetFirstUserActionRecorder]; } else {
diff --git a/ios/chrome/app/application_delegate/metrics_mediator_unittest.mm b/ios/chrome/app/application_delegate/metrics_mediator_unittest.mm index f2b744f..8f6a2d6 100644 --- a/ios/chrome/app/application_delegate/metrics_mediator_unittest.mm +++ b/ios/chrome/app/application_delegate/metrics_mediator_unittest.mm
@@ -17,6 +17,8 @@ #import "ios/chrome/browser/ui/main/browser_interface_provider.h" #import "ios/chrome/browser/ui/main/test/stub_browser_interface.h" #import "ios/chrome/browser/ui/main/test/stub_browser_interface_provider.h" +#import "ios/chrome/browser/web_state_list/fake_web_state_list_delegate.h" +#import "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/chrome/test/base/scoped_block_swizzler.h" #import "ios/chrome/test/ocmock/OCMockObject+BreakpadControllerTesting.h" #include "net/base/network_change_notifier.h" @@ -123,12 +125,17 @@ class MetricsMediatorLogLaunchTest : public PlatformTest { protected: - MetricsMediatorLogLaunchTest() : has_been_called_(FALSE) {} + MetricsMediatorLogLaunchTest() + : has_been_called_(FALSE), + web_state_list_( + std::make_unique<WebStateList>(&web_state_list_delegate_)) {} void initiateMetricsMediator(BOOL coldStart, int tabCount) { id mainTabModel = [OCMockObject mockForClass:[TabModel class]]; [[[mainTabModel stub] andReturnValue:@(tabCount)] count]; - [[[mainTabModel stub] andReturn:nil] currentTab]; + WebStateList* web_state_list = web_state_list_.get(); + [[[mainTabModel stub] andReturnValue:OCMOCK_VALUE(web_state_list)] + webStateList]; StubBrowserInterfaceProvider* concreteProvider = [[StubBrowserInterfaceProvider alloc] init]; @@ -162,6 +169,8 @@ __block BOOL has_been_called_; logLaunchMetricsBlock swizzle_block_; std::unique_ptr<ScopedBlockSwizzler> uma_histogram_swizzler_; + std::unique_ptr<WebStateList> web_state_list_; + FakeWebStateListDelegate web_state_list_delegate_; }; // Verifies that the log of the number of open tabs is sent and verifies
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm index 2cd1e30..faad283 100644 --- a/ios/chrome/app/main_controller.mm +++ b/ios/chrome/app/main_controller.mm
@@ -109,7 +109,6 @@ #import "ios/chrome/browser/snapshots/snapshot_cache_factory.h" #import "ios/chrome/browser/snapshots/snapshot_tab_helper.h" #include "ios/chrome/browser/system_flags.h" -#import "ios/chrome/browser/tabs/tab.h" #import "ios/chrome/browser/tabs/tab_model.h" #import "ios/chrome/browser/ui/authentication/signed_in_accounts_view_controller.h" #import "ios/chrome/browser/ui/browser_view/browser_coordinator.h" @@ -1496,7 +1495,8 @@ } - (void)prepareTabSwitcher { - web::WebState* currentWebState = self.currentBVC.tabModel.currentTab.webState; + web::WebState* currentWebState = + self.currentBVC.tabModel.webStateList->GetActiveWebState(); if (currentWebState) { BOOL loading = currentWebState->IsLoading(); SnapshotTabHelper::FromWebState(currentWebState) @@ -2171,7 +2171,8 @@ // Removing browsing data triggers session restore in navigation manager. If // there is an in-progress session restore, wait for it to finish before // attempting to clear browsing data again. - web::WebState* webState = [[[self.currentBVC tabModel] currentTab] webState]; + web::WebState* webState = + self.currentBVC.tabModel.webStateList->GetActiveWebState(); if (webState && webState->GetNavigationManager()) { webState->GetNavigationManager()->AddRestoreCompletionCallback( base::BindOnce(^{ @@ -2262,15 +2263,13 @@ tabOpenedCompletion:(ProceduralBlock)tabOpenedCompletion { BrowserViewController* targetBVC = targetMode == ApplicationMode::NORMAL ? self.mainBVC : self.otrBVC; - TabModel* targetTabModel = targetBVC.tabModel; - - Tab* currentTabInTargetBVC = [targetTabModel currentTab]; + web::WebState* currentWebState = + targetBVC.tabModel.webStateList->GetActiveWebState(); // Don't call loadWithParams for chrome://newtab when it's already loaded. // Note that it's safe to use -GetVisibleURL here, as it doesn't matter if the // NTP hasn't finished loading. - if (currentTabInTargetBVC.webState && - IsURLNtp(currentTabInTargetBVC.webState->GetVisibleURL()) && + if (currentWebState && IsURLNtp(currentWebState->GetVisibleURL()) && IsURLNtp(urlLoadParams.web_params.url)) { if (tabOpenedCompletion) { tabOpenedCompletion(); @@ -2287,8 +2286,7 @@ // If the current tab isn't an NTP, open a new tab. Be sure to use // -GetLastCommittedURL incase the NTP is still loading. if (alwaysInsertNewTab || - !(currentTabInTargetBVC.webState && - IsURLNtp(currentTabInTargetBVC.webState->GetVisibleURL()))) { + !(currentWebState && IsURLNtp(currentWebState->GetVisibleURL()))) { [targetBVC appendTabAddedCompletion:tabOpenedCompletion]; UrlLoadParams newTabParams = urlLoadParams; newTabParams.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; @@ -2590,7 +2588,8 @@ - (NSString*)currentPageDisplayURL { if (_tabSwitcherIsActive) return nil; - web::WebState* webState = [[[self currentTabModel] currentTab] webState]; + web::WebState* webState = + self.currentTabModel.webStateList->GetActiveWebState(); if (!webState) return nil; // Returns URL of browser tab that is currently showing.
diff --git a/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.h b/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.h index 541af35..f091c7d 100644 --- a/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.h +++ b/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.h
@@ -75,8 +75,6 @@ history::KeywordID keyword_id, const base::string16& term) override; void PrefetchImage(const GURL& url) override; - void OnAutocompleteControllerResultReady( - AutocompleteController* controller) override; bool IsTabOpenWithURL(const GURL& url, const AutocompleteInput* input) override;
diff --git a/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.mm b/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.mm index b15dd770..71e5924 100644 --- a/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.mm +++ b/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.mm
@@ -215,11 +215,6 @@ void AutocompleteProviderClientImpl::PrefetchImage(const GURL& url) {} -void AutocompleteProviderClientImpl::OnAutocompleteControllerResultReady( - AutocompleteController* controller) { - // iOS currently has no client for this event. -} - bool AutocompleteProviderClientImpl::IsTabOpenWithURL( const GURL& url, const AutocompleteInput* input) {
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index 0a28e63..d1568b95 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -392,6 +392,10 @@ flag_descriptions::kClosingLastIncognitoTabName, flag_descriptions::kClosingLastIncognitoTabDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(kClosingLastIncognitoTab)}, + {"omnibox-on-device-head-suggestions", + flag_descriptions::kOmniboxOnDeviceHeadSuggestionsName, + flag_descriptions::kOmniboxOnDeviceHeadSuggestionsDescription, + flags_ui::kOsIos, FEATURE_VALUE_TYPE(omnibox::kOnDeviceHeadProvider)}, {"omnibox-ui-max-autocomplete-matches", flag_descriptions::kOmniboxUIMaxAutocompleteMatchesName, flag_descriptions::kOmniboxUIMaxAutocompleteMatchesDescription,
diff --git a/ios/chrome/browser/infobars/BUILD.gn b/ios/chrome/browser/infobars/BUILD.gn index 78fd90d..67937969 100644 --- a/ios/chrome/browser/infobars/BUILD.gn +++ b/ios/chrome/browser/infobars/BUILD.gn
@@ -37,6 +37,8 @@ source_set("badge") { configs += [ "//build/config/compiler:enable_arc" ] sources = [ + "infobar_badge_model.h", + "infobar_badge_model.mm", "infobar_badge_tab_helper.h", "infobar_badge_tab_helper.mm", "infobar_badge_tab_helper_delegate.h", @@ -44,6 +46,7 @@ deps = [ ":infobars", ":public", + "//ios/chrome/browser/ui/badges:public", "//ios/chrome/browser/ui/infobars:feature_flags", "//ios/chrome/browser/ui/infobars:infobars_ui", "//ios/web",
diff --git a/ios/chrome/browser/infobars/infobar_badge_model.h b/ios/chrome/browser/infobars/infobar_badge_model.h new file mode 100644 index 0000000..8e26d74b --- /dev/null +++ b/ios/chrome/browser/infobars/infobar_badge_model.h
@@ -0,0 +1,22 @@ +// 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_INFOBARS_INFOBAR_BADGE_MODEL_H_ +#define IOS_CHROME_BROWSER_INFOBARS_INFOBAR_BADGE_MODEL_H_ + +#import <UIKit/UIKit.h> + +#import "ios/chrome/browser/infobars/infobar_type.h" +#import "ios/chrome/browser/ui/badges/badge_item.h" + +// A model object that represents a badge for an Infobar. +@interface InfobarBadgeModel : NSObject <BadgeItem> + +- (instancetype)initWithInfobarType:(InfobarType)type + accepted:(BOOL)accepted NS_DESIGNATED_INITIALIZER; +- (instancetype)init NS_UNAVAILABLE; + +@end + +#endif // IOS_CHROME_BROWSER_INFOBARS_INFOBAR_BADGE_MODEL_H_
diff --git a/ios/chrome/browser/infobars/infobar_badge_model.mm b/ios/chrome/browser/infobars/infobar_badge_model.mm new file mode 100644 index 0000000..27543c6 --- /dev/null +++ b/ios/chrome/browser/infobars/infobar_badge_model.mm
@@ -0,0 +1,47 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/infobars/infobar_badge_model.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@interface InfobarBadgeModel () + +// The type of Infobar associated with this badge. +@property(nonatomic, assign) InfobarType infobarType; + +@end + +@implementation InfobarBadgeModel +// Synthesized from protocol. +@synthesize tappable = _tappable; +// Synthesized from protocol. +@synthesize accepted = _accepted; + +- (instancetype)initWithInfobarType:(InfobarType)type accepted:(BOOL)accepted { + self = [super init]; + if (self) { + _tappable = YES; + _infobarType = type; + _accepted = accepted; + } + return self; +} + +#pragma mark - BadgeViewModel + +- (BadgeType)badgeType { + switch (self.infobarType) { + case InfobarType::kInfobarTypeConfirm: + return BadgeType::kBadgeTypeConfirm; + case InfobarType::kInfobarTypePasswordSave: + return BadgeType::kBadgeTypePasswordSave; + case InfobarType::kInfobarTypePasswordUpdate: + return BadgeType::kBadgeTypePasswordUpdate; + } +} + +@end
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/ios_chrome_flag_descriptions.cc index 260c52c..526c6f8 100644 --- a/ios/chrome/browser/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/ios_chrome_flag_descriptions.cc
@@ -336,6 +336,12 @@ const char kOmniboxUseDefaultSearchEngineFaviconDescription[] = "Shows default search engine favicon in the omnibox"; +const char kOmniboxOnDeviceHeadSuggestionsName[] = + "Omnibox on device head suggestions"; +const char kOmniboxOnDeviceHeadSuggestionsDescription[] = + "Shows Google head non personalized search suggestions provided by a " + "compact on device model"; + const char kOnlyNewPasswordFormParsingName[] = "Use only new password form parsing"; const char kOnlyNewPasswordFormParsingDescription[] =
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.h b/ios/chrome/browser/ios_chrome_flag_descriptions.h index b3ecf83..b675513 100644 --- a/ios/chrome/browser/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/ios_chrome_flag_descriptions.h
@@ -281,6 +281,11 @@ extern const char kOmniboxUseDefaultSearchEngineFaviconName[]; extern const char kOmniboxUseDefaultSearchEngineFaviconDescription[]; +// Title and description for the flag to enable Omnibox On Device Head +// suggestions. +extern const char kOmniboxOnDeviceHeadSuggestionsName[]; +extern const char kOmniboxOnDeviceHeadSuggestionsDescription[]; + // Title and description for the flag to enable using only new password form // parsing. extern const char kOnlyNewPasswordFormParsingName[];
diff --git a/ios/chrome/browser/metrics/new_tab_page_uma.mm b/ios/chrome/browser/metrics/new_tab_page_uma.mm index ff0121ba..0f24afb 100644 --- a/ios/chrome/browser/metrics/new_tab_page_uma.mm +++ b/ios/chrome/browser/metrics/new_tab_page_uma.mm
@@ -8,9 +8,9 @@ #include "components/google/core/common/google_util.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/chrome_url_constants.h" -#import "ios/chrome/browser/tabs/tab.h" #import "ios/chrome/browser/tabs/tab_model.h" #import "ios/chrome/browser/tabs/tab_model_list.h" +#import "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/web/public/web_state/web_state.h" #include "url/gurl.h" @@ -21,10 +21,12 @@ namespace new_tab_page_uma { bool IsCurrentlyOnNTP(ios::ChromeBrowserState* browser_state) { - TabModel* tab_model = - TabModelList::GetLastActiveTabModelForChromeBrowserState(browser_state); - return tab_model.currentTab.webState && - tab_model.currentTab.webState->GetVisibleURL() == kChromeUINewTabURL; + WebStateList* webStateList = + TabModelList::GetLastActiveTabModelForChromeBrowserState(browser_state) + .webStateList; + return webStateList->GetActiveWebState() && + webStateList->GetActiveWebState()->GetVisibleURL() == + kChromeUINewTabURL; } void RecordAction(ios::ChromeBrowserState* browserState, ActionType type) {
diff --git a/ios/chrome/browser/send_tab_to_self/ios_send_tab_to_self_infobar_delegate.cc b/ios/chrome/browser/send_tab_to_self/ios_send_tab_to_self_infobar_delegate.cc index 744f4e37..6bf918b3b 100644 --- a/ios/chrome/browser/send_tab_to_self/ios_send_tab_to_self_infobar_delegate.cc +++ b/ios/chrome/browser/send_tab_to_self/ios_send_tab_to_self_infobar_delegate.cc
@@ -10,6 +10,7 @@ #include "components/infobars/core/infobar.h" #include "components/send_tab_to_self/send_tab_to_self_entry.h" #include "components/send_tab_to_self/send_tab_to_self_metrics.h" +#include "components/send_tab_to_self/send_tab_to_self_model.h" #include "ios/chrome/grit/ios_theme_resources.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/window_open_disposition.h" @@ -19,16 +20,19 @@ // static std::unique_ptr<IOSSendTabToSelfInfoBarDelegate> -IOSSendTabToSelfInfoBarDelegate::Create(const SendTabToSelfEntry* entry) { - return base::WrapUnique(new IOSSendTabToSelfInfoBarDelegate(entry)); +IOSSendTabToSelfInfoBarDelegate::Create(const SendTabToSelfEntry* entry, + SendTabToSelfModel* model) { + return std::make_unique<IOSSendTabToSelfInfoBarDelegate>(entry, model); } IOSSendTabToSelfInfoBarDelegate::~IOSSendTabToSelfInfoBarDelegate() {} IOSSendTabToSelfInfoBarDelegate::IOSSendTabToSelfInfoBarDelegate( - const SendTabToSelfEntry* entry) { + const SendTabToSelfEntry* entry, + SendTabToSelfModel* model) + : entry_(entry), model_(model) { DCHECK(entry); - entry_ = entry; + DCHECK(model); RecordNotificationHistogram(SendTabToSelfNotification::kShown); } @@ -59,6 +63,7 @@ } bool IOSSendTabToSelfInfoBarDelegate::Accept() { + model_->MarkEntryOpened(entry_->GetGUID()); RecordNotificationHistogram(SendTabToSelfNotification::kOpened); infobar()->owner()->OpenURL(entry_->GetURL(), WindowOpenDisposition::CURRENT_TAB); @@ -66,6 +71,7 @@ } bool IOSSendTabToSelfInfoBarDelegate::Cancel() { + model_->DismissEntry(entry_->GetGUID()); RecordNotificationHistogram(SendTabToSelfNotification::kDismissed); return true; }
diff --git a/ios/chrome/browser/send_tab_to_self/ios_send_tab_to_self_infobar_delegate.h b/ios/chrome/browser/send_tab_to_self/ios_send_tab_to_self_infobar_delegate.h index f4a32b8..d4d3045 100644 --- a/ios/chrome/browser/send_tab_to_self/ios_send_tab_to_self_infobar_delegate.h +++ b/ios/chrome/browser/send_tab_to_self/ios_send_tab_to_self_infobar_delegate.h
@@ -15,16 +15,19 @@ namespace send_tab_to_self { class SendTabToSelfEntry; +class SendTabToSelfModel; class IOSSendTabToSelfInfoBarDelegate : public ConfirmInfoBarDelegate { public: static std::unique_ptr<IOSSendTabToSelfInfoBarDelegate> Create( - const SendTabToSelfEntry* entry); + const SendTabToSelfEntry* entry, + SendTabToSelfModel* model); + explicit IOSSendTabToSelfInfoBarDelegate(const SendTabToSelfEntry* entry, + SendTabToSelfModel* model); ~IOSSendTabToSelfInfoBarDelegate() override; private: - IOSSendTabToSelfInfoBarDelegate(const SendTabToSelfEntry* entry); // ConfirmInfoBarDelegate: infobars::InfoBarDelegate::InfoBarIdentifier GetIdentifier() const override; @@ -39,6 +42,9 @@ // The entry that was share to this device. Must outlive this instance. const SendTabToSelfEntry* entry_ = nullptr; + // The SendTabToSelfModel that holds the |entry_|. Must outlive this instance. + SendTabToSelfModel* model_ = nullptr; + DISALLOW_COPY_AND_ASSIGN(IOSSendTabToSelfInfoBarDelegate); };
diff --git a/ios/chrome/browser/send_tab_to_self/send_tab_to_self_client_service_ios.h b/ios/chrome/browser/send_tab_to_self/send_tab_to_self_client_service_ios.h index ba386076..1a59d5d 100644 --- a/ios/chrome/browser/send_tab_to_self/send_tab_to_self_client_service_ios.h +++ b/ios/chrome/browser/send_tab_to_self/send_tab_to_self_client_service_ios.h
@@ -10,7 +10,6 @@ #include "base/macros.h" #include "components/keyed_service/core/keyed_service.h" -#include "components/send_tab_to_self/send_tab_to_self_model.h" #include "components/send_tab_to_self/send_tab_to_self_model_observer.h" #import "ios/chrome/browser/web_state_list/web_state_list_observer.h" #import "ios/web/public/web_state/web_state_observer.h"
diff --git a/ios/chrome/browser/send_tab_to_self/send_tab_to_self_client_service_ios.mm b/ios/chrome/browser/send_tab_to_self/send_tab_to_self_client_service_ios.mm index c30858f..4505d5b59 100644 --- a/ios/chrome/browser/send_tab_to_self/send_tab_to_self_client_service_ios.mm +++ b/ios/chrome/browser/send_tab_to_self/send_tab_to_self_client_service_ios.mm
@@ -13,6 +13,7 @@ #include "base/logging.h" #include "components/infobars/core/infobar.h" #include "components/infobars/core/infobar_manager.h" +#include "components/send_tab_to_self/send_tab_to_self_model.h" #include "components/sync/driver/sync_driver_switches.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/infobars/infobar.h" @@ -166,8 +167,8 @@ return; } - infobar_manager->AddInfoBar( - CreateConfirmInfoBar(IOSSendTabToSelfInfoBarDelegate::Create(entry))); + infobar_manager->AddInfoBar(CreateConfirmInfoBar( + IOSSendTabToSelfInfoBarDelegate::Create(entry, model_))); } void SendTabToSelfClientServiceIOS::CleanUpObserversAndVariables() {
diff --git a/ios/chrome/browser/signin/device_accounts_provider_impl.h b/ios/chrome/browser/signin/device_accounts_provider_impl.h index e270a2c0..ce89364 100644 --- a/ios/chrome/browser/signin/device_accounts_provider_impl.h +++ b/ios/chrome/browser/signin/device_accounts_provider_impl.h
@@ -21,7 +21,7 @@ void GetAccessToken(const std::string& gaia_id, const std::string& client_id, const std::set<std::string>& scopes, - const AccessTokenCallback& callback) override; + AccessTokenCallback callback) override; std::vector<AccountInfo> GetAllAccounts() const override; AuthenticationErrorCategory GetAuthenticationErrorCategory( const std::string& gaia_id,
diff --git a/ios/chrome/browser/signin/device_accounts_provider_impl.mm b/ios/chrome/browser/signin/device_accounts_provider_impl.mm index 958072a..e16dfda 100644 --- a/ios/chrome/browser/signin/device_accounts_provider_impl.mm +++ b/ios/chrome/browser/signin/device_accounts_provider_impl.mm
@@ -38,15 +38,20 @@ const std::string& gaia_id, const std::string& client_id, const std::set<std::string>& scopes, - const AccessTokenCallback& callback) { - AccessTokenCallback scoped_callback = callback; + AccessTokenCallback callback) { + DCHECK(!callback.is_null()); ios::ChromeIdentityService* identity_service = ios::GetChromeBrowserProvider()->GetChromeIdentityService(); + + // AccessTokenCallback is non-copyable. Using __block allocates the memory + // directly in the block object at compilation time (instead of doing a + // copy). This is required to have correct interaction between move-only + // types and Objective-C blocks. + __block AccessTokenCallback scopedCallback = std::move(callback); identity_service->GetAccessToken( identity_service->GetIdentityWithGaiaID(gaia_id), client_id, scopes, ^(NSString* token, NSDate* expiration, NSError* error) { - if (!scoped_callback.is_null()) - scoped_callback.Run(token, expiration, error); + std::move(scopedCallback).Run(token, expiration, error); }); }
diff --git a/ios/chrome/browser/tabs/tab_model.mm b/ios/chrome/browser/tabs/tab_model.mm index 2d168a2..37ed359 100644 --- a/ios/chrome/browser/tabs/tab_model.mm +++ b/ios/chrome/browser/tabs/tab_model.mm
@@ -306,6 +306,7 @@ } - (WebStateList*)webStateList { + DCHECK(_webStateList); return _webStateList.get(); }
diff --git a/ios/chrome/browser/translate/translate_egtest.mm b/ios/chrome/browser/translate/translate_egtest.mm index 5e3c091..e5ac48a 100644 --- a/ios/chrome/browser/translate/translate_egtest.mm +++ b/ios/chrome/browser/translate/translate_egtest.mm
@@ -1102,15 +1102,8 @@ performAction:grey_tap()]; // Make sure the "Always Translate French" entry is now selected and tap it. - id<GREYMatcher> selectedMatcher = ElementIsSelected(YES); - if (@available(iOS 13, *)) { - // TODO(crbug.com/979079): "Always Translate French" is actually invisible - // due to a real bug in the options menu. Remove the line below when the bug - // is fixed. - selectedMatcher = grey_accessibilityTrait(UIAccessibilityTraitSelected); - } [[[EarlGrey selectElementWithMatcher:AlwaysTranslate(@"French")] - assertWithMatcher:selectedMatcher] performAction:grey_tap()]; + assertWithMatcher:ElementIsSelected(YES)] performAction:grey_tap()]; // Make sure that French to English translation is no longer whitelisted. GREYAssert(!translatePrefs->IsLanguagePairWhitelisted("fr", "en"),
diff --git a/ios/chrome/browser/ui/activity_services/BUILD.gn b/ios/chrome/browser/ui/activity_services/BUILD.gn index cd31a20..4009ba1a 100644 --- a/ios/chrome/browser/ui/activity_services/BUILD.gn +++ b/ios/chrome/browser/ui/activity_services/BUILD.gn
@@ -73,6 +73,7 @@ "//ios/chrome/browser/ui/activity_services/requirements", "//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/coordinators:chrome_coordinators", + "//ios/chrome/browser/web_state_list", "//url", ] }
diff --git a/ios/chrome/browser/ui/activity_services/activity_service_legacy_coordinator.mm b/ios/chrome/browser/ui/activity_services/activity_service_legacy_coordinator.mm index 35bd049a..35fa6ee3 100644 --- a/ios/chrome/browser/ui/activity_services/activity_service_legacy_coordinator.mm +++ b/ios/chrome/browser/ui/activity_services/activity_service_legacy_coordinator.mm
@@ -8,7 +8,6 @@ #include "base/time/time.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/passwords/password_tab_helper.h" -#import "ios/chrome/browser/tabs/tab.h" #import "ios/chrome/browser/tabs/tab_model.h" #import "ios/chrome/browser/ui/activity_services/activity_service_controller.h" #import "ios/chrome/browser/ui/activity_services/canonical_url_retriever.h" @@ -20,6 +19,7 @@ #import "ios/chrome/browser/ui/activity_services/share_to_data_builder.h" #import "ios/chrome/browser/ui/commands/activity_service_commands.h" #import "ios/chrome/browser/ui/commands/command_dispatcher.h" +#import "ios/chrome/browser/web_state_list/web_state_list.h" #include "url/gurl.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -86,7 +86,7 @@ self.sharePageStartTime = base::TimeTicks::Now(); __weak ActivityServiceLegacyCoordinator* weakSelf = self; activity_services::RetrieveCanonicalUrl( - self.tabModel.currentTab.webState, ^(const GURL& url) { + self.tabModel.webStateList->GetActiveWebState(), ^(const GURL& url) { [weakSelf sharePageWithCanonicalURL:url]; }); } @@ -94,7 +94,7 @@ #pragma mark - Providers - (id<PasswordFormFiller>)currentPasswordFormFiller { - web::WebState* webState = self.tabModel.currentTab.webState; + web::WebState* webState = self.tabModel.webStateList->GetActiveWebState(); return webState ? PasswordTabHelper::FromWebState(webState) ->GetPasswordFormFiller() : nil;
diff --git a/ios/chrome/browser/ui/badges/BUILD.gn b/ios/chrome/browser/ui/badges/BUILD.gn new file mode 100644 index 0000000..18e1d67 --- /dev/null +++ b/ios/chrome/browser/ui/badges/BUILD.gn
@@ -0,0 +1,11 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("public") { + configs += [ "//build/config/compiler:enable_arc" ] + sources = [ + "badge_item.h", + "badge_type.h", + ] +}
diff --git a/ios/chrome/browser/ui/badges/badge_item.h b/ios/chrome/browser/ui/badges/badge_item.h new file mode 100644 index 0000000..4c44e420 --- /dev/null +++ b/ios/chrome/browser/ui/badges/badge_item.h
@@ -0,0 +1,24 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_BADGES_BADGE_ITEM_H_ +#define IOS_CHROME_BROWSER_UI_BADGES_BADGE_ITEM_H_ + +#import <UIKit/UIKit.h> + +#import "ios/chrome/browser/ui/badges/badge_type.h" + +// Holds properties and values the UI needs to configure a badge button. +@protocol BadgeItem + +// The type of the badge. +- (BadgeType)badgeType; +// Some badges may not be tappable if there is no action associated with it. +@property(nonatomic, assign, readonly, getter=isTappable) BOOL tappable; +// Whether this badge is in an accepted state. +@property(nonatomic, assign, readonly, getter=isAccepted) BOOL accepted; + +@end + +#endif // IOS_CHROME_BROWSER_UI_BADGES_BADGE_ITEM_H_
diff --git a/ios/chrome/browser/ui/badges/badge_type.h b/ios/chrome/browser/ui/badges/badge_type.h new file mode 100644 index 0000000..c36b97e --- /dev/null +++ b/ios/chrome/browser/ui/badges/badge_type.h
@@ -0,0 +1,18 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_BADGES_BADGE_TYPE_H_ +#define IOS_CHROME_BROWSER_UI_BADGES_BADGE_TYPE_H_ + +// Badge types. +enum class BadgeType { + // Badge type for the confirm Infobar. + kBadgeTypeConfirm = 0, + // Badge type for the Save Passwords Infobar. + kBadgeTypePasswordSave = 1, + // Badge type for the Update Passwords Infobar. + kBadgeTypePasswordUpdate = 2, +}; + +#endif // IOS_CHROME_BROWSER_UI_BADGES_BADGE_TYPE_H_
diff --git a/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm b/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm index 4aaaadf..e55abfd 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm
@@ -2016,12 +2016,6 @@ // Verify Copy URL functionality on single URL selection. - (void)testCopyFunctionalityOnSingleURL { - // TODO(crbug.com/979402): Disabled on iOS13 since copy/paste is not working - // in the Simulator. - if (@available(iOS 13.0, *)) { - EARL_GREY_TEST_DISABLED(@"Disabled on iOS 13"); - } - [BookmarksTestCase setupStandardBookmarks]; [BookmarksTestCase openBookmarks]; [BookmarksTestCase openMobileBookmarks];
diff --git a/ios/chrome/browser/ui/first_run/BUILD.gn b/ios/chrome/browser/ui/first_run/BUILD.gn index e91f47e..791019e 100644 --- a/ios/chrome/browser/ui/first_run/BUILD.gn +++ b/ios/chrome/browser/ui/first_run/BUILD.gn
@@ -46,6 +46,7 @@ "//ios/chrome/browser/ui/settings/utils", "//ios/chrome/browser/ui/util", "//ios/chrome/browser/ui/util:terms_util", + "//ios/chrome/browser/web_state_list", "//ios/chrome/common", "//ios/public/provider/chrome/browser", "//ios/public/provider/chrome/browser/signin",
diff --git a/ios/chrome/browser/ui/first_run/first_run_chrome_signin_view_controller.mm b/ios/chrome/browser/ui/first_run/first_run_chrome_signin_view_controller.mm index 266014eb..87f0f6b 100644 --- a/ios/chrome/browser/ui/first_run/first_run_chrome_signin_view_controller.mm +++ b/ios/chrome/browser/ui/first_run/first_run_chrome_signin_view_controller.mm
@@ -16,11 +16,14 @@ #import "ios/chrome/browser/ui/first_run/first_run_util.h" #import "ios/chrome/browser/ui/promos/signin_promo_view_controller.h" #include "ios/chrome/browser/ui/util/ui_util.h" +#import "ios/chrome/browser/web_state_list/web_state_list.h" #include "ios/chrome/grit/ios_strings.h" #import "ios/public/provider/chrome/browser/chrome_browser_provider.h" #import "ios/public/provider/chrome/browser/signin/chrome_identity.h" #import "ios/public/provider/chrome/browser/signin/chrome_identity_service.h" #import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h" +#import "ios/web/public/web_state/web_state.h" + #import "ui/base/l10n/l10n_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -109,7 +112,8 @@ - (void)finishFirstRunAndDismissWithCompletion:(ProceduralBlock)completion { DCHECK(self.presentingViewController); - FinishFirstRun(self.browserState, [_tabModel currentTab], _firstRunConfig, + web::WebState* currentWebState = _tabModel.webStateList->GetActiveWebState(); + FinishFirstRun(self.browserState, currentWebState, _firstRunConfig, self.presenter); [self.presentingViewController dismissViewControllerAnimated:YES completion:^{
diff --git a/ios/chrome/browser/ui/first_run/first_run_util.h b/ios/chrome/browser/ui/first_run/first_run_util.h index 2f5b378..61ef002 100644 --- a/ios/chrome/browser/ui/first_run/first_run_util.h +++ b/ios/chrome/browser/ui/first_run/first_run_util.h
@@ -18,6 +18,9 @@ namespace ios { class ChromeBrowserState; } +namespace web { +class WebState; +} // Notification sent when the first run ends, right before dimissing the Terms // of Service modal view. @@ -45,7 +48,7 @@ // Methods for writing sentinel and recording metrics and posting notifications void FinishFirstRun(ios::ChromeBrowserState* browserState, - Tab* tab, + web::WebState* web_state, FirstRunConfiguration* config, id<SyncPresenter> presenter);
diff --git a/ios/chrome/browser/ui/first_run/first_run_util.mm b/ios/chrome/browser/ui/first_run/first_run_util.mm index 9f75f0a..06b053e5 100644 --- a/ios/chrome/browser/ui/first_run/first_run_util.mm +++ b/ios/chrome/browser/ui/first_run/first_run_util.mm
@@ -17,12 +17,12 @@ #import "ios/chrome/browser/first_run/first_run_configuration.h" #include "ios/chrome/browser/first_run/first_run_metrics.h" #include "ios/chrome/browser/signin/identity_manager_factory.h" -#include "ios/chrome/browser/tabs/tab.h" #include "ios/chrome/browser/ui/first_run/first_run_histograms.h" #import "ios/chrome/browser/ui/settings/sync/utils/sync_util.h" #import "ios/chrome/browser/ui/settings/utils/settings_utils.h" #include "ios/chrome/browser/ui/util/ui_util.h" #include "ios/web/public/thread/web_thread.h" +#import "ios/web/public/web_state/web_state.h" #include "services/identity/public/cpp/identity_manager.h" #import "ui/gfx/ios/NSString+CrStringDrawing.h" @@ -153,7 +153,7 @@ } void FinishFirstRun(ios::ChromeBrowserState* browserState, - Tab* tab, + web::WebState* web_state, FirstRunConfiguration* config, id<SyncPresenter> presenter) { [[NSNotificationCenter defaultCenter] @@ -163,7 +163,7 @@ config.hasSSOAccount); // Display the sync errors infobar. - DisplaySyncErrors(browserState, tab.webState, presenter); + DisplaySyncErrors(browserState, web_state, presenter); } void RecordProductTourTimingMetrics(NSString* timer_name,
diff --git a/ios/chrome/browser/ui/history/history_ui_egtest.mm b/ios/chrome/browser/ui/history/history_ui_egtest.mm index 25d47c9..1d5e421 100644 --- a/ios/chrome/browser/ui/history/history_ui_egtest.mm +++ b/ios/chrome/browser/ui/history/history_ui_egtest.mm
@@ -379,12 +379,6 @@ // Tests display and selection of 'Copy URL' in a context menu on a history // entry. - (void)testContextMenuCopy { - // TODO(crbug.com/979728): Disabled on iOS13 since copy/paste is not working - // in the Simulator. - if (@available(iOS 13.0, *)) { - EARL_GREY_TEST_DISABLED(@"Disabled on iOS 13"); - } - ProceduralBlock clearPasteboard = ^{ [[UIPasteboard generalPasteboard] setURLs:nil]; };
diff --git a/ios/chrome/browser/ui/page_info/page_info_legacy_coordinator.mm b/ios/chrome/browser/ui/page_info/page_info_legacy_coordinator.mm index 146d1a06..96b603e 100644 --- a/ios/chrome/browser/ui/page_info/page_info_legacy_coordinator.mm +++ b/ios/chrome/browser/ui/page_info/page_info_legacy_coordinator.mm
@@ -13,7 +13,6 @@ #include "ios/chrome/browser/reading_list/features.h" #import "ios/chrome/browser/reading_list/offline_page_tab_helper.h" #include "ios/chrome/browser/reading_list/offline_url_utils.h" -#import "ios/chrome/browser/tabs/tab.h" #import "ios/chrome/browser/tabs/tab_model.h" #import "ios/chrome/browser/ui/commands/command_dispatcher.h" #import "ios/chrome/browser/ui/commands/open_new_tab_command.h" @@ -165,7 +164,7 @@ #pragma mark - PageInfoReloading - (void)reload { - web::WebState* webState = self.tabModel.currentTab.webState; + web::WebState* webState = self.tabModel.webStateList->GetActiveWebState(); if (webState) { // |check_for_repost| is true because the reload is explicitly initiated // by the user.
diff --git a/ios/chrome/browser/ui/payments/payment_request_journey_logger_egtest.mm b/ios/chrome/browser/ui/payments/payment_request_journey_logger_egtest.mm index 8007042..1bc73668 100644 --- a/ios/chrome/browser/ui/payments/payment_request_journey_logger_egtest.mm +++ b/ios/chrome/browser/ui/payments/payment_request_journey_logger_egtest.mm
@@ -750,7 +750,8 @@ GREYAssertEqual(JourneyLogger::EVENT_USER_ABORTED | JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE | JourneyLogger::EVENT_REQUEST_METHOD_OTHER | - JourneyLogger::EVENT_REQUEST_METHOD_BASIC_CARD, + JourneyLogger::EVENT_REQUEST_METHOD_BASIC_CARD | + JourneyLogger::EVENT_NEEDS_COMPLETION_PAYMENT, buckets[0].min, @""); // Make sure that the metrics that required the Payment Request to be shown
diff --git a/ios/chrome/browser/ui/settings/cells/settings_switch_cell.mm b/ios/chrome/browser/ui/settings/cells/settings_switch_cell.mm index 197aac2..d467398 100644 --- a/ios/chrome/browser/ui/settings/cells/settings_switch_cell.mm +++ b/ios/chrome/browser/ui/settings/cells/settings_switch_cell.mm
@@ -253,4 +253,12 @@ } } +- (UIAccessibilityTraits)accessibilityTraits { + UIAccessibilityTraits accessibilityTraits = super.accessibilityTraits; + if (!self.switchView.isEnabled) { + accessibilityTraits |= UIAccessibilityTraitNotEnabled; + } + return accessibilityTraits; +} + @end
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_image_item.mm b/ios/chrome/browser/ui/table_view/cells/table_view_image_item.mm index da6b41c..cb9a5d6 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_image_item.mm +++ b/ios/chrome/browser/ui/table_view/cells/table_view_image_item.mm
@@ -192,4 +192,12 @@ return self.textLabel.text; } +- (UIAccessibilityTraits)accessibilityTraits { + UIAccessibilityTraits accessibilityTraits = super.accessibilityTraits; + if (!self.isUserInteractionEnabled) { + accessibilityTraits |= UIAccessibilityTraitNotEnabled; + } + return accessibilityTraits; +} + @end
diff --git a/ios/chrome/browser/ui/translate/cells/translate_popup_menu_item.h b/ios/chrome/browser/ui/translate/cells/translate_popup_menu_item.h index a8e1825..9fd3dac7 100644 --- a/ios/chrome/browser/ui/translate/cells/translate_popup_menu_item.h +++ b/ios/chrome/browser/ui/translate/cells/translate_popup_menu_item.h
@@ -26,6 +26,9 @@ - (void)setTitle:(NSString*)title; +// Whether the cell will display a trailing checkmark or not. +- (void)setCheckmark:(BOOL)checkmark; + // After this is called, the cell is listening for the // UIContentSizeCategoryDidChangeNotification notification and updates its font // size to the new category.
diff --git a/ios/chrome/browser/ui/translate/cells/translate_popup_menu_item.mm b/ios/chrome/browser/ui/translate/cells/translate_popup_menu_item.mm index 1535287..b083def 100644 --- a/ios/chrome/browser/ui/translate/cells/translate_popup_menu_item.mm +++ b/ios/chrome/browser/ui/translate/cells/translate_popup_menu_item.mm
@@ -38,7 +38,7 @@ withStyler:(ChromeTableViewStyler*)styler { [super configureCell:cell withStyler:styler]; cell.accessibilityTraits = UIAccessibilityTraitButton; - cell.selected = self.isSelected; + [cell setCheckmark:self.selected]; [cell setTitle:self.title]; } @@ -136,10 +136,8 @@ self.titleLabel.text = title; } -- (void)setSelected:(BOOL)selected { - [super setSelected:selected]; - - if (selected) { +- (void)setCheckmark:(BOOL)checkmark { + if (checkmark) { self.checkmarkView.hidden = NO; self.accessibilityTraits |= UIAccessibilityTraitSelected; }
diff --git a/ios/chrome/browser/ui/util/CRUILabel+AttributeUtils.h b/ios/chrome/browser/ui/util/CRUILabel+AttributeUtils.h index 97f4b9b..2e1a95d 100644 --- a/ios/chrome/browser/ui/util/CRUILabel+AttributeUtils.h +++ b/ios/chrome/browser/ui/util/CRUILabel+AttributeUtils.h
@@ -8,9 +8,16 @@ #import <UIKit/UIKit.h> @interface UILabel (CRUILabelAttributeUtils) -// The height of the label. +// The line height for the text in the receiver. // Make sure to create a LabelObserver for this label and start observing before -// setting this property. +// setting this property. When the last LabelObserver is removed for a label +// where this property is set, there is no expected behavior for the line +// height on further text changes -- it may be retained or overwritten. +// +// TODO(crbug.com/980510) : When iOS12 support is removed, determine if this +// property is still needed, or if (under iOS13+) setting the line height +// in a paragraph style persits across label frame changes. +// @property(nonatomic, assign, setter=cr_setLineHeight:) CGFloat cr_lineHeight; @end
diff --git a/ios/chrome/browser/ui/util/CRUILabel+AttributeUtils_unittest.mm b/ios/chrome/browser/ui/util/CRUILabel+AttributeUtils_unittest.mm index f6edb9b6..0d436bf 100644 --- a/ios/chrome/browser/ui/util/CRUILabel+AttributeUtils_unittest.mm +++ b/ios/chrome/browser/ui/util/CRUILabel+AttributeUtils_unittest.mm
@@ -45,6 +45,15 @@ UILabel* label = _scopedLabel; label.text = @"sample text"; + NSMutableAttributedString* textWithLineHeight = + [[NSMutableAttributedString alloc] + initWithString:@"attributed sample text"]; + NSMutableParagraphStyle* style = [[NSMutableParagraphStyle alloc] init]; + style.maximumLineHeight = 15.0; + [textWithLineHeight addAttribute:NSParagraphStyleAttributeName + value:style + range:NSMakeRange(0, [textWithLineHeight length])]; + // Add a second observer. LabelObserver* secondObserver = [LabelObserver observerForLabel:label]; [secondObserver startObserving]; @@ -62,8 +71,8 @@ // Once both are stopped, the height isn't persisted when the text changes. [_observer stopObserving]; label.cr_lineHeight = 25.0; - label.text = @"longer sample text"; - CheckLabelLineHeight(0); + label.attributedText = textWithLineHeight; + CheckLabelLineHeight(15.0); } TEST_F(UILabelAttributeUtilsTest, SettingTests) { @@ -80,18 +89,19 @@ NSMutableAttributedString* string = [[NSMutableAttributedString alloc] initWithString:@"attributed sample text"]; - label.attributedText = string; + label.attributedText = [string copy]; CheckLabelLineHeight(20.0); [string addAttribute:NSForegroundColorAttributeName value:[UIColor brownColor] range:NSMakeRange(0, [string length])]; - label.attributedText = string; + label.attributedText = [string copy]; CheckLabelLineHeight(20.0); NSMutableParagraphStyle* style = [[NSMutableParagraphStyle alloc] init]; style.maximumLineHeight = 15.0; [string addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0, [string length])]; + label.attributedText = [string copy]; CheckLabelLineHeight(20.0); }
diff --git a/ios/chrome/browser/ui/util/label_observer.h b/ios/chrome/browser/ui/util/label_observer.h index 198c620..23ec5a1 100644 --- a/ios/chrome/browser/ui/util/label_observer.h +++ b/ios/chrome/browser/ui/util/label_observer.h
@@ -27,8 +27,10 @@ // should be called before |label| is deallocated. - (void)startObserving; -// Stops observing the label. The label stop being observed once the number of -// call to this function match the number of call to |-startObserving|. +// Stops observing the label. The label stops being observed once the number of +// call to this function match the number of call to |-startObserving|. When +// observation of a label ends, none of its attributes are changed, and none +// of the registered actions are called. - (void)stopObserving; // Block type that takes a label. Blocks registered for a label will be called
diff --git a/ios/chrome/browser/url_loading/app_url_loading_service.mm b/ios/chrome/browser/url_loading/app_url_loading_service.mm index cf9eb0e..936436c 100644 --- a/ios/chrome/browser/url_loading/app_url_loading_service.mm +++ b/ios/chrome/browser/url_loading/app_url_loading_service.mm
@@ -7,11 +7,12 @@ #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/main/browser.h" #import "ios/chrome/browser/snapshots/snapshot_tab_helper.h" -#import "ios/chrome/browser/tabs/tab.h" #import "ios/chrome/browser/tabs/tab_model.h" #import "ios/chrome/browser/url_loading/url_loading_params.h" #import "ios/chrome/browser/url_loading/url_loading_service.h" #import "ios/chrome/browser/url_loading/url_loading_service_factory.h" +#import "ios/chrome/browser/web_state_list/web_state_list.h" +#import "ios/web/public/web_state/web_state.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -56,9 +57,10 @@ params.in_incognito) { // Must take a snapshot of the tab before we switch the incognito mode // because the currentTab will change after the switch. - Tab* currentTab = [delegate_ currentTabModel].currentTab; - if (currentTab) { - SnapshotTabHelper::FromWebState(currentTab.webState) + web::WebState* currentWebState = + [delegate_ currentTabModel].webStateList->GetActiveWebState(); + if (currentWebState) { + SnapshotTabHelper::FromWebState(currentWebState) ->UpdateSnapshotWithCallback(nil); }
diff --git a/ios/chrome/browser/web/forms_egtest.mm b/ios/chrome/browser/web/forms_egtest.mm index a6f8a6f8..53e370e 100644 --- a/ios/chrome/browser/web/forms_egtest.mm +++ b/ios/chrome/browser/web/forms_egtest.mm
@@ -431,11 +431,7 @@ } // A new navigation dismisses the repost dialog. -// TODO(crbug.com/971670): Reenable for slim nav. - (void)testRepostFormDismissedByNewNavigation { - if (web::GetWebClient()->IsSlimNavigationManagerEnabled()) { - EARL_GREY_TEST_SKIPPED(@"Test not running with slim nav."); - } [self setUpFormTestSimpleHttpServer]; const GURL destinationURL = GetDestinationUrl(); @@ -455,21 +451,23 @@ [ChromeEarlGrey reload]; } - // When slim navigation manager is enabled, synchronization must be disabled - // until after the repost confirmation is dismissed because it is presented - // during the load. It is always disabled, but immediately re-enabled if - // slim navigation manger is not enabled. This is necessary in order to keep - // the correct scope of ScopedSynchronizationDisabler which ensures - // synchronization is not left disabled if the test fails. - std::unique_ptr<ScopedSynchronizationDisabler> disabler = - std::make_unique<ScopedSynchronizationDisabler>(); - if (![ChromeEarlGrey isSlimNavigationManagerEnabled]) { - disabler.reset(); - } + { + // When slim navigation manager is enabled, synchronization must be disabled + // until after the repost confirmation is dismissed because it is presented + // during the load. It is always disabled, but immediately re-enabled if + // slim navigation manger is not enabled. This is necessary in order to keep + // the correct scope of ScopedSynchronizationDisabler which ensures + // synchronization is not left disabled if the test fails. + std::unique_ptr<ScopedSynchronizationDisabler> disabler = + std::make_unique<ScopedSynchronizationDisabler>(); + if (![ChromeEarlGrey isSlimNavigationManagerEnabled]) { + disabler.reset(); + } - // Repost confirmation box should be visible. - [ChromeEarlGrey - waitForSufficientlyVisibleElementWithMatcher:ResendPostButtonMatcher()]; + // Repost confirmation box should be visible. + [ChromeEarlGrey + waitForSufficientlyVisibleElementWithMatcher:ResendPostButtonMatcher()]; + } // Starting a new navigation while the repost dialog is presented should not // crash.
diff --git a/ios/chrome/test/earl_grey/BUILD.gn b/ios/chrome/test/earl_grey/BUILD.gn index cf617cc..0fa3abd 100644 --- a/ios/chrome/test/earl_grey/BUILD.gn +++ b/ios/chrome/test/earl_grey/BUILD.gn
@@ -17,7 +17,6 @@ ":ios_chrome_reading_list_egtests", ":ios_chrome_settings_egtests", ":ios_chrome_smoke_egtests", - ":ios_chrome_tab_grid_egtests", ":ios_chrome_translate_egtests", ":ios_chrome_ui_egtests", ":ios_chrome_web_egtests", @@ -71,13 +70,6 @@ ] } -chrome_ios_eg_test("ios_chrome_tab_grid_egtests") { - deps = [ - ":test_support", - "//ios/chrome/browser/ui/tab_grid:eg_tests", - ] -} - chrome_ios_eg_test("ios_chrome_ui_egtests") { deps = [ "//ios/chrome/browser/ui/activity_services:eg_tests", @@ -106,6 +98,7 @@ "//ios/chrome/browser/ui/settings/sync/utils:eg_tests", "//ios/chrome/browser/ui/side_swipe:eg_tests", "//ios/chrome/browser/ui/signin_interaction:eg_tests", + "//ios/chrome/browser/ui/tab_grid:eg_tests", "//ios/chrome/browser/ui/tabs:eg_tests", "//ios/chrome/browser/ui/toolbar:eg_tests", "//ios/chrome/browser/ui/webui:eg_tests",
diff --git a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm index f7e648d..1a9405a2 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm +++ b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm
@@ -33,6 +33,7 @@ #import "ios/chrome/browser/ui/settings/sync/sync_settings_table_view_controller.h" #import "ios/chrome/browser/ui/static_content/static_html_view_controller.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_constants.h" +#import "ios/chrome/browser/ui/util/ui_util.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #include "ios/chrome/grit/ios_strings.h" #import "ios/chrome/test/app/chrome_test_util.h" @@ -296,6 +297,9 @@ } + (id<GREYMatcher>)showTabsButton { + if (IsIPadIdiom()) { + return grey_accessibilityID(@"Enter Tab Switcher"); + } return grey_allOf(grey_accessibilityID(kToolbarStackButtonIdentifier), grey_sufficientlyVisible(), nil); }
diff --git a/ios/web/navigation/crw_wk_navigation_handler.mm b/ios/web/navigation/crw_wk_navigation_handler.mm index 0fd83149..a4581854 100644 --- a/ios/web/navigation/crw_wk_navigation_handler.mm +++ b/ios/web/navigation/crw_wk_navigation_handler.mm
@@ -243,7 +243,9 @@ (action.navigationType == WKNavigationTypeFormResubmitted)) { self.webStateImpl->ShowRepostFormWarningDialog( base::BindOnce(^(bool shouldContinue) { - if (shouldContinue) { + if ([self.delegate navigationHandlerWebViewBeingDestroyed:self]) { + decisionHandler(WKNavigationActionPolicyCancel); + } else if (shouldContinue) { decisionHandler(WKNavigationActionPolicyAllow); } else { decisionHandler(WKNavigationActionPolicyCancel);
diff --git a/ios/web/web_state/js/find_in_page_js_unittest.mm b/ios/web/web_state/js/find_in_page_js_unittest.mm index 3ea5190..60a1963 100644 --- a/ios/web/web_state/js/find_in_page_js_unittest.mm +++ b/ios/web/web_state/js/find_in_page_js_unittest.mm
@@ -430,9 +430,9 @@ web_state()->GetWebViewProxy().scrollViewProxy.contentOffset.y; return top_scroll_after_select > 0; })); - // Scroll offset should be 1032.6667 for iPhoneX and 1033 for every - // other device. - EXPECT_NEAR(top_scroll_after_select, 1032.75, 0.5); + // Scroll offset should either be 1035.333 for most iPhone and 1035.5 for iPad + // and 5S. + EXPECT_NEAR(top_scroll_after_select, 1035, 0.5); } // Tests that FindInPage is able to clear CSS and match highlighting.
diff --git a/ios/web/web_state/js/resources/find_in_page.js b/ios/web/web_state/js/resources/find_in_page.js index 675a3ff5..f4302faa 100644 --- a/ios/web/web_state/js/resources/find_in_page.js +++ b/ios/web/web_state/js/resources/find_in_page.js
@@ -683,7 +683,7 @@ return; } - match.nodes[0].scrollIntoView(/*alignToTop=*/false); + match.nodes[0].scrollIntoView({block: "center", inline: "center"}); }; /**
diff --git a/ios/web_view/internal/signin/web_view_device_accounts_provider_impl.h b/ios/web_view/internal/signin/web_view_device_accounts_provider_impl.h index b996d88..8066be23 100644 --- a/ios/web_view/internal/signin/web_view_device_accounts_provider_impl.h +++ b/ios/web_view/internal/signin/web_view_device_accounts_provider_impl.h
@@ -25,7 +25,7 @@ void GetAccessToken(const std::string& gaia_id, const std::string& client_id, const std::set<std::string>& scopes, - const AccessTokenCallback& callback) override; + AccessTokenCallback callback) override; std::vector<AccountInfo> GetAllAccounts() const override; AuthenticationErrorCategory GetAuthenticationErrorCategory( const std::string& gaia_id,
diff --git a/ios/web_view/internal/signin/web_view_device_accounts_provider_impl.mm b/ios/web_view/internal/signin/web_view_device_accounts_provider_impl.mm index 52355a1..e611608 100644 --- a/ios/web_view/internal/signin/web_view_device_accounts_provider_impl.mm +++ b/ios/web_view/internal/signin/web_view_device_accounts_provider_impl.mm
@@ -25,12 +25,13 @@ const std::string& gaia_id, const std::string& client_id, const std::set<std::string>& scopes, - const AccessTokenCallback& callback) { + AccessTokenCallback callback) { // |sync_controller| may still be nil if this is called too early so // |callback| will not be invoked. That's OK because this will be called again // after |sync_controller| has been set. CWVSyncController* sync_controller = signin_client_->GetSyncController(); - [sync_controller fetchAccessTokenForScopes:scopes callback:callback]; + [sync_controller fetchAccessTokenForScopes:scopes + callback:std::move(callback)]; } std::vector<DeviceAccountsProvider::AccountInfo>
diff --git a/ios/web_view/internal/sync/cwv_sync_controller.mm b/ios/web_view/internal/sync/cwv_sync_controller.mm index 16e9824..75bb3090 100644 --- a/ios/web_view/internal/sync/cwv_sync_controller.mm +++ b/ios/web_view/internal/sync/cwv_sync_controller.mm
@@ -23,6 +23,8 @@ #error "This file requires ARC support." #endif +using AccessTokenCallback = DeviceAccountsProvider::AccessTokenCallback; + NSErrorDomain const CWVSyncErrorDomain = @"org.chromium.chromewebview.SyncErrorDomain"; @@ -203,23 +205,24 @@ #pragma mark - Internal Methods -- (void) - fetchAccessTokenForScopes:(const std::set<std::string>&)scopes - callback: - (const DeviceAccountsProvider::AccessTokenCallback&) - callback { +- (void)fetchAccessTokenForScopes:(const std::set<std::string>&)scopes + callback:(AccessTokenCallback)callback { + DCHECK(!callback.is_null()); NSMutableArray<NSString*>* scopesArray = [NSMutableArray array]; for (const auto& scope : scopes) { [scopesArray addObject:base::SysUTF8ToNSString(scope)]; } - DeviceAccountsProvider::AccessTokenCallback scopedCallback = callback; + + // AccessTokenCallback is non-copyable. Using __block allocates the memory + // directly in the block object at compilation time (instead of doing a + // copy). This is required to have correct interaction between move-only + // types and Objective-C blocks. + __block AccessTokenCallback scopedCallback = std::move(callback); [_dataSource syncController:self getAccessTokenForScopes:[scopesArray copy] completionHandler:^(NSString* accessToken, NSDate* expirationDate, NSError* error) { - if (!scopedCallback.is_null()) { - scopedCallback.Run(accessToken, expirationDate, error); - } + std::move(scopedCallback).Run(accessToken, expirationDate, error); }]; }
diff --git a/ios/web_view/internal/sync/cwv_sync_controller_internal.h b/ios/web_view/internal/sync/cwv_sync_controller_internal.h index c51f07b..e865deb 100644 --- a/ios/web_view/internal/sync/cwv_sync_controller_internal.h +++ b/ios/web_view/internal/sync/cwv_sync_controller_internal.h
@@ -35,11 +35,9 @@ // Called by WebViewDeviceAccountsProviderImpl to obtain // access tokens for |scopes| to be passed back in |callback|. -- (void) - fetchAccessTokenForScopes:(const std::set<std::string>&)scopes - callback: - (const DeviceAccountsProvider::AccessTokenCallback&) - callback; +- (void)fetchAccessTokenForScopes:(const std::set<std::string>&)scopes + callback:(DeviceAccountsProvider::AccessTokenCallback) + callback; // Called by IOSWebViewSigninClient when signing out. - (void)didSignoutWithSourceMetric:(signin_metrics::ProfileSignout)metric;
diff --git a/ios/web_view/internal/sync/cwv_sync_controller_unittest.mm b/ios/web_view/internal/sync/cwv_sync_controller_unittest.mm index 5ca956c..eeb9fe2 100644 --- a/ios/web_view/internal/sync/cwv_sync_controller_unittest.mm +++ b/ios/web_view/internal/sync/cwv_sync_controller_unittest.mm
@@ -125,8 +125,8 @@ [sync_controller_ startSyncWithIdentity:identity dataSource:data_source]; std::set<std::string> scopes = {kTestScope1, kTestScope2}; - DeviceAccountsProvider::AccessTokenCallback callback; - [sync_controller_ fetchAccessTokenForScopes:scopes callback:callback]; + [sync_controller_ fetchAccessTokenForScopes:scopes + callback:base::DoNothing()]; [data_source verify]; }
diff --git a/media/audio/android/opensles_output.cc b/media/audio/android/opensles_output.cc index 17554fa..594174c 100644 --- a/media/audio/android/opensles_output.cc +++ b/media/audio/android/opensles_output.cc
@@ -436,7 +436,9 @@ reinterpret_cast<int16_t*>(audio_data_[active_buffer_index_])); } else { DCHECK_EQ(sample_format_, kSampleFormatF32); - audio_bus_->ToInterleaved<Float32SampleTypeTraits>( + + // We skip clipping since that occurs at the shared memory boundary. + audio_bus_->ToInterleaved<Float32SampleTypeTraitsNoClip>( frames_filled, reinterpret_cast<float*>(audio_data_[active_buffer_index_])); }
diff --git a/media/audio/audio_sync_reader.cc b/media/audio/audio_sync_reader.cc index bba78e8..9cc45305 100644 --- a/media/audio/audio_sync_reader.cc +++ b/media/audio/audio_sync_reader.cc
@@ -235,8 +235,12 @@ } output_bus_->SetBitstreamDataSize(data_size); output_bus_->SetBitstreamFrames(bitstream_frames); + output_bus_->CopyTo(dest); + return; } - output_bus_->CopyTo(dest); + + // Copy and clip data coming across the shared memory since it's untrusted. + output_bus_->CopyAndClipTo(dest); } void AudioSyncReader::Close() {
diff --git a/media/audio/fuchsia/audio_output_stream_fuchsia.cc b/media/audio/fuchsia/audio_output_stream_fuchsia.cc index 4a79c4a0..cbcda51b 100644 --- a/media/audio/fuchsia/audio_output_stream_fuchsia.cc +++ b/media/audio/fuchsia/audio_output_stream_fuchsia.cc
@@ -221,7 +221,9 @@ // Save samples to the |payload_buffer_|. size_t packet_size = parameters_.GetBytesPerBuffer(kSampleFormatF32); DCHECK_LE(payload_buffer_pos_ + packet_size, payload_buffer_.size()); - audio_bus_->ToInterleaved<media::Float32SampleTypeTraits>( + + // We skip clipping since that occurs at the shared memory boundary. + audio_bus_->ToInterleaved<Float32SampleTypeTraitsNoClip>( audio_bus_->frames(), reinterpret_cast<float*>(static_cast<uint8_t*>(payload_buffer_.memory()) + payload_buffer_pos_));
diff --git a/media/audio/pulse/pulse_output.cc b/media/audio/pulse/pulse_output.cc index 6b03e08..6ee4d63 100644 --- a/media/audio/pulse/pulse_output.cc +++ b/media/audio/pulse/pulse_output.cc
@@ -164,7 +164,8 @@ frames_to_copy = std::min(audio_bus_->frames() - frame_offset_in_bus, frames_to_copy); - audio_bus_->ToInterleavedPartial<Float32SampleTypeTraits>( + // We skip clipping since that occurs at the shared memory boundary. + audio_bus_->ToInterleavedPartial<Float32SampleTypeTraitsNoClip>( frame_offset_in_bus, frames_to_copy, reinterpret_cast<float*>(pa_buffer)); frame_offset_in_bus += frames_to_copy;
diff --git a/media/audio/win/audio_low_latency_output_win.cc b/media/audio/win/audio_low_latency_output_win.cc index fbb3bf4..225682e 100644 --- a/media/audio/win/audio_low_latency_output_win.cc +++ b/media/audio/win/audio_low_latency_output_win.cc
@@ -599,7 +599,9 @@ DCHECK_LE(num_filled_bytes, packet_size_bytes_); audio_bus_->Scale(volume_); - audio_bus_->ToInterleaved<Float32SampleTypeTraits>( + + // We skip clipping since that occurs at the shared memory boundary. + audio_bus_->ToInterleaved<Float32SampleTypeTraitsNoClip>( frames_filled, reinterpret_cast<float*>(audio_data)); // Release the buffer space acquired in the GetBuffer() call.
diff --git a/media/base/audio_bus.cc b/media/base/audio_bus.cc index 12f2e7ae..991e73e1 100644 --- a/media/base/audio_bus.cc +++ b/media/base/audio_bus.cc
@@ -358,6 +358,18 @@ CopyPartialFramesTo(0, frames(), 0, dest); } +void AudioBus::CopyAndClipTo(AudioBus* dest) const { + DCHECK(!is_bitstream_format_); + CHECK_EQ(channels(), dest->channels()); + CHECK_LE(frames(), dest->frames()); + for (int i = 0; i < channels(); ++i) { + float* dest_ptr = dest->channel(i); + const float* source_ptr = channel(i); + for (int j = 0; j < frames(); ++j) + dest_ptr[j] = Float32SampleTypeTraits::FromFloat(source_ptr[j]); + } +} + void AudioBus::CopyPartialFramesTo(int source_start_frame, int frame_count, int dest_start_frame,
diff --git a/media/base/audio_bus.h b/media/base/audio_bus.h index e128f32..024fee8 100644 --- a/media/base/audio_bus.h +++ b/media/base/audio_bus.h
@@ -151,6 +151,9 @@ // AudioBus object must have the same frames() and channels(). void CopyTo(AudioBus* dest) const; + // Similar to above, but clips values to [-1, 1] during the copy process. + void CopyAndClipTo(AudioBus* dest) const; + // Helper method to copy frames from one AudioBus to another. Both AudioBus // objects must have the same number of channels(). |source_start_frame| is // the starting offset. |dest_start_frame| is the starting offset in |dest|.
diff --git a/media/base/audio_bus_perftest.cc b/media/base/audio_bus_perftest.cc index 2140a228..cf12edfc1 100644 --- a/media/base/audio_bus_perftest.cc +++ b/media/base/audio_bus_perftest.cc
@@ -18,7 +18,9 @@ static const int kSampleRate = 48000; template <typename T, class SampleTraits> -void RunInterleaveBench(AudioBus* bus, const std::string& trace_name) { +void RunInterleaveBench(AudioBus* bus, + const std::string& trace_name, + bool to_interleaved_only = false) { const int frame_size = bus->frames() * bus->channels(); std::unique_ptr<T[]> interleaved(new T[frame_size]); @@ -31,6 +33,9 @@ total_time_milliseconds / kBenchmarkIterations, "ms", true); + if (to_interleaved_only) + return; + start = base::TimeTicks::Now(); for (int i = 0; i < kBenchmarkIterations; ++i) bus->FromInterleaved<SampleTraits>(interleaved.get(), bus->frames()); @@ -52,4 +57,42 @@ RunInterleaveBench<float, Float32SampleTypeTraits>(bus.get(), "float"); } +TEST(AudioBusPerfTest, DISABLED_ToInterleavedFloat) { + std::unique_ptr<AudioBus> bus = AudioBus::Create(2, kSampleRate * 120); + FakeAudioRenderCallback callback(0.2, kSampleRate); + callback.Render(base::TimeDelta(), base::TimeTicks::Now(), 0, bus.get()); + + RunInterleaveBench<float, Float32SampleTypeTraits>( + bus.get(), "to_interleave_float", true); + RunInterleaveBench<float, Float32SampleTypeTraitsNoClip>( + bus.get(), "to_interleave_float_no_clip", true); +} + +void RunCopyBench(void (AudioBus::*f)(AudioBus*) const, const char* name) { + // Setup. + std::unique_ptr<AudioBus> bus = AudioBus::Create(2, kSampleRate * 120); + std::unique_ptr<AudioBus> dest = AudioBus::Create(2, kSampleRate * 120); + FakeAudioRenderCallback callback(0.2, kSampleRate); + callback.Render(base::TimeDelta(), base::TimeTicks::Now(), 0, bus.get()); + + // Warmup. + for (int i = 0; i < kBenchmarkIterations; ++i) + (bus.get()->*f)(dest.get()); + + // Benchmark. + auto start = base::TimeTicks::Now(); + for (int i = 0; i < kBenchmarkIterations; ++i) + (bus.get()->*f)(dest.get()); + auto total_time_milliseconds = + (base::TimeTicks::Now() - start).InMillisecondsF(); + + perf_test::PrintResult( + name, "", "", total_time_milliseconds / kBenchmarkIterations, "ms", true); +} + +TEST(AudioBusPerfTest, DISABLED_CopyBench) { + RunCopyBench(&AudioBus::CopyTo, "audio_bus_copy_no_clip"); + RunCopyBench(&AudioBus::CopyAndClipTo, "audio_bus_copy_clip"); +} + } // namespace media
diff --git a/media/base/audio_bus_unittest.cc b/media/base/audio_bus_unittest.cc index 9b21d76..46a124cf 100644 --- a/media/base/audio_bus_unittest.cc +++ b/media/base/audio_bus_unittest.cc
@@ -300,6 +300,23 @@ static const float kTestVectorFloat32[kTestVectorSize] = { -1.0f, 0.0f, 1.0f, -1.0f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f}; +// This is based on kTestVectorFloat32, but has some of the values outside of +// sanity. +static const float kTestVectorFloat32Invalid[kTestVectorSize] = { + -5.0f, + 0.0f, + 5.0f, + -1.0f, + 0.5f, + -0.5f, + 0.0f, + std::numeric_limits<float>::infinity(), + std::numeric_limits<float>::signaling_NaN(), + std::numeric_limits<float>::quiet_NaN()}; + +static const float kTestVectorFloat32Sanitized[kTestVectorSize] = { + -1.0f, 0.0f, 1.0f, -1.0f, 0.5f, -0.5f, 0.0f, 1.0f, -1.0f, -1.0f}; + // Expected results. static const int kTestVectorFrameCount = kTestVectorSize / 2; static const float kTestVectorResult[][kTestVectorFrameCount] = { @@ -519,29 +536,50 @@ } TEST_F(AudioBusTest, ToInterleavedSanitized) { - // This is based on kTestVectorFloat32, but has some of the values outside of - // sanity. - static const float kTestVectorFloat32Invalid[kTestVectorSize] = { - -5.0f, - 0.0f, - 5.0f, - -1.0f, - 0.5f, - -0.5f, - 0.0f, - std::numeric_limits<float>::infinity(), - std::numeric_limits<float>::signaling_NaN(), - std::numeric_limits<float>::quiet_NaN()}; std::unique_ptr<AudioBus> bus = AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount); bus->FromInterleaved<Float32SampleTypeTraits>(kTestVectorFloat32Invalid, bus->frames()); // Verify FromInterleaved applied no sanity. ASSERT_EQ(bus->channel(0)[0], kTestVectorFloat32Invalid[0]); - float test_array[base::size(kTestVectorFloat32)]; + float test_array[base::size(kTestVectorFloat32Sanitized)]; bus->ToInterleaved<Float32SampleTypeTraits>(bus->frames(), test_array); + for (size_t i = 0; i < base::size(kTestVectorFloat32Sanitized); ++i) + ASSERT_EQ(kTestVectorFloat32Sanitized[i], test_array[i]); + + // Verify that Float32SampleTypeTraitsNoClip applied no sanity. + bus->ToInterleaved<Float32SampleTypeTraitsNoClip>(bus->frames(), test_array); ASSERT_EQ(0, - memcmp(test_array, kTestVectorFloat32, sizeof(kTestVectorFloat32))); + memcmp(test_array, kTestVectorFloat32Invalid, + kTestVectorFrameCount * sizeof(*kTestVectorFloat32Invalid) * + kTestVectorChannelCount)); +} + +TEST_F(AudioBusTest, CopyAndClipTo) { + auto bus = AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount); + bus->FromInterleaved<Float32SampleTypeTraits>(kTestVectorFloat32Invalid, + bus->frames()); + auto expected = + AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount); + expected->FromInterleaved<Float32SampleTypeTraits>( + kTestVectorFloat32Sanitized, bus->frames()); + + // Verify FromInterleaved applied no sanity. + ASSERT_EQ(bus->channel(0)[0], kTestVectorFloat32Invalid[0]); + + std::unique_ptr<AudioBus> copy_to_bus = + AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount); + bus->CopyAndClipTo(copy_to_bus.get()); + + for (int ch = 0; ch < expected->channels(); ++ch) { + for (int i = 0; i < expected->frames(); ++i) + ASSERT_EQ(copy_to_bus->channel(ch)[i], expected->channel(ch)[i]); + } + + ASSERT_EQ(expected->channels(), copy_to_bus->channels()); + ASSERT_EQ(expected->frames(), copy_to_bus->frames()); + ASSERT_EQ(expected->is_bitstream_format(), + copy_to_bus->is_bitstream_format()); } // Verify ToInterleavedPartial() interleaves audio correctly.
diff --git a/media/base/audio_sample_types.h b/media/base/audio_sample_types.h index f77edf3c..af734ec 100644 --- a/media/base/audio_sample_types.h +++ b/media/base/audio_sample_types.h
@@ -63,11 +63,9 @@ static SampleType From(FloatType source_value) { // Apply clipping (aka. clamping). These values are frequently sent to OS // level drivers that may not properly handle these values. - if (std::isnan(source_value)) - return kZeroPointValue; - if (source_value <= kMinValue) + if (UNLIKELY(!(source_value >= kMinValue))) return kMinValue; - if (source_value >= kMaxValue) + if (UNLIKELY(source_value >= kMaxValue)) return kMaxValue; return static_cast<SampleType>(source_value); } @@ -78,6 +76,44 @@ } }; +// Similar to above, but does not apply clipping. +template <typename SampleType> +class FloatSampleTypeTraitsNoClip { + static_assert(std::is_floating_point<SampleType>::value, + "Template is only valid for float types."); + + public: + using ValueType = SampleType; + + static constexpr SampleType kMinValue = -1.0f; + static constexpr SampleType kMaxValue = +1.0f; + static constexpr SampleType kZeroPointValue = 0.0f; + + static SampleType FromFloat(float source_value) { + return From<float>(source_value); + } + static float ToFloat(SampleType source_value) { + return To<float>(source_value); + } + static SampleType FromDouble(double source_value) { + return From<double>(source_value); + } + static double ToDouble(SampleType source_value) { + return To<double>(source_value); + } + + private: + template <typename FloatType> + static SampleType From(FloatType source_value) { + return static_cast<SampleType>(source_value); + } + + template <typename FloatType> + static FloatType To(SampleType source_value) { + return static_cast<FloatType>(source_value); + } +}; + // For uint8_t, int16_t, int32_t... // See also the aliases for commonly used types at the bottom of this file. template <typename SampleType> @@ -208,6 +244,7 @@ // Aliases for commonly used sample formats. using Float32SampleTypeTraits = FloatSampleTypeTraits<float>; +using Float32SampleTypeTraitsNoClip = FloatSampleTypeTraitsNoClip<float>; using Float64SampleTypeTraits = FloatSampleTypeTraits<double>; using UnsignedInt8SampleTypeTraits = FixedSampleTypeTraits<uint8_t>; using SignedInt16SampleTypeTraits = FixedSampleTypeTraits<int16_t>;
diff --git a/media/base/supported_types.cc b/media/base/supported_types.cc index 0f5b4aa6..aa46e61b 100644 --- a/media/base/supported_types.cc +++ b/media/base/supported_types.cc
@@ -7,6 +7,7 @@ #include "base/feature_list.h" #include "base/no_destructor.h" #include "build/build_config.h" +#include "media/base/media.h" #include "media/base/media_client.h" #include "media/base/media_switches.h" #include "media/media_buildflags.h" @@ -153,9 +154,11 @@ return true; #if defined(OS_ANDROID) - // Support for VP9.2, VP9.3 was not added until Nougat. + // Support for VP9.2, VP9.3 was not added until Nougat and requires that we + // have the platform decoder (MediaCodec) available. if (base::android::BuildInfo::GetInstance()->sdk_int() < - base::android::SDK_VERSION_NOUGAT) { + base::android::SDK_VERSION_NOUGAT || + !HasPlatformDecoderSupport()) { return false; }
diff --git a/media/capture/video/chromeos/camera_device_delegate.cc b/media/capture/video/chromeos/camera_device_delegate.cc index 01711828..88ef6a4 100644 --- a/media/capture/video/chromeos/camera_device_delegate.cc +++ b/media/capture/video/chromeos/camera_device_delegate.cc
@@ -221,7 +221,7 @@ base::OnceClosure device_close_callback) { DCHECK(ipc_task_runner_->BelongsToCurrentThread()); - reprocess_manager_->FlushReprocessOptions(device_descriptor_.device_id); + reprocess_manager_->Flush(device_descriptor_.device_id); if (!device_context_ || device_context_->GetState() == CameraDeviceContext::State::kStopped || @@ -781,17 +781,13 @@ FROM_HERE, "Failed to get default request settings"); return; } - device_context_->SetState(CameraDeviceContext::State::kCapturing); - camera_3a_controller_->SetAutoFocusModeForStillCapture(); - request_manager_->StartPreview(std::move(settings)); - - if (!take_photo_callbacks_.empty()) { - TakePhotoImpl(); - } - - if (set_photo_option_callback_) { - std::move(set_photo_option_callback_).Run(true); - } + reprocess_manager_->GetFpsRange( + device_descriptor_.device_id, + chrome_capture_params_.requested_format.frame_size.width(), + chrome_capture_params_.requested_format.frame_size.height(), + media::BindToCurrentLoop( + base::BindOnce(&CameraDeviceDelegate::OnGotFpsRange, GetWeakPtr(), + std::move(settings)))); } void CameraDeviceDelegate::OnConstructedDefaultStillCaptureRequestSettings( @@ -812,6 +808,42 @@ } } +void CameraDeviceDelegate::OnGotFpsRange( + cros::mojom::CameraMetadataPtr settings, + base::Optional<gfx::Range> specified_fps_range) { + device_context_->SetState(CameraDeviceContext::State::kCapturing); + camera_3a_controller_->SetAutoFocusModeForStillCapture(); + if (specified_fps_range.has_value()) { + const int32_t entry_length = 2; + + // CameraMetadata is represented as an uint8 array. According to the + // definition of the FPS metadata tag, its data type is int32, so we + // reinterpret_cast here. + std::vector<uint8_t> fps_range(sizeof(int32_t) * entry_length); + auto* fps_ptr = reinterpret_cast<int32_t*>(fps_range.data()); + fps_ptr[0] = specified_fps_range->GetMin(); + fps_ptr[1] = specified_fps_range->GetMax(); + cros::mojom::CameraMetadataEntryPtr e = + cros::mojom::CameraMetadataEntry::New(); + e->tag = + cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AE_TARGET_FPS_RANGE; + e->type = cros::mojom::EntryType::TYPE_INT32; + e->count = entry_length; + e->data = std::move(fps_range); + + AddOrUpdateMetadataEntry(&settings, std::move(e)); + } + request_manager_->StartPreview(std::move(settings)); + + if (!take_photo_callbacks_.empty()) { + TakePhotoImpl(); + } + + if (set_photo_option_callback_) { + std::move(set_photo_option_callback_).Run(true); + } +} + void CameraDeviceDelegate::ProcessCaptureRequest( cros::mojom::Camera3CaptureRequestPtr request, base::OnceCallback<void(int32_t)> callback) {
diff --git a/media/capture/video/chromeos/camera_device_delegate.h b/media/capture/video/chromeos/camera_device_delegate.h index 971a308..b1cca24 100644 --- a/media/capture/video/chromeos/camera_device_delegate.h +++ b/media/capture/video/chromeos/camera_device_delegate.h
@@ -16,6 +16,7 @@ #include "media/capture/video/video_capture_device.h" #include "media/capture/video_capture_types.h" #include "ui/gfx/geometry/size.h" +#include "ui/gfx/range/range.h" namespace media { @@ -159,6 +160,9 @@ void OnConstructedDefaultStillCaptureRequestSettings( cros::mojom::CameraMetadataPtr settings); + void OnGotFpsRange(cros::mojom::CameraMetadataPtr settings, + base::Optional<gfx::Range> specified_fps_range); + // StreamCaptureInterface implementations. These methods are called by // |stream_buffer_manager_| on |ipc_task_runner_|. void ProcessCaptureRequest(cros::mojom::Camera3CaptureRequestPtr request,
diff --git a/media/capture/video/chromeos/cros_image_capture_impl.cc b/media/capture/video/chromeos/cros_image_capture_impl.cc index 1d14432..b0c3b19 100644 --- a/media/capture/video/chromeos/cros_image_capture_impl.cc +++ b/media/capture/video/chromeos/cros_image_capture_impl.cc
@@ -34,6 +34,17 @@ device_id, effect, media::BindToCurrentLoop(std::move(callback))); } +void CrosImageCaptureImpl::SetFpsRange(const std::string& device_id, + const uint32_t stream_width, + const uint32_t stream_height, + const int32_t min_fps, + const int32_t max_fps, + SetFpsRangeCallback callback) { + reprocess_manager_->SetFpsRange( + device_id, stream_width, stream_height, min_fps, max_fps, + media::BindToCurrentLoop(std::move(callback))); +} + void CrosImageCaptureImpl::OnGotCameraInfo( GetCameraInfoCallback callback, cros::mojom::CameraInfoPtr camera_info) {
diff --git a/media/capture/video/chromeos/cros_image_capture_impl.h b/media/capture/video/chromeos/cros_image_capture_impl.h index 9a5c78f1..553a049a 100644 --- a/media/capture/video/chromeos/cros_image_capture_impl.h +++ b/media/capture/video/chromeos/cros_image_capture_impl.h
@@ -28,6 +28,12 @@ void SetReprocessOption(const std::string& device_id, cros::mojom::Effect effect, SetReprocessOptionCallback callback) override; + void SetFpsRange(const std::string& device_id, + const uint32_t stream_width, + const uint32_t stream_height, + const int32_t min_fps, + const int32_t max_fps, + SetFpsRangeCallback callback) override; private: void OnGotCameraInfo(GetCameraInfoCallback callback,
diff --git a/media/capture/video/chromeos/mojo/cros_image_capture.mojom b/media/capture/video/chromeos/mojo/cros_image_capture.mojom index e2adaf2..215f191 100644 --- a/media/capture/video/chromeos/mojo/cros_image_capture.mojom +++ b/media/capture/video/chromeos/mojo/cros_image_capture.mojom
@@ -32,4 +32,15 @@ // actual video device id. SetReprocessOption(string source_id, Effect effect) => (int32 status, media.mojom.Blob blob); + + // Sets the frame rate range for upcoming configured camera stream. + // The |source_id| might need translation to be actual video device id. + // The |stream_width| and |stream_height| are the target stream resolution + // that the caller sets the frame rate range for. + // The |min_frame_rate| and |max_frame_rate| represent the frame rate range. + // If the given frame rate is valid and set successfully, |is_success| returns + // true. False otherwise. + SetFpsRange(string source_id, uint32 stream_width, uint32 stream_height, + int32 min_frame_rate, int32 max_frame_rate) + => (bool is_success); }; \ No newline at end of file
diff --git a/media/capture/video/chromeos/renderer_facing_cros_image_capture.cc b/media/capture/video/chromeos/renderer_facing_cros_image_capture.cc index 6d09adf..f48ea78 100644 --- a/media/capture/video/chromeos/renderer_facing_cros_image_capture.cc +++ b/media/capture/video/chromeos/renderer_facing_cros_image_capture.cc
@@ -39,6 +39,19 @@ std::move(callback)); } +void RendererFacingCrosImageCapture::SetFpsRangeWithRealId( + const uint32_t stream_width, + const uint32_t stream_height, + const int32_t min_frame_rate, + const int32_t max_frame_rate, + SetFpsRangeCallback callback, + const base::Optional<std::string>& device_id) { + DCHECK(device_id.has_value()); + cros_image_capture_->SetFpsRange(*device_id, stream_width, stream_height, + min_frame_rate, max_frame_rate, + std::move(callback)); +} + void RendererFacingCrosImageCapture::GetCameraInfo( const std::string& source_id, GetCameraInfoCallback callback) { @@ -59,4 +72,18 @@ weak_ptr_factory_.GetWeakPtr(), effect, std::move(callback)))); } +void RendererFacingCrosImageCapture::SetFpsRange(const std::string& source_id, + const uint32_t stream_width, + const uint32_t stream_height, + const int32_t min_frame_rate, + const int32_t max_frame_rate, + SetFpsRangeCallback callback) { + mapping_callback_.Run( + source_id, + media::BindToCurrentLoop(base::BindOnce( + &RendererFacingCrosImageCapture::SetFpsRangeWithRealId, + weak_ptr_factory_.GetWeakPtr(), stream_width, stream_height, + min_frame_rate, max_frame_rate, std::move(callback)))); +} + } // namespace media \ No newline at end of file
diff --git a/media/capture/video/chromeos/renderer_facing_cros_image_capture.h b/media/capture/video/chromeos/renderer_facing_cros_image_capture.h index ad6fa0b..cc951e8 100644 --- a/media/capture/video/chromeos/renderer_facing_cros_image_capture.h +++ b/media/capture/video/chromeos/renderer_facing_cros_image_capture.h
@@ -41,12 +41,25 @@ SetReprocessOptionCallback callback, const base::Optional<std::string>& device_id); + void SetFpsRangeWithRealId(const uint32_t stream_width, + const uint32_t stream_height, + const int32_t min_frame_rate, + const int32_t max_frame_rate, + SetFpsRangeCallback callback, + const base::Optional<std::string>& device_id); + // cros::mojom::CrosImageCapture implementations. void GetCameraInfo(const std::string& source_id, GetCameraInfoCallback callback) override; void SetReprocessOption(const std::string& source_id, cros::mojom::Effect effect, SetReprocessOptionCallback callback) override; + void SetFpsRange(const std::string& source_id, + const uint32_t stream_width, + const uint32_t stream_height, + const int32_t min_frame_rate, + const int32_t max_frame_rate, + SetFpsRangeCallback callback) override; private: cros::mojom::CrosImageCapturePtr cros_image_capture_;
diff --git a/media/capture/video/chromeos/reprocess_manager.cc b/media/capture/video/chromeos/reprocess_manager.cc index 9fce50d..3c0776c 100644 --- a/media/capture/video/chromeos/reprocess_manager.cc +++ b/media/capture/video/chromeos/reprocess_manager.cc
@@ -79,12 +79,10 @@ std::move(take_photo_callback), std::move(consumption_callback))); } -void ReprocessManager::FlushReprocessOptions(const std::string& device_id) { +void ReprocessManager::Flush(const std::string& device_id) { sequenced_task_runner_->PostTask( - FROM_HERE, - base::BindOnce( - &ReprocessManager::ReprocessManagerImpl::FlushReprocessOptions, - base::Unretained(impl.get()), device_id)); + FROM_HERE, base::BindOnce(&ReprocessManager::ReprocessManagerImpl::Flush, + base::Unretained(impl.get()), device_id)); } void ReprocessManager::GetCameraInfo(const std::string& device_id, @@ -96,6 +94,31 @@ std::move(callback))); } +void ReprocessManager::SetFpsRange( + const std::string& device_id, + const uint32_t stream_width, + const uint32_t stream_height, + const int32_t min_fps, + const int32_t max_fps, + cros::mojom::CrosImageCapture::SetFpsRangeCallback callback) { + sequenced_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&ReprocessManager::ReprocessManagerImpl::SetFpsRange, + base::Unretained(impl.get()), device_id, stream_width, + stream_height, min_fps, max_fps, std::move(callback))); +} + +void ReprocessManager::GetFpsRange(const std::string& device_id, + const uint32_t stream_width, + const uint32_t stream_height, + GetFpsRangeCallback callback) { + sequenced_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&ReprocessManager::ReprocessManagerImpl::GetFpsRange, + base::Unretained(impl.get()), device_id, stream_width, + stream_height, std::move(callback))); +} + ReprocessManager::ReprocessManagerImpl::ReprocessManagerImpl( CameraInfoGetter get_camera_info) : get_camera_info_(std::move(get_camera_info)) {} @@ -147,10 +170,13 @@ std::move(consumption_callback).Run(std::move(result_task_queue)); } -void ReprocessManager::ReprocessManagerImpl::FlushReprocessOptions( +void ReprocessManager::ReprocessManagerImpl::Flush( const std::string& device_id) { auto empty_queue = ReprocessTaskQueue(); reprocess_task_queue_map_[device_id].swap(empty_queue); + + auto empty_map = ResolutionFpsRangeMap(); + resolution_fps_range_map_[device_id].swap(empty_map); } void ReprocessManager::ReprocessManagerImpl::GetCameraInfo( @@ -159,4 +185,69 @@ std::move(callback).Run(get_camera_info_.Run(device_id)); } +void ReprocessManager::ReprocessManagerImpl::SetFpsRange( + const std::string& device_id, + const uint32_t stream_width, + const uint32_t stream_height, + const int32_t min_fps, + const int32_t max_fps, + cros::mojom::CrosImageCapture::SetFpsRangeCallback callback) { + const int entry_length = 2; + + auto camera_info = get_camera_info_.Run(device_id); + auto& static_metadata = camera_info->static_camera_characteristics; + auto available_fps_range_entries = GetMetadataEntryAsSpan<int32_t>( + static_metadata, cros::mojom::CameraMetadataTag:: + ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES); + CHECK(available_fps_range_entries.size() % entry_length == 0); + + bool is_valid = false; + for (size_t i = 0; i < available_fps_range_entries.size(); + i += entry_length) { + if (available_fps_range_entries[i] == min_fps && + available_fps_range_entries[i + 1] == max_fps) { + is_valid = true; + break; + } + } + + if (!is_valid) { + std::move(callback).Run(false); + return; + } + + auto resolution = gfx::Size(stream_width, stream_height); + auto fps_range = gfx::Range(min_fps, max_fps); + resolution_fps_range_map_[device_id][resolution] = fps_range; + std::move(callback).Run(true); +} + +void ReprocessManager::ReprocessManagerImpl::GetFpsRange( + const std::string& device_id, + const uint32_t stream_width, + const uint32_t stream_height, + GetFpsRangeCallback callback) { + if (resolution_fps_range_map_.find(device_id) == + resolution_fps_range_map_.end()) { + std::move(callback).Run({}); + return; + } + + auto resolution = gfx::Size(stream_width, stream_height); + auto& fps_map = resolution_fps_range_map_[device_id]; + if (fps_map.find(resolution) == fps_map.end()) { + std::move(callback).Run({}); + return; + } + + std::move(callback).Run(fps_map[resolution]); +} + +bool ReprocessManager::ReprocessManagerImpl::SizeComparator::operator()( + const gfx::Size size_1, + const gfx::Size size_2) const { + return size_1.width() < size_2.width() || (size_1.width() == size_2.width() && + size_1.height() < size_2.height()); +} + } // namespace media
diff --git a/media/capture/video/chromeos/reprocess_manager.h b/media/capture/video/chromeos/reprocess_manager.h index c7dea66..ac2add5 100644 --- a/media/capture/video/chromeos/reprocess_manager.h +++ b/media/capture/video/chromeos/reprocess_manager.h
@@ -19,6 +19,8 @@ #include "media/capture/video/chromeos/mojo/camera_common.mojom.h" #include "media/capture/video/chromeos/mojo/cros_image_capture.mojom.h" #include "mojo/public/cpp/bindings/binding.h" +#include "ui/gfx/geometry/size.h" +#include "ui/gfx/range/range.h" namespace media { @@ -51,9 +53,18 @@ const std::string& device_id)>; using GetCameraInfoCallback = base::OnceCallback<void(cros::mojom::CameraInfoPtr camera_info)>; + using GetFpsRangeCallback = + base::OnceCallback<void(base::Optional<gfx::Range>)>; class ReprocessManagerImpl { public: + struct SizeComparator { + bool operator()(const gfx::Size size_1, const gfx::Size size_2) const; + }; + + using ResolutionFpsRangeMap = + base::flat_map<gfx::Size, gfx::Range, SizeComparator>; + ReprocessManagerImpl(CameraInfoGetter get_camera_info); ~ReprocessManagerImpl(); @@ -68,14 +79,29 @@ media::mojom::ImageCapture::TakePhotoCallback take_photo_callback, base::OnceCallback<void(ReprocessTaskQueue)> consumption_callback); - void FlushReprocessOptions(const std::string& device_id); + void Flush(const std::string& device_id); void GetCameraInfo(const std::string& device_id, GetCameraInfoCallback callback); + void SetFpsRange( + const std::string& device_id, + const uint32_t stream_width, + const uint32_t stream_height, + const int32_t min_fps, + const int32_t max_fps, + cros::mojom::CrosImageCapture::SetFpsRangeCallback callback); + + void GetFpsRange(const std::string& device_id, + const uint32_t stream_width, + const uint32_t stream_height, + GetFpsRangeCallback callback); + private: base::flat_map<std::string, base::queue<ReprocessTask>> reprocess_task_queue_map_; + base::flat_map<std::string, ResolutionFpsRangeMap> + resolution_fps_range_map_; CameraInfoGetter get_camera_info_; @@ -103,13 +129,27 @@ media::mojom::ImageCapture::TakePhotoCallback take_photo_callback, base::OnceCallback<void(ReprocessTaskQueue)> consumption_callback); - // Clears all remaining ReprocessTasks in the queue for given device id. - void FlushReprocessOptions(const std::string& device_id); + // Clears all temporary queues and maps that is used for given device id. + void Flush(const std::string& device_id); // Gets camera information for current active device. void GetCameraInfo(const std::string& device_id, GetCameraInfoCallback callback); + // Sets fps range for given device. + void SetFpsRange(const std::string& device_id, + const uint32_t stream_width, + const uint32_t stream_height, + const int32_t min_fps, + const int32_t max_fps, + cros::mojom::CrosImageCapture::SetFpsRangeCallback callback); + + // Gets fps range for given device and resolution. + void GetFpsRange(const std::string& device_id, + const uint32_t stream_width, + const uint32_t stream_height, + GetFpsRangeCallback callback); + private: scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_; std::unique_ptr<ReprocessManagerImpl> impl;
diff --git a/media/cast/sender/external_video_encoder.cc b/media/cast/sender/external_video_encoder.cc index cc13dc5b..282194d 100644 --- a/media/cast/sender/external_video_encoder.cc +++ b/media/cast/sender/external_video_encoder.cc
@@ -600,15 +600,6 @@ video_config.codec != CODEC_VIDEO_H264) return false; -#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) - // Disable VP8 HW encoding on ChromeOS Intel platform, because some target - // cannot decode correctly VP8 bitstream generated by ChromeOS Intel HW video - // encoder. - // TODO(crbug.com/955286): Enable once the decoders on the targets are fixed. - if (video_config.codec == CODEC_VIDEO_VP8) - return false; -#endif - // TODO(miu): "Layering hooks" are needed to be able to query outside of // libmedia, to determine whether the system provides a hardware encoder. For // now, assume that this was already checked by this point.
diff --git a/media/cast/sender/video_encoder_unittest.cc b/media/cast/sender/video_encoder_unittest.cc index 6eba9d5..743bc7f 100644 --- a/media/cast/sender/video_encoder_unittest.cc +++ b/media/cast/sender/video_encoder_unittest.cc
@@ -365,16 +365,8 @@ values.push_back(std::make_pair(CODEC_VIDEO_FAKE, false)); // Software VP8 encoder. values.push_back(std::make_pair(CODEC_VIDEO_VP8, false)); - - // VP8 HW encoding on ChromeOS Intel platform is disabled. - // See ExternalVideoEncoder::IsSupported(). - // TODO(crbug.com/955286): Remove this once VP8 HW encoder is enabled on - // ChromeOS Intel platform. -#if !defined(OS_CHROMEOS) || !defined(ARCH_CPU_X86_FAMILY) // Hardware-accelerated encoder (faked). values.push_back(std::make_pair(CODEC_VIDEO_VP8, true)); -#endif - #if defined(OS_MACOSX) // VideoToolbox encoder (when VideoToolbox is present). FrameSenderConfig video_config = GetDefaultVideoSenderConfig();
diff --git a/media/cast/sender/video_sender_unittest.cc b/media/cast/sender/video_sender_unittest.cc index 47b57154..8eadecf 100644 --- a/media/cast/sender/video_sender_unittest.cc +++ b/media/cast/sender/video_sender_unittest.cc
@@ -14,7 +14,6 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/test/simple_test_tick_clock.h" -#include "build/build_config.h" #include "media/base/fake_single_thread_task_runner.h" #include "media/base/video_frame.h" #include "media/cast/cast_environment.h" @@ -42,16 +41,6 @@ using testing::_; using testing::AtLeast; -#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) -// ExternalEncoder::IsFormatSupported() returns false because some target cannot -// decode correctly VP8 bitstream generated by ChromeOS Intel HW video encoder. -// Because of this, ExternalEncoder is not created and a VEA factory function is -// not called. It causes ExternalEncoder tests fail because it expects the VEA -// factory function is called. -// TODO(crbug.com/955286): Run ExternalEncoder tests again once VP8 HW encoding -// on ChromeOS Intel platform is enabled. -#define DISABLED_EXTERNAL_ENCODER_TESTS -#endif void SaveOperationalStatus(OperationalStatus* out_status, OperationalStatus in_status) { @@ -269,13 +258,7 @@ EXPECT_LE(1, transport_->number_of_rtcp_packets()); } -#ifdef DISABLED_EXTERNAL_ENCODER_TESTS -#define MAYBE_ExternalEncoder DISABLED_ExternalEncoder -#else -#define MAYBE_ExternalEncoder ExternalEncoder -#endif - -TEST_F(VideoSenderTest, MAYBE_ExternalEncoder) { +TEST_F(VideoSenderTest, ExternalEncoder) { InitEncoder(true, true); ASSERT_EQ(STATUS_INITIALIZED, operational_status_); @@ -314,13 +297,7 @@ EXPECT_LT(0, vea_factory_.shm_response_count()); } -#ifdef DISABLED_EXTERNAL_ENCODER_TESTS -#define MAYBE_ExternalEncoderInitFails DISABLED_ExternalEncoderInitFails -#else -#define MAYBE_ExternalEncoderInitFails ExternalEncoderInitFails -#endif - -TEST_F(VideoSenderTest, MAYBE_ExternalEncoderInitFails) { +TEST_F(VideoSenderTest, ExternalEncoderInitFails) { InitEncoder(true, false); // The SizeAdaptableExternalVideoEncoder initally reports STATUS_INITIALIZED
diff --git a/media/gpu/test/video_player/test_vda_video_decoder.cc b/media/gpu/test/video_player/test_vda_video_decoder.cc index e88cd0a4..820931a3 100644 --- a/media/gpu/test/video_player/test_vda_video_decoder.cc +++ b/media/gpu/test/video_player/test_vda_video_decoder.cc
@@ -61,8 +61,11 @@ // Invalidate all scheduled tasks. weak_this_factory_.InvalidateWeakPtrs(); - // Delete all video frames and related textures. + // Delete all video frames and related textures and the decoder. + frame_renderer_->AcquireGLContext(); video_frames_.clear(); + decoder_ = nullptr; + frame_renderer_->ReleaseGLContext(); delete this; }
diff --git a/media/gpu/vaapi/vaapi_video_decoder.cc b/media/gpu/vaapi/vaapi_video_decoder.cc index 738bea3..cbf279e 100644 --- a/media/gpu/vaapi/vaapi_video_decoder.cc +++ b/media/gpu/vaapi/vaapi_video_decoder.cc
@@ -476,7 +476,7 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DCHECK_EQ(state_, State::kDecoding); DCHECK(video_frame); - VLOGF(4); + DVLOGF(4); scoped_refptr<VideoFrame> converted_frame = frame_converter_->ConvertFrame(video_frame); @@ -540,7 +540,7 @@ void VaapiVideoDecoder::NotifyFrameAvailableTask() { DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); - VLOGF(4); + DVLOGF(4); // If we were waiting for output buffers, retry the current decode task. if (state_ == State::kWaitingForOutput) {
diff --git a/media/gpu/vaapi/vaapi_wrapper.cc b/media/gpu/vaapi/vaapi_wrapper.cc index 20282ba..f47c240 100644 --- a/media/gpu/vaapi/vaapi_wrapper.cc +++ b/media/gpu/vaapi/vaapi_wrapper.cc
@@ -139,7 +139,6 @@ constexpr const char* kMesaGalliumDriverPrefix = "Mesa Gallium driver"; constexpr const char* kIntelI965DriverPrefix = "Intel i965 driver"; -constexpr const char* kIntelIHDDriverPrefix = "Intel iHD driver"; static const struct { std::string va_driver; @@ -1035,19 +1034,6 @@ i420_format.fourcc = VA_FOURCC_I420; supported_formats_.push_back(i420_format); } - } else if (base::StartsWith(VADisplayState::Get()->va_vendor_string(), - kIntelIHDDriverPrefix, - base::CompareCase::SENSITIVE)) { - // TODO(andrescj): for Intel's media driver, remove everything that's not - // I420 or NV12 since it is 'over-advertising' the supported formats. Remove - // this workaround once https://crbug.com/955284 is fixed. - supported_formats_.erase( - std::remove_if(supported_formats_.begin(), supported_formats_.end(), - [](const VAImageFormat& format) { - return format.fourcc != VA_FOURCC_I420 && - format.fourcc != VA_FOURCC_NV12; - }), - supported_formats_.end()); } return true; }
diff --git a/mojo/public/tools/bindings/chromium_bindings_configuration.gni b/mojo/public/tools/bindings/chromium_bindings_configuration.gni index d4327c6..3f26ece 100644 --- a/mojo/public/tools/bindings/chromium_bindings_configuration.gni +++ b/mojo/public/tools/bindings/chromium_bindings_configuration.gni
@@ -22,6 +22,7 @@ "//device/bluetooth/public/mojom/typemaps.gni", "//device/bluetooth/public/mojom/test/typemaps.gni", "//device/gamepad/public/cpp/typemaps.gni", + "//fuchsia/mojo/test_typemaps.gni", "//gpu/ipc/common/typemaps.gni", "//ipc/typemaps.gni", "//media/capture/mojom/typemaps.gni",
diff --git a/net/cert/cert_verify_proc_unittest.cc b/net/cert/cert_verify_proc_unittest.cc index 254961d..b5e8795 100644 --- a/net/cert/cert_verify_proc_unittest.cc +++ b/net/cert/cert_verify_proc_unittest.cc
@@ -250,6 +250,18 @@ verify_proc_type == CERT_VERIFY_PROC_ANDROID; } +// Returns true if a non-self-signed CA certificate added through +// ScopedTestRoot can verify successfully as the root of a chain by the given +// CertVerifyProcType. +bool ScopedTestRootCanTrustIntermediateCert( + CertVerifyProcType verify_proc_type) { + return verify_proc_type == CERT_VERIFY_PROC_MAC || + verify_proc_type == CERT_VERIFY_PROC_IOS || + verify_proc_type == CERT_VERIFY_PROC_NSS || + verify_proc_type == CERT_VERIFY_PROC_BUILTIN || + verify_proc_type == CERT_VERIFY_PROC_ANDROID; +} + // TODO(crbug.com/649017): This is not parameterized by the CertVerifyProc // because the CertVerifyProc::Verify() does this unconditionally based on the // platform. @@ -1038,6 +1050,99 @@ EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_IS_EV); } +// Target cert has an EV policy, and has a valid path to the EV root, but the +// intermediate has been trusted directly. Should stop building the path at the +// intermediate and verify OK but not with STATUS_IS_EV. +// See https://crbug.com/979801 +TEST_P(CertVerifyProcInternalTest, TrustedIntermediateCertWithEVPolicy) { + if (!SupportsEV()) { + LOG(INFO) << "Skipping test as EV verification is not yet supported"; + return; + } + if (!ScopedTestRootCanTrustIntermediateCert(verify_proc_type())) { + LOG(INFO) << "Skipping test as intermediate cert cannot be trusted"; + return; + } + + CertificateList orig_certs = CreateCertificateListFromFile( + GetTestCertsDirectory(), "explicit-policy-chain.pem", + X509Certificate::FORMAT_AUTO); + ASSERT_EQ(3U, orig_certs.size()); + + for (bool trust_the_intermediate : {false, true}) { + // Need to build unique certs for each try otherwise caching can break + // things. + CertBuilder root(orig_certs[2]->cert_buffer(), nullptr); + CertBuilder intermediate(orig_certs[1]->cert_buffer(), &root); + CertBuilder leaf(orig_certs[0]->cert_buffer(), &intermediate); + + // The policy that "explicit-policy-chain.pem" target certificate asserts. + static const char kEVTestCertPolicy[] = "1.2.3.4"; + // Consider the root of the test chain a valid EV root for the test policy. + ScopedTestEVPolicy scoped_test_ev_policy( + EVRootCAMetadata::GetInstance(), + X509Certificate::CalculateFingerprint256(root.GetCertBuffer()), + kEVTestCertPolicy); + + // CRLSet which covers the leaf. + base::StringPiece intermediate_spki; + ASSERT_TRUE(asn1::ExtractSPKIFromDERCert( + x509_util::CryptoBufferAsStringPiece(intermediate.GetCertBuffer()), + &intermediate_spki)); + SHA256HashValue intermediate_spki_hash; + crypto::SHA256HashString(intermediate_spki, &intermediate_spki_hash, + sizeof(SHA256HashValue)); + scoped_refptr<CRLSet> crl_set = + CRLSet::ForTesting(false, &intermediate_spki_hash, "", "", {}); + + std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates; + intermediates.push_back(bssl::UpRef(intermediate.GetCertBuffer())); + scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromBuffer( + bssl::UpRef(leaf.GetCertBuffer()), std::move(intermediates)); + ASSERT_TRUE(cert.get()); + + scoped_refptr<X509Certificate> intermediate_cert = + X509Certificate::CreateFromBuffer( + bssl::UpRef(intermediate.GetCertBuffer()), {}); + ASSERT_TRUE(intermediate_cert.get()); + + scoped_refptr<X509Certificate> root_cert = + X509Certificate::CreateFromBuffer(bssl::UpRef(root.GetCertBuffer()), + {}); + ASSERT_TRUE(root_cert.get()); + + if (!trust_the_intermediate) { + // First trust just the root. This verifies that the test setup is + // actually correct. + ScopedTestRoot scoped_test_root({root_cert}); + CertVerifyResult verify_result; + int flags = 0; + int error = Verify(cert.get(), "policy_test.example", flags, + crl_set.get(), CertificateList(), &verify_result); + EXPECT_THAT(error, IsOk()); + ASSERT_TRUE(verify_result.verified_cert); + // Verified chain should include the intermediate and the root. + EXPECT_EQ(2U, verify_result.verified_cert->intermediate_buffers().size()); + // Should be EV. + EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV); + } else { + // Now try with trusting both the intermediate and the root. + ScopedTestRoot scoped_test_root({intermediate_cert, root_cert}); + CertVerifyResult verify_result; + int flags = 0; + int error = Verify(cert.get(), "policy_test.example", flags, + crl_set.get(), CertificateList(), &verify_result); + EXPECT_THAT(error, IsOk()); + ASSERT_TRUE(verify_result.verified_cert); + // Verified chain should only go to the trusted intermediate, not the + // root. + EXPECT_EQ(1U, verify_result.verified_cert->intermediate_buffers().size()); + // Should not be EV. + EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_IS_EV); + } + } +} + // TODO(crbug.com/605457): the test expectation was incorrect on some // configurations, so disable the test until it is fixed (better to have // a bug to track a failing test than a false sense of security due to
diff --git a/net/cert/test_root_certs.cc b/net/cert/test_root_certs.cc index f455d18f..2790669 100644 --- a/net/cert/test_root_certs.cc +++ b/net/cert/test_root_certs.cc
@@ -60,19 +60,23 @@ ScopedTestRoot::ScopedTestRoot() = default; ScopedTestRoot::ScopedTestRoot(X509Certificate* cert) { - Reset(cert); + Reset({cert}); +} + +ScopedTestRoot::ScopedTestRoot(CertificateList certs) { + Reset(std::move(certs)); } ScopedTestRoot::~ScopedTestRoot() { - Reset(nullptr); + Reset({}); } -void ScopedTestRoot::Reset(X509Certificate* cert) { - if (cert_.get()) +void ScopedTestRoot::Reset(CertificateList certs) { + if (!certs_.empty()) TestRootCerts::GetInstance()->Clear(); - if (cert) - TestRootCerts::GetInstance()->Add(cert); - cert_ = cert; + for (const auto& cert : certs) + TestRootCerts::GetInstance()->Add(cert.get()); + certs_ = certs; } } // namespace net
diff --git a/net/cert/test_root_certs.h b/net/cert/test_root_certs.h index 5315718..c0be7b7 100644 --- a/net/cert/test_root_certs.h +++ b/net/cert/test_root_certs.h
@@ -32,6 +32,7 @@ namespace net { class X509Certificate; +typedef std::vector<scoped_refptr<X509Certificate>> CertificateList; // TestRootCerts is a helper class for unit tests that is used to // artificially mark a certificate as trusted, independent of the local @@ -149,17 +150,21 @@ // TestRootCerts store (if there were existing roots they are // cleared). explicit ScopedTestRoot(X509Certificate* cert); + // Creates a ScopedTestRoot that sets |certs| as the only roots in the + // TestRootCerts store (if there were existing roots they are + // cleared). + explicit ScopedTestRoot(CertificateList certs); ~ScopedTestRoot(); - // Assigns |cert| to be the new test root cert. If |cert| is NULL, undoes + // Assigns |certs| to be the new test root certs. If |certs| is empty, undoes // any work the ScopedTestRoot may have previously done. - // If |cert_| contains a certificate (due to a prior call to Reset or due to - // a cert being passed at construction), the existing TestRootCerts store is + // If |certs_| contains certificates (due to a prior call to Reset or due to + // certs being passed at construction), the existing TestRootCerts store is // cleared. - void Reset(X509Certificate* cert); + void Reset(CertificateList certs); private: - scoped_refptr<X509Certificate> cert_; + CertificateList certs_; DISALLOW_COPY_AND_ASSIGN(ScopedTestRoot); };
diff --git a/net/quic/crypto_test_utils_chromium.cc b/net/quic/crypto_test_utils_chromium.cc index f1c2d89f..e63cdc8 100644 --- a/net/quic/crypto_test_utils_chromium.cc +++ b/net/quic/crypto_test_utils_chromium.cc
@@ -59,7 +59,7 @@ // Load and install the root for the validated chain. scoped_refptr<X509Certificate> root_cert = ImportCertFromFile(GetTestCertsDirectory(), cert_file); - scoped_root_.Reset(root_cert.get()); + scoped_root_.Reset({root_cert}); } ~TestProofVerifierChromium() override {}
diff --git a/net/quic/platform/impl/quic_flags_impl.cc b/net/quic/platform/impl/quic_flags_impl.cc index 3cd9d44..d2c719d0 100644 --- a/net/quic/platform/impl/quic_flags_impl.cc +++ b/net/quic/platform/impl/quic_flags_impl.cc
@@ -203,7 +203,7 @@ } logging::LoggingSettings settings; - settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; + settings.logging_dest = logging::LOG_TO_STDERR; CHECK(logging::InitLogging(settings)); return result.non_flag_args;
diff --git a/net/test/spawned_test_server/remote_test_server_spawner_request.cc b/net/test/spawned_test_server/remote_test_server_spawner_request.cc index 3ca8305..91aacd5 100644 --- a/net/test/spawned_test_server/remote_test_server_spawner_request.cc +++ b/net/test/spawned_test_server/remote_test_server_spawner_request.cc
@@ -22,6 +22,7 @@ #include "net/base/port_util.h" #include "net/base/upload_bytes_element_reader.h" #include "net/http/http_response_headers.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_test_util.h" #include "url/gurl.h" @@ -85,7 +86,8 @@ // Prepare the URLRequest for sending the command. DCHECK(!request_.get()); context_.reset(new TestURLRequestContext); - request_ = context_->CreateRequest(url, DEFAULT_PRIORITY, this); + request_ = context_->CreateRequest(url, DEFAULT_PRIORITY, this, + TRAFFIC_ANNOTATION_FOR_TESTS); if (post_data.empty()) { request_->set_method("GET");
diff --git a/net/tools/quic/quic_http_proxy_backend_stream.cc b/net/tools/quic/quic_http_proxy_backend_stream.cc index 9aecf83..cdd598cc 100644 --- a/net/tools/quic/quic_http_proxy_backend_stream.cc +++ b/net/tools/quic/quic_http_proxy_backend_stream.cc
@@ -12,6 +12,7 @@ #include "net/http/http_status_code.h" #include "net/http/http_util.h" #include "net/ssl/ssl_info.h" +#include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/redirect_info.h" #include "net/url_request/url_request_context.h" @@ -188,7 +189,7 @@ void QuicHttpProxyBackendStream::SendRequestOnBackendThread() { DCHECK(quic_proxy_task_runner_->BelongsToCurrentThread()); url_request_ = proxy_context_->GetURLRequestContext()->CreateRequest( - url_, net::DEFAULT_PRIORITY, this); + url_, net::DEFAULT_PRIORITY, this, MISSING_TRAFFIC_ANNOTATION); url_request_->set_method(method_type_); url_request_->SetExtraRequestHeaders(request_headers_); if (upload_) {
diff --git a/net/traffic_annotation/network_traffic_annotation.h b/net/traffic_annotation/network_traffic_annotation.h index a4f0b8f..6319a81 100644 --- a/net/traffic_annotation/network_traffic_annotation.h +++ b/net/traffic_annotation/network_traffic_annotation.h
@@ -361,12 +361,20 @@ net::DefineNetworkTrafficAnnotation(ANNOTATION_ID, "No proto yet.") #endif +// These annotations are unavailable on desktop Linux + Windows. They are +// available on other platforms, since we only audit network annotations on +// Linux & Windows. +// +// On Linux and Windows, use MISSING_TRAFFIC_ANNOTATION or +// TRAFFIC_ANNOTATION_FOR_TESTS. +#if (!defined(OS_WIN) && !defined(OS_LINUX)) || defined(OS_CHROMEOS) #define NO_TRAFFIC_ANNOTATION_YET \ net::DefineNetworkTrafficAnnotation("undefined", "Nothing here yet.") #define NO_PARTIAL_TRAFFIC_ANNOTATION_YET \ net::DefinePartialNetworkTrafficAnnotation("undefined", "undefined", \ "Nothing here yet.") +#endif #define MISSING_TRAFFIC_ANNOTATION \ net::DefineNetworkTrafficAnnotation( \
diff --git a/net/url_request/url_fetcher.cc b/net/url_request/url_fetcher.cc index e815b57..331420f 100644 --- a/net/url_request/url_fetcher.cc +++ b/net/url_request/url_fetcher.cc
@@ -11,6 +11,7 @@ URLFetcher::~URLFetcher() = default; +#if (!defined(OS_WIN) && !defined(OS_LINUX)) || defined(OS_CHROMEOS) // static std::unique_ptr<URLFetcher> URLFetcher::Create( const GURL& url, @@ -27,6 +28,7 @@ URLFetcherDelegate* d) { return Create(id, url, request_type, d, MISSING_TRAFFIC_ANNOTATION); } +#endif // static std::unique_ptr<URLFetcher> URLFetcher::Create(
diff --git a/net/url_request/url_fetcher.h b/net/url_request/url_fetcher.h index fc8d1d1..6579924 100644 --- a/net/url_request/url_fetcher.h +++ b/net/url_request/url_fetcher.h
@@ -14,6 +14,7 @@ #include "base/callback_forward.h" #include "base/memory/ref_counted.h" #include "base/supports_user_data.h" +#include "build/build_config.h" #include "net/base/ip_endpoint.h" #include "net/base/net_export.h" #include "net/traffic_annotation/network_traffic_annotation.h" @@ -109,6 +110,10 @@ virtual ~URLFetcher(); + // The unannotated Create() methods are not available on desktop Linux + + // Windows. They are available on other platforms, since we only audit network + // annotations on Linux & Windows. +#if (!defined(OS_WIN) && !defined(OS_LINUX)) || defined(OS_CHROMEOS) // |url| is the URL to send the request to. It must be valid. // |request_type| is the type of request to make. // |d| the object that will receive the callback on fetch completion. @@ -129,6 +134,7 @@ const GURL& url, URLFetcher::RequestType request_type, URLFetcherDelegate* d); +#endif // |url| is the URL to send the request to. It must be valid. // |request_type| is the type of request to make.
diff --git a/net/url_request/url_request_context.cc b/net/url_request/url_request_context.cc index 7f93577..4b7b5547 100644 --- a/net/url_request/url_request_context.cc +++ b/net/url_request/url_request_context.cc
@@ -89,12 +89,14 @@ return &network_session->context(); } +#if (!defined(OS_WIN) && !defined(OS_LINUX)) || defined(OS_CHROMEOS) std::unique_ptr<URLRequest> URLRequestContext::CreateRequest( const GURL& url, RequestPriority priority, URLRequest::Delegate* delegate) const { return CreateRequest(url, priority, delegate, MISSING_TRAFFIC_ANNOTATION); } +#endif std::unique_ptr<URLRequest> URLRequestContext::CreateRequest( const GURL& url,
diff --git a/net/url_request/url_request_context.h b/net/url_request/url_request_context.h index 6199f94..41663f7 100644 --- a/net/url_request/url_request_context.h +++ b/net/url_request/url_request_context.h
@@ -17,6 +17,7 @@ #include "base/memory/weak_ptr.h" #include "base/threading/thread_checker.h" #include "base/trace_event/memory_dump_provider.h" +#include "build/build_config.h" #include "net/base/net_export.h" #include "net/base/request_priority.h" #include "net/http/http_network_session.h" @@ -89,12 +90,18 @@ // session. const HttpNetworkSession::Context* GetNetworkSessionContext() const; +#if (!defined(OS_WIN) && !defined(OS_LINUX)) || defined(OS_CHROMEOS) // This function should not be used in Chromium, please use the version with // NetworkTrafficAnnotationTag in the future. + // + // The unannotated method is not available on desktop Linux + Windows. It's + // available on other platforms, since we only audit network annotations on + // Linux & Windows. std::unique_ptr<URLRequest> CreateRequest( const GURL& url, RequestPriority priority, URLRequest::Delegate* delegate) const; +#endif // |traffic_annotation| is metadata about the network traffic send via this // URLRequest, see net::DefineNetworkTrafficAnnotation. Note that:
diff --git a/remoting/host/ftl_signaling_connector.cc b/remoting/host/ftl_signaling_connector.cc index 1a745ca..0c4a8f9 100644 --- a/remoting/host/ftl_signaling_connector.cc +++ b/remoting/host/ftl_signaling_connector.cc
@@ -19,6 +19,35 @@ namespace { +constexpr base::TimeDelta kBackoffResetDelay = base::TimeDelta::FromSeconds(30); +constexpr base::TimeDelta kNetworkChangeDelay = base::TimeDelta::FromSeconds(5); + +const net::BackoffEntry::Policy kBackoffPolicy = { + // Number of initial errors (in sequence) to ignore before applying + // exponential back-off rules. + 0, + + // Initial delay for exponential back-off in ms. (1s) + 1000, + + // Factor by which the waiting time will be multiplied. + 2, + + // Fuzzing percentage. ex: 10% will spread requests randomly + // between 90%-100% of the calculated time. + 0.5, + + // Maximum amount of time we are willing to delay our request in ms. (1m) + 60000, + + // Time to keep an entry from being discarded even when it + // has no significant state, -1 to never discard. + -1, + + // Starts with initial delay. + false, +}; + const char* SignalStrategyErrorToString(SignalStrategy::Error error) { switch (error) { case SignalStrategy::OK: @@ -39,7 +68,8 @@ FtlSignalStrategy* signal_strategy, base::OnceClosure auth_failed_callback) : signal_strategy_(signal_strategy), - auth_failed_callback_(std::move(auth_failed_callback)) { + auth_failed_callback_(std::move(auth_failed_callback)), + backoff_(&kBackoffPolicy) { DCHECK(signal_strategy_); DCHECK(auth_failed_callback_); net::NetworkChangeNotifier::AddNetworkChangeObserver(this); @@ -53,7 +83,7 @@ } void FtlSignalingConnector::Start() { - TryReconnect(); + TryReconnect(base::TimeDelta()); } void FtlSignalingConnector::OnSignalStrategyStateChange( @@ -63,15 +93,19 @@ if (state == SignalStrategy::CONNECTED) { HOST_LOG << "Signaling connected. New JID: " << signal_strategy_->GetLocalAddress().jid(); + backoff_reset_timer_.Start(FROM_HERE, kBackoffResetDelay, &backoff_, + &net::BackoffEntry::Reset); } else if (state == SignalStrategy::DISCONNECTED) { HOST_LOG << "Signaling disconnected. error=" << SignalStrategyErrorToString(signal_strategy_->GetError()); + backoff_reset_timer_.AbandonAndStop(); + backoff_.InformOfRequest(false); if (signal_strategy_->IsSignInError() && signal_strategy_->GetError() == SignalStrategy::AUTHENTICATION_FAILED) { std::move(auth_failed_callback_).Run(); return; } - TryReconnect(); + TryReconnect(backoff_.GetTimeUntilRelease()); } } @@ -86,14 +120,13 @@ if (type != net::NetworkChangeNotifier::CONNECTION_NONE && signal_strategy_->GetState() == SignalStrategy::DISCONNECTED) { HOST_LOG << "Network state changed to online."; - TryReconnect(); + TryReconnect(kNetworkChangeDelay); } } -void FtlSignalingConnector::TryReconnect() { +void FtlSignalingConnector::TryReconnect(base::TimeDelta delay) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - timer_.Start(FROM_HERE, base::TimeDelta(), this, - &FtlSignalingConnector::DoReconnect); + timer_.Start(FROM_HERE, delay, this, &FtlSignalingConnector::DoReconnect); } void FtlSignalingConnector::DoReconnect() {
diff --git a/remoting/host/ftl_signaling_connector.h b/remoting/host/ftl_signaling_connector.h index d930465..3dbb1b2 100644 --- a/remoting/host/ftl_signaling_connector.h +++ b/remoting/host/ftl_signaling_connector.h
@@ -8,6 +8,7 @@ #include "base/macros.h" #include "base/sequence_checker.h" #include "base/timer/timer.h" +#include "net/base/backoff_entry.h" #include "net/base/network_change_notifier.h" #include "remoting/signaling/ftl_signal_strategy.h" @@ -43,14 +44,19 @@ net::NetworkChangeNotifier::ConnectionType type) override; private: - void TryReconnect(); + void TryReconnect(base::TimeDelta delay); void DoReconnect(); FtlSignalStrategy* signal_strategy_; base::OnceClosure auth_failed_callback_; + net::BackoffEntry backoff_; base::OneShotTimer timer_; + // Timer to reset |backoff_|. We delay resetting the backoff so that we can + // treat an immediate CONNECTED->DISCONNECTED transition as failure. + base::OneShotTimer backoff_reset_timer_; + SEQUENCE_CHECKER(sequence_checker_); DISALLOW_COPY_AND_ASSIGN(FtlSignalingConnector);
diff --git a/remoting/host/signaling_connector.cc b/remoting/host/signaling_connector.cc index 397ea44..ffe1cee 100644 --- a/remoting/host/signaling_connector.cc +++ b/remoting/host/signaling_connector.cc
@@ -20,6 +20,8 @@ namespace { +constexpr base::TimeDelta kBackoffResetDelay = base::TimeDelta::FromSeconds(30); + // The delay between reconnect attempts will increase exponentially up // to the maximum specified here. const int kMaxReconnectDelaySeconds = 10 * 60; @@ -72,10 +74,12 @@ if (state == SignalStrategy::CONNECTED) { HOST_LOG << "Signaling connected. New JID: " << signal_strategy_->GetLocalAddress().jid(); - reconnect_attempts_ = 0; + backoff_reset_timer_.Start(FROM_HERE, kBackoffResetDelay, this, + &SignalingConnector::ResetBackoff); } else if (state == SignalStrategy::DISCONNECTED) { HOST_LOG << "Signaling disconnected. error=" << SignalStrategyErrorToString(signal_strategy_->GetError()); + backoff_reset_timer_.Stop(); reconnect_attempts_++; if (signal_strategy_->GetError() == SignalStrategy::AUTHENTICATION_FAILED) @@ -143,7 +147,7 @@ void SignalingConnector::ResetAndTryReconnect() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); signal_strategy_->Disconnect(); - reconnect_attempts_ = 0; + ResetBackoff(); timer_.Stop(); ScheduleTryReconnect(); } @@ -180,4 +184,9 @@ } } +void SignalingConnector::ResetBackoff() { + backoff_reset_timer_.Stop(); + reconnect_attempts_ = 0; +} + } // namespace remoting
diff --git a/remoting/host/signaling_connector.h b/remoting/host/signaling_connector.h index 3ece5ec..f0d78f3 100644 --- a/remoting/host/signaling_connector.h +++ b/remoting/host/signaling_connector.h
@@ -53,6 +53,7 @@ void ResetAndTryReconnect(); void TryReconnect(); void OnDnsBlackholeCheckerDone(bool allow); + void ResetBackoff(); XmppSignalStrategy* signal_strategy_; base::Closure auth_failed_callback_; @@ -65,6 +66,10 @@ base::OneShotTimer timer_; + // Timer to reset |backoff_|. We delay resetting the backoff so that we can + // treat an immediate CONNECTED->DISCONNECTED transition as failure. + base::OneShotTimer backoff_reset_timer_; + SEQUENCE_CHECKER(sequence_checker_); base::WeakPtrFactory<SignalingConnector> weak_factory_;
diff --git a/remoting/host/token_validator_factory_impl.cc b/remoting/host/token_validator_factory_impl.cc index 6d2a066d..b209068 100644 --- a/remoting/host/token_validator_factory_impl.cc +++ b/remoting/host/token_validator_factory_impl.cc
@@ -89,7 +89,7 @@ request_ = request_context_getter_->GetURLRequestContext()->CreateRequest( third_party_auth_config_.token_validation_url, net::DEFAULT_PRIORITY, - this); + this, MISSING_TRAFFIC_ANNOTATION); #if defined(GOOGLE_CHROME_BUILD) std::string app_name = "Chrome Remote Desktop";
diff --git a/remoting/protocol/webrtc_frame_scheduler_simple.cc b/remoting/protocol/webrtc_frame_scheduler_simple.cc index eb7f245f..db58984 100644 --- a/remoting/protocol/webrtc_frame_scheduler_simple.cc +++ b/remoting/protocol/webrtc_frame_scheduler_simple.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include "base/bind.h" +#include "base/numerics/ranges.h" #include "base/time/default_tick_clock.h" #include "remoting/base/constants.h" #include "remoting/protocol/frame_stats.h" @@ -275,8 +276,17 @@ // Ensure that the capture rate is capped by kTargetFrameInterval, to avoid // excessive CPU usage by the capturer. - target_capture_time = std::max( - target_capture_time, last_capture_started_time_ + kTargetFrameInterval); + // Also ensure that the video does not freeze for excessively long periods. + // This protects against, for example, bugs in the b/w estimator or the + // LeakyBucket implementation which may result in unbounded wait times. + // If the network is such that it really takes > 2 or 3 seconds to send one + // video frame, then this upper-bound cap could result in packet-loss, + // triggering PLI (key-frame request). But the session would be already + // unusable under such network conditions. And the client would trigger PLI + // anyway if it doesn't receive any video for > 3 seconds. + target_capture_time = base::ClampToRange( + target_capture_time, last_capture_started_time_ + kTargetFrameInterval, + last_capture_started_time_ + kKeepAliveInterval); } target_capture_time = std::max(target_capture_time, now);
diff --git a/services/audio/sync_reader.cc b/services/audio/sync_reader.cc index ed3b6a9..17889fb4 100644 --- a/services/audio/sync_reader.cc +++ b/services/audio/sync_reader.cc
@@ -218,8 +218,12 @@ } output_bus_->SetBitstreamDataSize(data_size); output_bus_->SetBitstreamFrames(bitstream_frames); + output_bus_->CopyTo(dest); + return; } - output_bus_->CopyTo(dest); + + // Copy and clip data coming across the shared memory since it's untrusted. + output_bus_->CopyAndClipTo(dest); } void SyncReader::Close() {
diff --git a/services/device/usb/usb_device_handle_usbfs.cc b/services/device/usb/usb_device_handle_usbfs.cc index 0204bd6..cc3d8e46 100644 --- a/services/device/usb/usb_device_handle_usbfs.cc +++ b/services/device/usb/usb_device_handle_usbfs.cc
@@ -450,6 +450,8 @@ // see if the handle is closed. device_->HandleClosed(this); device_ = nullptr; + // The device is no longer attached so we don't have any endpoints either. + endpoints_.clear(); // Releases |helper_|. blocking_task_runner_->PostTask( @@ -746,7 +748,10 @@ auto it = interfaces_.find(interface_number); DCHECK(it != interfaces_.end()); interfaces_.erase(it); - RefreshEndpointInfo(); + if (device_) { + // Only refresh endpoints if a device is still attached. + RefreshEndpointInfo(); + } std::move(callback).Run(true); } @@ -853,6 +858,7 @@ void UsbDeviceHandleUsbfs::RefreshEndpointInfo() { DCHECK(sequence_checker_.CalledOnValidSequence()); + DCHECK(device_); endpoints_.clear(); const UsbConfigDescriptor* config = device_->active_configuration();
diff --git a/services/identity/public/cpp/access_token_fetcher_unittest.cc b/services/identity/public/cpp/access_token_fetcher_unittest.cc index fa0942691..af9f08d 100644 --- a/services/identity/public/cpp/access_token_fetcher_unittest.cc +++ b/services/identity/public/cpp/access_token_fetcher_unittest.cc
@@ -553,7 +553,7 @@ // The URLLoaderFactory present in the pending request should match // the one we specified when creating the AccessTokenFetcher. - std::vector<FakeProfileOAuth2TokenService::PendingRequest> pending_requests = + std::vector<FakeOAuth2AccessTokenManager::PendingRequest> pending_requests = token_service()->GetPendingRequests(); EXPECT_EQ(pending_requests.size(), 1U); @@ -588,7 +588,7 @@ run_loop2.Run(); // There should be one pending request in this case too. - std::vector<FakeProfileOAuth2TokenService::PendingRequest> pending_requests2 = + std::vector<FakeOAuth2AccessTokenManager::PendingRequest> pending_requests2 = token_service()->GetPendingRequests(); EXPECT_EQ(pending_requests2.size(), 1U);
diff --git a/services/identity/public/cpp/identity_manager_unittest.cc b/services/identity/public/cpp/identity_manager_unittest.cc index 8ff3d28..2e2561b 100644 --- a/services/identity/public/cpp/identity_manager_unittest.cc +++ b/services/identity/public/cpp/identity_manager_unittest.cc
@@ -1065,7 +1065,7 @@ // The URLLoaderFactory present in the pending request should match // the one we specified when creating the AccessTokenFetcher. - std::vector<FakeProfileOAuth2TokenService::PendingRequest> pending_requests = + std::vector<FakeOAuth2AccessTokenManager::PendingRequest> pending_requests = token_service()->GetPendingRequests(); EXPECT_EQ(pending_requests.size(), 1U); EXPECT_EQ(pending_requests[0].url_loader_factory, @@ -1105,7 +1105,7 @@ run_loop2.Run(); // There should be one pending request now as well, just like before. - std::vector<FakeProfileOAuth2TokenService::PendingRequest> pending_requests2 = + std::vector<FakeOAuth2AccessTokenManager::PendingRequest> pending_requests2 = token_service()->GetPendingRequests(); EXPECT_EQ(pending_requests2.size(), 1U);
diff --git a/services/network/network_service_proxy_delegate_unittest.cc b/services/network/network_service_proxy_delegate_unittest.cc index 5a30ebd..d422b32 100644 --- a/services/network/network_service_proxy_delegate_unittest.cc +++ b/services/network/network_service_proxy_delegate_unittest.cc
@@ -7,6 +7,7 @@ #include <string> #include "base/test/scoped_task_environment.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request_test_util.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -50,7 +51,8 @@ } std::unique_ptr<net::URLRequest> CreateRequest(const GURL& url) { - return context_->CreateRequest(url, net::DEFAULT_PRIORITY, nullptr); + return context_->CreateRequest(url, net::DEFAULT_PRIORITY, nullptr, + TRAFFIC_ANNOTATION_FOR_TESTS); } void SetConfig(mojom::CustomProxyConfigPtr config) {
diff --git a/services/tracing/perfetto/system_perfetto_unittest.cc b/services/tracing/perfetto/system_perfetto_unittest.cc index 899bae8..0e628c23 100644 --- a/services/tracing/perfetto/system_perfetto_unittest.cc +++ b/services/tracing/perfetto/system_perfetto_unittest.cc
@@ -114,6 +114,7 @@ void RunUntilIdle() { scoped_task_environment_.RunUntilIdle(); } protected: + // |tmp_dir_| must be destroyed last. So must be declared first. base::ScopedTempDir tmp_dir_; std::string producer_socket_; std::string consumer_socket_; @@ -122,8 +123,7 @@ base::test::ScopedTaskEnvironment scoped_task_environment_; }; -// https://crbug.com/980247, crash on Android M. -TEST_F(SystemPerfettoTest, DISABLED_SystemTraceEndToEnd) { +TEST_F(SystemPerfettoTest, SystemTraceEndToEnd) { auto system_service = CreateMockSystemService(); // Set up the producer to talk to the system. @@ -153,8 +153,7 @@ PerfettoProducer::DeleteSoonForTesting(std::move(system_producer)); } -// https://crbug.com/980247, crash on Android M. -TEST_F(SystemPerfettoTest, DISABLED_OneSystemSourceWithMultipleLocalSources) { +TEST_F(SystemPerfettoTest, OneSystemSourceWithMultipleLocalSources) { auto system_service = CreateMockSystemService(); // Start a trace using the system Perfetto service. @@ -242,9 +241,8 @@ PerfettoProducer::DeleteSoonForTesting(std::move(system_producer)); } -// https://crbug.com/980247, crash on Android M. TEST_F(SystemPerfettoTest, - DISABLED_MultipleSystemSourceWithOneLocalSourcesLocalFirst) { + MultipleSystemSourceWithOneLocalSourcesLocalFirst) { auto system_service = CreateMockSystemService(); base::RunLoop local_no_more_packets_runloop; @@ -339,8 +337,7 @@ PerfettoProducer::DeleteSoonForTesting(std::move(system_producer)); } -// https://crbug.com/980247, crash on Android M. -TEST_F(SystemPerfettoTest, DISABLED_MultipleSystemAndLocalSources) { +TEST_F(SystemPerfettoTest, MultipleSystemAndLocalSources) { auto system_service = CreateMockSystemService(); // Start a trace using the system Perfetto service. @@ -431,8 +428,7 @@ PerfettoProducer::DeleteSoonForTesting(std::move(system_producer)); } -// https://crbug.com/980247, crash on Android M. -TEST_F(SystemPerfettoTest, DISABLED_MultipleSystemAndLocalSourcesLocalFirst) { +TEST_F(SystemPerfettoTest, MultipleSystemAndLocalSourcesLocalFirst) { auto system_service = CreateMockSystemService(); // We construct it up front so it connects to the service before the local @@ -519,8 +515,7 @@ PerfettoProducer::DeleteSoonForTesting(std::move(system_producer)); } -// https://crbug.com/980247, crash on Android M. -TEST_F(SystemPerfettoTest, DISABLED_SystemToLowAPILevel) { +TEST_F(SystemPerfettoTest, SystemToLowAPILevel) { if (base::android::BuildInfo::GetInstance()->sdk_int() >= base::android::SDK_VERSION_P) { LOG(INFO) << "Skipping SystemToLowAPILevel test, this phone supports the "
diff --git a/services/tracing/perfetto/system_test_utils.cc b/services/tracing/perfetto/system_test_utils.cc index d077c91e..830adfb 100644 --- a/services/tracing/perfetto/system_test_utils.cc +++ b/services/tracing/perfetto/system_test_utils.cc
@@ -21,9 +21,11 @@ task_runner_(std::make_unique<PerfettoTaskRunner>( base::SequencedTaskRunnerHandle::Get())) { service_ = perfetto::ServiceIPCHost::CreateInstance(task_runner_.get()); + DCHECK(service_); unlink(producer_socket.c_str()); unlink(consumer_socket.c_str()); - DCHECK(service_->Start(producer_.c_str(), consumer_.c_str())); + bool succeeded = service_->Start(producer_.c_str(), consumer_.c_str()); + DCHECK(succeeded); } MockSystemService::~MockSystemService() {
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index 833d317..5a991d4 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -20147,7 +20147,6 @@ "--gs-results-bucket=chromium-result-details", "--recover-devices" ], - "experiment_percentage": 100, "merge": { "args": [ "--bucket", @@ -22946,6 +22945,50 @@ "--bucket", "chromium-result-details", "--test-name", + "android_browsertests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] + }, + "test": "android_browsertests" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", "android_webview_unittests" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
diff --git a/testing/buildbot/chromium.chrome.json b/testing/buildbot/chromium.chrome.json deleted file mode 100644 index 81fceb6..0000000 --- a/testing/buildbot/chromium.chrome.json +++ /dev/null
@@ -1,2225 +0,0 @@ -{ - "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {}, - "AAAAA2 See generate_buildbot_json.py to make changes": {}, - "chromeos-amd64-generic-google-rel": { - "additional_compile_targets": [ - "chrome" - ] - }, - "chromeos-betty-google-rel": { - "additional_compile_targets": [ - "chromiumos_preflight" - ], - "gtest_tests": [ - { - "args": [ - "--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", - "pool": "chrome.tests.cros-vm" - } - ] - }, - "test": "aura_unittests" - }, - { - "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", - "pool": "chrome.tests.cros-vm" - } - ] - }, - "test": "base_unittests" - }, - { - "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", - "pool": "chrome.tests.cros-vm" - } - ] - }, - "test": "cacheinvalidation_unittests" - }, - { - "args": [ - "--test-launcher-jobs=1", - "--gtest_filter=-*UsingRealWebcam_CaptureMjpeg*" - ], - "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", - "pool": "chrome.tests.cros-vm" - } - ] - }, - "test": "capture_unittests" - }, - { - "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", - "pool": "chrome.tests.cros-vm" - } - ] - }, - "test": "cc_unittests" - }, - { - "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", - "pool": "chrome.tests.cros-vm" - } - ], - "idempotent": false - }, - "test": "chrome_all_tast_tests" - }, - { - "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", - "pool": "chrome.tests.cros-vm" - } - ] - }, - "test": "cros_vm_sanity_test" - }, - { - "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", - "pool": "chrome.tests.cros-vm" - } - ] - }, - "test": "crypto_unittests" - }, - { - "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", - "pool": "chrome.tests.cros-vm" - } - ] - }, - "test": "display_unittests" - }, - { - "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", - "pool": "chrome.tests.cros-vm" - } - ] - }, - "test": "google_apis_unittests" - }, - { - "args": [ - "--stop-ui", - "--dbus-stub", - "--gtest_filter=SplitViewTest.SplitViewResize" - ], - "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", - "pool": "chrome.tests.cros-vm" - } - ] - }, - "test": "interactive_ui_tests" - }, - { - "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", - "pool": "chrome.tests.cros-vm" - } - ] - }, - "test": "ipc_tests" - }, - { - "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", - "pool": "chrome.tests.cros-vm" - } - ] - }, - "test": "jingle_unittests" - }, - { - "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", - "pool": "chrome.tests.cros-vm" - } - ] - }, - "test": "latency_unittests" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/chromeos.media_unittests.filter" - ], - "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", - "pool": "chrome.tests.cros-vm" - } - ] - }, - "test": "media_unittests" - }, - { - "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", - "pool": "chrome.tests.cros-vm" - } - ] - }, - "test": "midi_unittests" - }, - { - "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", - "pool": "chrome.tests.cros-vm" - } - ] - }, - "test": "mojo_unittests" - }, - { - "args": [ - "--vpython-dir=../../vpython_dir_linux_amd64" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/luci/vpython/linux-amd64", - "location": "vpython_dir_linux_amd64", - "revision": "git_revision:9a931a5307c46b16b1c12e01e8239d4a73830b89" - } - ], - "dimension_sets": [ - { - "kvm": "1", - "os": "Ubuntu-16.04", - "pool": "chrome.tests.cros-vm" - } - ], - "shards": 3 - }, - "test": "net_unittests" - }, - { - "args": [ - "--stop-ui" - ], - "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", - "pool": "chrome.tests.cros-vm" - } - ] - }, - "test": "ozone_gl_unittests" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/chromeos.ozone_unittests.filter" - ], - "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", - "pool": "chrome.tests.cros-vm" - } - ] - }, - "test": "ozone_unittests" - }, - { - "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", - "pool": "chrome.tests.cros-vm" - } - ] - }, - "test": "pdf_unittests" - }, - { - "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", - "pool": "chrome.tests.cros-vm" - } - ] - }, - "test": "printing_unittests" - }, - { - "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", - "pool": "chrome.tests.cros-vm" - } - ] - }, - "test": "sandbox_linux_unittests" - }, - { - "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", - "pool": "chrome.tests.cros-vm" - } - ] - }, - "test": "sql_unittests" - }, - { - "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", - "pool": "chrome.tests.cros-vm" - } - ] - }, - "test": "url_unittests" - } - ], - "isolated_scripts": [ - { - "args": [ - "--browser=cros-chrome", - "--remote=127.0.0.1", - "--remote-ssh-port=9222", - "--xvfb" - ], - "isolate_name": "telemetry_perf_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "telemetry_perf_unittests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "kvm": "1", - "os": "Ubuntu-16.04", - "pool": "chrome.tests.cros-vm" - } - ], - "idempotent": false, - "shards": 6 - } - }, - { - "args": [ - "--jobs=1", - "--browser=cros-chrome", - "--remote=127.0.0.1", - "--remote-ssh-port=9222" - ], - "isolate_name": "telemetry_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "telemetry_unittests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "kvm": "1", - "os": "Ubuntu-16.04", - "pool": "chrome.tests.cros-vm" - } - ], - "idempotent": false, - "shards": 24 - } - } - ] - }, - "linux-chromeos-google-rel": { - "additional_compile_targets": [ - "chrome", - "chrome_sandbox", - "linux_symbols", - "symupload" - ], - "gtest_tests": [ - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "accessibility_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "angle_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "app_list_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "app_shell_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "ash_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "aura_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "base_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "base_util_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "blink_common_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "blink_fuzzer_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "blink_heap_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "blink_platform_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "webkit_unit_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "blink_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "boringssl_crypto_tests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "boringssl_ssl_tests" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/chromeos.browser_tests.filter" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ], - "shards": 10 - }, - "test": "browser_tests" - }, - { - "args": [ - "--enable-features=VizDisplayCompositor", - "--test-launcher-filter-file=../../testing/buildbot/filters/chromeos.browser_tests.filter" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "viz_browser_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ], - "shards": 10 - }, - "test": "browser_tests" - }, - { - "args": [ - "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0", - "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_browser_tests.filter" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "webui_html_imports_polyfill_browser_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "browser_tests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "cacheinvalidation_unittests" - }, - { - "args": [ - "--gtest_filter=-*UsingRealWebcam*" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "capture_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "cast_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "cc_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "chrome_app_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "chromedriver_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "chromeos_components_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "chromeos_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "components_browsertests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "components_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "compositor_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ], - "shards": 6 - }, - "test": "content_browsertests" - }, - { - "args": [ - "--disable-perfetto", - "--gtest_filter=TracingControllerTest.*:BackgroundTracingManagerBrowserTest.*" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "nonperfetto_content_browsertests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "content_browsertests" - }, - { - "args": [ - "--enable-features=VizDisplayCompositor" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "viz_content_browsertests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ], - "shards": 10 - }, - "test": "content_browsertests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "content_unittests" - }, - { - "args": [ - "--enable-features=VizDisplayCompositor" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "viz_content_unittests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "content_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "crypto_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "dbus_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "device_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "display_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "events_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "exo_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "extensions_browsertests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "extensions_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "filesystem_service_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "gcm_unit_tests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "gfx_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "gin_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "gl_unittests_ozone" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "google_apis_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "gpu_unittests" - }, - { - "args": [ - "--gtest_filter=-SadTabViewInteractiveUITest.ReloadMultipleSadTabs" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ], - "shards": 3 - }, - "test": "interactive_ui_tests" - }, - { - "args": [ - "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0", - "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "webui_html_imports_polyfill_interactive_ui_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "interactive_ui_tests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "ipc_tests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "jingle_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "keyboard_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "latency_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "leveldb_service_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "libjingle_xmpp_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "media_blink_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "media_service_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "media_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "message_center_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "midi_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "mojo_core_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "mojo_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "nacl_helper_nonsfi_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "nacl_loader_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "native_theme_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "net_unittests" - }, - { - "args": [ - "--ozone-platform=headless" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "ozone_gl_unittests" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/chromeos.ozone_unittests.filter" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "ozone_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "ozone_x11_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "pdf_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "perfetto_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "ppapi_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "printing_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "remoting_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "sandbox_linux_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "service_manager_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "services_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "shell_dialogs_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "skia_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "snapshot_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "sql_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "storage_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "sync_integration_tests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "traffic_annotation_auditor_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "ui_base_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "ui_chromeos_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "ui_touch_selection_unittests" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/chromeos.unit_tests.filter" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "unit_tests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "url_unittests" - }, - { - "experiment_percentage": 100, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "usage_time_limit_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "views_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "viz_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "wayland_client_perftests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "wm_unittests" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04", - "pool": "chrome.tests" - } - ] - }, - "test": "wtf_unittests" - } - ] - }, - "linux-google-rel": { - "additional_compile_targets": [ - "chrome", - "chrome/installer/linux" - ], - "isolated_scripts": [ - { - "isolate_name": "chrome_sizes", - "merge": { - "script": "//tools/perf/process_perf_results.py" - }, - "name": "chrome_sizes", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "pool": "chrome.tests" - } - ] - } - } - ] - }, - "mac-google-rel": { - "additional_compile_targets": [ - "chrome" - ], - "isolated_scripts": [ - { - "isolate_name": "chrome_sizes", - "merge": { - "script": "//tools/perf/process_perf_results.py" - }, - "name": "chrome_sizes", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.14.4", - "pool": "chrome.tests" - } - ], - "optional_dimensions": { - "300": [ - { - "os": "Mac-10.14.3" - } - ], - "600": [ - { - "os": "Mac-10.14.5" - } - ] - } - } - } - ] - }, - "win-google-rel": { - "additional_compile_targets": [ - "chrome", - "chrome_official_builder" - ], - "isolated_scripts": [ - { - "isolate_name": "chrome_sizes", - "merge": { - "script": "//tools/perf/process_perf_results.py" - }, - "name": "chrome_sizes", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Windows-10-15063", - "pool": "chrome.tests" - } - ] - } - } - ] - } -}
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index 2d6bd52..96a1493 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -2369,6 +2369,9 @@ ] }, "Android FYI 32 Vk Release (Pixel 2)": { + "additional_compile_targets": [ + "angle_apks" + ], "gtest_tests": [ { "args": [ @@ -2727,6 +2730,9 @@ ] }, "Android FYI 64 Vk Release (Pixel 2)": { + "additional_compile_targets": [ + "angle_apks" + ], "gtest_tests": [ { "args": [ @@ -11784,11 +11790,18 @@ "args": [ "--num-retries=3", "--additional-driver-flag=--enable-features=VizDisplayCompositor,UseSkiaRenderer", - "--additional-driver-flag=--use-gl=swiftshader", + "--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-features=UseSkiaRenderer", + "--additional-expectations=../../third_party/blink/web_tests/FlagExpectations/enable-gpu-rasterization" ], "isolate_name": "blink_web_tests_exparchive", "merge": { @@ -11797,7 +11810,7 @@ ], "script": "//third_party/blink/tools/merge_web_test_results.py" }, - "name": "skia_renderer_blink_web_tests", + "name": "skia_renderer_gl_blink_web_tests", "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, @@ -11863,43 +11876,6 @@ "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=swiftshader", - "--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=swiftshader", - "--additional-driver-flag=--disable-vulkan-fallback-to-gl-for-testing", - "--fuzzy-diff", - "--skipped=always", - "--test-list=../../testing/buildbot/filters/gpu.skiarenderer_vulkan_blink_web_tests.filter", - "--additional-expectations=../../third_party/blink/web_tests/FlagExpectations/use-vulkan=swiftshader" - ], - "isolate_name": "blink_web_tests_exparchive", - "merge": { - "args": [ - "--verbose" - ], - "script": "//third_party/blink/tools/merge_web_test_results.py" - }, - "name": "vulkan_swift_shader_blink_web_tests", - "results_handler": "layout tests", - "swarming": { - "can_use_on_swarming_builders": true, - "containment_type": "AUTO", - "dimension_sets": [ - { - "gpu": "nvidia-quadro-p400-ubuntu-stable", - "os": "linux-nvidia-stable", - "pool": "Chrome-GPU" - } - ] - } } ] },
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index 34d30d8e..033a41ac 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -15891,7 +15891,8 @@ { "args": [ "--gs-results-bucket=chromium-result-details", - "--recover-devices" + "--recover-devices", + "--test-launcher-filter-file=../../testing/buildbot/filters/android.asan.services_unittests.filter" ], "merge": { "args": [
diff --git a/testing/buildbot/client.v8.fyi.json b/testing/buildbot/client.v8.fyi.json index c346c260..9ddbee9b 100644 --- a/testing/buildbot/client.v8.fyi.json +++ b/testing/buildbot/client.v8.fyi.json
@@ -172,8 +172,7 @@ "${got_cr_revision}", "--test-machine-name", "${buildername}", - "--use-skia-gold", - "--stream-goldctl-output" + "--use-skia-gold" ], "experiment_percentage": 100, "isolate_name": "telemetry_gpu_integration_test", @@ -542,8 +541,7 @@ "${got_cr_revision}", "--test-machine-name", "${buildername}", - "--use-skia-gold", - "--stream-goldctl-output" + "--use-skia-gold" ], "experiment_percentage": 100, "isolate_name": "telemetry_gpu_integration_test", @@ -906,8 +904,7 @@ "${got_cr_revision}", "--test-machine-name", "${buildername}", - "--use-skia-gold", - "--stream-goldctl-output" + "--use-skia-gold" ], "experiment_percentage": 100, "isolate_name": "telemetry_gpu_integration_test", @@ -1265,8 +1262,7 @@ "${got_cr_revision}", "--test-machine-name", "${buildername}", - "--use-skia-gold", - "--stream-goldctl-output" + "--use-skia-gold" ], "experiment_percentage": 100, "isolate_name": "telemetry_gpu_integration_test", @@ -1728,8 +1724,7 @@ "${got_cr_revision}", "--test-machine-name", "${buildername}", - "--use-skia-gold", - "--stream-goldctl-output" + "--use-skia-gold" ], "experiment_percentage": 100, "isolate_name": "telemetry_gpu_integration_test",
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index 0b60cf97..d1d211b 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -105,6 +105,10 @@ "label": "//android_webview/test:android_webview_unittests", "type": "console_test_launcher", }, + "angle_apks": { + "label": "//third_party/angle:angle_apks", + "type": "additional_compile_target", + }, "angle_deqp_egl_tests": { "args": [], "label": "//third_party/angle/src/tests:angle_deqp_egl_tests",
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 6604147..85a1718a 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -26,7 +26,6 @@ 'Lollipop Tablet Tester', 'Marshmallow 64 bit Tester', 'Marshmallow Tablet Tester', - 'android-marshmallow-arm64-rel', # chromium.clang.json 'ToTAndroid', 'ToTAndroidCFI', @@ -1238,28 +1237,7 @@ }, }, }, - # TODO(https://crbug.com/977620): Remove this once the V8 bots are fixed and - # no longer need additional logging. - 'pixel_skia_gold_test': { - 'modifications': { - 'Android V8 FYI Release (Nexus 5X)': { - 'args': [ '--stream-goldctl-output' ] - }, - 'Linux V8 FYI Release (NVIDIA)': { - 'args': [ '--stream-goldctl-output' ] - }, - 'Linux V8 FYI Release - pointer compression (NVIDIA)': { - 'args': [ '--stream-goldctl-output' ] - }, - 'Mac V8 FYI Release (Intel)': { - 'args': [ '--stream-goldctl-output' ] - }, - 'Win V8 FYI Release (NVIDIA)': { - 'args': [ '--stream-goldctl-output' ] - }, - }, - }, - 'pixel_test': { + 'pixel_test':{ 'modifications': { 'Android Release (Nexus 5X)': { 'swarming': { @@ -1282,6 +1260,13 @@ ], }, 'services_unittests': { + 'modifications': { + 'android-asan': { + 'args': [ + '--test-launcher-filter-file=../../testing/buildbot/filters/android.asan.services_unittests.filter', + ], + }, + }, 'remove_from': [ # chromium.clang 'ToTLinuxMSan', # https://crbug.com/831676
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 40ad437..8a0425b 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -100,7 +100,6 @@ 'swarming': { 'shards': 1, }, - 'experiment_percentage': 100, }, 'android_webview_unittests': {}, 'breakpad_unittests': {}, @@ -3141,46 +3140,25 @@ }, 'gpu_blink_web_tests': { - 'skia_renderer_blink_web_tests': { + 'skia_renderer_gl_blink_web_tests': { # layout test failures are retried 3 times when '--test-list' is not # passed, but 0 times when '--test-list' is passed. We want to always # retry 3 times, so we explicitly specify it. 'args': [ '--num-retries=3', '--additional-driver-flag=--enable-features=VizDisplayCompositor,UseSkiaRenderer', - '--additional-driver-flag=--use-gl=swiftshader', - '--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', - ], - 'isolate_name': 'blink_web_tests_exparchive', - 'merge': { - 'args': [ - '--verbose', - ], - 'script': '//third_party/blink/tools/merge_web_test_results.py', - }, - 'results_handler': 'layout tests', - }, - 'vulkan_swift_shader_blink_web_tests': { - # layout test failures are retried 3 times when '--test-list' is not - # passed, but 0 times when '--test-list' is passed. We want to always - # retry 3 times, so we explicitly specify it. - 'args': [ - '--num-retries=3', - '--additional-driver-flag=--enable-features=VizDisplayCompositor,UseSkiaRenderer', - '--additional-driver-flag=--use-gl=swiftshader', + '--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=swiftshader', - '--additional-driver-flag=--disable-vulkan-fallback-to-gl-for-testing', + '--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/use-vulkan=swiftshader', + '--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': {
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 079924b..df795c73 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -622,87 +622,6 @@ }, }, }, - # TODO(bpastene): Remove 'chromium.chrome' when it's been switched to 'chrome' - { - 'name': 'chromium.chrome', - 'machines': { - 'chromeos-amd64-generic-google-rel': { - 'additional_compile_targets': [ - 'chrome', - ], - }, - 'chromeos-betty-google-rel': { - 'additional_compile_targets': [ - 'chromiumos_preflight', - ], - 'test_suites': { - 'gtest_tests': 'chromeos_device_friendly_gtests', - 'isolated_scripts': 'chromeos_isolated_scripts', - }, - 'swarming': { - 'dimension_sets': [ - { - 'kvm': '1', - 'os': 'Ubuntu-16.04', - 'pool': 'chrome.tests.cros-vm', - }, - ], - }, - }, - 'linux-chromeos-google-rel': { - 'additional_compile_targets': [ - 'chrome', - 'chrome_sandbox', - 'linux_symbols', - 'symupload' - ], - 'mixins': [ - 'chrome-swarming-pool', - 'linux-trusty', - ], - 'test_suites': { - 'gtest_tests': 'linux_chromeos_gtests', - }, - }, - 'linux-google-rel': { - 'additional_compile_targets': [ - 'chrome', - 'chrome/installer/linux', - ], - 'mixins': [ - 'chrome-swarming-pool', - ], - 'test_suites': { - 'isolated_scripts': 'chrome_sizes', - }, - }, - 'mac-google-rel': { - 'additional_compile_targets': [ - 'chrome', - ], - 'mixins': [ - 'chrome-swarming-pool', - 'mac_10.14', - ], - 'test_suites': { - 'isolated_scripts': 'chrome_sizes', - }, - }, - 'win-google-rel': { - 'additional_compile_targets': [ - 'chrome', - 'chrome_official_builder', - ], - 'mixins': [ - 'chrome-swarming-pool', - 'win10', - ], - 'test_suites': { - 'isolated_scripts': 'chrome_sizes', - }, - }, - }, - }, { 'name': 'chromium.chromiumos', 'machines': { @@ -2408,6 +2327,9 @@ 'pie', 'walleye', ], + 'additional_compile_targets': [ + 'angle_apks', + ], 'test_suites': { 'gtest_tests': 'gpu_angle_gtests', 'isolated_scripts': 'gpu_angle_perf_isolated_scripts', @@ -2433,6 +2355,9 @@ 'pie', 'walleye', ], + 'additional_compile_targets': [ + 'angle_apks', + ], 'test_suites': { 'gtest_tests': 'gpu_angle_gtests', 'isolated_scripts': 'gpu_angle_perf_isolated_scripts',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 0fde556..b562f0e 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -574,19 +574,6 @@ ] } ] - }, - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "AudioServiceStreams", - "enable_features": [ - "AudioServiceAudioStreams" - ] - } - ] } ], "AudioServiceOutOfProcessSandboxApmMac": [ @@ -1445,22 +1432,6 @@ ] } ], - "ClearOldOnDemandFavicons": [ - { - "platforms": [ - "android", - "ios" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "ClearOldOnDemandFavicons" - ] - } - ] - } - ], "ClipboardContentBehavior": [ { "platforms": [ @@ -3526,7 +3497,6 @@ "UIVerticalMargin": "10" }, "enable_features": [ - "OmniboxDedupeGoogleDriveURLs", "OmniboxDisplayTitleForCurrentUrl", "OmniboxDocumentProvider", "OmniboxGroupSuggestionsBySearchVsUrl",
diff --git a/third_party/.gitignore b/third_party/.gitignore index 8d544dc..c21d7d8 100644 --- a/third_party/.gitignore +++ b/third_party/.gitignore
@@ -81,7 +81,6 @@ /fuchsia-sdk/images /fuchsia-sdk/sdk /gestures/gestures -/gles1_conform /gles2_conform /glfw/src /glslang/src
diff --git a/third_party/blink/public/mojom/payments/payment_app.mojom b/third_party/blink/public/mojom/payments/payment_app.mojom index 567f572..4b88899 100644 --- a/third_party/blink/public/mojom/payments/payment_app.mojom +++ b/third_party/blink/public/mojom/payments/payment_app.mojom
@@ -33,6 +33,7 @@ PAYMENT_DETAILS_NOT_OBJECT, PAYMENT_EVENT_BROWSER_ERROR, PAYMENT_EVENT_TIMEOUT, + PAYMENT_HANDLER_INSECURE_NAVIGATION, }; // This struct is provided to hold a payment instrument from render
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom index 57b0633..adbd4e62 100644 --- a/third_party/blink/public/mojom/web_feature/web_feature.mojom +++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -2328,6 +2328,16 @@ kCreateObjectURLMediaSourceFromWorker = 2939, kCSSAtRuleProperty = 2940, kServiceWorkerInterceptedRequestFromOriginDirtyStyleSheet = 2941, + kWebkitMarginBeforeCollapseDiscard = 2942, + kWebkitMarginBeforeCollapseSeparate = 2943, + kWebkitMarginBeforeCollapseSeparateMaybeDoesSomething = 2944, + kWebkitMarginAfterCollapseDiscard = 2945, + kWebkitMarginAfterCollapseSeparate = 2946, + kWebkitMarginAfterCollapseSeparateMaybeDoesSomething = 2947, + kCredentialManagerCreateWithUVM = 2948, + kCredentialManagerGetWithUVM = 2949, + kCredentialManagerCreateSuccessWithUVM = 2950, + kCredentialManagerGetSuccessWithUVM = 2951, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/public/platform/task_type.h b/third_party/blink/public/platform/task_type.h index c3a709b..c258f61 100644 --- a/third_party/blink/public/platform/task_type.h +++ b/third_party/blink/public/platform/task_type.h
@@ -130,9 +130,9 @@ // Tasks used for DedicatedWorker's requestAnimationFrame. kWorkerAnimation = 51, - // For tasks started with the experimental Scheduling API - kExperimentalWebSchedulingUserInteraction = 53, - kExperimentalWebSchedulingBestEffort = 54, + // Obsolete. + // kExperimentalWebSchedulingUserInteraction = 53, + // kExperimentalWebSchedulingBestEffort = 54, // https://drafts.csswg.org/css-font-loading/#task-source kFontLoading = 56,
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h index 37e738e..5a76012 100644 --- a/third_party/blink/public/platform/web_runtime_features.h +++ b/third_party/blink/public/platform/web_runtime_features.h
@@ -85,7 +85,6 @@ BLINK_PLATFORM_EXPORT static void EnableAutomaticLazyImageLoading(bool); BLINK_PLATFORM_EXPORT static void EnableBackgroundFetch(bool); BLINK_PLATFORM_EXPORT static void EnableBlinkHeapIncrementalMarking(bool); - BLINK_PLATFORM_EXPORT static void EnableBloatedRendererDetection(bool); BLINK_PLATFORM_EXPORT static void EnableBlockingFocusWithoutUserActivation( bool); BLINK_PLATFORM_EXPORT static void EnableCacheInlineScriptCode(bool);
diff --git a/third_party/blink/renderer/bindings/core/v8/BUILD.gn b/third_party/blink/renderer/bindings/core/v8/BUILD.gn index d8da6a0..bc35093 100644 --- a/third_party/blink/renderer/bindings/core/v8/BUILD.gn +++ b/third_party/blink/renderer/bindings/core/v8/BUILD.gn
@@ -180,8 +180,6 @@ "$bindings_core_v8_output_dir/v8_resize_observer_callback.h", "$bindings_core_v8_output_dir/v8_scroll_state_callback.cc", "$bindings_core_v8_output_dir/v8_scroll_state_callback.h", - "$bindings_core_v8_output_dir/v8_task_queue_post_callback.cc", - "$bindings_core_v8_output_dir/v8_task_queue_post_callback.h", "$bindings_core_v8_output_dir/v8_void_function.cc", "$bindings_core_v8_output_dir/v8_void_function.h", ]
diff --git a/third_party/blink/renderer/bindings/core/v8/source_location.cc b/third_party/blink/renderer/bindings/core/v8/source_location.cc index 3585c18..35c9508 100644 --- a/third_party/blink/renderer/bindings/core/v8/source_location.cc +++ b/third_party/blink/renderer/bindings/core/v8/source_location.cc
@@ -181,7 +181,13 @@ std::unique_ptr<v8_inspector::protocol::Runtime::API::StackTrace> SourceLocation::BuildInspectorObject() const { - return stack_trace_ ? stack_trace_->buildInspectorObject() : nullptr; + return BuildInspectorObject(std::numeric_limits<int>::max()); +} + +std::unique_ptr<v8_inspector::protocol::Runtime::API::StackTrace> +SourceLocation::BuildInspectorObject(int max_async_depth) const { + return stack_trace_ ? stack_trace_->buildInspectorObject(max_async_depth) + : nullptr; } String SourceLocation::ToString() const {
diff --git a/third_party/blink/renderer/bindings/core/v8/source_location.h b/third_party/blink/renderer/bindings/core/v8/source_location.h index 5d14e3e..3126e04 100644 --- a/third_party/blink/renderer/bindings/core/v8/source_location.h +++ b/third_party/blink/renderer/bindings/core/v8/source_location.h
@@ -58,8 +58,8 @@ return std::move(stack_trace_); } - std::unique_ptr<SourceLocation> Clone() - const; // Safe to pass between threads. + // Safe to pass between threads, drops async chain in stack trace. + std::unique_ptr<SourceLocation> Clone() const; // No-op when stack trace is unknown. void ToTracedValue(TracedValue*, const char* name) const; @@ -71,6 +71,9 @@ std::unique_ptr<v8_inspector::protocol::Runtime::API::StackTrace> BuildInspectorObject() const; + std::unique_ptr<v8_inspector::protocol::Runtime::API::StackTrace> + BuildInspectorObject(int max_async_depth) const; + private: static std::unique_ptr<SourceLocation> CreateFromNonEmptyV8StackTrace( std::unique_ptr<v8_inspector::V8StackTrace>,
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc index 82bfcb5..d4fcac3 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
@@ -40,6 +40,7 @@ #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/bindings/core/v8/source_location.h" +#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script.h" #include "third_party/blink/renderer/bindings/core/v8/use_counter_callback.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_context_snapshot.h" @@ -59,6 +60,7 @@ #include "third_party/blink/renderer/core/inspector/main_thread_debugger.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/script/modulator.h" +#include "third_party/blink/renderer/core/trustedtypes/trusted_types_util.h" #include "third_party/blink/renderer/core/workers/worker_global_scope.h" #include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h" #include "third_party/blink/renderer/platform/bindings/v8_per_context_data.h" @@ -348,7 +350,8 @@ WrapperTypeInfo::Unwrap(data), holder); } -static bool CodeGenerationCheckCallbackInMainThread( +// Check whether Content Security Policy allows script execution. +static bool ContentSecurityPolicyCodeGenerationCheck( v8::Local<v8::Context> context, v8::Local<v8::String> source) { if (ExecutionContext* execution_context = ToExecutionContext(context)) { @@ -370,6 +373,53 @@ return false; } +static v8::MaybeLocal<v8::String> TrustedTypesCodeGenerationCheck( + v8::Local<v8::Context> context, + v8::Local<v8::Value> source) { + ExceptionState exception_state(context->GetIsolate(), + ExceptionState::kExecutionContext, "eval", ""); + StringOrTrustedScript string_or_trusted_script; + V8StringOrTrustedScript::ToImpl( + context->GetIsolate(), source, string_or_trusted_script, + UnionTypeConversionMode::kNotNullable, exception_state); + + String modified_source = GetStringFromTrustedScript( + string_or_trusted_script, ToExecutionContext(context), exception_state); + if (exception_state.HadException()) { + exception_state.ClearException(); + return v8::MaybeLocal<v8::String>(); + } + + return V8String(context->GetIsolate(), modified_source); +} + +static v8::MaybeLocal<v8::String> CodeGenerationCheckCallbackInMainThread( + v8::Local<v8::Context> context, + v8::Local<v8::Value> source) { + bool allowed_by_csp = + source->IsString() && ContentSecurityPolicyCodeGenerationCheck( + context, source.As<v8::String>()); + // Without trusted types, we decide based on CSP. + if (!RequireTrustedTypesCheck(ToExecutionContext(context))) { + if (allowed_by_csp) + return source.As<v8::String>(); + return v8::MaybeLocal<v8::String>(); + } + + // With Trusted Types, we pass when either CSP or TT allow the value. + // We will always run the TT check because of reporting, and because a + // default policy might want to modify the string. + v8::MaybeLocal<v8::String> trusted_types_string = + TrustedTypesCodeGenerationCheck(context, source); + if (allowed_by_csp || !trusted_types_string.IsEmpty()) { + if (trusted_types_string.IsEmpty()) { + return source.As<v8::String>(); + } + return trusted_types_string; + } + return v8::MaybeLocal<v8::String>(); +} + static bool WasmCodeGenerationCheckCallbackInMainThread( v8::Local<v8::Context> context, v8::Local<v8::String> source) { @@ -647,7 +697,7 @@ v8::Isolate::kMessageLog); isolate->SetFailedAccessCheckCallbackFunction( FailedAccessCheckCallbackInMainThread); - isolate->SetAllowCodeGenerationFromStringsCallback( + isolate->SetModifyCodeGenerationFromStringsCallback( CodeGenerationCheckCallbackInMainThread); isolate->SetAllowWasmCodeGenerationCallback( WasmCodeGenerationCheckCallbackInMainThread);
diff --git a/third_party/blink/renderer/core/animation/compositor_animations.cc b/third_party/blink/renderer/core/animation/compositor_animations.cc index fb2a8fa..8dc50ef3 100644 --- a/third_party/blink/renderer/core/animation/compositor_animations.cc +++ b/third_party/blink/renderer/core/animation/compositor_animations.cc
@@ -336,37 +336,27 @@ if (!Platform::Current()->IsThreadedAnimationEnabled()) reasons |= kAcceleratedAnimationsDisabled; - LayoutObject* layout_object = target_element.GetLayoutObject(); - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { + if (const auto* layout_object = target_element.GetLayoutObject()) { // We query paint property tree state below to determine whether the - // animation is compositable. There is a known lifecycle violation where an - // animation can be cancelled during style update. See - // CompositorAnimations::cancelAnimationOnCompositor and - // http://crbug.com/676456. When this is fixed we would like to enable - // the DCHECK below. - // DCHECK(document().lifecycle().state() >= - // DocumentLifecycle::PrePaintClean); - DCHECK(layout_object); - - if (!layout_object->UniqueId()) - reasons |= kTargetHasInvalidCompositingState; - + // animation is compositable. TODO(crbug.com/676456): There is a known + // lifecycle violation where an animation can be cancelled during style + // update. See CompositorAnimations::CancelAnimationOnCompositor(). + // When this is fixed we would like to enable the DCHECK below. + // DCHECK_GE(GetDocument().Lifecycle().GetState(), + // DocumentLifecycle::kPrePaintClean); + bool has_direct_compositing_reasons = false; if (const auto* paint_properties = layout_object->FirstFragment().PaintProperties()) { - const TransformPaintPropertyNode* transform_node = - paint_properties->Transform(); - const EffectPaintPropertyNode* effect_node = paint_properties->Effect(); - bool has_direct_compositing_reasons = - (transform_node && transform_node->HasDirectCompositingReasons()) || - (effect_node && effect_node->HasDirectCompositingReasons()); - if (!has_direct_compositing_reasons) - reasons |= kTargetHasInvalidCompositingState; + const auto* transform = paint_properties->Transform(); + const auto* effect = paint_properties->Effect(); + has_direct_compositing_reasons = + (transform && transform->HasDirectCompositingReasons()) || + (effect && effect->HasDirectCompositingReasons()); } - } else { - if (!layout_object || - layout_object->GetCompositingState() != kPaintsIntoOwnBacking) { + if (!has_direct_compositing_reasons) reasons |= kTargetHasInvalidCompositingState; - } + } else { + reasons |= kTargetHasInvalidCompositingState; } return reasons; @@ -482,11 +472,6 @@ const Animation& animation, int id, double pause_time) { - // FIXME: CheckCanStartAnimationOnCompositor queries compositingState, which - // is not necessarily up to date. - // https://code.google.com/p/chromium/issues/detail?id=339847 - DisableCompositingQueryAsserts disabler; - DCHECK_EQ(CheckCanStartElementOnCompositor(element), kNoFailure); CompositorAnimation* compositor_animation = animation.GetCompositorAnimation();
diff --git a/third_party/blink/renderer/core/animation/compositor_animations_test.cc b/third_party/blink/renderer/core/animation/compositor_animations_test.cc index 58bc43b8..2f5080e 100644 --- a/third_party/blink/renderer/core/animation/compositor_animations_test.cc +++ b/third_party/blink/renderer/core/animation/compositor_animations_test.cc
@@ -1645,11 +1645,9 @@ } } // namespace + TEST_P(AnimationCompositorAnimationsTest, CanStartElementOnCompositorTransformBasedOnPaintProperties) { - if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - return; - Persistent<Element> element = GetDocument().CreateElementForBinding("shared"); LayoutObjectProxy* layout_object = LayoutObjectProxy::Create(element.Get()); layout_object->EnsureIdForTestingProxy(); @@ -1682,9 +1680,6 @@ TEST_P(AnimationCompositorAnimationsTest, CanStartElementOnCompositorEffectBasedOnPaintProperties) { - if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - return; - Persistent<Element> element = GetDocument().CreateElementForBinding("shared"); LayoutObjectProxy* layout_object = LayoutObjectProxy::Create(element.Get()); layout_object->EnsureIdForTestingProxy(); @@ -1780,8 +1775,9 @@ } TEST_P(AnimationCompositorAnimationsTest, CompositedTransformAnimation) { - // TODO(wangxianzhu): Fix this test for CompositeAfterPaint. - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) + if (!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled() || + // TODO(wangxianzhu): Fix this test for CompositeAfterPaint. + RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) return; LoadTestData("transform-animation.html"); @@ -1792,22 +1788,20 @@ ASSERT_NE(nullptr, properties); const auto* transform = properties->Transform(); ASSERT_NE(nullptr, transform); - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() || - RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) { - EXPECT_TRUE(transform->HasDirectCompositingReasons()); - EXPECT_TRUE(transform->HasActiveTransformAnimation()); - // Make sure the animation state is initialized in paint properties. - auto* property_trees = - document->View()->RootCcLayer()->layer_tree_host()->property_trees(); - auto* cc_transform = property_trees->transform_tree.Node( - property_trees->element_id_to_transform_node_index - [transform->GetCompositorElementId()]); - ASSERT_NE(nullptr, cc_transform); - EXPECT_TRUE(cc_transform->has_potential_animation); - EXPECT_TRUE(cc_transform->is_currently_animating); - EXPECT_EQ(cc::kNotScaled, cc_transform->starting_animation_scale); - EXPECT_EQ(cc::kNotScaled, cc_transform->maximum_animation_scale); - } + EXPECT_TRUE(transform->HasDirectCompositingReasons()); + EXPECT_TRUE(transform->HasActiveTransformAnimation()); + + // Make sure the animation state is initialized in paint properties. + auto* property_trees = + document->View()->RootCcLayer()->layer_tree_host()->property_trees(); + auto* cc_transform = property_trees->transform_tree.Node( + property_trees->element_id_to_transform_node_index + [transform->GetCompositorElementId()]); + ASSERT_NE(nullptr, cc_transform); + EXPECT_TRUE(cc_transform->has_potential_animation); + EXPECT_TRUE(cc_transform->is_currently_animating); + EXPECT_EQ(cc::kNotScaled, cc_transform->starting_animation_scale); + EXPECT_EQ(cc::kNotScaled, cc_transform->maximum_animation_scale); // Make sure the animation is started on the compositor. EXPECT_EQ(CheckCanStartElementOnCompositor(*target), @@ -1819,8 +1813,9 @@ } TEST_P(AnimationCompositorAnimationsTest, CompositedScaleAnimation) { - // TODO(wangxianzhu): Fix this test for CompositeAfterPaint. - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) + if (!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled() || + // TODO(wangxianzhu): Fix this test for CompositeAfterPaint. + RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) return; LoadTestData("scale-animation.html"); @@ -1831,22 +1826,20 @@ ASSERT_NE(nullptr, properties); const auto* transform = properties->Transform(); ASSERT_NE(nullptr, transform); - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() || - RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) { - EXPECT_TRUE(transform->HasDirectCompositingReasons()); - EXPECT_TRUE(transform->HasActiveTransformAnimation()); - // Make sure the animation state is initialized in paint properties. - auto* property_trees = - document->View()->RootCcLayer()->layer_tree_host()->property_trees(); - auto* cc_transform = property_trees->transform_tree.Node( - property_trees->element_id_to_transform_node_index - [transform->GetCompositorElementId()]); - ASSERT_NE(nullptr, cc_transform); - EXPECT_TRUE(cc_transform->has_potential_animation); - EXPECT_TRUE(cc_transform->is_currently_animating); - EXPECT_EQ(2.f, cc_transform->starting_animation_scale); - EXPECT_EQ(5.f, cc_transform->maximum_animation_scale); - } + EXPECT_TRUE(transform->HasDirectCompositingReasons()); + EXPECT_TRUE(transform->HasActiveTransformAnimation()); + + // Make sure the animation state is initialized in paint properties. + auto* property_trees = + document->View()->RootCcLayer()->layer_tree_host()->property_trees(); + auto* cc_transform = property_trees->transform_tree.Node( + property_trees->element_id_to_transform_node_index + [transform->GetCompositorElementId()]); + ASSERT_NE(nullptr, cc_transform); + EXPECT_TRUE(cc_transform->has_potential_animation); + EXPECT_TRUE(cc_transform->is_currently_animating); + EXPECT_EQ(2.f, cc_transform->starting_animation_scale); + EXPECT_EQ(5.f, cc_transform->maximum_animation_scale); // Make sure the animation is started on the compositor. EXPECT_EQ(CheckCanStartElementOnCompositor(*target),
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 f391fd95..f83470e4 100644 --- a/third_party/blink/renderer/core/animation/css/css_animations.cc +++ b/third_party/blink/renderer/core/animation/css/css_animations.cc
@@ -494,12 +494,6 @@ previous_active_interpolations_for_standard_animations_.swap( pending_update_.ActiveInterpolationsForStandardAnimations()); - // FIXME: cancelling, pausing, unpausing animations all query - // compositingState, which is not necessarily up to date here - // since we call this from recalc style. - // https://code.google.com/p/chromium/issues/detail?id=339847 - DisableCompositingQueryAsserts disabler; - for (wtf_size_t paused_index : pending_update_.AnimationIndicesWithPauseToggled()) { Animation& animation = *running_animations_[paused_index]->animation;
diff --git a/third_party/blink/renderer/core/animation/css_angle_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_angle_interpolation_type.cc index c0db244..832abb8 100644 --- a/third_party/blink/renderer/core/animation/css_angle_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_angle_interpolation_type.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/core/animation/css_angle_interpolation_type.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" namespace blink { @@ -29,8 +30,8 @@ const InterpolableValue& value, const NonInterpolableValue*, const StyleResolverState&) const { - return CSSPrimitiveValue::Create(ToInterpolableNumber(value).Value(), - CSSPrimitiveValue::UnitType::kDegrees); + return CSSNumericLiteralValue::Create(ToInterpolableNumber(value).Value(), + CSSPrimitiveValue::UnitType::kDegrees); } } // namespace blink
diff --git a/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc index 9addee20..5bc7819 100644 --- a/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc
@@ -8,6 +8,7 @@ #include "base/memory/ptr_util.h" #include "third_party/blink/renderer/core/css/css_crossfade_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/css_property_names.h" #include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h" @@ -59,8 +60,8 @@ return end_; return MakeGarbageCollected<cssvalue::CSSCrossfadeValue>( start_, end_, - CSSPrimitiveValue::Create(progress, - CSSPrimitiveValue::UnitType::kNumber)); + CSSNumericLiteralValue::Create(progress, + CSSPrimitiveValue::UnitType::kNumber)); } DECLARE_NON_INTERPOLABLE_VALUE_TYPE();
diff --git a/third_party/blink/renderer/core/animation/css_number_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_number_interpolation_type.cc index 303f5ab..54893a3 100644 --- a/third_party/blink/renderer/core/animation/css_number_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_number_interpolation_type.cc
@@ -9,6 +9,7 @@ #include "base/memory/ptr_util.h" #include "base/optional.h" #include "third_party/blink/renderer/core/animation/number_property_functions.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/resolver/style_builder.h" #include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h" @@ -38,8 +39,9 @@ const NonInterpolableValue*, const StyleResolverState&) const { double number = ToInterpolableNumber(value).Value(); - return CSSPrimitiveValue::Create(round_to_integer_ ? round(number) : number, - CSSPrimitiveValue::UnitType::kNumber); + return CSSNumericLiteralValue::Create( + round_to_integer_ ? round(number) : number, + CSSPrimitiveValue::UnitType::kNumber); } InterpolationValue CSSNumberInterpolationType::CreateNumberValue( @@ -105,11 +107,12 @@ double clamped_number = NumberPropertyFunctions::ClampNumber( CssProperty(), ToInterpolableNumber(interpolable_value).Value()); if (!NumberPropertyFunctions::SetNumber(CssProperty(), *state.Style(), - clamped_number)) + clamped_number)) { StyleBuilder::ApplyProperty( GetProperty().GetCSSProperty(), state, - *CSSPrimitiveValue::Create(clamped_number, - CSSPrimitiveValue::UnitType::kNumber)); + *CSSNumericLiteralValue::Create(clamped_number, + CSSPrimitiveValue::UnitType::kNumber)); + } } } // namespace blink
diff --git a/third_party/blink/renderer/core/animation/css_resolution_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_resolution_interpolation_type.cc index af862cd3..3b8b3af 100644 --- a/third_party/blink/renderer/core/animation/css_resolution_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_resolution_interpolation_type.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/core/animation/css_resolution_interpolation_type.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" namespace blink { @@ -30,8 +31,9 @@ const InterpolableValue& value, const NonInterpolableValue*, const StyleResolverState&) const { - return CSSPrimitiveValue::Create(ToInterpolableNumber(value).Value(), - CSSPrimitiveValue::UnitType::kDotsPerPixel); + return CSSNumericLiteralValue::Create( + ToInterpolableNumber(value).Value(), + CSSPrimitiveValue::UnitType::kDotsPerPixel); } } // namespace blink
diff --git a/third_party/blink/renderer/core/animation/css_time_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_time_interpolation_type.cc index 1b1980d..6f41dba 100644 --- a/third_party/blink/renderer/core/animation/css_time_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_time_interpolation_type.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/core/animation/css_time_interpolation_type.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" namespace blink { @@ -29,8 +30,8 @@ const InterpolableValue& value, const NonInterpolableValue*, const StyleResolverState&) const { - return CSSPrimitiveValue::Create(ToInterpolableNumber(value).Value(), - CSSPrimitiveValue::UnitType::kSeconds); + return CSSNumericLiteralValue::Create(ToInterpolableNumber(value).Value(), + CSSPrimitiveValue::UnitType::kSeconds); } } // namespace blink
diff --git a/third_party/blink/renderer/core/animation/css_transform_origin_interpolation_type.h b/third_party/blink/renderer/core/animation/css_transform_origin_interpolation_type.h index 1dd8f99d..a26c050 100644 --- a/third_party/blink/renderer/core/animation/css_transform_origin_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_transform_origin_interpolation_type.h
@@ -9,6 +9,7 @@ #include "third_party/blink/renderer/core/animation/css_position_axis_list_interpolation_type.h" #include "third_party/blink/renderer/core/animation/length_interpolation_functions.h" #include "third_party/blink/renderer/core/animation/list_interpolation_functions.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_value_list.h" namespace blink { @@ -29,7 +30,7 @@ 3, [&list](wtf_size_t index) { if (index == list.length()) { return LengthInterpolationFunctions::MaybeConvertCSSValue( - *CSSPrimitiveValue::Create( + *CSSNumericLiteralValue::Create( 0, CSSPrimitiveValue::UnitType::kPixels)); } const CSSValue& item = list.Item(index);
diff --git a/third_party/blink/renderer/core/animation/keyframe_effect.cc b/third_party/blink/renderer/core/animation/keyframe_effect.cc index 3881c11..a6b9953 100644 --- a/third_party/blink/renderer/core/animation/keyframe_effect.cc +++ b/third_party/blink/renderer/core/animation/keyframe_effect.cc
@@ -275,10 +275,6 @@ bool KeyframeEffect::CancelAnimationOnCompositor( CompositorAnimation* compositor_animation) { - // FIXME: cancelAnimationOnCompositor is called from withins style recalc. - // This queries compositingState, which is not necessarily up to date. - // https://code.google.com/p/chromium/issues/detail?id=339847 - DisableCompositingQueryAsserts disabler; if (!HasActiveAnimationsOnCompositor()) return false; if (!target_ || !target_->GetLayoutObject())
diff --git a/third_party/blink/renderer/core/animation/length_interpolation_functions.cc b/third_party/blink/renderer/core/animation/length_interpolation_functions.cc index 6e7df16..8125dac 100644 --- a/third_party/blink/renderer/core/animation/length_interpolation_functions.cc +++ b/third_party/blink/renderer/core/animation/length_interpolation_functions.cc
@@ -5,6 +5,8 @@ #include "third_party/blink/renderer/core/animation/length_interpolation_functions.h" #include "third_party/blink/renderer/core/css/css_calculation_value.h" +#include "third_party/blink/renderer/core/css/css_math_function_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h" #include "third_party/blink/renderer/platform/geometry/calculation_value.h" @@ -212,7 +214,7 @@ CSSLengthNonInterpolableValue::HasPercentage(non_interpolable_value); CSSCalcExpressionNode* root_node = nullptr; - CSSPrimitiveValue* first_value = nullptr; + CSSNumericLiteralValue* first_value = nullptr; for (wtf_size_t i = 0; i < CSSPrimitiveValue::kLengthUnitTypeCount; i++) { double value = ToInterpolableNumber(*interpolable_list.Get(i)).Value(); @@ -220,8 +222,8 @@ (i != CSSPrimitiveValue::kUnitTypePercentage || !has_percentage)) { continue; } - CSSPrimitiveValue* current_value = - CSSPrimitiveValue::Create(value, IndexToUnitType(i)); + CSSNumericLiteralValue* current_value = + CSSNumericLiteralValue::Create(value, IndexToUnitType(i)); if (!first_value) { DCHECK(!root_node); @@ -238,12 +240,13 @@ } if (root_node) { - return CSSPrimitiveValue::Create(CSSCalcValue::Create(root_node)); + return CSSMathFunctionValue::Create(CSSCalcValue::Create(root_node)); } if (first_value) { return first_value; } - return CSSPrimitiveValue::Create(0, CSSPrimitiveValue::UnitType::kPixels); + return CSSNumericLiteralValue::Create(0, + CSSPrimitiveValue::UnitType::kPixels); } } // namespace blink
diff --git a/third_party/blink/renderer/core/core_idl_files.gni b/third_party/blink/renderer/core/core_idl_files.gni index a22c8098..37bf162 100644 --- a/third_party/blink/renderer/core/core_idl_files.gni +++ b/third_party/blink/renderer/core/core_idl_files.gni
@@ -129,8 +129,6 @@ "dom/node_list.idl", "dom/processing_instruction.idl", "dom/range.idl", - "dom/scripted_task_queue.idl", - "dom/scripted_task_queue_controller.idl", "dom/static_range.idl", "dom/text.idl", "dom/tree_walker.idl",
diff --git a/third_party/blink/renderer/core/css/BUILD.gn b/third_party/blink/renderer/core/css/BUILD.gn index 997ce670..9375ce6 100644 --- a/third_party/blink/renderer/core/css/BUILD.gn +++ b/third_party/blink/renderer/core/css/BUILD.gn
@@ -108,12 +108,16 @@ "css_layout_function_value.h", "css_markup.cc", "css_markup.h", + "css_math_function_value.cc", + "css_math_function_value.h", "css_math_operator.cc", "css_math_operator.h", "css_media_rule.cc", "css_media_rule.h", "css_namespace_rule.cc", "css_namespace_rule.h", + "css_numeric_literal_value.cc", + "css_numeric_literal_value.h", "css_origin_clean.h", "css_page_rule.cc", "css_page_rule.h",
diff --git a/third_party/blink/renderer/core/css/basic_shape_functions.cc b/third_party/blink/renderer/core/css/basic_shape_functions.cc index a9c160dd..f6418d3 100644 --- a/third_party/blink/renderer/core/css/basic_shape_functions.cc +++ b/third_party/blink/renderer/core/css/basic_shape_functions.cc
@@ -31,6 +31,7 @@ #include "third_party/blink/renderer/core/css/css_basic_shape_values.h" #include "third_party/blink/renderer/core/css/css_identifier_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value_mappings.h" #include "third_party/blink/renderer/core/css/css_ray_value.h" #include "third_party/blink/renderer/core/css/css_value_pair.h" @@ -122,8 +123,8 @@ case BasicShape::kStyleRayType: { const StyleRay& ray = To<StyleRay>(*basic_shape); return MakeGarbageCollected<cssvalue::CSSRayValue>( - *CSSPrimitiveValue::Create(ray.Angle(), - CSSPrimitiveValue::UnitType::kDegrees), + *CSSNumericLiteralValue::Create( + ray.Angle(), CSSPrimitiveValue::UnitType::kDegrees), *CSSIdentifierValue::Create(RaySizeToKeyword(ray.Size())), (ray.Contain() ? CSSIdentifierValue::Create(CSSValueID::kContain) : nullptr)); @@ -169,8 +170,10 @@ const Vector<Length>& values = polygon->Values(); for (unsigned i = 0; i < values.size(); i += 2) { polygon_value->AppendPoint( - CSSPrimitiveValue::Create(values.at(i), style.EffectiveZoom()), - CSSPrimitiveValue::Create(values.at(i + 1), style.EffectiveZoom())); + CSSPrimitiveValue::CreateFromLength(values.at(i), + style.EffectiveZoom()), + CSSPrimitiveValue::CreateFromLength(values.at(i + 1), + style.EffectiveZoom())); } return polygon_value; } @@ -179,14 +182,14 @@ auto* inset_value = MakeGarbageCollected<cssvalue::CSSBasicShapeInsetValue>(); - inset_value->SetTop( - CSSPrimitiveValue::Create(inset->Top(), style.EffectiveZoom())); - inset_value->SetRight( - CSSPrimitiveValue::Create(inset->Right(), style.EffectiveZoom())); - inset_value->SetBottom( - CSSPrimitiveValue::Create(inset->Bottom(), style.EffectiveZoom())); - inset_value->SetLeft( - CSSPrimitiveValue::Create(inset->Left(), style.EffectiveZoom())); + inset_value->SetTop(CSSPrimitiveValue::CreateFromLength( + inset->Top(), style.EffectiveZoom())); + inset_value->SetRight(CSSPrimitiveValue::CreateFromLength( + inset->Right(), style.EffectiveZoom())); + inset_value->SetBottom(CSSPrimitiveValue::CreateFromLength( + inset->Bottom(), style.EffectiveZoom())); + inset_value->SetLeft(CSSPrimitiveValue::CreateFromLength( + inset->Left(), style.EffectiveZoom())); inset_value->SetTopLeftRadius( ValueForLengthSize(inset->TopLeftRadius(), style));
diff --git a/third_party/blink/renderer/core/css/css_axis_value.cc b/third_party/blink/renderer/core/css/css_axis_value.cc index b0183b8..81e2585 100644 --- a/third_party/blink/renderer/core/css/css_axis_value.cc +++ b/third_party/blink/renderer/core/css/css_axis_value.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/css/css_axis_value.h" #include "third_party/blink/renderer/core/css/css_identifier_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" @@ -32,9 +33,12 @@ default: NOTREACHED(); } - Append(*CSSPrimitiveValue::Create(x, CSSPrimitiveValue::UnitType::kNumber)); - Append(*CSSPrimitiveValue::Create(y, CSSPrimitiveValue::UnitType::kNumber)); - Append(*CSSPrimitiveValue::Create(z, CSSPrimitiveValue::UnitType::kNumber)); + Append( + *CSSNumericLiteralValue::Create(x, CSSPrimitiveValue::UnitType::kNumber)); + Append( + *CSSNumericLiteralValue::Create(y, CSSPrimitiveValue::UnitType::kNumber)); + Append( + *CSSNumericLiteralValue::Create(z, CSSPrimitiveValue::UnitType::kNumber)); } CSSAxisValue::CSSAxisValue(double x, double y, double z) @@ -51,9 +55,12 @@ z = 1; axis_name_ = CSSValueID::kZ; } - Append(*CSSPrimitiveValue::Create(x, CSSPrimitiveValue::UnitType::kNumber)); - Append(*CSSPrimitiveValue::Create(y, CSSPrimitiveValue::UnitType::kNumber)); - Append(*CSSPrimitiveValue::Create(z, CSSPrimitiveValue::UnitType::kNumber)); + Append( + *CSSNumericLiteralValue::Create(x, CSSPrimitiveValue::UnitType::kNumber)); + Append( + *CSSNumericLiteralValue::Create(y, CSSPrimitiveValue::UnitType::kNumber)); + Append( + *CSSNumericLiteralValue::Create(z, CSSPrimitiveValue::UnitType::kNumber)); } String CSSAxisValue::CustomCSSText() const {
diff --git a/third_party/blink/renderer/core/css/css_basic_shape_values.cc b/third_party/blink/renderer/core/css/css_basic_shape_values.cc index 2639c9e..0c035a0 100644 --- a/third_party/blink/renderer/core/css/css_basic_shape_values.cc +++ b/third_party/blink/renderer/core/css/css_basic_shape_values.cc
@@ -30,6 +30,7 @@ #include "third_party/blink/renderer/core/css/css_basic_shape_values.h" #include "third_party/blink/renderer/core/css/css_identifier_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/css_value_pair.h" #include "third_party/blink/renderer/platform/geometry/length.h" @@ -90,9 +91,9 @@ if ((side == CSSValueID::kRight || side == CSSValueID::kBottom) && amount->IsPercentage()) { side = default_side; - amount = - CSSPrimitiveValue::Create(100 - amount->GetFloatValue(), - CSSPrimitiveValue::UnitType::kPercentage); + amount = CSSNumericLiteralValue::Create( + 100 - amount->GetFloatValue(), + CSSPrimitiveValue::UnitType::kPercentage); } } else { amount = To<CSSPrimitiveValue>(offset); @@ -100,14 +101,14 @@ if (side == CSSValueID::kCenter) { side = default_side; - amount = - CSSPrimitiveValue::Create(50, CSSPrimitiveValue::UnitType::kPercentage); + amount = CSSNumericLiteralValue::Create( + 50, CSSPrimitiveValue::UnitType::kPercentage); } else if (!amount || (amount->IsLength() && !amount->GetFloatValue())) { if (side == CSSValueID::kRight || side == CSSValueID::kBottom) - amount = CSSPrimitiveValue::Create( + amount = CSSNumericLiteralValue::Create( 100, CSSPrimitiveValue::UnitType::kPercentage); else - amount = CSSPrimitiveValue::Create( + amount = CSSNumericLiteralValue::Create( 0, CSSPrimitiveValue::UnitType::kPercentage); side = default_side; }
diff --git a/third_party/blink/renderer/core/css/css_calculation_value.cc b/third_party/blink/renderer/core/css/css_calculation_value.cc index 6e65b97..f0fd1294 100644 --- a/third_party/blink/renderer/core/css/css_calculation_value.cc +++ b/third_party/blink/renderer/core/css/css_calculation_value.cc
@@ -30,6 +30,7 @@ #include "third_party/blink/renderer/core/css/css_calculation_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value_mappings.h" #include "third_party/blink/renderer/core/css/resolver/style_resolver.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" @@ -177,7 +178,7 @@ if (std::isnan(value) || std::isinf(value)) return nullptr; return MakeGarbageCollected<CSSCalcPrimitiveValue>( - CSSPrimitiveValue::Create(value, type), is_integer); + CSSNumericLiteralValue::Create(value, type), is_integer); } CSSCalcPrimitiveValue::CSSCalcPrimitiveValue(CSSPrimitiveValue* value, @@ -702,7 +703,7 @@ return nullptr; return CSSCalcPrimitiveValue::Create( - CSSPrimitiveValue::Create(token.NumericValue(), type), + CSSNumericLiteralValue::Create(token.NumericValue(), type), token.GetNumericValueType() == kIntegerValueType); } @@ -818,10 +819,10 @@ double percent) { return CreateExpressionNode( CreateExpressionNode( - CSSPrimitiveValue::Create(percent, - CSSPrimitiveValue::UnitType::kPercentage), + CSSNumericLiteralValue::Create( + percent, CSSPrimitiveValue::UnitType::kPercentage), percent == trunc(percent)), - CreateExpressionNode(CSSPrimitiveValue::Create( + CreateExpressionNode(CSSNumericLiteralValue::Create( pixels, CSSPrimitiveValue::UnitType::kPixels), pixels == trunc(pixels)), CSSMathOperator::kAdd);
diff --git a/third_party/blink/renderer/core/css/css_calculation_value.h b/third_party/blink/renderer/core/css/css_calculation_value.h index 0a704f9..b7090eb 100644 --- a/third_party/blink/renderer/core/css/css_calculation_value.h +++ b/third_party/blink/renderer/core/css/css_calculation_value.h
@@ -97,6 +97,7 @@ bool is_nested_calc_ = false; }; +// TODO(crbug.com/825895): Rename it and make it store a CSSNumericLiteralValue class CSSCalcPrimitiveValue final : public CSSCalcExpressionNode { public: static CSSCalcPrimitiveValue* Create(CSSPrimitiveValue* value,
diff --git a/third_party/blink/renderer/core/css/css_calculation_value_test.cc b/third_party/blink/renderer/core/css/css_calculation_value_test.cc index 21edc4b..e90935a 100644 --- a/third_party/blink/renderer/core/css/css_calculation_value_test.cc +++ b/third_party/blink/renderer/core/css/css_calculation_value_test.cc
@@ -31,6 +31,7 @@ #include "third_party/blink/renderer/core/css/css_calculation_value.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/css_property_value_set.h" #include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h" @@ -86,7 +87,8 @@ TestAccumulatePixelsAndPercent( conversion_data, CSSCalcValue::CreateExpressionNode( - CSSPrimitiveValue::Create(10, CSSPrimitiveValue::UnitType::kPixels), + CSSNumericLiteralValue::Create(10, + CSSPrimitiveValue::UnitType::kPixels), true), 50, 0); @@ -94,12 +96,12 @@ conversion_data, CSSCalcValue::CreateExpressionNode( CSSCalcValue::CreateExpressionNode( - CSSPrimitiveValue::Create(10, - CSSPrimitiveValue::UnitType::kPixels), + CSSNumericLiteralValue::Create( + 10, CSSPrimitiveValue::UnitType::kPixels), true), CSSCalcValue::CreateExpressionNode( - CSSPrimitiveValue::Create(20, - CSSPrimitiveValue::UnitType::kPixels), + CSSNumericLiteralValue::Create( + 20, CSSPrimitiveValue::UnitType::kPixels), true), CSSMathOperator::kAdd), 150, 0); @@ -108,12 +110,12 @@ conversion_data, CSSCalcValue::CreateExpressionNode( CSSCalcValue::CreateExpressionNode( - CSSPrimitiveValue::Create(1, - CSSPrimitiveValue::UnitType::kInches), + CSSNumericLiteralValue::Create( + 1, CSSPrimitiveValue::UnitType::kInches), true), CSSCalcValue::CreateExpressionNode( - CSSPrimitiveValue::Create(2, - CSSPrimitiveValue::UnitType::kNumber), + CSSNumericLiteralValue::Create( + 2, CSSPrimitiveValue::UnitType::kNumber), true), CSSMathOperator::kMultiply), 960, 0); @@ -123,21 +125,21 @@ CSSCalcValue::CreateExpressionNode( CSSCalcValue::CreateExpressionNode( CSSCalcValue::CreateExpressionNode( - CSSPrimitiveValue::Create( + CSSNumericLiteralValue::Create( 50, CSSPrimitiveValue::UnitType::kPixels), true), CSSCalcValue::CreateExpressionNode( - CSSPrimitiveValue::Create( + CSSNumericLiteralValue::Create( 0.25, CSSPrimitiveValue::UnitType::kNumber), false), CSSMathOperator::kMultiply), CSSCalcValue::CreateExpressionNode( CSSCalcValue::CreateExpressionNode( - CSSPrimitiveValue::Create( + CSSNumericLiteralValue::Create( 20, CSSPrimitiveValue::UnitType::kPixels), true), CSSCalcValue::CreateExpressionNode( - CSSPrimitiveValue::Create( + CSSNumericLiteralValue::Create( 40, CSSPrimitiveValue::UnitType::kPercentage), false), CSSMathOperator::kSubtract),
diff --git a/third_party/blink/renderer/core/css/css_math_function_value.cc b/third_party/blink/renderer/core/css/css_math_function_value.cc new file mode 100644 index 0000000..14efb05 --- /dev/null +++ b/third_party/blink/renderer/core/css/css_math_function_value.cc
@@ -0,0 +1,40 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/css/css_math_function_value.h" + +#include "third_party/blink/renderer/core/css/css_calculation_value.h" +#include "third_party/blink/renderer/platform/geometry/length.h" +#include "third_party/blink/renderer/platform/wtf/size_assertions.h" + +namespace blink { + +struct SameSizeAsCSSMathFunctionValue : CSSPrimitiveValue { + Member<void*> calc; +}; +ASSERT_SIZE(CSSMathFunctionValue, SameSizeAsCSSMathFunctionValue); + +void CSSMathFunctionValue::TraceAfterDispatch(blink::Visitor* visitor) { + visitor->Trace(calc_); + CSSPrimitiveValue::TraceAfterDispatch(visitor); +} + +CSSMathFunctionValue::CSSMathFunctionValue(CSSCalcValue* calc) + : CSSPrimitiveValue(UnitType::kCalc, kMathFunctionClass), calc_(calc) {} + +// static +CSSMathFunctionValue* CSSMathFunctionValue::Create(CSSCalcValue* calc) { + return MakeGarbageCollected<CSSMathFunctionValue>(calc); +} + +// static +CSSMathFunctionValue* CSSMathFunctionValue::Create(const Length& length, + float zoom) { + const CalculationValue& calc = length.GetCalculationValue(); + return Create(CSSCalcValue::Create( + CSSCalcValue::CreateExpressionNode(calc.Pixels() / zoom, calc.Percent()), + calc.GetValueRange())); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/css/css_math_function_value.h b/third_party/blink/renderer/core/css/css_math_function_value.h new file mode 100644 index 0000000..680f02cf --- /dev/null +++ b/third_party/blink/renderer/core/css/css_math_function_value.h
@@ -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. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_MATH_FUNCTION_VALUE_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_MATH_FUNCTION_VALUE_H_ + +#include "third_party/blink/renderer/core/css/css_primitive_value.h" + +namespace blink { + +// Numeric values that involve math functions (calc(), min(), max(), etc). This +// is the equivalence of CSS Typed OM's |CSSMathValue| in the |CSSValue| class +// hierarchy. +class CORE_EXPORT CSSMathFunctionValue : public CSSPrimitiveValue { + public: + static CSSMathFunctionValue* Create(const Length&, float zoom); + static CSSMathFunctionValue* Create(CSSCalcValue*); + + explicit CSSMathFunctionValue(CSSCalcValue*); + + CSSCalcValue* CssCalcValue() const { return calc_; } + + void TraceAfterDispatch(blink::Visitor* visitor); + + private: + Member<CSSCalcValue> calc_; +}; + +template <> +struct DowncastTraits<CSSMathFunctionValue> { + static bool AllowFrom(const CSSValue& value) { + return value.IsMathFunctionValue(); + } +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_MATH_FUNCTION_VALUE_H_
diff --git a/third_party/blink/renderer/core/css/css_numeric_literal_value.cc b/third_party/blink/renderer/core/css/css_numeric_literal_value.cc new file mode 100644 index 0000000..3446926 --- /dev/null +++ b/third_party/blink/renderer/core/css/css_numeric_literal_value.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 "third_party/blink/renderer/core/css/css_numeric_literal_value.h" + +#include "third_party/blink/renderer/core/css/css_value_pool.h" +#include "third_party/blink/renderer/platform/wtf/size_assertions.h" + +namespace blink { + +struct SameSizeAsCSSNumericLiteralValue : CSSPrimitiveValue { + double num; +}; +ASSERT_SIZE(CSSNumericLiteralValue, SameSizeAsCSSNumericLiteralValue); + +void CSSNumericLiteralValue::TraceAfterDispatch(blink::Visitor* visitor) { + CSSPrimitiveValue::TraceAfterDispatch(visitor); +} + +CSSNumericLiteralValue::CSSNumericLiteralValue(double num, UnitType type) + : CSSPrimitiveValue(type, kNumericLiteralClass), num_(num) { + DCHECK(std::isfinite(num)); +} + +// static +CSSNumericLiteralValue* CSSNumericLiteralValue::Create(double value, + UnitType type) { + // TODO(timloh): This looks wrong. + if (std::isinf(value)) + return nullptr; + + if (value < 0 || value > CSSValuePool::kMaximumCacheableIntegerValue) + return MakeGarbageCollected<CSSNumericLiteralValue>(value, type); + + int int_value = clampTo<int>(value); + if (value != int_value) + return MakeGarbageCollected<CSSNumericLiteralValue>(value, type); + + // TODO(xiaochengh): Make |CSSValuePool| cache |CSSNumericLiteralValue| to + // avoid type casting. + CSSValuePool& pool = CssValuePool(); + CSSPrimitiveValue* result = nullptr; + switch (type) { + case CSSPrimitiveValue::UnitType::kPixels: + result = pool.PixelCacheValue(int_value); + if (!result) { + result = pool.SetPixelCacheValue( + int_value, + MakeGarbageCollected<CSSNumericLiteralValue>(value, type)); + } + return To<CSSNumericLiteralValue>(result); + case CSSPrimitiveValue::UnitType::kPercentage: + result = pool.PercentCacheValue(int_value); + if (!result) { + result = pool.SetPercentCacheValue( + int_value, + MakeGarbageCollected<CSSNumericLiteralValue>(value, type)); + } + return To<CSSNumericLiteralValue>(result); + case CSSPrimitiveValue::UnitType::kNumber: + case CSSPrimitiveValue::UnitType::kInteger: + result = pool.NumberCacheValue(int_value); + if (!result) { + result = pool.SetNumberCacheValue( + int_value, MakeGarbageCollected<CSSNumericLiteralValue>( + value, CSSPrimitiveValue::UnitType::kInteger)); + } + return To<CSSNumericLiteralValue>(result); + default: + return MakeGarbageCollected<CSSNumericLiteralValue>(value, type); + } +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/css/css_numeric_literal_value.h b/third_party/blink/renderer/core/css/css_numeric_literal_value.h new file mode 100644 index 0000000..4d2de315 --- /dev/null +++ b/third_party/blink/renderer/core/css/css_numeric_literal_value.h
@@ -0,0 +1,38 @@ +// 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_CSS_CSS_NUMERIC_LITERAL_VALUE_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_NUMERIC_LITERAL_VALUE_H_ + +#include "third_party/blink/renderer/core/css/css_primitive_value.h" + +namespace blink { + +// Numeric values that can be expressed as a single unit (or a naked number or +// percentage). The equivalence of CSS Typed OM's |CSSUnitValue| in the +// |CSSValue| class hierarchy. +class CORE_EXPORT CSSNumericLiteralValue : public CSSPrimitiveValue { + public: + static CSSNumericLiteralValue* Create(double num, UnitType); + + CSSNumericLiteralValue(double num, UnitType type); + + double DoubleValue() const { return num_; } + + void TraceAfterDispatch(blink::Visitor* visitor); + + private: + double num_; +}; + +template <> +struct DowncastTraits<CSSNumericLiteralValue> { + static bool AllowFrom(const CSSValue& value) { + return value.IsNumericLiteralValue(); + } +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_NUMERIC_LITERAL_VALUE_H_
diff --git a/third_party/blink/renderer/core/css/css_primitive_value.cc b/third_party/blink/renderer/core/css/css_primitive_value.cc index 6e843c5d..2ee06c5 100644 --- a/third_party/blink/renderer/core/css/css_primitive_value.cc +++ b/third_party/blink/renderer/core/css/css_primitive_value.cc
@@ -26,6 +26,8 @@ #include "build/build_config.h" #include "third_party/blink/renderer/core/css/css_calculation_value.h" #include "third_party/blink/renderer/core/css/css_markup.h" +#include "third_party/blink/renderer/core/css/css_math_function_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_resolution_units.h" #include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h" #include "third_party/blink/renderer/core/css/css_value_pool.h" @@ -48,7 +50,6 @@ } // namespace struct SameSizeAsCSSPrimitiveValue : CSSValue { - double num; }; ASSERT_SIZE(CSSPrimitiveValue, SameSizeAsCSSPrimitiveValue); @@ -92,53 +93,11 @@ } } -CSSPrimitiveValue* CSSPrimitiveValue::Create(double value, UnitType type) { - // TODO(timloh): This looks wrong. - if (std::isinf(value)) - value = 0; - - if (value < 0 || value > CSSValuePool::kMaximumCacheableIntegerValue) - return MakeGarbageCollected<CSSPrimitiveValue>(value, type); - - int int_value = clampTo<int>(value); - if (value != int_value) - return MakeGarbageCollected<CSSPrimitiveValue>(value, type); - - CSSValuePool& pool = CssValuePool(); - CSSPrimitiveValue* result = nullptr; - switch (type) { - case CSSPrimitiveValue::UnitType::kPixels: - result = pool.PixelCacheValue(int_value); - if (!result) { - result = pool.SetPixelCacheValue( - int_value, MakeGarbageCollected<CSSPrimitiveValue>(value, type)); - } - return result; - case CSSPrimitiveValue::UnitType::kPercentage: - result = pool.PercentCacheValue(int_value); - if (!result) { - result = pool.SetPercentCacheValue( - int_value, MakeGarbageCollected<CSSPrimitiveValue>(value, type)); - } - return result; - case CSSPrimitiveValue::UnitType::kNumber: - case CSSPrimitiveValue::UnitType::kInteger: - result = pool.NumberCacheValue(int_value); - if (!result) - result = pool.SetNumberCacheValue( - int_value, MakeGarbageCollected<CSSPrimitiveValue>( - value, CSSPrimitiveValue::UnitType::kInteger)); - return result; - default: - return MakeGarbageCollected<CSSPrimitiveValue>(value, type); - } -} - CSSPrimitiveValue::UnitType CSSPrimitiveValue::TypeWithCalcResolved() const { if (GetType() != UnitType::kCalc) return GetType(); - switch (value_.calc->Category()) { + switch (CssCalcValue()->Category()) { case kCalcAngle: return UnitType::kDegrees; case kCalcFrequency: @@ -165,69 +124,43 @@ return UnitType::kUnknown; } -CSSPrimitiveValue::CSSPrimitiveValue(double num, UnitType type) - : CSSValue(kPrimitiveClass) { - Init(type); - DCHECK(std::isfinite(num)); - value_.num = num; +CSSPrimitiveValue::CSSPrimitiveValue(UnitType unit_type, ClassType class_type) + : CSSValue(class_type) { + primitive_unit_type_ = static_cast<unsigned>(unit_type); } -CSSPrimitiveValue::CSSPrimitiveValue(const Length& length, float zoom) - : CSSValue(kPrimitiveClass) { +// static +CSSPrimitiveValue* CSSPrimitiveValue::CreateFromLength(const Length& length, + float zoom) { switch (length.GetType()) { case Length::kPercent: - Init(UnitType::kPercentage); - DCHECK(std::isfinite(length.Percent())); - value_.num = length.Percent(); - break; + return CSSNumericLiteralValue::Create(length.Percent(), + UnitType::kPercentage); case Length::kFixed: - Init(UnitType::kPixels); - value_.num = length.Value() / zoom; - break; + return CSSNumericLiteralValue::Create(length.Value() / zoom, + UnitType::kPixels); case Length::kCalculated: { const CalculationValue& calc = length.GetCalculationValue(); - if (calc.Pixels() && calc.Percent()) { - Init(CSSCalcValue::Create(CSSCalcValue::CreateExpressionNode( - calc.Pixels() / zoom, calc.Percent()), - calc.GetValueRange())); - break; - } + if (calc.Pixels() && calc.Percent()) + return CSSMathFunctionValue::Create(length, zoom); if (calc.Percent()) { - Init(UnitType::kPercentage); - value_.num = calc.Percent(); - } else { - Init(UnitType::kPixels); - value_.num = calc.Pixels() / zoom; + double num = calc.Percent(); + if (num < 0 && calc.IsNonNegative()) + num = 0; + return CSSNumericLiteralValue::Create(num, UnitType::kPercentage); } - if (value_.num < 0 && calc.IsNonNegative()) - value_.num = 0; - break; + double num = calc.Pixels() / zoom; + if (num < 0 && calc.IsNonNegative()) + num = 0; + return CSSNumericLiteralValue::Create(num, UnitType::kPixels); } - case Length::kAuto: - case Length::kMinContent: - case Length::kMaxContent: - case Length::kFillAvailable: - case Length::kFitContent: - case Length::kExtendToZoom: - case Length::kDeviceWidth: - case Length::kDeviceHeight: - case Length::kMaxSizeNone: - NOTREACHED(); + default: break; } + NOTREACHED(); + return nullptr; } -void CSSPrimitiveValue::Init(UnitType type) { - primitive_unit_type_ = static_cast<unsigned>(type); -} - -void CSSPrimitiveValue::Init(CSSCalcValue* c) { - Init(UnitType::kCalc); - value_.calc = c; -} - -CSSPrimitiveValue::~CSSPrimitiveValue() = default; - double CSSPrimitiveValue::ComputeSeconds() const { DCHECK(IsTime() || (IsCalculated() && CssCalcValue()->Category() == kCalcTime)); @@ -325,7 +258,7 @@ double CSSPrimitiveValue::ComputeLengthDouble( const CSSToLengthConversionData& conversion_data) const { if (GetType() == UnitType::kCalc) - return value_.calc->ComputeLengthPx(conversion_data); + return CssCalcValue()->ComputeLengthPx(conversion_data); return conversion_data.ZoomedComputedPixels(GetDoubleValue(), GetType()); } @@ -343,8 +276,8 @@ bool conversion_success = UnitTypeToLengthUnitType(GetType(), length_type); DCHECK(conversion_success); length_array.values[length_type] += - value_.num * ConversionToCanonicalUnitsScaleFactor(GetType()) * - multiplier; + To<CSSNumericLiteralValue>(this)->DoubleValue() * + ConversionToCanonicalUnitsScaleFactor(GetType()) * multiplier; length_array.type_flags.set(length_type); } @@ -415,7 +348,9 @@ } double CSSPrimitiveValue::GetDoubleValue() const { - return GetType() != UnitType::kCalc ? value_.num : value_.calc->DoubleValue(); + return GetType() != UnitType::kCalc + ? To<CSSNumericLiteralValue>(this)->DoubleValue() + : CssCalcValue()->DoubleValue(); } CSSPrimitiveValue::UnitType CSSPrimitiveValue::CanonicalUnitTypeForCategory( @@ -649,21 +584,22 @@ // be represented in non-exponential format with 6 digit precision. constexpr int kMinInteger = -999999; constexpr int kMaxInteger = 999999; - // If the value_.num is small integer, go the fast path. - if (value_.num < kMinInteger || value_.num > kMaxInteger || - std::trunc(value_.num) != value_.num) { - text = FormatNumber(value_.num, UnitTypeToString(GetType())); + double value = To<CSSNumericLiteralValue>(this)->DoubleValue(); + // If the value is small integer, go the fast path. + if (value < kMinInteger || value > kMaxInteger || + std::trunc(value) != value) { + text = FormatNumber(value, UnitTypeToString(GetType())); } else { StringBuilder builder; - int value = value_.num; + int int_value = value; const char* unit_type = UnitTypeToString(GetType()); - builder.AppendNumber(value); + builder.AppendNumber(int_value); builder.Append(unit_type, strlen(unit_type)); text = builder.ToString(); } } break; case UnitType::kCalc: - text = value_.calc->CustomCSSText(); + text = CssCalcValue()->CustomCSSText(); break; case UnitType::kCalcPercentageWithNumber: case UnitType::kCalcPercentageWithLength: @@ -713,10 +649,11 @@ case UnitType::kViewportMin: case UnitType::kViewportMax: case UnitType::kFraction: - return value_.num == other.value_.num; + return To<CSSNumericLiteralValue>(this)->DoubleValue() == + To<CSSNumericLiteralValue>(other).DoubleValue(); case UnitType::kCalc: - return value_.calc && other.value_.calc && - value_.calc->Equals(*other.value_.calc); + return CssCalcValue() && other.CssCalcValue() && + CssCalcValue()->Equals(*other.CssCalcValue()); case UnitType::kChs: case UnitType::kCalcPercentageWithNumber: case UnitType::kCalcPercentageWithLength: @@ -728,14 +665,12 @@ return false; } +CSSCalcValue* CSSPrimitiveValue::CssCalcValue() const { + DCHECK(IsCalculated()); + return To<CSSMathFunctionValue>(this)->CssCalcValue(); +} + void CSSPrimitiveValue::TraceAfterDispatch(blink::Visitor* visitor) { - switch (GetType()) { - case UnitType::kCalc: - visitor->Trace(value_.calc); - break; - default: - break; - } CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_primitive_value.h b/third_party/blink/renderer/core/css/css_primitive_value.h index 7381336..f2a0ad8d 100644 --- a/third_party/blink/renderer/core/css/css_primitive_value.h +++ b/third_party/blink/renderer/core/css/css_primitive_value.h
@@ -62,8 +62,8 @@ return static_cast<float>(value); } -// CSSPrimitiveValue stores numeric data types (e.g. 1, 10px, 4%) and calc() -// values (e.g. calc(3px + 2em)). +// Common interface for numeric data types, including both literals (e.g. 1, +// 10px, 4%) and values involving math functions (e.g. calc(3px + 2em)). class CORE_EXPORT CSSPrimitiveValue : public CSSValue { public: // These units are iterated through, so be careful when adding or changing the @@ -106,6 +106,9 @@ // Other units kFraction, kInteger, + + // TODO(crbug.com/979895): Remove |kCalc|, and move/remove the remaining + // calc flags to CSSMathFunctionValue. kCalc, kCalcPercentageWithNumber, kCalcPercentageWithLength, @@ -218,21 +221,12 @@ static bool IsFlex(UnitType unit) { return unit == UnitType::kFraction; } bool IsFlex() const { return IsFlex(GetType()); } - static CSSPrimitiveValue* Create(double value, UnitType); - static CSSPrimitiveValue* Create(const Length& value, float zoom) { - return MakeGarbageCollected<CSSPrimitiveValue>(value, zoom); - } - static CSSPrimitiveValue* Create(CSSCalcValue* value) { - return MakeGarbageCollected<CSSPrimitiveValue>(value); - } + // Creates either a |CSSNumericLiteralValue| or a |CSSMathFunctionValue|, + // depending on whether |value| is calculated or not. We should never create a + // |CSSPrimitiveValue| that's not of any of its subclasses. + static CSSPrimitiveValue* CreateFromLength(const Length& value, float zoom); - CSSPrimitiveValue(const Length&, float zoom); - CSSPrimitiveValue(double, UnitType); - CSSPrimitiveValue(CSSCalcValue* val) : CSSValue(kPrimitiveClass) { - Init(val); - } - ~CSSPrimitiveValue(); - + // TODO(crbug.com/979895): Split this function properly. UnitType TypeWithCalcResolved() const; double ComputeDegrees() const; @@ -246,6 +240,9 @@ // Converts to a Length (Fixed, Percent or Calculated) Length ConvertToLength(const CSSToLengthConversionData&) const; + // TODO(crbug.com/979895): Make sure this functions are called only when + // applicable: on a numeric literal, or on a calc() that can be resolved into + // a single value without extra context (e.g., CSSToLengthConversionData). double GetDoubleValue() const; float GetFloatValue() const { return GetValue<float>(); } int GetIntValue() const { return GetValue<int>(); } @@ -254,10 +251,8 @@ return clampTo<T>(GetDoubleValue()); } - CSSCalcValue* CssCalcValue() const { - DCHECK(IsCalculated()); - return value_.calc; - } + // TODO(crbug.com/979895): Move this to |CSSMathFunctionValue| + CSSCalcValue* CssCalcValue() const; template <typename T> inline T ConvertTo() const; // Defined in CSSPrimitiveValueMappings.h @@ -283,27 +278,18 @@ static bool UnitTypeToLengthUnitType(UnitType, LengthUnitType&); static UnitType LengthUnitTypeToUnitType(LengthUnitType); - private: + protected: + CSSPrimitiveValue(UnitType unit_type, ClassType class_type); + // Code generated by css_primitive_value_unit_trie.cc.tmpl static UnitType StringToUnitType(const LChar*, unsigned length); static UnitType StringToUnitType(const UChar*, unsigned length); - void Init(UnitType); - void Init(const Length&); - void Init(CSSCalcValue*); - double ComputeLengthDouble(const CSSToLengthConversionData&) const; inline UnitType GetType() const { return static_cast<UnitType>(primitive_unit_type_); } - - union { - double num; - // FIXME: oilpan: Should be a member, but no support for members in unions. - // Just trace the raw ptr for now. - CSSCalcValue* calc; - } value_; }; using CSSLengthArray = CSSPrimitiveValue::CSSLengthArray;
diff --git a/third_party/blink/renderer/core/css/css_primitive_value_test.cc b/third_party/blink/renderer/core/css/css_primitive_value_test.cc index c375ad1..da73b41 100644 --- a/third_party/blink/renderer/core/css/css_primitive_value_test.cc +++ b/third_party/blink/renderer/core/css/css_primitive_value_test.cc
@@ -6,6 +6,8 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/core/css/css_calculation_value.h" +#include "third_party/blink/renderer/core/css/css_math_function_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" namespace blink { namespace { @@ -18,11 +20,11 @@ }; CSSPrimitiveValue* Create(UnitValue v) { - return CSSPrimitiveValue::Create(v.value, v.unit_type); + return CSSNumericLiteralValue::Create(v.value, v.unit_type); } CSSPrimitiveValue* CreateAddition(UnitValue a, UnitValue b) { - return CSSPrimitiveValue::Create( + return CSSMathFunctionValue::Create( CSSCalcValue::Create(CSSCalcValue::CreateExpressionNode( CSSCalcValue::CreateExpressionNode(Create(a)), CSSCalcValue::CreateExpressionNode(Create(b)),
diff --git a/third_party/blink/renderer/core/css/css_value.cc b/third_party/blink/renderer/core/css/css_value.cc index 1e56eae..8bc8973 100644 --- a/third_party/blink/renderer/core/css/css_value.cc +++ b/third_party/blink/renderer/core/css/css_value.cc
@@ -54,6 +54,8 @@ #include "third_party/blink/renderer/core/css/css_initial_value.h" #include "third_party/blink/renderer/core/css/css_invalid_variable_value.h" #include "third_party/blink/renderer/core/css/css_layout_function_value.h" +#include "third_party/blink/renderer/core/css/css_math_function_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_paint_value.h" #include "third_party/blink/renderer/core/css/css_path_value.h" #include "third_party/blink/renderer/core/css/css_pending_substitution_value.h" @@ -95,7 +97,7 @@ case Length::kPercent: case Length::kFixed: case Length::kCalculated: - return CSSPrimitiveValue::Create(value, zoom); + return CSSPrimitiveValue::CreateFromLength(value, zoom); case Length::kDeviceWidth: case Length::kDeviceHeight: case Length::kMaxSizeNone: @@ -214,7 +216,9 @@ return CompareCSSValues<CSSGridTemplateAreasValue>(*this, other); case kPathClass: return CompareCSSValues<CSSPathValue>(*this, other); - case kPrimitiveClass: + case kNumericLiteralClass: + case kMathFunctionClass: + // TODO(crbug.com/979895): Should call into the subclasses. return CompareCSSValues<CSSPrimitiveValue>(*this, other); case kRayClass: return CompareCSSValues<CSSRayValue>(*this, other); @@ -324,7 +328,9 @@ return To<CSSGridTemplateAreasValue>(this)->CustomCSSText(); case kPathClass: return To<CSSPathValue>(this)->CustomCSSText(); - case kPrimitiveClass: + case kNumericLiteralClass: + case kMathFunctionClass: + // TODO(crbug.com/979895): Should call into the subclasses. return To<CSSPrimitiveValue>(this)->CustomCSSText(); case kRayClass: return To<CSSRayValue>(this)->CustomCSSText(); @@ -462,8 +468,11 @@ case kPathClass: To<CSSPathValue>(this)->~CSSPathValue(); return; - case kPrimitiveClass: - To<CSSPrimitiveValue>(this)->~CSSPrimitiveValue(); + case kNumericLiteralClass: + To<CSSNumericLiteralValue>(this)->~CSSNumericLiteralValue(); + return; + case kMathFunctionClass: + To<CSSMathFunctionValue>(this)->~CSSMathFunctionValue(); return; case kRayClass: To<CSSRayValue>(this)->~CSSRayValue(); @@ -619,8 +628,11 @@ case kPathClass: To<CSSPathValue>(this)->TraceAfterDispatch(visitor); return; - case kPrimitiveClass: - To<CSSPrimitiveValue>(this)->TraceAfterDispatch(visitor); + case kNumericLiteralClass: + To<CSSNumericLiteralValue>(this)->TraceAfterDispatch(visitor); + return; + case kMathFunctionClass: + To<CSSMathFunctionValue>(this)->TraceAfterDispatch(visitor); return; case kRayClass: To<CSSRayValue>(this)->TraceAfterDispatch(visitor);
diff --git a/third_party/blink/renderer/core/css/css_value.h b/third_party/blink/renderer/core/css/css_value.h index aa39904..bc02bde 100644 --- a/third_party/blink/renderer/core/css/css_value.h +++ b/third_party/blink/renderer/core/css/css_value.h
@@ -49,7 +49,13 @@ String CssText() const; - bool IsPrimitiveValue() const { return class_type_ == kPrimitiveClass; } + bool IsNumericLiteralValue() const { + return class_type_ == kNumericLiteralClass; + } + bool IsMathFunctionValue() const { return class_type_ == kMathFunctionClass; } + bool IsPrimitiveValue() const { + return IsNumericLiteralValue() || IsMathFunctionValue(); + } bool IsIdentifierValue() const { return class_type_ == kIdentifierClass; } bool IsValuePair() const { return class_type_ == kValuePairClass; } bool IsValueList() const { return class_type_ >= kValueListClass; } @@ -181,7 +187,8 @@ protected: static const size_t kClassTypeBits = 6; enum ClassType { - kPrimitiveClass, + kNumericLiteralClass, + kMathFunctionClass, kIdentifierClass, kColorClass, kCounterClass,
diff --git a/third_party/blink/renderer/core/css/cssom/computed_style_property_map.cc b/third_party/blink/renderer/core/css/cssom/computed_style_property_map.cc index 5ab8054..196ad3a 100644 --- a/third_party/blink/renderer/core/css/cssom/computed_style_property_map.cc +++ b/third_party/blink/renderer/core/css/cssom/computed_style_property_map.cc
@@ -8,6 +8,7 @@ #include "third_party/blink/renderer/core/css/css_custom_property_declaration.h" #include "third_party/blink/renderer/core/css/css_function_value.h" #include "third_party/blink/renderer/core/css/css_identifier_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_variable_data.h" #include "third_party/blink/renderer/core/css/properties/css_property_ref.h" #include "third_party/blink/renderer/core/dom/document.h" @@ -36,12 +37,12 @@ CSSFunctionValue* result = MakeGarbageCollected<CSSFunctionValue>( operation.Is3DOperation() ? CSSValueID::kScale3d : CSSValueID::kScale); - result->Append(*CSSPrimitiveValue::Create( + result->Append(*CSSNumericLiteralValue::Create( scale.X(), CSSPrimitiveValue::UnitType::kNumber)); - result->Append(*CSSPrimitiveValue::Create( + result->Append(*CSSNumericLiteralValue::Create( scale.Y(), CSSPrimitiveValue::UnitType::kNumber)); if (operation.Is3DOperation()) { - result->Append(*CSSPrimitiveValue::Create( + result->Append(*CSSNumericLiteralValue::Create( scale.Z(), CSSPrimitiveValue::UnitType::kNumber)); } return result; @@ -55,10 +56,10 @@ CSSFunctionValue* result = MakeGarbageCollected<CSSFunctionValue>( operation.Is3DOperation() ? CSSValueID::kTranslate3d : CSSValueID::kTranslate); - result->Append(*CSSPrimitiveValue::Create(translate.X(), zoom)); - result->Append(*CSSPrimitiveValue::Create(translate.Y(), zoom)); + result->Append(*CSSPrimitiveValue::CreateFromLength(translate.X(), zoom)); + result->Append(*CSSPrimitiveValue::CreateFromLength(translate.Y(), zoom)); if (operation.Is3DOperation()) { - result->Append(*CSSPrimitiveValue::Create( + result->Append(*CSSNumericLiteralValue::Create( translate.Z(), CSSPrimitiveValue::UnitType::kPixels)); } return result; @@ -69,13 +70,13 @@ const auto& rotate = ToRotateTransformOperation(operation); CSSFunctionValue* result = MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kRotate3d); - result->Append(*CSSPrimitiveValue::Create( + result->Append(*CSSNumericLiteralValue::Create( rotate.X(), CSSPrimitiveValue::UnitType::kNumber)); - result->Append(*CSSPrimitiveValue::Create( + result->Append(*CSSNumericLiteralValue::Create( rotate.Y(), CSSPrimitiveValue::UnitType::kNumber)); - result->Append(*CSSPrimitiveValue::Create( + result->Append(*CSSNumericLiteralValue::Create( rotate.Z(), CSSPrimitiveValue::UnitType::kNumber)); - result->Append(*CSSPrimitiveValue::Create( + result->Append(*CSSNumericLiteralValue::Create( rotate.Angle(), CSSPrimitiveValue::UnitType::kDegrees)); return result; } @@ -83,30 +84,30 @@ const auto& rotate = ToRotateTransformOperation(operation); auto* result = MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kRotate); - result->Append(*CSSPrimitiveValue::Create( + result->Append(*CSSNumericLiteralValue::Create( rotate.Angle(), CSSPrimitiveValue::UnitType::kDegrees)); return result; } case TransformOperation::kSkewX: { const auto& skew = ToSkewTransformOperation(operation); auto* result = MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kSkewX); - result->Append(*CSSPrimitiveValue::Create( + result->Append(*CSSNumericLiteralValue::Create( skew.AngleX(), CSSPrimitiveValue::UnitType::kDegrees)); return result; } case TransformOperation::kSkewY: { const auto& skew = ToSkewTransformOperation(operation); auto* result = MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kSkewY); - result->Append(*CSSPrimitiveValue::Create( + result->Append(*CSSNumericLiteralValue::Create( skew.AngleY(), CSSPrimitiveValue::UnitType::kDegrees)); return result; } case TransformOperation::kSkew: { const auto& skew = ToSkewTransformOperation(operation); auto* result = MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kSkew); - result->Append(*CSSPrimitiveValue::Create( + result->Append(*CSSNumericLiteralValue::Create( skew.AngleX(), CSSPrimitiveValue::UnitType::kDegrees)); - result->Append(*CSSPrimitiveValue::Create( + result->Append(*CSSNumericLiteralValue::Create( skew.AngleY(), CSSPrimitiveValue::UnitType::kDegrees)); return result; } @@ -114,7 +115,7 @@ const auto& perspective = ToPerspectiveTransformOperation(operation); auto* result = MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kPerspective); - result->Append(*CSSPrimitiveValue::Create( + result->Append(*CSSNumericLiteralValue::Create( perspective.Perspective(), CSSPrimitiveValue::UnitType::kPixels)); return result; } @@ -125,7 +126,7 @@ double values[6] = {matrix.A(), matrix.B(), matrix.C(), matrix.D(), matrix.E(), matrix.F()}; for (double value : values) { - result->Append(*CSSPrimitiveValue::Create( + result->Append(*CSSNumericLiteralValue::Create( value, CSSPrimitiveValue::UnitType::kNumber)); } return result; @@ -140,7 +141,7 @@ matrix.M31(), matrix.M32(), matrix.M33(), matrix.M34(), matrix.M41(), matrix.M42(), matrix.M43(), matrix.M44()}; for (double value : values) { - result->Append(*CSSPrimitiveValue::Create( + result->Append(*CSSNumericLiteralValue::Create( value, CSSPrimitiveValue::UnitType::kNumber)); } return result;
diff --git a/third_party/blink/renderer/core/css/cssom/css_math_value.cc b/third_party/blink/renderer/core/css/cssom/css_math_value.cc index 633fbbf..d443b26 100644 --- a/third_party/blink/renderer/core/css/cssom/css_math_value.cc +++ b/third_party/blink/renderer/core/css/cssom/css_math_value.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/css/cssom/css_math_value.h" #include "third_party/blink/renderer/core/css/css_calculation_value.h" +#include "third_party/blink/renderer/core/css/css_math_function_value.h" namespace blink { @@ -12,7 +13,7 @@ CSSCalcExpressionNode* node = ToCalcExpressionNode(); if (!node) return nullptr; - return CSSPrimitiveValue::Create(CSSCalcValue::Create(node)); + return CSSMathFunctionValue::Create(CSSCalcValue::Create(node)); } } // namespace blink
diff --git a/third_party/blink/renderer/core/css/cssom/css_matrix_component.cc b/third_party/blink/renderer/core/css/cssom/css_matrix_component.cc index 1137dafa..d6545b6 100644 --- a/third_party/blink/renderer/core/css/cssom/css_matrix_component.cc +++ b/third_party/blink/renderer/core/css/cssom/css_matrix_component.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/core/css/cssom/css_matrix_component.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/cssom/css_matrix_component_options.h" #include "third_party/blink/renderer/core/geometry/dom_matrix.h" @@ -58,7 +59,7 @@ double values[6] = {matrix_->a(), matrix_->b(), matrix_->c(), matrix_->d(), matrix_->e(), matrix_->f()}; for (double value : values) { - result->Append(*CSSPrimitiveValue::Create( + result->Append(*CSSNumericLiteralValue::Create( value, CSSPrimitiveValue::UnitType::kNumber)); } } else { @@ -68,7 +69,7 @@ matrix_->m31(), matrix_->m32(), matrix_->m33(), matrix_->m34(), matrix_->m41(), matrix_->m42(), matrix_->m43(), matrix_->m44()}; for (double value : values) { - result->Append(*CSSPrimitiveValue::Create( + result->Append(*CSSNumericLiteralValue::Create( value, CSSPrimitiveValue::UnitType::kNumber)); } }
diff --git a/third_party/blink/renderer/core/css/cssom/css_perspective.cc b/third_party/blink/renderer/core/css/cssom/css_perspective.cc index 3dacfe9..7b728d8 100644 --- a/third_party/blink/renderer/core/css/cssom/css_perspective.cc +++ b/third_party/blink/renderer/core/css/cssom/css_perspective.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/css/cssom/css_perspective.h" #include "third_party/blink/renderer/core/css/css_calculation_value.h" +#include "third_party/blink/renderer/core/css/css_math_function_value.h" #include "third_party/blink/renderer/core/css/cssom/css_unit_value.h" #include "third_party/blink/renderer/core/geometry/dom_matrix.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" @@ -69,7 +70,7 @@ // Wrap out of range length with a calc. CSSCalcExpressionNode* node = length_->ToCalcExpressionNode(); node->SetIsNestedCalc(); - length = CSSPrimitiveValue::Create(CSSCalcValue::Create(node)); + length = CSSMathFunctionValue::Create(CSSCalcValue::Create(node)); } else { length = length_->ToCSSValue(); }
diff --git a/third_party/blink/renderer/core/css/cssom/css_unit_value.cc b/third_party/blink/renderer/core/css/cssom/css_unit_value.cc index 608ecd9..c1901b4 100644 --- a/third_party/blink/renderer/core/css/cssom/css_unit_value.cc +++ b/third_party/blink/renderer/core/css/cssom/css_unit_value.cc
@@ -6,6 +6,8 @@ #include "third_party/blink/renderer/core/animation/length_property_functions.h" #include "third_party/blink/renderer/core/css/css_calculation_value.h" +#include "third_party/blink/renderer/core/css/css_math_function_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_resolution_units.h" #include "third_party/blink/renderer/core/css/css_syntax_descriptor.h" #include "third_party/blink/renderer/core/css/cssom/css_math_invert.h" @@ -169,7 +171,7 @@ } const CSSPrimitiveValue* CSSUnitValue::ToCSSValue() const { - return CSSPrimitiveValue::Create(value_, unit_); + return CSSNumericLiteralValue::Create(value_, unit_); } const CSSPrimitiveValue* CSSUnitValue::ToCSSValueWithProperty( @@ -179,15 +181,15 @@ // Wrap out of range values with a calc. CSSCalcExpressionNode* node = ToCalcExpressionNode(); node->SetIsNestedCalc(); - return CSSPrimitiveValue::Create(CSSCalcValue::Create(node)); + return CSSMathFunctionValue::Create(CSSCalcValue::Create(node)); } - return CSSPrimitiveValue::Create(value_, unit_); + return CSSNumericLiteralValue::Create(value_, unit_); } CSSCalcExpressionNode* CSSUnitValue::ToCalcExpressionNode() const { return CSSCalcValue::CreateExpressionNode( - CSSPrimitiveValue::Create(value_, unit_)); + CSSNumericLiteralValue::Create(value_, unit_)); } CSSNumericValue* CSSUnitValue::Negate() {
diff --git a/third_party/blink/renderer/core/css/font_face_cache_test.cc b/third_party/blink/renderer/core/css/font_face_cache_test.cc index fe60820..813528eb 100644 --- a/third_party/blink/renderer/core/css/font_face_cache_test.cc +++ b/third_party/blink/renderer/core/css/font_face_cache_test.cc
@@ -9,6 +9,7 @@ #include "third_party/blink/renderer/core/css/css_font_family_value.h" #include "third_party/blink/renderer/core/css/css_font_style_range_value.h" #include "third_party/blink/renderer/core/css/css_identifier_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_property_value_set.h" #include "third_party/blink/renderer/core/css/css_segmented_font_face.h" #include "third_party/blink/renderer/core/css/css_value_list.h" @@ -115,7 +116,7 @@ CSSIdentifierValue::Create(CSSValueID::kUltraExpanded); CSSIdentifierValue* stretch_value_condensed = CSSIdentifierValue::Create(CSSValueID::kCondensed); - CSSPrimitiveValue* weight_value = CSSPrimitiveValue::Create( + CSSPrimitiveValue* weight_value = CSSNumericLiteralValue::Create( BoldWeightValue(), CSSPrimitiveValue::UnitType::kNumber); CSSIdentifierValue* style_value = CSSIdentifierValue::Create(CSSValueID::kItalic); @@ -132,7 +133,7 @@ CSSIdentifierValue::Create(CSSValueID::kUltraExpanded); CSSIdentifierValue* stretch_value_condensed = CSSIdentifierValue::Create(CSSValueID::kCondensed); - CSSPrimitiveValue* weight_value = CSSPrimitiveValue::Create( + CSSPrimitiveValue* weight_value = CSSNumericLiteralValue::Create( NormalWeightValue(), CSSPrimitiveValue::UnitType::kNumber); CSSIdentifierValue* style_value = CSSIdentifierValue::Create(CSSValueID::kNormal); @@ -164,11 +165,11 @@ CSSIdentifierValue* style_value = CSSIdentifierValue::Create(CSSValueID::kNormal); CSSPrimitiveValue* weight_value_black = - CSSPrimitiveValue::Create(900, CSSPrimitiveValue::UnitType::kNumber); + CSSNumericLiteralValue::Create(900, CSSPrimitiveValue::UnitType::kNumber); AppendTestFaceForCapabilities(*stretch_value, *style_value, *weight_value_black); CSSPrimitiveValue* weight_value_thin = - CSSPrimitiveValue::Create(100, CSSPrimitiveValue::UnitType::kNumber); + CSSNumericLiteralValue::Create(100, CSSPrimitiveValue::UnitType::kNumber); AppendTestFaceForCapabilities(*stretch_value, *style_value, *weight_value_thin); ASSERT_EQ(cache_.GetNumSegmentedFacesForTesting(), 2ul); @@ -234,8 +235,9 @@ CSSValue* slopes[] = {CSSIdentifierValue::Create(CSSValueID::kNormal), CSSIdentifierValue::Create(CSSValueID::kItalic)}; CSSValue* weights[] = { - CSSPrimitiveValue::Create(100, CSSPrimitiveValue::UnitType::kNumber), - CSSPrimitiveValue::Create(900, CSSPrimitiveValue::UnitType::kNumber)}; + CSSNumericLiteralValue::Create(100, CSSPrimitiveValue::UnitType::kNumber), + CSSNumericLiteralValue::Create(900, + CSSPrimitiveValue::UnitType::kNumber)}; Vector<FontSelectionValue> width_choices = {CondensedWidthValue(), ExpandedWidthValue()}; @@ -295,18 +297,18 @@ CSSIdentifierValue* style_value = CSSIdentifierValue::Create(CSSValueID::kNormal); CSSPrimitiveValue* weight_value_from = - CSSPrimitiveValue::Create(700, CSSPrimitiveValue::UnitType::kNumber); + CSSNumericLiteralValue::Create(700, CSSPrimitiveValue::UnitType::kNumber); CSSPrimitiveValue* weight_value_to = - CSSPrimitiveValue::Create(800, CSSPrimitiveValue::UnitType::kNumber); + CSSNumericLiteralValue::Create(800, CSSPrimitiveValue::UnitType::kNumber); CSSValueList* weight_list = CSSValueList::CreateSpaceSeparated(); weight_list->Append(*weight_value_from); weight_list->Append(*weight_value_to); AppendTestFaceForCapabilities(*stretch_value, *style_value, *weight_list); CSSPrimitiveValue* second_weight_value_from = - CSSPrimitiveValue::Create(100, CSSPrimitiveValue::UnitType::kNumber); + CSSNumericLiteralValue::Create(100, CSSPrimitiveValue::UnitType::kNumber); CSSPrimitiveValue* second_weight_value_to = - CSSPrimitiveValue::Create(200, CSSPrimitiveValue::UnitType::kNumber); + CSSNumericLiteralValue::Create(200, CSSPrimitiveValue::UnitType::kNumber); CSSValueList* second_weight_list = CSSValueList::CreateSpaceSeparated(); second_weight_list->Append(*second_weight_value_from); second_weight_list->Append(*second_weight_value_to); @@ -340,15 +342,15 @@ CSSIdentifierValue::Create(CSSValueID::kNormal); CSSPrimitiveValue* weight_values_lower[] = { - CSSPrimitiveValue::Create(600, CSSPrimitiveValue::UnitType::kNumber), - CSSPrimitiveValue::Create(415, CSSPrimitiveValue::UnitType::kNumber), - CSSPrimitiveValue::Create(475, CSSPrimitiveValue::UnitType::kNumber), + CSSNumericLiteralValue::Create(600, CSSPrimitiveValue::UnitType::kNumber), + CSSNumericLiteralValue::Create(415, CSSPrimitiveValue::UnitType::kNumber), + CSSNumericLiteralValue::Create(475, CSSPrimitiveValue::UnitType::kNumber), }; CSSPrimitiveValue* weight_values_upper[] = { - CSSPrimitiveValue::Create(610, CSSPrimitiveValue::UnitType::kNumber), - CSSPrimitiveValue::Create(425, CSSPrimitiveValue::UnitType::kNumber), - CSSPrimitiveValue::Create(485, CSSPrimitiveValue::UnitType::kNumber), + CSSNumericLiteralValue::Create(610, CSSPrimitiveValue::UnitType::kNumber), + CSSNumericLiteralValue::Create(425, CSSPrimitiveValue::UnitType::kNumber), + CSSNumericLiteralValue::Create(485, CSSPrimitiveValue::UnitType::kNumber), }; // From https://drafts.csswg.org/css-fonts-4/#font-style-matching: "If the @@ -397,14 +399,14 @@ } TEST_F(FontFaceCacheTest, StretchRangeMatching) { - CSSPrimitiveValue* stretch_value_from = - CSSPrimitiveValue::Create(65, CSSPrimitiveValue::UnitType::kPercentage); - CSSPrimitiveValue* stretch_value_to = - CSSPrimitiveValue::Create(70, CSSPrimitiveValue::UnitType::kPercentage); + CSSPrimitiveValue* stretch_value_from = CSSNumericLiteralValue::Create( + 65, CSSPrimitiveValue::UnitType::kPercentage); + CSSPrimitiveValue* stretch_value_to = CSSNumericLiteralValue::Create( + 70, CSSPrimitiveValue::UnitType::kPercentage); CSSIdentifierValue* style_value = CSSIdentifierValue::Create(CSSValueID::kNormal); CSSPrimitiveValue* weight_value = - CSSPrimitiveValue::Create(400, CSSPrimitiveValue::UnitType::kNumber); + CSSNumericLiteralValue::Create(400, CSSPrimitiveValue::UnitType::kNumber); CSSValueList* stretch_list = CSSValueList::CreateSpaceSeparated(); stretch_list->Append(*stretch_value_from); stretch_list->Append(*stretch_value_to); @@ -412,9 +414,9 @@ const float kStretchFrom = 110; const float kStretchTo = 120; - CSSPrimitiveValue* second_stretch_value_from = CSSPrimitiveValue::Create( + CSSPrimitiveValue* second_stretch_value_from = CSSNumericLiteralValue::Create( kStretchFrom, CSSPrimitiveValue::UnitType::kPercentage); - CSSPrimitiveValue* second_stretch_value_to = CSSPrimitiveValue::Create( + CSSPrimitiveValue* second_stretch_value_to = CSSNumericLiteralValue::Create( kStretchTo, CSSPrimitiveValue::UnitType::kPercentage); CSSValueList* second_stretch_list = CSSValueList::CreateSpaceSeparated(); second_stretch_list->Append(*second_stretch_value_from); @@ -444,16 +446,16 @@ CSSIdentifierValue* stretch_value = CSSIdentifierValue::Create(CSSValueID::kNormal); CSSPrimitiveValue* weight_value = - CSSPrimitiveValue::Create(400, CSSPrimitiveValue::UnitType::kNumber); + CSSNumericLiteralValue::Create(400, CSSPrimitiveValue::UnitType::kNumber); CSSIdentifierValue* oblique_keyword_value = CSSIdentifierValue::Create(CSSValueID::kOblique); CSSValueList* oblique_range = CSSValueList::CreateCommaSeparated(); CSSPrimitiveValue* oblique_from = - CSSPrimitiveValue::Create(30, CSSPrimitiveValue::UnitType::kNumber); + CSSNumericLiteralValue::Create(30, CSSPrimitiveValue::UnitType::kNumber); CSSPrimitiveValue* oblique_to = - CSSPrimitiveValue::Create(35, CSSPrimitiveValue::UnitType::kNumber); + CSSNumericLiteralValue::Create(35, CSSPrimitiveValue::UnitType::kNumber); oblique_range->Append(*oblique_from); oblique_range->Append(*oblique_to); auto* oblique_value = MakeGarbageCollected<CSSFontStyleRangeValue>( @@ -463,9 +465,9 @@ CSSValueList* oblique_range_second = CSSValueList::CreateCommaSeparated(); CSSPrimitiveValue* oblique_from_second = - CSSPrimitiveValue::Create(5, CSSPrimitiveValue::UnitType::kNumber); + CSSNumericLiteralValue::Create(5, CSSPrimitiveValue::UnitType::kNumber); CSSPrimitiveValue* oblique_to_second = - CSSPrimitiveValue::Create(10, CSSPrimitiveValue::UnitType::kNumber); + CSSNumericLiteralValue::Create(10, CSSPrimitiveValue::UnitType::kNumber); oblique_range_second->Append(*oblique_from_second); oblique_range_second->Append(*oblique_to_second); auto* oblique_value_second = MakeGarbageCollected<CSSFontStyleRangeValue>(
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_fast_paths.cc b/third_party/blink/renderer/core/css/parser/css_parser_fast_paths.cc index 9ac477d..3086876 100644 --- a/third_party/blink/renderer/core/css/parser/css_parser_fast_paths.cc +++ b/third_party/blink/renderer/core/css/parser/css_parser_fast_paths.cc
@@ -10,6 +10,7 @@ #include "third_party/blink/renderer/core/css/css_identifier_value.h" #include "third_party/blink/renderer/core/css/css_inherited_value.h" #include "third_party/blink/renderer/core/css/css_initial_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/css_unset_value.h" #include "third_party/blink/renderer/core/css/parser/css_parser_idioms.h" @@ -144,7 +145,7 @@ if (number < 0 && !accepts_negative_numbers) return nullptr; - return CSSPrimitiveValue::Create(number, unit); + return CSSNumericLiteralValue::Create(number, unit); } static inline bool IsColorPropertyID(CSSPropertyID property_id) { @@ -1152,7 +1153,7 @@ if (unit != CSSPrimitiveValue::UnitType::kPixels && (number || unit != CSSPrimitiveValue::UnitType::kNumber)) return false; - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( number, CSSPrimitiveValue::UnitType::kPixels)); pos += argument_length + 1; --expected_count; @@ -1175,7 +1176,7 @@ double number = CharactersToDouble(pos, argument_length, &ok); if (!ok) return false; - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( number, CSSPrimitiveValue::UnitType::kNumber)); pos += argument_length + 1; --expected_count;
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 9c17e8bf..c1b1386 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
@@ -12,6 +12,8 @@ #include "third_party/blink/renderer/core/css/css_image_set_value.h" #include "third_party/blink/renderer/core/css/css_image_value.h" #include "third_party/blink/renderer/core/css/css_initial_value.h" +#include "third_party/blink/renderer/core/css/css_math_function_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_paint_value.h" #include "third_party/blink/renderer/core/css/css_property_value.h" #include "third_party/blink/renderer/core/css/css_shadow_value.h" @@ -130,7 +132,7 @@ double max_allowed = is_percentage ? 100.0 : 1.0; if (To<CSSPrimitiveValue>(parsed_value)->GetDoubleValue() > max_allowed) { - parsed_value = CSSPrimitiveValue::Create( + parsed_value = CSSNumericLiteralValue::Create( max_allowed, is_percentage ? CSSPrimitiveValue::UnitType::kPercentage : CSSPrimitiveValue::UnitType::kNumber); @@ -202,7 +204,7 @@ if (!calc_value_) return nullptr; source_range_ = range_; - return CSSPrimitiveValue::Create(calc_value_.Release()); + return CSSMathFunctionValue::Create(calc_value_.Release()); } CSSPrimitiveValue* ConsumeRoundedInt() { @@ -212,7 +214,7 @@ CSSPrimitiveValue::UnitType unit_type = CSSPrimitiveValue::UnitType::kInteger; double rounded_value = floor(calc_value_->DoubleValue() + 0.5); - return CSSPrimitiveValue::Create(rounded_value, unit_type); + return CSSNumericLiteralValue::Create(rounded_value, unit_type); } CSSPrimitiveValue* ConsumeNumber() { @@ -222,7 +224,8 @@ CSSPrimitiveValue::UnitType unit_type = calc_value_->IsInt() ? CSSPrimitiveValue::UnitType::kInteger : CSSPrimitiveValue::UnitType::kNumber; - return CSSPrimitiveValue::Create(calc_value_->DoubleValue(), unit_type); + return CSSNumericLiteralValue::Create(calc_value_->DoubleValue(), + unit_type); } bool ConsumeNumberRaw(double& result) { @@ -246,7 +249,7 @@ if (token.GetNumericValueType() == kNumberValueType || token.NumericValue() < minimum_value) return nullptr; - return CSSPrimitiveValue::Create( + return CSSNumericLiteralValue::Create( range.ConsumeIncludingWhitespace().NumericValue(), CSSPrimitiveValue::UnitType::kInteger); } @@ -312,7 +315,7 @@ if (token.GetType() == kNumberToken) { if (value_range == kValueRangeNonNegative && token.NumericValue() < 0) return nullptr; - return CSSPrimitiveValue::Create( + return CSSNumericLiteralValue::Create( range.ConsumeIncludingWhitespace().NumericValue(), token.GetUnitType()); } CalcParser calc_parser(range, kValueRangeAll); @@ -368,7 +371,7 @@ } if (value_range == kValueRangeNonNegative && token.NumericValue() < 0) return nullptr; - return CSSPrimitiveValue::Create( + return CSSNumericLiteralValue::Create( range.ConsumeIncludingWhitespace().NumericValue(), token.GetUnitType()); } if (token.GetType() == kNumberToken) { @@ -380,7 +383,7 @@ CSSPrimitiveValue::UnitType::kPixels; if (css_parser_mode == kSVGAttributeMode) unit_type = CSSPrimitiveValue::UnitType::kUserUnits; - return CSSPrimitiveValue::Create( + return CSSNumericLiteralValue::Create( range.ConsumeIncludingWhitespace().NumericValue(), unit_type); } if (css_parser_mode == kSVGAttributeMode) @@ -397,7 +400,7 @@ if (token.GetType() == kPercentageToken) { if (value_range == kValueRangeNonNegative && token.NumericValue() < 0) return nullptr; - return CSSPrimitiveValue::Create( + return CSSNumericLiteralValue::Create( range.ConsumeIncludingWhitespace().NumericValue(), CSSPrimitiveValue::UnitType::kPercentage); } @@ -488,7 +491,7 @@ case CSSPrimitiveValue::UnitType::kRadians: case CSSPrimitiveValue::UnitType::kGradians: case CSSPrimitiveValue::UnitType::kTurns: - return CSSPrimitiveValue::Create( + return CSSNumericLiteralValue::Create( range.ConsumeIncludingWhitespace().NumericValue(), token.GetUnitType()); default: @@ -499,7 +502,8 @@ unitless_zero_feature) { range.ConsumeIncludingWhitespace(); context->Count(*unitless_zero_feature); - return CSSPrimitiveValue::Create(0, CSSPrimitiveValue::UnitType::kDegrees); + return CSSNumericLiteralValue::Create( + 0, CSSPrimitiveValue::UnitType::kDegrees); } CalcParser calc_parser(range, kValueRangeAll); if (const CSSCalcValue* calculation = calc_parser.Value()) { @@ -507,12 +511,12 @@ return nullptr; if (CSSPrimitiveValue* result = calc_parser.ConsumeValue()) { if (result->GetDoubleValue() < minimum_value) { - return CSSPrimitiveValue::Create(minimum_value, - result->TypeWithCalcResolved()); + return CSSNumericLiteralValue::Create(minimum_value, + result->TypeWithCalcResolved()); } if (result->GetDoubleValue() > maximum_value) { - return CSSPrimitiveValue::Create(maximum_value, - result->TypeWithCalcResolved()); + return CSSNumericLiteralValue::Create(maximum_value, + result->TypeWithCalcResolved()); } return result; } @@ -538,7 +542,7 @@ CSSPrimitiveValue::UnitType unit = token.GetUnitType(); if (unit == CSSPrimitiveValue::UnitType::kMilliseconds || unit == CSSPrimitiveValue::UnitType::kSeconds) - return CSSPrimitiveValue::Create( + return CSSNumericLiteralValue::Create( range.ConsumeIncludingWhitespace().NumericValue(), token.GetUnitType()); return nullptr; @@ -560,7 +564,7 @@ if (unit == CSSPrimitiveValue::UnitType::kDotsPerPixel || unit == CSSPrimitiveValue::UnitType::kDotsPerInch || unit == CSSPrimitiveValue::UnitType::kDotsPerCentimeter) { - return CSSPrimitiveValue::Create( + return CSSNumericLiteralValue::Create( range.ConsumeIncludingWhitespace().NumericValue(), unit); } return nullptr; @@ -1116,14 +1120,14 @@ if (args.Peek().GetType() == kIdentToken) { if ((horizontal && ConsumeIdent<CSSValueID::kLeft>(args)) || (!horizontal && ConsumeIdent<CSSValueID::kTop>(args))) - return CSSPrimitiveValue::Create( + return CSSNumericLiteralValue::Create( 0., CSSPrimitiveValue::UnitType::kPercentage); if ((horizontal && ConsumeIdent<CSSValueID::kRight>(args)) || (!horizontal && ConsumeIdent<CSSValueID::kBottom>(args))) - return CSSPrimitiveValue::Create( + return CSSNumericLiteralValue::Create( 100., CSSPrimitiveValue::UnitType::kPercentage); if (ConsumeIdent<CSSValueID::kCenter>(args)) - return CSSPrimitiveValue::Create( + return CSSNumericLiteralValue::Create( 50., CSSPrimitiveValue::UnitType::kPercentage); return nullptr; } @@ -1165,8 +1169,8 @@ return false; } - stop.offset_ = - CSSPrimitiveValue::Create(position, CSSPrimitiveValue::UnitType::kNumber); + stop.offset_ = CSSNumericLiteralValue::Create( + position, CSSPrimitiveValue::UnitType::kNumber); stop.color_ = ConsumeDeprecatedGradientStopColor(args, css_parser_mode); return stop.color_ && args.AtEnd(); } @@ -1550,12 +1554,12 @@ CSSPrimitiveValue* percentage = nullptr; if (CSSPrimitiveValue* percent_value = ConsumePercent(args, kValueRangeAll)) - percentage = CSSPrimitiveValue::Create( + percentage = CSSNumericLiteralValue::Create( clampTo<double>(percent_value->GetDoubleValue() / 100.0, 0, 1), CSSPrimitiveValue::UnitType::kNumber); else if (CSSPrimitiveValue* number_value = ConsumeNumber(args, kValueRangeAll)) - percentage = CSSPrimitiveValue::Create( + percentage = CSSNumericLiteralValue::Create( clampTo<double>(number_value->GetDoubleValue(), 0, 1), CSSPrimitiveValue::UnitType::kNumber); @@ -1695,7 +1699,7 @@ double image_scale_factor = token.NumericValue(); if (image_scale_factor <= 0) return nullptr; - image_set->Append(*CSSPrimitiveValue::Create( + image_set->Append(*CSSNumericLiteralValue::Create( image_scale_factor, CSSPrimitiveValue::UnitType::kNumber)); } while (ConsumeCommaIncludingWhitespace(args)); if (!args.AtEnd())
diff --git a/third_party/blink/renderer/core/css/properties/computed_style_utils.cc b/third_party/blink/renderer/core/css/properties/computed_style_utils.cc index a722dfde..fa8511a 100644 --- a/third_party/blink/renderer/core/css/properties/computed_style_utils.cc +++ b/third_party/blink/renderer/core/css/properties/computed_style_utils.cc
@@ -15,6 +15,7 @@ #include "third_party/blink/renderer/core/css/css_function_value.h" #include "third_party/blink/renderer/core/css/css_grid_line_names_value.h" #include "third_party/blink/renderer/core/css/css_initial_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value_mappings.h" #include "third_party/blink/renderer/core/css/css_quad_value.h" #include "third_party/blink/renderer/core/css/css_reflect_value.h" @@ -305,11 +306,12 @@ // TODO(alancutter): Make this code aware of calc lengths. if (image.ImageSlices().Top().IsPercentOrCalc()) { - top = CSSPrimitiveValue::Create(image.ImageSlices().Top().Value(), - CSSPrimitiveValue::UnitType::kPercentage); + top = CSSNumericLiteralValue::Create( + image.ImageSlices().Top().Value(), + CSSPrimitiveValue::UnitType::kPercentage); } else { - top = CSSPrimitiveValue::Create(image.ImageSlices().Top().Value(), - CSSPrimitiveValue::UnitType::kNumber); + top = CSSNumericLiteralValue::Create(image.ImageSlices().Top().Value(), + CSSPrimitiveValue::UnitType::kNumber); } if (image.ImageSlices().Right() == image.ImageSlices().Top() && @@ -320,12 +322,13 @@ left = top; } else { if (image.ImageSlices().Right().IsPercentOrCalc()) { - right = - CSSPrimitiveValue::Create(image.ImageSlices().Right().Value(), - CSSPrimitiveValue::UnitType::kPercentage); + right = CSSNumericLiteralValue::Create( + image.ImageSlices().Right().Value(), + CSSPrimitiveValue::UnitType::kPercentage); } else { - right = CSSPrimitiveValue::Create(image.ImageSlices().Right().Value(), - CSSPrimitiveValue::UnitType::kNumber); + right = + CSSNumericLiteralValue::Create(image.ImageSlices().Right().Value(), + CSSPrimitiveValue::UnitType::kNumber); } if (image.ImageSlices().Bottom() == image.ImageSlices().Top() && @@ -334,26 +337,26 @@ left = right; } else { if (image.ImageSlices().Bottom().IsPercentOrCalc()) { - bottom = - CSSPrimitiveValue::Create(image.ImageSlices().Bottom().Value(), - CSSPrimitiveValue::UnitType::kPercentage); + bottom = CSSNumericLiteralValue::Create( + image.ImageSlices().Bottom().Value(), + CSSPrimitiveValue::UnitType::kPercentage); } else { - bottom = - CSSPrimitiveValue::Create(image.ImageSlices().Bottom().Value(), - CSSPrimitiveValue::UnitType::kNumber); + bottom = CSSNumericLiteralValue::Create( + image.ImageSlices().Bottom().Value(), + CSSPrimitiveValue::UnitType::kNumber); } if (image.ImageSlices().Left() == image.ImageSlices().Right()) { left = right; } else { if (image.ImageSlices().Left().IsPercentOrCalc()) { - left = CSSPrimitiveValue::Create( + left = CSSNumericLiteralValue::Create( image.ImageSlices().Left().Value(), CSSPrimitiveValue::UnitType::kPercentage); } else { - left = - CSSPrimitiveValue::Create(image.ImageSlices().Left().Value(), - CSSPrimitiveValue::UnitType::kNumber); + left = CSSNumericLiteralValue::Create( + image.ImageSlices().Left().Value(), + CSSPrimitiveValue::UnitType::kNumber); } } } @@ -369,8 +372,8 @@ const BorderImageLength& border_image_length, const ComputedStyle& style) { if (border_image_length.IsNumber()) { - return CSSPrimitiveValue::Create(border_image_length.Number(), - CSSPrimitiveValue::UnitType::kNumber); + return CSSNumericLiteralValue::Create(border_image_length.Number(), + CSSPrimitiveValue::UnitType::kNumber); } return CSSValue::Create(border_image_length.length(), style.EffectiveZoom()); } @@ -477,9 +480,9 @@ CSSPrimitiveValue* offset = nullptr; // TODO(alancutter): Make this work correctly for calc lengths. if (reflection->Offset().IsPercentOrCalc()) { - offset = - CSSPrimitiveValue::Create(reflection->Offset().Percent(), - CSSPrimitiveValue::UnitType::kPercentage); + offset = CSSNumericLiteralValue::Create( + reflection->Offset().Percent(), + CSSPrimitiveValue::UnitType::kPercentage); } else { offset = ZoomAdjustedPixelValue(reflection->Offset().Value(), style); } @@ -585,8 +588,8 @@ // is negative right. So we get the opposite length unit and see if it is // auto. if (opposite.IsAuto()) { - return CSSPrimitiveValue::Create(0, - CSSPrimitiveValue::UnitType::kPixels); + return CSSNumericLiteralValue::Create( + 0, CSSPrimitiveValue::UnitType::kPixels); } if (opposite.IsPercentOrCalc()) { @@ -769,8 +772,9 @@ CSSPrimitiveValue* ComputedStyleUtils::ValueForFontStretch( const ComputedStyle& style) { - return CSSPrimitiveValue::Create(style.GetFontDescription().Stretch(), - CSSPrimitiveValue::UnitType::kPercentage); + return CSSNumericLiteralValue::Create( + style.GetFontDescription().Stretch(), + CSSPrimitiveValue::UnitType::kPercentage); } CSSValue* ComputedStyleUtils::ValueForFontStyle(const ComputedStyle& style) { @@ -787,16 +791,16 @@ // "20deg"', but since we compute that to 'italic' (handled above), // we don't perform any special treatment of that value here. CSSValueList* oblique_values = CSSValueList::CreateSpaceSeparated(); - oblique_values->Append( - *CSSPrimitiveValue::Create(angle, CSSPrimitiveValue::UnitType::kDegrees)); + oblique_values->Append(*CSSNumericLiteralValue::Create( + angle, CSSPrimitiveValue::UnitType::kDegrees)); return MakeGarbageCollected<CSSFontStyleRangeValue>( *CSSIdentifierValue::Create(CSSValueID::kOblique), *oblique_values); } CSSPrimitiveValue* ComputedStyleUtils::ValueForFontWeight( const ComputedStyle& style) { - return CSSPrimitiveValue::Create(style.GetFontDescription().Weight(), - CSSPrimitiveValue::UnitType::kNumber); + return CSSNumericLiteralValue::Create(style.GetFontDescription().Weight(), + CSSPrimitiveValue::UnitType::kNumber); } CSSIdentifierValue* ComputedStyleUtils::ValueForFontVariantCaps( @@ -1041,8 +1045,8 @@ CSSValue* SpecifiedValueForGridTrackBreadth(const GridLength& track_breadth, const ComputedStyle& style) { if (!track_breadth.IsLength()) { - return CSSPrimitiveValue::Create(track_breadth.Flex(), - CSSPrimitiveValue::UnitType::kFraction); + return CSSNumericLiteralValue::Create( + track_breadth.Flex(), CSSPrimitiveValue::UnitType::kFraction); } const Length& track_breadth_length = track_breadth.length(); @@ -1062,7 +1066,7 @@ case kMinMaxTrackSizing: { if (track_size.MinTrackBreadth().IsAuto() && track_size.MaxTrackBreadth().IsFlex()) { - return CSSPrimitiveValue::Create( + return CSSNumericLiteralValue::Create( track_size.MaxTrackBreadth().Flex(), CSSPrimitiveValue::UnitType::kFraction); } @@ -1282,10 +1286,10 @@ CSSValueList* list = CSSValueList::CreateSpaceSeparated(); if (position.IsSpan()) { list->Append(*CSSIdentifierValue::Create(CSSValueID::kSpan)); - list->Append(*CSSPrimitiveValue::Create( + list->Append(*CSSNumericLiteralValue::Create( position.SpanPosition(), CSSPrimitiveValue::UnitType::kNumber)); } else { - list->Append(*CSSPrimitiveValue::Create( + list->Append(*CSSNumericLiteralValue::Create( position.IntegerPosition(), CSSPrimitiveValue::UnitType::kNumber)); } @@ -1419,11 +1423,11 @@ CSSValueList* list = CSSValueList::CreateCommaSeparated(); if (timing_data) { for (wtf_size_t i = 0; i < timing_data->DelayList().size(); ++i) { - list->Append(*CSSPrimitiveValue::Create( + list->Append(*CSSNumericLiteralValue::Create( timing_data->DelayList()[i], CSSPrimitiveValue::UnitType::kSeconds)); } } else { - list->Append(*CSSPrimitiveValue::Create( + list->Append(*CSSNumericLiteralValue::Create( CSSTimingData::InitialDelay(), CSSPrimitiveValue::UnitType::kSeconds)); } return list; @@ -1451,14 +1455,14 @@ CSSValueList* list = CSSValueList::CreateCommaSeparated(); if (timing_data) { for (wtf_size_t i = 0; i < timing_data->DurationList().size(); ++i) { - list->Append( - *CSSPrimitiveValue::Create(timing_data->DurationList()[i], - CSSPrimitiveValue::UnitType::kSeconds)); + list->Append(*CSSNumericLiteralValue::Create( + timing_data->DurationList()[i], + CSSPrimitiveValue::UnitType::kSeconds)); } } else { list->Append( - *CSSPrimitiveValue::Create(CSSTimingData::InitialDuration(), - CSSPrimitiveValue::UnitType::kSeconds)); + *CSSNumericLiteralValue::Create(CSSTimingData::InitialDuration(), + CSSPrimitiveValue::UnitType::kSeconds)); } return list; } @@ -1484,8 +1488,8 @@ double iteration_count) { if (iteration_count == std::numeric_limits<double>::infinity()) return CSSIdentifierValue::Create(CSSValueID::kInfinite); - return CSSPrimitiveValue::Create(iteration_count, - CSSPrimitiveValue::UnitType::kNumber); + return CSSNumericLiteralValue::Create(iteration_count, + CSSPrimitiveValue::UnitType::kNumber); } CSSValue* ComputedStyleUtils::ValueForAnimationPlayState( @@ -1566,13 +1570,13 @@ const ComputedStyle& style) { CSSValueList* list = CSSValueList::CreateSpaceSeparated(); if (radius.Width().IsPercent()) { - list->Append(*CSSPrimitiveValue::Create( + list->Append(*CSSNumericLiteralValue::Create( radius.Width().Percent(), CSSPrimitiveValue::UnitType::kPercentage)); } else { list->Append(*ZoomAdjustedPixelValueForLength(radius.Width(), style)); } if (radius.Height().IsPercent()) { - list->Append(*CSSPrimitiveValue::Create( + list->Append(*CSSNumericLiteralValue::Create( radius.Height().Percent(), CSSPrimitiveValue::UnitType::kPercentage)); } else { list->Append(*ZoomAdjustedPixelValueForLength(radius.Height(), style)); @@ -1601,56 +1605,56 @@ transform_value = MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kMatrix); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.A(), CSSPrimitiveValue::UnitType::kNumber)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.B(), CSSPrimitiveValue::UnitType::kNumber)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.C(), CSSPrimitiveValue::UnitType::kNumber)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.D(), CSSPrimitiveValue::UnitType::kNumber)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.E(), CSSPrimitiveValue::UnitType::kNumber)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.F(), CSSPrimitiveValue::UnitType::kNumber)); } else { transform_value = MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kMatrix3d); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.M11(), CSSPrimitiveValue::UnitType::kNumber)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.M12(), CSSPrimitiveValue::UnitType::kNumber)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.M13(), CSSPrimitiveValue::UnitType::kNumber)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.M14(), CSSPrimitiveValue::UnitType::kNumber)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.M21(), CSSPrimitiveValue::UnitType::kNumber)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.M22(), CSSPrimitiveValue::UnitType::kNumber)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.M23(), CSSPrimitiveValue::UnitType::kNumber)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.M24(), CSSPrimitiveValue::UnitType::kNumber)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.M31(), CSSPrimitiveValue::UnitType::kNumber)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.M32(), CSSPrimitiveValue::UnitType::kNumber)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.M33(), CSSPrimitiveValue::UnitType::kNumber)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.M34(), CSSPrimitiveValue::UnitType::kNumber)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.M41(), CSSPrimitiveValue::UnitType::kNumber)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.M42(), CSSPrimitiveValue::UnitType::kNumber)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.M43(), CSSPrimitiveValue::UnitType::kNumber)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.M44(), CSSPrimitiveValue::UnitType::kNumber)); } @@ -1810,7 +1814,7 @@ list->Append(*MakeGarbageCollected<CSSCustomIdentValue>(item.key)); int32_t number = is_increment ? item.value.IncrementValue() : item.value.ResetValue(); - list->Append(*CSSPrimitiveValue::Create( + list->Append(*CSSNumericLiteralValue::Create( (double)number, CSSPrimitiveValue::UnitType::kInteger)); } @@ -1994,35 +1998,35 @@ case FilterOperation::GRAYSCALE: filter_value = MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kGrayscale); - filter_value->Append(*CSSPrimitiveValue::Create( + filter_value->Append(*CSSNumericLiteralValue::Create( To<BasicColorMatrixFilterOperation>(filter_operation)->Amount(), CSSPrimitiveValue::UnitType::kNumber)); break; case FilterOperation::SEPIA: filter_value = MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kSepia); - filter_value->Append(*CSSPrimitiveValue::Create( + filter_value->Append(*CSSNumericLiteralValue::Create( To<BasicColorMatrixFilterOperation>(filter_operation)->Amount(), CSSPrimitiveValue::UnitType::kNumber)); break; case FilterOperation::SATURATE: filter_value = MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kSaturate); - filter_value->Append(*CSSPrimitiveValue::Create( + filter_value->Append(*CSSNumericLiteralValue::Create( To<BasicColorMatrixFilterOperation>(filter_operation)->Amount(), CSSPrimitiveValue::UnitType::kNumber)); break; case FilterOperation::HUE_ROTATE: filter_value = MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kHueRotate); - filter_value->Append(*CSSPrimitiveValue::Create( + filter_value->Append(*CSSNumericLiteralValue::Create( To<BasicColorMatrixFilterOperation>(filter_operation)->Amount(), CSSPrimitiveValue::UnitType::kDegrees)); break; case FilterOperation::INVERT: filter_value = MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kInvert); - filter_value->Append(*CSSPrimitiveValue::Create( + filter_value->Append(*CSSNumericLiteralValue::Create( To<BasicComponentTransferFilterOperation>(filter_operation) ->Amount(), CSSPrimitiveValue::UnitType::kNumber)); @@ -2030,7 +2034,7 @@ case FilterOperation::OPACITY: filter_value = MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kOpacity); - filter_value->Append(*CSSPrimitiveValue::Create( + filter_value->Append(*CSSNumericLiteralValue::Create( To<BasicComponentTransferFilterOperation>(filter_operation) ->Amount(), CSSPrimitiveValue::UnitType::kNumber)); @@ -2038,7 +2042,7 @@ case FilterOperation::BRIGHTNESS: filter_value = MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kBrightness); - filter_value->Append(*CSSPrimitiveValue::Create( + filter_value->Append(*CSSNumericLiteralValue::Create( To<BasicComponentTransferFilterOperation>(filter_operation) ->Amount(), CSSPrimitiveValue::UnitType::kNumber)); @@ -2046,7 +2050,7 @@ case FilterOperation::CONTRAST: filter_value = MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kContrast); - filter_value->Append(*CSSPrimitiveValue::Create( + filter_value->Append(*CSSNumericLiteralValue::Create( To<BasicComponentTransferFilterOperation>(filter_operation) ->Amount(), CSSPrimitiveValue::UnitType::kNumber));
diff --git a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc index 7f7525dc..d7d96dfa 100644 --- a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc +++ b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
@@ -21,6 +21,7 @@ #include "third_party/blink/renderer/core/css/css_grid_template_areas_value.h" #include "third_party/blink/renderer/core/css/css_identifier_value.h" #include "third_party/blink/renderer/core/css/css_initial_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_path_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/css_property_names.h" @@ -395,7 +396,7 @@ return false; } context.Count(WebFeature::kUnitlessPerspectiveInTransformProperty); - parsed_value = CSSPrimitiveValue::Create( + parsed_value = CSSNumericLiteralValue::Create( perspective, CSSPrimitiveValue::UnitType::kPixels); } if (!parsed_value) @@ -1296,7 +1297,8 @@ value = clampTo<int>(counter_value->GetDoubleValue()); list->Append(*MakeGarbageCollected<CSSValuePair>( counter_name, - CSSPrimitiveValue::Create(value, CSSPrimitiveValue::UnitType::kInteger), + CSSNumericLiteralValue::Create(value, + CSSPrimitiveValue::UnitType::kInteger), CSSValuePair::kDropIdenticalValues)); } while (!range.AtEnd()); return list; @@ -1609,7 +1611,7 @@ token.GetUnitType() == CSSPrimitiveValue::UnitType::kFraction) { if (range.Peek().NumericValue() < 0) return nullptr; - return CSSPrimitiveValue::Create( + return CSSNumericLiteralValue::Create( range.ConsumeIncludingWhitespace().NumericValue(), CSSPrimitiveValue::UnitType::kFraction); } @@ -1904,7 +1906,7 @@ // invalid. if (numeric_value) { - numeric_value = CSSPrimitiveValue::Create( + numeric_value = CSSNumericLiteralValue::Create( clampTo(numeric_value->GetIntValue(), -kGridMaxTracks, kGridMaxTracks), CSSPrimitiveValue::UnitType::kInteger); }
diff --git a/third_party/blink/renderer/core/css/properties/css_parsing_utils.h b/third_party/blink/renderer/core/css/properties/css_parsing_utils.h index bfe84e38..8cac7f3 100644 --- a/third_party/blink/renderer/core/css/properties/css_parsing_utils.h +++ b/third_party/blink/renderer/core/css/properties/css_parsing_utils.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PROPERTIES_CSS_PARSING_UTILS_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PROPERTIES_CSS_PARSING_UTILS_H_ +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/parser/css_parser_mode.h" #include "third_party/blink/renderer/core/css/parser/css_parser_token_range.h" #include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h" @@ -255,8 +256,8 @@ else return nullptr; range.ConsumeIncludingWhitespace(); - return CSSPrimitiveValue::Create(percent, - CSSPrimitiveValue::UnitType::kPercentage); + return CSSNumericLiteralValue::Create( + percent, CSSPrimitiveValue::UnitType::kPercentage); } return css_property_parser_helpers::ConsumeLengthOrPercent( range, css_parser_mode, kValueRangeAll);
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 47e99b6..1aed7ef 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
@@ -14,6 +14,7 @@ #include "third_party/blink/renderer/core/css/css_grid_template_areas_value.h" #include "third_party/blink/renderer/core/css/css_identifier_value.h" #include "third_party/blink/renderer/core/css/css_layout_function_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value_mappings.h" #include "third_party/blink/renderer/core/css/css_quad_value.h" @@ -146,8 +147,8 @@ const CSSValue* AnimationDelay::InitialValue() const { DEFINE_STATIC_LOCAL( const Persistent<CSSValue>, value, - (CSSPrimitiveValue::Create(CSSTimingData::InitialDelay(), - CSSPrimitiveValue::UnitType::kSeconds))); + (CSSNumericLiteralValue::Create(CSSTimingData::InitialDelay(), + CSSPrimitiveValue::UnitType::kSeconds))); return value; } @@ -207,8 +208,8 @@ const CSSValue* AnimationDuration::InitialValue() const { DEFINE_STATIC_LOCAL( const Persistent<CSSValue>, value, - (CSSPrimitiveValue::Create(CSSTimingData::InitialDuration(), - CSSPrimitiveValue::UnitType::kSeconds))); + (CSSNumericLiteralValue::Create(CSSTimingData::InitialDuration(), + CSSPrimitiveValue::UnitType::kSeconds))); return value; } @@ -279,8 +280,8 @@ const CSSValue* AnimationIterationCount::InitialValue() const { DEFINE_STATIC_LOCAL( const Persistent<CSSValue>, value, - (CSSPrimitiveValue::Create(CSSAnimationData::InitialIterationCount(), - CSSPrimitiveValue::UnitType::kNumber))); + (CSSNumericLiteralValue::Create(CSSAnimationData::InitialIterationCount(), + CSSPrimitiveValue::UnitType::kNumber))); return value; } @@ -829,9 +830,9 @@ const CSSValue* BorderImageOutset::InitialValue() const { DEFINE_STATIC_LOCAL( const Persistent<CSSQuadValue>, value, - (CSSQuadValue::Create( - CSSPrimitiveValue::Create(0, CSSPrimitiveValue::UnitType::kInteger), - CSSQuadValue::kSerializeAsQuad))); + (CSSQuadValue::Create(CSSNumericLiteralValue::Create( + 0, CSSPrimitiveValue::UnitType::kInteger), + CSSQuadValue::kSerializeAsQuad))); return value; } @@ -879,7 +880,7 @@ const Persistent<CSSBorderImageSliceValue>, value, (MakeGarbageCollected<CSSBorderImageSliceValue>( CSSQuadValue::Create( - CSSPrimitiveValue::Create( + CSSNumericLiteralValue::Create( 100, CSSPrimitiveValue::UnitType::kPercentage), CSSQuadValue::kSerializeAsQuad), /* fill */ false))); @@ -936,9 +937,9 @@ const CSSValue* BorderImageWidth::InitialValue() const { DEFINE_STATIC_LOCAL( const Persistent<CSSQuadValue>, value, - (CSSQuadValue::Create( - CSSPrimitiveValue::Create(1, CSSPrimitiveValue::UnitType::kInteger), - CSSQuadValue::kSerializeAsQuad))); + (CSSQuadValue::Create(CSSNumericLiteralValue::Create( + 1, CSSPrimitiveValue::UnitType::kInteger), + CSSQuadValue::kSerializeAsQuad))); return value; } @@ -1635,8 +1636,8 @@ bool allow_visited_style) const { if (style.HasAutoColumnCount()) return CSSIdentifierValue::Create(CSSValueID::kAuto); - return CSSPrimitiveValue::Create(style.ColumnCount(), - CSSPrimitiveValue::UnitType::kNumber); + return CSSNumericLiteralValue::Create(style.ColumnCount(), + CSSPrimitiveValue::UnitType::kNumber); } const CSSValue* ColumnFill::CSSValueFromComputedStyleInternal( @@ -2395,8 +2396,8 @@ const LayoutObject*, Node*, bool allow_visited_style) const { - return CSSPrimitiveValue::Create(svg_style.FillOpacity(), - CSSPrimitiveValue::UnitType::kNumber); + return CSSNumericLiteralValue::Create(svg_style.FillOpacity(), + CSSPrimitiveValue::UnitType::kNumber); } const CSSValue* FillRule::CSSValueFromComputedStyleInternal( @@ -2466,8 +2467,8 @@ const LayoutObject*, Node*, bool allow_visited_style) const { - return CSSPrimitiveValue::Create(style.FlexGrow(), - CSSPrimitiveValue::UnitType::kNumber); + return CSSNumericLiteralValue::Create(style.FlexGrow(), + CSSPrimitiveValue::UnitType::kNumber); } const CSSValue* FlexShrink::ParseSingleValue( @@ -2484,8 +2485,8 @@ const LayoutObject*, Node*, bool allow_visited_style) const { - return CSSPrimitiveValue::Create(style.FlexShrink(), - CSSPrimitiveValue::UnitType::kNumber); + return CSSNumericLiteralValue::Create(style.FlexShrink(), + CSSPrimitiveValue::UnitType::kNumber); } const CSSValue* FlexWrap::CSSValueFromComputedStyleInternal( @@ -2547,8 +2548,8 @@ const LayoutObject*, Node*, bool allow_visited_style) const { - return CSSPrimitiveValue::Create(svg_style.FloodOpacity(), - CSSPrimitiveValue::UnitType::kNumber); + return CSSNumericLiteralValue::Create(svg_style.FloodOpacity(), + CSSPrimitiveValue::UnitType::kNumber); } const CSSValue* FontFamily::ParseSingleValue( @@ -2621,8 +2622,8 @@ Node* styled_node, bool allow_visited_style) const { if (style.HasFontSizeAdjust()) { - return CSSPrimitiveValue::Create(style.FontSizeAdjust(), - CSSPrimitiveValue::UnitType::kNumber); + return CSSNumericLiteralValue::Create(style.FontSizeAdjust(), + CSSPrimitiveValue::UnitType::kNumber); } return CSSIdentifierValue::Create(CSSValueID::kNone); } @@ -3277,7 +3278,8 @@ bool allow_visited_style) const { if (style.RespectImageOrientation() == kRespectImageOrientation) return CSSIdentifierValue::Create(CSSValueID::kFromImage); - return CSSPrimitiveValue::Create(0, CSSPrimitiveValue::UnitType::kDegrees); + return CSSNumericLiteralValue::Create(0, + CSSPrimitiveValue::UnitType::kDegrees); } const CSSValue* ImageRendering::CSSValueFromComputedStyleInternal( @@ -4361,7 +4363,7 @@ CSSValueList* list = CSSValueList::CreateSpaceSeparated(); if (style.OffsetRotate().type == OffsetRotationType::kAuto) list->Append(*CSSIdentifierValue::Create(CSSValueID::kAuto)); - list->Append(*CSSPrimitiveValue::Create( + list->Append(*CSSNumericLiteralValue::Create( style.OffsetRotate().angle, CSSPrimitiveValue::UnitType::kDegrees)); return list; } @@ -4378,8 +4380,8 @@ const LayoutObject*, Node*, bool allow_visited_style) const { - return CSSPrimitiveValue::Create(style.Opacity(), - CSSPrimitiveValue::UnitType::kNumber); + return CSSNumericLiteralValue::Create(style.Opacity(), + CSSPrimitiveValue::UnitType::kNumber); } const CSSValue* Order::ParseSingleValue(CSSParserTokenRange& range, @@ -4394,8 +4396,8 @@ const LayoutObject*, Node*, bool allow_visited_style) const { - return CSSPrimitiveValue::Create(style.Order(), - CSSPrimitiveValue::UnitType::kNumber); + return CSSNumericLiteralValue::Create(style.Order(), + CSSPrimitiveValue::UnitType::kNumber); } const CSSValue* Orphans::ParseSingleValue(CSSParserTokenRange& range, @@ -4410,8 +4412,8 @@ const LayoutObject*, Node*, bool allow_visited_style) const { - return CSSPrimitiveValue::Create(style.Orphans(), - CSSPrimitiveValue::UnitType::kNumber); + return CSSNumericLiteralValue::Create(style.Orphans(), + CSSPrimitiveValue::UnitType::kNumber); } const CSSValue* OutlineColor::ParseSingleValue( @@ -4832,7 +4834,7 @@ if (!css_property_parser_helpers::ConsumeNumberRaw(range, perspective)) return nullptr; context.Count(WebFeature::kUnitlessPerspectiveInPerspectiveProperty); - parsed_value = CSSPrimitiveValue::Create( + parsed_value = CSSNumericLiteralValue::Create( perspective, CSSPrimitiveValue::UnitType::kPixels); } if (parsed_value && @@ -5070,14 +5072,14 @@ CSSValueList* list = CSSValueList::CreateSpaceSeparated(); if (style.Rotate()->X() != 0 || style.Rotate()->Y() != 0 || style.Rotate()->Z() != 1) { - list->Append(*CSSPrimitiveValue::Create( + list->Append(*CSSNumericLiteralValue::Create( style.Rotate()->X(), CSSPrimitiveValue::UnitType::kNumber)); - list->Append(*CSSPrimitiveValue::Create( + list->Append(*CSSNumericLiteralValue::Create( style.Rotate()->Y(), CSSPrimitiveValue::UnitType::kNumber)); - list->Append(*CSSPrimitiveValue::Create( + list->Append(*CSSNumericLiteralValue::Create( style.Rotate()->Z(), CSSPrimitiveValue::UnitType::kNumber)); } - list->Append(*CSSPrimitiveValue::Create( + list->Append(*CSSNumericLiteralValue::Create( style.Rotate()->Angle(), CSSPrimitiveValue::UnitType::kDegrees)); return list; } @@ -5170,12 +5172,12 @@ if (!style.Scale()) return CSSIdentifierValue::Create(CSSValueID::kNone); CSSValueList* list = CSSValueList::CreateSpaceSeparated(); - list->Append(*CSSPrimitiveValue::Create( + list->Append(*CSSNumericLiteralValue::Create( style.Scale()->X(), CSSPrimitiveValue::UnitType::kNumber)); - list->Append(*CSSPrimitiveValue::Create( + list->Append(*CSSNumericLiteralValue::Create( style.Scale()->Y(), CSSPrimitiveValue::UnitType::kNumber)); if (style.Scale()->Z() != 1) { - list->Append(*CSSPrimitiveValue::Create( + list->Append(*CSSNumericLiteralValue::Create( style.Scale()->Z(), CSSPrimitiveValue::UnitType::kNumber)); } return list; @@ -5548,8 +5550,8 @@ const LayoutObject*, Node*, bool allow_visited_style) const { - return CSSPrimitiveValue::Create(style.ShapeImageThreshold(), - CSSPrimitiveValue::UnitType::kNumber); + return CSSNumericLiteralValue::Create(style.ShapeImageThreshold(), + CSSPrimitiveValue::UnitType::kNumber); } const CSSValue* ShapeMargin::ParseSingleValue( @@ -5797,8 +5799,8 @@ const LayoutObject*, Node*, bool allow_visited_style) const { - return CSSPrimitiveValue::Create(svg_style.StopOpacity(), - CSSPrimitiveValue::UnitType::kNumber); + return CSSNumericLiteralValue::Create(svg_style.StopOpacity(), + CSSPrimitiveValue::UnitType::kNumber); } const CSSValue* Stroke::ParseSingleValue(CSSParserTokenRange& range, @@ -5900,8 +5902,8 @@ const LayoutObject*, Node*, bool allow_visited_style) const { - return CSSPrimitiveValue::Create(svg_style.StrokeMiterLimit(), - CSSPrimitiveValue::UnitType::kNumber); + return CSSNumericLiteralValue::Create(svg_style.StrokeMiterLimit(), + CSSPrimitiveValue::UnitType::kNumber); } const CSSValue* StrokeOpacity::ParseSingleValue( @@ -5917,8 +5919,8 @@ const LayoutObject*, Node*, bool allow_visited_style) const { - return CSSPrimitiveValue::Create(svg_style.StrokeOpacity(), - CSSPrimitiveValue::UnitType::kNumber); + return CSSNumericLiteralValue::Create(svg_style.StrokeOpacity(), + CSSPrimitiveValue::UnitType::kNumber); } const CSSValue* StrokeWidth::ParseSingleValue( @@ -5938,8 +5940,8 @@ bool allow_visited_style) const { const Length& length = svg_style.StrokeWidth().length(); if (length.IsFixed()) { - return CSSPrimitiveValue::Create(length.Value(), - CSSPrimitiveValue::UnitType::kPixels); + return CSSNumericLiteralValue::Create(length.Value(), + CSSPrimitiveValue::UnitType::kPixels); } return CSSValue::Create(length, style.EffectiveZoom()); } @@ -5961,10 +5963,10 @@ const LayoutObject*, Node*, bool allow_visited_style) const { - return CSSPrimitiveValue::Create(style.GetTabSize().GetPixelSize(1.0), - style.GetTabSize().IsSpaces() - ? CSSPrimitiveValue::UnitType::kNumber - : CSSPrimitiveValue::UnitType::kPixels); + return CSSNumericLiteralValue::Create( + style.GetTabSize().GetPixelSize(1.0), + style.GetTabSize().IsSpaces() ? CSSPrimitiveValue::UnitType::kNumber + : CSSPrimitiveValue::UnitType::kPixels); } const CSSValue* TableLayout::CSSValueFromComputedStyleInternal( @@ -6291,8 +6293,9 @@ bool allow_visited_style) const { if (style.GetTextSizeAdjust().IsAuto()) return CSSIdentifierValue::Create(CSSValueID::kAuto); - return CSSPrimitiveValue::Create(style.GetTextSizeAdjust().Multiplier() * 100, - CSSPrimitiveValue::UnitType::kPercentage); + return CSSNumericLiteralValue::Create( + style.GetTextSizeAdjust().Multiplier() * 100, + CSSPrimitiveValue::UnitType::kPercentage); } const CSSValue* TextTransform::CSSValueFromComputedStyleInternal( @@ -6565,8 +6568,8 @@ const CSSValue* TransitionDelay::InitialValue() const { DEFINE_STATIC_LOCAL( const Persistent<CSSValue>, value, - (CSSPrimitiveValue::Create(CSSTimingData::InitialDelay(), - CSSPrimitiveValue::UnitType::kSeconds))); + (CSSNumericLiteralValue::Create(CSSTimingData::InitialDelay(), + CSSPrimitiveValue::UnitType::kSeconds))); return value; } @@ -6590,8 +6593,8 @@ const CSSValue* TransitionDuration::InitialValue() const { DEFINE_STATIC_LOCAL( const Persistent<CSSValue>, value, - (CSSPrimitiveValue::Create(CSSTimingData::InitialDuration(), - CSSPrimitiveValue::UnitType::kSeconds))); + (CSSNumericLiteralValue::Create(CSSTimingData::InitialDuration(), + CSSPrimitiveValue::UnitType::kSeconds))); return value; } @@ -6949,8 +6952,8 @@ const LayoutObject*, Node*, bool allow_visited_style) const { - return CSSPrimitiveValue::Create(style.BoxFlex(), - CSSPrimitiveValue::UnitType::kNumber); + return CSSNumericLiteralValue::Create(style.BoxFlex(), + CSSPrimitiveValue::UnitType::kNumber); } const CSSValue* WebkitBoxOrdinalGroup::ParseSingleValue( @@ -6966,8 +6969,8 @@ const LayoutObject*, Node*, bool allow_visited_style) const { - return CSSPrimitiveValue::Create(style.BoxOrdinalGroup(), - CSSPrimitiveValue::UnitType::kNumber); + return CSSNumericLiteralValue::Create(style.BoxOrdinalGroup(), + CSSPrimitiveValue::UnitType::kNumber); } const CSSValue* WebkitBoxOrient::CSSValueFromComputedStyleInternal( @@ -7000,7 +7003,8 @@ CSSPrimitiveValue* offset = nullptr; if (range.AtEnd()) { - offset = CSSPrimitiveValue::Create(0, CSSPrimitiveValue::UnitType::kPixels); + offset = + CSSNumericLiteralValue::Create(0, CSSPrimitiveValue::UnitType::kPixels); } else { offset = ConsumeLengthOrPercent( range, context.Mode(), kValueRangeAll, @@ -7120,8 +7124,8 @@ bool allow_visited_style) const { if (!style.HasLineClamp()) return CSSIdentifierValue::Create(CSSValueID::kNone); - return CSSPrimitiveValue::Create(style.LineClamp(), - CSSPrimitiveValue::UnitType::kNumber); + return CSSNumericLiteralValue::Create(style.LineClamp(), + CSSPrimitiveValue::UnitType::kNumber); } const CSSValue* WebkitLocale::ParseSingleValue( @@ -7931,8 +7935,8 @@ const LayoutObject*, Node*, bool allow_visited_style) const { - return CSSPrimitiveValue::Create(style.Widows(), - CSSPrimitiveValue::UnitType::kNumber); + return CSSNumericLiteralValue::Create(style.Widows(), + CSSPrimitiveValue::UnitType::kNumber); } const CSSValue* Width::ParseSingleValue(CSSParserTokenRange& range, @@ -8169,8 +8173,8 @@ bool allow_visited_style) const { if (style.HasAutoZIndex() || !style.IsStackingContext()) return CSSIdentifierValue::Create(CSSValueID::kAuto); - return CSSPrimitiveValue::Create(style.ZIndex(), - CSSPrimitiveValue::UnitType::kInteger); + return CSSNumericLiteralValue::Create(style.ZIndex(), + CSSPrimitiveValue::UnitType::kInteger); } const CSSValue* Zoom::ParseSingleValue(CSSParserTokenRange& range, @@ -8206,8 +8210,8 @@ const LayoutObject*, Node*, bool allow_visited_style) const { - return CSSPrimitiveValue::Create(style.Zoom(), - CSSPrimitiveValue::UnitType::kNumber); + return CSSNumericLiteralValue::Create(style.Zoom(), + CSSPrimitiveValue::UnitType::kNumber); } void Zoom::ApplyInitial(StyleResolverState& state) const {
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/shorthands_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/shorthands_custom.cc index eef5e2f..af3c16b 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/shorthands_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/shorthands_custom.cc
@@ -6,6 +6,7 @@ #include "third_party/blink/renderer/core/css/css_font_family_value.h" #include "third_party/blink/renderer/core/css/css_identifier_value.h" #include "third_party/blink/renderer/core/css/css_initial_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value_mappings.h" #include "third_party/blink/renderer/core/css/css_property_value.h" #include "third_party/blink/renderer/core/css/css_value_pair.h" @@ -110,13 +111,13 @@ CSSValueList* animations_list = CSSValueList::CreateCommaSeparated(); for (wtf_size_t i = 0; i < animation_data->NameList().size(); ++i) { CSSValueList* list = CSSValueList::CreateSpaceSeparated(); - list->Append(*CSSPrimitiveValue::Create( + list->Append(*CSSNumericLiteralValue::Create( CSSTimingData::GetRepeated(animation_data->DurationList(), i), CSSPrimitiveValue::UnitType::kSeconds)); list->Append(*ComputedStyleUtils::CreateTimingFunctionValue( CSSTimingData::GetRepeated(animation_data->TimingFunctionList(), i) .get())); - list->Append(*CSSPrimitiveValue::Create( + list->Append(*CSSNumericLiteralValue::Create( CSSTimingData::GetRepeated(animation_data->DelayList(), i), CSSPrimitiveValue::UnitType::kSeconds)); list->Append(*ComputedStyleUtils::ValueForAnimationIterationCount( @@ -138,15 +139,15 @@ // animation-name default value. list->Append(*CSSIdentifierValue::Create(CSSValueID::kNone)); list->Append( - *CSSPrimitiveValue::Create(CSSAnimationData::InitialDuration(), - CSSPrimitiveValue::UnitType::kSeconds)); + *CSSNumericLiteralValue::Create(CSSAnimationData::InitialDuration(), + CSSPrimitiveValue::UnitType::kSeconds)); list->Append(*ComputedStyleUtils::CreateTimingFunctionValue( CSSAnimationData::InitialTimingFunction().get())); - list->Append(*CSSPrimitiveValue::Create( + list->Append(*CSSNumericLiteralValue::Create( CSSAnimationData::InitialDelay(), CSSPrimitiveValue::UnitType::kSeconds)); list->Append( - *CSSPrimitiveValue::Create(CSSAnimationData::InitialIterationCount(), - CSSPrimitiveValue::UnitType::kNumber)); + *CSSNumericLiteralValue::Create(CSSAnimationData::InitialIterationCount(), + CSSPrimitiveValue::UnitType::kNumber)); list->Append(*ComputedStyleUtils::ValueForAnimationDirection( CSSAnimationData::InitialDirection())); list->Append(*ComputedStyleUtils::ValueForAnimationFillMode( @@ -957,7 +958,7 @@ // flex only allows a basis of 0 (sans units) if // flex-grow and flex-shrink values have already been // set. - flex_basis = CSSPrimitiveValue::Create( + flex_basis = CSSNumericLiteralValue::Create( 0, CSSPrimitiveValue::UnitType::kPixels); } else { return false; @@ -980,7 +981,7 @@ if (flex_shrink == kUnsetValue) flex_shrink = 1; if (!flex_basis) { - flex_basis = CSSPrimitiveValue::Create( + flex_basis = CSSNumericLiteralValue::Create( 0, CSSPrimitiveValue::UnitType::kPercentage); } } @@ -989,14 +990,14 @@ return false; css_property_parser_helpers::AddProperty( CSSPropertyID::kFlexGrow, CSSPropertyID::kFlex, - *CSSPrimitiveValue::Create(clampTo<float>(flex_grow), - CSSPrimitiveValue::UnitType::kNumber), + *CSSNumericLiteralValue::Create(clampTo<float>(flex_grow), + CSSPrimitiveValue::UnitType::kNumber), important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit, properties); css_property_parser_helpers::AddProperty( CSSPropertyID::kFlexShrink, CSSPropertyID::kFlex, - *CSSPrimitiveValue::Create(clampTo<float>(flex_shrink), - CSSPrimitiveValue::UnitType::kNumber), + *CSSNumericLiteralValue::Create(clampTo<float>(flex_shrink), + CSSPrimitiveValue::UnitType::kNumber), important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit, properties); @@ -1065,14 +1066,14 @@ properties); css_property_parser_helpers::AddProperty( CSSPropertyID::kFontWeight, CSSPropertyID::kFont, - *CSSPrimitiveValue::Create(font_weight, - CSSPrimitiveValue::UnitType::kNumber), + *CSSNumericLiteralValue::Create(font_weight, + CSSPrimitiveValue::UnitType::kNumber), important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit, properties); css_property_parser_helpers::AddProperty( CSSPropertyID::kFontSize, CSSPropertyID::kFont, - *CSSPrimitiveValue::Create(font_size, - CSSPrimitiveValue::UnitType::kPixels), + *CSSNumericLiteralValue::Create(font_size, + CSSPrimitiveValue::UnitType::kPixels), important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit, properties); @@ -2909,13 +2910,13 @@ CSSValueList* list = CSSValueList::CreateSpaceSeparated(); list->Append(*ComputedStyleUtils::CreateTransitionPropertyValue( transition_data->PropertyList()[i])); - list->Append(*CSSPrimitiveValue::Create( + list->Append(*CSSNumericLiteralValue::Create( CSSTimingData::GetRepeated(transition_data->DurationList(), i), CSSPrimitiveValue::UnitType::kSeconds)); list->Append(*ComputedStyleUtils::CreateTimingFunctionValue( CSSTimingData::GetRepeated(transition_data->TimingFunctionList(), i) .get())); - list->Append(*CSSPrimitiveValue::Create( + list->Append(*CSSNumericLiteralValue::Create( CSSTimingData::GetRepeated(transition_data->DelayList(), i), CSSPrimitiveValue::UnitType::kSeconds)); transitions_list->Append(*list); @@ -2927,13 +2928,13 @@ // transition-property default value. list->Append(*CSSIdentifierValue::Create(CSSValueID::kAll)); list->Append( - *CSSPrimitiveValue::Create(CSSTransitionData::InitialDuration(), - CSSPrimitiveValue::UnitType::kSeconds)); + *CSSNumericLiteralValue::Create(CSSTransitionData::InitialDuration(), + CSSPrimitiveValue::UnitType::kSeconds)); list->Append(*ComputedStyleUtils::CreateTimingFunctionValue( CSSTransitionData::InitialTimingFunction().get())); list->Append( - *CSSPrimitiveValue::Create(CSSTransitionData::InitialDelay(), - CSSPrimitiveValue::UnitType::kSeconds)); + *CSSNumericLiteralValue::Create(CSSTransitionData::InitialDelay(), + CSSPrimitiveValue::UnitType::kSeconds)); return list; }
diff --git a/third_party/blink/renderer/core/css/resolver/css_variable_resolver_test.cc b/third_party/blink/renderer/core/css/resolver/css_variable_resolver_test.cc index 5abadf99..c7d3d620 100644 --- a/third_party/blink/renderer/core/css/resolver/css_variable_resolver_test.cc +++ b/third_party/blink/renderer/core/css/resolver/css_variable_resolver_test.cc
@@ -6,6 +6,7 @@ #include "third_party/blink/renderer/core/css/css_custom_property_declaration.h" #include "third_party/blink/renderer/core/css/css_inherited_value.h" #include "third_party/blink/renderer/core/css/css_initial_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_syntax_string_parser.h" #include "third_party/blink/renderer/core/css/css_unset_value.h" #include "third_party/blink/renderer/core/css/css_variable_reference_value.h" @@ -108,7 +109,8 @@ } const CSSValue* CreatePxValue(double px) { - return CSSPrimitiveValue::Create(px, CSSPrimitiveValue::UnitType::kPixels); + return CSSNumericLiteralValue::Create(px, + CSSPrimitiveValue::UnitType::kPixels); } size_t MaxSubstitutionTokens() const {
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc index 01e53b7d..fcc8b5a 100644 --- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc +++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
@@ -42,6 +42,7 @@ #include "third_party/blink/renderer/core/css/css_font_variation_value.h" #include "third_party/blink/renderer/core/css/css_grid_auto_repeat_value.h" #include "third_party/blink/renderer/core/css/css_grid_integer_repeat_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_path_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value_mappings.h" #include "third_party/blink/renderer/core/css/css_quad_value.h" @@ -1465,8 +1466,8 @@ auto* identifier_value = DynamicTo<CSSIdentifierValue>(value); if (identifier_value && IsValidCSSValueID(identifier_value->GetValueID())) { float multiplier = ConvertLineWidth<float>(state, value); - return CSSPrimitiveValue::Create(multiplier / 48, - CSSPrimitiveValue::UnitType::kEms) + return CSSNumericLiteralValue::Create(multiplier / 48, + CSSPrimitiveValue::UnitType::kEms) ->ComputeLength<float>(state.CssToLengthConversionData()); } return To<CSSPrimitiveValue>(value).ComputeLength<float>( @@ -1726,7 +1727,7 @@ // Instead of the actual zoom, use 1 to avoid potential rounding errors Length length = primitive_value->ConvertToLength( css_to_length_conversion_data.CopyWithAdjustedZoom(1)); - return *CSSPrimitiveValue::Create(length, 1); + return *CSSPrimitiveValue::CreateFromLength(length, 1); } // If we encounter a calculated number that was not resolved during @@ -1739,21 +1740,24 @@ CSSPrimitiveValue::UnitType::kNumber)) { double double_value = primitive_value->CssCalcValue()->DoubleValue(); auto unit_type = CSSPrimitiveValue::UnitType::kInteger; - return *CSSPrimitiveValue::Create(std::round(double_value), unit_type); + return *CSSNumericLiteralValue::Create(std::round(double_value), + unit_type); } if (primitive_value->IsAngle()) { - return *CSSPrimitiveValue::Create(primitive_value->ComputeDegrees(), - CSSPrimitiveValue::UnitType::kDegrees); + return *CSSNumericLiteralValue::Create( + primitive_value->ComputeDegrees(), + CSSPrimitiveValue::UnitType::kDegrees); } if (primitive_value->IsTime()) { - return *CSSPrimitiveValue::Create(primitive_value->ComputeSeconds(), - CSSPrimitiveValue::UnitType::kSeconds); + return *CSSNumericLiteralValue::Create( + primitive_value->ComputeSeconds(), + CSSPrimitiveValue::UnitType::kSeconds); } if (primitive_value->IsResolution()) { - return *CSSPrimitiveValue::Create( + return *CSSNumericLiteralValue::Create( primitive_value->ComputeDotsPerPixel(), CSSPrimitiveValue::UnitType::kDotsPerPixel); }
diff --git a/third_party/blink/renderer/core/css/threaded/css_to_length_conversion_data_threaded_test.cc b/third_party/blink/renderer/core/css/threaded/css_to_length_conversion_data_threaded_test.cc index afa544e..6f1fd9ad 100644 --- a/third_party/blink/renderer/core/css/threaded/css_to_length_conversion_data_threaded_test.cc +++ b/third_party/blink/renderer/core/css/threaded/css_to_length_conversion_data_threaded_test.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/threaded/multi_threaded_test_util.h" #include "third_party/blink/renderer/platform/fonts/font.h" #include "third_party/blink/renderer/platform/fonts/font_description.h" @@ -32,8 +33,8 @@ CSSToLengthConversionData conversionData(nullptr, fontSizes, viewportSize, 1); - CSSPrimitiveValue& value = - *CSSPrimitiveValue::Create(3.14, CSSPrimitiveValue::UnitType::kEms); + CSSPrimitiveValue& value = *CSSNumericLiteralValue::Create( + 3.14, CSSPrimitiveValue::UnitType::kEms); Length length = value.ConvertToLength(conversionData); EXPECT_EQ(length.Value(), 50.24f); @@ -49,8 +50,8 @@ CSSToLengthConversionData conversionData(nullptr, fontSizes, viewportSize, 1); - CSSPrimitiveValue& value = - *CSSPrimitiveValue::Create(44, CSSPrimitiveValue::UnitType::kPixels); + CSSPrimitiveValue& value = *CSSNumericLiteralValue::Create( + 44, CSSPrimitiveValue::UnitType::kPixels); Length length = value.ConvertToLength(conversionData); EXPECT_EQ(length.Value(), 44); @@ -66,7 +67,7 @@ CSSToLengthConversionData conversionData(nullptr, fontSizes, viewportSize, 1); - CSSPrimitiveValue& value = *CSSPrimitiveValue::Create( + CSSPrimitiveValue& value = *CSSNumericLiteralValue::Create( 1, CSSPrimitiveValue::UnitType::kViewportWidth); Length length = value.ConvertToLength(conversionData); @@ -84,7 +85,7 @@ 1); CSSPrimitiveValue& value = - *CSSPrimitiveValue::Create(1, CSSPrimitiveValue::UnitType::kRems); + *CSSNumericLiteralValue::Create(1, CSSPrimitiveValue::UnitType::kRems); Length length = value.ConvertToLength(conversionData); EXPECT_EQ(length.Value(), 16);
diff --git a/third_party/blink/renderer/core/css/zoom_adjusted_pixel_value.h b/third_party/blink/renderer/core/css/zoom_adjusted_pixel_value.h index 05cb1f9..81bf92f6 100644 --- a/third_party/blink/renderer/core/css/zoom_adjusted_pixel_value.h +++ b/third_party/blink/renderer/core/css/zoom_adjusted_pixel_value.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_ZOOM_ADJUSTED_PIXEL_VALUE_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_ZOOM_ADJUSTED_PIXEL_VALUE_H_ +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h" @@ -14,7 +15,7 @@ inline CSSPrimitiveValue* ZoomAdjustedPixelValue(double value, const ComputedStyle& style) { - return CSSPrimitiveValue::Create( + return CSSNumericLiteralValue::Create( AdjustForAbsoluteZoom::AdjustFloat(value, style), CSSPrimitiveValue::UnitType::kPixels); }
diff --git a/third_party/blink/renderer/core/dom/BUILD.gn b/third_party/blink/renderer/core/dom/BUILD.gn index 1ca2ba9..394115b 100644 --- a/third_party/blink/renderer/core/dom/BUILD.gn +++ b/third_party/blink/renderer/core/dom/BUILD.gn
@@ -226,10 +226,6 @@ "scripted_animation_controller.h", "scripted_idle_task_controller.cc", "scripted_idle_task_controller.h", - "scripted_task_queue.cc", - "scripted_task_queue.h", - "scripted_task_queue_controller.cc", - "scripted_task_queue_controller.h", "shadow_root.cc", "shadow_root.h", "shadow_root_v0.cc",
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 9a717518..97f7acb 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -599,22 +599,358 @@ online_observer_handle_; }; +// A helper class that allows the security context be initialized in the +// process of constructing the document. +class Document::SecurityContextInit : public FeaturePolicyParserDelegate { + STACK_ALLOCATED(); + + public: + SecurityContextInit(const DocumentInit& initializer, + DocumentClassFlags document_classes) { + // Content Security Policy can provide sandbox flags. In CSP + // 'self' will be determined when the policy is bound. That occurs + // once the document is constructed. + InitializeContentSecurityPolicy(initializer, document_classes); + + // Sandbox flags can come from initializer, loader or CSP. + InitializeSandboxFlags(initializer); + + // The origin can be opaque based on sandbox flags. + InitializeOrigin(initializer); + + // Initialize origin trials, requires the post sandbox flags + // security origin. + InitializeOriginTrials(initializer); + + // Initialize feature policy, depends on origin trials. + InitializeFeaturePolicy(initializer, document_classes); + + // Initialize the agent. Depends on security origin. + InitializeAgent(initializer); + } + + const scoped_refptr<SecurityOrigin>& GetSecurityOrigin() const { + return security_origin_; + } + + WebSandboxFlags GetSandboxFlags() { return sandbox_flags_; } + + ContentSecurityPolicy* GetCSP() const { return csp_; } + + std::unique_ptr<FeaturePolicy> TakeFeaturePolicy() { + DCHECK(feature_policy_); + return std::move(feature_policy_); + } + + const Vector<String>& FeaturePolicyParseMessages() const { + return feature_policy_parse_messages_; + } + const ParsedFeaturePolicy& ParsedHeader() const { return parsed_header_; } + + OriginTrialContext* GetOriginTrialContext() { return origin_trials_; } + + Agent* GetAgent() { return agent_; } + + void CountFeaturePolicyUsage(mojom::WebFeature feature) override { + feature_count_.insert(feature); + } + + bool FeaturePolicyFeatureObserved( + mojom::FeaturePolicyFeature feature) override { + if (parsed_feature_policies_.Contains(feature)) + return true; + parsed_feature_policies_.insert(feature); + return false; + } + + bool FeatureEnabled(OriginTrialFeature feature) const override { + return origin_trials_->IsFeatureEnabled(feature); + } + + void ApplyPendingDataToDocument(Document& document) { + for (auto feature : feature_count_) + UseCounter::Count(document, feature); + for (auto feature : parsed_feature_policies_) + document.FeaturePolicyFeatureObserved(feature); + } + + bool BindCSPImmediately() const { return bind_csp_immediately_; } + + private: + void InitializeContentSecurityPolicy(const DocumentInit& initializer, + DocumentClassFlags document_classes) { + auto* frame = initializer.GetFrame(); + ContentSecurityPolicy* last_origin_document_csp = + frame ? frame->Loader().GetLastOriginDocumentCSP() : nullptr; + + KURL url; + if (initializer.ShouldSetURL()) { + url = initializer.Url(); + if (url.IsEmpty()) + url = BlankURL(); + } + + if (initializer.HasSecurityContext() && !initializer.OriginToCommit() && + initializer.OwnerDocument()) { + // Alias certain security properties from |owner_document|. Used for + // the case of about:blank pages inheriting the security properties of + // their requestor context. + // Note that this is currently somewhat broken; Blink always inherits + // from the parent or opener, even though it should actually be + // inherited from the request initiator. + if (url.IsEmpty()) { + last_origin_document_csp = + initializer.OwnerDocument()->GetContentSecurityPolicy(); + } + } + + csp_ = initializer.GetContentSecurityPolicy(); + + if (!csp_ && initializer.ImportsController()) { + // If this document is an HTML import, grab a reference to its master + // document's Content Security Policy. We don't bind the CSP's delegate + // in 'InitSecurityPolicy' in this case, as we can't rebind the + // master document's policy object: The Content Security Policy's delegate + // needs to remain set to the master document. + csp_ = + initializer.ImportsController()->Master()->GetContentSecurityPolicy(); + } else { + if (!csp_) { + csp_ = MakeGarbageCollected<ContentSecurityPolicy>(); + bind_csp_immediately_ = true; + } + + // We should inherit the navigation initiator CSP if the document is + // loaded using a local-scheme url. + if (last_origin_document_csp && + (url.IsEmpty() || url.ProtocolIsAbout() || url.ProtocolIsData() || + url.ProtocolIs("blob") || url.ProtocolIs("filesystem"))) { + csp_->CopyStateFrom(last_origin_document_csp); + } + + if (document_classes & kPluginDocumentClass) { + // TODO(andypaicu): This should inherit the origin document's plugin + // types but because this could be a OOPIF document it might not have + // access. In this situation we fallback on using the parent/opener. + if (last_origin_document_csp) { + csp_->CopyPluginTypesFrom(last_origin_document_csp); + } else if (frame) { + Frame* inherit_from = frame->Tree().Parent() + ? frame->Tree().Parent() + : frame->Client()->Opener(); + if (inherit_from && frame != inherit_from) { + DCHECK( + inherit_from->GetSecurityContext() && + inherit_from->GetSecurityContext()->GetContentSecurityPolicy()); + csp_->CopyPluginTypesFrom( + inherit_from->GetSecurityContext()->GetContentSecurityPolicy()); + } + } + } + } + } + + void InitializeSandboxFlags(const DocumentInit& initializer) { + sandbox_flags_ = initializer.GetSandboxFlags() | csp_->GetSandboxMask(); + auto* frame = initializer.GetFrame(); + if (frame && frame->Loader().GetDocumentLoader()->Archive()) { + // The URL of a Document loaded from a MHTML archive is controlled by + // the Content-Location header. This would allow UXSS, since + // Content-Location can be arbitrarily controlled to control the + // Document's URL and origin. Instead, force a Document loaded from a + // MHTML archive to be sandboxed, providing exceptions only for creating + // new windows. + sandbox_flags_ |= + (WebSandboxFlags::kAll & + ~(WebSandboxFlags::kPopups | + WebSandboxFlags::kPropagatesToAuxiliaryBrowsingContexts)); + } + } + + void InitializeOrigin(const DocumentInit& initializer) { + scoped_refptr<SecurityOrigin> document_origin = + initializer.GetDocumentOrigin(); + if ((sandbox_flags_ & WebSandboxFlags::kOrigin) != WebSandboxFlags::kNone) { + scoped_refptr<SecurityOrigin> sandboxed_origin = + initializer.OriginToCommit() + ? initializer.OriginToCommit() + : document_origin->DeriveNewOpaqueOrigin(); + + // If we're supposed to inherit our security origin from our + // owner, but we're also sandboxed, the only things we inherit are + // the origin's potential trustworthiness and the ability to + // load local resources. The latter lets about:blank iframes in + // file:// URL documents load images and other resources from + // the file system. + // + // Note: Sandboxed about:srcdoc iframe without "allow-same-origin" aren't + // allowed to load user's file, even if its parent can. + if (initializer.OwnerDocument()) { + if (document_origin->IsPotentiallyTrustworthy()) + sandboxed_origin->SetOpaqueOriginIsPotentiallyTrustworthy(true); + if (document_origin->CanLoadLocalResources() && + !initializer.IsSrcdocDocument()) + sandboxed_origin->GrantLoadLocalResources(); + } + security_origin_ = sandboxed_origin; + } else { + security_origin_ = document_origin; + } + } + + void InitializeFeaturePolicy(const DocumentInit& initializer, + DocumentClassFlags document_classes) { + auto* frame = initializer.GetFrame(); + // For a main frame, get inherited feature policy from the opener if any. + const FeaturePolicy::FeatureState* opener_feature_state = nullptr; + if (frame && frame->IsMainFrame() && !frame->OpenerFeatureState().empty()) { + opener_feature_state = &frame->OpenerFeatureState(); + } + + parsed_header_ = FeaturePolicyParser::ParseHeader( + initializer.FeaturePolicyHeader(), security_origin_, + &feature_policy_parse_messages_, this); + + if (sandbox_flags_ != WebSandboxFlags::kNone && + RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) { + // The sandbox flags might have come from CSP header or the browser; in + // such cases the sandbox is not part of the container policy. They are + // added to the header policy (which specifically makes sense in the case + // of CSP sandbox). + ApplySandboxFlagsToParsedFeaturePolicy(sandbox_flags_, parsed_header_); + } + + ParsedFeaturePolicy container_policy; + if (frame && frame->Owner()) + container_policy = frame->Owner()->GetFramePolicy().container_policy; + + // TODO(icelland): This is problematic querying sandbox flags before + // feature policy is initialized. + if (RuntimeEnabledFeatures::BlockingFocusWithoutUserActivationEnabled() && + frame && frame->Tree().Parent() && + (sandbox_flags_ & WebSandboxFlags::kNavigation) != + WebSandboxFlags::kNone) { + // Enforcing the policy for sandbox frames (for context see + // https://crbug.com/954349). + DisallowFeatureIfNotPresent( + mojom::FeaturePolicyFeature::kFocusWithoutUserActivation, + container_policy); + } + + const FeaturePolicy* parent_feature_policy = nullptr; + if (frame && !frame->IsMainFrame()) { + parent_feature_policy = + frame->Tree().Parent()->GetSecurityContext()->GetFeaturePolicy(); + } + + // If we are a HTMLViewSourceDocument we use container, header or + // inherited policies. https://crbug.com/898688 + if (document_classes & kViewSourceDocumentClass) { + feature_policy_ = FeaturePolicy::CreateFromParentPolicy( + nullptr, {}, security_origin_->ToUrlOrigin()); + return; + } + + // Feature policy should either come from a parent in the case of an + // embedded child frame, or from an opener if any when a new window is + // created by an opener. A main frame without an opener would not have a + // parent policy nor an opener feature state. + DCHECK(!parent_feature_policy || !opener_feature_state); + if (!opener_feature_state || + !RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) { + feature_policy_ = FeaturePolicy::CreateFromParentPolicy( + parent_feature_policy, container_policy, + security_origin_->ToUrlOrigin()); + } else { + DCHECK(!parent_feature_policy); + feature_policy_ = FeaturePolicy::CreateWithOpenerPolicy( + *opener_feature_state, security_origin_->ToUrlOrigin()); + } + feature_policy_->SetHeaderPolicy(parsed_header_); + } + + void InitializeOriginTrials(const DocumentInit& initializer) { + origin_trials_ = MakeGarbageCollected<OriginTrialContext>(); + + const String& header_value = initializer.OriginTrialsHeader(); + + if (header_value.IsEmpty()) + return; + std::unique_ptr<Vector<String>> tokens( + OriginTrialContext::ParseHeaderValue(header_value)); + if (!tokens) + return; + origin_trials_->AddTokens(security_origin_.get(), true, *tokens); + } + + void InitializeAgent(const DocumentInit& initializer) { + Document* context_document = initializer.ContextDocument(); + Frame* frame = nullptr; + if (context_document) { + frame = context_document->GetFrame(); + } else { + frame = initializer.GetFrame(); + } + if (frame) { + bool has_potential_universal_access_privilege = false; + if (Settings* settings = frame->GetSettings()) { + // TODO(keishi): Also check if AllowUniversalAccessFromFileURLs might + // dynamically change. + if (!settings->GetWebSecurityEnabled() || + settings->GetAllowUniversalAccessFromFileURLs()) + has_potential_universal_access_privilege = true; + } + agent_ = frame->window_agent_factory().GetAgentForOrigin( + has_potential_universal_access_privilege, + V8PerIsolateData::MainThreadIsolate(), security_origin_.get()); + } else { + // ContextDocument is null only for Documents created in unit tests. + // In that case, use a throw away WindowAgent. + agent_ = MakeGarbageCollected<WindowAgent>( + V8PerIsolateData::MainThreadIsolate()); + } + } + + scoped_refptr<SecurityOrigin> security_origin_; + WebSandboxFlags sandbox_flags_ = WebSandboxFlags::kNone; + std::unique_ptr<FeaturePolicy> feature_policy_; + Vector<String> feature_policy_parse_messages_; + ParsedFeaturePolicy parsed_header_; + Member<ContentSecurityPolicy> csp_; + Member<OriginTrialContext> origin_trials_; + Member<Agent> agent_; + HashSet<mojom::FeaturePolicyFeature> parsed_feature_policies_; + HashSet<mojom::WebFeature> feature_count_; + bool bind_csp_immediately_ = false; +}; + Document* Document::Create(Document& document) { - Document* new_document = MakeGarbageCollected<Document>( - DocumentInit::Create().WithContextDocument(&document).WithURL( - BlankURL())); - new_document->SetSecurityOrigin(document.GetMutableSecurityOrigin()); + Document* new_document = + MakeGarbageCollected<Document>(DocumentInit::Create() + .WithContextDocument(&document) + .WithURL(BlankURL()) + .WithOwnerDocument(&document)); new_document->SetContextFeatures(document.GetContextFeatures()); return new_document; } Document::Document(const DocumentInit& initializer, DocumentClassFlags document_classes) + : Document(initializer, + SecurityContextInit(initializer, document_classes), + document_classes) {} + +Document::Document(const DocumentInit& initializer, + SecurityContextInit security_initializer, + DocumentClassFlags document_classes) : ContainerNode(nullptr, kCreateDocument), TreeScope(*this), + SecurityContext(security_initializer.GetSecurityOrigin(), + security_initializer.GetSandboxFlags(), + security_initializer.TakeFeaturePolicy()), ExecutionContext(V8PerIsolateData::MainThreadIsolate(), - nullptr, - MakeGarbageCollected<OriginTrialContext>()), + security_initializer.GetAgent(), + security_initializer.GetOriginTrialContext()), evaluate_media_queries_on_style_recalc_(false), pending_sheet_layout_(kNoLayoutWithPendingSheets), frame_(initializer.GetFrame()), @@ -707,6 +1043,7 @@ isolated_world_csp_map_( MakeGarbageCollected< HeapHashMap<int, Member<ContentSecurityPolicy>>>()) { + security_initializer.ApplyPendingDataToDocument(*this); if (frame_) { DCHECK(frame_->GetPage()); ProvideContextFeaturesToDocumentFrom(*this, *frame_->GetPage()); @@ -746,29 +1083,8 @@ UpdateBaseURL(); } - InitSecurityContext(initializer); - if (frame_) - frame_->Client()->DidSetFramePolicyHeaders(GetSandboxFlags(), {}); - - Document* context_document = ContextDocument(); - if (context_document && context_document->GetFrame()) { - bool has_potential_universal_access_privilege = false; - if (Settings* settings = context_document->GetFrame()->GetSettings()) { - // TODO(keishi): Also check if AllowUniversalAccessFromFileURLs might - // dynamically change. - if (!settings->GetWebSecurityEnabled() || - settings->GetAllowUniversalAccessFromFileURLs()) - has_potential_universal_access_privilege = true; - } - SetAgent( - context_document->GetFrame()->window_agent_factory().GetAgentForOrigin( - has_potential_universal_access_privilege, GetIsolate(), - GetSecurityOrigin())); - } else { - // If the ContextDocument or its frame is not available, use a throw away - // WindowAgent as we do in GetScheduler. - SetAgent(MakeGarbageCollected<WindowAgent>(GetIsolate())); - } + InitSecurityContext(initializer, security_initializer); + FeaturePolicyInitialized(initializer, security_initializer); InitDNSPrefetch(); @@ -4549,9 +4865,11 @@ } Document* Document::CloneDocumentWithoutChildren() const { - DocumentInit init = DocumentInit::Create() - .WithContextDocument(ContextDocument()) - .WithURL(Url()); + DocumentInit init = + DocumentInit::Create() + .WithContextDocument(ContextDocument()) + .WithURL(Url()) + .WithOriginToCommit(GetSecurityOrigin()->IsolatedCopy()); if (IsXMLDocument()) { if (IsXHTMLDocument()) return XMLDocument::CreateXHTML( @@ -4565,7 +4883,6 @@ SetCompatibilityMode(other.GetCompatibilityMode()); SetEncodingData(other.encoding_data_); SetContextFeatures(other.GetContextFeatures()); - SetSecurityOrigin(other.GetSecurityOrigin()->IsolatedCopy()); SetMimeType(other.contentType()); } @@ -6291,32 +6608,33 @@ }); } -void Document::ApplyFeaturePolicyFromHeader( - const String& feature_policy_header) { - if (!feature_policy_header.IsEmpty()) +void Document::FeaturePolicyInitialized( + const DocumentInit& document_initializer, + const SecurityContextInit& security_initializer) { + // Processing of the feature policy header is done before the SecurityContext + // is initialized. This method just records the usage. + if (!document_initializer.FeaturePolicyHeader().IsEmpty()) UseCounter::Count(*this, WebFeature::kFeaturePolicyHeader); - Vector<String> messages; - auto declared_policy = FeaturePolicyParser::ParseHeader( - feature_policy_header, GetSecurityOrigin(), &messages, this); - for (auto& message : messages) { + for (const auto& message : + security_initializer.FeaturePolicyParseMessages()) { AddConsoleMessage( ConsoleMessage::Create(mojom::ConsoleMessageSource::kSecurity, mojom::ConsoleMessageLevel::kError, "Error with Feature-Policy header: " + message)); } - if (GetSandboxFlags() != WebSandboxFlags::kNone && - RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) { - // The sandbox flags might have come from CSP header or the browser; in such - // cases the sandbox is not part of the container policy. They are added - // to the header policy (which specifically makes sense in the case of CSP - // sandbox). - ApplySandboxFlagsToParsedFeaturePolicy(GetSandboxFlags(), declared_policy); - } - ApplyFeaturePolicy(declared_policy); if (frame_) { - frame_->Client()->DidSetFramePolicyHeaders(GetSandboxFlags(), - declared_policy); + pending_parsed_headers_ = security_initializer.ParsedHeader(); } + + // At this point, the document will not have been installed in the frame's + // LocalDOMWindow, so we cannot call frame_->IsFeatureEnabled. This calls + // SecurityContext::IsFeatureEnabled instead, which cannot report, but we + // don't need reporting here in any case. + is_vertical_scroll_enforced_ = + frame_ && !frame_->IsMainFrame() && + RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled() && + !GetFeaturePolicy()->IsFeatureEnabled( + mojom::FeaturePolicyFeature::kVerticalScroll); } const ParsedFeaturePolicy Document::GetOwnerContainerPolicy() const { @@ -6335,36 +6653,12 @@ return nullptr; } -void Document::ApplyFeaturePolicy(const ParsedFeaturePolicy& declared_policy) { - // For a main frame, get inherited feature policy from the opener if any. - const FeaturePolicy::FeatureState* opener_feature_state = nullptr; - if (frame_ && frame_->IsMainFrame() && - !frame_->OpenerFeatureState().empty()) { - opener_feature_state = &frame_->OpenerFeatureState(); +void Document::ApplyPendingFeaturePolicyHeaders() { + if (frame_) { + frame_->Client()->DidSetFramePolicyHeaders(GetSandboxFlags(), + pending_parsed_headers_); } - - auto container_policy = GetOwnerContainerPolicy(); - if (RuntimeEnabledFeatures::BlockingFocusWithoutUserActivationEnabled() && - frame_ && frame_->Tree().Parent() && - IsSandboxed(WebSandboxFlags::kNavigation)) { - // Enforcing the policy for sandbox frames (for context see - // https://crbug.com/954349). - DisallowFeatureIfNotPresent( - mojom::FeaturePolicyFeature::kFocusWithoutUserActivation, - container_policy); - } - InitializeFeaturePolicy(declared_policy, container_policy, - GetParentFeaturePolicy(), opener_feature_state); - - // At this point, the document will not have been installed in the frame's - // LocalDOMWindow, so we cannot call frame_->IsFeatureEnabled. This calls - // SecurityContext::IsFeatureEnabled instead, which cannot report, but we - // don't need reporting here in any case. - is_vertical_scroll_enforced_ = - frame_ && !frame_->IsMainFrame() && - RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled() && - !GetFeaturePolicy()->IsFeatureEnabled( - mojom::FeaturePolicyFeature::kVerticalScroll); + pending_parsed_headers_.clear(); } void Document::ApplyReportOnlyFeaturePolicyFromHeader( @@ -6444,90 +6738,45 @@ return ukm_source_id_; } -void Document::InitSecurityContext(const DocumentInit& initializer) { - DCHECK(!GetSecurityOrigin()); +void Document::InitContentSecurityPolicy(ContentSecurityPolicy* csp) { + SetContentSecurityPolicy(csp); + GetContentSecurityPolicy()->BindToDelegate( + GetContentSecurityPolicyDelegate()); +} +void Document::InitSecurityContext( + const DocumentInit& initializer, + const SecurityContextInit& security_initializer) { + DCHECK(GetSecurityOrigin()); + + // If the CSP was provided by the DocumentLoader or is from ImportsController + // it doesn't need to be bound right now. ImportsController takes a reference + // to a master document's CSP which is already bound. Document construction + // occurs in the DocumentLoader occurs before the frame reference is bound so + // callbacks from binding the CSP delegate immediately would not get called + // if it was bound immediately. eg. Callbacks back to browser or console + // logging. + if (security_initializer.BindCSPImmediately()) { + InitContentSecurityPolicy(security_initializer.GetCSP()); + } else { + SetContentSecurityPolicy(security_initializer.GetCSP()); + } if (!initializer.HasSecurityContext()) { // No source for a security context. // This can occur via document.implementation.createDocument(). cookie_url_ = KURL(g_empty_string); - SetSecurityOrigin(initializer.GetDocumentOrigin()); - InitContentSecurityPolicy(); - ApplyFeaturePolicy({}); return; } - - SandboxFlags sandbox_flags = initializer.GetSandboxFlags(); - if (fetcher_->Archive()) { - // The URL of a Document loaded from a MHTML archive is controlled by the - // Content-Location header. This would allow UXSS, since Content-Location - // can be arbitrarily controlled to control the Document's URL and origin. - // Instead, force a Document loaded from a MHTML archive to be sandboxed, - // providing exceptions only for creating new windows. - sandbox_flags |= - (WebSandboxFlags::kAll & - ~(WebSandboxFlags::kPopups | - WebSandboxFlags::kPropagatesToAuxiliaryBrowsingContexts)); - } - // In the common case, create the security context from the currently - // loading URL with a fresh content security policy. - EnforceSandboxFlags(sandbox_flags); SetInsecureRequestPolicy(initializer.GetInsecureRequestPolicy()); if (initializer.InsecureNavigationsToUpgrade()) { for (auto to_upgrade : *initializer.InsecureNavigationsToUpgrade()) AddInsecureNavigationUpgrade(to_upgrade); } - ContentSecurityPolicy* last_origin_document_csp_ = - frame_ ? frame_->Loader().GetLastOriginDocumentCSP() : nullptr; - - scoped_refptr<SecurityOrigin> document_origin = - initializer.GetDocumentOrigin(); cookie_url_ = url_; if (!initializer.OriginToCommit() && initializer.OwnerDocument()) { - // Alias certain security properties from |owner_document|. Used for - // the case of about:blank pages inheriting the security properties of - // their requestor context. - // Note that this is currently somewhat broken; Blink always inherits - // from the parent or opener, even though it should actually be - // inherited from the request initiator. cookie_url_ = initializer.OwnerDocument()->CookieURL(); - if (url_.IsEmpty()) { - last_origin_document_csp_ = - initializer.OwnerDocument()->GetContentSecurityPolicy(); - } - } - - if (IsSandboxed(WebSandboxFlags::kOrigin)) { - DCHECK(!initializer.ContextDocument()); - scoped_refptr<SecurityOrigin> sandboxed_origin = - initializer.OriginToCommit() ? initializer.OriginToCommit() - : document_origin->DeriveNewOpaqueOrigin(); - - // If we're supposed to inherit our security origin from our - // owner, but we're also sandboxed, the only things we inherit are - // the origin's potential trustworthiness and the ability to - // load local resources. The latter lets about:blank iframes in - // file:// URL documents load images and other resources from - // the file system. - // - // Note: Sandboxed about:srcdoc iframe without "allow-same-origin" aren't - // allowed to load user's file, even if its parent can. - if (initializer.OwnerDocument()) { - if (document_origin->IsPotentiallyTrustworthy()) - sandboxed_origin->SetOpaqueOriginIsPotentiallyTrustworthy(true); - if (document_origin->CanLoadLocalResources() && !IsSrcdocDocument()) - sandboxed_origin->GrantLoadLocalResources(); - if (url_.IsEmpty()) { - last_origin_document_csp_ = - initializer.OwnerDocument()->GetContentSecurityPolicy(); - } - } - cookie_url_ = url_; - SetSecurityOrigin(std::move(sandboxed_origin)); - } else { - SetSecurityOrigin(std::move(document_origin)); } // Set the address space before setting up CSP, as the latter may override @@ -6547,18 +6796,6 @@ SetAddressSpace(mojom::IPAddressSpace::kPublic); } - if (ImportsController()) { - // If this document is an HTML import, grab a reference to it's master - // document's Content Security Policy. We don't call - // 'initContentSecurityPolicy' in this case, as we can't rebind the master - // document's policy object: its ExecutionContext needs to remain tied to - // the master document. - SetContentSecurityPolicy( - ImportsController()->Master()->GetContentSecurityPolicy()); - } else { - InitContentSecurityPolicy(nullptr, last_origin_document_csp_); - } - if (Settings* settings = initializer.GetSettings()) { if (!settings->GetWebSecurityEnabled()) { // Web security is turned off. We should let this document access every @@ -6582,19 +6819,30 @@ SecurityOrigin::Create(url_)->IsPotentiallyTrustworthy()) GetMutableSecurityOrigin()->SetOpaqueOriginIsPotentiallyTrustworthy(true); - ParsedFeaturePolicy declared_policy = {}; - if (GetSandboxFlags() != WebSandboxFlags::kNone && - RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) { - // If any sandbox flags are enforced above they should also be added as - // part of a declared policy to properly initialize the sandbox feature - // policies. - ApplySandboxFlagsToParsedFeaturePolicy(GetSandboxFlags(), declared_policy); - } - ApplyFeaturePolicy(declared_policy); - InitSecureContextState(); } +void Document::SetSecurityOrigin(scoped_refptr<SecurityOrigin> origin) { + // Enforce that we don't change access, we might change the reference (via + // IsolatedCopy but we can't change the security policy). + CHECK(origin); + CHECK(GetSecurityOrigin()->CanAccess(origin.get())); + SecurityContext::SetSecurityOrigin(origin); +} + +void Document::SetSecurityOriginForTesting( + scoped_refptr<SecurityOrigin> origin) { + SecurityContext::SetSecurityOrigin(origin); + if (frame_) + frame_->GetScriptController().UpdateSecurityOrigin(GetSecurityOrigin()); +} + +void Document::BindContentSecurityPolicy() { + DCHECK(!GetContentSecurityPolicy()->IsBound()); + GetContentSecurityPolicy()->BindToDelegate( + GetContentSecurityPolicyDelegate()); +} + void Document::InitSecureContextState() { DCHECK_EQ(secure_context_state_, SecureContextState::kUnknown); if (!GetSecurityOrigin()->IsPotentiallyTrustworthy()) { @@ -6621,47 +6869,6 @@ DCHECK_NE(secure_context_state_, SecureContextState::kUnknown); } -// the first parameter specifies a policy to use as the document csp meaning -// the document will take ownership of the policy -// the second parameter specifies a policy to inherit meaning the document -// will attempt to copy over the policy -void Document::InitContentSecurityPolicy( - ContentSecurityPolicy* csp, - const ContentSecurityPolicy* last_origin_document_csp) { - SetContentSecurityPolicy(csp ? csp - : MakeGarbageCollected<ContentSecurityPolicy>()); - - GetContentSecurityPolicy()->BindToDelegate( - GetContentSecurityPolicyDelegate()); - - // We should inherit the navigation initiator CSP if the document is loaded - // using a local-scheme url. - if (last_origin_document_csp && - (url_.IsEmpty() || url_.ProtocolIsAbout() || url_.ProtocolIsData() || - url_.ProtocolIs("blob") || url_.ProtocolIs("filesystem"))) { - GetContentSecurityPolicy()->CopyStateFrom(last_origin_document_csp); - } - - if (IsPluginDocument()) { - // TODO(andypaicu): This should inherit the origin document's plugin types - // but because this could be a OOPIF document it might not have access. - // In this situation we fallback on using the parent/opener. - if (last_origin_document_csp) { - GetContentSecurityPolicy()->CopyPluginTypesFrom(last_origin_document_csp); - } else if (frame_) { - Frame* inherit_from = frame_->Tree().Parent() - ? frame_->Tree().Parent() - : frame_->Client()->Opener(); - if (inherit_from && frame_ != inherit_from) { - DCHECK(inherit_from->GetSecurityContext() && - inherit_from->GetSecurityContext()->GetContentSecurityPolicy()); - GetContentSecurityPolicy()->CopyPluginTypesFrom( - inherit_from->GetSecurityContext()->GetContentSecurityPolicy()); - } - } - } -} - bool Document::CanExecuteScripts(ReasonForCallingCanExecuteScripts reason) { DCHECK(GetFrame()) << "you are querying canExecuteScripts on a non contextDocument."; @@ -6736,24 +6943,6 @@ return true; } -void Document::EnforceSandboxFlags(SandboxFlags mask) { - scoped_refptr<const SecurityOrigin> stand_in_origin = GetSecurityOrigin(); - bool is_potentially_trustworthy = - stand_in_origin && stand_in_origin->IsPotentiallyTrustworthy(); - ApplySandboxFlags(mask, is_potentially_trustworthy); -} - -void Document::UpdateSecurityOrigin(scoped_refptr<SecurityOrigin> origin) { - SetSecurityOrigin(std::move(origin)); - DidUpdateSecurityOrigin(); -} - -void Document::DidUpdateSecurityOrigin() { - if (!frame_) - return; - frame_->GetScriptController().UpdateSecurityOrigin(GetSecurityOrigin()); -} - bool Document::IsContextThread() const { return IsMainThread(); } @@ -8188,7 +8377,6 @@ template class CORE_TEMPLATE_EXPORT Supplement<Document>; } // namespace blink - #ifndef NDEBUG static WeakDocumentSet& liveDocumentSet() { DEFINE_STATIC_LOCAL(blink::Persistent<WeakDocumentSet>, set,
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h index b04fc0e..8e9eada 100644 --- a/third_party/blink/renderer/core/dom/document.h +++ b/third_party/blink/renderer/core/dom/document.h
@@ -225,6 +225,7 @@ kMediaDocumentClass = 1 << 4, kSVGDocumentClass = 1 << 5, kXMLDocumentClass = 1 << 6, + kViewSourceDocumentClass = 1 << 7, }; enum ShadowCascadeOrder { @@ -564,6 +565,8 @@ void Initialize(); virtual void Shutdown(); + void InitContentSecurityPolicy(ContentSecurityPolicy*); + // If you have a Document, use GetLayoutView() instead which is faster. void GetLayoutObject() const = delete; @@ -1097,20 +1100,11 @@ const SVGDocumentExtensions* SvgExtensions(); SVGDocumentExtensions& AccessSVGExtensions(); - // the first parameter specifies a policy to use as the document csp meaning - // the document will take ownership of the policy - // the second parameter specifies a policy to inherit meaning the document - // will attempt to copy over the policy - void InitContentSecurityPolicy(ContentSecurityPolicy* = nullptr, - const ContentSecurityPolicy* = nullptr); - bool AllowInlineEventHandler(Node*, EventListener*, const String& context_url, const WTF::OrdinalNumber& context_line); - void EnforceSandboxFlags(WebSandboxFlags mask) override; - void StatePopped(scoped_refptr<SerializedScriptValue>); enum LoadEventProgress { @@ -1288,8 +1282,6 @@ void MaybeHandleHttpRefresh(const String&, HttpRefreshType); bool IsHttpRefreshScheduledWithin(double interval_in_seconds); - void UpdateSecurityOrigin(scoped_refptr<SecurityOrigin>); - void SetHasViewportUnits() { has_viewport_units_ = true; } bool HasViewportUnits() const { return has_viewport_units_; } void SetResizedForViewportUnits(); @@ -1393,10 +1385,8 @@ // May return nullptr when PerformanceManager instrumentation is disabled. DocumentResourceCoordinator* GetResourceCoordinator(); - // Set an explicit feature policy on this document in response to an HTTP - // Feature-Policy header. This will be relayed to the embedder through the - // LocalFrameClient. - void ApplyFeaturePolicyFromHeader(const String& feature_policy_header); + // Apply pending feature policy headers. + void ApplyPendingFeaturePolicyHeaders(); // Set the report-only feature policy on this document in response to an HTTP // Feature-Policy-Report-Only header. @@ -1570,10 +1560,20 @@ bool IsUseCounted(CSSPropertyID property, UseCounterHelper::CSSPropertyType) const; void ClearUseCounterForTesting(mojom::WebFeature); + void SetSecurityOrigin(scoped_refptr<SecurityOrigin>) final; + + // This method should be used sparingly because it does not adjust the + // window agent or agent cluster. If you are using this in a unit test + // you should likely navigate the document to adjust the security origin + // instead. + void SetSecurityOriginForTesting(scoped_refptr<SecurityOrigin>); + + // Bind Content Security Policy to this document. This will cause the + // CSP to resolve the 'self' attribute and all policies will then be + // applied to this document. + void BindContentSecurityPolicy(); protected: - void DidUpdateSecurityOrigin() final; - void ClearXMLVersion() { xml_version_ = String(); } virtual Document* CloneDocumentWithoutChildren() const; @@ -1591,6 +1591,16 @@ FRIEND_TEST_ALL_PREFIXES(FrameFetchContextSubresourceFilterTest, DuringOnFreeze); class NetworkStateObserver; + class SecurityContextInit; + + Document(const DocumentInit& initization, + SecurityContextInit init_helper, + DocumentClassFlags document_classes); + + // Post initialization of the object handling of the feature policy. + void FeaturePolicyInitialized( + const DocumentInit& document_initializer, + const SecurityContextInit& security_initializer); friend class AXContext; void AddAXContext(AXContext*); @@ -1605,7 +1615,8 @@ ScriptedAnimationController& EnsureScriptedAnimationController(); ScriptedIdleTaskController& EnsureScriptedIdleTaskController(); - void InitSecurityContext(const DocumentInit&); + void InitSecurityContext(const DocumentInit&, + const SecurityContextInit& security_initializer); void InitSecureContextState(); SecurityContext& GetSecurityContext() final { return *this; } const SecurityContext& GetSecurityContext() const final { return *this; } @@ -1702,12 +1713,6 @@ const ParsedFeaturePolicy GetOwnerContainerPolicy() const; const FeaturePolicy* GetParentFeaturePolicy() const; - // Set the feature policy on this document, inheriting as necessary from the - // parent document and frame owner (if they exist). The caller must ensure - // that any changes to the declared policy are relayed to the embedder through - // the LocalFrameClient. - void ApplyFeaturePolicy(const ParsedFeaturePolicy& declared_policy); - // Returns true if use of |method_name| for markup insertion is allowed by // feature policy; otherwise returns false and throws a DOM exception. bool AllowedToUseDynamicMarkUpInsertion(const char* method_name, @@ -2039,6 +2044,10 @@ static_cast<size_t>(mojom::FeaturePolicyFeature::kMaxValue) + 1> potentially_violated_features_; + // Pending parsed headers to send to browser after DidCommitNavigation + // IPC. + ParsedFeaturePolicy pending_parsed_headers_; + AtomicString override_last_modified_; // Map from isolated world IDs to their ContentSecurityPolicy instances.
diff --git a/third_party/blink/renderer/core/dom/document_init.cc b/third_party/blink/renderer/core/dom/document_init.cc index 2971f96..b05c7171 100644 --- a/third_party/blink/renderer/core/dom/document_init.cc +++ b/third_party/blink/renderer/core/dom/document_init.cc
@@ -94,17 +94,19 @@ } WebSandboxFlags DocumentInit::GetSandboxFlags() const { - DCHECK(MasterDocumentLoader()); DocumentLoader* loader = MasterDocumentLoader(); - WebSandboxFlags flags = loader->GetFrame()->Loader().EffectiveSandboxFlags(); + WebSandboxFlags flags = sandbox_flags_; + if (loader) { + flags |= loader->GetFrame()->Loader().EffectiveSandboxFlags(); - // If the load was blocked by CSP, force the Document's origin to be unique, - // so that the blocked document appears to be a normal cross-origin document's - // load per CSP spec: https://www.w3.org/TR/CSP3/#directive-frame-ancestors. - if (loader->WasBlockedAfterCSP()) { - flags |= WebSandboxFlags::kOrigin; + // If the load was blocked by CSP, force the Document's origin to be unique, + // so that the blocked document appears to be a normal cross-origin + // document's load per CSP spec: + // https://www.w3.org/TR/CSP3/#directive-frame-ancestors. + if (loader->WasBlockedAfterCSP()) { + flags |= WebSandboxFlags::kOrigin; + } } - return flags; } @@ -242,4 +244,28 @@ return context_document_; } +DocumentInit& DocumentInit::WithFeaturePolicyHeader(const String& header) { + DCHECK(feature_policy_header_.IsEmpty()); + feature_policy_header_ = header; + return *this; +} + +DocumentInit& DocumentInit::WithOriginTrialsHeader(const String& header) { + DCHECK(origin_trials_header_.IsEmpty()); + origin_trials_header_ = header; + return *this; +} + +DocumentInit& DocumentInit::WithSandboxFlags(WebSandboxFlags flags) { + // Only allow adding more sandbox flags. + sandbox_flags_ |= flags; + return *this; +} + +DocumentInit& DocumentInit::WithContentSecurityPolicy( + ContentSecurityPolicy* policy) { + content_security_policy_ = policy; + return *this; +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/dom/document_init.h b/third_party/blink/renderer/core/dom/document_init.h index fef80d0..cd5ed82 100644 --- a/third_party/blink/renderer/core/dom/document_init.h +++ b/third_party/blink/renderer/core/dom/document_init.h
@@ -40,6 +40,7 @@ namespace blink { +class ContentSecurityPolicy; class Document; class DocumentLoader; class LocalFrame; @@ -118,6 +119,19 @@ V0CustomElementRegistrationContext* RegistrationContext(Document*) const; DocumentInit& WithNewRegistrationContext(); + DocumentInit& WithFeaturePolicyHeader(const String& header); + const String& FeaturePolicyHeader() const { return feature_policy_header_; } + + DocumentInit& WithOriginTrialsHeader(const String& header); + const String& OriginTrialsHeader() const { return origin_trials_header_; } + + DocumentInit& WithSandboxFlags(WebSandboxFlags flags); + + DocumentInit& WithContentSecurityPolicy(ContentSecurityPolicy* policy); + ContentSecurityPolicy* GetContentSecurityPolicy() const { + return content_security_policy_; + } + private: DocumentInit(HTMLImportsController*); @@ -162,6 +176,18 @@ Member<V0CustomElementRegistrationContext> registration_context_; bool create_new_registration_context_; + + // The feature policy set via response header. + String feature_policy_header_; + + // The origin trial set via response header. + String origin_trials_header_; + + // Additional sandbox flags + WebSandboxFlags sandbox_flags_ = WebSandboxFlags::kNone; + + // Loader's CSP + Member<ContentSecurityPolicy> content_security_policy_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/dom/dom_implementation.cc b/third_party/blink/renderer/core/dom/dom_implementation.cc index d2ef3ca..d5fe1fe 100644 --- a/third_party/blink/renderer/core/dom/dom_implementation.cc +++ b/third_party/blink/renderer/core/dom/dom_implementation.cc
@@ -83,8 +83,9 @@ DocumentType* doctype, ExceptionState& exception_state) { XMLDocument* doc = nullptr; - DocumentInit init = - DocumentInit::Create().WithContextDocument(document_->ContextDocument()); + DocumentInit init = DocumentInit::Create() + .WithContextDocument(document_->ContextDocument()) + .WithOwnerDocument(document_->ContextDocument()); if (namespace_uri == svg_names::kNamespaceURI) { doc = XMLDocument::CreateSVG(init); } else if (namespace_uri == html_names::xhtmlNamespaceURI) { @@ -94,7 +95,6 @@ doc = MakeGarbageCollected<XMLDocument>(init); } - doc->SetSecurityOrigin(document_->GetMutableSecurityOrigin()); doc->SetContextFeatures(document_->GetContextFeatures()); Node* document_element = nullptr; @@ -206,6 +206,7 @@ DocumentInit init = DocumentInit::Create() .WithContextDocument(document_->ContextDocument()) + .WithOwnerDocument(document_->ContextDocument()) .WithRegistrationContext(document_->RegistrationContext()); auto* d = MakeGarbageCollected<HTMLDocument>(init); d->open(); @@ -217,7 +218,6 @@ head_element->AppendChild(title_element); title_element->AppendChild(d->createTextNode(title), ASSERT_NO_EXCEPTION); } - d->SetSecurityOrigin(document_->GetMutableSecurityOrigin()); d->SetContextFeatures(document_->GetContextFeatures()); return d; }
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index 9ee037b1..ab9b8c6 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -44,6 +44,7 @@ #include "third_party/blink/renderer/core/animation/css/css_animations.h" #include "third_party/blink/renderer/core/aom/computed_accessible_node.h" #include "third_party/blink/renderer/core/css/css_identifier_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/css_property_value_set.h" #include "third_party/blink/renderer/core/css/css_selector_watch.h" @@ -4555,7 +4556,8 @@ } const ComputedStyle* Element::CachedStyleForPseudoElement( - const PseudoStyleRequest& request) { + const PseudoStyleRequest& request, + const ComputedStyle* parent_style) { const ComputedStyle* style = GetComputedStyle(); if (!style || (request.pseudo_id < kFirstInternalPseudoId && @@ -4567,7 +4569,8 @@ style->GetCachedPseudoStyle(request.pseudo_id)) return cached; - scoped_refptr<ComputedStyle> result = StyleForPseudoElement(request, style); + scoped_refptr<ComputedStyle> result = + StyleForPseudoElement(request, parent_style); if (result) return style->AddCachedPseudoStyle(std::move(result)); return nullptr; @@ -5405,8 +5408,8 @@ double value, CSSPrimitiveValue::UnitType unit, bool important) { - SetInlineStyleProperty(property_id, *CSSPrimitiveValue::Create(value, unit), - important); + SetInlineStyleProperty( + property_id, *CSSNumericLiteralValue::Create(value, unit), important); } void Element::SetInlineStyleProperty(CSSPropertyID property_id, @@ -5483,7 +5486,7 @@ double value, CSSPrimitiveValue::UnitType unit) { DCHECK(IsStyledElement()); - style->SetProperty(property_id, *CSSPrimitiveValue::Create(value, unit)); + style->SetProperty(property_id, *CSSNumericLiteralValue::Create(value, unit)); } void Element::AddPropertyToPresentationAttributeStyle(
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h index accc434..fd76212 100644 --- a/third_party/blink/renderer/core/dom/element.h +++ b/third_party/blink/renderer/core/dom/element.h
@@ -731,7 +731,9 @@ PseudoElement* GetPseudoElement(PseudoId) const; LayoutObject* PseudoElementLayoutObject(PseudoId) const; - const ComputedStyle* CachedStyleForPseudoElement(const PseudoStyleRequest&); + const ComputedStyle* CachedStyleForPseudoElement( + const PseudoStyleRequest&, + const ComputedStyle* parent_style = nullptr); scoped_refptr<ComputedStyle> StyleForPseudoElement( const PseudoStyleRequest&, const ComputedStyle* parent_style = nullptr);
diff --git a/third_party/blink/renderer/core/dom/scripted_task_queue.cc b/third_party/blink/renderer/core/dom/scripted_task_queue.cc deleted file mode 100644 index f4cfc3c..0000000 --- a/third_party/blink/renderer/core/dom/scripted_task_queue.cc +++ /dev/null
@@ -1,113 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/core/dom/scripted_task_queue.h" - -#include <memory> -#include <utility> - -#include "base/macros.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/bindings/core/v8/v8_task_queue_post_callback.h" -#include "third_party/blink/renderer/core/dom/abort_signal.h" -#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h" -#include "third_party/blink/renderer/platform/wtf/functional.h" - -namespace blink { - -class ScriptedTaskQueue::WrappedCallback - : public GarbageCollectedFinalized<WrappedCallback> { - public: - WrappedCallback(V8TaskQueuePostCallback* callback, - ScriptPromiseResolver* resolver, - TaskHandle task_handle) - : callback_(callback), - resolver_(resolver), - task_handle_(std::move(task_handle)) {} - - void Trace(Visitor* visitor) { - visitor->Trace(callback_); - visitor->Trace(resolver_); - } - - void Invoke() { - callback_->InvokeAndReportException(nullptr); - resolver_->Resolve(); - } - - void Reject() { resolver_->Reject(); } - - private: - Member<V8TaskQueuePostCallback> callback_; - Member<ScriptPromiseResolver> resolver_; - TaskHandle task_handle_; - - DISALLOW_COPY_AND_ASSIGN(WrappedCallback); -}; - -ScriptedTaskQueue::ScriptedTaskQueue(ExecutionContext* context, - TaskType task_type) - : ContextLifecycleObserver(context) { - task_runner_ = GetExecutionContext()->GetTaskRunner(task_type); -} - -void ScriptedTaskQueue::Trace(Visitor* visitor) { - visitor->Trace(pending_tasks_); - ScriptWrappable::Trace(visitor); - ContextLifecycleObserver::Trace(visitor); -} - -ScriptPromise ScriptedTaskQueue::postTask(ScriptState* script_state, - V8TaskQueuePostCallback* callback, - AbortSignal* signal) { - CallbackId id = next_callback_id_++; - - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - - if (signal) { - if (signal->aborted()) { - resolver->Reject(); - return resolver->Promise(); - } - - signal->AddAlgorithm( - WTF::Bind(&ScriptedTaskQueue::AbortTask, WrapPersistent(this), id)); - } - - TaskHandle task_handle = PostCancellableTask( - *task_runner_, FROM_HERE, - WTF::Bind(&ScriptedTaskQueue::CallbackFired, WrapPersistent(this), id)); - - pending_tasks_.Set(id, MakeGarbageCollected<WrappedCallback>( - callback, resolver, std::move(task_handle))); - - return resolver->Promise(); -} - -void ScriptedTaskQueue::CallbackFired(CallbackId id) { - auto task_iter = pending_tasks_.find(id); - if (task_iter == pending_tasks_.end()) - return; - - task_iter->value->Invoke(); - // Can't use the iterator here since running the task - // might invalidate it. - pending_tasks_.erase(id); -} - -void ScriptedTaskQueue::AbortTask(CallbackId id) { - auto task_iter = pending_tasks_.find(id); - if (task_iter == pending_tasks_.end()) - return; - - task_iter->value->Reject(); - pending_tasks_.erase(id); -} - -void ScriptedTaskQueue::ContextDestroyed(ExecutionContext*) { - pending_tasks_.clear(); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/dom/scripted_task_queue.h b/third_party/blink/renderer/core/dom/scripted_task_queue.h deleted file mode 100644 index 98bebb59..0000000 --- a/third_party/blink/renderer/core/dom/scripted_task_queue.h +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_SCRIPTED_TASK_QUEUE_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_SCRIPTED_TASK_QUEUE_H_ - -#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" -#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" -#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" -#include "third_party/blink/renderer/platform/heap/handle.h" - -namespace blink { - -class AbortSignal; -class ScriptState; -class V8TaskQueuePostCallback; - -// This class corresponds to the ScriptedTaskQueue interface. -class CORE_EXPORT ScriptedTaskQueue final : public ScriptWrappable, - public ContextLifecycleObserver { - DEFINE_WRAPPERTYPEINFO(); - USING_GARBAGE_COLLECTED_MIXIN(ScriptedTaskQueue); - - public: - static ScriptedTaskQueue* Create(ExecutionContext* context, - TaskType task_type) { - return MakeGarbageCollected<ScriptedTaskQueue>(context, task_type); - } - - explicit ScriptedTaskQueue(ExecutionContext*, TaskType); - - using CallbackId = int; - - ScriptPromise postTask(ScriptState*, - V8TaskQueuePostCallback* callback, - AbortSignal*); - - void CallbackFired(CallbackId id); - - void Trace(Visitor*) override; - - private: - // ContextLifecycleObserver interface. - void ContextDestroyed(ExecutionContext*) override; - - void AbortTask(CallbackId id); - - class WrappedCallback; - HeapHashMap<CallbackId, Member<WrappedCallback>> pending_tasks_; - CallbackId next_callback_id_ = 1; - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_SCRIPTED_TASK_QUEUE_H_
diff --git a/third_party/blink/renderer/core/dom/scripted_task_queue.idl b/third_party/blink/renderer/core/dom/scripted_task_queue.idl deleted file mode 100644 index df4c298..0000000 --- a/third_party/blink/renderer/core/dom/scripted_task_queue.idl +++ /dev/null
@@ -1,12 +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. - -callback TaskQueuePostCallback = void (); - -[ - RuntimeEnabled=ScriptedTaskQueue, - Exposed=Window -] interface ScriptedTaskQueue { - [CallWith=ScriptState] Promise<any> postTask(TaskQueuePostCallback callback, optional AbortSignal signal = null); -};
diff --git a/third_party/blink/renderer/core/dom/scripted_task_queue_controller.cc b/third_party/blink/renderer/core/dom/scripted_task_queue_controller.cc deleted file mode 100644 index fa6c7ad..0000000 --- a/third_party/blink/renderer/core/dom/scripted_task_queue_controller.cc +++ /dev/null
@@ -1,60 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/core/dom/scripted_task_queue_controller.h" - -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/dom/scripted_task_queue.h" -#include "third_party/blink/renderer/platform/bindings/exception_state.h" -#include "third_party/blink/renderer/platform/bindings/script_state.h" - -namespace blink { - -const char ScriptedTaskQueueController::kSupplementName[] = - "ScriptedTaskQueueController"; - -ScriptedTaskQueueController* ScriptedTaskQueueController::From( - Document& document) { - ScriptedTaskQueueController* task_queue_controller = - Supplement<Document>::From<ScriptedTaskQueueController>(document); - if (!task_queue_controller) { - task_queue_controller = - MakeGarbageCollected<ScriptedTaskQueueController>(&document); - Supplement<Document>::ProvideTo(document, task_queue_controller); - } - return task_queue_controller; -} - -ScriptedTaskQueueController::ScriptedTaskQueueController( - ExecutionContext* context) - : ContextLifecycleObserver(context) {} - -void ScriptedTaskQueueController::Trace(Visitor* visitor) { - visitor->Trace(task_queues_); - Supplement<Document>::Trace(visitor); - ScriptWrappable::Trace(visitor); - ContextLifecycleObserver::Trace(visitor); -} - -ScriptedTaskQueue* ScriptedTaskQueueController::defaultQueue( - const String& queue_name) { - auto iter = task_queues_.find(queue_name); - if (iter != task_queues_.end()) { - return iter->value.Get(); - } - - TaskType task_type = TaskType::kExperimentalWebSchedulingBestEffort; - if (queue_name == "user-interaction") - task_type = TaskType::kExperimentalWebSchedulingUserInteraction; - else if (queue_name != "best-effort") - NOTREACHED(); - - auto* task_queue = - ScriptedTaskQueue::Create(GetExecutionContext(), task_type); - task_queues_.insert(queue_name, task_queue); - - return task_queue; -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/dom/scripted_task_queue_controller.h b/third_party/blink/renderer/core/dom/scripted_task_queue_controller.h deleted file mode 100644 index 07446c9..0000000 --- a/third_party/blink/renderer/core/dom/scripted_task_queue_controller.h +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_SCRIPTED_TASK_QUEUE_CONTROLLER_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_SCRIPTED_TASK_QUEUE_CONTROLLER_H_ - -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.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/supplementable.h" -#include "third_party/blink/renderer/platform/wtf/hash_map.h" -#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" - -namespace blink { - -class Document; - -class ScriptedTaskQueue; - -// This class corresponds to the ScriptedTaskQueueController interface. -class CORE_EXPORT ScriptedTaskQueueController final - : public ScriptWrappable, - public ContextLifecycleObserver, - public Supplement<Document> { - DEFINE_WRAPPERTYPEINFO(); - USING_GARBAGE_COLLECTED_MIXIN(ScriptedTaskQueueController); - - public: - static const char kSupplementName[]; - - static ScriptedTaskQueueController* From(Document&); - - ScriptedTaskQueue* defaultQueue(const String&); - - explicit ScriptedTaskQueueController(ExecutionContext*); - - void Trace(Visitor*) override; - - private: - HeapHashMap<String, Member<ScriptedTaskQueue>> task_queues_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_SCRIPTED_TASK_QUEUE_CONTROLLER_H_
diff --git a/third_party/blink/renderer/core/dom/scripted_task_queue_controller.idl b/third_party/blink/renderer/core/dom/scripted_task_queue_controller.idl deleted file mode 100644 index bda09c2..0000000 --- a/third_party/blink/renderer/core/dom/scripted_task_queue_controller.idl +++ /dev/null
@@ -1,12 +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. - -enum MainThreadTaskQueueType { "user-interaction", "best-effort" }; - -[ - RuntimeEnabled=ScriptedTaskQueue, - Exposed=Window -] interface ScriptedTaskQueueController { - [ImplementedAs=defaultQueue] ScriptedTaskQueue default(MainThreadTaskQueueType queue_type); -};
diff --git a/third_party/blink/renderer/core/editing/commands/apply_style_command.cc b/third_party/blink/renderer/core/editing/commands/apply_style_command.cc index aff5d4a0..68df523 100644 --- a/third_party/blink/renderer/core/editing/commands/apply_style_command.cc +++ b/third_party/blink/renderer/core/editing/commands/apply_style_command.cc
@@ -26,6 +26,7 @@ #include "third_party/blink/renderer/core/editing/commands/apply_style_command.h" #include "third_party/blink/renderer/core/css/css_computed_style_declaration.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/css_property_names.h" #include "third_party/blink/renderer/core/css/css_property_value_set.h" @@ -510,8 +511,8 @@ if (current_font_size != desired_font_size) { inline_style->SetProperty( CSSPropertyID::kFontSize, - *CSSPrimitiveValue::Create(desired_font_size, - CSSPrimitiveValue::UnitType::kPixels), + *CSSNumericLiteralValue::Create(desired_font_size, + CSSPrimitiveValue::UnitType::kPixels), false); SetNodeAttribute(element, kStyleAttr, AtomicString(inline_style->AsText()));
diff --git a/third_party/blink/renderer/core/editing/editing_style.cc b/third_party/blink/renderer/core/editing/editing_style.cc index 755b7bb..6312c1f 100644 --- a/third_party/blink/renderer/core/editing/editing_style.cc +++ b/third_party/blink/renderer/core/editing/editing_style.cc
@@ -30,6 +30,7 @@ #include "third_party/blink/renderer/core/css/css_color_value.h" #include "third_party/blink/renderer/core/css/css_computed_style_declaration.h" #include "third_party/blink/renderer/core/css/css_identifier_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value_mappings.h" #include "third_party/blink/renderer/core/css/css_property_value_set.h" @@ -535,8 +536,8 @@ // ReplaceSelectionCommandTest_TextAutosizingDoesntInflateText gets here. mutable_style_->SetProperty( CSSPropertyID::kFontSize, - CSSPrimitiveValue::Create(computed_style->SpecifiedFontSize(), - CSSPrimitiveValue::UnitType::kPixels) + CSSNumericLiteralValue::Create(computed_style->SpecifiedFontSize(), + CSSPrimitiveValue::UnitType::kPixels) ->CssText(), /* important */ false, node->GetDocument().GetSecureContextMode()); }
diff --git a/third_party/blink/renderer/core/events/pointer_event_factory.cc b/third_party/blink/renderer/core/events/pointer_event_factory.cc index 5168b09..7e44bd3 100644 --- a/third_party/blink/renderer/core/events/pointer_event_factory.cc +++ b/third_party/blink/renderer/core/events/pointer_event_factory.cc
@@ -6,6 +6,8 @@ #include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" +#include "third_party/blink/renderer/core/page/chrome_client.h" +#include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/platform/geometry/float_size.h" namespace blink { @@ -94,13 +96,30 @@ MouseEvent::SetCoordinatesFromWebPointerProperties( web_pointer_event_in_root_frame, dom_window, pointer_event_init); + // TODO(crbug.com/802067): pointerrawupdate event's movements are not + // calculated. if (RuntimeEnabledFeatures::ConsolidatedMovementXYEnabled() && web_pointer_event.GetType() == WebInputEvent::kPointerMove) { - // TODO(eirage): pointerrawupdate event's movements are not calculated. - pointer_event_init->setMovementX(web_pointer_event.PositionInScreen().x - - last_global_position.X()); - pointer_event_init->setMovementY(web_pointer_event.PositionInScreen().y - - last_global_position.Y()); + // TODO(crbug.com/907309): Current movementX/Y is in physical pixel when + // zoom-for-dsf is enabled. Here we apply the device-scale-factor to align + // with the current behavior. We need to figure out what is the best + // behavior here. + float device_scale_factor = 1; + if (dom_window && dom_window->GetFrame()) { + LocalFrame* frame = dom_window->GetFrame(); + if (frame->GetPage()->DeviceScaleFactorDeprecated() == 1) { + device_scale_factor = frame->GetPage() + ->GetChromeClient() + .GetScreenInfo() + .device_scale_factor; + } + } + pointer_event_init->setMovementX( + (web_pointer_event.PositionInScreen().x - last_global_position.X()) * + device_scale_factor); + pointer_event_init->setMovementY( + (web_pointer_event.PositionInScreen().y - last_global_position.Y()) * + device_scale_factor); } // If width/height is unknown we let PointerEventInit set it to 1. @@ -316,14 +335,16 @@ pointer_event_init->setCoalescedEvents(coalesced_pointer_events); pointer_event_init->setPredictedEvents(predicted_pointer_events); - SetLastPosition(pointer_event_init->pointerId(), web_pointer_event); + SetLastPosition(pointer_event_init->pointerId(), + web_pointer_event.PositionInScreen()); return PointerEvent::Create(type, pointer_event_init, web_pointer_event.TimeStamp()); } -void PointerEventFactory::SetLastPosition(int pointer_id, - const WebPointerProperties& event) { - pointer_id_last_position_mapping_.Set(pointer_id, event.PositionInScreen()); +void PointerEventFactory::SetLastPosition( + int pointer_id, + const FloatPoint& position_in_screen) { + pointer_id_last_position_mapping_.Set(pointer_id, position_in_screen); } void PointerEventFactory::RemoveLastPosition(const int pointer_id) {
diff --git a/third_party/blink/renderer/core/events/pointer_event_factory.h b/third_party/blink/renderer/core/events/pointer_event_factory.h index 897ffd6..8c69118 100644 --- a/third_party/blink/renderer/core/events/pointer_event_factory.h +++ b/third_party/blink/renderer/core/events/pointer_event_factory.h
@@ -80,6 +80,7 @@ bool IsPrimary(const WebPointerProperties&) const; static const PointerId kMouseId; + static const PointerId kInvalidId; // Removes pointer_id from the map. void RemoveLastPosition(const PointerId pointer_id); @@ -90,6 +91,9 @@ FloatPoint GetLastPointerPosition(PointerId pointer_id, const WebPointerProperties& event) const; + void SetLastPosition(PointerId pointer_id, + const FloatPoint& position_in_screen); + private: // We use int64_t to cover the whole range for PointerId with no // deleted hash value. @@ -141,10 +145,6 @@ const Vector<WebPointerEvent>& event_list, LocalDOMWindow* view); - void SetLastPosition(PointerId pointer_id, const WebPointerProperties& event); - - static const PointerId kInvalidId; - PointerId current_id_; HashMap<IncomingId, PointerId,
diff --git a/third_party/blink/renderer/core/execution_context/execution_context.h b/third_party/blink/renderer/core/execution_context/execution_context.h index dd9329d..73bd1fa 100644 --- a/third_party/blink/renderer/core/execution_context/execution_context.h +++ b/third_party/blink/renderer/core/execution_context/execution_context.h
@@ -313,16 +313,11 @@ mojom::FeaturePolicyFeature feature) override; protected: - explicit ExecutionContext(v8::Isolate* isolate, - Agent* agent, - OriginTrialContext* origin_trial_context); + ExecutionContext(v8::Isolate* isolate, + Agent* agent, + OriginTrialContext* origin_trial_context); ~ExecutionContext() override; - void SetAgent(Agent* agent) { - DCHECK(agent); - agent_ = agent; - } - private: // ConsoleLogger implementation. void AddConsoleMessageImpl(mojom::ConsoleMessageSource,
diff --git a/third_party/blink/renderer/core/execution_context/remote_security_context.cc b/third_party/blink/renderer/core/execution_context/remote_security_context.cc index d8138e2..f2670bd8 100644 --- a/third_party/blink/renderer/core/execution_context/remote_security_context.cc +++ b/third_party/blink/renderer/core/execution_context/remote_security_context.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/execution_context/remote_security_context.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" @@ -40,8 +41,37 @@ GetContentSecurityPolicy()->SetupSelf(*GetSecurityOrigin()); } -void RemoteSecurityContext::ResetSandboxFlags() { - sandbox_flags_ = WebSandboxFlags::kNone; +void RemoteSecurityContext::ResetAndEnforceSandboxFlags(WebSandboxFlags flags) { + sandbox_flags_ = flags; + + if (IsSandboxed(WebSandboxFlags::kOrigin) && GetSecurityOrigin() && + !GetSecurityOrigin()->IsOpaque()) { + SetSecurityOrigin(GetSecurityOrigin()->DeriveNewOpaqueOrigin()); + } +} + +void RemoteSecurityContext::InitializeFeaturePolicy( + const ParsedFeaturePolicy& parsed_header, + const ParsedFeaturePolicy& container_policy, + const FeaturePolicy* parent_feature_policy, + const FeaturePolicy::FeatureState* opener_feature_state) { + // Feature policy should either come from a parent in the case of an embedded + // child frame, or from an opener if any when a new window is created by an + // opener. A main frame without an opener would not have a parent policy nor + // an opener feature state. + DCHECK(!parent_feature_policy || !opener_feature_state); + report_only_feature_policy_ = nullptr; + if (!opener_feature_state || + !RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) { + feature_policy_ = FeaturePolicy::CreateFromParentPolicy( + parent_feature_policy, container_policy, + security_origin_->ToUrlOrigin()); + } else { + DCHECK(!parent_feature_policy); + feature_policy_ = FeaturePolicy::CreateWithOpenerPolicy( + *opener_feature_state, security_origin_->ToUrlOrigin()); + } + feature_policy_->SetHeaderPolicy(parsed_header); } } // namespace blink
diff --git a/third_party/blink/renderer/core/execution_context/remote_security_context.h b/third_party/blink/renderer/core/execution_context/remote_security_context.h index 28c511b..9ef0272e5 100644 --- a/third_party/blink/renderer/core/execution_context/remote_security_context.h +++ b/third_party/blink/renderer/core/execution_context/remote_security_context.h
@@ -23,10 +23,24 @@ void SetReplicatedOrigin(scoped_refptr<SecurityOrigin>); void ResetReplicatedContentSecurityPolicy(); - void ResetSandboxFlags(); + void ResetAndEnforceSandboxFlags(WebSandboxFlags flags); - // FIXME: implement - void DidUpdateSecurityOrigin() override {} + // Constructs the enforcement FeaturePolicy struct for this security context. + // The resulting FeaturePolicy is a combination of: + // * |parsed_header|: from the FeaturePolicy part of the response headers. + // * |container_policy|: from <iframe>'s allow attribute. + // * |parent_feature_policy|: which is the current state of feature policies + // in a parent browsing context (frame). + // * |opener_feature_state|: the current state of the policies in an opener + // if any. + // Note that at most one of the |parent_feature_policy| or + // |opener_feature_state| should be provided. The |container_policy| is empty + // for a top-level security context. + void InitializeFeaturePolicy( + const ParsedFeaturePolicy& parsed_header, + const ParsedFeaturePolicy& container_policy, + const FeaturePolicy* parent_feature_policy, + const FeaturePolicy::FeatureState* opener_feature_state); }; } // namespace blink
diff --git a/third_party/blink/renderer/core/execution_context/security_context.cc b/third_party/blink/renderer/core/execution_context/security_context.cc index 55504fc2..479b162 100644 --- a/third_party/blink/renderer/core/execution_context/security_context.cc +++ b/third_party/blink/renderer/core/execution_context/security_context.cc
@@ -82,7 +82,14 @@ } SecurityContext::SecurityContext() - : sandbox_flags_(WebSandboxFlags::kNone), + : SecurityContext(nullptr, WebSandboxFlags::kNone, nullptr) {} + +SecurityContext::SecurityContext(scoped_refptr<SecurityOrigin> origin, + WebSandboxFlags sandbox_flags, + std::unique_ptr<FeaturePolicy> feature_policy) + : sandbox_flags_(sandbox_flags), + security_origin_(std::move(origin)), + feature_policy_(std::move(feature_policy)), address_space_(mojom::IPAddressSpace::kPublic), insecure_request_policy_(kLeaveInsecureRequestsAlone), require_safe_types_(false) {} @@ -144,25 +151,6 @@ return (sandbox_flags_ & mask) != WebSandboxFlags::kNone; } -void SecurityContext::EnforceSandboxFlags(WebSandboxFlags mask) { - ApplySandboxFlags(mask); -} - -void SecurityContext::ApplySandboxFlags(WebSandboxFlags mask, - bool is_potentially_trustworthy) { - sandbox_flags_ |= mask; - - if (IsSandboxed(WebSandboxFlags::kOrigin) && GetSecurityOrigin() && - !GetSecurityOrigin()->IsOpaque()) { - scoped_refptr<SecurityOrigin> security_origin = - GetSecurityOrigin()->DeriveNewOpaqueOrigin(); - security_origin->SetOpaqueOriginIsPotentiallyTrustworthy( - is_potentially_trustworthy); - SetSecurityOrigin(std::move(security_origin)); - DidUpdateSecurityOrigin(); - } -} - String SecurityContext::addressSpaceForBindings() const { switch (address_space_) { case mojom::IPAddressSpace::kPublic: @@ -199,36 +187,6 @@ feature_policy_ = std::move(feature_policy); } -void SecurityContext::InitializeFeaturePolicy( - const ParsedFeaturePolicy& parsed_header, - const ParsedFeaturePolicy& container_policy, - const FeaturePolicy* parent_feature_policy, - const FeaturePolicy::FeatureState* opener_feature_state) { - // Feature policy should either come from a parent in the case of an embedded - // child frame, or from an opener if any when a new window is created by an - // opener. A main frame without an opener would not have a parent policy nor - // an opener feature state. - DCHECK(!parent_feature_policy || !opener_feature_state); - report_only_feature_policy_ = nullptr; - if (!HasCustomizedFeaturePolicy()) { - feature_policy_ = FeaturePolicy::CreateFromParentPolicy( - nullptr, {}, security_origin_->ToUrlOrigin()); - return; - } - - if (!opener_feature_state || - !RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) { - feature_policy_ = FeaturePolicy::CreateFromParentPolicy( - parent_feature_policy, container_policy, - security_origin_->ToUrlOrigin()); - } else { - DCHECK(!parent_feature_policy); - feature_policy_ = FeaturePolicy::CreateWithOpenerPolicy( - *opener_feature_state, security_origin_->ToUrlOrigin()); - } - feature_policy_->SetHeaderPolicy(parsed_header); -} - // Uses the parent enforcing policy as the basis for the report-only policy. void SecurityContext::AddReportOnlyFeaturePolicy( const ParsedFeaturePolicy& parsed_report_only_header,
diff --git a/third_party/blink/renderer/core/execution_context/security_context.h b/third_party/blink/renderer/core/execution_context/security_context.h index ae66bb0..a376caf 100644 --- a/third_party/blink/renderer/core/execution_context/security_context.h +++ b/third_party/blink/renderer/core/execution_context/security_context.h
@@ -88,12 +88,10 @@ // Explicitly override the security origin for this security context. // Note: It is dangerous to change the security origin of a script context // that already contains content. - void SetSecurityOrigin(scoped_refptr<SecurityOrigin>); - virtual void DidUpdateSecurityOrigin() = 0; + virtual void SetSecurityOrigin(scoped_refptr<SecurityOrigin>); WebSandboxFlags GetSandboxFlags() const { return sandbox_flags_; } bool IsSandboxed(WebSandboxFlags mask) const; - virtual void EnforceSandboxFlags(WebSandboxFlags mask); void SetAddressSpace(mojom::IPAddressSpace space) { address_space_ = space; } mojom::IPAddressSpace AddressSpace() const { return address_space_; } @@ -136,22 +134,6 @@ return feature_policy_.get(); } void SetFeaturePolicy(std::unique_ptr<FeaturePolicy> feature_policy); - // Constructs the enforcement FeaturePolicy struct for this security context. - // The resulted FeaturePolicy is a combination of: - // * |parsed_header|: from the FeaturePolicy part of the response headers. - // * |container_policy|: from <iframe>'s allow attribute. - // * |parent_feature_policy|: which is the current state of feature policies - // in a parent browsing context (frame). - // * |opener_feature_state|: the current state of the policies in an opener - // if any. - // Note that at most one of the |parent_feature_policy| or - // |opener_feature_state| should be provided. The |container_policy| is empty - // for a top-level security context. - void InitializeFeaturePolicy( - const ParsedFeaturePolicy& parsed_header, - const ParsedFeaturePolicy& container_policy, - const FeaturePolicy* parent_feature_policy, - const FeaturePolicy::FeatureState* opener_feature_state); void AddReportOnlyFeaturePolicy( const ParsedFeaturePolicy& parsed_report_only_header, const ParsedFeaturePolicy& container_policy, @@ -181,31 +163,23 @@ mojom::FeaturePolicyDisposition, const String& message = g_empty_string) const {} - // Apply the sandbox flag. In addition, if the origin is not already opaque, - // the origin is updated to a newly created unique opaque origin, setting the - // potentially trustworthy bit from |is_potentially_trustworthy|. - void ApplySandboxFlags(WebSandboxFlags mask, - bool is_potentially_trustworthy = false); - protected: SecurityContext(); + SecurityContext(scoped_refptr<SecurityOrigin> origin, + WebSandboxFlags sandbox_flags, + std::unique_ptr<FeaturePolicy> feature_policy); virtual ~SecurityContext(); void SetContentSecurityPolicy(ContentSecurityPolicy*); - // Determines whether or not the SecurityContext has a customized feature - // policy. If this method returns false, |feature_policy_| is reset to a - // default value ignoring container, header, and inherited policies. - virtual bool HasCustomizedFeaturePolicy() const { return true; } - WebSandboxFlags sandbox_flags_; - - private: scoped_refptr<SecurityOrigin> security_origin_; - Member<ContentSecurityPolicy> content_security_policy_; std::unique_ptr<FeaturePolicy> feature_policy_; std::unique_ptr<FeaturePolicy> report_only_feature_policy_; + private: + Member<ContentSecurityPolicy> content_security_policy_; + mojom::IPAddressSpace address_space_; WebInsecureRequestPolicy insecure_request_policy_; bool mixed_autoupgrade_opt_out_;
diff --git a/third_party/blink/renderer/core/exported/web_frame_serializer.cc b/third_party/blink/renderer/core/exported/web_frame_serializer.cc index 11e15b0..6bd4f09d 100644 --- a/third_party/blink/renderer/core/exported/web_frame_serializer.cc +++ b/third_party/blink/renderer/core/exported/web_frame_serializer.cc
@@ -105,7 +105,7 @@ MHTMLFrameSerializerDelegate( WebFrameSerializer::MHTMLPartsGenerationDelegate&, HeapHashSet<WeakMember<const Element>>&); - ~MHTMLFrameSerializerDelegate() override; + ~MHTMLFrameSerializerDelegate() override = default; bool ShouldIgnoreElement(const Element&) override; bool ShouldIgnoreAttribute(const Element&, const Attribute&) override; bool RewriteLink(const Element&, String& rewritten_link) override; @@ -135,14 +135,6 @@ shadow_template_elements_(shadow_template_elements), popup_overlays_skipped_(false) {} -MHTMLFrameSerializerDelegate::~MHTMLFrameSerializerDelegate() { - if (web_delegate_.RemovePopupOverlay()) { - UMA_HISTOGRAM_BOOLEAN( - "PageSerialization.MhtmlGeneration.PopupOverlaySkipped", - popup_overlays_skipped_); - } -} - bool MHTMLFrameSerializerDelegate::ShouldIgnoreElement(const Element& element) { if (ShouldIgnoreHiddenElement(element)) return true;
diff --git a/third_party/blink/renderer/core/exported/web_frame_serializer_sanitization_test.cc b/third_party/blink/renderer/core/exported/web_frame_serializer_sanitization_test.cc index 15264f4..98e4a7c2 100644 --- a/third_party/blink/renderer/core/exported/web_frame_serializer_sanitization_test.cc +++ b/third_party/blink/renderer/core/exported/web_frame_serializer_sanitization_test.cc
@@ -41,7 +41,6 @@ #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" #include "third_party/blink/renderer/platform/mhtml/mhtml_archive.h" #include "third_party/blink/renderer/platform/mhtml/mhtml_parser.h" -#include "third_party/blink/renderer/platform/testing/histogram_tester.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" #include "third_party/blink/renderer/platform/testing/url_test_helpers.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" @@ -188,8 +187,6 @@ WebLocalFrameImpl* MainFrameImpl() { return helper_.LocalMainFrame(); } - HistogramTester histogram_tester_; - private: frame_test_helpers::WebViewHelper helper_; SimpleMHTMLPartsGenerationDelegate mhtml_delegate_; @@ -323,8 +320,6 @@ String mhtml = GenerateMHTMLFromHtml("http://www.test.com", "popup.html"); EXPECT_EQ(WTF::kNotFound, mhtml.Find("class=3D\"overlay")); EXPECT_EQ(WTF::kNotFound, mhtml.Find("class=3D\"modal")); - histogram_tester_.ExpectUniqueSample( - "PageSerialization.MhtmlGeneration.PopupOverlaySkipped", true, 1); } TEST_F(WebFrameSerializerSanitizationTest, PopupOverlayNotFound) { @@ -332,8 +327,6 @@ SetRemovePopupOverlay(true); String mhtml = GenerateMHTMLFromHtml("http://www.test.com", "text_only_page.html"); - histogram_tester_.ExpectUniqueSample( - "PageSerialization.MhtmlGeneration.PopupOverlaySkipped", false, 1); } TEST_F(WebFrameSerializerSanitizationTest, KeepPopupOverlayIfNotRequested) { @@ -342,8 +335,6 @@ String mhtml = GenerateMHTMLFromHtml("http://www.test.com", "popup.html"); EXPECT_NE(WTF::kNotFound, mhtml.Find("class=3D\"overlay")); EXPECT_NE(WTF::kNotFound, mhtml.Find("class=3D\"modal")); - histogram_tester_.ExpectTotalCount( - "PageSerialization.MhtmlGeneration.PopupOverlaySkipped", 0); } TEST_F(WebFrameSerializerSanitizationTest, LinkIntegrity) {
diff --git a/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc b/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc index 9c666af..969f491 100644 --- a/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc +++ b/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc
@@ -245,8 +245,7 @@ void WebRemoteFrameImpl::SetReplicatedSandboxFlags(WebSandboxFlags flags) { DCHECK(GetFrame()); - GetFrame()->GetSecurityContext()->ResetSandboxFlags(); - GetFrame()->GetSecurityContext()->EnforceSandboxFlags( + GetFrame()->GetSecurityContext()->ResetAndEnforceSandboxFlags( static_cast<SandboxFlags>(flags)); }
diff --git a/third_party/blink/renderer/core/feature_policy/policy_test.cc b/third_party/blink/renderer/core/feature_policy/policy_test.cc index f7bd73e..d915fd5f 100644 --- a/third_party/blink/renderer/core/feature_policy/policy_test.cc +++ b/third_party/blink/renderer/core/feature_policy/policy_test.cc
@@ -24,11 +24,13 @@ class PolicyTest : public testing::Test { public: void SetUp() override { - document_ = MakeGarbageCollected<Document>(); - document_->SetSecurityOrigin(SecurityOrigin::CreateFromString(kSelfOrigin)); - document_->ApplyFeaturePolicyFromHeader( - "fullscreen *; payment 'self'; midi 'none'; camera 'self' " - "https://example.com https://example.net"); + DocumentInit init = + DocumentInit::Create() + .WithOriginToCommit(SecurityOrigin::CreateFromString(kSelfOrigin)) + .WithFeaturePolicyHeader( + "fullscreen *; payment 'self'; midi 'none'; camera 'self' " + "https://example.com https://example.net"); + document_ = MakeGarbageCollected<Document>(init); } DOMFeaturePolicy* GetPolicy() const { return policy_; }
diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy.cc b/third_party/blink/renderer/core/frame/csp/content_security_policy.cc index 8ecf36b1..853bfaa 100644 --- a/third_party/blink/renderer/core/frame/csp/content_security_policy.cc +++ b/third_party/blink/renderer/core/frame/csp/content_security_policy.cc
@@ -158,6 +158,10 @@ require_trusted_types_(false), insecure_request_policy_(kLeaveInsecureRequestsAlone) {} +bool ContentSecurityPolicy::IsBound() { + return delegate_; +} + void ContentSecurityPolicy::BindToDelegate( ContentSecurityPolicyDelegate& delegate) { // TODO(crbug.com/915954): Add DCHECK(!delegate_). It seems some call sites @@ -346,10 +350,7 @@ Member<CSPDirectiveList> policy = CSPDirectiveList::Create(this, begin, position, type, source); - if (!policy->AllowEval(nullptr, - SecurityViolationReportingPolicy::kSuppressReporting, - kWillNotThrowException, g_empty_string) && - disable_eval_error_message_.IsNull()) { + if (policy->ShouldDisableEval() && disable_eval_error_message_.IsNull()) { disable_eval_error_message_ = policy->EvalDisabledErrorMessage(); } @@ -558,9 +559,7 @@ String ContentSecurityPolicy::EvalDisabledErrorMessage() const { for (const auto& policy : policies_) { - if (!policy->AllowEval(nullptr, - SecurityViolationReportingPolicy::kSuppressReporting, - kWillNotThrowException, g_empty_string)) { + if (policy->ShouldDisableEval()) { return policy->EvalDisabledErrorMessage(); } }
diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy.h b/third_party/blink/renderer/core/frame/csp/content_security_policy.h index 616556f..75f8137 100644 --- a/third_party/blink/renderer/core/frame/csp/content_security_policy.h +++ b/third_party/blink/renderer/core/frame/csp/content_security_policy.h
@@ -211,6 +211,7 @@ ~ContentSecurityPolicy(); void Trace(blink::Visitor*); + bool IsBound(); void BindToDelegate(ContentSecurityPolicyDelegate&); void SetupSelf(const SecurityOrigin&); void SetupSelf(const ContentSecurityPolicy&);
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc b/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc index 5da19f6d..1792c14 100644 --- a/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc +++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
@@ -161,6 +161,11 @@ ->GetText() + "\".\n"; directives->SetEvalDisabledErrorMessage(message); + } else if (directives->trusted_types_) { + String message = + "Refused to evaluate a string as JavaScript because this document " + "requires 'Trusted Type' assignment."; + directives->SetEvalDisabledErrorMessage(message); } if (directives->IsReportOnly() && @@ -772,6 +777,16 @@ ContentSecurityPolicy::DirectiveType::kScriptSrc)); } +bool CSPDirectiveList::ShouldDisableEvalBecauseScriptSrc() const { + return !AllowEval( + nullptr, SecurityViolationReportingPolicy::kSuppressReporting, + ContentSecurityPolicy::kWillNotThrowException, g_empty_string); +} + +bool CSPDirectiveList::ShouldDisableEvalBecauseTrustedTypes() const { + return trusted_types_; +} + bool CSPDirectiveList::AllowPluginType( const String& type, const String& type_attribute,
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list.h b/third_party/blink/renderer/core/frame/csp/csp_directive_list.h index 27af666a..fc9f93e2b 100644 --- a/third_party/blink/renderer/core/frame/csp/csp_directive_list.h +++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list.h
@@ -108,6 +108,12 @@ void ReportMixedContent(const KURL& mixed_url, ResourceRequest::RedirectStatus) const; + bool ShouldDisableEval() const { + return ShouldDisableEvalBecauseScriptSrc() || + ShouldDisableEvalBecauseTrustedTypes(); + } + bool ShouldDisableEvalBecauseScriptSrc() const; + bool ShouldDisableEvalBecauseTrustedTypes() const; const String& EvalDisabledErrorMessage() const { return eval_disabled_error_message_; }
diff --git a/third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.cc b/third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.cc index bdb9726..c4a1c22 100644 --- a/third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.cc +++ b/third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.cc
@@ -43,7 +43,25 @@ } void ExecutionContextCSPDelegate::SetSandboxFlags(SandboxFlags mask) { - GetSecurityContext().EnforceSandboxFlags(mask); + // Ideally sandbox flags are determined at construction time since + // sandbox flags influence the security origin and that influences + // the Agent that is assigned for the ExecutionContext. Changing + // an ExecutionContext's agent in the middle of an object lifecycle + // is not permitted. + + // Since Workers and Worklets don't share agents (each one is unique) + // we allow them to apply new sandbox flags on top of the current ones. + WorkerOrWorkletGlobalScope* worklet_or_worker = + DynamicTo<WorkerOrWorkletGlobalScope>(execution_context_.Get()); + if (worklet_or_worker) { + worklet_or_worker->ApplySandboxFlags(mask); + } + // Just check that all the sandbox flags that are set by CSP have + // already been set on the security context. Meta tags can't set them + // and we should have already constructed the document with the correct + // sandbox flags from CSP already. + WebSandboxFlags flags = GetSecurityContext().GetSandboxFlags(); + CHECK_EQ(flags | mask, flags); } void ExecutionContextCSPDelegate::SetAddressSpace(mojom::IPAddressSpace space) {
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc index 693be68..21d9b7f 100644 --- a/third_party/blink/renderer/core/frame/local_dom_window.cc +++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -55,7 +55,6 @@ #include "third_party/blink/renderer/core/dom/events/scoped_event_queue.h" #include "third_party/blink/renderer/core/dom/frame_request_callback_collection.h" #include "third_party/blink/renderer/core/dom/scripted_idle_task_controller.h" -#include "third_party/blink/renderer/core/dom/scripted_task_queue_controller.h" #include "third_party/blink/renderer/core/dom/sink_document.h" #include "third_party/blink/renderer/core/dom/user_gesture_indicator.h" #include "third_party/blink/renderer/core/editing/editor.h" @@ -985,13 +984,6 @@ return promise; } -ScriptedTaskQueueController* LocalDOMWindow::taskQueue() const { - if (Document* document = this->document()) { - return ScriptedTaskQueueController::From(*document); - } - return nullptr; -} - double LocalDOMWindow::devicePixelRatio() const { if (!GetFrame()) return 0.0;
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.h b/third_party/blink/renderer/core/frame/local_dom_window.h index e62a3e6..c2190f73 100644 --- a/third_party/blink/renderer/core/frame/local_dom_window.h +++ b/third_party/blink/renderer/core/frame/local_dom_window.h
@@ -61,7 +61,6 @@ class Modulator; class Navigator; class Screen; -class ScriptedTaskQueueController; class ScriptPromise; class ScriptState; class ScrollToOptions; @@ -218,8 +217,6 @@ // Acessibility Object Model ScriptPromise getComputedAccessibleNode(ScriptState*, Element*); - ScriptedTaskQueueController* taskQueue() const; - // WebKit animation extensions int requestAnimationFrame(V8FrameRequestCallback*); int webkitRequestAnimationFrame(V8FrameRequestCallback*);
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 e9fda55..2ea36ad 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
@@ -1629,12 +1629,8 @@ DCHECK(!page.MainFrame()); frame->InitializeCoreFrame( page, nullptr, name, - opener ? &ToCoreFrame(*opener)->window_agent_factory() : nullptr); - if (RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) - frame->GetFrame()->SetOpenerFeatureState(opener_feature_state); - // Can't force sandbox flags until there's a core frame. - frame->GetFrame()->Loader().ForceSandboxFlags( - static_cast<SandboxFlags>(sandbox_flags)); + opener ? &ToCoreFrame(*opener)->window_agent_factory() : nullptr, + sandbox_flags, opener_feature_state); return frame; } @@ -1652,6 +1648,17 @@ Frame* previous_frame = ToCoreFrame(*previous_web_frame); web_frame->SetParent(previous_web_frame->Parent()); web_frame->SetOpener(previous_web_frame->Opener()); + WebSandboxFlags sandbox_flags = WebSandboxFlags::kNone; + FeaturePolicy::FeatureState feature_state; + if (!previous_frame->Owner()) { + // Provisional main frames need to force sandbox flags. This is necessary + // to inherit sandbox flags when a sandboxed frame does a window.open() + // which triggers a cross-process navigation. + sandbox_flags = frame_policy.sandbox_flags; + // If there is an opener (even disowned), the opener policies must be + // inherited the same way as sandbox flag. + feature_state = previous_frame->OpenerFeatureState(); + } // Note: this *always* temporarily sets a frame owner, even for main frames! // When a core Frame is created with no owner, it attempts to set itself as // the main frame of the Page. However, this is a provisional frame, and may @@ -1666,21 +1673,14 @@ web_frame->InitializeCoreFrame( *previous_frame->GetPage(), MakeGarbageCollected<DummyFrameOwner>(), previous_frame->Tree().GetName(), - &ToCoreFrame(*previous_web_frame)->window_agent_factory()); + &ToCoreFrame(*previous_web_frame)->window_agent_factory(), sandbox_flags, + feature_state); LocalFrame* new_frame = web_frame->GetFrame(); new_frame->SetOwner(previous_frame->Owner()); if (auto* remote_frame_owner = DynamicTo<RemoteFrameOwner>(new_frame->Owner())) { remote_frame_owner->SetFramePolicy(frame_policy); - } else if (!new_frame->Owner()) { - // Provisional main frames need to force sandbox flags. This is necessary - // to inherit sandbox flags when a sandboxed frame does a window.open() - // which triggers a cross-process navigation. - new_frame->Loader().ForceSandboxFlags(frame_policy.sandbox_flags); - // If there is an opener (even disowned), the opener policies must be - // inherited the same way as sandbox flag. - new_frame->SetOpenerFeatureState(previous_frame->OpenerFeatureState()); } return web_frame; @@ -1745,11 +1745,17 @@ Page& page, FrameOwner* owner, const AtomicString& name, - WindowAgentFactory* window_agent_factory) { + WindowAgentFactory* window_agent_factory, + WebSandboxFlags sandbox_flags, + const FeaturePolicy::FeatureState& opener_feature_state) { SetCoreFrame(MakeGarbageCollected<LocalFrame>(local_frame_client_.Get(), page, owner, window_agent_factory, interface_registry_)); frame_->Tree().SetName(name); + if (RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) + frame_->SetOpenerFeatureState(opener_feature_state); + frame_->Loader().ForceSandboxFlags(sandbox_flags); + // We must call init() after frame_ is assigned because it is referenced // during init(). frame_->Init();
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 15ed90d..043afe00 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
@@ -347,10 +347,14 @@ void WasHidden() override; void WasShown() override; - void InitializeCoreFrame(Page&, - FrameOwner*, - const AtomicString& name, - WindowAgentFactory*); + void InitializeCoreFrame( + Page&, + FrameOwner*, + const AtomicString& name, + WindowAgentFactory*, + WebSandboxFlags sandbox_flags = WebSandboxFlags::kNone, + const FeaturePolicy::FeatureState& opener_feature_state = + FeaturePolicy::FeatureState()); LocalFrame* GetFrame() const { return frame_.Get(); } void WillBeDetached();
diff --git a/third_party/blink/renderer/core/frame/window.idl b/third_party/blink/renderer/core/frame/window.idl index 64959e80..b5c9a7b6 100644 --- a/third_party/blink/renderer/core/frame/window.idl +++ b/third_party/blink/renderer/core/frame/window.idl
@@ -120,8 +120,6 @@ [HighEntropy, Measure, NewObject] MediaQueryList matchMedia(DOMString query); [SameObject, Replaceable] readonly attribute Screen screen; - [RuntimeEnabled=ScriptedTaskQueue, SameObject, Replaceable] readonly attribute ScriptedTaskQueueController TaskQueue; - // browsing context void moveTo(long x, long y); void moveBy(long x, long y);
diff --git a/third_party/blink/renderer/core/html/html_document.cc b/third_party/blink/renderer/core/html/html_document.cc index fd65513..3db77e50 100644 --- a/third_party/blink/renderer/core/html/html_document.cc +++ b/third_party/blink/renderer/core/html/html_document.cc
@@ -81,7 +81,8 @@ DocumentInit::Create() .WithContextDocument(ContextDocument()) .WithURL(Url()) - .WithRegistrationContext(RegistrationContext())); + .WithRegistrationContext(RegistrationContext()) + .WithOriginToCommit(GetSecurityOrigin()->IsolatedCopy())); } // --------------------------------------------------------------------------
diff --git a/third_party/blink/renderer/core/html/html_table_element.cc b/third_party/blink/renderer/core/html/html_table_element.cc index 6eb0866..6f71888 100644 --- a/third_party/blink/renderer/core/html/html_table_element.cc +++ b/third_party/blink/renderer/core/html/html_table_element.cc
@@ -28,6 +28,7 @@ #include "third_party/blink/renderer/core/css/css_identifier_value.h" #include "third_party/blink/renderer/core/css/css_image_value.h" #include "third_party/blink/renderer/core/css/css_inherited_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_property_names.h" #include "third_party/blink/renderer/core/css/css_property_value_set.h" #include "third_party/blink/renderer/core/css/style_change_reason.h" @@ -532,18 +533,18 @@ *CSSInheritedValue::Create()); break; case kSolidBorders: - style->SetProperty( - CSSPropertyID::kBorderWidth, - *CSSPrimitiveValue::Create(1, CSSPrimitiveValue::UnitType::kPixels)); + style->SetProperty(CSSPropertyID::kBorderWidth, + *CSSNumericLiteralValue::Create( + 1, CSSPrimitiveValue::UnitType::kPixels)); style->SetProperty(CSSPropertyID::kBorderStyle, *CSSIdentifierValue::Create(CSSValueID::kSolid)); style->SetProperty(CSSPropertyID::kBorderColor, *CSSInheritedValue::Create()); break; case kInsetBorders: - style->SetProperty( - CSSPropertyID::kBorderWidth, - *CSSPrimitiveValue::Create(1, CSSPrimitiveValue::UnitType::kPixels)); + style->SetProperty(CSSPropertyID::kBorderWidth, + *CSSNumericLiteralValue::Create( + 1, CSSPrimitiveValue::UnitType::kPixels)); style->SetProperty(CSSPropertyID::kBorderStyle, *CSSIdentifierValue::Create(CSSValueID::kInset)); style->SetProperty(CSSPropertyID::kBorderColor, @@ -557,7 +558,7 @@ if (padding_) style->SetProperty(CSSPropertyID::kPadding, - *CSSPrimitiveValue::Create( + *CSSNumericLiteralValue::Create( padding_, CSSPrimitiveValue::UnitType::kPixels)); return style;
diff --git a/third_party/blink/renderer/core/html/html_view_source_document.cc b/third_party/blink/renderer/core/html/html_view_source_document.cc index 26fd34d..e45fe09 100644 --- a/third_party/blink/renderer/core/html/html_view_source_document.cc +++ b/third_party/blink/renderer/core/html/html_view_source_document.cc
@@ -52,7 +52,7 @@ HTMLViewSourceDocument::HTMLViewSourceDocument(const DocumentInit& initializer, const String& mime_type) - : HTMLDocument(initializer), type_(mime_type) { + : HTMLDocument(initializer, kViewSourceDocumentClass), type_(mime_type) { SetIsViewSource(true); // FIXME: Why do view-source pages need to load in quirks mode?
diff --git a/third_party/blink/renderer/core/html/html_view_source_document.h b/third_party/blink/renderer/core/html/html_view_source_document.h index 97ffda6..021425c 100644 --- a/third_party/blink/renderer/core/html/html_view_source_document.h +++ b/third_party/blink/renderer/core/html/html_view_source_document.h
@@ -75,9 +75,6 @@ Element* AddLink(const AtomicString& url, bool is_anchor); Element* AddBase(const AtomicString& href); - // A view-source document is not a regular WebPage. - bool HasCustomizedFeaturePolicy() const final { return false; } - String type_; Member<Element> current_; Member<HTMLTableSectionElement> tbody_;
diff --git a/third_party/blink/renderer/core/input/event_handler.cc b/third_party/blink/renderer/core/input/event_handler.cc index c3189ff..344bd58 100644 --- a/third_party/blink/renderer/core/input/event_handler.cc +++ b/third_party/blink/renderer/core/input/event_handler.cc
@@ -1401,6 +1401,12 @@ mouse_wheel_event_manager_->ElementRemoved(target); } +void EventHandler::SetMousePositionForPointerUnlock( + FloatPoint lock_position_in_screen) { + pointer_event_manager_->SetLastMousePositionForPointerUnlock( + lock_position_in_screen); +} + WebInputEventResult EventHandler::DispatchMousePointerEvent( const WebInputEvent::Type event_type, Element* target_element,
diff --git a/third_party/blink/renderer/core/input/event_handler.h b/third_party/blink/renderer/core/input/event_handler.h index 7666b16..1f954f0 100644 --- a/third_party/blink/renderer/core/input/event_handler.h +++ b/third_party/blink/renderer/core/input/event_handler.h
@@ -295,6 +295,10 @@ void SetIsFallbackCursorModeOn(bool is_on); + // Set the last mouse position so that next movemove after unlock will be + // calculated from the lock position. + void SetMousePositionForPointerUnlock(FloatPoint lock_position_in_screen); + private: enum NoCursorChangeType { kNoCursorChange };
diff --git a/third_party/blink/renderer/core/input/event_handler_test.cc b/third_party/blink/renderer/core/input/event_handler_test.cc index 54a85db..7837fa7 100644 --- a/third_party/blink/renderer/core/input/event_handler_test.cc +++ b/third_party/blink/renderer/core/input/event_handler_test.cc
@@ -2796,4 +2796,53 @@ .IsMousePositionUnknown()); } +// Tests that pen dragging on an element and moves will keep the element active. +TEST_F(EventHandlerSimTest, PenDraggingOnElementActive) { + WebView().MainFrameWidget()->Resize(WebSize(800, 600)); + + SimRequest main_resource("https://example.com/test.html", "text/html"); + LoadURL("https://example.com/test.html"); + + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <style> + div { + width: 200px; + height: 200px; + } + </style> + <div id="target"></div> + )HTML"); + + Compositor().BeginFrame(); + WebMouseEvent pen_down(WebMouseEvent::kMouseDown, WebFloatPoint(100, 100), + WebFloatPoint(100, 100), + WebPointerProperties::Button::kLeft, 0, + WebInputEvent::Modifiers::kLeftButtonDown, + WebInputEvent::GetStaticTimeStampForTests()); + pen_down.pointer_type = blink::WebPointerProperties::PointerType::kPen; + pen_down.SetFrameScale(1); + WebView().MainFrameWidget()->HandleInputEvent( + WebCoalescedInputEvent(pen_down)); + + WebMouseEvent pen_move(WebMouseEvent::kMouseMove, WebFloatPoint(100, 100), + WebFloatPoint(100, 100), + WebPointerProperties::Button::kLeft, 0, + WebInputEvent::Modifiers::kLeftButtonDown, + WebInputEvent::GetStaticTimeStampForTests()); + pen_move.pointer_type = blink::WebPointerProperties::PointerType::kPen; + pen_move.SetFrameScale(1); + // Send first mouse move to update mouse event sates. + WebView().MainFrameWidget()->HandleInputEvent( + WebCoalescedInputEvent(pen_move)); + + // Send another mouse move again to update active element to verify mouse + // event states. + WebView().MainFrameWidget()->HandleInputEvent( + WebCoalescedInputEvent(pen_move)); + + EXPECT_EQ(GetDocument().GetActiveElement(), + GetDocument().getElementById("target")); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/input/mouse_event_manager.cc b/third_party/blink/renderer/core/input/mouse_event_manager.cc index 4bde658..6049b4db 100644 --- a/third_party/blink/renderer/core/input/mouse_event_manager.cc +++ b/third_party/blink/renderer/core/input/mouse_event_manager.cc
@@ -31,9 +31,11 @@ #include "third_party/blink/renderer/core/layout/hit_test_result.h" #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/page/autoscroll_controller.h" +#include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/drag_controller.h" #include "third_party/blink/renderer/core/page/drag_state.h" #include "third_party/blink/renderer/core/page/focus_controller.h" +#include "third_party/blink/renderer/core/page/pointer_lock_controller.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/svg/svg_document_extensions.h" @@ -63,21 +65,40 @@ void UpdateMouseMovementXY(const WebMouseEvent& mouse_event, const FloatPoint* last_position, + LocalDOMWindow* dom_window, MouseEventInit* initializer) { if (RuntimeEnabledFeatures::ConsolidatedMovementXYEnabled() && mouse_event.GetType() == WebInputEvent::kMouseMove && last_position) { + // TODO(crbug.com/907309): Current movementX/Y is in physical pixel when + // zoom-for-dsf is enabled. Here we apply the device-scale-factor to align + // with the current behavior. We need to figure out what is the best + // behavior here. + float device_scale_factor = 1; + if (dom_window && dom_window->GetFrame()) { + LocalFrame* frame = dom_window->GetFrame(); + if (frame->GetPage()->DeviceScaleFactorDeprecated() == 1) { + device_scale_factor = frame->GetPage() + ->GetChromeClient() + .GetScreenInfo() + .device_scale_factor; + } + } if (RuntimeEnabledFeatures::FractionalMouseEventEnabled()) { - initializer->setMovementX(mouse_event.PositionInScreen().x - - last_position->X()); - initializer->setMovementY(mouse_event.PositionInScreen().y - - last_position->Y()); + initializer->setMovementX( + (mouse_event.PositionInScreen().x - last_position->X()) * + device_scale_factor); + initializer->setMovementY( + (mouse_event.PositionInScreen().y - last_position->Y()) * + device_scale_factor); } else { initializer->setMovementX( - static_cast<int>(mouse_event.PositionInScreen().x) - - static_cast<int>(last_position->X())); + static_cast<int>(mouse_event.PositionInScreen().x * + device_scale_factor) - + static_cast<int>(last_position->X() * device_scale_factor)); initializer->setMovementY( - static_cast<int>(mouse_event.PositionInScreen().y) - - static_cast<int>(last_position->Y())); + static_cast<int>(mouse_event.PositionInScreen().y * + device_scale_factor) - + static_cast<int>(last_position->Y() * device_scale_factor)); } } } @@ -255,7 +276,8 @@ MouseEvent::SetCoordinatesFromWebPointerProperties( mouse_event.FlattenTransform(), target_node->GetDocument().domWindow(), initializer); - UpdateMouseMovementXY(mouse_event, last_position, initializer); + UpdateMouseMovementXY(mouse_event, last_position, + target_node->GetDocument().domWindow(), initializer); initializer->setButton(static_cast<int16_t>(mouse_event.button)); initializer->setButtons(MouseEvent::WebInputEventModifiersToButtons( mouse_event.GetModifiers())); @@ -393,6 +415,10 @@ if (!frame_->GetPage()->IsCursorVisible()) return; + // Don't dispatch a synthetic event if pointer is locked. + if (frame_->GetPage()->GetPointerLockController().GetElement()) + return; + WebPointerEvent::Button button = WebPointerProperties::Button::kNoButton; int modifiers = KeyboardEventManager::GetCurrentModifierState() | WebInputEvent::kRelativeMotionEvent; @@ -829,25 +855,12 @@ frame_->GetSettings()->GetBarrelButtonForDragEnabled()) pen_drag_button = WebPointerProperties::Button::kBarrel; - // While resetting m_mousePressed here may seem out of place, it turns out - // to be needed to handle some bugs^Wfeatures in Blink mouse event handling: - // 1. Certain elements, such as <embed>, capture mouse events. They do not - // bubble back up. One way for a <embed> to start capturing mouse events - // is on a mouse press. The problem is the <embed> node only starts - // capturing mouse events *after* m_mousePressed for the containing frame - // has already been set to true. As a result, the frame's EventHandler - // never sees the mouse release event, which is supposed to reset - // m_mousePressed... so m_mousePressed ends up remaining true until the - // event handler finally gets another mouse released event. Oops. - // 2. Dragging doesn't start until after a mouse press event, but a drag - // that ends as a result of a mouse release does not send a mouse release - // event. As a result, m_mousePressed also ends up remaining true until - // the next mouse release event seen by the EventHandler. + // Only handles dragging for mouse left button drag and pen drag button. if ((!is_pen && event.Event().button != WebPointerProperties::Button::kLeft) || (is_pen && event.Event().button != pen_drag_button)) { - mouse_pressed_ = false; mouse_down_may_start_drag_ = false; + return WebInputEventResult::kNotHandled; } // When pressing Esc key while dragging and the object is outside of the
diff --git a/third_party/blink/renderer/core/input/pointer_event_manager.cc b/third_party/blink/renderer/core/input/pointer_event_manager.cc index ed303b4..ee5126d 100644 --- a/third_party/blink/renderer/core/input/pointer_event_manager.cc +++ b/third_party/blink/renderer/core/input/pointer_event_manager.cc
@@ -465,6 +465,9 @@ WebInputEventResult result = WebInputEventResult::kHandledSystem; if (pointer_event_target.target_element && pointer_event_target.target_frame && !non_hovering_pointers_canceled_) { + SetLastPointerPositionForFrameBoundary(web_pointer_event, + pointer_event_target.target_element); + PointerEvent* pointer_event = pointer_event_factory_.Create( web_pointer_event, coalesced_events, predicted_events, pointer_event_target.target_element @@ -664,21 +667,29 @@ const Vector<WebMouseEvent>& coalesced_events, const Vector<WebMouseEvent>& predicted_events, const String& canvas_region_id) { - // Fetch the last_mouse_position for creating MouseEvent before - // pointer_event_factory updates it. - FloatPoint last_mouse_position = - pointer_event_factory_.GetLastPointerPosition( - PointerEventFactory::kMouseId, event); - WebInputEventResult result = CreateAndDispatchPointerEvent( - target, mouse_event_type, event, coalesced_events, predicted_events, - canvas_region_id); + if (!(event.GetModifiers() & + WebInputEvent::Modifiers::kRelativeMotionEvent)) { + // Fetch the last_mouse_position for creating MouseEvent before + // pointer_event_factory updates it. + FloatPoint last_mouse_position = + pointer_event_factory_.GetLastPointerPosition( + PointerEventFactory::kMouseId, event); - result = event_handling_util::MergeEventResult( - result, mouse_event_manager_->DispatchMouseEvent( - target, mouse_event_type, event, canvas_region_id, - &last_mouse_position, nullptr)); + WebInputEventResult result = CreateAndDispatchPointerEvent( + target, mouse_event_type, event, coalesced_events, predicted_events, + canvas_region_id); - return result; + result = event_handling_util::MergeEventResult( + result, mouse_event_manager_->DispatchMouseEvent( + target, mouse_event_type, event, canvas_region_id, + &last_mouse_position, nullptr)); + return result; + } + pointer_event_factory_.SetLastPosition( + pointer_event_factory_.GetPointerEventId(event), + event.PositionInScreen()); + + return WebInputEventResult::kHandledSuppressed; } WebInputEventResult PointerEventManager::SendMousePointerEvent( @@ -705,7 +716,7 @@ // pointer_event_factory updates it. FloatPoint last_mouse_position = pointer_event_factory_.GetLastPointerPosition( - PointerEventFactory::kMouseId, mouse_event); + pointer_event_factory_.GetPointerEventId(mouse_event), mouse_event); PointerEvent* pointer_event = pointer_event_factory_.Create( web_pointer_event, pointer_coalesced_events, pointer_predicted_events, @@ -1043,6 +1054,29 @@ return false; } +void PointerEventManager::SetLastPointerPositionForFrameBoundary( + const WebPointerEvent& web_pointer_event, + Element* new_target) { + PointerId pointer_id = + pointer_event_factory_.GetPointerEventId(web_pointer_event); + Element* last_target = element_under_pointer_.Contains(pointer_id) + ? element_under_pointer_.at(pointer_id).target + : nullptr; + if (!new_target) { + pointer_event_factory_.RemoveLastPosition(pointer_id); + } else if (!last_target || new_target->GetDocument().GetFrame() != + last_target->GetDocument().GetFrame()) { + pointer_event_factory_.SetLastPosition( + pointer_id, web_pointer_event.PositionInScreen()); + } +} + +void PointerEventManager::SetLastMousePositionForPointerUnlock( + FloatPoint mouse_lock_position_in_screen) { + pointer_event_factory_.SetLastPosition(PointerEventFactory::kMouseId, + mouse_lock_position_in_screen); +} + void PointerEventManager::RemoveLastMousePosition() { pointer_event_factory_.RemoveLastPosition(PointerEventFactory::kMouseId); }
diff --git a/third_party/blink/renderer/core/input/pointer_event_manager.h b/third_party/blink/renderer/core/input/pointer_event_manager.h index 55cbda4f..09a29bf7 100644 --- a/third_party/blink/renderer/core/input/pointer_event_manager.h +++ b/third_party/blink/renderer/core/input/pointer_event_manager.h
@@ -98,6 +98,9 @@ void RemoveLastMousePosition(); + void SetLastMousePositionForPointerUnlock( + FloatPoint mouse_lock_position_in_screen); + Element* GetMouseCaptureTarget(); // Sends any outstanding events. For example it notifies TouchEventManager @@ -191,6 +194,13 @@ PointerEvent*); void SetElementUnderPointer(PointerEvent*, Element*); + // First movement after entering a new frame should be 0 as the new frame + // doesn't have the info for the previous events. This function sets the + // LastPosition to be same as current event position when target is in + // different frame, so that movement_x/y will be 0. + void SetLastPointerPositionForFrameBoundary(const WebPointerEvent& event, + Element* target); + // Processes the assignment of |m_pointerCaptureTarget| from // |m_pendingPointerCaptureTarget| and sends the got/lostpointercapture // events, as per the spec:
diff --git a/third_party/blink/renderer/core/input/scroll_manager.cc b/third_party/blink/renderer/core/input/scroll_manager.cc index fa4008d..c16ddd13 100644 --- a/third_party/blink/renderer/core/input/scroll_manager.cc +++ b/third_party/blink/renderer/core/input/scroll_manager.cc
@@ -318,7 +318,7 @@ ScrollableArea::ScrollCallback callback; if (RuntimeEnabledFeatures::UpdateHoverFromScrollAtBeginFrameEnabled()) { - callback = ScrollableArea::ScrollCallback(base::BindOnce( + callback = ScrollableArea::ScrollCallback(WTF::Bind( [](WeakPersistent<ScrollableArea> area) { if (area) area->MarkHoverStateDirty();
diff --git a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc index 0efc5a8..1bffc8a 100644 --- a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
@@ -776,7 +776,7 @@ BuildInitiatorObject(loader && loader->GetFrame() ? loader->GetFrame()->GetDocument() : nullptr, - initiator_info); + initiator_info, std::numeric_limits<int>::max()); std::unique_ptr<protocol::Network::Request> request_info( BuildObjectForResourceRequest(request, max_post_data_size_.Get())); @@ -1152,7 +1152,8 @@ std::unique_ptr<protocol::Network::Initiator> InspectorNetworkAgent::BuildInitiatorObject( Document* document, - const FetchInitiatorInfo& initiator_info) { + const FetchInitiatorInfo& initiator_info, + int max_async_depth) { if (!initiator_info.imported_module_referrer.IsEmpty()) { std::unique_ptr<protocol::Network::Initiator> initiator_object = protocol::Network::Initiator::create() @@ -1166,7 +1167,8 @@ std::unique_ptr<v8_inspector::protocol::Runtime::API::StackTrace> current_stack_trace = - SourceLocation::Capture(document)->BuildInspectorObject(); + SourceLocation::Capture(document)->BuildInspectorObject( + max_async_depth); if (current_stack_trace) { std::unique_ptr<protocol::Network::Initiator> initiator_object = protocol::Network::Initiator::create() @@ -1559,9 +1561,13 @@ const KURL&, double, ClientNavigationReason) { + // For navigations, we limit async stack trace to depth 1 to avoid the + // base::Value depth limits with Mojo serialization / parsing. + // See http://crbug.com/809996. frame_navigation_initiator_map_.Set( IdentifiersFactory::FrameId(frame), - BuildInitiatorObject(frame->GetDocument(), FetchInitiatorInfo())); + BuildInitiatorObject(frame->GetDocument(), FetchInitiatorInfo(), + /*max_async_depth=*/1)); } void InspectorNetworkAgent::FrameClearedScheduledNavigation(LocalFrame* frame) { @@ -1661,7 +1667,11 @@ frame_navigation_initiator_map_.find(IdentifiersFactory::FrameId(frame)); if (it != frame_navigation_initiator_map_.end()) return it->value->toJSON(); - return BuildInitiatorObject(frame->GetDocument(), FetchInitiatorInfo()) + // For navigations, we limit async stack trace to depth 1 to avoid the + // base::Value depth limits with Mojo serialization / parsing. + // See http://crbug.com/809996. + return BuildInitiatorObject(frame->GetDocument(), FetchInitiatorInfo(), + /*max_async_depth=*/1) ->toJSON(); }
diff --git a/third_party/blink/renderer/core/inspector/inspector_network_agent.h b/third_party/blink/renderer/core/inspector/inspector_network_agent.h index 3b916fdb..86a67007 100644 --- a/third_party/blink/renderer/core/inspector/inspector_network_agent.h +++ b/third_party/blink/renderer/core/inspector/inspector_network_agent.h
@@ -260,7 +260,8 @@ static std::unique_ptr<protocol::Network::Initiator> BuildInitiatorObject( Document*, - const FetchInitiatorInfo&); + const FetchInitiatorInfo&, + int max_async_depth); static bool IsNavigation(DocumentLoader*, uint64_t identifier); // This is null while inspecting workers.
diff --git a/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.cc b/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.cc index e78530e..1fb3468 100644 --- a/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.cc +++ b/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.cc
@@ -45,14 +45,14 @@ std::unique_ptr<GlobalScopeCreationParams> creation_params, WorkerReportingProxy& reporting_proxy, PendingLayoutRegistry* pending_layout_registry) - : WorkletGlobalScope(std::move(creation_params), reporting_proxy, frame), - pending_layout_registry_(pending_layout_registry) { - // Enable a separate microtask queue for LayoutWorklet. - // - // TODO(yutak): Set agent for all worklets and workers, not just - // LayoutWorklet. - SetAgent(Agent::CreateForWorkerOrWorklet(ToIsolate(frame))); -} + : WorkletGlobalScope(std::move(creation_params), + reporting_proxy, + frame, + // Enable a separate microtask queue for LayoutWorklet. + // TODO(yutak): Set agent for all worklets and workers, + // not just LayoutWorklet. + Agent::CreateForWorkerOrWorklet(ToIsolate(frame))), + pending_layout_registry_(pending_layout_registry) {} LayoutWorkletGlobalScope::~LayoutWorkletGlobalScope() = default;
diff --git a/third_party/blink/renderer/core/layout/layout_block_flow_line.cc b/third_party/blink/renderer/core/layout/layout_block_flow_line.cc index eee0e9cc..8b719f5 100644 --- a/third_party/blink/renderer/core/layout/layout_block_flow_line.cc +++ b/third_party/blink/renderer/core/layout/layout_block_flow_line.cc
@@ -2697,7 +2697,7 @@ void LayoutBlockFlow::SetShouldDoFullPaintInvalidationForFirstLine() { DCHECK(ChildrenInline()); if (RootInlineBox* first_root_box = FirstRootBox()) - first_root_box->SetShouldDoFullPaintInvalidationForFirstLine(); + first_root_box->SetShouldDoFullPaintInvalidationRecursively(); else if (const NGPaintFragment* paint_fragment = PaintFragment()) paint_fragment->SetShouldDoFullPaintInvalidationForFirstLine(); }
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc index 04d1a46..2e9fa45 100644 --- a/third_party/blink/renderer/core/layout/layout_box.cc +++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -5358,13 +5358,28 @@ DISABLE_CFI_PERF bool LayoutBox::ShouldBeConsideredAsReplaced() const { - // Checkboxes and radioboxes are not isAtomicInlineLevel() nor do they have - // their own layoutObject in which to override avoidFloats(). if (IsAtomicInlineLevel()) return true; + // We need to detect all types of objects that should be treated as replaced. + // Callers of this method will use the result for various things, such as + // determining how to size the object, or whether it needs to avoid adjacent + // floats, just like objects that establish a new formatting context. + // IsAtomicInlineLevel() will not catch all the cases. Objects may be + // block-level and still replaced, and we cannot deduce this from the + // LayoutObject type. Checkboxes and radio buttons are such examples. We need + // to check the Element type. This also applies to images, since we may have + // created a block-flow LayoutObject for the ALT text (which still counts as + // replaced). auto* element = DynamicTo<Element>(GetNode()); - return element && - (element->IsFormControlElement() || IsHTMLImageElement(element)); + if (!element) + return false; + if (element->IsFormControlElement()) { + // Form control elements are generally replaced objects. Fieldsets are not, + // though. A fieldset is (almost) a regular block container, and should be + // treated as such. + return !IsHTMLFieldSetElement(element); + } + return IsHTMLImageElement(element); } bool LayoutBox::HasNonCompositedScrollbars() const {
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc index 57e34c45..31972be 100644 --- a/third_party/blink/renderer/core/layout/layout_object.cc +++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -1983,18 +1983,8 @@ DCHECK(style); StyleDifference diff; - if (style_) { + if (style_) diff = style_->VisualInvalidationDiff(GetDocument(), *style); - if (const auto* cached_inherited_first_line_style = - style_->GetCachedPseudoStyle(kPseudoIdFirstLineInherited)) { - // Merge the difference to the first line style because even if the new - // style is the same as the old style, the new style may have some higher - // priority properties overriding first line style. - // See external/wpt/css/css-pseudo/first-line-change-inline-color*.html. - diff.Merge(cached_inherited_first_line_style->VisualInvalidationDiff( - GetDocument(), *style)); - } - } diff = AdjustStyleDifference(diff); @@ -2134,8 +2124,7 @@ void LayoutObject::UpdateFirstLineImageObservers( const ComputedStyle* new_style) { bool has_new_first_line_style = - new_style && new_style->HasPseudoStyle(kPseudoIdFirstLine) && - BehavesLikeBlockContainer(); + new_style && new_style->HasPseudoStyle(kPseudoIdFirstLine); if (!bitfields_.RegisteredAsFirstLineImageObserver() && !has_new_first_line_style) return; @@ -2150,21 +2139,36 @@ ? first_line_style_map.at(this) : nullptr; - const auto* new_first_line_style = - has_new_first_line_style ? FirstLineStyleWithoutFallback() : nullptr; + // Don't call CacheFirstLineStyle() which will update the cache, because this + // function can be called when the object has not been inserted into the tree + // and we can't update the pseudo style cache which may depend on ancestors. + const auto* cached_new_first_line_style = + has_new_first_line_style + ? new_style->GetCachedPseudoStyle(kPseudoIdFirstLine) + : nullptr; - if (new_first_line_style && !new_first_line_style->HasBackgroundImage()) - new_first_line_style = nullptr; + if (has_new_first_line_style) { + // If cached_new_first_line_style is null, it means that the new first line + // style has not been cached yet. Will check again when the object's first + // line style is actually used and cached. + bitfields_.SetPendingUpdateFirstLineImageObservers( + !cached_new_first_line_style); + } - if (old_first_line_style || new_first_line_style) { - UpdateFillImages( - old_first_line_style ? &old_first_line_style->BackgroundLayers() - : nullptr, - new_first_line_style ? &new_first_line_style->BackgroundLayers() - : nullptr); - if (new_first_line_style) { + if (cached_new_first_line_style && + !cached_new_first_line_style->HasBackgroundImage()) + cached_new_first_line_style = nullptr; + + if (old_first_line_style || cached_new_first_line_style) { + UpdateFillImages(old_first_line_style + ? &old_first_line_style->BackgroundLayers() + : nullptr, + cached_new_first_line_style + ? &cached_new_first_line_style->BackgroundLayers() + : nullptr); + if (cached_new_first_line_style) { bitfields_.SetRegisteredAsFirstLineImageObserver(true); - first_line_style_map.Set(this, new_first_line_style); + first_line_style_map.Set(this, cached_new_first_line_style); } else { bitfields_.SetRegisteredAsFirstLineImageObserver(false); first_line_style_map.erase(this); @@ -2398,7 +2402,7 @@ if (Parent() && has_old_first_line_style && has_new_first_line_style) { if (const auto* old_first_line_style = old_style->GetCachedPseudoStyle(kPseudoIdFirstLine)) { - if (const auto* new_first_line_style = FirstLineStyleWithoutFallback()) { + if (auto new_first_line_style = UncachedFirstLineStyle()) { diff = old_first_line_style->VisualInvalidationDiff( GetDocument(), *new_first_line_style); has_diff = true; @@ -3365,50 +3369,75 @@ UpdateLayout(); } -const ComputedStyle* LayoutObject::FirstLineStyleWithoutFallback() const { - DCHECK(GetDocument().GetStyleEngine().UsesFirstLineRules()); +enum StyleCacheState { kCached, kUncached }; - if (IsBeforeOrAfterContent() || IsText()) { - if (!Parent()) +static scoped_refptr<const ComputedStyle> FirstLineStyleForCachedUncachedType( + StyleCacheState type, + const LayoutObject* layout_object, + const ComputedStyle* style) { + DCHECK(layout_object); + + const LayoutObject* layout_object_for_first_line_style = layout_object; + if (layout_object->IsBeforeOrAfterContent()) { + if (!layout_object->Parent()) return nullptr; - return Parent()->FirstLineStyleWithoutFallback(); + layout_object_for_first_line_style = layout_object->Parent(); } - if (BehavesLikeBlockContainer()) { - if (const ComputedStyle* cached = - StyleRef().GetCachedPseudoStyle(kPseudoIdFirstLine)) - return cached; - + if (layout_object_for_first_line_style->BehavesLikeBlockContainer()) { if (const LayoutBlock* first_line_block = - To<LayoutBlock>(this)->EnclosingFirstLineStyleBlock()) { - if (first_line_block->Style() == Style()) - return first_line_block->GetCachedPseudoStyle(kPseudoIdFirstLine); - - // We can't use first_line_block->GetCachedPseudoStyle() because it's - // based on first_line_block's style. We need to get the uncached first - // line style based on this object's style and cache the result in it. - return StyleRef().AddCachedPseudoStyle( - first_line_block->GetUncachedPseudoStyle( - PseudoStyleRequest(kPseudoIdFirstLine), Style())); + To<LayoutBlock>(layout_object_for_first_line_style) + ->EnclosingFirstLineStyleBlock()) { + if (type == kCached) + return first_line_block->GetCachedPseudoStyle(kPseudoIdFirstLine, + style); + return first_line_block->GetUncachedPseudoStyle( + PseudoStyleRequest(kPseudoIdFirstLine), style); } - } else if (!IsAnonymous() && IsLayoutInline() && - !GetNode()->IsFirstLetterPseudoElement()) { - if (const ComputedStyle* cached = - StyleRef().GetCachedPseudoStyle(kPseudoIdFirstLineInherited)) - return cached; - - if (const ComputedStyle* parent_first_line_style = - Parent()->FirstLineStyleWithoutFallback()) { - // A first-line style is in effect. Get uncached first line style based on - // parent_first_line_style and cache the result in this object's style. - return StyleRef().AddCachedPseudoStyle(GetUncachedPseudoStyle( - kPseudoIdFirstLineInherited, parent_first_line_style)); + } else if (!layout_object_for_first_line_style->IsAnonymous() && + layout_object_for_first_line_style->IsLayoutInline() && + !layout_object_for_first_line_style->GetNode() + ->IsFirstLetterPseudoElement()) { + const ComputedStyle* parent_style = + layout_object_for_first_line_style->Parent()->FirstLineStyle(); + if (parent_style != layout_object_for_first_line_style->Parent()->Style()) { + if (type == kCached) { + // A first-line style is in effect. Cache a first-line style for + // ourselves. + return layout_object_for_first_line_style->GetCachedPseudoStyle( + kPseudoIdFirstLineInherited, parent_style); + } + return layout_object_for_first_line_style->GetUncachedPseudoStyle( + PseudoStyleRequest(kPseudoIdFirstLineInherited), parent_style); } } return nullptr; } -const ComputedStyle* LayoutObject::GetCachedPseudoStyle(PseudoId pseudo) const { +scoped_refptr<const ComputedStyle> LayoutObject::UncachedFirstLineStyle() + const { + if (!GetDocument().GetStyleEngine().UsesFirstLineRules()) + return nullptr; + + DCHECK(!IsText()); + + return FirstLineStyleForCachedUncachedType(kUncached, this, style_.get()); +} + +const ComputedStyle* LayoutObject::CachedFirstLineStyle() const { + DCHECK(GetDocument().GetStyleEngine().UsesFirstLineRules()); + + if (scoped_refptr<const ComputedStyle> style = + FirstLineStyleForCachedUncachedType( + kCached, IsText() ? Parent() : this, style_.get())) + return style.get(); + + return style_.get(); +} + +const ComputedStyle* LayoutObject::GetCachedPseudoStyle( + PseudoId pseudo, + const ComputedStyle* parent_style) const { DCHECK_NE(pseudo, kPseudoIdBefore); DCHECK_NE(pseudo, kPseudoIdAfter); if (!GetNode()) @@ -3418,7 +3447,15 @@ if (!element) return nullptr; - return element->CachedStyleForPseudoElement(PseudoStyleRequest(pseudo)); + const auto* cached_pseudo_style = element->CachedStyleForPseudoElement( + PseudoStyleRequest(pseudo), parent_style); + if (cached_pseudo_style && pseudo == kPseudoIdFirstLine && + bitfields_.PendingUpdateFirstLineImageObservers()) { + // Update image observers now after we have updated the first line + // style cache. + const_cast<LayoutObject*>(this)->UpdateFirstLineImageObservers(Style()); + } + return cached_pseudo_style; } scoped_refptr<ComputedStyle> LayoutObject::GetUncachedPseudoStyle(
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h index 95bcef7..7a7a448 100644 --- a/third_party/blink/renderer/core/layout/layout_object.h +++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -1137,12 +1137,12 @@ bool IsRenderedLegendInternal() const; - // The pseudo element style can be cached or uncached. Use the cached method + // The pseudo element style can be cached or uncached. Use the cached method // if the pseudo element doesn't respect any pseudo classes (and therefore - // has no concept of changing state). The cached pseudo style always inherits - // from the originating element's style (because we can cache only one - // version), while the uncached pseudo style can inherit from any style. - const ComputedStyle* GetCachedPseudoStyle(PseudoId) const; + // has no concept of changing state). + const ComputedStyle* GetCachedPseudoStyle( + PseudoId, + const ComputedStyle* parent_style = nullptr) const; scoped_refptr<ComputedStyle> GetUncachedPseudoStyle( const PseudoStyleRequest&, const ComputedStyle* parent_style = nullptr) const; @@ -1735,8 +1735,6 @@ } /* The following methods are inlined in LayoutObjectInlines.h */ - // If first line style is requested and there is no applicable first line - // style, the functions will return the style of this object. inline const ComputedStyle* FirstLineStyle() const; inline const ComputedStyle& FirstLineStyleRef() const; inline const ComputedStyle* Style(bool first_line) const; @@ -2640,6 +2638,10 @@ AncestorSkipInfo* = nullptr) const; private: + // Used only by applyFirstLineChanges to get a first line style based off of a + // given new style, without accessing the cache. + scoped_refptr<const ComputedStyle> UncachedFirstLineStyle() const; + // Adjusts a visual rect in the space of |visual_rect| to be in the space of // the |paint_invalidation_container|, if needed. They can be different only // if |paint_invalidation_container| is a composited scroller. @@ -2685,13 +2687,7 @@ LayoutFlowThread* LocateFlowThreadContainingBlock() const; void RemoveFromLayoutFlowThreadRecursive(LayoutFlowThread*); - // Returns the first line style declared in CSS. The style may be declared on - // an ancestor block (see EnclosingFirstLineStyleBlock()) that applies to this - // object. Returns nullptr if there is no applicable first line style. - // Whether the style applies is based on CSS rules, regardless of whether this - // object is really in the first line which is unknown before layout. - const ComputedStyle* FirstLineStyleWithoutFallback() const; - + const ComputedStyle* CachedFirstLineStyle() const; StyleDifference AdjustStyleDifference(StyleDifference) const; #if DCHECK_IS_ON() @@ -2831,6 +2827,7 @@ descendant_effective_allowed_touch_action_changed_(false), is_effective_root_scroller_(false), is_global_root_scroller_(false), + pending_update_first_line_image_observers_(false), registered_as_first_line_image_observer_(false), is_html_legend_element_(false), has_non_collapsed_border_decoration_(false), @@ -3080,6 +3077,11 @@ ADD_BOOLEAN_BITFIELD(is_effective_root_scroller_, IsEffectiveRootScroller); ADD_BOOLEAN_BITFIELD(is_global_root_scroller_, IsGlobalRootScroller); + // First line style is resolvable only after the object is inserted into + // the tree, so we should set this flag when the object set a style having + // first line style before it is inserted into the tree. + ADD_BOOLEAN_BITFIELD(pending_update_first_line_image_observers_, + PendingUpdateFirstLineImageObservers); // Indicates whether this object has been added as a first line image // observer. ADD_BOOLEAN_BITFIELD(registered_as_first_line_image_observer_,
diff --git a/third_party/blink/renderer/core/layout/layout_object_inlines.h b/third_party/blink/renderer/core/layout/layout_object_inlines.h index e48a354..d5cb8e3 100644 --- a/third_party/blink/renderer/core/layout/layout_object_inlines.h +++ b/third_party/blink/renderer/core/layout/layout_object_inlines.h
@@ -16,11 +16,9 @@ // these methods. inline const ComputedStyle* LayoutObject::FirstLineStyle() const { - if (GetDocument().GetStyleEngine().UsesFirstLineRules()) { - if (const ComputedStyle* first_line_style = FirstLineStyleWithoutFallback()) - return first_line_style; - } - return Style(); + return GetDocument().GetStyleEngine().UsesFirstLineRules() + ? CachedFirstLineStyle() + : Style(); } inline const ComputedStyle& LayoutObject::FirstLineStyleRef() const {
diff --git a/third_party/blink/renderer/core/layout/layout_object_test.cc b/third_party/blink/renderer/core/layout/layout_object_test.cc index 4d708109..28a54ec 100644 --- a/third_party/blink/renderer/core/layout/layout_object_test.cc +++ b/third_party/blink/renderer/core/layout/layout_object_test.cc
@@ -1040,19 +1040,4 @@ UpdateAllLifecyclePhasesForTest(); } -TEST_F(LayoutObjectTest, FirstLineBackgroundImageChangeStyleCrash) { - SetBodyInnerHTML(R"HTML( - <style> - #target::first-line { - background-image: url(data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==); - } - </style> - <div id="target">Target</div> - )HTML"); - // This should not crash. - GetDocument().getElementById("target")->setAttribute(html_names::kStyleAttr, - "color: blue"); - UpdateAllLifecyclePhasesForTest(); -} - } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_shift_tracker.cc b/third_party/blink/renderer/core/layout/layout_shift_tracker.cc index f4a595efb..04efa65 100644 --- a/third_party/blink/renderer/core/layout/layout_shift_tracker.cc +++ b/third_party/blink/renderer/core/layout/layout_shift_tracker.cc
@@ -119,7 +119,8 @@ &LayoutShiftTracker::TimerFired), frame_max_distance_(0.0), overall_max_distance_(0.0), - observed_input_or_scroll_(false) {} + observed_input_or_scroll_(false), + most_recent_input_timestamp_initialized_(false) {} void LayoutShiftTracker::AccumulateJank( const LayoutObject& source, @@ -291,7 +292,8 @@ double jank_fraction = region_area / viewport_area; DCHECK_GT(jank_fraction, 0); - score_ += jank_fraction; + if (!HadRecentInput()) + score_ += jank_fraction; DCHECK_GT(frame_max_distance_, 0.0); double viewport_max_dimension = std::max(viewport.Width(), viewport.Height()); @@ -302,13 +304,14 @@ double jank_fraction_with_move_distance = jank_fraction * move_distance_factor; - score_with_move_distance_ += jank_fraction_with_move_distance; + if (!HadRecentInput()) + score_with_move_distance_ += jank_fraction_with_move_distance; overall_max_distance_ = std::max(overall_max_distance_, frame_max_distance_); LocalFrame& frame = frame_view_->GetFrame(); #if DCHECK_IS_ON() - if (ShouldLog(frame)) { + if (!HadRecentInput() && ShouldLog(frame)) { DVLOG(1) << "in " << (frame.IsMainFrame() ? "" : "subframe ") << frame.GetDocument()->Url().GetString() << ", viewport was " << (jank_fraction * 100) << "% janked; raising score to " @@ -319,16 +322,18 @@ TRACE_EVENT_INSTANT2( "loading", "LayoutShift", TRACE_EVENT_SCOPE_THREAD, "data", PerFrameTraceData(jank_fraction, jank_fraction_with_move_distance, - granularity_scale), + granularity_scale, HadRecentInput()), "frame", ToTraceValue(&frame)); - double weighted_jank_fraction = jank_fraction * SubframeWeightingFactor(); - if (weighted_jank_fraction > 0) { - weighted_score_ += weighted_jank_fraction; - if (RuntimeEnabledFeatures::LayoutInstabilityMoveDistanceEnabled()) - weighted_jank_fraction *= move_distance_factor; - frame.Client()->DidObserveLayoutJank(weighted_jank_fraction, - observed_input_or_scroll_); + if (!HadRecentInput()) { + double weighted_jank_fraction = jank_fraction * SubframeWeightingFactor(); + if (weighted_jank_fraction > 0) { + weighted_score_ += weighted_jank_fraction; + if (RuntimeEnabledFeatures::LayoutInstabilityMoveDistanceEnabled()) + weighted_jank_fraction *= move_distance_factor; + frame.Client()->DidObserveLayoutJank(weighted_jank_fraction, + observed_input_or_scroll_); + } } if (RuntimeEnabledFeatures::LayoutInstabilityAPIEnabled( @@ -336,23 +341,22 @@ frame.DomWindow()) { WindowPerformance* performance = DOMWindowPerformance::performance(*frame.DomWindow()); - if (performance && - (performance->HasObserverFor(PerformanceEntry::kLayoutJank) || - performance->ShouldBufferEntries())) { + if (performance) { performance->AddLayoutJankFraction( RuntimeEnabledFeatures::LayoutInstabilityMoveDistanceEnabled() ? jank_fraction_with_move_distance - : jank_fraction); + : jank_fraction, + HadRecentInput(), most_recent_input_timestamp_); } } if (use_sweep_line) { - if (!region_experimental_.IsEmpty()) { + if (!region_experimental_.IsEmpty() && !HadRecentInput()) { SetLayoutShiftRects(region_experimental_.GetRects(), 1, true); } region_experimental_.Reset(); } else { - if (!region_.IsEmpty()) { + if (!region_.IsEmpty() && !HadRecentInput()) { SetLayoutShiftRects(region_.Rects(), granularity_scale, false); } region_ = Region(); @@ -378,6 +382,16 @@ // This cancels any previously scheduled task from the same timer. timer_.StartOneShot(kTimerDelay, FROM_HERE); + UpdateInputTimestamp(event.TimeStamp()); +} + +void LayoutShiftTracker::UpdateInputTimestamp(base::TimeTicks timestamp) { + if (!most_recent_input_timestamp_initialized_) { + most_recent_input_timestamp_ = timestamp; + most_recent_input_timestamp_initialized_ = true; + } else if (timestamp > most_recent_input_timestamp_) { + most_recent_input_timestamp_ = timestamp; + } } void LayoutShiftTracker::NotifyScroll(ScrollType scroll_type) { @@ -392,6 +406,11 @@ void LayoutShiftTracker::NotifyViewportSizeChanged() { // This cancels any previously scheduled task from the same timer. timer_.StartOneShot(kTimerDelay, FROM_HERE); + UpdateInputTimestamp(base::TimeTicks::Now()); +} + +bool LayoutShiftTracker::HadRecentInput() { + return timer_.IsActive(); } bool LayoutShiftTracker::IsActive() { @@ -399,17 +418,14 @@ // SVGImage::DataChanged. if (frame_view_->GetFrame().GetChromeClient().IsSVGImageChromeClient()) return false; - - if (timer_.IsActive()) - return false; - return true; } std::unique_ptr<TracedValue> LayoutShiftTracker::PerFrameTraceData( double jank_fraction, double jank_fraction_with_move_distance, - double granularity_scale) const { + double granularity_scale, + bool input_detected) const { auto value = std::make_unique<TracedValue>(); value->SetDouble("score", jank_fraction); value->SetDouble("score_with_move_distance", @@ -424,6 +440,7 @@ else RegionToTracedValue(region_, granularity_scale, *value); value->SetBoolean("is_main_frame", frame_view_->GetFrame().IsMainFrame()); + value->SetBoolean("had_recent_input", input_detected); return value; }
diff --git a/third_party/blink/renderer/core/layout/layout_shift_tracker.h b/third_party/blink/renderer/core/layout/layout_shift_tracker.h index 147e6144..7138142 100644 --- a/third_party/blink/renderer/core/layout/layout_shift_tracker.h +++ b/third_party/blink/renderer/core/layout/layout_shift_tracker.h
@@ -42,6 +42,7 @@ void NotifyInput(const WebInputEvent&); void NotifyScroll(ScrollType); void NotifyViewportSizeChanged(); + bool HadRecentInput(); bool IsActive(); double Score() const { return score_; } double ScoreWithMoveDistance() const { return score_with_move_distance_; } @@ -49,6 +50,9 @@ float OverallMaxDistance() const { return overall_max_distance_; } bool ObservedInputOrScroll() const { return observed_input_or_scroll_; } void Dispose() { timer_.Stop(); } + base::TimeTicks MostRecentInputTimestamp() { + return most_recent_input_timestamp_; + } private: void AccumulateJank(const LayoutObject&, @@ -59,7 +63,8 @@ std::unique_ptr<TracedValue> PerFrameTraceData( double jank_fraction, double jank_fraction_with_move_distance, - double granularity_scale) const; + double granularity_scale, + bool input_detected) const; double SubframeWeightingFactor() const; WebVector<gfx::Rect> ConvertIntRectsToGfxRects( const Vector<IntRect>& int_rects, @@ -67,6 +72,7 @@ void SetLayoutShiftRects(const Vector<IntRect>& int_rects, double granularity_scale, bool using_sweep_line); + void UpdateInputTimestamp(base::TimeTicks timestamp); // This owns us. UntracedMember<LocalFrameView> frame_view_; @@ -105,6 +111,11 @@ // Whether either a user input or document scroll have been observed. bool observed_input_or_scroll_; + + // Most recent timestamp of a user input event that has been observed. + // User input includes window resizing but not scrolling. + base::TimeTicks most_recent_input_timestamp_; + bool most_recent_input_timestamp_initialized_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_shift_tracker_test.cc b/third_party/blink/renderer/core/layout/layout_shift_tracker_test.cc index 4e42d5c..269b55a 100644 --- a/third_party/blink/renderer/core/layout/layout_shift_tracker_test.cc +++ b/third_party/blink/renderer/core/layout/layout_shift_tracker_test.cc
@@ -150,6 +150,10 @@ UpdateAllLifecyclePhases(); EXPECT_EQ(0.0, GetLayoutShiftTracker().Score()); EXPECT_TRUE(GetLayoutShiftTracker().ObservedInputOrScroll()); + EXPECT_TRUE(GetLayoutShiftTracker() + .MostRecentInputTimestamp() + .since_origin() + .InSecondsF() > 0.0); } TEST_F(LayoutShiftTrackerTest, CompositedElementMovement) {
diff --git a/third_party/blink/renderer/core/layout/line/inline_box.cc b/third_party/blink/renderer/core/layout/line/inline_box.cc index 32e388df..ce4ee01 100644 --- a/third_party/blink/renderer/core/layout/line/inline_box.cc +++ b/third_party/blink/renderer/core/layout/line/inline_box.cc
@@ -352,14 +352,13 @@ return Root().Block().FlipForWritingMode(point); } -void InlineBox::SetShouldDoFullPaintInvalidationForFirstLine() { - GetLineLayoutItem().StyleRef().ClearCachedPseudoStyles(); +void InlineBox::SetShouldDoFullPaintInvalidationRecursively() { GetLineLayoutItem().SetShouldDoFullPaintInvalidation(); if (!IsInlineFlowBox()) return; for (InlineBox* child = ToInlineFlowBox(this)->FirstChild(); child; child = child->NextOnLine()) - child->SetShouldDoFullPaintInvalidationForFirstLine(); + child->SetShouldDoFullPaintInvalidationRecursively(); } void InlineBox::SetLineLayoutItemShouldDoFullPaintInvalidationIfNeeded() {
diff --git a/third_party/blink/renderer/core/layout/line/inline_box.h b/third_party/blink/renderer/core/layout/line/inline_box.h index 2d5dc20..bd7a4bc 100644 --- a/third_party/blink/renderer/core/layout/line/inline_box.h +++ b/third_party/blink/renderer/core/layout/line/inline_box.h
@@ -374,8 +374,8 @@ } // Set all LineLayoutItems in the inline box subtree should do full paint - // invalidation and clear the first line style cache. - void SetShouldDoFullPaintInvalidationForFirstLine(); + // invalidation. + void SetShouldDoFullPaintInvalidationRecursively(); #define ADD_BOOLEAN_BITFIELD(field_name_, MethodNameBase) \ public: \
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc index 748872f..efe866f3 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
@@ -324,6 +324,8 @@ // Use 'text-indent' as the initial position. This lets tab positions to align // regardless of 'text-indent'. position_ = line_info->TextIndent(); + + overflow_item_index_ = 0; } void NGLineBreaker::NextLine( @@ -407,6 +409,11 @@ #endif continue; } + if (item.Type() == NGInlineItem::kOpenTag) { + if (HandleOpenTag(item, line_info)) + continue; + return; + } if (item.Type() == NGInlineItem::kAtomicInline) { if (HandleAtomicInline(item, percentage_resolution_block_size_for_min_max, line_info)) { @@ -439,9 +446,7 @@ return; } - if (item.Type() == NGInlineItem::kOpenTag) { - HandleOpenTag(item, line_info); - } else if (item.Type() == NGInlineItem::kOutOfFlowPositioned) { + if (item.Type() == NGInlineItem::kOutOfFlowPositioned) { AddItem(item, line_info); MoveToNextOf(item); } else if (item.Length()) { @@ -1337,7 +1342,8 @@ bool NGLineBreaker::ComputeOpenTagResult( const NGInlineItem& item, const NGConstraintSpace& constraint_space, - NGInlineItemResult* item_result) { + NGInlineItemResult* item_result, + base::Optional<NGLineBoxStrut> margins) { DCHECK_EQ(item.Type(), NGInlineItem::kOpenTag); DCHECK(item.Style()); const ComputedStyle& style = *item.Style(); @@ -1348,7 +1354,9 @@ item_result->borders = ComputeLineBorders(style); item_result->padding = ComputeLinePadding(constraint_space, style); if (item_result->has_edge) { - item_result->margins = ComputeLineMarginsForSelf(constraint_space, style); + item_result->margins = + margins ? *margins + : ComputeLineMarginsForSelf(constraint_space, style); item_result->inline_size = item_result->margins.inline_start + item_result->borders.inline_start + item_result->padding.inline_start; @@ -1358,11 +1366,39 @@ return false; } -void NGLineBreaker::HandleOpenTag(const NGInlineItem& item, +bool NGLineBreaker::HandleOpenTag(const NGInlineItem& item, NGLineInfo* line_info) { + DCHECK_EQ(item.Type(), NGInlineItem::kOpenTag); + DCHECK(item.Style()); + const ComputedStyle& style = *item.Style(); + + // OpenTag is not trailable, except when it has negative inline-start margin, + // which can bring the position back to inside of the available width. + base::Optional<NGLineBoxStrut> margins; + if (UNLIKELY(state_ == LineBreakState::kTrailing && + CanBreakAfterLast(line_info->Results()))) { + bool can_continue = false; + if (UNLIKELY(item_index_ >= overflow_item_index_ && + item.ShouldCreateBoxFragment() && item.HasStartEdge() && + style.MayHaveMargin())) { + margins = ComputeLineMarginsForSelf(constraint_space_, style); + LayoutUnit inline_start_margin = margins->inline_start; + can_continue = inline_start_margin < 0 && + position_ + inline_start_margin < AvailableWidthToFit(); + } + if (!can_continue) { + // Not that case. Break the line before this OpenTag. + line_info->SetIsLastLine(false); + return false; + } + // The state is back to normal because the position is back to inside of the + // available width. + state_ = LineBreakState::kContinue; + } + NGInlineItemResult* item_result = AddItem(item, line_info); - if (ComputeOpenTagResult(item, constraint_space_, item_result)) { + if (ComputeOpenTagResult(item, constraint_space_, item_result, margins)) { position_ += item_result->inline_size; // While the spec defines "non-zero margins, padding, or borders" prevents @@ -1374,8 +1410,6 @@ } bool was_auto_wrap = auto_wrap_; - DCHECK(item.Style()); - const ComputedStyle& style = *item.Style(); SetCurrentStyle(style); MoveToNextOf(item); @@ -1384,6 +1418,7 @@ if (UNLIKELY(!was_auto_wrap && auto_wrap_ && item_results.size() >= 2)) { ComputeCanBreakAfter(std::prev(item_result), auto_wrap_, break_iterator_); } + return true; } void NGLineBreaker::HandleCloseTag(const NGInlineItem& item, @@ -1437,6 +1472,8 @@ // At this point, item_results does not fit into the current line, and there // are no break opportunities in item_results.back(). void NGLineBreaker::HandleOverflow(NGLineInfo* line_info) { + overflow_item_index_ = std::max(overflow_item_index_, item_index_); + // Compute the width needing to rewind. When |width_to_rewind| goes negative, // items can fit within the line. LayoutUnit available_width = AvailableWidthToFit(); @@ -1529,6 +1566,7 @@ if (!item_results->IsEmpty()) Rewind(0, line_info); state_ = LineBreakState::kContinue; + overflow_item_index_ = 0; return; }
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h index 9cfae3f..3ba1558 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h
@@ -72,9 +72,11 @@ // Compute NGInlineItemResult for an open tag item. // Returns true if this item has edge and may have non-zero inline size. - static bool ComputeOpenTagResult(const NGInlineItem&, - const NGConstraintSpace&, - NGInlineItemResult*); + static bool ComputeOpenTagResult( + const NGInlineItem&, + const NGConstraintSpace&, + NGInlineItemResult*, + base::Optional<NGLineBoxStrut> margins = base::nullopt); // This enum is private, except for |WhitespaceStateForTesting()|. See // |whitespace_| member. @@ -164,7 +166,7 @@ Vector<LayoutObject*>* out_floats_for_min_max, NGLineInfo*); - void HandleOpenTag(const NGInlineItem&, NGLineInfo*); + bool HandleOpenTag(const NGInlineItem&, NGLineInfo*); void HandleCloseTag(const NGInlineItem&, NGLineInfo*); void HandleOverflow(NGLineInfo*); @@ -265,6 +267,9 @@ }; base::Optional<TrailingCollapsibleSpace> trailing_collapsible_space_; + // Keep track of item index where overflow occurrred. + unsigned overflow_item_index_; + // Keep track of handled float items. See HandleFloat(). const NGPositionedFloatVector& leading_floats_; unsigned leading_floats_index_ = 0u;
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 06472ca..161685c 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
@@ -1560,11 +1560,27 @@ LayoutUnit logical_block_offset = previous_inflow_position.logical_block_offset; - if (child.Style().MarginBeforeCollapse() != EMarginCollapse::kCollapse) { + EMarginCollapse margin_before_collapse = child.Style().MarginBeforeCollapse(); + if (margin_before_collapse != EMarginCollapse::kCollapse) { // Stop margin collapsing on the block-start side of the child. StopMarginCollapsing(child.Style().MarginBeforeCollapse(), margins.block_start, &logical_block_offset, &margin_strut); + + if (margin_before_collapse == EMarginCollapse::kSeparate) { + UseCounter::Count(Node().GetDocument(), + WebFeature::kWebkitMarginBeforeCollapseSeparate); + if (margin_strut != previous_inflow_position.margin_strut || + logical_block_offset != + previous_inflow_position.logical_block_offset) { + UseCounter::Count( + Node().GetDocument(), + WebFeature::kWebkitMarginBeforeCollapseSeparateMaybeDoesSomething); + } + } else if (margin_before_collapse == EMarginCollapse::kDiscard) { + UseCounter::Count(Node().GetDocument(), + WebFeature::kWebkitMarginBeforeCollapseDiscard); + } } else { margin_strut.Append(margins.block_start, child.Style().HasMarginBeforeQuirk()); @@ -1655,11 +1671,26 @@ NGMarginStrut margin_strut = layout_result.EndMarginStrut(); - if (child.Style().MarginAfterCollapse() != EMarginCollapse::kCollapse) { + EMarginCollapse margin_after_collapse = child.Style().MarginAfterCollapse(); + if (margin_after_collapse != EMarginCollapse::kCollapse) { + LayoutUnit logical_block_offset_copy = logical_block_offset; // Stop margin collapsing on the block-end side of the child. - StopMarginCollapsing(child.Style().MarginAfterCollapse(), - child_data.margins.block_end, &logical_block_offset, - &margin_strut); + StopMarginCollapsing(margin_after_collapse, child_data.margins.block_end, + &logical_block_offset, &margin_strut); + + if (margin_after_collapse == EMarginCollapse::kSeparate) { + UseCounter::Count(Node().GetDocument(), + WebFeature::kWebkitMarginAfterCollapseSeparate); + if (margin_strut != layout_result.EndMarginStrut() || + logical_block_offset != logical_block_offset_copy) { + UseCounter::Count( + Node().GetDocument(), + WebFeature::kWebkitMarginAfterCollapseSeparateMaybeDoesSomething); + } + } else if (margin_after_collapse == EMarginCollapse::kDiscard) { + UseCounter::Count(Node().GetDocument(), + WebFeature::kWebkitMarginAfterCollapseDiscard); + } } else { // Self collapsing child's end margin can "inherit" quirkiness from its // start margin. E.g.
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc index 7df0c59..c47b57b 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -20,6 +20,7 @@ #include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h" #include "third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.h" #include "third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h" +#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { @@ -441,10 +442,7 @@ node.GetLayoutBox()->ContainingBlock()->IsTable()); const ContainingBlockInfo& container_info = GetContainingBlockInfo(candidate); - - const TextDirection container_direction = container_info.direction; const TextDirection default_direction = default_containing_block_.direction; - const ComputedStyle& candidate_style = node.Style(); const WritingMode candidate_writing_mode = candidate_style.GetWritingMode(); @@ -481,6 +479,49 @@ .SetPercentageResolutionSize(container_content_size) .ToConstraintSpace(); + base::Optional<PaintLayerScrollableArea::FreezeScrollbarsScope> + freeze_scrollbars; + do { + scoped_refptr<const NGLayoutResult> layout_result = + Layout(node, candidate_constraint_space, physical_static_position, + container_content_size, container_info, only_layout); + + if (!freeze_scrollbars.has_value()) { + // Since out-of-flow positioning sets up a constraint space with fixed + // inline-size, the regular layout code (|NGBlockNode::Layout()|) cannot + // re-layout if it discovers that a scrollbar was added or removed. Handle + // that situation here. The assumption is that if preferred logical widths + // are dirty after layout, it means that scrollbars appeared or + // disappeared. We have the same logic in legacy layout in + // |LayoutBlockFlow::UpdateBlockLayout()|. + if (node.GetLayoutBox()->PreferredLogicalWidthsDirty()) { + // Freeze the scrollbars for this layout pass. We don't want them to + // change *again*. + freeze_scrollbars.emplace(); + continue; + } + } + + return layout_result; + } while (true); +} + +scoped_refptr<const NGLayoutResult> NGOutOfFlowLayoutPart::Layout( + NGBlockNode node, + const NGConstraintSpace& candidate_constraint_space, + const NGPhysicalStaticPosition& physical_static_position, + LogicalSize container_content_size, + const ContainingBlockInfo& container_info, + const LayoutBox* only_layout) { + const TextDirection default_direction = default_containing_block_.direction; + const ComputedStyle& candidate_style = node.Style(); + const WritingMode candidate_writing_mode = candidate_style.GetWritingMode(); + const TextDirection container_direction = container_info.direction; + + PhysicalSize container_physical_content_size = + ToPhysicalSize(container_content_size, writing_mode_); + LogicalSize container_content_size_in_candidate_writing_mode = + container_physical_content_size.ConvertToLogical(candidate_writing_mode); NGBoxStrut border_padding = ComputeBorders(candidate_constraint_space, node) + ComputePadding(candidate_constraint_space, candidate_style); @@ -622,6 +663,8 @@ block_estimate, node_position); } + // TODO(mstensho): Move the rest of this method back into LayoutCandidate(). + if (node.GetLayoutBox()->IsLayoutNGObject()) { To<LayoutBlock>(node.GetLayoutBox()) ->SetIsLegacyInitiatedOutOfFlowLayout(false);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h index 9f5f90e..2d66b63 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h +++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h
@@ -109,6 +109,13 @@ const NGLogicalOutOfFlowPositionedNode&, const LayoutBox* only_layout); + scoped_refptr<const NGLayoutResult> Layout(NGBlockNode, + const NGConstraintSpace&, + const NGPhysicalStaticPosition&, + LogicalSize container_content_size, + const ContainingBlockInfo&, + const LayoutBox* only_layout); + bool IsContainingBlockForCandidate(const NGLogicalOutOfFlowPositionedNode&); scoped_refptr<const NGLayoutResult> GenerateFragment(
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc index 6d4d478..36f4b8b 100644 --- a/third_party/blink/renderer/core/loader/document_loader.cc +++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -1304,11 +1304,8 @@ void DocumentLoader::DidInstallNewDocument(Document* document) { document->SetReadyState(Document::kLoading); - if (content_security_policy_) { - document->InitContentSecurityPolicy( - content_security_policy_.Release(), - GetFrameLoader().GetLastOriginDocumentCSP()); - } + if (content_security_policy_) + document->BindContentSecurityPolicy(); if (history_item_ && IsBackForwardLoadType(load_type_)) document->SetStateForNewFormElements(history_item_->GetDocumentState()); @@ -1480,14 +1477,26 @@ DCHECK(!frame_->GetDocument() || !frame_->GetDocument()->IsActive()); DCHECK_EQ(frame_->Tree().ChildCount(), 0u); - DocumentInit init = DocumentInit::Create() - .WithDocumentLoader(this) - .WithURL(url) - .WithOwnerDocument(owner_document) - .WithInitiatorOrigin(initiator_origin) - .WithOriginToCommit(origin_to_commit_) - .WithSrcdocDocument(loading_srcdoc_) - .WithNewRegistrationContext(); + // FeaturePolicy is reset in the browser process on commit, so this needs to + // be initialized and replicated to the browser process after commit messages + // are sent in didCommitNavigation(). + WTF::StringBuilder feature_policy; + feature_policy.Append(response_.HttpHeaderField(http_names::kFeaturePolicy)); + MergeFeaturesFromOriginPolicy(feature_policy, origin_policy_); + + DocumentInit init = + DocumentInit::Create() + .WithDocumentLoader(this) + .WithURL(url) + .WithOwnerDocument(owner_document) + .WithInitiatorOrigin(initiator_origin) + .WithOriginToCommit(origin_to_commit_) + .WithSrcdocDocument(loading_srcdoc_) + .WithNewRegistrationContext() + .WithFeaturePolicyHeader(feature_policy.ToString()) + .WithOriginTrialsHeader( + response_.HttpHeaderField(http_names::kOriginTrial)) + .WithContentSecurityPolicy(content_security_policy_.Get()); // A javascript: url inherits CSP from the document in which it was // executed. @@ -1592,9 +1601,6 @@ } #endif - OriginTrialContext::AddTokensFromHeader( - document, response_.HttpHeaderField(http_names::kOriginTrial)); - OriginTrialContext::ActivateNavigationFeaturesFromInitiator( document, &initiator_origin_trial_features_); } @@ -1629,10 +1635,7 @@ // FeaturePolicy is reset in the browser process on commit, so this needs to // be initialized and replicated to the browser process after commit messages // are sent in didCommitNavigation(). - WTF::StringBuilder feature_policy; - feature_policy.Append(response_.HttpHeaderField(http_names::kFeaturePolicy)); - MergeFeaturesFromOriginPolicy(feature_policy, origin_policy_); - document->ApplyFeaturePolicyFromHeader(feature_policy.ToString()); + document->ApplyPendingFeaturePolicyHeaders(); WTF::String report_only_feature_policy( response_.HttpHeaderField(http_names::kFeaturePolicyReportOnly));
diff --git a/third_party/blink/renderer/core/loader/document_loader.h b/third_party/blink/renderer/core/loader/document_loader.h index be60065c..b5e42faa 100644 --- a/third_party/blink/renderer/core/loader/document_loader.h +++ b/third_party/blink/renderer/core/loader/document_loader.h
@@ -260,13 +260,6 @@ void BlockParser(); void ResumeParser(); - // Returns the currently stored content security policy, if this is called - // after the document has been installed it will return nullptr as the - // CSP belongs to the document at that point. - const ContentSecurityPolicy* GetContentSecurityPolicy() const { - return content_security_policy_.Get(); - } - bool IsListingFtpDirectory() const { return listing_ftp_directory_; } UseCounterHelper& GetUseCounterHelper() { return use_counter_; }
diff --git a/third_party/blink/renderer/core/page/pointer_lock_controller.cc b/third_party/blink/renderer/core/page/pointer_lock_controller.cc index 869c348..9585b32 100644 --- a/third_party/blink/renderer/core/page/pointer_lock_controller.cc +++ b/third_party/blink/renderer/core/page/pointer_lock_controller.cc
@@ -132,10 +132,18 @@ } void PointerLockController::DidLosePointerLock() { - EnqueueEvent( - event_type_names::kPointerlockchange, + Document* pointer_lock_document = element_ ? &element_->GetDocument() - : document_of_removed_element_while_waiting_for_unlock_.Get()); + : document_of_removed_element_while_waiting_for_unlock_.Get(); + EnqueueEvent(event_type_names::kPointerlockchange, pointer_lock_document); + + // Set the last mouse position back the locked position. + if (pointer_lock_document) { + pointer_lock_document->GetFrame() + ->GetEventHandler() + .SetMousePositionForPointerUnlock(pointer_lock_screen_position_); + } + ClearElement(); document_of_removed_element_while_waiting_for_unlock_ = nullptr; }
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc index 3058d24..edff13e 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc +++ b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc
@@ -139,6 +139,9 @@ if (RequiresCompositingForScrollTimeline(*layer)) reasons |= CompositingReason::kScrollTimelineTarget; + if (RequiresCompositingForScrollDependentPosition(*layer)) + reasons |= CompositingReason::kScrollDependentPosition; + return reasons; }
diff --git a/third_party/blink/renderer/core/paint/image_element_timing.cc b/third_party/blink/renderer/core/paint/image_element_timing.cc index 49f8613..abac00e2 100644 --- a/third_party/blink/renderer/core/paint/image_element_timing.cc +++ b/third_party/blink/renderer/core/paint/image_element_timing.cc
@@ -43,10 +43,6 @@ } // namespace internal -// The maximum amount of characters included in Element Timing for inline -// images. -constexpr const unsigned kInlineImageMaxChars = 100u; - // static const char ImageElementTiming::kSupplementName[] = "ImageElementTiming"; @@ -110,6 +106,12 @@ if (node->IsInShadowTree()) return; + // Do not expose elements which should have effective zero opacity. + // We can afford to call this expensive method because this is only called + // once per image annotated with the elementtiming attribute. + if (!layout_object.HasNonZeroEffectiveOpacity()) + return; + FloatRect intersection_rect = ComputeIntersectionRect( frame, layout_object, current_paint_chunk_properties); const AtomicString attr = @@ -129,9 +131,7 @@ &layout_object.GetDocument())) { WindowPerformance* performance = DOMWindowPerformance::performance(*GetSupplementable()); - if (performance && - (performance->HasObserverFor(PerformanceEntry::kElement) || - performance->ShouldBufferEntries())) { + if (performance) { // Create an entry with a |startTime| of 0. performance->AddElementTiming( ImagePaintString(), url.GetString(), intersection_rect, @@ -210,8 +210,7 @@ base::TimeTicks timestamp) { WindowPerformance* performance = DOMWindowPerformance::performance(*GetSupplementable()); - if (performance && (performance->HasObserverFor(PerformanceEntry::kElement) || - performance->ShouldBufferEntries())) { + if (performance) { for (const auto& element_timing : element_timings_) { performance->AddElementTiming( ImagePaintString(), element_timing->url, element_timing->rect,
diff --git a/third_party/blink/renderer/core/paint/image_element_timing.h b/third_party/blink/renderer/core/paint/image_element_timing.h index 1482e47..82cc5bb 100644 --- a/third_party/blink/renderer/core/paint/image_element_timing.h +++ b/third_party/blink/renderer/core/paint/image_element_timing.h
@@ -32,6 +32,10 @@ public: static const char kSupplementName[]; + // The maximum amount of characters included in Element Timing and Largest + // Contentful Paint for inline images. + static constexpr const unsigned kInlineImageMaxChars = 100; + explicit ImageElementTiming(LocalDOMWindow&); virtual ~ImageElementTiming() = default;
diff --git a/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc b/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc index fcbf385..003ad9fa 100644 --- a/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc +++ b/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc
@@ -331,7 +331,7 @@ if (rect_size == 0) { records_manager_.RecordInvisibleNode(node_id); } else { - records_manager_.RecordVisibleNode(node_id, rect_size); + records_manager_.RecordVisibleNode(node_id, rect_size, cached_image); if (is_loaded) { records_manager_.OnImageLoaded(node_id, frame_index_); need_update_timing_at_frame_end_ = true; @@ -371,10 +371,12 @@ QueueToMeasurePaintTime(record, current_frame_index); } -void ImageRecordsManager::RecordVisibleNode(const DOMNodeId& node_id, - const uint64_t& visual_size) { +void ImageRecordsManager::RecordVisibleNode( + const DOMNodeId& node_id, + const uint64_t& visual_size, + const ImageResourceContent& cached_image) { std::unique_ptr<ImageRecord> record = - CreateImageRecord(node_id, nullptr, visual_size); + CreateImageRecord(node_id, &cached_image, visual_size); size_ordered_set_.insert(record->AsWeakPtr()); visible_node_map_.insert(node_id, std::move(record)); }
diff --git a/third_party/blink/renderer/core/paint/image_paint_timing_detector.h b/third_party/blink/renderer/core/paint/image_paint_timing_detector.h index 03f6e42..dd7cafd8 100644 --- a/third_party/blink/renderer/core/paint/image_paint_timing_detector.h +++ b/third_party/blink/renderer/core/paint/image_paint_timing_detector.h
@@ -78,7 +78,9 @@ DCHECK(!RecordedTooManyNodes()); invisible_node_ids_.insert(node_id); } - void RecordVisibleNode(const DOMNodeId&, const uint64_t& visual_size); + void RecordVisibleNode(const DOMNodeId&, + const uint64_t& visual_size, + const ImageResourceContent&); void RecordVisibleNode(const BackgroundImageId& background_image_id, const uint64_t& visual_size); size_t CountVisibleNodes() const { return visible_node_map_.size(); }
diff --git a/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator.cc b/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator.cc index f220825..1c3c8604 100644 --- a/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator.cc +++ b/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator.cc
@@ -4,6 +4,8 @@ #include "third_party/blink/renderer/core/paint/largest_contentful_paint_calculator.h" +#include "third_party/blink/renderer/core/paint/image_element_timing.h" + namespace blink { LargestContentfulPaintCalculator::LargestContentfulPaintCalculator( @@ -15,8 +17,10 @@ largest_image_.reset(); if (largest_image) { largest_image_ = std::make_unique<ImageRecord>(); + largest_image_->node_id = largest_image->node_id; largest_image_->first_size = largest_image->first_size; largest_image_->paint_time = largest_image->paint_time; + largest_image_->cached_image = largest_image->cached_image; } if (LargestImageSize() > LargestTextSize()) { @@ -55,14 +59,42 @@ DCHECK(window_performance_); DCHECK(type != LargestContentType::kUnknown); last_type_ = type; - // TODO(crbug.com/965505): finish implementation, including adding more - // attribution and doing proper cross-origin checks for images. if (type == LargestContentType::kImage) { + const ImageResourceContent* cached_image = largest_image_->cached_image; + DCHECK(cached_image); + const KURL& url = cached_image->Url(); + auto* document = window_performance_->GetExecutionContext(); + if (!url.ProtocolIsData() && + (!document || !Performance::PassesTimingAllowCheck( + cached_image->GetResponse(), + *document->GetSecurityOrigin(), document))) { + // Reset the paint time of this image. It cannot be exposed to the + // webexposed API. + largest_image_->paint_time = base::TimeTicks(); + } + const String& image_url = + url.ProtocolIsData() + ? url.GetString().Left(ImageElementTiming::kInlineImageMaxChars) + : url.GetString(); + Node* image_node = DOMNodeIds::NodeForId(largest_image_->node_id); + // Do not expose element attribution from shadow trees. + Element* image_element = + image_node->IsInShadowTree() ? nullptr : ToElement(image_node); + const AtomicString& image_id = + image_element ? image_element->GetIdAttribute() : AtomicString(); window_performance_->OnLargestContentfulPaintUpdated( - largest_image_->paint_time, largest_image_->first_size); + largest_image_->paint_time, largest_image_->first_size, + cached_image->LoadResponseEnd(), image_id, image_url, image_element); } else { + Node* text_node = DOMNodeIds::NodeForId(largest_text_->node_id); + // Do not expose element attribution from shadow trees. + Element* text_element = + text_node->IsInShadowTree() ? nullptr : ToElement(text_node); + const AtomicString& text_id = + text_element ? text_element->GetIdAttribute() : AtomicString(); window_performance_->OnLargestContentfulPaintUpdated( - largest_text_->paint_time, largest_text_->first_size); + largest_text_->paint_time, largest_text_->first_size, base::TimeTicks(), + text_id, g_empty_string, text_element); } }
diff --git a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc index de12ac6e..6793b9b 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
@@ -911,10 +911,9 @@ } void NGPaintFragment::SetShouldDoFullPaintInvalidationRecursively() { - if (LayoutObject* layout_object = GetMutableLayoutObject()) { - layout_object->StyleRef().ClearCachedPseudoStyles(); + if (LayoutObject* layout_object = GetMutableLayoutObject()) layout_object->SetShouldDoFullPaintInvalidation(); - } + for (NGPaintFragment* child : Children()) child->SetShouldDoFullPaintInvalidationRecursively(); } @@ -925,7 +924,6 @@ if (NGPaintFragment* line_box = FirstLineBox()) { line_box->SetShouldDoFullPaintInvalidationRecursively(); - GetLayoutObject()->StyleRef().ClearCachedPseudoStyles(); GetMutableLayoutObject()->SetShouldDoFullPaintInvalidation(); } }
diff --git a/third_party/blink/renderer/core/paint/paint_layer.cc b/third_party/blink/renderer/core/paint/paint_layer.cc index 20ecd4ba..954f57fd 100644 --- a/third_party/blink/renderer/core/paint/paint_layer.cc +++ b/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -2511,16 +2511,10 @@ gfx::RRectF PaintLayer::BackdropFilterBounds( const FloatRect& reference_box) const { auto& style = GetLayoutObject().StyleRef(); - gfx::RRectF backdrop_filter_bounds; - if (!style.HasBorderRadius()) { - backdrop_filter_bounds = gfx::RRectF(reference_box, 0); - } else { - FloatRoundedRect rrect = - style.GetRoundedBorderFor(LayoutRect(reference_box)); - backdrop_filter_bounds = gfx::RRectF(rrect); - } - float zoom = style.EffectiveZoom(); - backdrop_filter_bounds.Scale(zoom); + FloatRect scaled_reference_box(reference_box); + scaled_reference_box.Scale(style.EffectiveZoom()); + gfx::RRectF backdrop_filter_bounds = + gfx::RRectF(style.GetRoundedBorderFor(LayoutRect(scaled_reference_box))); return backdrop_filter_bounds; } bool PaintLayer::HitTestClippedOutByClipPath(
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc index 4af7bc46..c9ffd61 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -480,6 +480,9 @@ context_.current.should_flatten_inherited_transform; state.affected_by_outer_viewport_bounds_delta = IsAffectedByOuterViewportBoundsDelta(); + state.direct_compositing_reasons = + full_context_.direct_compositing_reasons & + CompositingReason::kScrollDependentPosition; if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() || RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) state.rendering_context_id = context_.current.rendering_context_id;
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc index 153a488..2770d44 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
@@ -4263,19 +4263,10 @@ ASSERT_TRUE(multicol_container->FirstFragment().NextFragment()); ASSERT_FALSE( multicol_container->FirstFragment().NextFragment()->NextFragment()); - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { - EXPECT_EQ(PhysicalOffset(8, 8), - multicol_container->FirstFragment().PaintOffset()); - EXPECT_EQ( - PhysicalOffset(59, -12), - multicol_container->FirstFragment().NextFragment()->PaintOffset()); - } else { - EXPECT_EQ(PhysicalOffset(), - multicol_container->FirstFragment().PaintOffset()); - EXPECT_EQ( - PhysicalOffset(51, -20), - multicol_container->FirstFragment().NextFragment()->PaintOffset()); - } + EXPECT_EQ(PhysicalOffset(), + multicol_container->FirstFragment().PaintOffset()); + EXPECT_EQ(PhysicalOffset(51, -20), + multicol_container->FirstFragment().NextFragment()->PaintOffset()); GetDocument().View()->LayoutViewport()->ScrollBy(ScrollOffset(0, 25), kUserScroll); @@ -4284,15 +4275,10 @@ ASSERT_TRUE(multicol_container->FirstFragment().NextFragment()); ASSERT_FALSE( multicol_container->FirstFragment().NextFragment()->NextFragment()); - - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { - EXPECT_EQ(PhysicalOffset(8, 8), - multicol_container->FirstFragment().PaintOffset()); - EXPECT_EQ( - PhysicalOffset(59, -12), - multicol_container->FirstFragment().NextFragment()->PaintOffset()); - } else { - } + EXPECT_EQ(PhysicalOffset(), + multicol_container->FirstFragment().PaintOffset()); + EXPECT_EQ(PhysicalOffset(51, -20), + multicol_container->FirstFragment().NextFragment()->PaintOffset()); } TEST_P(PaintPropertyTreeBuilderTest, FragmentsUnderMultiColumn) {
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc b/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc index 35b616d..11b515d0 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc
@@ -1701,4 +1701,28 @@ EXPECT_TRUE(span->GetLayoutObject()->NeedsPaintPropertyUpdate()); } +TEST_P(PaintPropertyTreeUpdateTest, FixedPositionCompositing) { + SetBodyInnerHTML(R"HTML( + <div id="space" style="height: 200px"></div> + <div id="fixed" style="position: fixed; top: 50px; left: 60px">Fixed</div> + )HTML"); + + EXPECT_FALSE(PaintPropertiesForElement("fixed")); + + auto* space = GetDocument().getElementById("space"); + space->setAttribute(html_names::kStyleAttr, "height: 2000px"); + UpdateAllLifecyclePhasesForTest(); + auto* properties = PaintPropertiesForElement("fixed"); + ASSERT_TRUE(properties); + auto* paint_offset_translation = properties->PaintOffsetTranslation(); + ASSERT_TRUE(paint_offset_translation); + EXPECT_EQ(FloatSize(60, 50), paint_offset_translation->Translation2D()); + EXPECT_TRUE(paint_offset_translation->HasDirectCompositingReasons()); + EXPECT_FALSE(properties->Transform()); + + space->setAttribute(html_names::kStyleAttr, "height: 100px"); + UpdateAllLifecyclePhasesForTest(); + EXPECT_FALSE(PaintPropertiesForElement("fixed")); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/scroll/scrollable_area.cc b/third_party/blink/renderer/core/scroll/scrollable_area.cc index 08d111a4..3666288 100644 --- a/third_party/blink/renderer/core/scroll/scrollable_area.cc +++ b/third_party/blink/renderer/core/scroll/scrollable_area.cc
@@ -31,7 +31,6 @@ #include "third_party/blink/renderer/core/scroll/scrollable_area.h" -#include "base/bind.h" #include "build/build_config.h" #include "cc/input/main_thread_scrolling_reason.h" #include "cc/input/scrollbar.h"
diff --git a/third_party/blink/renderer/core/style/computed_style.cc b/third_party/blink/renderer/core/style/computed_style.cc index 57ffbd0e..5c171223 100644 --- a/third_party/blink/renderer/core/style/computed_style.cc +++ b/third_party/blink/renderer/core/style/computed_style.cc
@@ -235,58 +235,34 @@ return Difference::kEqual; if (!old_style || !new_style) return Difference::kInherited; - - // For inline elements, the new computed first line style will be |new_style| - // inheriting from the parent's first line style. If |new_style| is different - // from |old_style|'s cached inherited first line style, the new computed - // first line style may be different from the old even if |new_style| and - // |old_style| equal. Especially if the difference is on inherited properties, - // we need to propagate the difference to descendants. - // See external/wpt/css/css-pseudo/first-line-change-inline-color*.html. - auto inherited_first_line_style_diff = Difference::kEqual; - if (const ComputedStyle* cached_inherited_first_line_style = - old_style->GetCachedPseudoStyle(kPseudoIdFirstLineInherited)) { - DCHECK(!new_style->GetCachedPseudoStyle(kPseudoIdFirstLineInherited)); - inherited_first_line_style_diff = - ComputeDifferenceIgnoringInheritedFirstLineStyle( - *cached_inherited_first_line_style, *new_style); - } - return std::max( - inherited_first_line_style_diff, - ComputeDifferenceIgnoringInheritedFirstLineStyle(*old_style, *new_style)); -} - -ComputedStyle::Difference -ComputedStyle::ComputeDifferenceIgnoringInheritedFirstLineStyle( - const ComputedStyle& old_style, - const ComputedStyle& new_style) { - DCHECK_NE(&old_style, &new_style); - if (old_style.Display() != new_style.Display() && - (old_style.IsDisplayFlexibleOrGridBox() || - old_style.IsDisplayLayoutCustomBox() || - new_style.IsDisplayFlexibleOrGridBox() || - new_style.IsDisplayLayoutCustomBox())) { + if (old_style->Display() != new_style->Display() && + (old_style->IsDisplayFlexibleOrGridBox() || + old_style->IsDisplayLayoutCustomBox() || + old_style->Display() == EDisplay::kContents || + new_style->IsDisplayFlexibleOrGridBox() || + new_style->IsDisplayLayoutCustomBox() || + new_style->Display() == EDisplay::kContents)) { return Difference::kDisplayAffectingDescendantStyles; } - if (!old_style.NonIndependentInheritedEqual(new_style)) + if (!old_style->NonIndependentInheritedEqual(*new_style)) return Difference::kInherited; - if (!old_style.LoadingCustomFontsEqual(new_style) || - old_style.JustifyItems() != new_style.JustifyItems()) + if (!old_style->LoadingCustomFontsEqual(*new_style) || + old_style->JustifyItems() != new_style->JustifyItems()) return Difference::kInherited; - bool non_inherited_equal = old_style.NonInheritedEqual(new_style); - if (!non_inherited_equal && old_style.HasExplicitlyInheritedProperties()) { + bool non_inherited_equal = old_style->NonInheritedEqual(*new_style); + if (!non_inherited_equal && old_style->HasExplicitlyInheritedProperties()) { return Difference::kInherited; } - if (!old_style.IndependentInheritedEqual(new_style)) + if (!old_style->IndependentInheritedEqual(*new_style)) return Difference::kIndependentInherited; if (non_inherited_equal) { - DCHECK(old_style == new_style); - if (PseudoStylesEqual(old_style, new_style)) + DCHECK(*old_style == *new_style); + if (PseudoStylesEqual(*old_style, *new_style)) return Difference::kEqual; return Difference::kPseudoStyle; } - if (new_style.HasAnyPublicPseudoStyles() || - old_style.HasAnyPublicPseudoStyles()) + if (new_style->HasAnyPublicPseudoStyles() || + old_style->HasAnyPublicPseudoStyles()) return Difference::kPseudoStyle; return Difference::kNonInherited; }
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h index 5522c29..cec12c8b6 100644 --- a/third_party/blink/renderer/core/style/computed_style.h +++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -369,10 +369,6 @@ const ComputedStyle* GetCachedPseudoStyle(PseudoId) const; const ComputedStyle* AddCachedPseudoStyle(scoped_refptr<ComputedStyle>) const; - void ClearCachedPseudoStyles() const { - if (cached_pseudo_styles_) - cached_pseudo_styles_->clear(); - } /** * ComputedStyle properties @@ -2682,10 +2678,6 @@ Top(), Right(), Bottom(), Left()); } - static Difference ComputeDifferenceIgnoringInheritedFirstLineStyle( - const ComputedStyle& old_style, - const ComputedStyle& new_style); - FRIEND_TEST_ALL_PREFIXES( ComputedStyleTest, UpdatePropertySpecificDifferencesRespectsTransformAnimation);
diff --git a/third_party/blink/renderer/core/style/computed_style_test.cc b/third_party/blink/renderer/core/style/computed_style_test.cc index cb14340..6c16aa4 100644 --- a/third_party/blink/renderer/core/style/computed_style_test.cc +++ b/third_party/blink/renderer/core/style/computed_style_test.cc
@@ -9,6 +9,7 @@ #include "third_party/blink/renderer/core/css/css_font_selector.h" #include "third_party/blink/renderer/core/css/css_gradient_value.h" #include "third_party/blink/renderer/core/css/css_identifier_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_test_helpers.h" #include "third_party/blink/renderer/core/css/css_value_list.h" #include "third_party/blink/renderer/core/css/properties/css_property_ref.h" @@ -447,9 +448,9 @@ using UnitType = CSSPrimitiveValue::UnitType; - const auto* value1 = CSSPrimitiveValue::Create(1.0, UnitType::kPixels); - const auto* value2 = CSSPrimitiveValue::Create(2.0, UnitType::kPixels); - const auto* value3 = CSSPrimitiveValue::Create(1.0, UnitType::kPixels); + const auto* value1 = CSSNumericLiteralValue::Create(1.0, UnitType::kPixels); + const auto* value2 = CSSNumericLiteralValue::Create(2.0, UnitType::kPixels); + const auto* value3 = CSSNumericLiteralValue::Create(1.0, UnitType::kPixels); Vector<AtomicString> properties; properties.push_back("--x");
diff --git a/third_party/blink/renderer/core/style/style_difference.h b/third_party/blink/renderer/core/style/style_difference.h index 9129296..b3cf6266 100644 --- a/third_party/blink/renderer/core/style/style_difference.h +++ b/third_party/blink/renderer/core/style/style_difference.h
@@ -44,20 +44,6 @@ scroll_anchor_disabling_property_changed_(false), compositing_reasons_changed_(false) {} - void Merge(StyleDifference other) { - paint_invalidation_type_ = - std::max(paint_invalidation_type_, other.paint_invalidation_type_); - layout_type_ = std::max(layout_type_, other.layout_type_); - needs_collect_inlines_ |= other.needs_collect_inlines_; - needs_reshape_ |= other.needs_reshape_; - recompute_overflow_ |= other.recompute_overflow_; - visual_rect_update_ |= other.visual_rect_update_; - property_specific_differences_ |= other.property_specific_differences_; - scroll_anchor_disabling_property_changed_ |= - other.scroll_anchor_disabling_property_changed_; - compositing_reasons_changed_ |= other.compositing_reasons_changed_; - } - bool HasDifference() const { return paint_invalidation_type_ || layout_type_ || needs_collect_inlines_ || needs_reshape_ || property_specific_differences_ ||
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 559f63fa..ea22338 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
@@ -761,9 +761,9 @@ SMILTime SVGSMILElement::RepeatingDuration() const { // Computing the active duration // http://www.w3.org/TR/SMIL2/smil-timing.html#Timing-ComputingActiveDur - SMILTime repeat_count = this->RepeatCount(); - SMILTime repeat_dur = this->RepeatDur(); - SMILTime simple_duration = this->SimpleDuration(); + SMILTime repeat_count = RepeatCount(); + SMILTime repeat_dur = RepeatDur(); + SMILTime simple_duration = SimpleDuration(); if (!simple_duration || (repeat_dur.IsUnresolved() && repeat_count.IsUnresolved())) return simple_duration;
diff --git a/third_party/blink/renderer/core/svg/svg_length.cc b/third_party/blink/renderer/core/svg/svg_length.cc index 1329dda..6ff0ded 100644 --- a/third_party/blink/renderer/core/svg/svg_length.cc +++ b/third_party/blink/renderer/core/svg/svg_length.cc
@@ -21,6 +21,7 @@ #include "third_party/blink/renderer/core/svg/svg_length.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/css_value.h" #include "third_party/blink/renderer/core/css/parser/css_parser.h" @@ -63,17 +64,17 @@ size_t initial_value_index = static_cast<size_t>(initial_value); DCHECK_LT(initial_value_index, base::size(g_initial_lengths_table)); const auto& entry = g_initial_lengths_table[initial_value_index]; - return *CSSPrimitiveValue::Create( + return *CSSNumericLiteralValue::Create( entry.value, static_cast<CSSPrimitiveValue::UnitType>(entry.unit)); } } // namespace SVGLength::SVGLength(SVGLengthMode mode) - : SVGLength( - *CSSPrimitiveValue::Create(0, - CSSPrimitiveValue::UnitType::kUserUnits), - mode) {} + : SVGLength(*CSSNumericLiteralValue::Create( + 0, + CSSPrimitiveValue::UnitType::kUserUnits), + mode) {} SVGLength::SVGLength(Initial initial, SVGLengthMode mode) : SVGLength(CreateInitialCSSValue(initial), mode) {} @@ -99,9 +100,10 @@ auto* length = MakeGarbageCollected<SVGLength>(); length->unit_mode_ = unit_mode_; - if (length->SetValueAsString(value) != SVGParseStatus::kNoError) - length->value_ = - CSSPrimitiveValue::Create(0, CSSPrimitiveValue::UnitType::kUserUnits); + if (length->SetValueAsString(value) != SVGParseStatus::kNoError) { + length->value_ = CSSNumericLiteralValue::Create( + 0, CSSPrimitiveValue::UnitType::kUserUnits); + } return length; } @@ -119,12 +121,12 @@ } void SVGLength::SetValueAsNumber(float value) { - value_ = - CSSPrimitiveValue::Create(value, CSSPrimitiveValue::UnitType::kUserUnits); + value_ = CSSNumericLiteralValue::Create( + value, CSSPrimitiveValue::UnitType::kUserUnits); } void SVGLength::SetValue(float value, const SVGLengthContext& context) { - value_ = CSSPrimitiveValue::Create( + value_ = CSSNumericLiteralValue::Create( context.ConvertValueFromUserUnits(value, UnitMode(), value_->TypeWithCalcResolved()), value_->TypeWithCalcResolved()); @@ -146,7 +148,7 @@ void SVGLength::SetUnitType(CSSPrimitiveValue::UnitType type) { DCHECK(IsSupportedCSSUnitType(type)); - value_ = CSSPrimitiveValue::Create(value_->GetFloatValue(), type); + value_ = CSSNumericLiteralValue::Create(value_->GetFloatValue(), type); } float SVGLength::ValueAsPercentage() const { @@ -199,8 +201,8 @@ // string (which we'll get for example for removeAttribute.) // Hopefully work on crbug.com/225807 can help here. if (string.IsNull()) { - value_ = - CSSPrimitiveValue::Create(0, CSSPrimitiveValue::UnitType::kUserUnits); + value_ = CSSNumericLiteralValue::Create( + 0, CSSPrimitiveValue::UnitType::kUserUnits); return SVGParseStatus::kNoError; } @@ -223,7 +225,7 @@ void SVGLength::NewValueSpecifiedUnits(CSSPrimitiveValue::UnitType type, float value) { - value_ = CSSPrimitiveValue::Create(value, type); + value_ = CSSNumericLiteralValue::Create(value, type); } void SVGLength::ConvertToSpecifiedUnits(CSSPrimitiveValue::UnitType type, @@ -231,7 +233,7 @@ DCHECK(IsSupportedCSSUnitType(type)); float value_in_user_units = Value(context); - value_ = CSSPrimitiveValue::Create( + value_ = CSSNumericLiteralValue::Create( context.ConvertValueFromUserUnits(value_in_user_units, UnitMode(), type), type); } @@ -329,7 +331,7 @@ } animated_number = length_context.ConvertValueFromUserUnits( animated_number, UnitMode(), new_unit); - value_ = CSSPrimitiveValue::Create(animated_number, new_unit); + value_ = CSSNumericLiteralValue::Create(animated_number, new_unit); } float SVGLength::CalculateDistance(SVGPropertyBase* to_value,
diff --git a/third_party/blink/renderer/core/svg/svg_length.h b/third_party/blink/renderer/core/svg/svg_length.h index 5e598038..f63aa8c 100644 --- a/third_party/blink/renderer/core/svg/svg_length.h +++ b/third_party/blink/renderer/core/svg/svg_length.h
@@ -21,6 +21,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_LENGTH_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_LENGTH_H_ +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/svg/properties/svg_property.h" #include "third_party/blink/renderer/core/svg/svg_length_context.h" @@ -81,7 +82,8 @@ float ValueInSpecifiedUnits() const { return value_->GetFloatValue(); } void SetValueInSpecifiedUnits(float value) { - value_ = CSSPrimitiveValue::Create(value, value_->TypeWithCalcResolved()); + value_ = + CSSNumericLiteralValue::Create(value, value_->TypeWithCalcResolved()); } const CSSPrimitiveValue& AsCSSPrimitiveValue() const { return *value_; }
diff --git a/third_party/blink/renderer/core/svg/svg_transform_list.cc b/third_party/blink/renderer/core/svg/svg_transform_list.cc index c24b8c2..c85f8ec 100644 --- a/third_party/blink/renderer/core/svg/svg_transform_list.cc +++ b/third_party/blink/renderer/core/svg/svg_transform_list.cc
@@ -26,6 +26,7 @@ #include "base/stl_util.h" #include "third_party/blink/renderer/core/css/css_function_value.h" #include "third_party/blink/renderer/core/css/css_identifier_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/css_value_list.h" #include "third_party/blink/renderer/core/svg/svg_parser_utilities.h" @@ -228,46 +229,46 @@ MakeGarbageCollected<CSSFunctionValue>(function_id); switch (function_id) { case CSSValueID::kRotate: { - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.Angle(), CSSPrimitiveValue::UnitType::kDegrees)); FloatPoint rotation_origin = transform.RotationCenter(); if (!ToFloatSize(rotation_origin).IsZero()) { - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( rotation_origin.X(), CSSPrimitiveValue::UnitType::kUserUnits)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( rotation_origin.Y(), CSSPrimitiveValue::UnitType::kUserUnits)); } break; } case CSSValueID::kSkewX: case CSSValueID::kSkewY: - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.Angle(), CSSPrimitiveValue::UnitType::kDegrees)); break; case CSSValueID::kMatrix: - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.Matrix().A(), CSSPrimitiveValue::UnitType::kUserUnits)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.Matrix().B(), CSSPrimitiveValue::UnitType::kUserUnits)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.Matrix().C(), CSSPrimitiveValue::UnitType::kUserUnits)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.Matrix().D(), CSSPrimitiveValue::UnitType::kUserUnits)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.Matrix().E(), CSSPrimitiveValue::UnitType::kUserUnits)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.Matrix().F(), CSSPrimitiveValue::UnitType::kUserUnits)); break; case CSSValueID::kScale: - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.Matrix().A(), CSSPrimitiveValue::UnitType::kUserUnits)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.Matrix().D(), CSSPrimitiveValue::UnitType::kUserUnits)); break; case CSSValueID::kTranslate: - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.Matrix().E(), CSSPrimitiveValue::UnitType::kUserUnits)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.Matrix().F(), CSSPrimitiveValue::UnitType::kUserUnits)); break; default:
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc index f741152..da3a667 100644 --- a/third_party/blink/renderer/core/testing/internals.cc +++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -890,7 +890,7 @@ To<LocalDOMWindow>(page->GetChromeClient().PagePopupWindowForTesting()); if (popup) { // We need to make the popup same origin so web tests can access it. - popup->document()->UpdateSecurityOrigin( + popup->document()->SetSecurityOriginForTesting( document_->GetMutableSecurityOrigin()); } return popup;
diff --git a/third_party/blink/renderer/core/testing/null_execution_context.h b/third_party/blink/renderer/core/testing/null_execution_context.h index 9c3edf1..06a6b411 100644 --- a/third_party/blink/renderer/core/testing/null_execution_context.h +++ b/third_party/blink/renderer/core/testing/null_execution_context.h
@@ -44,7 +44,6 @@ bool TasksNeedPause() override { return tasks_need_pause_; } void SetTasksNeedPause(bool flag) { tasks_need_pause_ = flag; } - void DidUpdateSecurityOrigin() override {} SecurityContext& GetSecurityContext() final { return *this; } const SecurityContext& GetSecurityContext() const final { return *this; } DOMTimerCoordinator* Timers() override { return nullptr; }
diff --git a/third_party/blink/renderer/core/timing/event_timing.cc b/third_party/blink/renderer/core/timing/event_timing.cc index 7bb1018..eda6d81 100644 --- a/third_party/blink/renderer/core/timing/event_timing.cc +++ b/third_party/blink/renderer/core/timing/event_timing.cc
@@ -49,14 +49,8 @@ performance->GetExecutionContext())) return false; - if (performance->HasObserverFor(PerformanceEntry::kEvent)) - return true; - if (performance->ShouldBufferEntries() && - !performance->IsEventTimingBufferFull()) { - return true; - } - - return false; + return (!performance->IsEventTimingBufferFull() || + performance->HasObserverFor(PerformanceEntry::kEvent)); } EventTiming::EventTiming(base::TimeTicks processing_start,
diff --git a/third_party/blink/renderer/core/timing/largest_contentful_paint.cc b/third_party/blink/renderer/core/timing/largest_contentful_paint.cc index b7b67e7..1e25325 100644 --- a/third_party/blink/renderer/core/timing/largest_contentful_paint.cc +++ b/third_party/blink/renderer/core/timing/largest_contentful_paint.cc
@@ -10,8 +10,18 @@ namespace blink { -LargestContentfulPaint::LargestContentfulPaint(double paint_time, uint64_t size) - : PerformanceEntry(g_empty_atom, paint_time, paint_time), size_(size) {} +LargestContentfulPaint::LargestContentfulPaint(double paint_time, + uint64_t size, + double response_end, + const AtomicString& id, + const String& url, + Element* element) + : PerformanceEntry(g_empty_atom, paint_time, paint_time), + size_(size), + response_end_(response_end), + id_(id), + url_(url), + element_(element) {} LargestContentfulPaint::~LargestContentfulPaint() = default; @@ -23,12 +33,24 @@ return PerformanceEntry::EntryType::kLargestContentfulPaint; } +Element* LargestContentfulPaint::element() const { + if (!element_ || !element_->isConnected() || element_->IsInShadowTree()) + return nullptr; + + return element_; +} + void LargestContentfulPaint::BuildJSONValue(V8ObjectBuilder& builder) const { PerformanceEntry::BuildJSONValue(builder); builder.Add("size", size_); + builder.Add("responseEnd", response_end_); + builder.Add("id", id_); + builder.Add("url", url_); + builder.Add("element", element_); } void LargestContentfulPaint::Trace(blink::Visitor* visitor) { + visitor->Trace(element_); PerformanceEntry::Trace(visitor); }
diff --git a/third_party/blink/renderer/core/timing/largest_contentful_paint.h b/third_party/blink/renderer/core/timing/largest_contentful_paint.h index 31ccc79..0b9ce41 100644 --- a/third_party/blink/renderer/core/timing/largest_contentful_paint.h +++ b/third_party/blink/renderer/core/timing/largest_contentful_paint.h
@@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_LARGEST_CONTENTFUL_PAINT_H_ #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/timing/performance_entry.h" namespace blink { @@ -16,13 +17,22 @@ DEFINE_WRAPPERTYPEINFO(); public: - LargestContentfulPaint(double paint_time, uint64_t size); + LargestContentfulPaint(double paint_time, + uint64_t size, + double response_end, + const AtomicString& id, + const String& url, + Element*); ~LargestContentfulPaint() override; AtomicString entryType() const override; PerformanceEntryType EntryTypeEnum() const override; uint64_t size() const { return size_; } + DOMHighResTimeStamp responseEnd() const { return response_end_; } + const AtomicString& id() const { return id_; } + const String& url() const { return url_; } + Element* element() const; void Trace(blink::Visitor*) override; @@ -30,6 +40,10 @@ void BuildJSONValue(V8ObjectBuilder&) const override; uint64_t size_; + DOMHighResTimeStamp response_end_; + AtomicString id_; + String url_; + WeakMember<Element> element_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/timing/largest_contentful_paint.idl b/third_party/blink/renderer/core/timing/largest_contentful_paint.idl index d4b5232c2..2c7ff70 100644 --- a/third_party/blink/renderer/core/timing/largest_contentful_paint.idl +++ b/third_party/blink/renderer/core/timing/largest_contentful_paint.idl
@@ -6,6 +6,10 @@ [Exposed=Window, RuntimeEnabled=LargestContentfulPaint] interface LargestContentfulPaint : PerformanceEntry { readonly attribute unsigned long long size; + readonly attribute DOMHighResTimeStamp responseEnd; + readonly attribute DOMString id; + readonly attribute DOMString url; + readonly attribute Element? element; [CallWith=ScriptState, ImplementedAs=toJSONForBinding] object toJSON(); };
diff --git a/third_party/blink/renderer/core/timing/layout_shift.cc b/third_party/blink/renderer/core/timing/layout_shift.cc index a842adc..b11ba21 100644 --- a/third_party/blink/renderer/core/timing/layout_shift.cc +++ b/third_party/blink/renderer/core/timing/layout_shift.cc
@@ -10,8 +10,14 @@ namespace blink { -LayoutShift::LayoutShift(double start_time, double value) - : PerformanceEntry(g_empty_atom, start_time, start_time), value_(value) {} +LayoutShift::LayoutShift(double start_time, + double value, + bool input_detected, + double input_timestamp) + : PerformanceEntry(g_empty_atom, start_time, start_time), + value_(value), + had_recent_input_(input_detected), + most_recent_input_timestamp_(input_timestamp) {} LayoutShift::~LayoutShift() = default; @@ -26,6 +32,8 @@ void LayoutShift::BuildJSONValue(V8ObjectBuilder& builder) const { PerformanceEntry::BuildJSONValue(builder); builder.Add("value", value_); + builder.Add("hadRecentInput", had_recent_input_); + builder.Add("lastInputTime", most_recent_input_timestamp_); } void LayoutShift::Trace(blink::Visitor* visitor) {
diff --git a/third_party/blink/renderer/core/timing/layout_shift.h b/third_party/blink/renderer/core/timing/layout_shift.h index 9652c89..d9dc5a0 100644 --- a/third_party/blink/renderer/core/timing/layout_shift.h +++ b/third_party/blink/renderer/core/timing/layout_shift.h
@@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_LAYOUT_SHIFT_H_ #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/dom/dom_high_res_time_stamp.h" #include "third_party/blink/renderer/core/timing/performance_entry.h" namespace blink { @@ -16,13 +17,18 @@ DEFINE_WRAPPERTYPEINFO(); public: - LayoutShift(double start_time, double value); + LayoutShift(double start_time, + double value, + bool input_detected, + double input_timestamp); ~LayoutShift() override; AtomicString entryType() const override; PerformanceEntryType EntryTypeEnum() const override; double value() const { return value_; } + bool hadRecentInput() const { return had_recent_input_; } + double lastInputTime() const { return most_recent_input_timestamp_; } void Trace(blink::Visitor*) override; @@ -30,6 +36,8 @@ void BuildJSONValue(V8ObjectBuilder&) const override; double value_; + bool had_recent_input_; + DOMHighResTimeStamp most_recent_input_timestamp_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/timing/layout_shift.idl b/third_party/blink/renderer/core/timing/layout_shift.idl index 76b6c76..639c82d 100644 --- a/third_party/blink/renderer/core/timing/layout_shift.idl +++ b/third_party/blink/renderer/core/timing/layout_shift.idl
@@ -6,6 +6,8 @@ [Exposed=Window, RuntimeEnabled=LayoutInstabilityAPI] interface LayoutShift : PerformanceEntry { readonly attribute double value; + readonly attribute boolean hadRecentInput; + readonly attribute DOMHighResTimeStamp lastInputTime; // TODO(peria): toJSON is not in spec. https://crbug.com/736332 [CallWith=ScriptState, ImplementedAs=toJSONForBinding] object toJSON();
diff --git a/third_party/blink/renderer/core/timing/performance.cc b/third_party/blink/renderer/core/timing/performance.cc index 7807f85..3d6ee0a0 100644 --- a/third_party/blink/renderer/core/timing/performance.cc +++ b/third_party/blink/renderer/core/timing/performance.cc
@@ -564,18 +564,16 @@ } void Performance::AddElementTimingBuffer(PerformanceElementTiming& entry) { - element_timing_buffer_.push_back(&entry); - - if (IsElementTimingBufferFull()) - DispatchEvent(*Event::Create(event_type_names::kElementtimingbufferfull)); + if (!IsElementTimingBufferFull()) { + element_timing_buffer_.push_back(&entry); + } } void Performance::AddEventTimingBuffer(PerformanceEventTiming& entry) { DCHECK(RuntimeEnabledFeatures::EventTimingEnabled(GetExecutionContext())); - event_timing_buffer_.push_back(&entry); - - if (IsEventTimingBufferFull()) - DispatchEvent(*Event::Create(event_type_names::kEventtimingbufferfull)); + if (!IsEventTimingBufferFull()) { + event_timing_buffer_.push_back(&entry); + } } void Performance::AddLayoutJankBuffer(LayoutShift& entry) { @@ -590,37 +588,6 @@ } } -unsigned Performance::ElementTimingBufferSize() const { - return element_timing_buffer_.size(); -} - -unsigned Performance::EventTimingBufferSize() const { - return event_timing_buffer_.size(); -} - -void Performance::clearElementTimings() { - element_timing_buffer_.clear(); -} - -void Performance::clearEventTimings() { - event_timing_buffer_.clear(); -} - -// TODO(crbug.com/72556): remove Element Timing buffering when shipping the -// 'buffered' flag. -void Performance::setElementTimingBufferMaxSize(unsigned size) { - element_timing_buffer_max_size_ = size; - if (IsElementTimingBufferFull()) - DispatchEvent(*Event::Create(event_type_names::kElementtimingbufferfull)); -} - -// TODO(yoav): EventTiming should follow a simpler buffering model. -void Performance::setEventTimingBufferMaxSize(unsigned size) { - event_timing_buffer_max_size_ = size; - if (IsEventTimingBufferFull()) - DispatchEvent(*Event::Create(event_type_names::kEventtimingbufferfull)); -} - void Performance::AddFirstPaintTiming(base::TimeTicks start_time) { AddPaintTiming(PerformancePaintTiming::PaintType::kFirstPaint, start_time); }
diff --git a/third_party/blink/renderer/core/timing/performance.h b/third_party/blink/renderer/core/timing/performance.h index c0d6a4e7..f2544bf 100644 --- a/third_party/blink/renderer/core/timing/performance.h +++ b/third_party/blink/renderer/core/timing/performance.h
@@ -175,18 +175,9 @@ bool IsElementTimingBufferFull() const; void AddElementTimingBuffer(PerformanceElementTiming&); - unsigned ElementTimingBufferSize() const; - void clearElementTimings(); - void setElementTimingBufferMaxSize(unsigned); - DEFINE_ATTRIBUTE_EVENT_LISTENER(elementtimingbufferfull, - kElementtimingbufferfull) bool IsEventTimingBufferFull() const; void AddEventTimingBuffer(PerformanceEventTiming&); - unsigned EventTimingBufferSize() const; - void clearEventTimings(); - void setEventTimingBufferMaxSize(unsigned); - DEFINE_ATTRIBUTE_EVENT_LISTENER(eventtimingbufferfull, kEventtimingbufferfull) void AddLayoutJankBuffer(LayoutShift&);
diff --git a/third_party/blink/renderer/core/timing/performance.idl b/third_party/blink/renderer/core/timing/performance.idl index 4e31532..b95d0b1 100644 --- a/third_party/blink/renderer/core/timing/performance.idl +++ b/third_party/blink/renderer/core/timing/performance.idl
@@ -51,19 +51,6 @@ void setResourceTimingBufferSize(unsigned long maxSize); attribute EventHandler onresourcetimingbufferfull; - // Element Timing - // https://github.com/npm1/Element-Timing - [MeasureAs=ElementTimingExplicitlyRequested, RuntimeEnabled=ElementTiming] void clearElementTimings(); - [MeasureAs=ElementTimingExplicitlyRequested, RuntimeEnabled=ElementTiming] void setElementTimingBufferMaxSize(unsigned long maxSize); - [MeasureAs=ElementTimingExplicitlyRequested, RuntimeEnabled=ElementTiming] attribute EventHandler onelementtimingbufferfull; - - - // Event Timing - // https://github.com/wicg/event-timing - [MeasureAs=PerformanceEventTimingBuffer, RuntimeEnabled=EventTiming] void clearEventTimings(); - [MeasureAs=PerformanceEventTimingBuffer, RuntimeEnabled=EventTiming] void setEventTimingBufferMaxSize(unsigned long maxSize); - [MeasureAs=PerformanceEventTimingBuffer, RuntimeEnabled=EventTiming] attribute EventHandler oneventtimingbufferfull; - // Navigation Timing // https://w3c.github.io/navigation-timing/#extensions-to-the-performance-interface [Exposed=Window, SameObject, Measure] readonly attribute PerformanceTiming timing;
diff --git a/third_party/blink/renderer/core/timing/performance_observer_test.cc b/third_party/blink/renderer/core/timing/performance_observer_test.cc index 3ce2de72..62094a6a 100644 --- a/third_party/blink/renderer/core/timing/performance_observer_test.cc +++ b/third_party/blink/renderer/core/timing/performance_observer_test.cc
@@ -74,7 +74,7 @@ EXPECT_EQ(0, NumPerformanceEntries()); // add a layoutjank to performance so getEntries() returns it - auto* entry = MakeGarbageCollected<LayoutShift>(0.0, 1234); + auto* entry = MakeGarbageCollected<LayoutShift>(0.0, 1234, true, 5678); base_->AddLayoutJankBuffer(*entry); // call observe with the buffered flag
diff --git a/third_party/blink/renderer/core/timing/window_performance.cc b/third_party/blink/renderer/core/timing/window_performance.cc index 8b8ffa36..b8fe4cfc 100644 --- a/third_party/blink/renderer/core/timing/window_performance.cc +++ b/third_party/blink/renderer/core/timing/window_performance.cc
@@ -322,12 +322,6 @@ } } -// We buffer Element Timing and Event Timing (long-latency events) entries until -// onload, i.e., LoadEventStart is not reached yet. -bool WindowPerformance::ShouldBufferEntries() { - return !timing() || !timing()->loadEventStart(); -} - void WindowPerformance::RegisterEventTiming(const AtomicString& event_type, base::TimeTicks start_time, base::TimeTicks processing_start, @@ -387,7 +381,7 @@ NotifyObserversOfEntry(*entry); } - if (ShouldBufferEntries() && !IsEventTimingBufferFull()) + if (!IsEventTimingBufferFull()) AddEventTimingBuffer(*entry); } event_timings_.clear(); @@ -412,7 +406,7 @@ WebFeature::kElementTimingExplicitlyRequested); NotifyObserversOfEntry(*entry); } - if (ShouldBufferEntries() && !IsElementTimingBufferFull()) + if (!IsElementTimingBufferFull()) AddElementTimingBuffer(*entry); } @@ -431,21 +425,30 @@ first_input_timing_ = entry; } -void WindowPerformance::AddLayoutJankFraction(double jank_fraction) { +void WindowPerformance::AddLayoutJankFraction(double jank_fraction, + bool input_detected, + base::TimeTicks input_timestamp) { DCHECK(RuntimeEnabledFeatures::LayoutInstabilityAPIEnabled( GetExecutionContext())); - auto* entry = MakeGarbageCollected<LayoutShift>(now(), jank_fraction); + auto* entry = MakeGarbageCollected<LayoutShift>( + now(), jank_fraction, input_detected, + input_detected ? MonotonicTimeToDOMHighResTimeStamp(input_timestamp) + : 0.0); if (HasObserverFor(PerformanceEntry::kLayoutJank)) NotifyObserversOfEntry(*entry); - if (ShouldBufferEntries()) - AddLayoutJankBuffer(*entry); + AddLayoutJankBuffer(*entry); } void WindowPerformance::OnLargestContentfulPaintUpdated( base::TimeTicks paint_time, - uint64_t paint_size) { + uint64_t paint_size, + base::TimeTicks response_end, + const AtomicString& id, + const String& url, + Element* element) { auto* entry = MakeGarbageCollected<LargestContentfulPaint>( - MonotonicTimeToDOMHighResTimeStamp(paint_time), paint_size); + MonotonicTimeToDOMHighResTimeStamp(paint_time), paint_size, + MonotonicTimeToDOMHighResTimeStamp(response_end), id, url, element); if (HasObserverFor(PerformanceEntry::kLargestContentfulPaint)) NotifyObserversOfEntry(*entry); AddLargestContentfulPaint(entry);
diff --git a/third_party/blink/renderer/core/timing/window_performance.h b/third_party/blink/renderer/core/timing/window_performance.h index 56898d4..383c55c 100644 --- a/third_party/blink/renderer/core/timing/window_performance.h +++ b/third_party/blink/renderer/core/timing/window_performance.h
@@ -63,8 +63,6 @@ void UpdateLongTaskInstrumentation() override; - bool ShouldBufferEntries(); - bool FirstInputDetected() const { return !!first_input_timing_; } // This method creates a PerformanceEventTiming and if needed creates a swap @@ -86,10 +84,16 @@ const AtomicString& id, Element*); - void AddLayoutJankFraction(double jank_fraction); + void AddLayoutJankFraction(double jank_fraction, + bool input_detected, + base::TimeTicks input_timestamp); - void OnLargestContentfulPaintUpdated(base::TimeTicks text_paint_time, - uint64_t text_paint_size); + void OnLargestContentfulPaintUpdated(base::TimeTicks paint_time, + uint64_t paint_size, + base::TimeTicks response_end, + const AtomicString& id, + const String& url, + Element*); void Trace(blink::Visitor*) override;
diff --git a/third_party/blink/renderer/core/timing/window_performance_test.cc b/third_party/blink/renderer/core/timing/window_performance_test.cc index ba7e86d..5f6cb7be 100644 --- a/third_party/blink/renderer/core/timing/window_performance_test.cc +++ b/third_party/blink/renderer/core/timing/window_performance_test.cc
@@ -225,7 +225,7 @@ } } -TEST_F(WindowPerformanceTest, EventTimingBeforeOnLoad) { +TEST_F(WindowPerformanceTest, EventTimingEntryBuffering) { ScopedEventTimingForTest event_timing(true); EXPECT_TRUE(page_holder_->GetFrame().Loader().GetDocumentLoader()); @@ -241,7 +241,6 @@ GetTimeOrigin() + base::TimeDelta::FromSecondsD(6.0); SimulateSwapPromise(swap_time); EXPECT_EQ(1u, performance_->getEntriesByName("click", "event").size()); - performance_->clearEventTimings(); page_holder_->GetFrame() .Loader() @@ -251,8 +250,7 @@ performance_->RegisterEventTiming("click", start_time, processing_start, processing_end, true); SimulateSwapPromise(swap_time); - EXPECT_EQ(0u, performance_->getEntriesByName("click", "event").size()); - performance_->clearEventTimings(); + EXPECT_EQ(2u, performance_->getEntriesByName("click", "event").size()); EXPECT_TRUE(page_holder_->GetFrame().Loader().GetDocumentLoader()); GetFrame()->PrepareForCommit(); @@ -260,8 +258,7 @@ performance_->RegisterEventTiming("click", start_time, processing_start, processing_end, false); SimulateSwapPromise(swap_time); - EXPECT_EQ(1u, performance_->getEntriesByName("click", "event").size()); - performance_->clearEventTimings(); + EXPECT_EQ(3u, performance_->getEntriesByName("click", "event").size()); } TEST_F(WindowPerformanceTest, Expose100MsEvents) {
diff --git a/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc b/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc index 695d0dd2..499b062 100644 --- a/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc +++ b/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc
@@ -110,17 +110,17 @@ return !allow; } -bool RequireTrustedTypes(const ExecutionContext* execution_context) { - return execution_context && - execution_context->GetSecurityContext().RequireTrustedTypes(); -} - TrustedTypePolicy* GetDefaultPolicy(const ExecutionContext* execution_context) { return execution_context->GetTrustedTypes()->getExposedPolicy("default"); } } // namespace +bool RequireTrustedTypesCheck(const ExecutionContext* execution_context) { + return execution_context && + execution_context->GetSecurityContext().RequireTrustedTypes(); +} + String GetStringFromTrustedType( const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL& string_or_trusted_type, @@ -129,7 +129,7 @@ DCHECK(!string_or_trusted_type.IsNull()); if (string_or_trusted_type.IsString() && - RequireTrustedTypes(execution_context)) { + RequireTrustedTypesCheck(execution_context)) { TrustedTypeFail(kAnyTrustedTypeAssignment, execution_context, exception_state); return g_empty_string; @@ -236,7 +236,7 @@ String GetStringFromTrustedHTML(const String& string, const ExecutionContext* execution_context, ExceptionState& exception_state) { - bool require_trusted_type = RequireTrustedTypes(execution_context); + bool require_trusted_type = RequireTrustedTypesCheck(execution_context); if (!require_trusted_type) { return string; } @@ -272,7 +272,7 @@ // string_or_trusted_script.IsNull(), unlike the various similar methods in // this file. - bool require_trusted_type = RequireTrustedTypes(execution_context); + bool require_trusted_type = RequireTrustedTypesCheck(execution_context); if (!require_trusted_type) { if (string_or_trusted_script.IsString()) { return string_or_trusted_script.GetAsString(); @@ -325,7 +325,7 @@ DCHECK(!string_or_trusted_script_url.IsNull()); bool require_trusted_type = - RequireTrustedTypes(execution_context) && + RequireTrustedTypesCheck(execution_context) && RuntimeEnabledFeatures::TrustedDOMTypesEnabled(execution_context); if (!require_trusted_type && string_or_trusted_script_url.IsString()) { return string_or_trusted_script_url.GetAsString(); @@ -363,7 +363,7 @@ ExceptionState& exception_state) { DCHECK(!string_or_trusted_url.IsNull()); - bool require_trusted_type = RequireTrustedTypes(execution_context); + bool require_trusted_type = RequireTrustedTypesCheck(execution_context); if (!require_trusted_type && string_or_trusted_url.IsUSVString()) { return string_or_trusted_url.GetAsUSVString(); } @@ -397,7 +397,7 @@ Node* TrustedTypesCheckForHTMLScriptElement(Node* child, Document* doc, ExceptionState& exception_state) { - bool require_trusted_type = RequireTrustedTypes(doc); + bool require_trusted_type = RequireTrustedTypesCheck(doc); if (!require_trusted_type) return child;
diff --git a/third_party/blink/renderer/core/trustedtypes/trusted_types_util.h b/third_party/blink/renderer/core/trustedtypes/trusted_types_util.h index 31c9f6ce..d28a8ec 100644 --- a/third_party/blink/renderer/core/trustedtypes/trusted_types_util.h +++ b/third_party/blink/renderer/core/trustedtypes/trusted_types_util.h
@@ -72,6 +72,15 @@ Document*, ExceptionState&); +// Determine whether a Trusted Types check is needed in this execution context. +// +// Note: All methods above handle this internally and will return success if a +// check is not required. However, in cases where not-required doesn't +// immediately imply "okay" this method can be used. +// Example: To determine whether 'eval' may pass, one needs to also take CSP +// into account. +bool CORE_EXPORT RequireTrustedTypesCheck(const ExecutionContext*); + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_TRUSTEDTYPES_TRUSTED_TYPES_UTIL_H_
diff --git a/third_party/blink/renderer/core/workers/worker_global_scope.cc b/third_party/blink/renderer/core/workers/worker_global_scope.cc index bb7d06a..86d6f330 100644 --- a/third_party/blink/renderer/core/workers/worker_global_scope.cc +++ b/third_party/blink/renderer/core/workers/worker_global_scope.cc
@@ -84,6 +84,17 @@ GetMemoryCache()->RemoveURLFromCache(url); } +scoped_refptr<SecurityOrigin> CreateSecurityOrigin( + GlobalScopeCreationParams* creation_params) { + scoped_refptr<SecurityOrigin> security_origin = + SecurityOrigin::Create(creation_params->script_url); + if (creation_params->starter_origin) { + security_origin->TransferPrivilegesFrom( + creation_params->starter_origin->CreatePrivilegeData()); + } + return security_origin; +} + } // namespace FontFaceSet* WorkerGlobalScope::fonts() { @@ -454,6 +465,7 @@ base::TimeTicks time_origin) : WorkerOrWorkletGlobalScope( thread->GetIsolate(), + CreateSecurityOrigin(creation_params.get()), Agent::CreateForWorkerOrWorklet(thread->GetIsolate()), creation_params->off_main_thread_fetch_option, creation_params->global_scope_name, @@ -478,13 +490,6 @@ script_eval_state_(ScriptEvalState::kPauseAfterFetch) { InstanceCounters::IncrementCounter( InstanceCounters::kWorkerGlobalScopeCounter); - scoped_refptr<SecurityOrigin> security_origin = - SecurityOrigin::Create(creation_params->script_url); - if (creation_params->starter_origin) { - security_origin->TransferPrivilegesFrom( - creation_params->starter_origin->CreatePrivilegeData()); - } - SetSecurityOrigin(std::move(security_origin)); // https://html.spec.whatwg.org/C/#run-a-worker // 4. Set worker global scope's HTTPS state to response's HTTPS state. [spec
diff --git a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc index 2c0c166..cdd93b5 100644 --- a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc +++ b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
@@ -168,6 +168,7 @@ WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope( v8::Isolate* isolate, + scoped_refptr<SecurityOrigin> origin, Agent* agent, OffMainThreadWorkerScriptFetchOption off_main_thread_fetch_option, const String& name, @@ -179,6 +180,7 @@ : ExecutionContext(isolate, agent, MakeGarbageCollected<OriginTrialContext>()), + SecurityContext(std::move(origin), WebSandboxFlags::kNone, nullptr), off_main_thread_fetch_option_(off_main_thread_fetch_option), name_(name), parent_devtools_token_(parent_devtools_token), @@ -397,6 +399,14 @@ return GetThread()->GetTaskRunner(type); } +void WorkerOrWorkletGlobalScope::ApplySandboxFlags(SandboxFlags mask) { + sandbox_flags_ |= mask; + if (IsSandboxed(WebSandboxFlags::kOrigin) && + !GetSecurityOrigin()->IsOpaque()) { + SetSecurityOrigin(GetSecurityOrigin()->DeriveNewOpaqueOrigin()); + } +} + void WorkerOrWorkletGlobalScope::SetOutsideContentSecurityPolicyHeaders( const Vector<CSPHeaderAndType>& headers) { outside_content_security_policy_headers_ = headers;
diff --git a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h index 2184df6..c1dbaf8e 100644 --- a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h +++ b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h
@@ -46,6 +46,7 @@ WorkerOrWorkletGlobalScope( v8::Isolate*, + scoped_refptr<SecurityOrigin> origin, Agent* agent, OffMainThreadWorkerScriptFetchOption, const String& name, @@ -74,9 +75,6 @@ void DisableEval(const String& error_message) final; bool CanExecuteScripts(ReasonForCallingCanExecuteScripts) final; - // SecurityContext - void DidUpdateSecurityOrigin() final {} - // Returns true when the WorkerOrWorkletGlobalScope is closing (e.g. via // WorkerGlobalScope#close() method). If this returns true, the worker is // going to be shutdown after the current task execution. Globals that @@ -143,6 +141,8 @@ return off_main_thread_fetch_option_; } + void ApplySandboxFlags(SandboxFlags mask); + protected: // Sets outside's CSP used for off-main-thread top-level worker script // fetch.
diff --git a/third_party/blink/renderer/core/workers/worklet_global_scope.cc b/third_party/blink/renderer/core/workers/worklet_global_scope.cc index 0418a301..85633e9 100644 --- a/third_party/blink/renderer/core/workers/worklet_global_scope.cc +++ b/third_party/blink/renderer/core/workers/worklet_global_scope.cc
@@ -31,13 +31,15 @@ WorkletGlobalScope::WorkletGlobalScope( std::unique_ptr<GlobalScopeCreationParams> creation_params, WorkerReportingProxy& reporting_proxy, - LocalFrame* frame) + LocalFrame* frame, + Agent* agent) : WorkletGlobalScope(std::move(creation_params), reporting_proxy, ToIsolate(frame), ThreadType::kMainThread, frame, - nullptr /* worker_thread */) {} + nullptr /* worker_thread */, + agent) {} WorkletGlobalScope::WorkletGlobalScope( std::unique_ptr<GlobalScopeCreationParams> creation_params, @@ -48,7 +50,8 @@ worker_thread->GetIsolate(), ThreadType::kOffMainThread, nullptr /* frame */, - worker_thread) {} + worker_thread, + nullptr /* agent */) {} // Partial implementation of the "set up a worklet environment settings object" // algorithm: @@ -59,12 +62,14 @@ v8::Isolate* isolate, ThreadType thread_type, LocalFrame* frame, - WorkerThread* worker_thread) + WorkerThread* worker_thread, + Agent* agent) : WorkerOrWorkletGlobalScope( isolate, + SecurityOrigin::CreateUniqueOpaque(), // TODO(tzik): Assign an Agent for Worklets after // NonMainThreadScheduler gets ready to run microtasks. - nullptr, + agent, creation_params->off_main_thread_fetch_option, creation_params->global_scope_name, creation_params->parent_devtools_token, @@ -91,9 +96,6 @@ // Step 2: "Let inheritedAPIBaseURL be outsideSettings's API base URL." // |url_| is the inheritedAPIBaseURL passed from the parent Document. - // Step 3: "Let origin be a unique opaque origin." - SetSecurityOrigin(SecurityOrigin::CreateUniqueOpaque()); - // Step 5: "Let inheritedReferrerPolicy be outsideSettings's referrer policy." SetReferrerPolicy(creation_params->referrer_policy);
diff --git a/third_party/blink/renderer/core/workers/worklet_global_scope.h b/third_party/blink/renderer/core/workers/worklet_global_scope.h index 3d267c4..bfde821 100644 --- a/third_party/blink/renderer/core/workers/worklet_global_scope.h +++ b/third_party/blink/renderer/core/workers/worklet_global_scope.h
@@ -129,7 +129,8 @@ // thread. WorkletGlobalScope(std::unique_ptr<GlobalScopeCreationParams>, WorkerReportingProxy&, - LocalFrame*); + LocalFrame*, + Agent* = nullptr); // Constructs an instance as a threaded worklet. Must be called on a worker // thread. WorkletGlobalScope(std::unique_ptr<GlobalScopeCreationParams>, @@ -153,7 +154,8 @@ v8::Isolate*, ThreadType, LocalFrame*, - WorkerThread*); + WorkerThread*, + Agent*); EventTarget* ErrorEventTarget() final { return nullptr; }
diff --git a/third_party/blink/renderer/core/xml/dom_parser.cc b/third_party/blink/renderer/core/xml/dom_parser.cc index c7973483..996234e 100644 --- a/third_party/blink/renderer/core/xml/dom_parser.cc +++ b/third_party/blink/renderer/core/xml/dom_parser.cc
@@ -43,13 +43,15 @@ Document* DOMParser::parseFromStringInternal(const String& str, const String& type) { Document* doc = DOMImplementation::createDocument( - type, DocumentInit::Create().WithContextDocument(context_document_), + type, + DocumentInit::Create() + .WithContextDocument(context_document_) + .WithOwnerDocument(context_document_), false); doc->SetContent(str); doc->SetMimeType(AtomicString(type)); if (context_document_) { doc->SetURL(context_document_->Url()); - doc->SetSecurityOrigin(context_document_->GetMutableSecurityOrigin()); } return doc; }
diff --git a/third_party/blink/renderer/core/xml/xslt_processor.cc b/third_party/blink/renderer/core/xml/xslt_processor.cc index 699f8228a..1a2ebe4 100644 --- a/third_party/blink/renderer/core/xml/xslt_processor.cc +++ b/third_party/blink/renderer/core/xml/xslt_processor.cc
@@ -87,6 +87,9 @@ if (frame) { Document* old_document = frame->GetDocument(); + init = init.WithOwnerDocument(old_document) + .WithSandboxFlags(old_document->GetSandboxFlags()); + // Before parsing, we need to save & detach the old document and get the new // document in place. Document::Shutdown() tears down the LocalFrameView, so // remember whether or not there was one. @@ -109,9 +112,7 @@ if (old_document) { DocumentXSLT::From(*result).SetTransformSourceDocument(old_document); - result->UpdateSecurityOrigin(old_document->GetMutableSecurityOrigin()); result->SetCookieURL(old_document->CookieURL()); - result->EnforceSandboxFlags(old_document->GetSandboxFlags()); auto* csp = MakeGarbageCollected<ContentSecurityPolicy>(); csp->CopyStateFrom(old_document->GetContentSecurityPolicy());
diff --git a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc index e9f8f3b..3cf125a 100644 --- a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc +++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
@@ -358,6 +358,7 @@ DocumentInit init = DocumentInit::Create() .WithContextDocument(GetDocument()->ContextDocument()) + .WithOwnerDocument(GetDocument()->ContextDocument()) .WithURL(response_.ResponseUrl()); if (is_html) response_document_ = MakeGarbageCollected<HTMLDocument>(init); @@ -365,7 +366,6 @@ response_document_ = MakeGarbageCollected<XMLDocument>(init); // FIXME: Set Last-Modified. - response_document_->SetSecurityOrigin(GetMutableSecurityOrigin()); response_document_->SetContextFeatures(GetDocument()->GetContextFeatures()); response_document_->SetMimeType(FinalResponseMIMETypeWithFallback()); }
diff --git a/third_party/blink/renderer/devtools/front_end/console/ConsolePrompt.js b/third_party/blink/renderer/devtools/front_end/console/ConsolePrompt.js index 7b99c74..80299e5f 100644 --- a/third_party/blink/renderer/devtools/front_end/console/ConsolePrompt.js +++ b/third_party/blink/renderer/devtools/front_end/console/ConsolePrompt.js
@@ -46,8 +46,13 @@ * @this {Console.ConsolePrompt} */ function gotFactory(factory) { - this._editor = - factory.createEditor({lineNumbers: false, lineWrapping: true, mimeType: 'javascript', autoHeight: true}); + this._editor = factory.createEditor({ + devtoolsAccessibleName: ls`Console prompt`, + lineNumbers: false, + lineWrapping: true, + mimeType: 'javascript', + autoHeight: true + }); this._defaultAutocompleteConfig = ObjectUI.JavaScriptAutocompleteConfig.createConfigForEditor(this._editor); this._editor.configureAutocomplete(Object.assign({}, this._defaultAutocompleteConfig, {
diff --git a/third_party/blink/renderer/devtools/front_end/console/console_strings.grdp b/third_party/blink/renderer/devtools/front_end/console/console_strings.grdp index e14b1fb..b51975fa 100644 --- a/third_party/blink/renderer/devtools/front_end/console/console_strings.grdp +++ b/third_party/blink/renderer/devtools/front_end/console/console_strings.grdp
@@ -198,6 +198,9 @@ <message name="IDS_DEVTOOLS_c0274fa278f2e0dfef862234e0eb9b8b" desc=""> <exception> </message> + <message name="IDS_DEVTOOLS_c43a34d2abee57824fac5bb704994d88" desc=""> + Console prompt + </message> <message name="IDS_DEVTOOLS_c9818b2c0890a205d294a2b31354f8b4" desc=""> All levels </message>
diff --git a/third_party/blink/renderer/modules/BUILD.gn b/third_party/blink/renderer/modules/BUILD.gn index d31d9b9..afb8575 100644 --- a/third_party/blink/renderer/modules/BUILD.gn +++ b/third_party/blink/renderer/modules/BUILD.gn
@@ -392,6 +392,7 @@ "service_worker/web_embedded_worker_impl_test.cc", "wake_lock/wake_lock_controller_test.cc", "wake_lock/wake_lock_state_record_test.cc", + "wake_lock/wake_lock_test_utils.cc", "wake_lock/wake_lock_test_utils.h", "webaudio/audio_basic_processor_handler_test.cc", "webaudio/audio_context_autoplay_test.cc",
diff --git a/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc b/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc index ed4a32b3..e676d55 100644 --- a/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc +++ b/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc
@@ -408,6 +408,8 @@ if (credential->echo_user_verification_methods) { extension_outputs->setUvm( UvmEntryToArray(std::move(*credential->user_verification_methods))); + UseCounter::Count(resolver->GetExecutionContext(), + WebFeature::kCredentialManagerCreateSuccessWithUVM); } #endif resolver->Resolve(MakeGarbageCollected<PublicKeyCredential>( @@ -461,6 +463,8 @@ if (credential->echo_user_verification_methods) { extension_outputs->setUvm( UvmEntryToArray(std::move(*credential->user_verification_methods))); + UseCounter::Count(resolver->GetExecutionContext(), + WebFeature::kCredentialManagerGetSuccessWithUVM); } #endif resolver->Resolve(MakeGarbageCollected<PublicKeyCredential>( @@ -497,6 +501,13 @@ UseCounter::Count(resolver->GetExecutionContext(), WebFeature::kCredentialManagerGetPublicKeyCredential); } +#if defined(OS_ANDROID) + if (options->publicKey()->hasExtensions() && + options->publicKey()->extensions()->hasUvm()) { + UseCounter::Count(resolver->GetExecutionContext(), + WebFeature::kCredentialManagerGetWithUVM); + } +#endif const String& relying_party_id = options->publicKey()->rpId(); if (!CheckPublicKeySecurityRequirements(resolver, relying_party_id)) @@ -684,6 +695,13 @@ resolver->GetExecutionContext(), WebFeature::kCredentialManagerCreatePublicKeyCredential); } +#if defined(OS_ANDROID) + if (options->publicKey()->hasExtensions() && + options->publicKey()->extensions()->hasUvm()) { + UseCounter::Count(resolver->GetExecutionContext(), + WebFeature::kCredentialManagerCreateWithUVM); + } +#endif const String& relying_party_id = options->publicKey()->rp()->id(); if (!CheckPublicKeySecurityRequirements(resolver, relying_party_id))
diff --git a/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h b/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h index a436d83f..d02e835 100644 --- a/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h +++ b/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h
@@ -20,6 +20,12 @@ class CanvasImageSource; class Color; +// In our internal implementation, there are different kinds of canvas such as +// recording canvas, GPU canvas. The CSS Paint API uses the recording canvas and +// this class is specifically designed for the recording canvas. +// +// The main difference between this class and other contexts is that +// PaintRenderingContext2D operates on CSS pixels rather than physical pixels. class MODULES_EXPORT PaintRenderingContext2D : public ScriptWrappable, public BaseRenderingContext2D { DEFINE_WRAPPERTYPEINFO(); @@ -93,6 +99,10 @@ IntSize container_size_; Member<const PaintRenderingContext2DSettings> context_settings_; bool did_record_draw_commands_in_paint_recorder_; + // The paint worklet canvas operates on CSS pixels, and that's different than + // the HTML canvas which operates on physical pixels. In other words, the + // paint worklet canvas needs to handle device scale factor and browser zoom, + // and this is designed for that purpose. float effective_zoom_; DISALLOW_COPY_AND_ASSIGN(PaintRenderingContext2D);
diff --git a/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc b/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc index c3226c44..04506f3d 100644 --- a/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc +++ b/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc
@@ -219,6 +219,11 @@ } void MediaRecorder::start(int time_slice, ExceptionState& exception_state) { + if (!GetExecutionContext() || GetExecutionContext()->IsContextDestroyed()) { + exception_state.ThrowDOMException(DOMExceptionCode::kNotAllowedError, + "Execution context is detached."); + return; + } if (state_ != State::kInactive) { exception_state.ThrowDOMException( DOMExceptionCode::kInvalidStateError, @@ -238,6 +243,11 @@ } void MediaRecorder::stop(ExceptionState& exception_state) { + if (!GetExecutionContext() || GetExecutionContext()->IsContextDestroyed()) { + exception_state.ThrowDOMException(DOMExceptionCode::kNotAllowedError, + "Execution context is detached."); + return; + } if (state_ == State::kInactive) { exception_state.ThrowDOMException( DOMExceptionCode::kInvalidStateError, @@ -249,6 +259,11 @@ } void MediaRecorder::pause(ExceptionState& exception_state) { + if (!GetExecutionContext() || GetExecutionContext()->IsContextDestroyed()) { + exception_state.ThrowDOMException(DOMExceptionCode::kNotAllowedError, + "Execution context is detached."); + return; + } if (state_ == State::kInactive) { exception_state.ThrowDOMException( DOMExceptionCode::kInvalidStateError, @@ -266,6 +281,11 @@ } void MediaRecorder::resume(ExceptionState& exception_state) { + if (!GetExecutionContext() || GetExecutionContext()->IsContextDestroyed()) { + exception_state.ThrowDOMException(DOMExceptionCode::kNotAllowedError, + "Execution context is detached."); + return; + } if (state_ == State::kInactive) { exception_state.ThrowDOMException( DOMExceptionCode::kInvalidStateError, @@ -282,6 +302,11 @@ } void MediaRecorder::requestData(ExceptionState& exception_state) { + if (!GetExecutionContext() || GetExecutionContext()->IsContextDestroyed()) { + exception_state.ThrowDOMException(DOMExceptionCode::kNotAllowedError, + "Execution context is detached."); + return; + } if (state_ == State::kInactive) { exception_state.ThrowDOMException( DOMExceptionCode::kInvalidStateError,
diff --git a/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc b/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc index c8a537bd..001cd2b1 100644 --- a/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc +++ b/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc
@@ -33,7 +33,11 @@ cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI); port_allocator_->Initialize(); - ice_transport_channel_ = webrtc::CreateIceTransport(port_allocator_.get()); + webrtc::IceTransportInit ice_transport_init; + ice_transport_init.set_port_allocator(port_allocator_.get()); + ice_transport_init.set_async_resolver_factory(async_resolver_factory_.get()); + ice_transport_channel_ = + webrtc::CreateIceTransport(std::move(ice_transport_init)); SetupIceTransportChannel(); // We need to set the ICE role even before Start is called since the Port // assumes that the role has been set before receiving incoming connectivity
diff --git a/third_party/blink/renderer/modules/sms/BUILD.gn b/third_party/blink/renderer/modules/sms/BUILD.gn index f9ef335..6e270728 100644 --- a/third_party/blink/renderer/modules/sms/BUILD.gn +++ b/third_party/blink/renderer/modules/sms/BUILD.gn
@@ -10,6 +10,8 @@ "navigator_sms.h", "sms.cc", "sms.h", + "sms_metrics.cc", + "sms_metrics.h", "sms_receiver.cc", "sms_receiver.h", ]
diff --git a/third_party/blink/renderer/modules/sms/sms_metrics.cc b/third_party/blink/renderer/modules/sms/sms_metrics.cc new file mode 100644 index 0000000..a1e21106 --- /dev/null +++ b/third_party/blink/renderer/modules/sms/sms_metrics.cc
@@ -0,0 +1,19 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/sms/sms_metrics.h" + +#include "base/metrics/histogram_macros.h" + +namespace blink { + +void RecordSMSOutcome(SMSReceiverOutcome outcome) { + UMA_HISTOGRAM_ENUMERATION("Blink.Sms.Receive.Outcome", outcome); +} + +void RecordSMSSuccessTime(const base::TimeDelta duration) { + UMA_HISTOGRAM_MEDIUM_TIMES("Blink.Sms.Receive.TimeSuccess", duration); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/sms/sms_metrics.h b/third_party/blink/renderer/modules/sms/sms_metrics.h new file mode 100644 index 0000000..2623be8 --- /dev/null +++ b/third_party/blink/renderer/modules/sms/sms_metrics.h
@@ -0,0 +1,29 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SMS_SMS_METRICS_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_SMS_SMS_METRICS_H_ + +namespace base { +class TimeDelta; +} + +namespace blink { + +// Don't change the meaning of these values because they are being recorded in a +// metric. +enum class SMSReceiverOutcome { + kSuccess = 0, + kTimeout = 1, + kConnectionError = 2, + kMaxValue = kConnectionError +}; + +void RecordSMSOutcome(SMSReceiverOutcome outcome); + +void RecordSMSSuccessTime(const base::TimeDelta duration); + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SMS_SMS_METRICS_H_
diff --git a/third_party/blink/renderer/modules/sms/sms_receiver.cc b/third_party/blink/renderer/modules/sms/sms_receiver.cc index 05f0015..f2ae5928 100644 --- a/third_party/blink/renderer/modules/sms/sms_receiver.cc +++ b/third_party/blink/renderer/modules/sms/sms_receiver.cc
@@ -13,6 +13,7 @@ #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/modules/sms/sms.h" +#include "third_party/blink/renderer/modules/sms/sms_metrics.h" #include "third_party/blink/renderer/modules/sms/sms_receiver_options.h" #include "third_party/blink/renderer/platform/bindings/name_client.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" @@ -66,9 +67,10 @@ &SMSReceiver::OnSMSReceiverConnectionError, WrapWeakPersistent(this))); } - service_->Receive(base::TimeDelta::FromSeconds(timeout_seconds), - WTF::Bind(&SMSReceiver::OnReceive, WrapPersistent(this), - WrapPersistent(resolver))); + service_->Receive( + base::TimeDelta::FromSeconds(timeout_seconds), + WTF::Bind(&SMSReceiver::OnReceive, WrapPersistent(this), + WrapPersistent(resolver), base::TimeTicks::Now())); return resolver->Promise(); } @@ -76,6 +78,7 @@ SMSReceiver::~SMSReceiver() = default; void SMSReceiver::OnReceive(ScriptPromiseResolver* resolver, + base::TimeTicks start_time, mojom::blink::SmsStatus status, const WTF::String& sms) { requests_.erase(resolver); @@ -83,8 +86,13 @@ if (status == mojom::blink::SmsStatus::kTimeout) { resolver->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kTimeoutError, "SMSReceiver timed out.")); + RecordSMSOutcome(SMSReceiverOutcome::kTimeout); return; } + + RecordSMSSuccessTime(base::TimeTicks::Now() - start_time); + RecordSMSOutcome(SMSReceiverOutcome::kSuccess); + resolver->Resolve(MakeGarbageCollected<blink::SMS>(sms)); } @@ -93,6 +101,7 @@ for (ScriptPromiseResolver* request : requests_) { request->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kNotFoundError, "SMSReceiver not available.")); + RecordSMSOutcome(SMSReceiverOutcome::kConnectionError); } requests_.clear(); }
diff --git a/third_party/blink/renderer/modules/sms/sms_receiver.h b/third_party/blink/renderer/modules/sms/sms_receiver.h index ad9a370..1c5f382 100644 --- a/third_party/blink/renderer/modules/sms/sms_receiver.h +++ b/third_party/blink/renderer/modules/sms/sms_receiver.h
@@ -35,6 +35,7 @@ HeapHashSet<Member<ScriptPromiseResolver>> requests_; void OnReceive(ScriptPromiseResolver* resolver, + base::TimeTicks start_time, mojom::blink::SmsStatus status, const WTF::String& sms);
diff --git a/third_party/blink/renderer/modules/wake_lock/wake_lock.cc b/third_party/blink/renderer/modules/wake_lock/wake_lock.cc index 9d993b0..50ee0f4 100644 --- a/third_party/blink/renderer/modules/wake_lock/wake_lock.cc +++ b/third_party/blink/renderer/modules/wake_lock/wake_lock.cc
@@ -27,6 +27,24 @@ } // namespace // static +ScriptPromise WakeLock::requestPermission(ScriptState* script_state, + const String& type) { + // https://w3c.github.io/wake-lock/#requestpermission-static-method + // 1. Let promise be a new promise. + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); + + // 2. Return promise and run the following steps in parallel: + // 2.1. Let state be the result of running and waiting for the obtain + // permission steps with type. + // 2.2. Resolve promise with state. + auto* document = GetDocument(script_state); + WakeLockController::From(*document).RequestPermission(ToWakeLockType(type), + resolver); + return promise; +} + +// static ScriptPromise WakeLock::request(ScriptState* script_state, const String& type, WakeLockRequestOptions* options) { @@ -113,12 +131,7 @@ // 6. Run the following steps in parallel, but abort when options' signal // member is present and its aborted flag is set: - // [...] - // 6.2. Let success be the result of awaiting acquire a wake lock with promise - // and type: - // 6.2.1. If success is false then reject promise with a "NotAllowedError" - // DOMException, and abort these steps. - controller.AcquireWakeLock(wake_lock_type, resolver); + controller.RequestWakeLock(wake_lock_type, resolver, options->signal()); // 7. Return promise. return promise;
diff --git a/third_party/blink/renderer/modules/wake_lock/wake_lock.h b/third_party/blink/renderer/modules/wake_lock/wake_lock.h index de8c04c2..4042b2b 100644 --- a/third_party/blink/renderer/modules/wake_lock/wake_lock.h +++ b/third_party/blink/renderer/modules/wake_lock/wake_lock.h
@@ -23,6 +23,7 @@ DEFINE_WRAPPERTYPEINFO(); public: + static ScriptPromise requestPermission(ScriptState*, const WTF::String& type); static ScriptPromise request(ScriptState*, const WTF::String& type, WakeLockRequestOptions*);
diff --git a/third_party/blink/renderer/modules/wake_lock/wake_lock.idl b/third_party/blink/renderer/modules/wake_lock/wake_lock.idl index 8884f6ef..d465b52 100644 --- a/third_party/blink/renderer/modules/wake_lock/wake_lock.idl +++ b/third_party/blink/renderer/modules/wake_lock/wake_lock.idl
@@ -13,5 +13,6 @@ Exposed=Window, RuntimeEnabled=WakeLock ] interface WakeLock { + [CallWith=ScriptState, Exposed=Window] static Promise<PermissionState> requestPermission(WakeLockType type); [CallWith=ScriptState] static Promise<void> request(WakeLockType type, optional WakeLockRequestOptions options); };
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 2678fd03..4f887b0 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
@@ -5,10 +5,18 @@ #include "third_party/blink/renderer/modules/wake_lock/wake_lock_controller.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" +#include "third_party/blink/renderer/core/dom/abort_signal.h" +#include "third_party/blink/renderer/core/dom/dom_exception.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" +#include "third_party/blink/renderer/modules/permissions/permission_utils.h" #include "third_party/blink/renderer/modules/wake_lock/wake_lock_state_record.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" namespace blink { +using mojom::blink::PermissionService; +using mojom::blink::PermissionStatus; + WakeLockController::WakeLockController(Document& document) : Supplement<Document>(document), ContextLifecycleObserver(&document), @@ -39,12 +47,56 @@ Supplement<Document>::Trace(visitor); } -void WakeLockController::AcquireWakeLock(WakeLockType type, - ScriptPromiseResolver* resolver) { - DCHECK_LE(type, WakeLockType::kMaxValue); - WakeLockStateRecord* state_record = state_records_[static_cast<size_t>(type)]; - DCHECK(state_record); - state_record->AcquireWakeLock(resolver); +void WakeLockController::RequestWakeLock(WakeLockType type, + ScriptPromiseResolver* resolver, + AbortSignal* signal) { + // https://w3c.github.io/wake-lock/#request-static-method + // 6. [...] abort when options' signal member is present and its aborted flag + // is set: + DCHECK(resolver); + // We were called via WakeLock::request(), which should have handled the + // signal->aborted() case. + DCHECK(!signal || !signal->aborted()); + // 6.1. Let state be the result of awaiting obtain permission steps with + // type: + ObtainPermission( + type, WTF::Bind(&WakeLockController::DidReceivePermissionResponse, + WrapPersistent(this), type, WrapPersistent(resolver), + WrapPersistent(signal))); +} + +void WakeLockController::DidReceivePermissionResponse( + WakeLockType type, + ScriptPromiseResolver* resolver, + AbortSignal* signal, + PermissionStatus status) { + // https://w3c.github.io/wake-lock/#request-static-method + DCHECK(status == PermissionStatus::GRANTED || + status == PermissionStatus::DENIED); + DCHECK(resolver); + if (signal && signal->aborted()) + return; + // 6.1.1. If state is "denied", then reject promise with a "NotAllowedError" + // DOMException, and abort these steps. + if (status != PermissionStatus::GRANTED) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kNotAllowedError, + "Wake Lock permission request denied")); + return; + } + // https://github.com/w3c/wake-lock/issues/222: the page can become hidden + // between RequestWakeLock() and AcquireWakeLock(), in which case we need to + // abort early. + if (type == WakeLockType::kScreen && + !(GetPage() && GetPage()->IsPageVisible())) { + ReleaseWakeLock(type, resolver); + return; + } + // 6.2. Let success be the result of awaiting acquire a wake lock with promise + // and type: + // 6.2.1. If success is false then reject promise with a "NotAllowedError" + // DOMException, and abort these steps. + AcquireWakeLock(type, resolver); } void WakeLockController::ReleaseWakeLock(WakeLockType type, @@ -55,6 +107,23 @@ state_record->ReleaseWakeLock(resolver); } +void WakeLockController::RequestPermission(WakeLockType type, + ScriptPromiseResolver* resolver) { + // https://w3c.github.io/wake-lock/#requestpermission-static-method + // 2.1. Let state be the result of running and waiting for the obtain + // permission steps with type. + // 2.2. Resolve promise with state. + auto permission_callback = WTF::Bind( + [](ScriptPromiseResolver* resolver, PermissionStatus status) { + DCHECK(status == PermissionStatus::GRANTED || + status == PermissionStatus::DENIED); + DCHECK(resolver); + resolver->Resolve(PermissionStatusToString(status)); + }, + WrapPersistent(resolver)); + ObtainPermission(type, std::move(permission_callback)); +} + void WakeLockController::ContextDestroyed(ExecutionContext*) { // https://w3c.github.io/wake-lock/#handling-document-loss-of-full-activity // 1. Let document be the responsible document of the current settings object. @@ -88,4 +157,54 @@ state_record->ClearWakeLocks(); } +void WakeLockController::AcquireWakeLock(WakeLockType type, + ScriptPromiseResolver* resolver) { + DCHECK_LE(type, WakeLockType::kMaxValue); + WakeLockStateRecord* state_record = state_records_[static_cast<size_t>(type)]; + DCHECK(state_record); + state_record->AcquireWakeLock(resolver); +} + +void WakeLockController::ObtainPermission( + WakeLockType type, + base::OnceCallback<void(PermissionStatus)> callback) { + // https:w3c.github.io/wake-lock/#dfn-obtain-permission + // Note we actually implement a simplified version of the "obtain permission" + // algorithm that essentially just calls the "request permission to use" + // algorithm from the Permissions spec (i.e. we bypass all the steps covering + // calling the "query a permission" algorithm and handling its result). + // * Right now, we can do that because there is no way for Chromium's + // permission system to get to the "prompt" state given how + // WakeLockPermissionContext is currently implemented. + // * Even if WakeLockPermissionContext changes in the future, this Blink + // implementation is unlikely to change because + // WakeLockPermissionContext::RequestPermission() will take its + // |user_gesture| argument into account to actually implement a slightly + // altered version of "request permission to use", the behavior of which + // will match the definition of "obtain permission" in the Wake Lock spec. + DCHECK(type == WakeLockType::kScreen || type == WakeLockType::kSystem); + static_assert( + static_cast<mojom::blink::WakeLockType>(WakeLockType::kScreen) == + mojom::blink::WakeLockType::kScreen, + "WakeLockType and mojom::blink::WakeLockType must have identical values"); + static_assert( + static_cast<mojom::blink::WakeLockType>(WakeLockType::kSystem) == + mojom::blink::WakeLockType::kSystem, + "WakeLockType and mojom::blink::WakeLockType must have identical values"); + + GetPermissionService().RequestPermission( + CreateWakeLockPermissionDescriptor( + static_cast<mojom::blink::WakeLockType>(type)), + LocalFrame::HasTransientUserActivation(GetSupplementable()->GetFrame()), + std::move(callback)); +} + +PermissionService& WakeLockController::GetPermissionService() { + if (!permission_service_) { + ConnectToPermissionService(GetSupplementable(), + mojo::MakeRequest(&permission_service_)); + } + return *permission_service_; +} + } // 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 91da4e8..241b7cf 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
@@ -5,6 +5,9 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WAKE_LOCK_CONTROLLER_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WAKE_LOCK_CONTROLLER_H_ +#include "base/callback.h" +#include "base/gtest_prod_util.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" #include "third_party/blink/renderer/core/page/page_visibility_observer.h" @@ -14,6 +17,7 @@ namespace blink { +class AbortSignal; class ScriptPromiseResolver; class WakeLockStateRecord; @@ -35,10 +39,14 @@ void Trace(blink::Visitor*) override; - void AcquireWakeLock(WakeLockType type, ScriptPromiseResolver*); + void RequestWakeLock(WakeLockType type, + ScriptPromiseResolver* resolver, + AbortSignal* signal); void ReleaseWakeLock(WakeLockType type, ScriptPromiseResolver*); + void RequestPermission(WakeLockType type, ScriptPromiseResolver*); + private: // ContextLifecycleObserver implementation void ContextDestroyed(ExecutionContext*) override; @@ -46,11 +54,29 @@ // PageVisibilityObserver implementation void PageVisibilityChanged() override; + void AcquireWakeLock(WakeLockType type, ScriptPromiseResolver*); + + void DidReceivePermissionResponse(WakeLockType type, + ScriptPromiseResolver*, + AbortSignal*, + mojom::blink::PermissionStatus); + + // Permission handling + void ObtainPermission( + WakeLockType type, + base::OnceCallback<void(mojom::blink::PermissionStatus)> callback); + mojom::blink::PermissionService& GetPermissionService(); + + mojom::blink::PermissionServicePtr 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 // record per responsible document [...] internal slots. - Member<WakeLockStateRecord> - state_records_[static_cast<size_t>(WakeLockType::kMaxValue) + 1]; + Member<WakeLockStateRecord> state_records_[kWakeLockTypeCount]; + + FRIEND_TEST_ALL_PREFIXES(WakeLockControllerTest, AcquireScreenWakeLock); + FRIEND_TEST_ALL_PREFIXES(WakeLockControllerTest, AcquireSystemWakeLock); + FRIEND_TEST_ALL_PREFIXES(WakeLockControllerTest, AcquireMultipleLocks); }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/wake_lock/wake_lock_controller_test.cc b/third_party/blink/renderer/modules/wake_lock/wake_lock_controller_test.cc index e44accb..4e8c086 100644 --- a/third_party/blink/renderer/modules/wake_lock/wake_lock_controller_test.cc +++ b/third_party/blink/renderer/modules/wake_lock/wake_lock_controller_test.cc
@@ -9,6 +9,7 @@ #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/abort_signal.h" #include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" @@ -16,6 +17,107 @@ namespace blink { +TEST(WakeLockControllerTest, RequestWakeLockGranted) { + MockWakeLockService wake_lock_service; + WakeLockTestingContext context(&wake_lock_service); + auto& controller = WakeLockController::From(*context.GetDocument()); + + context.GetPermissionService().SetPermissionResponse( + WakeLockType::kScreen, mojom::blink::PermissionStatus::GRANTED); + + auto* screen_resolver = + MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); + ScriptPromise screen_promise = screen_resolver->Promise(); + + controller.RequestWakeLock(WakeLockType::kScreen, screen_resolver, nullptr); + + MockWakeLock& screen_lock = + wake_lock_service.get_wake_lock(WakeLockType::kScreen); + MockPermissionService& permission_service = context.GetPermissionService(); + + permission_service.WaitForPermissionRequest(WakeLockType::kScreen); + screen_lock.WaitForRequest(); + + EXPECT_EQ(v8::Promise::kPending, + ScriptPromiseUtils::GetPromiseState(screen_promise)); + EXPECT_TRUE(screen_lock.is_acquired()); +} + +TEST(WakeLockControllerTest, RequestWakeLockDenied) { + MockWakeLockService wake_lock_service; + WakeLockTestingContext context(&wake_lock_service); + auto& controller = WakeLockController::From(*context.GetDocument()); + + context.GetPermissionService().SetPermissionResponse( + WakeLockType::kSystem, mojom::blink::PermissionStatus::DENIED); + + auto* system_resolver = + MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); + ScriptPromise system_promise = system_resolver->Promise(); + + controller.RequestWakeLock(WakeLockType::kSystem, system_resolver, nullptr); + + MockWakeLock& system_lock = + wake_lock_service.get_wake_lock(WakeLockType::kSystem); + MockPermissionService& permission_service = context.GetPermissionService(); + + permission_service.WaitForPermissionRequest(WakeLockType::kSystem); + context.WaitForPromiseRejection(system_promise); + + EXPECT_EQ(v8::Promise::kRejected, + ScriptPromiseUtils::GetPromiseState(system_promise)); + EXPECT_FALSE(system_lock.is_acquired()); + + // System locks are not allowed by default, so the promise should have been + // rejected with a NotAllowedError DOMException. + DOMException* dom_exception = + ScriptPromiseUtils::GetPromiseResolutionAsDOMException(system_promise); + ASSERT_NE(dom_exception, nullptr); + EXPECT_EQ("NotAllowedError", dom_exception->name()); +} + +// Abort early in DidReceivePermissionResponse(). +TEST(WakeLockControllerTest, RequestWakeLockAbortEarly) { + MockWakeLockService wake_lock_service; + WakeLockTestingContext context(&wake_lock_service); + auto& controller = WakeLockController::From(*context.GetDocument()); + + context.GetPermissionService().SetPermissionResponse( + WakeLockType::kScreen, mojom::blink::PermissionStatus::GRANTED); + + MockWakeLock& screen_lock = + wake_lock_service.get_wake_lock(WakeLockType::kScreen); + auto* screen_resolver = + MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); + ScriptPromise screen_promise = screen_resolver->Promise(); + + auto* abort_signal = MakeGarbageCollected<AbortSignal>(context.GetDocument()); + abort_signal->AddAlgorithm(WTF::Bind( + &WakeLockController::ReleaseWakeLock, WrapWeakPersistent(&controller), + WakeLockType::kScreen, WrapPersistent(screen_resolver))); + + controller.RequestWakeLock( + WakeLockType::kScreen, + MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()), + abort_signal); + + MockPermissionService& permission_service = context.GetPermissionService(); + + permission_service.WaitForPermissionRequest(WakeLockType::kScreen); + abort_signal->SignalAbort(); + + context.WaitForPromiseRejection(screen_promise); + + EXPECT_EQ(v8::Promise::kRejected, + ScriptPromiseUtils::GetPromiseState(screen_promise)); + EXPECT_FALSE(screen_lock.is_acquired()); + + DOMException* dom_exception = + ScriptPromiseUtils::GetPromiseResolutionAsDOMException(screen_promise); + ASSERT_NE(dom_exception, nullptr); + EXPECT_EQ("AbortError", dom_exception->name()); +} + TEST(WakeLockControllerTest, AcquireScreenWakeLock) { MockWakeLockService wake_lock_service; WakeLockTestingContext context(&wake_lock_service); @@ -31,7 +133,7 @@ EXPECT_TRUE(screen_lock.is_acquired()); } -TEST(WakeLockController, AcquireSystemWakeLock) { +TEST(WakeLockControllerTest, AcquireSystemWakeLock) { MockWakeLockService wake_lock_service; WakeLockTestingContext context(&wake_lock_service); auto& controller = WakeLockController::From(*context.GetDocument()); @@ -84,12 +186,14 @@ MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); ScriptPromise promise = resolver->Promise(); - EXPECT_EQ(v8::Promise::kPending, GetScriptPromiseState(promise)); + EXPECT_EQ(v8::Promise::kPending, + ScriptPromiseUtils::GetPromiseState(promise)); controller.ReleaseWakeLock(WakeLockType::kScreen, resolver); context.WaitForPromiseRejection(promise); // The promise is always rejected, even if it is not in [[ActiveLocks]]. - EXPECT_EQ(v8::Promise::kRejected, GetScriptPromiseState(promise)); + EXPECT_EQ(v8::Promise::kRejected, + ScriptPromiseUtils::GetPromiseState(promise)); EXPECT_FALSE(screen_lock.is_acquired()); } @@ -98,6 +202,9 @@ WakeLockTestingContext context(&wake_lock_service); auto& controller = WakeLockController::From(*context.GetDocument()); + context.GetPermissionService().SetPermissionResponse( + WakeLockType::kScreen, mojom::blink::PermissionStatus::GRANTED); + MockWakeLock& screen_lock = wake_lock_service.get_wake_lock(WakeLockType::kScreen); @@ -105,13 +212,15 @@ MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); ScriptPromise promise = resolver->Promise(); - controller.AcquireWakeLock(WakeLockType::kScreen, resolver); + controller.RequestWakeLock(WakeLockType::kScreen, resolver, + /*signal=*/nullptr); screen_lock.WaitForRequest(); controller.ReleaseWakeLock(WakeLockType::kScreen, resolver); context.WaitForPromiseRejection(promise); screen_lock.WaitForCancelation(); - EXPECT_EQ(v8::Promise::kRejected, GetScriptPromiseState(promise)); + EXPECT_EQ(v8::Promise::kRejected, + ScriptPromiseUtils::GetPromiseState(promise)); EXPECT_FALSE(screen_lock.is_acquired()); } @@ -122,6 +231,9 @@ WakeLockTestingContext context(&wake_lock_service); auto& controller = WakeLockController::From(*context.GetDocument()); + context.GetPermissionService().SetPermissionResponse( + WakeLockType::kScreen, mojom::blink::PermissionStatus::GRANTED); + MockWakeLock& screen_lock = wake_lock_service.get_wake_lock(WakeLockType::kScreen); auto* screen_resolver = @@ -133,14 +245,16 @@ &WakeLockController::ReleaseWakeLock, WrapWeakPersistent(&controller), WakeLockType::kScreen, WrapPersistent(screen_resolver))); - controller.AcquireWakeLock(WakeLockType::kScreen, screen_resolver); + controller.RequestWakeLock(WakeLockType::kScreen, screen_resolver, + /*signal=*/nullptr); screen_lock.WaitForRequest(); abort_signal->SignalAbort(); context.WaitForPromiseRejection(screen_promise); screen_lock.WaitForCancelation(); - EXPECT_EQ(v8::Promise::kRejected, GetScriptPromiseState(screen_promise)); + EXPECT_EQ(v8::Promise::kRejected, + ScriptPromiseUtils::GetPromiseState(screen_promise)); EXPECT_FALSE(screen_lock.is_acquired()); } @@ -154,6 +268,10 @@ wake_lock_service.get_wake_lock(WakeLockType::kScreen); MockWakeLock& system_lock = wake_lock_service.get_wake_lock(WakeLockType::kSystem); + context.GetPermissionService().SetPermissionResponse( + WakeLockType::kScreen, mojom::blink::PermissionStatus::GRANTED); + context.GetPermissionService().SetPermissionResponse( + WakeLockType::kSystem, mojom::blink::PermissionStatus::GRANTED); // First, acquire a handful of locks of different types. auto* screen_resolver1 = @@ -165,10 +283,13 @@ auto* system_resolver1 = MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); ScriptPromise system_promise1 = system_resolver1->Promise(); - controller.AcquireWakeLock(WakeLockType::kScreen, screen_resolver1); - controller.AcquireWakeLock(WakeLockType::kScreen, screen_resolver2); + controller.RequestWakeLock(WakeLockType::kScreen, screen_resolver1, + /*signal=*/nullptr); + controller.RequestWakeLock(WakeLockType::kScreen, screen_resolver2, + /*signal=*/nullptr); screen_lock.WaitForRequest(); - controller.AcquireWakeLock(WakeLockType::kSystem, system_resolver1); + controller.RequestWakeLock(WakeLockType::kSystem, system_resolver1, + /*signal=*/nullptr); system_lock.WaitForRequest(); // Now shut down our Document and make sure all [[ActiveLocks]] slots have @@ -189,6 +310,11 @@ WakeLockTestingContext context(&wake_lock_service); auto& controller = WakeLockController::From(*context.GetDocument()); + context.GetPermissionService().SetPermissionResponse( + WakeLockType::kScreen, mojom::blink::PermissionStatus::GRANTED); + context.GetPermissionService().SetPermissionResponse( + WakeLockType::kSystem, mojom::blink::PermissionStatus::GRANTED); + MockWakeLock& screen_lock = wake_lock_service.get_wake_lock(WakeLockType::kScreen); auto* screen_resolver = @@ -201,18 +327,80 @@ MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); ScriptPromise system_promise = system_resolver->Promise(); - controller.AcquireWakeLock(WakeLockType::kScreen, screen_resolver); + controller.RequestWakeLock(WakeLockType::kScreen, screen_resolver, + /*signal=*/nullptr); + controller.RequestWakeLock(WakeLockType::kSystem, system_resolver, + /*signal=*/nullptr); + screen_lock.WaitForRequest(); - controller.AcquireWakeLock(WakeLockType::kSystem, system_resolver); system_lock.WaitForRequest(); context.GetDocument()->GetPage()->SetIsHidden(true, false); + context.WaitForPromiseRejection(screen_promise); screen_lock.WaitForCancelation(); - EXPECT_EQ(v8::Promise::kRejected, GetScriptPromiseState(screen_promise)); + EXPECT_EQ(v8::Promise::kRejected, + ScriptPromiseUtils::GetPromiseState(screen_promise)); + DOMException* dom_exception = + ScriptPromiseUtils::GetPromiseResolutionAsDOMException(screen_promise); + ASSERT_NE(dom_exception, nullptr); + EXPECT_EQ("AbortError", dom_exception->name()); EXPECT_FALSE(screen_lock.is_acquired()); - EXPECT_EQ(v8::Promise::kPending, GetScriptPromiseState(system_promise)); + EXPECT_EQ(v8::Promise::kPending, + ScriptPromiseUtils::GetPromiseState(system_promise)); + EXPECT_TRUE(system_lock.is_acquired()); + + context.GetDocument()->GetPage()->SetIsHidden(false, false); + + auto* other_resolver = + MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); + ScriptPromise other_promise = system_resolver->Promise(); + controller.RequestWakeLock(WakeLockType::kScreen, other_resolver, + /*signal=*/nullptr); + screen_lock.WaitForRequest(); + EXPECT_EQ(v8::Promise::kPending, + ScriptPromiseUtils::GetPromiseState(other_promise)); + EXPECT_TRUE(screen_lock.is_acquired()); +} + +// https://w3c.github.io/wake-lock/#handling-document-loss-of-visibility +TEST(WakeLockControllerTest, PageVisibilityHiddenBeforeLockAcquisition) { + MockWakeLockService wake_lock_service; + WakeLockTestingContext context(&wake_lock_service); + auto& controller = WakeLockController::From(*context.GetDocument()); + + context.GetPermissionService().SetPermissionResponse( + WakeLockType::kScreen, mojom::blink::PermissionStatus::GRANTED); + context.GetPermissionService().SetPermissionResponse( + WakeLockType::kSystem, mojom::blink::PermissionStatus::GRANTED); + + MockWakeLock& screen_lock = + wake_lock_service.get_wake_lock(WakeLockType::kScreen); + auto* screen_resolver = + MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); + ScriptPromise screen_promise = screen_resolver->Promise(); + + MockWakeLock& system_lock = + wake_lock_service.get_wake_lock(WakeLockType::kSystem); + auto* system_resolver = + MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); + ScriptPromise system_promise = system_resolver->Promise(); + + controller.RequestWakeLock(WakeLockType::kScreen, screen_resolver, + /*signal=*/nullptr); + controller.RequestWakeLock(WakeLockType::kSystem, system_resolver, + /*signal=*/nullptr); + context.GetDocument()->GetPage()->SetIsHidden(true, false); + + context.WaitForPromiseRejection(screen_promise); + system_lock.WaitForRequest(); + + EXPECT_EQ(v8::Promise::kRejected, + ScriptPromiseUtils::GetPromiseState(screen_promise)); + EXPECT_FALSE(screen_lock.is_acquired()); + EXPECT_EQ(v8::Promise::kPending, + ScriptPromiseUtils::GetPromiseState(system_promise)); EXPECT_TRUE(system_lock.is_acquired()); } @@ -223,6 +411,9 @@ WakeLockTestingContext context(&wake_lock_service); auto& controller = WakeLockController::From(*context.GetDocument()); + context.GetPermissionService().SetPermissionResponse( + WakeLockType::kScreen, mojom::blink::PermissionStatus::GRANTED); + MockWakeLock& screen_lock = wake_lock_service.get_wake_lock(WakeLockType::kScreen); auto* screen_resolver = @@ -234,14 +425,16 @@ &WakeLockController::ReleaseWakeLock, WrapWeakPersistent(&controller), WakeLockType::kScreen, WrapPersistent(screen_resolver))); - controller.AcquireWakeLock(WakeLockType::kScreen, screen_resolver); + controller.RequestWakeLock(WakeLockType::kScreen, screen_resolver, + /*signal=*/nullptr); screen_lock.WaitForRequest(); context.GetDocument()->GetPage()->SetIsHidden(true, false); context.WaitForPromiseRejection(screen_promise); screen_lock.WaitForCancelation(); - EXPECT_EQ(v8::Promise::kRejected, GetScriptPromiseState(screen_promise)); + EXPECT_EQ(v8::Promise::kRejected, + ScriptPromiseUtils::GetPromiseState(screen_promise)); EXPECT_FALSE(screen_lock.is_acquired()); abort_signal->SignalAbort(); @@ -250,4 +443,46 @@ EXPECT_FALSE(screen_lock.is_acquired()); } +TEST(WakeLockControllerTest, RequestPermissionGranted) { + MockWakeLockService wake_lock_service; + WakeLockTestingContext context(&wake_lock_service); + auto& controller = WakeLockController::From(*context.GetDocument()); + + context.GetPermissionService().SetPermissionResponse( + WakeLockType::kSystem, mojom::blink::PermissionStatus::GRANTED); + + auto* system_resolver = + MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); + ScriptPromise system_promise = system_resolver->Promise(); + + controller.RequestPermission(WakeLockType::kSystem, system_resolver); + context.WaitForPromiseFulfillment(system_promise); + + EXPECT_EQ(v8::Promise::kFulfilled, + ScriptPromiseUtils::GetPromiseState(system_promise)); + EXPECT_EQ("granted", + ScriptPromiseUtils::GetPromiseResolutionAsString(system_promise)); +} + +TEST(WakeLockControllerTest, RequestPermissionDenied) { + MockWakeLockService wake_lock_service; + WakeLockTestingContext context(&wake_lock_service); + auto& controller = WakeLockController::From(*context.GetDocument()); + + context.GetPermissionService().SetPermissionResponse( + WakeLockType::kSystem, mojom::blink::PermissionStatus::DENIED); + + auto* system_resolver = + MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); + ScriptPromise system_promise = system_resolver->Promise(); + + controller.RequestPermission(WakeLockType::kSystem, system_resolver); + context.WaitForPromiseFulfillment(system_promise); + + EXPECT_EQ(v8::Promise::kFulfilled, + ScriptPromiseUtils::GetPromiseState(system_promise)); + EXPECT_EQ("denied", + ScriptPromiseUtils::GetPromiseResolutionAsString(system_promise)); +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/wake_lock/wake_lock_state_record_test.cc b/third_party/blink/renderer/modules/wake_lock/wake_lock_state_record_test.cc index eae4954..3fea7bc 100644 --- a/third_party/blink/renderer/modules/wake_lock/wake_lock_state_record_test.cc +++ b/third_party/blink/renderer/modules/wake_lock/wake_lock_state_record_test.cc
@@ -7,7 +7,6 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.h" @@ -24,11 +23,6 @@ return MakeGarbageCollected<WakeLockStateRecord>(context.GetDocument(), type); } -DOMException* GetDOMException(const ScriptPromise& promise) { - return V8DOMException::ToImplWithTypeCheck( - promise.GetIsolate(), promise.V8Value().As<v8::Promise>()->Result()); -} - } // namespace TEST(WakeLockStateRecordTest, AcquireWakeLock) { @@ -51,8 +45,10 @@ state_record->AcquireWakeLock(resolver2); screen_lock.WaitForRequest(); - EXPECT_EQ(v8::Promise::kPending, GetScriptPromiseState(promise1)); - EXPECT_EQ(v8::Promise::kPending, GetScriptPromiseState(promise2)); + EXPECT_EQ(v8::Promise::kPending, + ScriptPromiseUtils::GetPromiseState(promise1)); + EXPECT_EQ(v8::Promise::kPending, + ScriptPromiseUtils::GetPromiseState(promise2)); EXPECT_TRUE(screen_lock.is_acquired()); EXPECT_EQ(2U, state_record->active_locks_.size()); } @@ -72,7 +68,8 @@ state_record->AcquireWakeLock(resolver); screen_lock.WaitForRequest(); - EXPECT_EQ(v8::Promise::kPending, GetScriptPromiseState(promise)); + EXPECT_EQ(v8::Promise::kPending, + ScriptPromiseUtils::GetPromiseState(promise)); EXPECT_EQ(1U, state_record->active_locks_.size()); EXPECT_TRUE(screen_lock.is_acquired()); @@ -80,8 +77,10 @@ context.WaitForPromiseRejection(promise); screen_lock.WaitForCancelation(); - EXPECT_EQ(v8::Promise::kRejected, GetScriptPromiseState(promise)); - DOMException* dom_exception = GetDOMException(promise); + EXPECT_EQ(v8::Promise::kRejected, + ScriptPromiseUtils::GetPromiseState(promise)); + DOMException* dom_exception = + ScriptPromiseUtils::GetPromiseResolutionAsDOMException(promise); ASSERT_NE(nullptr, dom_exception); EXPECT_EQ("AbortError", dom_exception->name()); @@ -111,14 +110,16 @@ context.WaitForPromiseRejection(promise); screen_lock.WaitForCancelation(); - EXPECT_EQ(v8::Promise::kRejected, GetScriptPromiseState(promise)); + EXPECT_EQ(v8::Promise::kRejected, + ScriptPromiseUtils::GetPromiseState(promise)); EXPECT_EQ(0U, state_record->active_locks_.size()); EXPECT_FALSE(screen_lock.is_acquired()); state_record->ReleaseWakeLock(resolver); test::RunPendingTasks(); - EXPECT_EQ(v8::Promise::kRejected, GetScriptPromiseState(promise)); + EXPECT_EQ(v8::Promise::kRejected, + ScriptPromiseUtils::GetPromiseState(promise)); EXPECT_EQ(0U, state_record->active_locks_.size()); EXPECT_FALSE(screen_lock.is_acquired()); } @@ -142,17 +143,22 @@ state_record->AcquireWakeLock(resolver2); screen_lock.WaitForRequest(); - EXPECT_EQ(v8::Promise::kPending, GetScriptPromiseState(promise1)); - EXPECT_EQ(v8::Promise::kPending, GetScriptPromiseState(promise2)); + EXPECT_EQ(v8::Promise::kPending, + ScriptPromiseUtils::GetPromiseState(promise1)); + EXPECT_EQ(v8::Promise::kPending, + ScriptPromiseUtils::GetPromiseState(promise2)); EXPECT_EQ(2U, state_record->active_locks_.size()); EXPECT_TRUE(screen_lock.is_acquired()); state_record->ReleaseWakeLock(resolver1); context.WaitForPromiseRejection(promise1); - EXPECT_EQ(v8::Promise::kRejected, GetScriptPromiseState(promise1)); - EXPECT_EQ(v8::Promise::kPending, GetScriptPromiseState(promise2)); - DOMException* dom_exception = GetDOMException(promise1); + EXPECT_EQ(v8::Promise::kRejected, + ScriptPromiseUtils::GetPromiseState(promise1)); + EXPECT_EQ(v8::Promise::kPending, + ScriptPromiseUtils::GetPromiseState(promise2)); + DOMException* dom_exception = + ScriptPromiseUtils::GetPromiseResolutionAsDOMException(promise1); ASSERT_NE(nullptr, dom_exception); EXPECT_EQ("AbortError", dom_exception->name()); @@ -172,12 +178,14 @@ MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); ScriptPromise promise = resolver->Promise(); - EXPECT_EQ(v8::Promise::kPending, GetScriptPromiseState(promise)); + EXPECT_EQ(v8::Promise::kPending, + ScriptPromiseUtils::GetPromiseState(promise)); state_record->ReleaseWakeLock(resolver); context.WaitForPromiseRejection(promise); - EXPECT_EQ(v8::Promise::kRejected, GetScriptPromiseState(promise)); + EXPECT_EQ(v8::Promise::kRejected, + ScriptPromiseUtils::GetPromiseState(promise)); EXPECT_EQ(0U, state_record->active_locks_.size()); EXPECT_FALSE(screen_lock.is_acquired()); } @@ -221,12 +229,16 @@ context.WaitForPromiseRejection(promise2); system_lock.WaitForCancelation(); - EXPECT_EQ(v8::Promise::kRejected, GetScriptPromiseState(promise1)); - EXPECT_EQ(v8::Promise::kRejected, GetScriptPromiseState(promise2)); - DOMException* dom_exception = GetDOMException(promise1); + EXPECT_EQ(v8::Promise::kRejected, + ScriptPromiseUtils::GetPromiseState(promise1)); + EXPECT_EQ(v8::Promise::kRejected, + ScriptPromiseUtils::GetPromiseState(promise2)); + DOMException* dom_exception = + ScriptPromiseUtils::GetPromiseResolutionAsDOMException(promise1); ASSERT_NE(nullptr, dom_exception); EXPECT_EQ("AbortError", dom_exception->name()); - dom_exception = GetDOMException(promise2); + dom_exception = + ScriptPromiseUtils::GetPromiseResolutionAsDOMException(promise2); ASSERT_NE(nullptr, dom_exception); EXPECT_EQ("AbortError", dom_exception->name()); @@ -257,12 +269,16 @@ context.WaitForPromiseRejection(promise1); context.WaitForPromiseRejection(promise2); - EXPECT_EQ(v8::Promise::kRejected, GetScriptPromiseState(promise1)); - EXPECT_EQ(v8::Promise::kRejected, GetScriptPromiseState(promise2)); - DOMException* dom_exception = GetDOMException(promise1); + EXPECT_EQ(v8::Promise::kRejected, + ScriptPromiseUtils::GetPromiseState(promise1)); + EXPECT_EQ(v8::Promise::kRejected, + ScriptPromiseUtils::GetPromiseState(promise2)); + DOMException* dom_exception = + ScriptPromiseUtils::GetPromiseResolutionAsDOMException(promise1); ASSERT_NE(nullptr, dom_exception); EXPECT_EQ("AbortError", dom_exception->name()); - dom_exception = GetDOMException(promise2); + dom_exception = + ScriptPromiseUtils::GetPromiseResolutionAsDOMException(promise2); ASSERT_NE(nullptr, dom_exception); EXPECT_EQ("AbortError", dom_exception->name());
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 new file mode 100644 index 0000000..1e48ec2 --- /dev/null +++ b/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.cc
@@ -0,0 +1,144 @@ +// 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/wake_lock/wake_lock_test_utils.h" + +#include "third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h" +#include "third_party/blink/renderer/platform/bindings/v8_binding.h" + +namespace blink { + +using mojom::blink::PermissionDescriptorPtr; +using mojom::blink::PermissionStatus; + +// MockPermissionService + +MockPermissionService::MockPermissionService() = default; +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( + &MockPermissionService::OnConnectionError, WTF::Unretained(this))); +} + +void MockPermissionService::SetPermissionResponse(WakeLockType type, + PermissionStatus status) { + DCHECK(status == PermissionStatus::GRANTED || + status == PermissionStatus::DENIED); + permission_responses_[static_cast<size_t>(type)] = status; +} + +void MockPermissionService::OnConnectionError() { + binding_.Unbind(); +} + +bool MockPermissionService::GetWakeLockTypeFromDescriptor( + const PermissionDescriptorPtr& descriptor, + WakeLockType* output) { + if (!descriptor->extension || !descriptor->extension->is_wake_lock()) + return false; + switch (descriptor->extension->get_wake_lock()->type) { + case mojom::blink::WakeLockType::kScreen: + *output = WakeLockType::kScreen; + return true; + case mojom::blink::WakeLockType::kSystem: + *output = WakeLockType::kSystem; + return true; + default: + return false; + } +} + +void MockPermissionService::WaitForPermissionRequest(WakeLockType type) { + size_t pos = static_cast<size_t>(type); + DCHECK(!request_permission_callbacks_[pos]); + base::RunLoop run_loop; + request_permission_callbacks_[pos] = run_loop.QuitClosure(); + run_loop.Run(); +} + +void MockPermissionService::HasPermission(PermissionDescriptorPtr permission, + HasPermissionCallback callback) { + WakeLockType type; + if (!GetWakeLockTypeFromDescriptor(permission, &type)) { + std::move(callback).Run(PermissionStatus::DENIED); + return; + } + size_t pos = static_cast<size_t>(type); + DCHECK(permission_responses_[pos].has_value()); + std::move(callback).Run( + permission_responses_[pos].value_or(PermissionStatus::DENIED)); +} + +void MockPermissionService::RequestPermission( + PermissionDescriptorPtr permission, + bool user_gesture, + RequestPermissionCallback callback) { + WakeLockType type; + if (!GetWakeLockTypeFromDescriptor(permission, &type)) { + std::move(callback).Run(PermissionStatus::DENIED); + return; + } + + size_t pos = static_cast<size_t>(type); + DCHECK(permission_responses_[pos].has_value()); + if (request_permission_callbacks_[pos]) + std::move(request_permission_callbacks_[pos]).Run(); + std::move(callback).Run( + permission_responses_[pos].value_or(PermissionStatus::DENIED)); +} + +void MockPermissionService::RequestPermissions( + Vector<PermissionDescriptorPtr> permissions, + bool user_gesture, + mojom::blink::PermissionService::RequestPermissionsCallback) { + NOTREACHED(); +} + +void MockPermissionService::RevokePermission(PermissionDescriptorPtr permission, + RevokePermissionCallback) { + NOTREACHED(); +} + +void MockPermissionService::AddPermissionObserver( + PermissionDescriptorPtr permission, + PermissionStatus last_known_status, + mojom::blink::PermissionObserverPtr) { + NOTREACHED(); +} + +// ScriptPromiseUtils + +// static +v8::Promise::PromiseState ScriptPromiseUtils::GetPromiseState( + const ScriptPromise& promise) { + return promise.V8Value().As<v8::Promise>()->State(); +} + +// static +String ScriptPromiseUtils::GetPromiseResolutionAsString( + const ScriptPromise& promise) { + auto v8_promise = promise.V8Value().As<v8::Promise>(); + if (v8_promise->State() == v8::Promise::kPending) { + return g_empty_string; + } + ScriptValue promise_result(promise.GetScriptValue().GetScriptState(), + v8_promise->Result()); + String value; + if (!promise_result.ToString(value)) { + return g_empty_string; + } + return value; +} + +// static +DOMException* ScriptPromiseUtils::GetPromiseResolutionAsDOMException( + const ScriptPromise& promise) { + return V8DOMException::ToImplWithTypeCheck( + promise.GetIsolate(), promise.V8Value().As<v8::Promise>()->Result()); +} + +} // namespace blink
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 beba8a18..8b0d5e4 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
@@ -10,11 +10,13 @@ #include "base/callback.h" #include "base/logging.h" +#include "base/optional.h" #include "base/run_loop.h" #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "services/device/public/mojom/wake_lock.mojom-blink.h" #include "services/service_manager/public/cpp/interface_provider.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" #include "third_party/blink/renderer/bindings/core/v8/script_function.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" @@ -134,11 +136,57 @@ mock_wake_lock_[pos].Bind(std::move(request)); } - MockWakeLock - mock_wake_lock_[static_cast<size_t>(WakeLockType::kMaxValue) + 1]; + MockWakeLock mock_wake_lock_[kWakeLockTypeCount]; mojo::BindingSet<mojom::blink::WakeLockService> bindings_; }; +// Mock PermissionService implementation. It only implements the bits required +// by the Wake Lock code, and it mimics what we do in the content and chrome +// layers: screen locks are always granted, system locks are always denied. +class MockPermissionService final : public mojom::blink::PermissionService { + public: + MockPermissionService(); + ~MockPermissionService() override; + + void BindRequest(mojo::ScopedMessagePipeHandle handle); + + void SetPermissionResponse(WakeLockType, mojom::blink::PermissionStatus); + + void WaitForPermissionRequest(WakeLockType); + + private: + bool GetWakeLockTypeFromDescriptor( + const mojom::blink::PermissionDescriptorPtr& descriptor, + WakeLockType* output); + + // mojom::blink::PermissionService implementation + void HasPermission(mojom::blink::PermissionDescriptorPtr permission, + HasPermissionCallback) override; + void RequestPermission(mojom::blink::PermissionDescriptorPtr permission, + bool user_gesture, + RequestPermissionCallback) override; + void RequestPermissions( + Vector<mojom::blink::PermissionDescriptorPtr> permissions, + bool user_gesture, + 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 OnConnectionError(); + + mojo::Binding<mojom::blink::PermissionService> binding_{this}; + + base::Optional<mojom::blink::PermissionStatus> + permission_responses_[kWakeLockTypeCount]; + + base::OnceClosure request_permission_callbacks_[static_cast<size_t>( + WakeLockType::kMaxValue) + + 1]; +}; + // Overrides requests for WakeLockService with MockWakeLockService instances. // // Usage: @@ -161,11 +209,29 @@ mojom::blink::WakeLockService::Name_, WTF::BindRepeating(&MockWakeLockService::BindRequest, WTF::Unretained(mock_wake_lock_service))); + test_api.SetBinderForName( + mojom::blink::PermissionService::Name_, + WTF::BindRepeating(&MockPermissionService::BindRequest, + WTF::Unretained(&permission_service_))); } Document* GetDocument() { return &testing_scope_.GetDocument(); } LocalFrame* Frame() { return &testing_scope_.GetFrame(); } ScriptState* GetScriptState() { return testing_scope_.GetScriptState(); } + MockPermissionService& GetPermissionService() { return permission_service_; } + + // Synchronously waits for |promise| to be fulfilled. + ScriptPromise WaitForPromiseFulfillment(ScriptPromise promise) { + base::RunLoop run_loop; + ScriptPromise return_promise = + promise.Then(ClosureRunnerFunction::CreateFunction( + GetScriptState(), run_loop.QuitClosure())); + // Execute pending microtasks, otherwise it can take a few seconds for the + // promise to resolve. + v8::MicrotasksScope::PerformCheckpoint(GetScriptState()->GetIsolate()); + run_loop.Run(); + return return_promise; + } // Synchronously waits for |promise| to be rejected. void WaitForPromiseRejection(ScriptPromise promise) { @@ -180,8 +246,9 @@ } private: - // Helper class for WaitForPromiseRejection(). It provides a function that is - // invoked when a ScriptPromise is rejected that invokes |callback|. + // Helper class for WaitForPromise{Fulfillment,Rejection}(). It provides a + // function that is invoked when a ScriptPromise is rejected that invokes + // |callback|. class ClosureRunnerFunction final : public ScriptFunction { public: static v8::Local<v8::Function> CreateFunction( @@ -206,14 +273,27 @@ base::RepeatingClosure callback_; }; + MockPermissionService permission_service_; V8TestingScope testing_scope_; }; -// Shorthand for getting a PromiseState out of a ScriptPromise. -inline v8::Promise::PromiseState GetScriptPromiseState( - const ScriptPromise& promise) { - return promise.V8Value().As<v8::Promise>()->State(); -} +// Utility functions to retrieve promise data out of a ScriptPromise. +class ScriptPromiseUtils final { + public: + // Shorthand for getting a PromiseState out of a ScriptPromise. + static v8::Promise::PromiseState GetPromiseState( + const ScriptPromise& promise); + + // Shorthand for getting a String out of a ScriptPromise. This assumes the + // promise has been resolved with a string. If anything wrong happens during + // the conversion, an empty string is returned. + static String GetPromiseResolutionAsString(const ScriptPromise&); + + // Shorthand for getting a DOMException* out of a ScriptPromise. This assumes + // the promise has been resolved with a DOMException. If the conversion fails, + // nullptr is returned. + static DOMException* GetPromiseResolutionAsDOMException(const ScriptPromise&); +}; } // namespace blink
diff --git a/third_party/blink/renderer/modules/wake_lock/wake_lock_type.h b/third_party/blink/renderer/modules/wake_lock/wake_lock_type.h index 26a6087..09fe8e6 100644 --- a/third_party/blink/renderer/modules/wake_lock/wake_lock_type.h +++ b/third_party/blink/renderer/modules/wake_lock/wake_lock_type.h
@@ -26,6 +26,11 @@ // https://w3c.github.io/wake-lock/#the-wakelocktype-enum enum class WakeLockType : int8_t { kScreen, kSystem, kMaxValue = kSystem }; +// Useful for creating arrays with size N, where N is the number of different +// wake lock types. +constexpr size_t kWakeLockTypeCount = + static_cast<size_t>(WakeLockType::kMaxValue) + 1; + MODULES_EXPORT device::mojom::blink::WakeLockType ToMojomWakeLockType( WakeLockType type);
diff --git a/third_party/blink/renderer/modules/webaudio/analyser_node.idl b/third_party/blink/renderer/modules/webaudio/analyser_node.idl index d6578a7..8a299b4 100644 --- a/third_party/blink/renderer/modules/webaudio/analyser_node.idl +++ b/third_party/blink/renderer/modules/webaudio/analyser_node.idl
@@ -25,6 +25,7 @@ // See https://webaudio.github.io/web-audio-api/#analysernode [ + Exposed=Window, Constructor(BaseAudioContext context, optional AnalyserOptions options), RaisesException=Constructor, Measure
diff --git a/third_party/blink/renderer/modules/webaudio/audio_buffer.idl b/third_party/blink/renderer/modules/webaudio/audio_buffer.idl index 650c785f..d5546d6 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_buffer.idl +++ b/third_party/blink/renderer/modules/webaudio/audio_buffer.idl
@@ -28,6 +28,7 @@ // See https://webaudio.github.io/web-audio-api/#AudioBuffer [ + Exposed=Window, Constructor(AudioBufferOptions options), RaisesException=Constructor, Measure
diff --git a/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.idl b/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.idl index ed3550e..e41167f6 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.idl +++ b/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.idl
@@ -26,6 +26,7 @@ // A cached (non-streamed), memory-resident audio source // See https://webaudio.github.io/web-audio-api/#AudioBufferSourceNode [ + Exposed=Window, Constructor(BaseAudioContext context, optional AudioBufferSourceOptions options), RaisesException=Constructor, ActiveScriptWrappable,
diff --git a/third_party/blink/renderer/modules/webaudio/audio_context.idl b/third_party/blink/renderer/modules/webaudio/audio_context.idl index e386af9..41fd88b 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_context.idl +++ b/third_party/blink/renderer/modules/webaudio/audio_context.idl
@@ -32,6 +32,7 @@ // See https://webaudio.github.io/web-audio-api/#AudioContext [ + Exposed=Window, ActiveScriptWrappable, Constructor(optional AudioContextOptions contextOptions), ConstructorCallWith=Document,
diff --git a/third_party/blink/renderer/modules/webaudio/audio_destination_node.idl b/third_party/blink/renderer/modules/webaudio/audio_destination_node.idl index 29911739..ff155bf 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_destination_node.idl +++ b/third_party/blink/renderer/modules/webaudio/audio_destination_node.idl
@@ -24,6 +24,7 @@ */ // See https://webaudio.github.io/web-audio-api/#AudioDestinationNode +[Exposed=Window] interface AudioDestinationNode : AudioNode { readonly attribute unsigned long maxChannelCount; };
diff --git a/third_party/blink/renderer/modules/webaudio/audio_listener.idl b/third_party/blink/renderer/modules/webaudio/audio_listener.idl index de2f898..b48975c4 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_listener.idl +++ b/third_party/blink/renderer/modules/webaudio/audio_listener.idl
@@ -27,6 +27,7 @@ */ // See https://webaudio.github.io/web-audio-api/#audiolistener +[Exposed=Window] interface AudioListener { [RaisesException, MeasureAs=AudioListenerSetPosition] void setPosition(float x, float y, float z); [RaisesException, MeasureAs=AudioListenerSetOrientation] void setOrientation(float x, float y, float z, float xUp, float yUp, float zUp);
diff --git a/third_party/blink/renderer/modules/webaudio/audio_node.idl b/third_party/blink/renderer/modules/webaudio/audio_node.idl index 3bf9da4..277884e 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_node.idl +++ b/third_party/blink/renderer/modules/webaudio/audio_node.idl
@@ -36,6 +36,7 @@ "discrete" }; +[Exposed=Window] interface AudioNode : EventTarget { [RaisesException, MeasureAs=AudioNodeConnectToAudioNode] AudioNode connect(AudioNode destination, optional unsigned long output = 0, optional unsigned long input = 0); [RaisesException, MeasureAs=AudioNodeConnectToAudioParam] void connect(AudioParam destination, optional unsigned long output = 0);
diff --git a/third_party/blink/renderer/modules/webaudio/audio_param.idl b/third_party/blink/renderer/modules/webaudio/audio_param.idl index 002c9264..b21f6f81b 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_param.idl +++ b/third_party/blink/renderer/modules/webaudio/audio_param.idl
@@ -32,6 +32,7 @@ "k-rate" }; +[Exposed=Window] interface AudioParam { [RaisesException=Setter] attribute float value; [RaisesException=Setter] attribute AutomationRate automationRate;
diff --git a/third_party/blink/renderer/modules/webaudio/audio_param_map.idl b/third_party/blink/renderer/modules/webaudio/audio_param_map.idl index 4055562..cfef676b 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_param_map.idl +++ b/third_party/blink/renderer/modules/webaudio/audio_param_map.idl
@@ -4,6 +4,7 @@ // See https://webaudio.github.io/web-audio-api/#audioparammap +[Exposed=Window] interface AudioParamMap { readonly maplike<DOMString, AudioParam>; };
diff --git a/third_party/blink/renderer/modules/webaudio/audio_processing_event.idl b/third_party/blink/renderer/modules/webaudio/audio_processing_event.idl index 947990e..8ca38a5 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_processing_event.idl +++ b/third_party/blink/renderer/modules/webaudio/audio_processing_event.idl
@@ -25,6 +25,7 @@ // See https://webaudio.github.io/web-audio-api/#audioprocessingevent [ + Exposed=Window, Constructor(DOMString type, AudioProcessingEventInit eventInitDict) ] interface AudioProcessingEvent : Event {
diff --git a/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.idl b/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.idl index 07466238..951c5a0 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.idl +++ b/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.idl
@@ -4,6 +4,7 @@ // See https://webaudio.github.io/web-audio-api/#AudioScheduledSourceNode [ + Exposed=Window, ActiveScriptWrappable ] interface AudioScheduledSourceNode : AudioNode {
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet.idl b/third_party/blink/renderer/modules/webaudio/audio_worklet.idl index e24cf62..272c304 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_worklet.idl +++ b/third_party/blink/renderer/modules/webaudio/audio_worklet.idl
@@ -5,6 +5,7 @@ // See https://webaudio.github.io/web-audio-api/#audioworklet [ + Exposed=Window, SecureContext ] interface AudioWorklet : Worklet { };
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_node.idl b/third_party/blink/renderer/modules/webaudio/audio_worklet_node.idl index 4772e75..ac7e6dae 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_worklet_node.idl +++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_node.idl
@@ -5,6 +5,7 @@ // See https://webaudio.github.io/web-audio-api/#audioworkletnode [ + Exposed=Window, ActiveScriptWrappable, Constructor(BaseAudioContext context, DOMString name, optional AudioWorkletNodeOptions options), ConstructorCallWith=ScriptState,
diff --git a/third_party/blink/renderer/modules/webaudio/base_audio_context.idl b/third_party/blink/renderer/modules/webaudio/base_audio_context.idl index a1d7cd6..3a9bd6a 100644 --- a/third_party/blink/renderer/modules/webaudio/base_audio_context.idl +++ b/third_party/blink/renderer/modules/webaudio/base_audio_context.idl
@@ -14,6 +14,7 @@ callback DecodeSuccessCallback = void (AudioBuffer decodedData); [ + Exposed=Window, ActiveScriptWrappable ] interface BaseAudioContext : EventTarget { // All rendered audio ultimately connects to destination, which represents the audio hardware.
diff --git a/third_party/blink/renderer/modules/webaudio/biquad_filter_node.idl b/third_party/blink/renderer/modules/webaudio/biquad_filter_node.idl index 63fb78f..f507394 100644 --- a/third_party/blink/renderer/modules/webaudio/biquad_filter_node.idl +++ b/third_party/blink/renderer/modules/webaudio/biquad_filter_node.idl
@@ -36,6 +36,7 @@ }; [ + Exposed=Window, Constructor(BaseAudioContext context, optional BiquadFilterOptions options), RaisesException=Constructor, Measure
diff --git a/third_party/blink/renderer/modules/webaudio/channel_merger_node.idl b/third_party/blink/renderer/modules/webaudio/channel_merger_node.idl index 4998b14..f0639ea 100644 --- a/third_party/blink/renderer/modules/webaudio/channel_merger_node.idl +++ b/third_party/blink/renderer/modules/webaudio/channel_merger_node.idl
@@ -28,6 +28,7 @@ // See https://webaudio.github.io/web-audio-api/#channelmergernode [ + Exposed=Window, Constructor(BaseAudioContext context, optional ChannelMergerOptions options), RaisesException=Constructor, Measure
diff --git a/third_party/blink/renderer/modules/webaudio/channel_splitter_node.idl b/third_party/blink/renderer/modules/webaudio/channel_splitter_node.idl index 8f8d721..a91d7e76 100644 --- a/third_party/blink/renderer/modules/webaudio/channel_splitter_node.idl +++ b/third_party/blink/renderer/modules/webaudio/channel_splitter_node.idl
@@ -25,6 +25,7 @@ // See https://webaudio.github.io/web-audio-api/#channelsplitternode [ + Exposed=Window, Constructor(BaseAudioContext context, optional ChannelSplitterOptions options), RaisesException=Constructor, Measure
diff --git a/third_party/blink/renderer/modules/webaudio/constant_source_node.idl b/third_party/blink/renderer/modules/webaudio/constant_source_node.idl index 8342f2d..6a21393a 100644 --- a/third_party/blink/renderer/modules/webaudio/constant_source_node.idl +++ b/third_party/blink/renderer/modules/webaudio/constant_source_node.idl
@@ -4,6 +4,7 @@ // See https://webaudio.github.io/web-audio-api/#ConstantSourceNode [ + Exposed=Window, Constructor(BaseAudioContext context, optional ConstantSourceOptions options), RaisesException=Constructor, ActiveScriptWrappable,
diff --git a/third_party/blink/renderer/modules/webaudio/convolver_node.idl b/third_party/blink/renderer/modules/webaudio/convolver_node.idl index 53559c56..f1dcda3 100644 --- a/third_party/blink/renderer/modules/webaudio/convolver_node.idl +++ b/third_party/blink/renderer/modules/webaudio/convolver_node.idl
@@ -26,6 +26,7 @@ // A linear convolution effect // See https://webaudio.github.io/web-audio-api/#ConvolverNode [ + Exposed=Window, Constructor(BaseAudioContext context, optional ConvolverOptions options), RaisesException=Constructor, Measure
diff --git a/third_party/blink/renderer/modules/webaudio/delay_node.idl b/third_party/blink/renderer/modules/webaudio/delay_node.idl index cc9d24c..9dc6923 100644 --- a/third_party/blink/renderer/modules/webaudio/delay_node.idl +++ b/third_party/blink/renderer/modules/webaudio/delay_node.idl
@@ -25,6 +25,7 @@ // See https://webaudio.github.io/web-audio-api/#DelayNode [ + Exposed=Window, Constructor(BaseAudioContext context, optional DelayOptions options), RaisesException=Constructor, Measure
diff --git a/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.idl b/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.idl index 41c9008..adcbed3 100644 --- a/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.idl +++ b/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.idl
@@ -25,6 +25,7 @@ // See https://webaudio.github.io/web-audio-api/#dynamicscompressornode [ + Exposed=Window, Constructor(BaseAudioContext context, optional DynamicsCompressorOptions options), RaisesException=Constructor, Measure
diff --git a/third_party/blink/renderer/modules/webaudio/gain_node.idl b/third_party/blink/renderer/modules/webaudio/gain_node.idl index 4eb0275e..78a68d6 100644 --- a/third_party/blink/renderer/modules/webaudio/gain_node.idl +++ b/third_party/blink/renderer/modules/webaudio/gain_node.idl
@@ -25,6 +25,7 @@ // See https://webaudio.github.io/web-audio-api/#gainnode [ + Exposed=Window, Constructor(BaseAudioContext context, optional GainOptions options), RaisesException=Constructor, Measure
diff --git a/third_party/blink/renderer/modules/webaudio/iir_filter_node.idl b/third_party/blink/renderer/modules/webaudio/iir_filter_node.idl index b98d3196..6bd6e6d 100644 --- a/third_party/blink/renderer/modules/webaudio/iir_filter_node.idl +++ b/third_party/blink/renderer/modules/webaudio/iir_filter_node.idl
@@ -4,6 +4,7 @@ // See https://webaudio.github.io/web-audio-api/#iirfilternode [ + Exposed=Window, Constructor(BaseAudioContext context, IIRFilterOptions options), RaisesException=Constructor, Measure
diff --git a/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.idl b/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.idl index 9916261..22552cc8 100644 --- a/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.idl +++ b/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.idl
@@ -25,6 +25,7 @@ // See https://webaudio.github.io/web-audio-api/#mediaelementaudiosourcenode [ + Exposed=Window, Constructor(AudioContext context, MediaElementAudioSourceOptions options), RaisesException=Constructor, Measure
diff --git a/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.idl b/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.idl index d4bc924..c291a7e 100644 --- a/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.idl +++ b/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.idl
@@ -25,6 +25,7 @@ // See https://webaudio.github.io/web-audio-api/#mediastreamaudiodestinationnode [ + Exposed=Window, Constructor(AudioContext context, optional AudioNodeOptions options), RaisesException=Constructor, Measure
diff --git a/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.idl b/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.idl index 368ff9df..504d8fe2 100644 --- a/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.idl +++ b/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.idl
@@ -25,6 +25,7 @@ // See https://webaudio.github.io/web-audio-api/#offlineaudiocompletionevent [ + Exposed=Window, Constructor(DOMString type, OfflineAudioCompletionEventInit eventInitDict) ] interface OfflineAudioCompletionEvent : Event {
diff --git a/third_party/blink/renderer/modules/webaudio/offline_audio_context.idl b/third_party/blink/renderer/modules/webaudio/offline_audio_context.idl index 3c57739..7832c12 100644 --- a/third_party/blink/renderer/modules/webaudio/offline_audio_context.idl +++ b/third_party/blink/renderer/modules/webaudio/offline_audio_context.idl
@@ -25,6 +25,7 @@ // See https://webaudio.github.io/web-audio-api/#OfflineAudioContext [ + Exposed=Window, Constructor(unsigned long numberOfChannels, unsigned long numberOfFrames, float sampleRate), Constructor(OfflineAudioContextOptions options), ConstructorCallWith=ExecutionContext,
diff --git a/third_party/blink/renderer/modules/webaudio/oscillator_node.idl b/third_party/blink/renderer/modules/webaudio/oscillator_node.idl index d5cf7b82..328f042 100644 --- a/third_party/blink/renderer/modules/webaudio/oscillator_node.idl +++ b/third_party/blink/renderer/modules/webaudio/oscillator_node.idl
@@ -34,6 +34,7 @@ // OscillatorNode is an audio generator of periodic waveforms. [ + Exposed=Window, Constructor(BaseAudioContext context, optional OscillatorOptions options), RaisesException=Constructor, Measure
diff --git a/third_party/blink/renderer/modules/webaudio/panner_node.idl b/third_party/blink/renderer/modules/webaudio/panner_node.idl index 25a19fc..4a0d709 100644 --- a/third_party/blink/renderer/modules/webaudio/panner_node.idl +++ b/third_party/blink/renderer/modules/webaudio/panner_node.idl
@@ -36,6 +36,7 @@ }; [ + Exposed=Window, Constructor(BaseAudioContext context, optional PannerOptions options), RaisesException=Constructor, Measure
diff --git a/third_party/blink/renderer/modules/webaudio/periodic_wave.idl b/third_party/blink/renderer/modules/webaudio/periodic_wave.idl index f640cfa..6dcbc504c11 100644 --- a/third_party/blink/renderer/modules/webaudio/periodic_wave.idl +++ b/third_party/blink/renderer/modules/webaudio/periodic_wave.idl
@@ -26,6 +26,7 @@ // PeriodicWave represents a periodic audio waveform given by its Fourier coefficients. // See https://webaudio.github.io/web-audio-api/#periodicwave [ + Exposed=Window, Constructor(BaseAudioContext context, optional PeriodicWaveOptions options), RaisesException=Constructor, Measure
diff --git a/third_party/blink/renderer/modules/webaudio/script_processor_node.idl b/third_party/blink/renderer/modules/webaudio/script_processor_node.idl index 43b8b00..2c10bca 100644 --- a/third_party/blink/renderer/modules/webaudio/script_processor_node.idl +++ b/third_party/blink/renderer/modules/webaudio/script_processor_node.idl
@@ -26,6 +26,7 @@ // See https://webaudio.github.io/web-audio-api/#scriptprocessornode // For real-time audio stream synthesis/processing in JavaScript [ + Exposed=Window, ActiveScriptWrappable ] interface ScriptProcessorNode : AudioNode { // Rendering callback
diff --git a/third_party/blink/renderer/modules/webaudio/stereo_panner_node.idl b/third_party/blink/renderer/modules/webaudio/stereo_panner_node.idl index 2753d91..ce9dedbf 100644 --- a/third_party/blink/renderer/modules/webaudio/stereo_panner_node.idl +++ b/third_party/blink/renderer/modules/webaudio/stereo_panner_node.idl
@@ -4,6 +4,7 @@ // See https://webaudio.github.io/web-audio-api/#stereopannernode [ + Exposed=Window, Constructor(BaseAudioContext context, optional StereoPannerOptions options), RaisesException=Constructor, Measure
diff --git a/third_party/blink/renderer/modules/webaudio/wave_shaper_node.idl b/third_party/blink/renderer/modules/webaudio/wave_shaper_node.idl index bfecb7e3..19f396c 100644 --- a/third_party/blink/renderer/modules/webaudio/wave_shaper_node.idl +++ b/third_party/blink/renderer/modules/webaudio/wave_shaper_node.idl
@@ -31,6 +31,7 @@ }; [ + Exposed=Window, Constructor(BaseAudioContext context, optional WaveShaperOptions options), RaisesException=Constructor, Measure
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 2a41297e..c162d66 100644 --- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc +++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -39,10 +39,6 @@ RuntimeEnabledFeatures::SetHeapIncrementalMarkingEnabled(enable); } -void WebRuntimeFeatures::EnableBloatedRendererDetection(bool enable) { - RuntimeEnabledFeatures::SetBloatedRendererDetectionEnabled(enable); -} - void WebRuntimeFeatures::EnableBlockingFocusWithoutUserActivation(bool enable) { RuntimeEnabledFeatures::SetBlockingFocusWithoutUserActivationEnabled(enable); }
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc index 3f423b6a..a02cc968 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
@@ -550,7 +550,7 @@ scoped_refptr<StaticBitmapImage> Snapshot() override { TRACE_EVENT0("blink", "CanvasResourceProviderSharedImage::Snapshot"); - if (IsGpuContextLost()) + if (!IsValid()) return nullptr; EndWriteAccess();
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc index 3102466a..8277835 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
@@ -317,7 +317,6 @@ Pointee(DrawsRectangle(FloatRect(0, 0, 100, 100), Color::kWhite))); EXPECT_EQ(Translation(50, -50), child->ScreenSpaceTransform()); EXPECT_EQ(gfx::Size(100, 100), child->bounds()); - EXPECT_FALSE(GetTransformNode(child).transform_changed); } TEST_P(PaintArtifactCompositorTest, OneTransform) { @@ -337,7 +336,6 @@ ASSERT_EQ(2u, ContentLayerCount()); { const cc::Layer* layer = ContentLayerAt(0); - EXPECT_FALSE(GetTransformNode(layer).transform_changed); Vector<RectWithColor> rects_with_color; rects_with_color.push_back( @@ -353,7 +351,6 @@ } { const cc::Layer* layer = ContentLayerAt(1); - EXPECT_FALSE(GetTransformNode(layer).transform_changed); EXPECT_THAT( layer->GetPicture(), Pointee(DrawsRectangle(FloatRect(0, 0, 100, 100), Color::kGray))); @@ -379,7 +376,6 @@ ASSERT_EQ(2u, ContentLayerCount()); { const cc::Layer* layer = ContentLayerAt(0); - EXPECT_FALSE(GetTransformNode(layer).transform_changed); Vector<RectWithColor> rects_with_color; rects_with_color.push_back( @@ -395,7 +391,6 @@ } { const cc::Layer* layer = ContentLayerAt(1); - EXPECT_FALSE(GetTransformNode(layer).transform_changed); EXPECT_THAT( layer->GetPicture(), Pointee(DrawsRectangle(FloatRect(0, 0, 100, 100), Color::kGray))); @@ -422,7 +417,6 @@ ASSERT_EQ(2u, ContentLayerCount()); { const cc::Layer* layer = ContentLayerAt(0); - EXPECT_FALSE(GetTransformNode(layer).transform_changed); EXPECT_THAT( layer->GetPicture(), Pointee(DrawsRectangle(FloatRect(0, 0, 300, 200), Color::kWhite))); @@ -432,7 +426,6 @@ } { const cc::Layer* layer = ContentLayerAt(1); - EXPECT_FALSE(GetTransformNode(layer).transform_changed); EXPECT_THAT( layer->GetPicture(), Pointee(DrawsRectangle(FloatRect(0, 0, 300, 200), Color::kBlack)));
diff --git a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc index f187b8a..674d927 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
@@ -106,6 +106,7 @@ origin.Z()); } compositor_node.needs_local_transform_update = true; + compositor_node.transform_changed = true; } static void AdjustPageScaleToUsePostLocal(cc::TransformNode& page_scale) { @@ -117,6 +118,7 @@ page_scale.post_local.matrix() = page_scale.local.matrix(); page_scale.pre_local.matrix().setIdentity(); page_scale.local.matrix().setIdentity(); + page_scale.transform_changed = true; } static void SetTransformTreePageScaleFactor( @@ -176,7 +178,6 @@ property_trees->scroll_tree.SetScrollOffset( scroll_node->GetCompositorElementId(), cc_transform->scroll_offset); - cc_transform->transform_changed = true; property_trees->transform_tree.set_needs_update(true); property_trees->scroll_tree.set_needs_update(true); return true; @@ -201,7 +202,6 @@ // flag, we should clear it to let the compositor respect the new value. cc_transform->is_currently_animating = false; - cc_transform->transform_changed = true; property_trees->transform_tree.set_needs_update(true); return true; } @@ -221,7 +221,6 @@ SetTransformTreePageScaleFactor(&property_trees->transform_tree, cc_transform); - cc_transform->transform_changed = true; property_trees->transform_tree.set_needs_update(true); return true; }
diff --git a/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc b/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc index 0bf9ce6..a520aee 100644 --- a/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc +++ b/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc
@@ -103,7 +103,8 @@ for (const auto* t = &destination; t != &source; t = t->Parent()) { if (!t) { // |source| is not an ancestor of |destination|. Simply map. - GeometryMapper::SourceToDestinationRect(source, destination, rect_); + if (!IsInfinite()) + GeometryMapper::SourceToDestinationRect(source, destination, rect_); return; } if (t->ScrollNode())
diff --git a/third_party/blink/renderer/platform/graphics/paint/cull_rect_test.cc b/third_party/blink/renderer/platform/graphics/paint/cull_rect_test.cc index 5045c74..e965991 100644 --- a/third_party/blink/renderer/platform/graphics/paint/cull_rect_test.cc +++ b/third_party/blink/renderer/platform/graphics/paint/cull_rect_test.cc
@@ -349,6 +349,10 @@ // Should ignore old_cull_rect. cull_rect2.ApplyTransforms(*t2, *t1, old_cull_rect); EXPECT_EQ(cull_rect1, cull_rect2); + + CullRect infinite = CullRect::Infinite(); + infinite.ApplyTransforms(*t2, *t1, base::nullopt); + EXPECT_TRUE(infinite.IsInfinite()); } TEST_F(CullRectTest, ApplyTransformsSmallScrollContentsAfterBigScrollContents) {
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 2c14fde..1fd5181 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -180,15 +180,6 @@ name: "BlinkRuntimeCallStats", }, { - name: "BloatedRendererDetection", - status: "experimental", - }, - { - // Detects bloated renderers even if the uptime is small. - // Useful for local testing, not intended for production. - name: "BloatedRendererDetectionSkipUptimeCheck", - }, - { // Adding simpler reading methods - stream(), text(), and arrayBuffer() - // to the Blob interface. See: https://github.com/w3c/FileAPI/pull/117 name: "BlobReadMethods", @@ -1152,7 +1143,7 @@ }, { name: "PauseExecutionContextOnBackgroundFreeze", - status: "experimental", + status: "stable", }, { name: "PaymentApp", @@ -1384,10 +1375,6 @@ status: "stable", }, { - name: "ScriptedTaskQueue", - status: "experimental" - }, - { name: "ScriptStreamingOnPreload", }, // Serialize and restore scroll anchors.
diff --git a/third_party/blink/renderer/platform/scheduler/common/thread.cc b/third_party/blink/renderer/platform/scheduler/common/thread.cc index 09aadc79..efb9f22 100644 --- a/third_party/blink/renderer/platform/scheduler/common/thread.cc +++ b/third_party/blink/renderer/platform/scheduler/common/thread.cc
@@ -32,7 +32,7 @@ // Controls whether we use ThreadPriority::DISPLAY for compositor thread. const base::Feature kBlinkCompositorUseDisplayThreadPriority { "BlinkCompositorUseDisplayThreadPriority", -#if defined(OS_ANDROID) || defined(OS_CHROMEOS) || defined(USE_OZONE) +#if defined(OS_ANDROID) base::FEATURE_ENABLED_BY_DEFAULT #else base::FEATURE_DISABLED_BY_DEFAULT
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc index e2704d4d..39c9b8c2 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
@@ -410,10 +410,6 @@ case TaskType::kNetworkingControl: // Loading task queues are handled separately. return base::nullopt; - case TaskType::kExperimentalWebSchedulingUserInteraction: - case TaskType::kExperimentalWebSchedulingBestEffort: - // WebScheduling queues are handled separately. - return base::nullopt; // Throttling following tasks may break existing web pages, so tentatively // these are unthrottled. // TODO(nhiroki): Throttle them again after we're convinced that it's safe @@ -522,14 +518,6 @@ return frame_task_queue_controller_->InspectorTaskQueue(); case TaskType::kInternalContentCapture: return frame_task_queue_controller_->BestEffortTaskQueue(); - case TaskType::kExperimentalWebSchedulingUserInteraction: - return frame_task_queue_controller_->ExperimentalWebSchedulingTaskQueue( - FrameTaskQueueController::WebSchedulingTaskQueueType:: - kWebSchedulingUserVisiblePriority); - case TaskType::kExperimentalWebSchedulingBestEffort: - return frame_task_queue_controller_->ExperimentalWebSchedulingTaskQueue( - FrameTaskQueueController::WebSchedulingTaskQueueType:: - kWebSchedulingBestEffortPriority); default: // Non-loading task queue. DCHECK_LT(static_cast<size_t>(type), @@ -994,16 +982,6 @@ } } - if (task_queue->queue_type() == - MainThreadTaskQueue::QueueType::kWebSchedulingUserInteraction) { - return TaskQueue::QueuePriority::kNormalPriority; - } - - if (task_queue->queue_type() == - MainThreadTaskQueue::QueueType::kWebSchedulingBestEffort) { - return TaskQueue::QueuePriority::kLowPriority; - } - return task_queue->queue_type() == MainThreadTaskQueue::QueueType::kFrameLoadingControl ? TaskQueue::QueuePriority::kHighPriority
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.cc index 0526fc1..f1d31aa 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.cc
@@ -10,7 +10,6 @@ #include "base/callback.h" #include "base/logging.h" #include "base/trace_event/traced_value.h" -#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/scheduler/common/tracing_helper.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" @@ -90,16 +89,6 @@ } scoped_refptr<MainThreadTaskQueue> -FrameTaskQueueController::ExperimentalWebSchedulingTaskQueue( - WebSchedulingTaskQueueType task_queue_type) { - if (!web_scheduling_task_queues_[task_queue_type]) - CreateWebSchedulingTaskQueue(task_queue_type); - - DCHECK(web_scheduling_task_queues_[task_queue_type]); - return web_scheduling_task_queues_[task_queue_type]; -} - -scoped_refptr<MainThreadTaskQueue> FrameTaskQueueController::NonLoadingTaskQueue( MainThreadTaskQueue::QueueTraits queue_traits) { if (!non_loading_task_queues_.Contains(queue_traits.Key())) @@ -124,42 +113,6 @@ TaskQueueCreated(loading_task_queue_); } -void FrameTaskQueueController::CreateWebSchedulingTaskQueue( - WebSchedulingTaskQueueType task_queue_type) { - DCHECK(RuntimeEnabledFeatures::ScriptedTaskQueueEnabled()); - DCHECK(!web_scheduling_task_queues_[task_queue_type]); - // |main_thread_scheduler_impl_| can be null in unit tests. - DCHECK(main_thread_scheduler_impl_); - - MainThreadTaskQueue::QueueType main_thread_queue_type = - MainThreadTaskQueue::QueueType::kDefault; - switch (task_queue_type) { - case kWebSchedulingUserVisiblePriority: - main_thread_queue_type = - MainThreadTaskQueue::QueueType::kWebSchedulingUserInteraction; - break; - case kWebSchedulingBestEffortPriority: - main_thread_queue_type = - MainThreadTaskQueue::QueueType::kWebSchedulingBestEffort; - break; - case kWebSchedulingPriorityCount: - NOTREACHED(); - } - - scoped_refptr<MainThreadTaskQueue> task_queue = - main_thread_scheduler_impl_->NewTaskQueue( - MainThreadTaskQueue::QueueCreationParams(main_thread_queue_type) - .SetCanBePaused(true) - .SetCanBeFrozen(true) - .SetCanBeDeferred(task_queue_type != - kWebSchedulingUserVisiblePriority) - .SetCanBeThrottled(true) - .SetFrameScheduler(frame_scheduler_impl_)); - - TaskQueueCreated(task_queue); - web_scheduling_task_queues_[task_queue_type] = task_queue; -} - void FrameTaskQueueController::CreateLoadingControlTaskQueue() { DCHECK(!loading_control_task_queue_); // |main_thread_scheduler_impl_| can be null in unit tests.
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h b/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h index 77044023..41b8307 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h
@@ -82,15 +82,6 @@ // exist. scoped_refptr<MainThreadTaskQueue> VeryHighPriorityTaskQueue(); - enum WebSchedulingTaskQueueType : unsigned { - kWebSchedulingUserVisiblePriority, - kWebSchedulingBestEffortPriority, - kWebSchedulingPriorityCount - }; - // Return the Scheduling API task queue for the given priority. - scoped_refptr<MainThreadTaskQueue> ExperimentalWebSchedulingTaskQueue( - WebSchedulingTaskQueueType); - // Return the non-loading task queue associated with the given queue traits, // and created it if it doesn't exist. scoped_refptr<MainThreadTaskQueue> NonLoadingTaskQueue( @@ -122,7 +113,6 @@ void CreateLoadingTaskQueue(); void CreateLoadingControlTaskQueue(); - void CreateWebSchedulingTaskQueue(WebSchedulingTaskQueueType task_queue_type); void CreateNonLoadingTaskQueue(MainThreadTaskQueue::QueueTraits); void TaskQueueCreated(const scoped_refptr<MainThreadTaskQueue>&); @@ -152,9 +142,6 @@ scoped_refptr<MainThreadTaskQueue> very_high_priority_task_queue_; - scoped_refptr<MainThreadTaskQueue> - web_scheduling_task_queues_[kWebSchedulingPriorityCount]; - using NonLoadingTaskQueueMap = WTF::HashMap<MainThreadTaskQueue::QueueTraitsKeyType, scoped_refptr<MainThreadTaskQueue>>;
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc index d4ca899..89e9366 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc
@@ -56,10 +56,6 @@ return "cleanup_tq"; case MainThreadTaskQueue::QueueType::kOther: return "other_tq"; - case MainThreadTaskQueue::QueueType::kWebSchedulingUserInteraction: - return "web_scheduling_user_interaction_tq"; - case MainThreadTaskQueue::QueueType::kWebSchedulingBestEffort: - return "web_scheduling_background_tq"; case MainThreadTaskQueue::QueueType::kCount: NOTREACHED(); return nullptr; @@ -87,8 +83,6 @@ case QueueType::kFrameDeferrable: case QueueType::kFramePausable: case QueueType::kFrameUnpausable: - case QueueType::kWebSchedulingUserInteraction: - case QueueType::kWebSchedulingBestEffort: return QueueClass::kTimer; case QueueType::kCompositor: case QueueType::kInput:
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h index 91d959c..6fc2ae30 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h
@@ -65,8 +65,8 @@ kCleanup = 20, - kWebSchedulingUserInteraction = 21, - kWebSchedulingBestEffort = 22, + // 21 : kWebSchedulingUserInteraction, obsolete. + // 22 : kWebSchedulingBestEffort, obsolete. // Used to group multiple types when calculating Expected Queueing Time. kOther = 23,
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc b/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc index 20ab732..3cffe58 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc
@@ -61,10 +61,6 @@ return "IdleTask"; case TaskType::kMiscPlatformAPI: return "MiscPlatformAPI"; - case TaskType::kExperimentalWebSchedulingUserInteraction: - return "ExperimentalWebSchedulingUserInteraction"; - case TaskType::kExperimentalWebSchedulingBestEffort: - return "ExperimentalWebSchedulingBackground"; case TaskType::kFontLoading: return "FontLoading"; case TaskType::kApplicationLifeCycle:
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc index 8792794..a4b6cfc 100644 --- a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc +++ b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc
@@ -202,8 +202,6 @@ case TaskType::kWorkerThreadTaskQueueDefault: case TaskType::kWorkerThreadTaskQueueV8: case TaskType::kWorkerThreadTaskQueueCompositor: - case TaskType::kExperimentalWebSchedulingUserInteraction: - case TaskType::kExperimentalWebSchedulingBestEffort: case TaskType::kInternalTranslation: case TaskType::kServiceWorkerClientMessage: case TaskType::kInternalContentCapture:
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc index c7e6070..7ef100eb 100644 --- a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc +++ b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc
@@ -33,10 +33,6 @@ using base::sequence_manager::TaskQueue; namespace { -// Workers could be short-lived, set a shorter interval than -// the renderer thread. -constexpr base::TimeDelta kUnspecifiedWorkerThreadLoadTrackerReportingInterval = - base::TimeDelta::FromSeconds(1); // Worker throttling trial const char kWorkerThrottlingTrial[] = "BlinkSchedulerDedicatedWorkerThrottling"; @@ -49,14 +45,6 @@ constexpr base::TimeDelta kDefaultMaxThrottlingDelay = base::TimeDelta::FromSeconds(60); -void ReportWorkerTaskLoad(base::TimeTicks time, double load) { - int load_percentage = static_cast<int>(load * 100); - DCHECK_LE(load_percentage, 100); - // TODO(kinuko): Maybe we also want to separately log when the associated - // tab is in foreground and when not. - UMA_HISTOGRAM_PERCENTAGE("WorkerScheduler.WorkerThreadLoad", load_percentage); -} - base::Optional<base::TimeDelta> GetMaxBudgetLevel() { int max_budget_level_ms; if (!base::StringToInt( @@ -108,9 +96,6 @@ "WorkerSchedulerIdlePeriod", base::TimeDelta::FromMilliseconds(300), helper()->NewTaskQueue(TaskQueue::Spec("worker_idle_tq"))), - load_tracker_(helper()->NowTicks(), - base::BindRepeating(&ReportWorkerTaskLoad), - kUnspecifiedWorkerThreadLoadTrackerReportingInterval), lifecycle_state_(proxy ? proxy->lifecycle_state() : SchedulingLifecycleState::kNotThrottled), worker_metrics_helper_(thread_type, helper()->HasCPUTimingForEachTask()), @@ -121,9 +106,6 @@ if (connector_) { ukm_recorder_ = ukm::MojoUkmRecorder::Create(connector_.get()); } - thread_start_time_ = helper()->NowTicks(); - load_tracker_.Resume(thread_start_time_); - helper()->AddTaskTimeObserver(this); if (proxy && proxy->parent_frame_type()) worker_metrics_helper_.SetParentFrameType(*proxy->parent_frame_type()); @@ -141,8 +123,6 @@ TRACE_EVENT_OBJECT_DELETED_WITH_ID( TRACE_DISABLED_BY_DEFAULT("worker.scheduler"), "WorkerScheduler", this); - helper()->RemoveTaskTimeObserver(this); - DCHECK(worker_schedulers_.empty()); } @@ -194,19 +174,8 @@ void WorkerThreadScheduler::Shutdown() { DCHECK(initialized_); - load_tracker_.RecordIdle(helper()->NowTicks()); - base::TimeTicks end_time = helper()->NowTicks(); - base::TimeDelta delta = end_time - thread_start_time_; - - // The lifetime could be radically different for different workers, - // some workers could be short-lived (but last at least 1 sec in - // Service Workers case) or could be around as long as the tab is open. - UMA_HISTOGRAM_CUSTOM_TIMES( - "WorkerThread.Runtime", delta, base::TimeDelta::FromSeconds(1), - base::TimeDelta::FromDays(1), 50 /* bucket count */); task_queue_throttler_.reset(); idle_helper_.Shutdown(); - helper()->RemoveTaskTimeObserver(this); helper()->Shutdown(); } @@ -258,13 +227,6 @@ return idle_helper_.CurrentIdleTaskDeadline(); } -void WorkerThreadScheduler::WillProcessTask(base::TimeTicks start_time) {} - -void WorkerThreadScheduler::DidProcessTask(base::TimeTicks start_time, - base::TimeTicks end_time) { - load_tracker_.RecordTaskTime(start_time, end_time); -} - void WorkerThreadScheduler::OnLifecycleStateChanged( SchedulingLifecycleState lifecycle_state) { if (lifecycle_state_ == lifecycle_state)
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h index a532cae..dd02d88 100644 --- a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h +++ b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h
@@ -8,11 +8,9 @@ #include "base/macros.h" #include "base/message_loop/message_loop.h" #include "base/single_thread_task_runner.h" -#include "base/task/sequence_manager/task_time_observer.h" #include "components/scheduling_metrics/task_duration_metric_reporter.h" #include "third_party/blink/public/platform/web_thread_type.h" #include "third_party/blink/renderer/platform/scheduler/common/idle_helper.h" -#include "third_party/blink/renderer/platform/scheduler/common/thread_load_tracker.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_status.h" #include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.h" @@ -41,12 +39,10 @@ class WakeUpBudgetPool; class CPUTimeBudgetPool; -class PLATFORM_EXPORT WorkerThreadScheduler - : public NonMainThreadSchedulerImpl, - public IdleHelper::Delegate, - public base::sequence_manager::TaskTimeObserver { +class PLATFORM_EXPORT WorkerThreadScheduler : public NonMainThreadSchedulerImpl, + public IdleHelper::Delegate { public: - // |sequence_manager|and |proxy| must remain valid for the entire lifetime of + // |sequence_manager| and |proxy| must remain valid for the entire lifetime of // this object. WorkerThreadScheduler( WebThreadType thread_type, @@ -78,11 +74,6 @@ base::sequence_manager::TaskQueue::TaskTiming* task_timing, base::sequence_manager::LazyNow* lazy_now) override; - // TaskTimeObserver implementation: - void WillProcessTask(base::TimeTicks start_time) override; - void DidProcessTask(base::TimeTicks start_time, - base::TimeTicks end_time) override; - SchedulerHelper* GetSchedulerHelperForTesting(); base::TimeTicks CurrentIdleTaskDeadlineForTesting() const; @@ -146,9 +137,7 @@ const WebThreadType thread_type_; IdleHelper idle_helper_; - ThreadLoadTracker load_tracker_; bool initialized_; - base::TimeTicks thread_start_time_; scoped_refptr<NonMainThreadTaskQueue> control_task_queue_; scoped_refptr<base::SingleThreadTaskRunner> v8_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint index 49ab56e..cc1c846 100644 --- a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint +++ b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint
@@ -82,7 +82,6 @@ Bug(none) compositing/reflections/nested-reflection-mask-change.html [ Failure ] Bug(none) compositing/rtl/rtl-iframe-absolute.html [ Failure ] Bug(none) compositing/rtl/rtl-iframe-relative.html [ Failure ] -Bug(none) compositing/scrollbars/nested-overlay-scrollbars.html [ Failure ] Bug(none) compositing/squashing/add-remove-squashed-layers.html [ Failure ] Bug(none) compositing/squashing/composited-bounds-for-negative-z.html [ Failure ] Bug(none) compositing/squashing/do-not-squash-non-self-painting-layer.html [ Failure ] @@ -132,8 +131,6 @@ crbug.com/907601 virtual/threaded/fast/scrolling/events/scrollend-event-fired-after-snap.html [ Skip ] -crbug.com/959949 external/wpt/element-timing/invisible-images.html [ Failure Pass ] - # Single pixel difference around one of the radiused borders. Bug(none) external/wpt/css/filter-effects/backdrop-filter-reference-filter.html [ Failure ] @@ -157,6 +154,7 @@ crbug.com/842356 paint/invalidation/compositing/containing-block-removed.html [ Failure ] # Extra raster invalidations. +Bug(none) compositing/overflow/do-not-repaint-if-scrolling-composited-layers.html [ Failure ] Bug(none) paint/invalidation/compositing/clipping-should-not-repaint-composited-descendants.html [ Failure ] Bug(none) paint/invalidation/compositing/should-not-repaint-composited-filter.html [ Failure ] Bug(none) paint/invalidation/compositing/should-not-repaint-composited-opacity.html [ Failure ] @@ -283,6 +281,7 @@ crbug.com/931486 compositing/force-compositing-mode/overflow-iframe-enter-compositing.html [ Failure ] crbug.com/931486 compositing/force-compositing-mode/overflow-iframe-layer.html [ Failure ] crbug.com/931486 compositing/iframes/overlapped-iframe-iframe.html [ Failure ] +crbug.com/931486 compositing/layer-creation/fixed-position-change-out-of-view-in-view.html [ Failure ] crbug.com/931486 compositing/overflow/accelerated-overflow-scroll-should-not-affect-perspective.html [ Failure ] crbug.com/931486 compositing/overflow/content-gains-scrollbars.html [ Failure ] crbug.com/931486 compositing/overflow/content-loses-scrollbars.html [ Failure ] @@ -293,6 +292,7 @@ crbug.com/931486 compositing/overflow/scroll-parent-with-non-stacking-context-composited-ancestor.html [ Failure ] crbug.com/931486 compositing/overflow/scrollbar-layer-placement-negative-z-index-child-positioned.html [ Failure ] crbug.com/931486 compositing/overflow/scrollbar-layer-placement.html [ Failure ] +crbug.com/931486 compositing/layer-creation/fixed-position-in-fixed-overflow.html [ Failure ] crbug.com/931486 compositing/layer-creation/fixed-position-nonscrollable-body-mismatch-containers.html [ Failure ] crbug.com/931486 compositing/layer-creation/fixed-position-out-of-view-positioning.html [ Failure ] crbug.com/931486 compositing/layer-creation/overflow-scroll-overlap.html [ Failure ] @@ -304,13 +304,16 @@ crbug.com/931486 compositing/rtl/rtl-absolute-overflow.html [ Failure ] crbug.com/931486 compositing/rtl/rtl-fixed-overflow.html [ Failure ] crbug.com/931486 compositing/rtl/rtl-iframe-absolute-overflow.html [ Failure ] +crbug.com/931486 compositing/rtl/rtl-iframe-fixed-overflow.html [ Failure ] crbug.com/931486 compositing/squashing/frame-clip-squashed-scrolled.html [ Failure ] +crbug.com/931486 compositing/squashing/squash-above-fixed-1.html [ Failure ] +crbug.com/931486 compositing/squashing/squash-above-fixed-3.html [ Failure ] crbug.com/931486 paint/invalidation/scroll/fixed-child-move-after-scroll.html [ Failure ] crbug.com/931486 paint/invalidation/scroll/fixed-child-of-fixed-move-after-scroll.html [ Failure ] crbug.com/931486 paint/invalidation/position/fixed-tranformed.html [ Failure ] crbug.com/931486 paint/invalidation/scroll/inline-style-change-in-scrolled-view.html [ Failure ] crbug.com/931486 paint/invalidation/background/background-image-paint-invalidation.html [ Failure ] -crbug.com/931486 crbug.com/931491 paint/invalidation/compositing/fixed-pos-inside-composited-intermediate-layer.html [ Failure ] +crbug.com/931486 paint/invalidation/compositing/fixed-pos-inside-composited-intermediate-layer.html [ Failure ] crbug.com/931486 crbug.com/931491 paint/invalidation/compositing/fixed-pos-with-abs-pos-child-scroll.html [ Failure ] crbug.com/931486 crbug.com/931491 paint/invalidation/compositing/fixed-scroll-in-empty-root-layer.html [ Failure ] crbug.com/931486 paint/invalidation/compositing/opacity-from-zero-to-non-zero-composited.html [ Failure ] @@ -376,6 +379,7 @@ crbug.com/909749 fast/events/touch/compositor-touch-hit-rects-non-composited-scroll.html [ Failure ] # Backdrop filter +crbug.com/923429 compositing/layer-creation/fixed-position-out-of-view-with-backdrop-filter.html [ Failure ] crbug.com/923429 css3/filters/backdrop-filter-basic-blur.html [ Timeout Failure ] crbug.com/923429 css3/filters/backdrop-filter-boundary.html [ Failure ] crbug.com/923429 css3/filters/backdrop-filter-browser-zoom.html [ Failure ] @@ -386,6 +390,7 @@ crbug.com/923429 css3/filters/backdrop-filter-rendering-no-background.html [ Failure ] crbug.com/923429 css3/filters/backdrop-filter-transform.html [ Failure ] crbug.com/923429 css3/filters/backdrop-filter-edge-pixels.html [ Failure ] +crbug.com/923429 css3/filters/backdrop-filter-clip-radius-zoom.html [ Failure ] crbug.com/923429 external/wpt/css/filter-effects/backdrop-filter-basic-background-color.html [ Failure ] crbug.com/923429 external/wpt/css/filter-effects/backdrop-filter-basic-opacity-2.html [ Failure ] crbug.com/923429 external/wpt/css/filter-effects/backdrop-filter-basic.html [ Failure ] @@ -413,6 +418,7 @@ crbug.com/923429 virtual/scalefactor200/css3/filters/backdrop-filter-rendering-no-background.html [ Failure ] crbug.com/923429 virtual/scalefactor200/css3/filters/backdrop-filter-rendering.html [ Failure ] crbug.com/923429 virtual/scalefactor200/css3/filters/backdrop-filter-transform.html [ Failure ] +crbug.com/923429 virtual/scalefactor200/css3/filters/backdrop-filter-clip-radius-zoom.html [ Failure ] crbug.com/923429 virtual/scalefactor200/external/wpt/css/filter-effects/backdrop-filter-basic-background-color.html [ Failure ] crbug.com/923429 virtual/scalefactor200/external/wpt/css/filter-effects/backdrop-filter-basic-opacity-2.html [ Failure ] crbug.com/923429 virtual/scalefactor200/external/wpt/css/filter-effects/backdrop-filter-basic.html [ Failure ] @@ -435,24 +441,6 @@ crbug.com/940033 virtual/fractional_scrolling_threaded/fast/scrolling/wheel-scrolling-over-custom-scrollbar.html [ Failure ] crbug.com/940033 virtual/threaded/fast/scrolling/wheel-scrolling-over-custom-scrollbar.html [ Failure ] -# Missing composited layer for fixed-position -crbug.com/931491 compositing/layer-creation/fixed-position-change-out-of-view-in-view.html [ Failure ] -crbug.com/931491 compositing/layer-creation/fixed-position-in-fixed-overflow.html [ Failure ] -crbug.com/931491 compositing/layer-creation/fixed-position-out-of-view-scaled-iframe-scroll.html [ Failure ] -crbug.com/931491 compositing/layer-creation/fixed-position-out-of-view-scaled-iframe.html [ Failure ] -crbug.com/931491 compositing/layer-creation/fixed-position-out-of-view-scaled-scroll.html [ Failure ] -crbug.com/931491 compositing/layer-creation/fixed-position-out-of-view-scaled.html [ Failure ] -crbug.com/931491 compositing/layer-creation/fixed-position-out-of-view-with-backdrop-filter.html [ Failure ] -crbug.com/931491 compositing/layer-creation/fixed-position-out-of-view.html [ Failure ] -crbug.com/931491 compositing/layer-creation/fixed-position-under-transform.html [ Failure ] -crbug.com/931491 compositing/rtl/rtl-iframe-fixed-overflow.html [ Failure ] -crbug.com/931491 compositing/rtl/rtl-iframe-fixed.html [ Failure ] -crbug.com/931491 compositing/squashing/no-squashing-into-fixed-position-that-clips.html [ Failure ] -crbug.com/931491 compositing/squashing/squash-above-fixed-1.html [ Failure ] -crbug.com/931491 compositing/squashing/squash-above-fixed-2.html [ Failure ] -crbug.com/931491 compositing/squashing/squash-above-fixed-3.html [ Failure ] -crbug.com/931491 compositing/squashing/squash-paint-invalidation-fixed-position.html [ Failure ] - crbug.com/918155 scrollbars/overlay-scrollbar-over-child-layer.html [ Failure ] crbug.com/918155 virtual/prefer_compositing_to_lcd_text/scrollbars/overlay-scrollbar-over-child-layer.html [ Failure ] @@ -478,71 +466,6 @@ # Crash on non-contiguous effect on multiple columns Bug(none) fast/multicol/composited-layer-will-change.html [ Crash ] -# Crash in CompositeorAnimations::CheckCanStartElementOnCompositor() etc. -crbug.com/962191 animations/stability/base-render-style-crash.html [ Crash ] -crbug.com/962191 animations/stability/option-element-crash.html [ Crash ] -crbug.com/962191 animations/stability/option-opacity-inherit-crash.html [ Crash ] -crbug.com/962191 animations/web-animations/animation-state-changes-positive-playback-rate.html [ Crash ] -crbug.com/962191 compositing/overflow/do-not-repaint-if-scrolling-composited-layers.html [ Crash ] -crbug.com/962191 external/wpt/css/css-animations/CSSPseudoElement-getAnimations.tentative.html [ Crash ] -crbug.com/962191 external/wpt/css/css-animations/KeyframeEffect-target.tentative.html [ Crash ] -crbug.com/962191 external/wpt/css/css-easing/cubic-bezier-timing-functions-output.html [ Crash ] -crbug.com/962191 external/wpt/css/css-easing/step-timing-functions-output.html [ Crash ] -crbug.com/962191 external/wpt/css/css-logical/animation-001.html [ Crash ] -crbug.com/962191 external/wpt/css/css-transitions/KeyframeEffect-target.tentative.html [ Crash ] -crbug.com/962191 external/wpt/scroll-animations/scroll-animation.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/animation-model/animation-types/accumulation-per-property.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/animation-model/animation-types/addition-per-property.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/animation-model/animation-types/discrete.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/animation-model/animation-types/interpolation-per-property.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/animation-model/animation-types/visibility.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/animation-model/combining-effects/effect-composition.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/animation-model/keyframe-effects/computed-keyframes-shorthands.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/animation-model/keyframe-effects/effect-value-context-filling.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/animation-model/keyframe-effects/effect-value-context.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/animation-model/keyframe-effects/effect-value-iteration-composite-operation.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/animation-model/keyframe-effects/effect-value-overlapping-keyframes.html [ Crash ] -crbug.com/966981 external/wpt/web-animations/animation-model/keyframe-effects/effect-value-replaced-animations.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/animation-model/keyframe-effects/effect-value-transformed-distance.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/interfaces/Animatable/animate.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/interfaces/Animatable/getAnimations.html [ Crash ] -crbug.com/966981 external/wpt/web-animations/interfaces/Animation/commitStyles.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/interfaces/Animation/finished.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/interfaces/Animation/id.html [ Crash ] -crbug.com/966981 external/wpt/web-animations/interfaces/Animation/persist.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/interfaces/Animation/ready.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/interfaces/AnimationEffect/updateTiming.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/interfaces/Document/getAnimations.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/interfaces/KeyframeEffect/target.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/timing-model/animation-effects/active-time.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/timing-model/animation-effects/current-iteration.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/timing-model/animation-effects/phases-and-states.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/timing-model/animation-effects/simple-iteration-progress.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/timing-model/animations/canceling-an-animation.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/timing-model/animations/finishing-an-animation.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/timing-model/animations/play-states.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/timing-model/animations/playing-an-animation.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/timing-model/animations/reversing-an-animation.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/timing-model/animations/seamlessly-updating-the-playback-rate-of-an-animation.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/timing-model/animations/setting-the-current-time-of-an-animation.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/timing-model/animations/setting-the-playback-rate-of-an-animation.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/timing-model/animations/setting-the-start-time-of-an-animation.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/timing-model/animations/setting-the-timeline-of-an-animation.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/timing-model/animations/the-current-time-of-an-animation.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/timing-model/animations/updating-the-finished-state.html [ Crash ] -crbug.com/962191 external/wpt/web-animations/timing-model/time-transformations/transformed-progress.html [ Crash ] -crbug.com/962191 http/tests/devtools/animation/animation-timeline.js [ Crash ] -crbug.com/962191 http/tests/devtools/elements/styles-3/spectrum.js [ Crash ] -crbug.com/962191 http/tests/devtools/sources/bezier-swatch-position.js [ Crash ] -crbug.com/962191 transitions/svg-transitions.html [ Crash ] -crbug.com/962191 virtual/threaded/animations/stability/base-render-style-crash.html [ Crash ] -crbug.com/962191 virtual/threaded/animations/stability/option-element-crash.html [ Crash ] -crbug.com/962191 virtual/threaded/animations/stability/option-opacity-inherit-crash.html [ Crash ] -crbug.com/962191 virtual/threaded/animations/web-animations/animation-state-changes-positive-playback-rate.html [ Crash ] -crbug.com/962191 virtual/threaded/external/wpt/css/css-animations/CSSPseudoElement-getAnimations.tentative.html [ Crash ] -crbug.com/962191 virtual/threaded/external/wpt/css/css-animations/KeyframeEffect-target.tentative.html [ Crash ] -crbug.com/962191 virtual/threaded/transitions/svg-transitions.html [ Crash ] - # Clip-path and mask. crbug.com/979369 compositing/images/direct-image-clip-path.html [ Failure ] crbug.com/979369 compositing/images/direct-image-dynamic-clip-path.html [ Failure ]
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-gpu-rasterization b/third_party/blink/web_tests/FlagExpectations/enable-gpu-rasterization new file mode 100644 index 0000000..d814edd8 --- /dev/null +++ b/third_party/blink/web_tests/FlagExpectations/enable-gpu-rasterization
@@ -0,0 +1,143 @@ +# Blur +crbug.com/972621 compositing/culling/scrolled-within-boxshadow.html [ Skip ] +crbug.com/972621 compositing/culling/translated-boxshadow.html [ Skip ] +crbug.com/972621 compositing/culling/unscrolled-within-boxshadow.html [ Skip ] +crbug.com/972621 compositing/geometry/clipping-foreground.html [ Skip ] +crbug.com/972621 compositing/geometry/foreground-layer.html [ Skip ] +crbug.com/972621 compositing/geometry/vertical-scroll-composited.html [ Skip ] +crbug.com/972621 compositing/iframes/composited-iframe-alignment.html [ Skip ] +crbug.com/972621 compositing/overflow/border-radius-above-composited-subframe.html [ Skip ] +crbug.com/972621 compositing/overflow/border-radius-composited-subframe.html [ Skip ] +crbug.com/972621 compositing/overflow/scrollbar-layer-placement-negative-z-index-child-positioned.html [ Skip ] +crbug.com/972621 compositing/overflow/scrollbar-layer-placement.html [ Skip ] +crbug.com/972621 compositing/shadows/shadow-drawing.html [ Skip ] +crbug.com/972621 css2.1/t090501-c414-flt-02-d-g.html [ Skip ] +crbug.com/972621 css2.1/t090501-c414-flt-03-b-g.html [ Skip ] +crbug.com/972621 css2.1/t100304-c43-rpl-bbx-00-d-g.html [ Skip ] +crbug.com/972621 css2.1/t100304-c43-rpl-bbx-01-d-g.html [ Skip ] +crbug.com/972621 css3/background/background-repeat-round-auto1.html [ Skip ] +crbug.com/972621 css3/background/background-repeat-round-border.html [ Skip ] +crbug.com/972621 css3/background/background-repeat-round-content.html [ Skip ] +crbug.com/972621 css3/background/background-repeat-round-padding.html [ Skip ] +crbug.com/972621 css3/filters/blur-filter-page-scroll-parents.html [ Skip ] +crbug.com/972621 css3/filters/blur-filter-page-scroll.html [ Skip ] +crbug.com/972621 css3/filters/crash-filter-change.html [ Skip ] +crbug.com/972621 css3/filters/effect-blur-hw.html [ Skip ] +crbug.com/972621 css3/filters/effect-blur.html [ Skip ] +crbug.com/972621 css3/filters/effect-brightness-clamping.html [ Skip ] +crbug.com/972621 css3/filters/effect-combined.html [ Skip ] +crbug.com/972621 css3/filters/effect-drop-shadow.html [ Skip ] +crbug.com/972621 css3/filters/regions-expanding.html [ Skip ] +crbug.com/972621 images/rgb-png-with-cmyk-color-profile.html [ Skip ] +crbug.com/972621 images/ycbcr-with-cmyk-color-profile.html [ Skip ] +crbug.com/972621 media/video-poster-scale.html [ Skip ] +crbug.com/972621 transforms/shadows.html [ Skip ] +crbug.com/972621 transforms/svg-vs-css.xhtml [ Skip ] + +# Input timing doesn't match screenshots +crbug.com/935970 compositing/gestures/gesture-tapHighlight-img-and-text.html [ Skip ] +crbug.com/935970 compositing/gestures/gesture-tapHighlight-multicol.html [ Skip ] +crbug.com/935970 compositing/gestures/gesture-tapHighlight-nested-cursor.html [ Skip ] +crbug.com/935970 compositing/gestures/gesture-tapHighlight-nested-cursor3.html [ Skip ] +crbug.com/935970 compositing/gestures/gesture-tapHighlight-simple-scaled-document.html [ Skip ] +crbug.com/935970 compositing/gestures/gesture-tapHighlight-with-squashing.html [ Skip ] +crbug.com/935970 compositing/iframes/layout-on-compositing-change.html [ Skip ] +crbug.com/935970 compositing/squashing/squash-compositing-hover.html [ Skip ] +crbug.com/935970 compositing/squashing/squash-transform-repainting-child.html [ Skip ] +crbug.com/935970 compositing/squashing/squash-transform-repainting-transformed-child.html [ Skip ] +crbug.com/935970 css3/viewport-percentage-lengths/vh-resize.html [ Skip ] +crbug.com/935970 images/drag-image-2.html [ Skip ] +crbug.com/935970 images/drag-image-descendant-iframe-composited.html [ Skip ] +crbug.com/935970 images/drag-image-descendant-painting-sibling.html [ Skip ] +crbug.com/935970 images/drag-image-transformed-child.html [ Skip ] +crbug.com/935970 images/drag-image-transformed-parent.html [ Skip ] +crbug.com/935970 images/drag-image.html [ Skip ] +crbug.com/935970 images/server-side-imagemap.html [ Skip ] +crbug.com/935970 media/color-profile-video-poster-image.html [ Skip ] +crbug.com/935970 media/controls-drag-timebar.html [ Skip ] +crbug.com/935970 media/controls-timeline.html [ Skip ] +crbug.com/935970 media/controls/video-enter-exit-fullscreen-while-hovering-shows-controls.html [ Skip ] +crbug.com/935970 media/controls/video-enter-exit-fullscreen-without-hovering-doesnt-show-controls.html [ Skip ] +crbug.com/935970 media/media-controls-tap-show-controls-without-activating.html [ Skip ] +crbug.com/935970 media/remoteplayback/prompt-twice-throws.html [ Skip ] +crbug.com/935970 media/video-controls-always-visible-when-control-hovered.html [ Skip ] +crbug.com/935970 media/video-controls-auto-hide-after-play-by-touch.html [ Skip ] +crbug.com/935970 media/video-controls-fullscreen.html [ Skip ] +crbug.com/935970 media/video-controls-hide-after-touch-on-control.html [ Skip ] +crbug.com/935970 media/video-controls-hide-on-move-outside-controls.html [ Skip ] +crbug.com/935970 media/video-controls-mouse-events-captured.html [ Skip ] +crbug.com/935970 media/video-controls-overflow-menu-closed-captions-button.html [ Skip ] +crbug.com/935970 media/video-controls-overflow-menu-fullscreen-button.html [ Skip ] +crbug.com/935970 media/video-controls-overflow-menu-mute-button.html [ Skip ] +crbug.com/935970 media/video-controls-overflow-menu-play-button.html [ Skip ] +crbug.com/935970 media/video-controls-transformed.html [ Skip ] +crbug.com/935970 media/video-controls-visibility-multimodal-mouse-after-touch.html [ Skip ] +crbug.com/935970 media/video-controls-visibility-multimodal-touch-after-mouse.html [ Skip ] +crbug.com/935970 media/video-controls-visible-audio-only.html [ Skip ] +crbug.com/935970 media/video-persistence.html [ Skip ] +crbug.com/935970 media/video-src-blob.html [ Skip ] +crbug.com/935970 images/huge-image-viewport-scale.html [ Skip ] +crbug.com/935970 images/image-map-multiple-xhtml.xhtml [ Skip ] +crbug.com/935970 images/image-map-multiple.html [ Skip ] +crbug.com/935970 media/audio-delete-while-slider-thumb-clicked.html [ Skip ] + +# Filter Rebaseline +crbug.com/978605 compositing/masks/mask-with-added-filters.html [ Skip ] +crbug.com/978605 compositing/masks/mask-with-removed-filters.html [ Skip ] + +# Tests fail even with a fuzzy pixel diff. They require a re-baseline. +crbug.com/954328 compositing/fixed-background-after-style-recalc.html [ Failure ] +crbug.com/954328 compositing/overflow/mask-with-filter.html [ Failure ] +crbug.com/954328 css3/blending/background-blend-mode-crossfade-image-gradient.html [ Failure ] +crbug.com/954328 css3/blending/background-blend-mode-default-value.html [ Failure ] +crbug.com/954328 css3/blending/background-blend-mode-gradient-gradient.html [ Failure ] +crbug.com/954328 css3/blending/background-blend-mode-gradient-image.html [ Failure ] +crbug.com/954328 css3/blending/background-blend-mode-image-color.html [ Failure ] +crbug.com/954328 css3/blending/background-blend-mode-image-image.html [ Failure ] +crbug.com/954328 css3/blending/background-blend-mode-image-svg.html [ Failure ] +crbug.com/954328 css3/blending/background-blend-mode-multiple-background-layers.html [ Failure ] +crbug.com/954328 css3/blending/background-blend-mode-single-layer-no-blending.html [ Failure ] +crbug.com/954328 css3/blending/background-blend-mode-svg-color.html [ Failure ] +crbug.com/954328 css3/blending/background-blend-mode-tiled-gradient.html [ Failure ] +crbug.com/954328 css3/blending/effect-background-blend-mode-stacking.html [ Failure ] +crbug.com/954328 css3/blending/effect-background-blend-mode-tiled.html [ Failure ] +crbug.com/954328 css3/blending/effect-background-blend-mode.html [ Failure ] +crbug.com/954328 css3/blending/mix-blend-mode-isolated-group-1.html [ Failure ] +crbug.com/954328 css3/blending/mix-blend-mode-isolated-group-2.html [ Failure ] +crbug.com/954328 css3/blending/mix-blend-mode-isolated-group-3.html [ Failure ] +crbug.com/954328 css3/filters/filter-change-repaint.html [ Failure ] +crbug.com/954328 css3/filters/filter-repaint-blur.html [ Failure ] +crbug.com/954328 css3/filters/filter-repaint-child-layers.html [ Failure ] +crbug.com/954328 css3/filters/filter-repaint-shadow.html [ Failure ] +crbug.com/954328 css3/filters/filter-repaint.html [ Failure ] +crbug.com/954328 css3/masking/mask-luminance-png.html [ Failure ] +crbug.com/954328 css3/masking/mask-repeat-round-auto1.html [ Failure ] +crbug.com/954328 css3/masking/mask-repeat-round-border.html [ Failure ] +crbug.com/954328 css3/masking/mask-repeat-round-content.html [ Failure ] +crbug.com/954328 css3/masking/mask-repeat-round-padding.html [ Failure ] +crbug.com/954328 css3/masking/mask-repeat-space-border.html [ Failure ] +crbug.com/954328 images/color-profile-animate-rotate.html [ Failure ] +crbug.com/954328 images/color-profile-animate.html [ Failure ] +crbug.com/954328 images/color-profile-background-image-cover.html [ Failure ] +crbug.com/954328 images/color-profile-background-image-cross-fade-png.html [ Failure ] +crbug.com/954328 images/color-profile-background-image-cross-fade.html [ Failure ] +crbug.com/954328 images/color-profile-background-image-repeat.html [ Failure ] +crbug.com/954328 images/color-profile-background-image-space.html [ Failure ] +crbug.com/954328 images/color-profile-border-fade.html [ Failure ] +crbug.com/954328 images/color-profile-border-image.html [ Failure ] +crbug.com/954328 images/color-profile-border-radius.html [ Failure ] +crbug.com/954328 images/color-profile-filter.html [ Failure ] +crbug.com/954328 images/color-profile-group.html [ Failure ] +crbug.com/954328 images/color-profile-image-canvas-pattern.html [ Failure ] +crbug.com/954328 images/color-profile-image-canvas.html [ Failure ] +crbug.com/954328 images/color-profile-image-filter-all.html [ Failure ] +crbug.com/954328 images/color-profile-image-profile-match.html [ Failure ] +crbug.com/954328 images/color-profile-image.html [ Failure ] +crbug.com/954328 images/color-profile-layer-filter.html [ Failure ] +crbug.com/954328 images/color-profile-mask-image-svg.html [ Failure ] +crbug.com/954328 images/color-profile-object.html [ Failure ] +crbug.com/954328 images/color-profile-svg-fill-text.html [ Failure ] +crbug.com/954328 images/color-profile-svg.html [ Failure ] +crbug.com/954328 images/optimize-contrast-canvas.html [ Failure ] +crbug.com/954328 images/optimize-contrast-image.html [ Failure ] +crbug.com/954328 images/webp-color-profile-lossy.html [ Failure ]
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests index ea4b31a..662a5ef 100644 --- a/third_party/blink/web_tests/NeverFixTests +++ b/third_party/blink/web_tests/NeverFixTests
@@ -2272,3 +2272,4 @@ external/wpt/web-share/share-image-manual.html [ WontFix ] external/wpt/uievents/order-of-events/mouse-events/wheel-basic-manual.html [ WontFix ] external/wpt/uievents/order-of-events/mouse-events/wheel-scrolling-manual.html [ WontFix ] +external/wpt/html/webappapis/user-prompts/print-manual.html [ WontFix ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 0decafd..4b3244df 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -2689,6 +2689,7 @@ 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. @@ -6228,8 +6229,6 @@ # Sheriff 2019-06-26 crbug.com/978966 [ Mac ] paint/markers/ellipsis-mixed-text-in-ltr-flow-with-markers.html [ Pass Failure ] -crbug.com/979253 external/wpt/css/css-pseudo/first-line-with-out-of-flow.html [ Failure ] - # Sheriff 2019-06-27 crbug.com/979193 [ Mac ] paint/invalidation/svg/relative-sized-use-on-symbol.xhtml [ Pass Failure ] crbug.com/979193 [ Mac ] paint/invalidation/svg/remove-background-property-on-root.html [ Pass Failure ]
diff --git a/third_party/blink/web_tests/compositing/layer-creation/fixed-position-out-of-view-scaled-iframe-scroll.html b/third_party/blink/web_tests/compositing/layer-creation/fixed-position-out-of-view-scaled-iframe-scroll.html index c253bd9..7a3d821 100644 --- a/third_party/blink/web_tests/compositing/layer-creation/fixed-position-out-of-view-scaled-iframe-scroll.html +++ b/third_party/blink/web_tests/compositing/layer-creation/fixed-position-out-of-view-scaled-iframe-scroll.html
@@ -13,14 +13,18 @@ addEventListener("load", function() { internals.setPageScaleFactor(0.5); setTimeout(function() { - var layerTreeScaledDown = internals.layerTreeAsText(document.getElementById("iframe").contentDocument); + var layerTreeScaledDown = JSON.stringify( + JSON.parse(internals.layerTreeAsText(document.getElementById("iframe").contentDocument)).layers); internals.setPageScaleFactor(1.5); setTimeout(function() { - var layerTreeScaledUp = internals.layerTreeAsText(document.getElementById("iframe").contentDocument); + var layerTreeScaledUp = JSON.stringify( + JSON.parse(internals.layerTreeAsText(document.getElementById("iframe").contentDocument)).layers); // Because logical size of the frame is unchanged, the layer tree in the frame should not be affected by the page scale. document.getElementById("result").innerText = - layerTreeScaledUp == layerTreeScaledDown ? "PASS" : "FAIL"; + layerTreeScaledUp == layerTreeScaledDown + ? "PASS" + : "FAIL\nScale 0.5:\n" + layerTreeScaledDown + "\nScale 1.5:\n" + layerTreeScaledUp; testRunner.notifyDone(); }, 0); }, 0);
diff --git a/third_party/blink/web_tests/compositing/layer-creation/fixed-position-out-of-view-scaled-iframe.html b/third_party/blink/web_tests/compositing/layer-creation/fixed-position-out-of-view-scaled-iframe.html index 76d6819..a4c84bf 100644 --- a/third_party/blink/web_tests/compositing/layer-creation/fixed-position-out-of-view-scaled-iframe.html +++ b/third_party/blink/web_tests/compositing/layer-creation/fixed-position-out-of-view-scaled-iframe.html
@@ -13,14 +13,18 @@ addEventListener("load", function() { internals.setPageScaleFactor(0.5); setTimeout(function() { - var layerTreeScaledDown = internals.layerTreeAsText(document.getElementById("iframe").contentDocument); + var layerTreeScaledDown = JSON.stringify( + JSON.parse(internals.layerTreeAsText(document.getElementById("iframe").contentDocument)).layers); internals.setPageScaleFactor(1.5); setTimeout(function() { - var layerTreeScaledUp = internals.layerTreeAsText(document.getElementById("iframe").contentDocument); + var layerTreeScaledUp = JSON.stringify( + JSON.parse(internals.layerTreeAsText(document.getElementById("iframe").contentDocument)).layers); // Because logical size of the frame is unchanged, the layer tree in the frame should not be affected by the page scale. document.getElementById("result").innerText = - layerTreeScaledUp == layerTreeScaledDown ? "PASS" : "FAIL"; + layerTreeScaledUp == layerTreeScaledDown + ? "PASS" + : "FAIL\nScale 0.5:\n" + layerTreeScaledDown + "\nScale 1.5:\n" + layerTreeScaledUp; testRunner.notifyDone(); }, 0); }, 0);
diff --git a/third_party/blink/web_tests/css3/filters/backdrop-filter-browser-zoom-expected.png b/third_party/blink/web_tests/css3/filters/backdrop-filter-browser-zoom-expected.png index 66a21ab..d57edd36 100644 --- a/third_party/blink/web_tests/css3/filters/backdrop-filter-browser-zoom-expected.png +++ b/third_party/blink/web_tests/css3/filters/backdrop-filter-browser-zoom-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/css3/filters/backdrop-filter-clip-radius-zoom-expected.png b/third_party/blink/web_tests/css3/filters/backdrop-filter-clip-radius-zoom-expected.png new file mode 100644 index 0000000..6e558e6 --- /dev/null +++ b/third_party/blink/web_tests/css3/filters/backdrop-filter-clip-radius-zoom-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/css3/filters/backdrop-filter-clip-radius-zoom.html b/third_party/blink/web_tests/css3/filters/backdrop-filter-clip-radius-zoom.html new file mode 100644 index 0000000..7cd3464 --- /dev/null +++ b/third_party/blink/web_tests/css3/filters/backdrop-filter-clip-radius-zoom.html
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<title>Backdrop filter clipping radius with zoom</title> +<link rel="author" title="Mason Freed" href="mailto:masonfreed@chromium.org"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects-2/#BackdropFilterProperty"> + +<!--You should see two completely filled black rectangles with rounded corners.--> + +<!-- TODO(978481): Convert this back to WPT test. See crbug.com/978481 for + an implementation in WPT that is waiting for the WPT Fuzzy Matching feature. +--> + +<div id='rect1'></div> +<div id='rect2'></div> + +<style> +body { + zoom: 5; +} +div { + width: 100px; + height: 20px; + backdrop-filter: invert(1); + border: 2px dashed green; +} +#rect1 { + border-radius: 20px / 5px; +} +#rect2 { + position: relative; + top:5px; + border-radius: 4px; +} +p { + font-size: 0.2em; +} +</style>
diff --git a/third_party/blink/web_tests/css3/filters/backdrop-filter-clip-rect-zoom-expected.png b/third_party/blink/web_tests/css3/filters/backdrop-filter-clip-rect-zoom-expected.png index da57311..0a9456d 100644 --- a/third_party/blink/web_tests/css3/filters/backdrop-filter-clip-rect-zoom-expected.png +++ b/third_party/blink/web_tests/css3/filters/backdrop-filter-clip-rect-zoom-expected.png Binary files differ
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 7c18709..d4ae383c 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
@@ -5923,6 +5923,12 @@ {} ] ], + "html/webappapis/user-prompts/print-manual.html": [ + [ + "html/webappapis/user-prompts/print-manual.html", + {} + ] + ], "input-events/input-events-cut-paste-manual.html": [ [ "input-events/input-events-cut-paste-manual.html", @@ -36181,6 +36187,18 @@ {} ] ], + "css/css-break/fieldset.html": [ + [ + "css/css-break/fieldset.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], "css/css-break/floats-and-text-narrow-and-short-dynamic.html": [ [ "css/css-break/floats-and-text-narrow-and-short-dynamic.html", @@ -59183,6 +59201,18 @@ {} ] ], + "css/css-position/position-absolute-fieldset.html": [ + [ + "css/css-position/position-absolute-fieldset.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], "css/css-position/position-relative-table-tbody-left-absolute-child.html": [ [ "css/css-position/position-relative-table-tbody-left-absolute-child.html", @@ -60095,54 +60125,6 @@ {} ] ], - "css/css-pseudo/first-line-change-inline-color-nested.html": [ - [ - "css/css-pseudo/first-line-change-inline-color-nested.html", - [ - [ - "/css/css-pseudo/first-line-change-inline-color-nested-ref.html", - "==" - ] - ], - {} - ] - ], - "css/css-pseudo/first-line-change-inline-color.html": [ - [ - "css/css-pseudo/first-line-change-inline-color.html", - [ - [ - "/css/css-pseudo/first-line-change-inline-color-ref.html", - "==" - ] - ], - {} - ] - ], - "css/css-pseudo/first-line-on-ancestor-block.html": [ - [ - "css/css-pseudo/first-line-on-ancestor-block.html", - [ - [ - "/css/css-pseudo/first-line-on-ancestor-block-ref.html", - "==" - ] - ], - {} - ] - ], - "css/css-pseudo/first-line-with-out-of-flow.html": [ - [ - "css/css-pseudo/first-line-with-out-of-flow.html", - [ - [ - "/css/css-pseudo/first-line-with-out-of-flow-ref.html", - "==" - ] - ], - {} - ] - ], "css/css-pseudo/marker-and-other-pseudo-elements.html": [ [ "css/css-pseudo/marker-and-other-pseudo-elements.html", @@ -62687,6 +62669,18 @@ {} ] ], + "css/css-sizing/auto-scrollbar-inside-stf-abspos.html": [ + [ + "css/css-sizing/auto-scrollbar-inside-stf-abspos.html", + [ + [ + "/css/css-sizing/auto-scrollbar-inside-stf-abspos-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-sizing/block-image-percentage-max-height-inside-inline.html": [ [ "css/css-sizing/block-image-percentage-max-height-inside-inline.html", @@ -124322,6 +124316,12 @@ "content-security-policy/reporting/report-only-in-meta.sub.html.sub.headers": [ [] ], + "content-security-policy/reporting/report-only-unsafe-eval-expected.txt": [ + [] + ], + "content-security-policy/reporting/report-only-unsafe-eval.html.sub.headers": [ + [] + ], "content-security-policy/reporting/report-original-url.sub.html.sub.headers": [ [] ], @@ -138680,18 +138680,6 @@ "css/css-pseudo/first-line-and-placeholder-ref.html": [ [] ], - "css/css-pseudo/first-line-change-inline-color-nested-ref.html": [ - [] - ], - "css/css-pseudo/first-line-change-inline-color-ref.html": [ - [] - ], - "css/css-pseudo/first-line-on-ancestor-block-ref.html": [ - [] - ], - "css/css-pseudo/first-line-with-out-of-flow-ref.html": [ - [] - ], "css/css-pseudo/idlharness-expected.txt": [ [] ], @@ -139259,6 +139247,9 @@ "css/css-sizing/META.yml": [ [] ], + "css/css-sizing/auto-scrollbar-inside-stf-abspos-ref.html": [ + [] + ], "css/css-sizing/clone-intrinsic-size-ref.html": [ [] ], @@ -171923,9 +171914,6 @@ "wake-lock/OWNERS": [ [] ], - "wake-lock/idlharness.https.any-expected.txt": [ - [] - ], "wake-lock/idlharness.https.any.worker-expected.txt": [ [] ], @@ -194818,6 +194806,12 @@ } ] ], + "content-security-policy/reporting/report-only-unsafe-eval.html": [ + [ + "content-security-policy/reporting/report-only-unsafe-eval.html", + {} + ] + ], "content-security-policy/reporting/report-original-url.sub.html": [ [ "content-security-policy/reporting/report-original-url.sub.html", @@ -246592,6 +246586,12 @@ } ] ], + "largest-contentful-paint/cross-origin-image.sub.html": [ + [ + "largest-contentful-paint/cross-origin-image.sub.html", + {} + ] + ], "largest-contentful-paint/observe-image.html": [ [ "largest-contentful-paint/observe-image.html", @@ -284192,6 +284192,12 @@ {} ] ], + "trusted-types/block-eval.tentative.html": [ + [ + "trusted-types/block-eval.tentative.html", + {} + ] + ], "trusted-types/block-string-assignment-to-DOMParser-parseFromString.tentative.html": [ [ "trusted-types/block-string-assignment-to-DOMParser-parseFromString.tentative.html", @@ -284276,6 +284282,12 @@ {} ] ], + "trusted-types/eval-with-permissive-csp.tentative.html": [ + [ + "trusted-types/eval-with-permissive-csp.tentative.html", + {} + ] + ], "trusted-types/idlharness.window.js": [ [ "trusted-types/idlharness.window.html", @@ -320271,6 +320283,18 @@ "b56292b4703acaee09b6dfb7b0f1bb674b788207", "support" ], + "content-security-policy/reporting/report-only-unsafe-eval-expected.txt": [ + "c519bb48381748380014ee7c974b535aef9db1a2", + "support" + ], + "content-security-policy/reporting/report-only-unsafe-eval.html": [ + "ebaf6941a898e88a96ec61e8742fd63375811c27", + "testharness" + ], + "content-security-policy/reporting/report-only-unsafe-eval.html.sub.headers": [ + "549f3dbaa2e302777799d14c5ca1eb13a83493bf", + "support" + ], "content-security-policy/reporting/report-original-url.sub.html": [ "45c1aeb2de86e64ec7de51bf0898c85f42d13320", "testharness" @@ -343343,6 +343367,10 @@ "fb80ec45bceec093481fa54513c606c5952628b1", "testharness" ], + "css/css-break/fieldset.html": [ + "fe76988293b8d1d9a6226b23bb9b40e86fcc007a", + "reftest" + ], "css/css-break/floats-and-text-narrow-and-short-dynamic-ref.html": [ "51855d2d7a724d44f44c1585708851fd62242fbe", "support" @@ -344636,7 +344664,7 @@ "reftest" ], "css/css-conditional/idlharness-expected.txt": [ - "aa36ecb31338f12757bca6247de65a1488070c1a", + "bf46c15032c38cc21c3a6a50ca31e6edb1fff12b", "support" ], "css/css-conditional/idlharness.html": [ @@ -350856,7 +350884,7 @@ "support" ], "css/css-fonts/math-script-level-and-math-style/math-script-level-001.tentative.html": [ - "8856b2b14a910c34b04586123098896834bbd83b", + "6a353a635b82d89fb6a933aad2d7554059aa3da2", "testharness" ], "css/css-fonts/math-script-level-and-math-style/math-script-level-002.tentative-expected.txt": [ @@ -350864,7 +350892,7 @@ "support" ], "css/css-fonts/math-script-level-and-math-style/math-script-level-002.tentative.html": [ - "b3f56fefad7a5f242b7daafc96ff6723f328c8e1", + "0abce02e72d3687023a232d7398cd014aa0633f7", "testharness" ], "css/css-fonts/math-script-level-and-math-style/math-script-level-003.tentative-ref.html": [ @@ -350872,7 +350900,7 @@ "support" ], "css/css-fonts/math-script-level-and-math-style/math-script-level-003.tentative.html": [ - "501001243740a142ac8cad12a78b48caaa056be5", + "f5bf9982e27f0fde970761d0506eff7f5b6ec741", "reftest" ], "css/css-fonts/math-script-level-and-math-style/math-script-level-004.tentative-expected.txt": [ @@ -350880,7 +350908,7 @@ "support" ], "css/css-fonts/math-script-level-and-math-style/math-script-level-004.tentative.html": [ - "6fe35c2719e4e460e0c88f261ba3f5185a5f062d", + "cb82472a0c0af76af8174eaea43e1ab3e6346fd9", "testharness" ], "css/css-fonts/math-script-level-and-math-style/math-script-level-005.tentative-ref.html": [ @@ -350888,7 +350916,7 @@ "support" ], "css/css-fonts/math-script-level-and-math-style/math-script-level-005.tentative.html": [ - "7f289ffcd81daaf0fed81b4c02e7417ee75a7e18", + "34860d7a5c2734d08984ddd061520320aeaa46e1", "reftest" ], "css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-001.tentative-ref.html": [ @@ -350896,7 +350924,7 @@ "support" ], "css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-001.tentative.html": [ - "0765630fac3376b305504304c61aac1b1123663d", + "ad187b5dc254e672a66eedb2ae219ddf953156a6", "reftest" ], "css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-002.tentative-ref.html": [ @@ -350904,7 +350932,7 @@ "support" ], "css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-002.tentative.html": [ - "baff728800dad0002b663e85d26cfb8c6a2bb811", + "c111f2c38d5d0f5c614f125bde292c73727f754a", "reftest" ], "css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-003.tentative-ref.html": [ @@ -350912,7 +350940,7 @@ "support" ], "css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-003.tentative.html": [ - "827dbd41be42199c2d7ebc6e042e2d75b8dd9b50", + "4282481761207d8a947ddb8f462a9a2cd555ede8", "reftest" ], "css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-004.tentative-ref.html": [ @@ -350920,7 +350948,7 @@ "support" ], "css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-004.tentative.html": [ - "8917d68be11a55f373bd08918ae047b775f56b80", + "150d4285e9802beabe7b677c96465ba261633b1c", "reftest" ], "css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-005.tentative-ref.html": [ @@ -350928,7 +350956,7 @@ "support" ], "css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-005.tentative.html": [ - "90c09d50ffe3cbcf90218f612da077f87a9b8e34", + "718a564070d9b5c91023b1c3c054f6380527cbde", "reftest" ], "css/css-fonts/math-script-level-and-math-style/math-script-level-font-size-clamping-001.tentative-ref.html": [ @@ -350936,11 +350964,11 @@ "support" ], "css/css-fonts/math-script-level-and-math-style/math-script-level-font-size-clamping-001.tentative.html": [ - "6a70cf33a8b16e57ddf2e8acb3d87e10ecfbe6e6", + "e25ee56c3e334d83158149528193fb7ee734df81", "reftest" ], "css/css-fonts/math-script-level-and-math-style/math-style-001.tentative.html": [ - "6df35170255c62bf391ce77b9629802c8969fa9b", + "56cb1eca09d7741275df03ea217e2b31acb04371", "testharness" ], "css/css-fonts/quoted-generic-ignored-ref.html": [ @@ -365943,6 +365971,10 @@ "35d5f65055d09b377e55a7d3e5dcaf8d3b609a39", "reftest" ], + "css/css-position/position-absolute-fieldset.html": [ + "b212e627ae13dc32080936512a85d72367d3dad3", + "reftest" + ], "css/css-position/position-absolute-in-inline-001.html": [ "204260ee6784c9e648ab9f1e86b113f0d7227e22", "testharness" @@ -366611,42 +366643,10 @@ "2db3480feb5928c6a39fbf6084cf07bec0ba4767", "reftest" ], - "css/css-pseudo/first-line-change-inline-color-nested-ref.html": [ - "84becd9a78d186ba3c0e658746fd56aef8039b74", - "support" - ], - "css/css-pseudo/first-line-change-inline-color-nested.html": [ - "4a58f1ea5b623ffa5acd2993be16de399cd24127", - "reftest" - ], - "css/css-pseudo/first-line-change-inline-color-ref.html": [ - "84becd9a78d186ba3c0e658746fd56aef8039b74", - "support" - ], - "css/css-pseudo/first-line-change-inline-color.html": [ - "2a5be916b01d5d12eec1a4e81d912d95c7036916", - "reftest" - ], "css/css-pseudo/first-line-first-letter-insert-crash.html": [ "17f035dedf1ef8df71918a1eacb01e1f0b80d46b", "testharness" ], - "css/css-pseudo/first-line-on-ancestor-block-ref.html": [ - "7193bf25eb88c5443457480f7ce27782acd9473a", - "support" - ], - "css/css-pseudo/first-line-on-ancestor-block.html": [ - "6b797107df80156b511b9dc58c5ee40d6114cfc4", - "reftest" - ], - "css/css-pseudo/first-line-with-out-of-flow-ref.html": [ - "7193bf25eb88c5443457480f7ce27782acd9473a", - "support" - ], - "css/css-pseudo/first-line-with-out-of-flow.html": [ - "798ecf8264e2ddb38257c6cb1174bcc069c6e6d1", - "reftest" - ], "css/css-pseudo/idlharness-expected.txt": [ "977415282ae39a096e46008e91d55452f5244b02", "support" @@ -369191,6 +369191,14 @@ "0dbbb2f9404da7cfa89f2e75af3ca06cfbe4be7e", "testharness" ], + "css/css-sizing/auto-scrollbar-inside-stf-abspos-ref.html": [ + "076893b2728772662f06b9474bcc1918c860b480", + "support" + ], + "css/css-sizing/auto-scrollbar-inside-stf-abspos.html": [ + "9479b2eb3f51aed98741beadff4a8407b3ae9f33", + "reftest" + ], "css/css-sizing/block-image-percentage-max-height-inside-inline.html": [ "2f6ad684c1fb0be5498dc6a5b938da67adfe3ec7", "reftest" @@ -409004,7 +409012,7 @@ "testharness" ], "element-timing/buffer-before-onload.html": [ - "88a641bbb666816da9a636ed43d23c205bf0e8f9", + "68eeeefe15fdc587cdf0d4382f90c33ee3230290", "testharness" ], "element-timing/cross-origin-element.sub.html": [ @@ -411368,7 +411376,7 @@ "support" ], "event-timing/bufferbeforeonload.html": [ - "c91546ae41a499635573a2f7d7ea20b0283ca21f", + "c30c01aa96bb9bc835bb1ce93bff86f5e99789d7", "testharness" ], "event-timing/crossiframe.html": [ @@ -411388,15 +411396,15 @@ "manual" ], "event-timing/observethenonload.html": [ - "e1c36e302108b1bd886130c7df38d8e536dc4473", + "4145eae0a59a5da2fc5fbca95ee2721fc3b58b2b", "testharness" ], "event-timing/onloadthenobserve-firstInput.html": [ - "1422ceaa95582200ba1250dcdd53aec502b59856", + "4efdfbbf006cdd8577b4d11b668974bfe20aaa84", "testharness" ], "event-timing/onloadthenobserve.html": [ - "e2f9c932e6f5122af68ff84fd9495cf6fc216314", + "d97228577a187ddf10f5513697d9b0424aab4588", "testharness" ], "event-timing/only-observe-firstInput.html": [ @@ -411408,7 +411416,7 @@ "testharness" ], "event-timing/resources/crossiframe-childframe.html": [ - "7aa4ace73afad7878205736c02a81e863127bb43", + "ee9da6cad5411b477c3c11d6fc932ef132855bf7", "support" ], "event-timing/resources/event-timing-test-utils.js": [ @@ -435647,6 +435655,10 @@ "55cb5ce527ea69fa23e6aba675719bb6524d7411", "manual" ], + "html/webappapis/user-prompts/print-manual.html": [ + "3afef1d4fef99b589d060ea6742331f454325be7", + "manual" + ], "idle-detection/META.yml": [ "7e5836bc3701366fba535a67a0ffc4032776b104", "support" @@ -437679,12 +437691,16 @@ "bbdc7aee84437ebd0e029556dd1d1fcb9670dc5d", "testharness" ], + "largest-contentful-paint/cross-origin-image.sub.html": [ + "3716f9319227c0f5bdfbcf17a21a718cf7dd72e8", + "testharness" + ], "largest-contentful-paint/observe-image.html": [ - "43cdfab074d62827fca5e55b8b334b9fafb6507b", + "8adf2150afcc74082d173f06f6aa929c33a52b87", "testharness" ], "largest-contentful-paint/observe-text.html": [ - "77ed06e2aa1fb99d1199b9e3b6e99620037ef959", + "a9a0d750d66712eaf72fca9897d84794ae44c35d", "testharness" ], "layout-instability/buffer-layout-shift.html": [ @@ -437972,7 +437988,7 @@ "support" ], "mathml/presentation-markup/direction/direction-overall.html": [ - "7f377e540f4388088a401fb6995947d488d3f76f", + "5351ca51688d51b2e399a296d52e1b23543a0c96", "reftest" ], "mathml/presentation-markup/direction/direction-token-ref.html": [ @@ -437980,15 +437996,15 @@ "support" ], "mathml/presentation-markup/direction/direction-token.html": [ - "a02793cc84ac61c814b6f884869ae8a920a2b748", + "1896f3fe394d6a31f6f6aaff79f6bfc3d647c462", "reftest" ], "mathml/presentation-markup/direction/direction.html": [ - "05ea8b74fb5fcdeb994cfc6d80dc88d2cd8ccde4", + "11d0515d7194050701cb82a12e96237d800ef741", "testharness" ], "mathml/presentation-markup/fractions/frac-1.html": [ - "6b9fb2844298cbc228f91a23c6439e0f67f4f20b", + "6be38d5439da9181ee53464abcf22863a9d176ce", "testharness" ], "mathml/presentation-markup/fractions/frac-bar-001-ref.html": [ @@ -437996,7 +438012,7 @@ "support" ], "mathml/presentation-markup/fractions/frac-bar-001.html": [ - "d6151f62190768776e1a85b4c9b9bc6a8c0a69a6", + "887ff174cc40c9b06303d22e08cef59e9b72f382", "reftest" ], "mathml/presentation-markup/fractions/frac-color-001-notref.html": [ @@ -438004,7 +438020,7 @@ "support" ], "mathml/presentation-markup/fractions/frac-color-001.html": [ - "d1a3e6eac41ff23190225954016b7b37a8e71880", + "d0674c6c88afb875b2bf199c0931005acf34eba8", "reftest" ], "mathml/presentation-markup/fractions/frac-color-002-ref.html": [ @@ -438012,7 +438028,7 @@ "support" ], "mathml/presentation-markup/fractions/frac-color-002.html": [ - "597acab652c4ad9b94ec5c612b4fda53c422309c", + "4b45c8e1cfb7b4bb775832c03e5e692c22f19f90", "reftest" ], "mathml/presentation-markup/fractions/frac-created-dynamically-2-ref.html": [ @@ -438020,7 +438036,7 @@ "support" ], "mathml/presentation-markup/fractions/frac-created-dynamically-2.html": [ - "a9707071a0624c7701cef46ff7e3746fb3feeb00", + "2aa9675bb1f170640088a1071687890ee715523a", "reftest" ], "mathml/presentation-markup/fractions/frac-created-dynamically-3-ref.html": [ @@ -438028,7 +438044,7 @@ "support" ], "mathml/presentation-markup/fractions/frac-created-dynamically-3.html": [ - "cec71163c392ebc6891339f8f1d80bad8c3f2596", + "c90119d8ef5f5282331c94ae1c57a9a3c8284f9d", "reftest" ], "mathml/presentation-markup/fractions/frac-created-dynamically-ref.html": [ @@ -438036,7 +438052,7 @@ "support" ], "mathml/presentation-markup/fractions/frac-created-dynamically.html": [ - "3224eb4eaf188c32d6152339d86a87aa03cfa62e", + "7a555f20ea370b918bca2c64d5381cbab625732b", "reftest" ], "mathml/presentation-markup/fractions/frac-linethickness-001-ref.html": [ @@ -438044,7 +438060,7 @@ "support" ], "mathml/presentation-markup/fractions/frac-linethickness-001.html": [ - "eca82878caec21ea50ed0d3562ac3449e54c7567", + "4d6bda2c1670d9e615c7c3ffbc3891b90a22ecd4", "reftest" ], "mathml/presentation-markup/fractions/frac-linethickness-002-ref.html": [ @@ -438052,7 +438068,7 @@ "support" ], "mathml/presentation-markup/fractions/frac-linethickness-002.html": [ - "fd45994646938e4d22765524382004f19ef021b7", + "ce122f710160a71ac4eb7c9c7436447b7a4dd504", "reftest" ], "mathml/presentation-markup/fractions/frac-linethickness-003-notref.html": [ @@ -438060,7 +438076,7 @@ "support" ], "mathml/presentation-markup/fractions/frac-linethickness-003.html": [ - "b23cce80be40dd53ff898a5bc7d2246ae3770322", + "c9fa0f381749174ea1ac3222462574cb6232d95c", "reftest" ], "mathml/presentation-markup/fractions/frac-linethickness-004-ref.html": [ @@ -438068,7 +438084,7 @@ "support" ], "mathml/presentation-markup/fractions/frac-linethickness-004.html": [ - "ff96a3d753e226dcd2ecfa44808804f71ce02c45", + "d9689fcdc6813382d92ced5c5941181a47110b2c", "reftest" ], "mathml/presentation-markup/fractions/frac-mrow-001-ref.html": [ @@ -438076,7 +438092,7 @@ "support" ], "mathml/presentation-markup/fractions/frac-mrow-001.html": [ - "14476450008531dba09da4677b60ba65262dca0a", + "cb154c65edc38103a6ebc47b5fc9f1466655abb1", "reftest" ], "mathml/presentation-markup/fractions/frac-numalign-denomalign-001-ref.html": [ @@ -438084,15 +438100,15 @@ "support" ], "mathml/presentation-markup/fractions/frac-numalign-denomalign-001.html": [ - "d734f1d1f33922d5d29daa81d2ba7b1075415b23", + "59d663f6a4e455b2e66a1d22a6a141a7edc9a132", "reftest" ], "mathml/presentation-markup/fractions/frac-parameters-1.html": [ - "59e335ae5a3df081e300705d6e5d020924af7bef", + "55404fa562c4dd304eb84702bee4578d02ae7925", "testharness" ], "mathml/presentation-markup/fractions/frac-parameters-2.html": [ - "b1ee502ccdae6cf96d2f104d7daf1c2dbba390f7", + "63ab97760fc03161b9b3c63d09819463131864ad", "testharness" ], "mathml/presentation-markup/fractions/frac-parameters-gap-001-ref.html": [ @@ -438148,19 +438164,19 @@ "support" ], "mathml/presentation-markup/fractions/frac-visibility-001.html": [ - "8fbf5ac806e61e400214b2157180e8aac4fd2d31", + "65b95054db46339159fc6e0f8438144b02b19a09", "reftest" ], "mathml/presentation-markup/mrow/inferred-mrow-baseline.html": [ - "0904d9f17ed2ed1e5af5134ea1ccfcb17674581b", + "672d90de93363331a418f33ecac8f2380bd5fb5f", "testharness" ], "mathml/presentation-markup/mrow/inferred-mrow-stretchy.html": [ - "f75726c11d09d488e81041f4da79e30edc752895", + "75587d076c2790608133b7a81558a42dc2581cff", "testharness" ], "mathml/presentation-markup/operators/mo-axis-height-1.html": [ - "c88484b9d59a7811f6cfde7065de4facbdf1f74a", + "63595b0278445db92e3e5bfe8b7cfb03fd9bdc6e", "testharness" ], "mathml/presentation-markup/operators/mo-form-dynamic-ref.html": [ @@ -438168,7 +438184,7 @@ "support" ], "mathml/presentation-markup/operators/mo-form-dynamic.html": [ - "dcd1ec53c31efb2435415e372786e7a1fae15775", + "fff3bd9ff336f52b7abb5efdf4b1fb767518ace7", "reftest" ], "mathml/presentation-markup/operators/mo-form-fallback-ref.html": [ @@ -438176,7 +438192,7 @@ "support" ], "mathml/presentation-markup/operators/mo-form-fallback.html": [ - "aab62087b595a5f784c0b98e6a6cd0e419ac3a17", + "b517dd574688fa0ab50dff4a120507de4a9797bf", "reftest" ], "mathml/presentation-markup/operators/mo-form-minus-plus-ref.html": [ @@ -438184,7 +438200,7 @@ "support" ], "mathml/presentation-markup/operators/mo-form-minus-plus.html": [ - "8a4ac3d737315cca5c2ad19a95e60146bd633cf1", + "487bca25eaa61d6fb0a110124e962e48fe55dd20", "reftest" ], "mathml/presentation-markup/operators/mo-form-ref.html": [ @@ -438192,7 +438208,7 @@ "support" ], "mathml/presentation-markup/operators/mo-form.html": [ - "7c11c14691162b69c1a2e854734ae6ac37db10e2", + "4f651d1c9b7ce43dd9e159793b630aa3c44b69af", "reftest" ], "mathml/presentation-markup/operators/mo-movablelimits-default-ref.html": [ @@ -438200,7 +438216,7 @@ "support" ], "mathml/presentation-markup/operators/mo-movablelimits-default.html": [ - "cd01fe47682ff1be6a09551589875088476f22c4", + "a05bef47ee76914d190af18141c966a4c3e12ef7", "reftest" ], "mathml/presentation-markup/operators/mo-movablelimits-dynamic-ref.html": [ @@ -438208,7 +438224,7 @@ "support" ], "mathml/presentation-markup/operators/mo-movablelimits-dynamic.html": [ - "a92c6c01dc9da3aed4012843eb156b36f877d050", + "53cf76c0588ff2dd664b3fb9e622c7e30b5c6eb7", "reftest" ], "mathml/presentation-markup/operators/mo-movablelimits-ref.html": [ @@ -438216,7 +438232,7 @@ "support" ], "mathml/presentation-markup/operators/mo-movablelimits.html": [ - "0855594100b2b5cac13fb464108bf130288c0e32", + "9be866fabee972bfa1608e2c2e2e64c439c07eea", "reftest" ], "mathml/presentation-markup/operators/mo-paint-lspace-rspace-ref.html": [ @@ -438224,59 +438240,59 @@ "support" ], "mathml/presentation-markup/operators/mo-paint-lspace-rspace.html": [ - "879962c4776181b6bb505d1e0072b5f5e58b667e", + "8fb095b61240d93caa3289f68fe52c37069f14c9", "reftest" ], "mathml/presentation-markup/radicals/root-parameters-1.html": [ - "51d4713d4ea1c429e018c6a0914b130bc6dc1cd5", + "5ad0b7315e02b9d893937a376b0545ff7bb0eada", "testharness" ], "mathml/presentation-markup/scripts/subsup-1.html": [ - "447aa66d4a30bc68f69fc17f91b08723229b14ff", + "01a6b0e1ed1fed2d069ac2b8b3e3716ffeee08b7", "testharness" ], "mathml/presentation-markup/scripts/subsup-2.html": [ - "9e2b6dbef79089fe4c37ddbf6cbbdc4e7a3f1d36", + "2fd6963b6a7906aaeabd17a16a53a9ebbe56116f", "testharness" ], "mathml/presentation-markup/scripts/subsup-3.html": [ - "742fa8cbce6463bcc2bb48bcdd98df488d1c086f", + "60df24a799027c0704be4622976ea8e2ae2a3d22", "testharness" ], "mathml/presentation-markup/scripts/subsup-4.html": [ - "fc70fef9b801f41a32913ba4362927bedb94d0ef", + "6886766097cecff350ddcf3ce81bb87e70b4ce28", "testharness" ], "mathml/presentation-markup/scripts/subsup-5.html": [ - "a67d68d5e031c1a8b31df877b213d255f002b935", + "2cc4e6d9554a1f6fde6c16e37fec2a39c441a0e8", "testharness" ], "mathml/presentation-markup/scripts/subsup-parameters-1.html": [ - "208a0a870d6e61e3c7530fc620e650e00ca740da", + "7503ad166af33745701ab379cf51fd5cda8ce7dc", "testharness" ], "mathml/presentation-markup/scripts/subsup-parameters-2.html": [ - "4a9db6618bcc1fa9fd459d9b0aa70f347bc62184", + "62aa7a9dc3be90a343dbcb4810e5cb479707be2e", "testharness" ], "mathml/presentation-markup/scripts/underover-1.html": [ - "45367e3541b285bcc6256193ab7cd544baf422f3", + "b17835528a0ed8d78d643ef9f24dd7822b62f559", "testharness" ], "mathml/presentation-markup/scripts/underover-parameters-1.html": [ - "cc09abb899ad629fb959aef9fc84f093ad0a6f76", + "d8a564a1159518195e889694aee8d0b167efec91", "testharness" ], "mathml/presentation-markup/scripts/underover-parameters-2.html": [ - "d6d9185cc961c0d6d7e52825563b30c622f015a2", + "c10f77ee2c807b8a24566574f6ff6377736ae514", "testharness" ], "mathml/presentation-markup/scripts/underover-parameters-3.html": [ - "23c7dfa744550ecf4032350fdf902f28863dac57", + "86562fd374bdb44983657954f5b554ae62db8984", "testharness" ], "mathml/presentation-markup/scripts/underover-parameters-4.html": [ - "bfc3cafa913fb38dde5cecf83be0a4a710bfb763", + "f7fb389b59feb23276773a91b854fd6ab105fc15", "testharness" ], "mathml/presentation-markup/spaces/mspace-children-ref.html": [ @@ -438284,11 +438300,11 @@ "support" ], "mathml/presentation-markup/spaces/mspace-children.html": [ - "90d524ab418ed8c141da037eba9334c83fb5cced", + "8824c7967041dae2eb3d2943c79c4afff339ffb3", "reftest" ], "mathml/presentation-markup/spaces/space-1.html": [ - "7bc5b8e5128d031c14d73b53939926a63265b3c9", + "53734deeee1126d83ee83fd4d5d8d37af4d6d6c9", "testharness" ], "mathml/presentation-markup/spaces/space-2-ref.html": [ @@ -438296,11 +438312,11 @@ "support" ], "mathml/presentation-markup/spaces/space-2.html": [ - "5b8351a1ed00d29e43d71e1f293fe63b1a0c2dc4", + "d7b38458998c7d4d96adf3f31ccaca9d9886469f", "reftest" ], "mathml/presentation-markup/tables/table-axis-height.html": [ - "e723008b410342b087a0f066980f8520e55c4ccc", + "feb29077e8e34bcd3155f0661f4878bb93bdbf19", "testharness" ], "mathml/relations/css-styling/color-1-ref.html": [ @@ -438308,7 +438324,7 @@ "support" ], "mathml/relations/css-styling/color-1.html": [ - "8158cec6a86475d98042df02e8e89928516184d3", + "4d9d084a5a6b6414e01d4f4693237b4544e1ad48", "reftest" ], "mathml/relations/css-styling/display-1-ref.html": [ @@ -438316,11 +438332,11 @@ "support" ], "mathml/relations/css-styling/display-1.html": [ - "9ae6fe0b84f4d7b145b7fef0ed16168c3f4a74dd", + "38dd0bafdf84e5e20cfc904bc9b9f2a219a6b8ff", "reftest" ], "mathml/relations/css-styling/displaystyle-1.html": [ - "ddb2173a2e01ff78b16bc9c86f4a0f2ad37935dc", + "c2ccb78dc9f49ed5dceb10a4a1f6eccf19ad3902", "testharness" ], "mathml/relations/css-styling/dynamic-dir-1-ref.html": [ @@ -438328,7 +438344,7 @@ "support" ], "mathml/relations/css-styling/dynamic-dir-1.html": [ - "c4c99d878c19305d02d0ed450e46da66802c0746", + "3667ece8c53ccdb4747794ff48dde79f5c405629", "reftest" ], "mathml/relations/css-styling/lengths-1-ref.html": [ @@ -438336,11 +438352,11 @@ "support" ], "mathml/relations/css-styling/lengths-1.html": [ - "30916d5a567a882eb9b0fb7c6a07b7c2e02416f2", + "9b0c27a26715dd2724360b841b3c581d0e967811", "reftest" ], "mathml/relations/css-styling/lengths-2.html": [ - "aa38e9729de8569151b98307395ec8a2a5fe4b7f", + "73fd23bbfd91d0b5b274b546c53814eef66eb24a", "testharness" ], "mathml/relations/css-styling/mathsize-attribute-ref.html": [ @@ -438348,7 +438364,7 @@ "support" ], "mathml/relations/css-styling/mathsize-attribute.html": [ - "00d12e4839cb91e5294409af03d3ad3847eb4213", + "803f236a6a9dc241d978393c3305c9770ad4786d", "reftest" ], "mathml/relations/css-styling/mathvariant-bold-fraktur-ref.html": [ @@ -438356,7 +438372,7 @@ "support" ], "mathml/relations/css-styling/mathvariant-bold-fraktur.html": [ - "f4141810820518d0b1b3c2d832827dbaa77c6871", + "8085ad50832e0e14d3eee810cf32410e6c6d7707", "reftest" ], "mathml/relations/css-styling/mathvariant-bold-italic-ref.html": [ @@ -438364,7 +438380,7 @@ "support" ], "mathml/relations/css-styling/mathvariant-bold-italic.html": [ - "7b53e986d4f07796c8d44a8356081082ad238d96", + "1e1b0b0debd74e228f72df7e5a10040a9bcb3aea", "reftest" ], "mathml/relations/css-styling/mathvariant-bold-ref.html": [ @@ -438376,7 +438392,7 @@ "support" ], "mathml/relations/css-styling/mathvariant-bold-sans-serif.html": [ - "544db02f2eedc3229e57eac3016e3aa086061704", + "cd6cc7a0c5009d726f99c6a43b7304b8fd453be7", "reftest" ], "mathml/relations/css-styling/mathvariant-bold-script-ref.html": [ @@ -438384,11 +438400,11 @@ "support" ], "mathml/relations/css-styling/mathvariant-bold-script.html": [ - "dc48fbeaaf54ba184e02f062f074443de0e4835b", + "8ff7556dacd0496927b8d52e367d9e9150c4892d", "reftest" ], "mathml/relations/css-styling/mathvariant-bold.html": [ - "a51be7b23fd2bdbc9364a29a0766b53dea67dad2", + "f11594f82707a86f964c9a0aa2c1cfede0fabdb0", "reftest" ], "mathml/relations/css-styling/mathvariant-double-struck-ref.html": [ @@ -438396,7 +438412,7 @@ "support" ], "mathml/relations/css-styling/mathvariant-double-struck.html": [ - "3090fdc85c04d037f391c34dec615ce8827c222c", + "856672bcecd8f80249ab910ced30ece8c48171ac", "reftest" ], "mathml/relations/css-styling/mathvariant-fraktur-ref.html": [ @@ -438404,7 +438420,7 @@ "support" ], "mathml/relations/css-styling/mathvariant-fraktur.html": [ - "8bd15a558bf77d652237a6470cd64401f1787134", + "8ef57a0e2b98c7daec4e7c9473803e18f81aa42f", "reftest" ], "mathml/relations/css-styling/mathvariant-initial-ref.html": [ @@ -438412,7 +438428,7 @@ "support" ], "mathml/relations/css-styling/mathvariant-initial.html": [ - "58751bd1266971584260bc5d2c25935da4951672", + "de4b89f7f5a5547eb3dccd66035125d604c64679", "reftest" ], "mathml/relations/css-styling/mathvariant-italic-ref.html": [ @@ -438420,7 +438436,7 @@ "support" ], "mathml/relations/css-styling/mathvariant-italic.html": [ - "5bcbd322de85c885987457b128ad71bd7de72601", + "4cf3de045630d50b933d0cd29b527ecdcb610d12", "reftest" ], "mathml/relations/css-styling/mathvariant-looped-ref.html": [ @@ -438428,7 +438444,7 @@ "support" ], "mathml/relations/css-styling/mathvariant-looped.html": [ - "0326e86e8f4faf907b3698d319160242949bb0e5", + "2a774c7716cb324f7627c3484af5e07228bccad6", "reftest" ], "mathml/relations/css-styling/mathvariant-monospace-ref.html": [ @@ -438436,7 +438452,7 @@ "support" ], "mathml/relations/css-styling/mathvariant-monospace.html": [ - "8d9a5d3df27c1a8e85e00c6fee00ff3ddb8ef066", + "1c23630ecf744436b83bd1baafd3e5f7e14fabb7", "reftest" ], "mathml/relations/css-styling/mathvariant-sans-serif-bold-italic-ref.html": [ @@ -438444,7 +438460,7 @@ "support" ], "mathml/relations/css-styling/mathvariant-sans-serif-bold-italic.html": [ - "21401bc84ac95a40069b471f824b4e05e116d171", + "f67a6ab6db254d01e8000e774d40f406e8c47b78", "reftest" ], "mathml/relations/css-styling/mathvariant-sans-serif-italic-ref.html": [ @@ -438452,7 +438468,7 @@ "support" ], "mathml/relations/css-styling/mathvariant-sans-serif-italic.html": [ - "2573872319148c1c0bdfb359858a5369c28cc176", + "ab43df50c568d1fbb48bd7e9a65bb0623eb29978", "reftest" ], "mathml/relations/css-styling/mathvariant-sans-serif-ref.html": [ @@ -438460,7 +438476,7 @@ "support" ], "mathml/relations/css-styling/mathvariant-sans-serif.html": [ - "513e0351cc3f3e714d76adc0379fd4421ac90080", + "bfee81c0cb6825c83ee7ddd14c3d96994fc28d6b", "reftest" ], "mathml/relations/css-styling/mathvariant-script-ref.html": [ @@ -438468,7 +438484,7 @@ "support" ], "mathml/relations/css-styling/mathvariant-script.html": [ - "efd3f7e8ff6925a7941ea387f65faf63c5186f01", + "dd7ab6a06db11746ce39a23ca11728090f23fefc", "reftest" ], "mathml/relations/css-styling/mathvariant-stretched-ref.html": [ @@ -438476,7 +438492,7 @@ "support" ], "mathml/relations/css-styling/mathvariant-stretched.html": [ - "20c5a39a83a75e1736bd4cdcb7baf81952667856", + "8530c6880481f1629482902b2fdcb7205841c0a8", "reftest" ], "mathml/relations/css-styling/mathvariant-tailed-ref.html": [ @@ -438484,7 +438500,7 @@ "support" ], "mathml/relations/css-styling/mathvariant-tailed.html": [ - "c88d433ce5f43314c1f1249aa48d36ca0141b4a0", + "823438ec12ae909a222f7b1a17872e6b577ce771", "reftest" ], "mathml/relations/css-styling/visibility-1-ref.html": [ @@ -438492,7 +438508,7 @@ "support" ], "mathml/relations/css-styling/visibility-1.html": [ - "c84f97aeeb84d79b7937338445de720986f246ce", + "7083ef70fb3c8b5e90b7e590364b5c2c3502aefe", "reftest" ], "mathml/relations/html5-tree/class-1-ref.html": [ @@ -438500,11 +438516,11 @@ "support" ], "mathml/relations/html5-tree/class-1.html": [ - "ee4b4b50d3f4d630c80fea170008b73d5b4b9851", + "a1efbd218462b05f99d78d9c04090df1457e575a", "reftest" ], "mathml/relations/html5-tree/class-2.html": [ - "4e1ae6b707405d900e309ac11792606a6a6f295e", + "8d6515af9f97279e6c0ab036409f7f5a31757e8a", "testharness" ], "mathml/relations/html5-tree/color-attributes-1-ref.html": [ @@ -438512,11 +438528,11 @@ "support" ], "mathml/relations/html5-tree/color-attributes-1.html": [ - "6f9f93721a2a9173c9efb156bcc875bd61123edb", + "585aebaf393d85187b644a97f6e7f28535fa9095", "reftest" ], "mathml/relations/html5-tree/display-1.html": [ - "77038ee223c5a319f8536f01532530093dc69c18", + "3a180f5d42bcd3d260019edabc6ecf455b8dcf8f", "testharness" ], "mathml/relations/html5-tree/dynamic-1-ref.html": [ @@ -438524,7 +438540,7 @@ "support" ], "mathml/relations/html5-tree/dynamic-1.html": [ - "48fdd25915598b63a849752260349b2bd2186720", + "b4d603a9aa6b59f243df113f79fc6bac89b1ec47", "reftest" ], "mathml/relations/html5-tree/href-click-1-ref.html": [ @@ -438532,7 +438548,7 @@ "support" ], "mathml/relations/html5-tree/href-click-1.html": [ - "dd6b7990a3c1719ff66c8e93d9d98b3ea97bfdf0", + "bf902b5e8f6ef20cbb55a2655a7b734b715bc05b", "reftest" ], "mathml/relations/html5-tree/href-click-2-ref.html": [ @@ -438540,11 +438556,11 @@ "support" ], "mathml/relations/html5-tree/href-click-2.html": [ - "4c5253df1596d4acf6208579fea731b058ac1a58", + "c23d87c2358c296ad331fb981ff58b6bea6253e9", "reftest" ], "mathml/relations/html5-tree/href-click-3.html": [ - "f2863febc1f14d4e1170b1ebcddb9bf30aedfd24", + "a8475ea3ff801dfdb6f4d6d5a7e049a6eafe7c00", "testharness" ], "mathml/relations/html5-tree/integration-point-1-ref.html": [ @@ -438552,7 +438568,7 @@ "support" ], "mathml/relations/html5-tree/integration-point-1.html": [ - "3221a67503bc0cba619715c1fd25d1e2c2ce1081", + "4d10af86c72a7e2904ba92858456e6a7b6d3aaae", "reftest" ], "mathml/relations/html5-tree/integration-point-2-ref.html": [ @@ -438560,7 +438576,7 @@ "support" ], "mathml/relations/html5-tree/integration-point-2.html": [ - "d42eeb03ed21d133decebb8ee287c23ac08d9699", + "20d499d3f89f673a00ad22a53f8e9a116a2e6843", "reftest" ], "mathml/relations/html5-tree/integration-point-3-ref.html": [ @@ -438568,7 +438584,7 @@ "support" ], "mathml/relations/html5-tree/integration-point-3.html": [ - "1feb8317ff12252bc131dd7368c8162b79a0d803", + "1f62d8e630a1361ca65c5c76679f4e61bb2688dc", "reftest" ], "mathml/relations/html5-tree/required-extensions-2-ref.html": [ @@ -438576,7 +438592,7 @@ "support" ], "mathml/relations/html5-tree/required-extensions-2.html": [ - "1d7af04d9edcb76cd870e63145d3d7096bd59c09", + "e1d7a853704ce5f9edf2f2d6d6a414be51fe4e4b", "reftest" ], "mathml/relations/html5-tree/unique-identifier-1-iframe-1.html": [ @@ -438592,11 +438608,11 @@ "support" ], "mathml/relations/html5-tree/unique-identifier-1.html": [ - "42a547ac218f1d8590fd48a0d6331ef3b1c2c86d", + "e2315f149936fc5f23622533db63727b630c4e2f", "reftest" ], "mathml/relations/html5-tree/unique-identifier-2.html": [ - "421ad7a86d03861084a98ea00b17e7b77e1365f5", + "2c3190c51e25769a2e83ea1812c3112c962d7ab4", "testharness" ], "mathml/relations/html5-tree/unique-identifier-3-ref.html": [ @@ -438604,7 +438620,7 @@ "support" ], "mathml/relations/html5-tree/unique-identifier-3.html": [ - "c58e5026cfad049bef38d825df256cc0111c7b8c", + "7cfac89e85b4cc0b39c2711756c0ce01194542df", "reftest" ], "mathml/relations/text-and-math/use-typo-metrics-1-ref.html": [ @@ -438612,7 +438628,7 @@ "support" ], "mathml/relations/text-and-math/use-typo-metrics-1.html": [ - "3797aef5fc0fa316cd8268accd8501be88cd6c44", + "4e92a846461b65d150cef9a9444de27abf40a26d", "reftest" ], "mathml/tools/axisheight.py": [ @@ -438636,7 +438652,7 @@ "support" ], "mathml/tools/mathvariant-transforms.py": [ - "ba99b595f0aa6338ba7a752801c4a32dbbefc9ef", + "51c7c187a170731aee47b3366bd8ce23a73f3611", "support" ], "mathml/tools/percentscaledown.py": [ @@ -475103,6 +475119,10 @@ "6ae52639d1dc0d5b303cb4cdb6fb727481234be9", "testharness" ], + "trusted-types/block-eval.tentative.html": [ + "e1a6a69accd1fa8ddaddd1c49970755a275bd8eb", + "testharness" + ], "trusted-types/block-string-assignment-to-DOMParser-parseFromString.tentative.html": [ "4446a58836695355efd0fbf3f9f5a0bd6c60c8a3", "testharness" @@ -475167,6 +475187,10 @@ "a6aa061f7307330e027c3e8b26e6b931cee2bb7c", "testharness" ], + "trusted-types/eval-with-permissive-csp.tentative.html": [ + "68d119a520121f2c5a3f88028abcf657799b9123", + "testharness" + ], "trusted-types/idlharness.window.js": [ "de13697764ed487060de3dd425cd39cba73ff13b", "testharness" @@ -476339,10 +476363,6 @@ "776c59be658f749fcdd0a8ea6a92ac82c88d344e", "support" ], - "wake-lock/idlharness.https.any-expected.txt": [ - "4c1af702441d331e3e39eb041911d60e10cb380c", - "support" - ], "wake-lock/idlharness.https.any.js": [ "2ad9980dae53727ea328e942dead029a936875cc", "testharness"
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/reporting/report-only-unsafe-eval-expected.txt b/third_party/blink/web_tests/external/wpt/content-security-policy/reporting/report-only-unsafe-eval-expected.txt new file mode 100644 index 0000000..c519bb4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/content-security-policy/reporting/report-only-unsafe-eval-expected.txt
@@ -0,0 +1,6 @@ +This is a testharness.js-based test. +PASS Eval is allowed because the CSP is report-only +FAIL SPV event is still raised assert_unreached: SPV event has not been received Reached unreachable code +FAIL Violation report status OK. assert_equals: No such report. expected "" but got "false" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/reporting/report-only-unsafe-eval.html b/third_party/blink/web_tests/external/wpt/content-security-policy/reporting/report-only-unsafe-eval.html new file mode 100644 index 0000000..ebaf694 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/content-security-policy/reporting/report-only-unsafe-eval.html
@@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html> +<head> + <script nonce='abc' src="/resources/testharness.js"></script> + <script nonce='abc' src="/resources/testharnessreport.js"></script> + <!-- CSP headers +Content-Security-Policy-Report-Only: script-src 'unsafe-inline' 'nonce-abc'; report-uri ../support/report.py?op=put&reportID={{$id}} +--> +</head> +<body> + <script nonce='abc'> + var t = async_test("Eval is allowed because the CSP is report-only"); + + var t_spv = async_test("SPV event is still raised"); + t_spv.step_timeout(t_spv.unreached_func("SPV event has not been received"), 3000); + document.addEventListener('securitypolicyviolation', t_spv.step_func(e => { + assert_equals(e.violatedDirective, "script-src"); + assert_equals(e.blockedURI, "eval"); + })); + + try { + eval("t.done()"); + } catch { + t.step(t.unreached_func("The eval should have executed succesfully")); + t_spv.step(tsv_unreached_func("The eval execution should have triggered a securitypolicyviolation event")); + } + </script> + <script nonce='abc' async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=script-src%20%27unsafe-inline%27'></script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/reporting/report-only-unsafe-eval.html.sub.headers b/third_party/blink/web_tests/external/wpt/content-security-policy/reporting/report-only-unsafe-eval.html.sub.headers new file mode 100644 index 0000000..549f3db --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/content-security-policy/reporting/report-only-unsafe-eval.html.sub.headers
@@ -0,0 +1,4 @@ +Cache-Control: no-store, no-cache, must-revalidate +Pragma: no-cache +Set-Cookie: report-only-unsafe-eval={{$id:uuid()}}; Path=/content-security-policy/reporting/ +Content-Security-Policy-Report-Only: script-src 'unsafe-inline' 'nonce-abc'; report-uri ../support/report.py?op=put&reportID={{$id}}
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/inline-negative-margin-001.html b/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/inline-negative-margin-001.html new file mode 100644 index 0000000..e8a00ec --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/CSS2/linebox/inline-negative-margin-001.html
@@ -0,0 +1,26 @@ +<!DOCTYPE html> +<title>CSS Test: Check inline negative margin should not cause the line to wrap</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/check-layout-th.js"></script> +<link rel="help" href="https://crbug.com/979894"> +<link rel="help" href="https://drafts.csswg.org/css2/visudet.html#inline-width"> +<link rel="author" title="Koji Ishii" href="mailto:kojii@chromium.org"> +<style> +html, body { margin: 0; } +div { + font-family: Ahem; + font-size: 10px; + line-height: 1; +} +#container { + display: inline-block; +} +span { + color: orange; +} +</style> +<body> + <div id="container" data-expected-height=10>123 <span style="margin-left: -8ch">1234 </span></div> +<script>checkLayout('#container');</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/fieldset.html b/third_party/blink/web_tests/external/wpt/css/css-break/fieldset.html new file mode 100644 index 0000000..fe76988 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/fieldset.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-break-3/#possible-breaks"> +<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> +<style> + fieldset { margin:0; border:none; padding:0; } + .block { break-inside:avoid; height:50px; background:green; } + .fail { background:red; } +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div style="columns:2; column-fill:auto; width:100px; height:140px; column-gap:0; overflow:hidden;"> + <fieldset> + <div class="block"></div> + <div class="block"></div> + <div class="block"></div> + <div class="block"></div> + + <!-- No room for this - should be clipped: --> + <div class="block fail"></div> + </fieldset> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-001.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-001.tentative.html index 8856b2b..6a353a6 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-001.tentative.html +++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-001.tentative.html
@@ -4,6 +4,7 @@ <title>math-script-level</title> <meta charset="utf-8"> <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/3746"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-math-script-level-property"> <meta name="assert" content="Check the resolved value of math-script-level"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-002.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-002.tentative.html index b3f56fe..0abce02 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-002.tentative.html +++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-002.tentative.html
@@ -4,6 +4,7 @@ <title>math-script-level</title> <meta charset="utf-8"> <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/3746"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-math-script-level-property"> <meta name="assert" content="Verify effect of math-script-level auto | add(<integer>) | <integer>, starting from different values of math-script-level."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-003.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-003.tentative.html index 50100124..f5bf998 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-003.tentative.html +++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-003.tentative.html
@@ -4,6 +4,7 @@ <title>math-script-level</title> <meta charset="utf-8"> <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/3746"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-math-script-level-property"> <meta name="assert" content="If font-size is specified or if the specified value of math-script-level is initial then math-script-level does not affect the computed value of font-size."> <link rel="match" href="math-script-level-003.tentative-ref.html"> <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-004.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-004.tentative.html index 6fe35c2..cb82472a 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-004.tentative.html +++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-004.tentative.html
@@ -4,6 +4,7 @@ <title>math-script-level</title> <meta charset="utf-8"> <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/3746"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-math-script-level-property"> <meta name="assert" content="Check the resolved value of math-script-level"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-005.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-005.tentative.html index 7f289ff..34860d7a 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-005.tentative.html +++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-005.tentative.html
@@ -5,6 +5,7 @@ <meta charset="utf-8"> <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/3746"> <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/3906"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-math-script-level-property"> <meta name="assert" content="If the computed font-size is changed because of font-family change, math-script-level does not affect the computed value of font-size."> <link rel="match" href="math-script-level-005.tentative-ref.html"> </head>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-001.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-001.tentative.html index 0765630f..ad187b5d 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-001.tentative.html +++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-001.tentative.html
@@ -4,6 +4,8 @@ <title>math-script-level: auto and math-style</title> <meta charset="utf-8"> <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/3746"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-math-script-level-property"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-math-style-property"> <meta name="assert" content="If math-script-level is 'auto' and the inherited value of math-style is 'display' then the computed value of math-script-level is the inherited value."> <link rel="match" href="math-script-level-auto-and-math-style-001.tentative-ref.html"> <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-002.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-002.tentative.html index baff728..c111f2c3 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-002.tentative.html +++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-002.tentative.html
@@ -4,6 +4,8 @@ <title>math-script-level: auto and math-style</title> <meta charset="utf-8"> <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/3746"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-math-script-level-property"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-math-style-property"> <meta name="assert" content="If math-script-level is 'auto' and the inherited value of math-style is 'inline' then the computed value of math-script-level is the inherited value plus one."> <link rel="match" href="math-script-level-auto-and-math-style-002.tentative-ref.html"> <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-003.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-003.tentative.html index 827dbd4..428248176 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-003.tentative.html +++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-003.tentative.html
@@ -4,6 +4,8 @@ <title>math-script-level: auto and math-style</title> <meta charset="utf-8"> <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/3746"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-math-script-level-property"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-math-style-property"> <meta name="assert" content="Initial value of math-style is 'inline'"> <link rel="match" href="math-script-level-auto-and-math-style-003.tentative-ref.html"> <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-004.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-004.tentative.html index 8917d68..150d428 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-004.tentative.html +++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-004.tentative.html
@@ -4,6 +4,8 @@ <title>math-script-level: auto and math-style</title> <meta charset="utf-8"> <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/3746"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-math-script-level-property"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-math-style-property"> <meta name="assert" content="Initial value of math-style is 'inline'"> <link rel="match" href="math-script-level-auto-and-math-style-004.tentative-ref.html"> <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-005.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-005.tentative.html index 90c09d5..718a5640 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-005.tentative.html +++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-005.tentative.html
@@ -4,6 +4,8 @@ <title>math-script-level: auto and math-style</title> <meta charset="utf-8"> <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/3746"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-math-script-level-property"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-math-style-property"> <meta name="assert" content="math-style is inherited"> <link rel="match" href="math-script-level-auto-and-math-style-005.tentative-ref.html"> <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-font-size-clamping-001.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-font-size-clamping-001.tentative.html index 6a70cf3..e25ee56 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-font-size-clamping-001.tentative.html +++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-font-size-clamping-001.tentative.html
@@ -4,6 +4,7 @@ <title>math-script-level clamping</title> <meta charset="utf-8"> <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/3739"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-math-script-level-property"> <meta name="assert" content="Clamping due to browser's min font size only affects the used size."> <link rel="match" href="math-script-level-font-size-clamping-001.tentative-ref.html"> <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-style-001.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-style-001.tentative.html index 6df3517..56cb1ec 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-style-001.tentative.html +++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/math-script-level-and-math-style/math-style-001.tentative.html
@@ -4,6 +4,7 @@ <title>math-style</title> <meta charset="utf-8"> <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/3746"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-math-style-property"> <meta name="assert" content="Check the resolved value of math-style"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-fieldset.html b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-fieldset.html new file mode 100644 index 0000000..b212e62 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-fieldset.html
@@ -0,0 +1,8 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/CSS22/visudet.html#abs-non-replaced-width"> +<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div style="position:relative; width:100px; height:100px; background:red;"> + <fieldset style="position:absolute; left:0; top:0; right:0; bottom:0; margin:0; border:none; background:green;"></fieldset> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-line-change-inline-color-nested-ref.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-line-change-inline-color-nested-ref.html deleted file mode 100644 index 84becd9..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-line-change-inline-color-nested-ref.html +++ /dev/null
@@ -1,2 +0,0 @@ -<!DOCTYPE html> -<p style="color: blue">Blue <span style="color: green">This text should be green.</span> Blue</p>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-line-change-inline-color-nested.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-line-change-inline-color-nested.html deleted file mode 100644 index 4a58f1e..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-line-change-inline-color-nested.html +++ /dev/null
@@ -1,23 +0,0 @@ -<!DOCTYPE html> -<html class="reftest-wait"> -<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#first-line-pseudo"> -<link rel="match" href="first-line-change-inline-color-nested-ref.html"> -<style> - #block { color: green; } - #block::first-line { color: blue; } - .green { color: green; } -</style> -<div id="block"> - <div> - <p>Blue <span id="target"><span>This text should be green.</span></span> Blue</p> - </div> -</div> -<script> -requestAnimationFrame(() => { - requestAnimationFrame(() => { - target.className = 'green'; - document.documentElement.removeAttribute('class'); - }); -}); -</script> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-line-change-inline-color-ref.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-line-change-inline-color-ref.html deleted file mode 100644 index 84becd9..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-line-change-inline-color-ref.html +++ /dev/null
@@ -1,2 +0,0 @@ -<!DOCTYPE html> -<p style="color: blue">Blue <span style="color: green">This text should be green.</span> Blue</p>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-line-change-inline-color.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-line-change-inline-color.html deleted file mode 100644 index 2a5be916..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-line-change-inline-color.html +++ /dev/null
@@ -1,23 +0,0 @@ -<!DOCTYPE html> -<html class="reftest-wait"> -<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#first-line-pseudo"> -<link rel="match" href="first-line-change-inline-color-ref.html"> -<style> - #block { color: green; } - #block::first-line { color: blue; } - .green { color: green; } -</style> -<div id="block"> - <div> - <p>Blue <span id="target">This text should be green.</span> Blue</p> - </div> -</div> -<script> -requestAnimationFrame(() => { - requestAnimationFrame(() => { - target.className = 'green'; - document.documentElement.removeAttribute('class'); - }); -}); -</script> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-line-on-ancestor-block-ref.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-line-on-ancestor-block-ref.html deleted file mode 100644 index 7193bf25..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-line-on-ancestor-block-ref.html +++ /dev/null
@@ -1,5 +0,0 @@ -<!DOCTYPE html> -<div> - <span style="color: green">This text should be green.</span><br> - <span style="color: blue">This text should be blue.</span> -</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-line-on-ancestor-block.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-line-on-ancestor-block.html deleted file mode 100644 index 6b797107..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-line-on-ancestor-block.html +++ /dev/null
@@ -1,16 +0,0 @@ -<!DOCTYPE html> -<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#first-line-pseudo"> -<link rel="match" href="first-line-on-ancestor-block-ref.html"> -<style> - #block::first-line { color: green; } -</style> -<div id="block"> - <div> - <div style="color: blue"> - <div> - <span><span>This text should be green.</span></span><br> - This text should be blue. - </div> - </div> - </div> -</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-line-with-out-of-flow-ref.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-line-with-out-of-flow-ref.html deleted file mode 100644 index 7193bf25..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-line-with-out-of-flow-ref.html +++ /dev/null
@@ -1,5 +0,0 @@ -<!DOCTYPE html> -<div> - <span style="color: green">This text should be green.</span><br> - <span style="color: blue">This text should be blue.</span> -</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-line-with-out-of-flow.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-line-with-out-of-flow.html deleted file mode 100644 index 798ecf8..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-line-with-out-of-flow.html +++ /dev/null
@@ -1,20 +0,0 @@ -<!DOCTYPE html> -<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#first-line-pseudo"> -<link rel="match" href="first-line-with-out-of-flow-ref.html"> -<style> - #block::first-line { color: green; } -</style> -<div id="block"> - <div style="position: absolute"><br></div> - <div style="float: right"><br></div> - <div> - <div style="position: absolute"><br></div> - <div style="float: right"><br></div> - <div style="color: blue"> - <div> - <span><span>This text should be green.</span></span><br> - This text should be blue. - </div> - </div> - </div> -</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-sizing/auto-scrollbar-inside-stf-abspos-ref.html b/third_party/blink/web_tests/external/wpt/css/css-sizing/auto-scrollbar-inside-stf-abspos-ref.html new file mode 100644 index 0000000..076893b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-sizing/auto-scrollbar-inside-stf-abspos-ref.html
@@ -0,0 +1,8 @@ +<!DOCTYPE html> +<style> + body { overflow:hidden; } +</style> +<p>The word PASS should be visible below.</p> +<div style="position:absolute; height:5em; overflow-y:scroll;"> + <div style="height:15em;">PASS</div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-sizing/auto-scrollbar-inside-stf-abspos.html b/third_party/blink/web_tests/external/wpt/css/css-sizing/auto-scrollbar-inside-stf-abspos.html new file mode 100644 index 0000000..9479b2eb --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-sizing/auto-scrollbar-inside-stf-abspos.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-sizing-3/#valdef-width-fit-content-length-percentage"> +<link rel="match" href="auto-scrollbar-inside-stf-abspos-ref.html"> +<style> + /* Set non-auto overflow on the viewport, so that the UA is more likely to get + the size right the first time. Otherwise, a re-layout might hide the bug + that we're trying to test. */ + body { overflow:hidden; } +</style> +<p>The word PASS should be visible below.</p> +<div style="position:absolute;"> + <div style="height:5em; overflow-y:auto;"> + <div style="height:15em;">PASS</div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/element-timing/buffer-before-onload.html b/third_party/blink/web_tests/external/wpt/element-timing/buffer-before-onload.html index 88a641bb..68eeeef 100644 --- a/third_party/blink/web_tests/external/wpt/element-timing/buffer-before-onload.html +++ b/third_party/blink/web_tests/external/wpt/element-timing/buffer-before-onload.html
@@ -10,8 +10,7 @@ <script> /* In this test, a slow image is added to the frame to delay onload. The entry - for the other image should be available before onload, and thus delivered to - the performance timeline. + is available from the observer with the buffered flag set to true. */ async_test(function(t) { if (!window.PerformanceElementTiming) { @@ -23,18 +22,26 @@ img.setAttribute('elementtiming', 'my_image'); img.setAttribute('id', 'my_id'); document.body.appendChild(img); - window.onload = t.step_func_done( () => { - const entries = performance.getEntriesByType('element'); - assert_greater_than_equal(entries.length, 1); - assert_equals(performance.getEntries().filter(e => e.identifier === 'my_image').length, 1); - const entry = entries[0]; - const index = window.location.href.lastIndexOf('/'); - const pathname = window.location.href.substring(0, index) + - '/resources/square20.jpg'; - checkElement(entry, pathname, 'my_image', 'my_id', beforeRender, img); - checkNaturalSize(entry, 20, 20); + + // this PerformanceObserver should be notified about the previously + // buffered element entry + new PerformanceObserver(function (entryList, observer) { + assert_equals(entryList.getEntries().length, 1); + entryList.getEntries().forEach(function(entry) { + assert_equals(entry.entryType, "element"); + const index = window.location.href.lastIndexOf('/'); + const pathname = window.location.href.substring(0, index) + + '/resources/square20.jpg'; + checkElement(entry, pathname, 'my_image', 'my_id', beforeRender, img); + checkNaturalSize(entry, 20, 20); + observer.disconnect(); + t.done(); + }); + }).observe({ + type: "element", + buffered: true }); - }, "Element Timing: image loads before onload."); + }, "Element Timing: image loads before onload available from buffered flag."); </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/element-timing/invisible-images.html b/third_party/blink/web_tests/external/wpt/element-timing/invisible-images.html index eb53cd7c..06d9bfd0 100644 --- a/third_party/blink/web_tests/external/wpt/element-timing/invisible-images.html +++ b/third_party/blink/web_tests/external/wpt/element-timing/invisible-images.html
@@ -20,9 +20,10 @@ assert_unreached("PerformanceElementTiming is not implemented"); } const observer = new PerformanceObserver( - t.step_func_done(() => { + t.step_func_done((entries) => { // The image should not have caused an entry, so fail test. - assert_unreached('Should not have received an entry!'); + assert_unreached('Should not have received an entry! Received one with identifier ' + + entries.getEntries()[0].identifier); }) ); observer.observe({entryTypes: ['element']}); @@ -46,6 +47,30 @@ img3.setAttribute('elementtiming', 'my_image3'); img3.setAttribute('id', 'displayNone'); document.body.appendChild(img3); + + const div = document.createElement('div'); + div.setAttribute('id', 'opacity0'); + const img4 = document.createElement('img'); + img4.src = '/images/blue.png'; + img4.setAttribute('elementtiming', 'my_image4'); + div.appendChild(img4); + document.body.appendChild(div); + + const div2 = document.createElement('div'); + div2.setAttribute('id', 'visibilityHidden'); + const img5 = document.createElement('img'); + img5.src = '/images/blue.png'; + img5.setAttribute('elementtiming', 'my_image5'); + div.appendChild(img5); + document.body.appendChild(div2); + + const div3 = document.createElement('div'); + div3.setAttribute('id', 'displayNone'); + const img6 = document.createElement('img'); + img6.src = '/images/blue.png'; + img6.setAttribute('elementtiming', 'my_image6'); + div.appendChild(img6); + document.body.appendChild(div3); // Images have been added but should not cause entries to be dispatched. // Wait for 500ms and end test, ensuring no entry was created. t.step_timeout(() => {
diff --git a/third_party/blink/web_tests/external/wpt/event-timing/bufferbeforeonload.html b/third_party/blink/web_tests/external/wpt/event-timing/bufferbeforeonload.html index c91546a..c30c01aa 100644 --- a/third_party/blink/web_tests/external/wpt/event-timing/bufferbeforeonload.html +++ b/third_party/blink/web_tests/external/wpt/event-timing/bufferbeforeonload.html
@@ -27,9 +27,7 @@ firstClickEnd = performance.now(); } - function validateEntries() { - const entries = performance.getEntriesByName('mousedown', 'event'); - + function validateEntries(entries) { const entriesBeforeOnload = entries.filter( e => e.startTime < onloadStart); assert_equals(entriesBeforeOnload.length, 1, @@ -48,8 +46,8 @@ const entriesAfterOnload = entries.filter( e => e.startTime >= onloadStart); - assert_equals(entriesAfterOnload.length, 0, - "Events after onload shouldn't be buffered."); + assert_equals(entriesAfterOnload.length, 1, + "Events after onload should still be buffered."); } /* Timeline: @@ -66,24 +64,31 @@ async_test(function(t) { clickTimeMin = performance.now(); clickAndBlockMain('button'); - // Use a dummy observer to know when both clicks have been dispatched. - const observerPromise = new Promise((resolve, reject) => { - let entryCount = 0; - new PerformanceObserver(entryList => { - entryCount += entryList.getEntries().filter( - entry => entry.name === 'mousedown').length; - if (entryCount >= 2) - resolve(); - }).observe({ entryTypes: ['event'] }); - }); // Event handlers will be dispatched asynchronously, so this will be called // before processing begins. processingStartMin = performance.now(); + const bufferedEntries = []; on_event(window, 'load', e => { onloadStart = performance.now(); - const clickPromise = clickAndBlockMain('button'); - Promise.all([observerPromise, clickPromise]).then( - t.step_func_done(validateEntries)); + // Register the observer after the page has been loaded + const observer = new PerformanceObserver(function (entryList, observer) { + entryList.getEntries().forEach(function(entry) { + assert_equals(entry.entryType, "event"); + if (entry.name === 'mousedown') { + bufferedEntries.push(entry); + } + if (bufferedEntries.length == 2) { + validateEntries(bufferedEntries) + observer.disconnect(); + t.done(); + } + }); + }) + observer.observe({ + type: "event", + buffered: true + }); + clickAndBlockMain('button'); }); }, "Event Timing: click, onload.");
diff --git a/third_party/blink/web_tests/external/wpt/event-timing/observethenonload.html b/third_party/blink/web_tests/external/wpt/event-timing/observethenonload.html index e1c36e3..4145eae 100644 --- a/third_party/blink/web_tests/external/wpt/event-timing/observethenonload.html +++ b/third_party/blink/web_tests/external/wpt/event-timing/observethenonload.html
@@ -20,19 +20,6 @@ let onloadStart; let observedEntries = []; - function verifyBuffer(bufferedEntries) { - assert_equals(bufferedEntries.length, 1, - "Only events before onload should be buffered."); - const entry = bufferedEntries[0]; - assert_greater_than(onloadStart, entry.startTime, - "Onload should be later than entry's start time."); - assert_greater_than(entry.processingStart, timeBeforeFirstClick, - "The entry's processing start should be after timeBeforeFirstClick"); - assert_less_than(entry.processingStart, timeAfterFirstClick, - "The entry's processing start should be before timeAfterFirstClick."); - verifyClickEvent(entry, true); - } - function verifyObserverEntries(observedEntries) { const entriesAfterFirstClick = observedEntries.filter( e => e.startTime > timeAfterFirstClick); @@ -60,6 +47,9 @@ "entry2's processing start should be berfore timeAfterFirstClick."); assert_greater_than(timeAfterFirstClick, entry2.startTime, "timeAfterFirstClick should be later than entry2's start time."); + // This should happen before onLoad + assert_greater_than(onloadStart, entry2.startTime, + "Onload should be later than entry's start time."); } /* Timeline: @@ -82,7 +72,7 @@ entry => entry.name === 'mousedown')); if (observedEntries.length < 2) return; resolve(observedEntries); - }).observe({ entryTypes: ['event'] }); + }).observe({ type: 'event' , buffered: true}); }); timeBeforeFirstClick = performance.now(); clickAndBlockMain('button').then( () => { @@ -95,7 +85,6 @@ Promise.all([observerPromise, bufferPromise]).then((results) => { timeAfterSecondClick = performance.now(); t.step(verifyObserverEntries.bind(null, results[0])); - t.step(verifyBuffer.bind(null, performance.getEntriesByName('mousedown', 'event'))); t.done(); }); });
diff --git a/third_party/blink/web_tests/external/wpt/event-timing/onloadthenobserve-firstInput.html b/third_party/blink/web_tests/external/wpt/event-timing/onloadthenobserve-firstInput.html index 1422cea..4efdfbb 100644 --- a/third_party/blink/web_tests/external/wpt/event-timing/onloadthenobserve-firstInput.html +++ b/third_party/blink/web_tests/external/wpt/event-timing/onloadthenobserve-firstInput.html
@@ -23,30 +23,38 @@ async_test(function(t) { let numFirstInputObserved = 0; let numEventsObserved = 0; - new PerformanceObserver(t.step_func((entryList, obs) => { - const observedEntries = entryList.getEntries().filter( - entry => entry.name === 'mousedown'); - numEventsObserved += observedEntries.filter(entry => - entry.entryType == 'event').length; - numFirstInputObserved += observedEntries.filter(entry => - entry.entryType == 'firstInput').length; + let observedEventEntries = []; + + const event_observer_promise = new Promise((resolve, reject) => { + new PerformanceObserver(function(entryList) { + observedEventEntries = entryList.getEntries().filter( + entry => entry.name === 'mousedown'); + numEventsObserved += observedEventEntries.length; if (numEventsObserved >= 2) { - assert_equals(performance.getEntriesByType('event').length, 0, - "There should be no buffered event entries."); - assert_equals(performance.getEntriesByType('firstInput').length, 1, - "There should be a buffered firstInput entry."); - // There should be 2 event entries and one firstInput entry. + // There should be 2 event entries. assert_equals(numEventsObserved, 2, "There should be 2 observed event entries."); - assert_equals(numFirstInputObserved, 1, - "There should be only 1 observed firstInput entry."); - t.done(); + resolve(); } - })).observe({ entryTypes: ['event', 'firstInput'] }); - on_event(window, 'load', () => { - clickAndBlockMain('button').then(() => { + }).observe({ type: 'event' , buffered: true}); + }); + + const first_input_observer_promise = new Promise((resolve, reject) => { + new PerformanceObserver(function(entryList) { + assert_equals(entryList.getEntries().length, 1); + resolve(); + }).observe({ type: 'firstInput' , buffered: true}); + }); + + on_event(window, 'load', function(e) { + const click_promise = clickAndBlockMain('button').then(() => { clickAndBlockMain('button'); }); + Promise.all( + [event_observer_promise, first_input_observer_promise, click_promise] + ).then(() => { + t.done(); + }); }); }, "Event Timing: check firstInput after onload, observer, click, click."
diff --git a/third_party/blink/web_tests/external/wpt/event-timing/onloadthenobserve.html b/third_party/blink/web_tests/external/wpt/event-timing/onloadthenobserve.html index e2f9c93..d9722857 100644 --- a/third_party/blink/web_tests/external/wpt/event-timing/onloadthenobserve.html +++ b/third_party/blink/web_tests/external/wpt/event-timing/onloadthenobserve.html
@@ -17,16 +17,9 @@ let observerStart; let processingStartMin; - function verifyBufferAndObserverEntries(observedEntries) { - // Verify buffer entries - const bufferedEntries = performance.getEntriesByName('mousedown', 'event'); - const bufferedEntriesBeforeObserver = bufferedEntries.filter(e => e.startTime < - observerStart); - assert_equals(bufferedEntries.length, 0, - "Long latency events after onload should not be buffered." - ); - - // Verify observer entries + function verifyObserverEntries(observedEntries) { + // Verify observer entries. Should not include first click since we didn't + // buffered to true. assert_equals(observedEntries.length, 1, "Long latency task after observer start should be observed."); const entry = observedEntries[0]; verifyClickEvent(entry); @@ -45,8 +38,8 @@ callbackTime = performance.now(); const observedEntries = entryList.getEntries().filter( entry => entry.name === 'mousedown'); - verifyBufferAndObserverEntries(observedEntries); - })).observe({ entryTypes: ['event'] }); + verifyObserverEntries(observedEntries); + })).observe({ type: 'event'}); observerStart = performance.now(); }
diff --git a/third_party/blink/web_tests/external/wpt/event-timing/resources/crossiframe-childframe.html b/third_party/blink/web_tests/external/wpt/event-timing/resources/crossiframe-childframe.html index 7aa4ace..ee9da6c 100644 --- a/third_party/blink/web_tests/external/wpt/event-timing/resources/crossiframe-childframe.html +++ b/third_party/blink/web_tests/external/wpt/event-timing/resources/crossiframe-childframe.html
@@ -2,7 +2,6 @@ <html> <script src=event-timing-test-utils.js></script> <button id='button_child_frame'>Generate a 'click' event</button> -<img src=slow-image.py> <script> const clickTimeMin = performance.now(); clickAndBlockMain('button_child_frame'); @@ -10,7 +9,7 @@ const observerPromise = new Promise((resolve, reject) => { new PerformanceObserver((entryList) => { resolve(entryList.getEntries().filter(entry => entry.name === 'mousedown')); - }).observe({ entryTypes: ['event'] }); + }).observe({ type:'event', buffered: true }); }); window.addEventListener('load', e => { observerPromise.then((observedEntries) => {
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/user-prompts/print-manual.html b/third_party/blink/web_tests/external/wpt/html/webappapis/user-prompts/print-manual.html new file mode 100644 index 0000000..3afef1d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/webappapis/user-prompts/print-manual.html
@@ -0,0 +1,93 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Printing</title> +<link rel=help href="https://html.spec.whatwg.org/#printing"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +setup({explicit_timeout: true}) +</script> + +<p>Click on the button below.</p> +<p>If the browser offers to print the current page, dismiss the prompt to +return to this page. The following should then appear in the box marked as +"Output":</p> +<pre> +before calling print() +beforeprint +afterprint +after calling print() +</pre> +<p>If no user dialog appears, either the above or the following should be +printed in the box marked as "Output":</p> +<pre> +before calling print() +after calling print() +</pre> +<p>The test passes if the above criteria are satisfied and "PASS" appears in a +table below this paragraph. The test fails otherwise.</p> + +<button onclick="testBtn(this)">Click here!</button> +<h3>Output</h3> +<pre id=output></pre> + +<script> +"use strict"; +// This test is actually synchronous, but we use async_test()'s nice +// infrastructure around t.step() to capture errors in event listeners. This is +// necessary since it seems like in Chrome, exceptions in beforeprint/afterprint +// event listeners are not propagated to error events. See +// https://crbug.com/977828. +const t = async_test(); +const log = []; +function out(str) { + log.push(str); + output.appendChild(document.createTextNode(str + "\n")); +} +function testBtn(btn) { + btn.remove(); + window.addEventListener("beforeprint", function (ev) { + // t.step_func() does not preserve `this`, which we test below. + t.step(() => { + out("beforeprint"); + assert_equals(ev.__proto__, Event.prototype); + assert_equals(this, window); + assert_equals(ev.target, window); + assert_equals(ev.type, "beforeprint"); + }); + }); + window.addEventListener("afterprint", function (ev) { + // t.step_func() does not preserve `this`, which we test below. + t.step(() => { + out("afterprint"); + assert_equals(ev.__proto__, Event.prototype); + assert_equals(this, window); + assert_equals(ev.target, window); + assert_equals(ev.type, "afterprint"); + }); + }); + out("before calling print()"); + print(); + out("after calling print()"); + t.step(() => { + try { + assert_array_equals(log, [ + "before calling print()", + "beforeprint", + "afterprint", + "after calling print()", + ]); + } catch (err) { + try { + assert_array_equals(log, [ + "before calling print()", + "after calling print()", + ]); + } catch (err) { + assert_unreached("Output does not match either possibility"); + } + } + }); + t.done(); +} +</script>
diff --git a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/cross-origin-image.sub.html b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/cross-origin-image.sub.html new file mode 100644 index 0000000..3716f93 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/cross-origin-image.sub.html
@@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<meta charset=utf-8> +<title>Largest Contentful Paint: observe cross-origin images but without startTime.</title> +<body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + async_test(function (t) { + if (!window.LargestContentfulPaint) { + assert_unreached("LargestContentfulPaint is not implemented"); + } + const observer = new PerformanceObserver( + t.step_func_done(function(entryList) { + assert_equals(entryList.getEntries().length, 1); + const entry = entryList.getEntries()[0]; + assert_equals(entry.entryType, 'largestContentfulPaint'); + assert_equals(entry.startTime, 0, 'The startTime value should be 0 for a cross origin image.'); + assert_equals(entry.duration, 0); + // blue.png is 133 x 106. + assert_equals(entry.size, 14098); + assert_equals(entry.id, 'image_id'); + const pathname = 'http://{{domains[www]}}:{{ports[http][1]}}/images/blue.png'; + assert_equals(entry.url, pathname); + assert_equals(entry.responseEnd, + performance.getEntriesByName(pathname, 'resource')[0].responseEnd); + assert_equals(entry.element, document.getElementById('image_id')); + }) + ); + observer.observe({type: 'largestContentfulPaint', buffered: true}); + }, 'Cross-origin image is observable, with startTime equal to 0.'); +</script> + +<img src='http://{{domains[www]}}:{{ports[http][1]}}/images/blue.png' id='image_id'/> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/observe-image.html b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/observe-image.html index 43cdfab0..8adf215 100644 --- a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/observe-image.html +++ b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/observe-image.html
@@ -22,11 +22,19 @@ assert_equals(entry.duration, 0); // blue.png is 133 x 106. assert_equals(entry.size, 14098); + assert_equals(entry.id, 'image_id'); + // 25 is the length of "largest-contentful-paint/". + const index = window.location.href.lastIndexOf('/') - 25; + const pathname = window.location.href.substring(0, index) + '/images/blue.png'; + assert_equals(entry.url, pathname); + assert_equals(entry.responseEnd, + performance.getEntriesByName(pathname, 'resource')[0].responseEnd); + assert_equals(entry.element, document.getElementById('image_id')); }) ); observer.observe({type: 'largestContentfulPaint', buffered: true}); - }, 'Element with elementtiming attribute is observable.'); + }, 'Same-origin image is observable.'); </script> -<img src='/images/blue.png'/> +<img src='/images/blue.png' id='image_id'/> </body>
diff --git a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/observe-text.html b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/observe-text.html index 77ed06e..a9a0d75 100644 --- a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/observe-text.html +++ b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/observe-text.html
@@ -27,6 +27,10 @@ // Width of at least 100 px. // TODO: find a good way to bound text width. assert_greater_than_equal(entry.size, 1200); + assert_equals(entry.responseEnd, 0); + assert_equals(entry.id, 'my_text'); + assert_equals(entry.url, ''); + assert_equals(entry.element, document.getElementById('my_text')); }) ); observer.observe({type: 'largestContentfulPaint', buffered: true}); @@ -34,5 +38,5 @@ }, 'Element with elementtiming attribute is observable.'); </script> -<p>This is important text! :)</p> +<p id='my_text'>This is important text! :)</p> </body>
diff --git a/third_party/blink/web_tests/external/wpt/layout-instability/observe-layout-shift.html b/third_party/blink/web_tests/external/wpt/layout-instability/observe-layout-shift.html index db8d3ae4..25e4950f6 100644 --- a/third_party/blink/web_tests/external/wpt/layout-instability/observe-layout-shift.html +++ b/third_party/blink/web_tests/external/wpt/layout-instability/observe-layout-shift.html
@@ -6,9 +6,39 @@ #myDiv { position: relative; width: 300px; height: 100px; } </style> <div id='myDiv'></div> +<button id='button'>Generate a 'click' event</button> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<script> +<script src=/resources/testdriver.js></script> +<script src=/resources/testdriver-vendor.js></script><script> + let timeAfterClick; + function mainThreadBusy(duration) { + const now = performance.now(); + while (performance.now() < now + duration); + } + + function clickOnElement(id, callback) { + const element = document.getElementById(id); + const rect = element.getBoundingClientRect(); + const xCenter = rect.x + rect.width / 2; + const yCenter = rect.y + rect.height / 2; + const leftButton = 0; + const clickHandler = () => { + mainThreadBusy(120); + if (callback) + callback(); + element.removeEventListener("mousedown", clickHandler); + }; + element.addEventListener("mousedown", clickHandler); + test_driver.click(element); + } + + function clickAndBlockMain(id) { + return new Promise((resolve, reject) => { + clickOnElement(id, resolve); + }); + } + async_test(function (t) { const startTime = performance.now(); const observer = new PerformanceObserver( @@ -32,6 +62,37 @@ document.getElementById('myDiv').style = "top: 60px"; }; }, 'Layout shift is observable via PerformanceObserver.'); + + async_test(function (t) { + const startTime = performance.now(); + const observer = new PerformanceObserver( + t.step_func_done(function(entryList) { + const endTime = performance.now(); + assert_equals(entryList.getEntries().length, 1); + const entry = entryList.getEntries()[0]; + assert_equals(entry.entryType, "layoutShift"); + assert_equals(entry.name, ""); + assert_greater_than_equal(entry.startTime, startTime) + assert_less_than_equal(entry.startTime, endTime) + assert_equals(entry.duration, 0.0); + // The layout shift value should be: 300 * (100 + 60) / viewport size. + assert_equals(entry.value, 300 * (100 + 60) / + (document.documentElement.clientWidth * document.documentElement.clientHeight)); + // We should see that there was a click input entry + assert_equals(entry.hadRecentInput, true); + assert_greater_than_equal(timeAfterClick, entry.lastInputTime); + }) + ); + observer.observe({entryTypes: ['layoutShift']}); + window.onload = () => { + // User input event + clickAndBlockMain('button').then( () => { + timeAfterClick = performance.now(); + // Modify the position of the div. + document.getElementById('myDiv').style = "top: 60px"; + }); + }; + }, 'Layout shift within user input is observable via PerformanceObserver.'); </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/direction/direction-overall.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/direction/direction-overall.html index 7f377e5..5351ca5 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/direction/direction-overall.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/direction/direction-overall.html
@@ -4,6 +4,11 @@ <meta charset="utf-8"/> <title>Verify dir attribute on various containers</title> <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-top-level-math-element"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#horizontally-group-sub-expressions-mrow"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#style-change-mstyle"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#radicals-msqrt-mroot"> <meta name="assert" content="Verify dir attribute on various containers."> <link rel="match" href="direction-overall-ref.html"> </head>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/direction/direction-token.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/direction/direction-token.html index a02793cc..1896f3f 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/direction/direction-token.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/direction/direction-token.html
@@ -4,6 +4,8 @@ <meta charset="utf-8"/> <title>Verify dir attribute on token elements</title> <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#token-elements"> <meta name="assert" content="Verify dir attribute on various token elements."> <link rel="match" href="direction-token-ref.html"> </head>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/direction/direction.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/direction/direction.html index 05ea8b7..11d0515 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/direction/direction.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/direction/direction.html
@@ -4,6 +4,7 @@ <meta charset="utf-8"/> <title>Verify computed direction</title> <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-top-level-math-element"> <meta name="assert" content="Verify computed direction value."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-1.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-1.html index 6b9fb28..6be38d5 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-1.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>Fraction</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mfrac"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#fractions-mfrac"> <meta name="assert" content="Verify fraction metrics for different sizes of numerator and denominator."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-bar-001.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-bar-001.html index d6151f62..887ff17 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-bar-001.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-bar-001.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>fractions bar</title> - <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mfrac"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#fractions-mfrac"> <meta name="assert" content="Verifies painting of the fraction bar"> <link rel="match" href="frac-bar-001-ref.html"> <style type="text/css">
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-color-001.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-color-001.html index d1a3e6eac..d0674c6c 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-color-001.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-color-001.html
@@ -3,7 +3,8 @@ <head> <meta charset="utf-8"> <title>Fraction bar color</title> - <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mfrac"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#fractions-mfrac"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> <meta name="assert" content="The CSS color property has an effect on the fraction bar."> <link rel="mismatch" href="frac-color-001-notref.html"> </head>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-color-002.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-color-002.html index 597acab..4b45c8e1 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-color-002.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-color-002.html
@@ -3,8 +3,9 @@ <head> <meta charset="utf-8"> <title>fractions color</title> - <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mfrac"> - <meta name="assert" content="Verifies the color attribute affects the fraction bar"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#fractions-mfrac"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> + <meta name="assert" content="Verifies the color property affects the fraction bar"> <link rel="match" href="frac-color-002-ref.html"> </head> <body>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-created-dynamically-2.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-created-dynamically-2.html index a970707..2aa9675 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-created-dynamically-2.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-created-dynamically-2.html
@@ -3,7 +3,8 @@ <head> <meta charset="utf-8"> <title>mfrac created dynamically</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mfrac"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#fractions-mfrac"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#dom-and-javascript"> <meta name="assert" content="A dynamically added mfrac should render like the equivalent markup."> <link rel="match" href="frac-created-dynamically-2-ref.html"> <script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-created-dynamically-3.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-created-dynamically-3.html index cec71163c..c90119d 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-created-dynamically-3.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-created-dynamically-3.html
@@ -3,7 +3,8 @@ <head> <meta charset="utf-8"> <title>mfrac created dynamically</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mfrac"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#fractions-mfrac"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#dom-and-javascript"> <meta name="assert" content="A dynamically added mfrac should render like the equivalent markup."> <link rel="match" href="frac-created-dynamically-3-ref.html"> <script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-created-dynamically.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-created-dynamically.html index 3224eb4e..7a555f2 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-created-dynamically.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-created-dynamically.html
@@ -3,7 +3,8 @@ <head> <meta charset="utf-8"> <title>mfrac created dynamically</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mfrac"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#fractions-mfrac"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#dom-and-javascript"> <meta name="assert" content="A dynamically added mfrac should render like the equivalent markup."> <link rel="match" href="frac-created-dynamically-ref.html"> <script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-linethickness-001.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-linethickness-001.html index eca8287..4d6bda2 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-linethickness-001.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-linethickness-001.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>fractions linethickness</title> - <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mfrac"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#fractions-mfrac"> <meta name="assert" content="Verifies deprecated 'thin', 'medium', 'thick' and unitless values have no effect on the linethickness of the mfrac element"> <link rel="match" href="frac-linethickness-001-ref.html"> <style type="text/css">
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-linethickness-002.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-linethickness-002.html index fd45994..ce122f7 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-linethickness-002.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-linethickness-002.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>fractions linethickness</title> - <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mfrac"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#fractions-mfrac"> <meta name="assert" content="Verifies fraction with negative, percent and named space linethickness values."> <link rel="match" href="frac-linethickness-002-ref.html"> <style type="text/css">
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-linethickness-003.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-linethickness-003.html index b23cce8..c9fa0f3 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-linethickness-003.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-linethickness-003.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>fractions linethickness</title> - <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mfrac"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#fractions-mfrac"> <meta name="assert" content="Verifies fraction with 0px bar."> <link rel="mismatch" href="frac-linethickness-003-notref.html"> </head>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-linethickness-004.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-linethickness-004.html index ff96a3d7..d9689fc 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-linethickness-004.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-linethickness-004.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>fractions linethickness</title> - <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mfrac"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#fractions-mfrac"> <meta name="assert" content="Verifies that unitless value of zero causes no fraction bar to be painted"> <link rel="match" href="frac-linethickness-004-ref.html"> <style type="text/css">
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-mrow-001.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-mrow-001.html index 1447645..cb154c6 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-mrow-001.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-mrow-001.html
@@ -3,8 +3,8 @@ <head> <meta charset="utf-8"> <title>Fraction mrow</title> - <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mfrac"> - <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mrow"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#fractions-mfrac"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#horizontally-group-sub-expressions-mrow"> <meta name="assert" content="This test that <mrow> elements can be used as numerator and denominator of fractions."> <link rel="match" href="frac-mrow-001-ref.html"> </head>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-numalign-denomalign-001.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-numalign-denomalign-001.html index d734f1d1..59d663f 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-numalign-denomalign-001.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-numalign-denomalign-001.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>Fraction numalign denomalign</title> - <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mfrac"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#fractions-mfrac"> <meta name="assert" content="This fraction alignment with the numalign/denomalign attributes."> <link rel="match" href="frac-numalign-denomalign-001-ref.html"> </head>
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 59e335a..55404fa 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
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>Fraction parameters</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mfrac"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#fractions-mfrac"> <meta name="assert" content="Element mfrac correctly uses the fraction parameters from the MATH table."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
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 b1ee502..63ab9776 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
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>Stack parameters</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mfrac"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#fractions-mfrac"> <meta name="assert" content="Element mfrac correctly uses the stack parameters from the MATH table."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-visibility-001.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-visibility-001.html index 8fbf5ac..65b9505 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-visibility-001.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/fractions/frac-visibility-001.html
@@ -3,7 +3,8 @@ <head> <meta charset="utf-8"> <title>Fraction bar visibility</title> - <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mfrac"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#fractions-mfrac"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> <meta name="assert" content="The CSS visible property affects the rendering of the fraction bar."> <link rel="match" href="frac-visibility-001-ref.html"> </head>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/mrow/inferred-mrow-baseline.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/mrow/inferred-mrow-baseline.html index 0904d9f1..672d90d 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/mrow/inferred-mrow-baseline.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/mrow/inferred-mrow-baseline.html
@@ -3,7 +3,14 @@ <head> <meta charset="utf-8"> <title>Baseline of inferred mrows</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mrow"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#horizontally-group-sub-expressions-mrow"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#radicals-msqrt-mroot"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#style-change-mstyle"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#error-message-merror"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#making-sub-expressions-invisible-mphantom"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-top-level-math-element"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#enclose-expression-inside-notation-menclose"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#adjust-space-around-content-mpadded"> <meta name="assert" content="Baseline for mrow-like elements is correct."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/mrow/inferred-mrow-stretchy.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/mrow/inferred-mrow-stretchy.html index f75726c1..75587d0 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/mrow/inferred-mrow-stretchy.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/mrow/inferred-mrow-stretchy.html
@@ -3,8 +3,16 @@ <head> <meta charset="utf-8"> <title>Stretchy in inferred mrows</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mrow"> -<meta name="assert" content="Baseline for mrow-like elements is correct."> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#horizontally-group-sub-expressions-mrow"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#radicals-msqrt-mroot"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#style-change-mstyle"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#error-message-merror"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#making-sub-expressions-invisible-mphantom"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-top-level-math-element"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#enclose-expression-inside-notation-menclose"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#adjust-space-around-content-mpadded"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<meta name="assert" content="Operators can stretch inside mrow-like elements."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <style>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-axis-height-1.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-axis-height-1.html index c88484b9..63595b02 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-axis-height-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-axis-height-1.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>mo axis height</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#tokenmo"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> <meta name="assert" content="Element mo correctly uses the axis height parameter from the MATH table."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-form-dynamic.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-form-dynamic.html index dcd1ec5..fff3bd9 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-form-dynamic.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-form-dynamic.html
@@ -3,7 +3,8 @@ <head> <meta charset="utf-8"/> <title><mo> dynamic form</title> - <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#tokenmo"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#dom-and-javascript"> <meta name="assert" content="This test verifies that the form of the operators (and thus their spacing) is updated when you change the child list."> <link rel="match" href="mo-form-dynamic-ref.html">
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-form-fallback.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-form-fallback.html index aab62087..b517dd5 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-form-fallback.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-form-fallback.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"/> <title>form fallback</title> - <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#tokenmo"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> <meta name="assert" content="Verify fallback to postfix/prefix forms."> <link rel="match" href="mo-form-fallback-ref.html"> </head>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-form-minus-plus.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-form-minus-plus.html index 8a4ac3d..487bca25 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-form-minus-plus.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-form-minus-plus.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"/> <title>form plus/minus</title> - <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#tokenmo"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> <meta name="assert" content="Verifies behavior of form of plus/minus etc."> <link rel="match" href="mo-form-minus-plus-ref.html"> </head>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-form.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-form.html index 7c11c14..4f651d1 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-form.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-form.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"/> <title><mo> form attribute</title> - <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#tokenmo"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> <meta name="assert" content="Verifies behavior of form attribute."> <link rel="match" href="mo-form-ref.html"> </head>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-movablelimits-default.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-movablelimits-default.html index cd01fe4..a05bef4 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-movablelimits-default.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-movablelimits-default.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"/> <title><mo> movablelimits default value</title> - <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#tokenmo"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> <meta name="assert" content="Verifies default value of movablelimits for some operators."> <link rel="match" href="mo-movablelimits-default-ref.html"> </head>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-movablelimits-dynamic.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-movablelimits-dynamic.html index a92c6c0..53cf76c 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-movablelimits-dynamic.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-movablelimits-dynamic.html
@@ -3,7 +3,8 @@ <head> <meta charset="utf-8"/> <title>Test dynamically removing movablelimits attribute</title> - <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#tokenmo"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#dom-and-javascript"> <meta name="assert" content="Verifies dynamically removing movablelimits."> <link rel="match" href="mo-movablelimits-dynamic-ref.html"> <script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-movablelimits.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-movablelimits.html index 08555941..9be866f 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-movablelimits.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-movablelimits.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"/> <title><mo> movablelimits</title> - <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#tokenmo"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> <meta name="assert" content="Verifies effect of movablelimits on mo in both displaystyle modes."> <link rel="match" href="mo-movablelimits-ref.html"> </head>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-paint-lspace-rspace.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-paint-lspace-rspace.html index 879962c4..8fb095b 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-paint-lspace-rspace.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/operators/mo-paint-lspace-rspace.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title><mo> paint lspace rspace</title> - <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#tokenmo"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> <meta name="assert" content="Verifies values for lspace and rspace for element mo in LTR and RTL modes."> <link rel="match" href="mo-paint-lspace-rspace-ref.html"> </head>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/radicals/root-parameters-1.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/radicals/root-parameters-1.html index 51d4713..5ad0b73 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/radicals/root-parameters-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/radicals/root-parameters-1.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>Radical parameters</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#msqrt"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#radicals-msqrt-mroot"> <meta name="assert" content="Elements msqrt and mroot correctly use the radical parameters from the MATH table."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-1.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-1.html index 447aa66d..01a6b0e 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-1.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>Subscripts and Superscripts metrics</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#msubmsup"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#subscripts-and-superscripts-msub-msup-msubsup"> <meta name="assert" content="Basic metrics for elements msub, msup and msubsup."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-2.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-2.html index 9e2b6db..2fd6963 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-2.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-2.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>Subscripts and Superscripts metrics</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#msubmsup"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#subscripts-and-superscripts-msub-msup-msubsup"> <meta name="assert" content="Basic metrics for the mmultiscript element."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-3.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-3.html index 742fa8c..60df24a 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-3.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-3.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>Subscripts and Superscripts metrics</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#msubmsup"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#subscripts-and-superscripts-msub-msup-msubsup"> <meta name="assert" content="Basic metrics for the mmultiscript element with many scripts."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-4.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-4.html index fc70fef..68867660 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-4.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-4.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>Subscripts and Superscripts metrics</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#msubmsup"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#subscripts-and-superscripts-msub-msup-msubsup"> <meta name="assert" content="Verify metrics of scripted elements for bases of different heights."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-5.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-5.html index a67d68d..2cc4e6d9 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-5.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-5.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>Subscripts and Superscripts metrics</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#msubmsup"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#subscripts-and-superscripts-msub-msup-msubsup"> <meta name="assert" content="Verify metrics of scripted elements with tall scripts."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-parameters-1.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-parameters-1.html index 208a0a87..7503ad16 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-parameters-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-parameters-1.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>Subscripts and Superscripts parameters</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#msubmsup"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#subscripts-and-superscripts-msub-msup-msubsup"> <meta name="assert" content="Elements msub, msup, subsup and msubsup correctly use the subscript and superscript parameters from the MATH table."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-parameters-2.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-parameters-2.html index 4a9db661..62aa7a9d 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-parameters-2.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/subsup-parameters-2.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>Subscripts and Superscripts parameters</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#msubmsup"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#subscripts-and-superscripts-msub-msup-msubsup"> <meta name="assert" content="Elements msub, msup, subsup and msubsup correctly use the italic correction from the MATH table."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-1.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-1.html index 45367e3..b178355 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-1.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>Underscripts and Overscripts parameters</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mundermover"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> <meta name="assert" content="Elements munder, mover, munderover correctly ."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-1.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-1.html index cc09abb..d8a564a 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-1.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>Underscripts and Overscripts parameters</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mundermover"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> <meta name="assert" content="Elements munder, mover, munderover correctly use the limit parameters from the MATH table."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-2.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-2.html index d6d9185..c10f77e 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-2.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-2.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>Underscripts and Overscripts parameters</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mundermover"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> <meta name="assert" content="Elements munder, mover, munderover correctly use the stretch stack parameters from the MATH table."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-3.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-3.html index 23c7dfa..86562fd 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-3.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-3.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>Underscripts and Overscripts parameters</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mundermover"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> <meta name="assert" content="Elements munder, mover, munderover correctly use underbar/overbar and AccentBaseHeight parameters from the MATH table."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-4.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-4.html index bfc3caf..f7fb389 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-4.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-parameters-4.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>Underscripts and Overscripts parameters</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mundermover"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> <meta name="assert" content="Elements munder, mover, munderover correctly use underbar/overbar and AccentBaseHeight parameters from the MATH table."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/spaces/mspace-children.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/spaces/mspace-children.html index 90d524ab..8824c79 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/spaces/mspace-children.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/spaces/mspace-children.html
@@ -2,7 +2,7 @@ <head> <meta charset="utf-8"> <title>space</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mspace"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#space-mspace"> <link rel="match" href="mspace-children-ref.html"/> <meta name="assert" content="Verify mspace visual rendering of its children"> </head>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/spaces/space-1.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/spaces/space-1.html index 7bc5b8e..53734dee 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/spaces/space-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/spaces/space-1.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>Space</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mspace"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#space-mspace"> <meta name="assert" content="Verify mspace metrics for different values of height, depth and width"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/spaces/space-2.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/spaces/space-2.html index 5b8351a1..d7b38458 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/spaces/space-2.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/spaces/space-2.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>space</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mspace"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#space-mspace"> <link rel="match" href="space-2-ref.html"/> <meta name="assert" content="Verify mspace visual rendering for different values of height, depth and width"> </head>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/tables/table-axis-height.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/tables/table-axis-height.html index e723008..feb2907 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/tables/table-axis-height.html +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/tables/table-axis-height.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>table axis height</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#tables"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#table-or-matrix-mtable"> <meta name="assert" content="Element mtable correctly uses the axis height parameter from the MATH table."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/color-1.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/color-1.html index 8158cec6..4d9d084 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/color-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/color-1.html
@@ -3,7 +3,11 @@ <head> <meta charset="utf-8"> <title>color</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#cssstyling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#text-mtext"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#fraction-with-nonzero-line-thickness"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#radical-symbol"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#enclose-expression-inside-notation-menclose"> <link rel="match" href="color-1-ref.html"/> <meta name="assert" content="Verify that the color is used for text and graphical elements."> </head>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/display-1.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/display-1.html index 9ae6fe0b..38dd0baf 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/display-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/display-1.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>display</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#cssstyling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> <link rel="match" href="display-1-ref.html"/> <meta name="assert" content="Verify that the 'display: none' property works on MathML elements."> </head>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/displaystyle-1.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/displaystyle-1.html index ddb2173a..c2ccb78 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/displaystyle-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/displaystyle-1.html
@@ -3,7 +3,9 @@ <head> <meta charset="utf-8"> <title>displaystyle</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#cssstyling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-math-style-property"> <meta name="assert" content="Verify that the correct inheritance of the displaystyle value by measuring the size of large operators."> <style> @font-face {
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/dynamic-dir-1.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/dynamic-dir-1.html index c4c99d87..3667ece8 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/dynamic-dir-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/dynamic-dir-1.html
@@ -2,9 +2,10 @@ <html class="reftest-wait"> <head> <meta charset="utf-8"> - <title>Test dynamically changing dir attribute</title></head> - <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#cssproperties"> - <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#dom"> + <title>Test dynamically changing dir attribute</title> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#dom-and-javascript"> <meta name="assert" content="The dir attribute should update direction map to css properties dynamically"> <link rel="match" href="dynamic-dir-1-ref.html"> <script> @@ -16,10 +17,10 @@ ["math", "mstyle", "mrow"].forEach((tag) => { let elements = document.getElementsByTagName(tag); - // set an explcit rtl where there was none + // set an explicit rtl where there was none elements[0].setAttribute("dir", "rtl"); - // change explcit ltr to rtl + // change explicit ltr to rtl elements[1].setAttribute("dir", "rtl"); // remove an explicitly set dir="rtl" @@ -99,4 +100,4 @@ </math> </p> </body> -</html> \ No newline at end of file +</html>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/lengths-1.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/lengths-1.html index 30916d5..9b0c27a 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/lengths-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/lengths-1.html
@@ -3,7 +3,10 @@ <head> <meta charset="utf-8"/> <title>MathML lengths</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#cssstyling"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#types-for-mathml-attribute-values"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#legacy-mathml-style-attributes"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#space-mspace"> <link rel="match" href="lengths-1-ref.html"/> <meta name="assert" content="Verify whether the different units are accepted for MathML lengths."> <style>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/lengths-2.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/lengths-2.html index aa38e97..73fd23bb 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/lengths-2.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/lengths-2.html
@@ -3,7 +3,10 @@ <head> <meta charset="utf-8"> <title>MathML lengths</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#cssstyling"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#types-for-mathml-attribute-values"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#legacy-mathml-style-attributes"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#space-mspace"> <meta name="assert" content="Verify various cases of the MathML length syntax."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathsize-attribute.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathsize-attribute.html index 00d12e4..803f236 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathsize-attribute.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathsize-attribute.html
@@ -3,6 +3,7 @@ <head> <meta charset="utf-8"/> <title>Verify mathsize attribute</title> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#legacy-mathml-style-attributes"> <meta name="assert" content="Verify mathsize attribute values."> <link rel="match" href="mathsize-attribute-ref.html">
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-bold-fraktur.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-bold-fraktur.html index f414181..8085ad5 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-bold-fraktur.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-bold-fraktur.html
@@ -3,7 +3,9 @@ <head> <meta charset="utf-8"/> <title>mathvariant bold-fraktur</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#cssproperties"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-mathvariant-attribute"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#new-text-transform-values"> <link rel="match" href="mathvariant-bold-fraktur-ref.html"/> <meta name="assert" content="Verify that a single-char <mtext> with a bold-fraktur mathvariant is equivalent to an <mtext> with the transformed unicode character."> <style>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-bold-italic.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-bold-italic.html index 7b53e986..1e1b0b0d 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-bold-italic.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-bold-italic.html
@@ -3,7 +3,9 @@ <head> <meta charset="utf-8"/> <title>mathvariant bold-italic</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#cssproperties"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-mathvariant-attribute"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#new-text-transform-values"> <link rel="match" href="mathvariant-bold-italic-ref.html"/> <meta name="assert" content="Verify that a single-char <mtext> with a bold-italic mathvariant is equivalent to an <mtext> with the transformed unicode character."> <style>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-bold-sans-serif.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-bold-sans-serif.html index 544db02f..cd6cc7a 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-bold-sans-serif.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-bold-sans-serif.html
@@ -3,7 +3,9 @@ <head> <meta charset="utf-8"/> <title>mathvariant bold-sans-serif</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#cssproperties"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-mathvariant-attribute"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#new-text-transform-values"> <link rel="match" href="mathvariant-bold-sans-serif-ref.html"/> <meta name="assert" content="Verify that a single-char <mtext> with a bold-sans-serif mathvariant is equivalent to an <mtext> with the transformed unicode character."> <style>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-bold-script.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-bold-script.html index dc48fbea..8ff7556da 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-bold-script.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-bold-script.html
@@ -3,7 +3,9 @@ <head> <meta charset="utf-8"/> <title>mathvariant bold-script</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#cssproperties"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-mathvariant-attribute"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#new-text-transform-values"> <link rel="match" href="mathvariant-bold-script-ref.html"/> <meta name="assert" content="Verify that a single-char <mtext> with a bold-script mathvariant is equivalent to an <mtext> with the transformed unicode character."> <style>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-bold.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-bold.html index a51be7b..f11594f 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-bold.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-bold.html
@@ -3,7 +3,9 @@ <head> <meta charset="utf-8"/> <title>mathvariant bold</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#cssproperties"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-mathvariant-attribute"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#new-text-transform-values"> <link rel="match" href="mathvariant-bold-ref.html"/> <meta name="assert" content="Verify that a single-char <mtext> with a bold mathvariant is equivalent to an <mtext> with the transformed unicode character."> <style>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-double-struck.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-double-struck.html index 3090fdc..856672b 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-double-struck.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-double-struck.html
@@ -3,7 +3,9 @@ <head> <meta charset="utf-8"/> <title>mathvariant double-struck</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#cssproperties"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-mathvariant-attribute"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#new-text-transform-values"> <link rel="match" href="mathvariant-double-struck-ref.html"/> <meta name="assert" content="Verify that a single-char <mtext> with a double-struck mathvariant is equivalent to an <mtext> with the transformed unicode character."> <style>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-fraktur.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-fraktur.html index 8bd15a55..8ef57a0 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-fraktur.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-fraktur.html
@@ -3,7 +3,9 @@ <head> <meta charset="utf-8"/> <title>mathvariant fraktur</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#cssproperties"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-mathvariant-attribute"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#new-text-transform-values"> <link rel="match" href="mathvariant-fraktur-ref.html"/> <meta name="assert" content="Verify that a single-char <mtext> with a fraktur mathvariant is equivalent to an <mtext> with the transformed unicode character."> <style>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-initial.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-initial.html index 58751bd1..de4b89f 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-initial.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-initial.html
@@ -3,7 +3,9 @@ <head> <meta charset="utf-8"/> <title>mathvariant initial</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#cssproperties"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-mathvariant-attribute"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#new-text-transform-values"> <link rel="match" href="mathvariant-initial-ref.html"/> <meta name="assert" content="Verify that a single-char <mtext> with a initial mathvariant is equivalent to an <mtext> with the transformed unicode character."> <style>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-italic.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-italic.html index 5bcbd32..4cf3de04 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-italic.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-italic.html
@@ -3,7 +3,9 @@ <head> <meta charset="utf-8"/> <title>mathvariant italic</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#cssproperties"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-mathvariant-attribute"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#new-text-transform-values"> <link rel="match" href="mathvariant-italic-ref.html"/> <meta name="assert" content="Verify that a single-char <mtext> with a italic mathvariant is equivalent to an <mtext> with the transformed unicode character."> <style>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-looped.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-looped.html index 0326e86e..2a774c7 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-looped.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-looped.html
@@ -3,7 +3,9 @@ <head> <meta charset="utf-8"/> <title>mathvariant looped</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#cssproperties"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-mathvariant-attribute"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#new-text-transform-values"> <link rel="match" href="mathvariant-looped-ref.html"/> <meta name="assert" content="Verify that a single-char <mtext> with a looped mathvariant is equivalent to an <mtext> with the transformed unicode character."> <style>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-monospace.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-monospace.html index 8d9a5d3..1c23630 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-monospace.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-monospace.html
@@ -3,7 +3,9 @@ <head> <meta charset="utf-8"/> <title>mathvariant monospace</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#cssproperties"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-mathvariant-attribute"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#new-text-transform-values"> <link rel="match" href="mathvariant-monospace-ref.html"/> <meta name="assert" content="Verify that a single-char <mtext> with a monospace mathvariant is equivalent to an <mtext> with the transformed unicode character."> <style>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-sans-serif-bold-italic.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-sans-serif-bold-italic.html index 21401bc..f67a6ab 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-sans-serif-bold-italic.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-sans-serif-bold-italic.html
@@ -3,7 +3,9 @@ <head> <meta charset="utf-8"/> <title>mathvariant sans-serif-bold-italic</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#cssproperties"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-mathvariant-attribute"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#new-text-transform-values"> <link rel="match" href="mathvariant-sans-serif-bold-italic-ref.html"/> <meta name="assert" content="Verify that a single-char <mtext> with a sans-serif-bold-italic mathvariant is equivalent to an <mtext> with the transformed unicode character."> <style>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-sans-serif-italic.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-sans-serif-italic.html index 2573872..ab43df5 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-sans-serif-italic.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-sans-serif-italic.html
@@ -3,7 +3,9 @@ <head> <meta charset="utf-8"/> <title>mathvariant sans-serif-italic</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#cssproperties"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-mathvariant-attribute"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#new-text-transform-values"> <link rel="match" href="mathvariant-sans-serif-italic-ref.html"/> <meta name="assert" content="Verify that a single-char <mtext> with a sans-serif-italic mathvariant is equivalent to an <mtext> with the transformed unicode character."> <style>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-sans-serif.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-sans-serif.html index 513e035..bfee81c0 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-sans-serif.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-sans-serif.html
@@ -3,7 +3,9 @@ <head> <meta charset="utf-8"/> <title>mathvariant sans-serif</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#cssproperties"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-mathvariant-attribute"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#new-text-transform-values"> <link rel="match" href="mathvariant-sans-serif-ref.html"/> <meta name="assert" content="Verify that a single-char <mtext> with a sans-serif mathvariant is equivalent to an <mtext> with the transformed unicode character."> <style>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-script.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-script.html index efd3f7e..dd7ab6a 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-script.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-script.html
@@ -3,7 +3,9 @@ <head> <meta charset="utf-8"/> <title>mathvariant script</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#cssproperties"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-mathvariant-attribute"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#new-text-transform-values"> <link rel="match" href="mathvariant-script-ref.html"/> <meta name="assert" content="Verify that a single-char <mtext> with a script mathvariant is equivalent to an <mtext> with the transformed unicode character."> <style>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-stretched.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-stretched.html index 20c5a39..8530c688 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-stretched.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-stretched.html
@@ -3,7 +3,9 @@ <head> <meta charset="utf-8"/> <title>mathvariant stretched</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#cssproperties"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-mathvariant-attribute"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#new-text-transform-values"> <link rel="match" href="mathvariant-stretched-ref.html"/> <meta name="assert" content="Verify that a single-char <mtext> with a stretched mathvariant is equivalent to an <mtext> with the transformed unicode character."> <style>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-tailed.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-tailed.html index c88d433c..823438e 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-tailed.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathvariant-tailed.html
@@ -3,7 +3,9 @@ <head> <meta charset="utf-8"/> <title>mathvariant tailed</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#cssproperties"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-mathvariant-attribute"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#new-text-transform-values"> <link rel="match" href="mathvariant-tailed-ref.html"/> <meta name="assert" content="Verify that a single-char <mtext> with a tailed mathvariant is equivalent to an <mtext> with the transformed unicode character."> <style>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/visibility-1.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/visibility-1.html index c84f97ae..7083ef7 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/visibility-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/visibility-1.html
@@ -3,7 +3,11 @@ <head> <meta charset="utf-8"> <title>visibility</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#cssstyling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#text-mtext"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#fraction-with-nonzero-line-thickness"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#radical-symbol"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#enclose-expression-inside-notation-menclose"> <link rel="match" href="visibility-1-ref.html"/> <meta name="assert" content="Verify that visibility=hidden is used for text and graphical elements."> </head>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/class-1.html b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/class-1.html index ee4b4b5..a1efbd2 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/class-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/class-1.html
@@ -3,7 +3,8 @@ <head> <meta charset="utf-8"/> <title>Class</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mathmltree"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> <link rel="match" href="class-1-ref.html"/> <meta name="assert" content="Verify that the class attribute affects CSS selectors."> <style>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/class-2.html b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/class-2.html index 4e1ae6b..8d6515af 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/class-2.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/class-2.html
@@ -3,7 +3,8 @@ <head> <meta charset="utf-8"> <title>Class</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mathmltree"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#dom-and-javascript"> <meta name="assert" content="Verify whether the getElementsByClassName() works for MathML elements."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/color-attributes-1.html b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/color-attributes-1.html index 6f9f937..585aeba 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/color-attributes-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/color-attributes-1.html
@@ -3,7 +3,8 @@ <head> <meta charset="utf-8"/> <title>Color Attributes</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mathmltree"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#legacy-mathml-style-attributes"> <meta name="assert" content="Verify that the mathcolor and mathbackground attributes are supported on the math element."> <link rel="match" href="color-attributes-1-ref.html"/> <style>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/display-1.html b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/display-1.html index 77038ee2..3a180f5d 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/display-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/display-1.html
@@ -3,7 +3,8 @@ <head> <meta charset="utf-8"/> <title>MathML display attribute</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mathmltree"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-top-level-math-element"> <meta name="assert" content="Verify that the display attribute on the math element is supported and impacts centering and line breaking with surrounding content."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/dynamic-1.html b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/dynamic-1.html index 48fdd2591..b4d603a9 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/dynamic-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/dynamic-1.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"/> <title>Dynamic MathML DOM</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#dom"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#dom-and-javascript"/> <link rel="match" href="dynamic-1-ref.html"/> <meta name="assert" content="Verify that the MathML DOM tree can be modified via javascript and that the rendering is correctly updated."> <style>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/href-click-1.html b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/href-click-1.html index dd6b7990..bf902b5e 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/href-click-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/href-click-1.html
@@ -3,7 +3,8 @@ <head> <meta charset="utf-8"/> <title>href click</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mathmltree"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#dom-and-javascript"> <link rel="match" href="href-click-1-ref.html"/> <meta name="assert" content="Verify that a click on a link moves to the target."> <script type="text/javascript">
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/href-click-2.html b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/href-click-2.html index 4c5253d..c23d87c2 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/href-click-2.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/href-click-2.html
@@ -3,7 +3,8 @@ <head> <meta charset="utf-8"/> <title>href click</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mathmltree"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#dom-and-javascript"> <link rel="match" href="href-click-2-ref.html"/> <meta name="assert" content="Verify that a click on an element bubbles to an ancestor link."> <script type="text/javascript">
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/href-click-3.html b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/href-click-3.html index f2863fe..a8475ea 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/href-click-3.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/href-click-3.html
@@ -3,7 +3,8 @@ <head> <meta charset="utf-8"> <title>href click</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mathmltree"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#dom-and-javascript"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <script src="/resources/testdriver.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/integration-point-1.html b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/integration-point-1.html index 3221a67..4d10af8 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/integration-point-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/integration-point-1.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"/> <title>MathML inside foreignObject</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#dom"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#html-and-svg"> <link rel="match" href="integration-point-1-ref.html"/> <meta name="assert" content="Verify that MathML can be used inside a foreignObject element."> </head>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/integration-point-2.html b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/integration-point-2.html index d42eeb0..20d499d 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/integration-point-2.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/integration-point-2.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"/> <title>MathML as a phrasing content</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#dom"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#html-and-svg"> <link rel="match" href="integration-point-2-ref.html"/> <meta name="assert" content="Verify that MathML can be used at positions where phrasing content is accepted."> <style type="text/css">
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/integration-point-3.html b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/integration-point-3.html index 1feb8317..1f62d8e 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/integration-point-3.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/integration-point-3.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"/> <title>phrasing content inside mtext</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#dom"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#html-and-svg"> <link rel="match" href="integration-point-3-ref.html"/> <meta name="assert" content="Verify that <mtext> can contain phrasing content"> <style type="text/css">
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/required-extensions-2.html b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/required-extensions-2.html index 1d7af04..e1d7a85 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/required-extensions-2.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/required-extensions-2.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"/> <title>SVG requiredExtensions</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#dom"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#html-and-svg"> <link rel="match" href="required-extensions-2-ref.html"/> <meta name="assert" content="Verify that a foreignObject with MathML used as a requiredExtensions value is selected for display in a SVG switch element."> </head>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/unique-identifier-1.html b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/unique-identifier-1.html index 42a547a..e2315f14 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/unique-identifier-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/unique-identifier-1.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"/> <title>Unique identifier</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mathmltree"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> <link rel="match" href="unique-identifier-1-ref.html"/> <meta name="assert" content="Verify that the id on a MathML element can be used as a fragment identifier in order to force initial scrolling."> </head>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/unique-identifier-2.html b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/unique-identifier-2.html index 421ad7a..2c3190c 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/unique-identifier-2.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/unique-identifier-2.html
@@ -3,7 +3,8 @@ <head> <meta charset="utf-8"> <title>Unique Identifier</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mathmltree"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#dom-and-javascript"> <meta name="assert" content="Verify whether the getElementById() works for MathML elements."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/unique-identifier-3.html b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/unique-identifier-3.html index c58e502..7cfac89e 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/unique-identifier-3.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/unique-identifier-3.html
@@ -3,7 +3,8 @@ <head> <meta charset="utf-8"/> <title>Unique Identifier</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#mathmltree"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling"> <link rel="match" href="unique-identifier-3-ref.html"/> <meta name="assert" content="Verify that the id attribute affects CSS selectors."> <style>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/text-and-math/use-typo-metrics-1.html b/third_party/blink/web_tests/external/wpt/mathml/relations/text-and-math/use-typo-metrics-1.html index 3797aef5..4e92a84 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/text-and-math/use-typo-metrics-1.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/text-and-math/use-typo-metrics-1.html
@@ -1,7 +1,7 @@ <!DOCTYPE html> <meta charset="utf-8"/> <title>Open Font Format: USE_TYPO_METRICS</title> -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#openfontformat"/> +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#text-layout"/> <link rel="match" href="use-typo-metrics-1-ref.html"/> <meta name="assert" content="Verify that the USE_TYPO_METRICS flag from the OS/2 table is taken into account to calculate line height."> <style>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/tools/mathvariant-transforms.py b/third_party/blink/web_tests/external/wpt/mathml/tools/mathvariant-transforms.py index ba99b59..51c7c18 100755 --- a/third_party/blink/web_tests/external/wpt/mathml/tools/mathvariant-transforms.py +++ b/third_party/blink/web_tests/external/wpt/mathml/tools/mathvariant-transforms.py
@@ -81,7 +81,9 @@ reftest.write(source % mathvariant) reftestReference.write(source % ("%s (reference)" % mathvariant)) source ='\ -<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#cssproperties"/>\n\ +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling">\n\ +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-mathvariant-attribute">\n\ +<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#new-text-transform-values">\n\ <link rel="match" href="mathvariant-%s-ref.html"/>\n\ <meta name="assert" content="Verify that a single-char <mtext> with a %s mathvariant is equivalent to an <mtext> with the transformed unicode character.">\n' reftest.write(source % (mathvariant, mathvariant))
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_support.js b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_support.js index 9a491dd6..ae9b55c 100644 --- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_support.js +++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_support.js
@@ -325,3 +325,31 @@ .pointerUp() .send(); } + +function pointerHoverInTarget(pointerType, target, direction) { + var x_delta = 0; + var y_delta = 0; + if (direction == "down") { + x_delta = 0; + y_delta = 10; + } else if (direction == "up") { + x_delta = 0; + y_delta = -10; + } else if (direction == "right") { + x_delta = 10; + y_delta = 0; + } else if (direction == "left") { + x_delta = -10; + y_delta = 0; + } else { + throw("drag direction '" + direction + "' is not expected, direction should be 'down', 'up', 'left' or 'right'"); + } + var pointerId = pointerType + "Pointer1"; + return new test_driver.Actions() + .addPointer(pointerId, pointerType) + .pointerMove(0, 0, {origin: target}) + .pointerMove(x_delta, y_delta, {origin: target}) + .pointerMove(2 * x_delta, 2 * y_delta, {origin: target}) + .pointerMove(3 * x_delta, 3 * y_delta, {origin: target}) + .send(); +}
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerlock/pointerevent_movementxy_when_locked.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerlock/pointerevent_movementxy_when_locked.html deleted file mode 100644 index bdad97df..0000000 --- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerlock/pointerevent_movementxy_when_locked.html +++ /dev/null
@@ -1,89 +0,0 @@ -<!doctype html> -<html> - <head> - <title>Pointer Events pointer lock tests</title> - <meta name="viewport" content="width=device-width"> - <link rel="stylesheet" type="text/css" href="/external/wpt/pointerevents/pointerevent_styles.css"> - <script src="/resources/testharness.js"></script> - <script src="/resources/testharnessreport.js"></script> - <script src="/resources/testdriver.js"></script> - <script src="/resources/testdriver-actions.js"></script> - <script src="/resources/testdriver-vendor.js"></script> - <script type="text/javascript" src="../pointerevent_support.js"></script> - <style> - #testContainer { - touch-action: none; - user-select: none; - position: relative; - } - </style> - <script> - var lock_change_count = 0; - var mouseeventMovements = [] - var pointereventMovements = [] - - function resetTestState() { - } - - function run() { - var test_pointerEvent = setup_pointerevent_test("pointerevent movementX/Y when lock test", ['mouse']); - var div1 = document.getElementById("target"); - - on_event(div1, 'pointerdown', function(event) { - if (lock_change_count == 0) - div1.requestPointerLock(); - }); - on_event(div1, 'pointerup', function(event) { - if (lock_change_count == 1) - document.exitPointerLock(); - }); - on_event(div1, 'pointermove', function(event) { - if (lock_change_count == 1) { - pointereventMovements.push(`${event.movementX}, ${event.movementY}`); - } - }); - on_event(div1, 'mousemove', function(event) { - if (lock_change_count == 1) { - mouseeventMovements.push(`${event.movementX}, ${event.movementY}`); - } - }); - on_event(document, 'pointerlockchange', function(event) { - lock_change_count++; - if (lock_change_count == 1) { - test_pointerEvent.step(function() { - assert_equals(document.pointerLockElement, div1, "document.pointerLockElement should be div1."); - }); - } else if (lock_change_count == 2) { - test_pointerEvent.step(function() { - assert_equals(document.pointerLockElement, null, "document.pointerLockElement should be null."); - assert_not_equals(mouseeventMovements.length, 0); - assert_array_equals(pointereventMovements, mouseeventMovements, "pointermove should have movementX/Y same as mousemove"); - }); - test_pointerEvent.done(); - } - }); - - // Inject mouse inputs. - pointerDragInTarget('mouse', target, 'right'); - } - </script> - </head> - <body onload="run()"> - <h1>Pointer Events movement in locked state test</h1> - <h2 id="pointerTypeDescription"></h2> - <h4> - Test Description: This test checks if pointermove.movementX/Y matches mousemove.movementX/Y when pointer is locked. - <ol> - <li>Press left button down on the green rectangle and hold it.</li> - <li>Move the mouse inside the green rectangle.</li> - </ol> - </ol> - - Test passes if the proper behavior of the events is observed. - </h4> - <div id="testContainer"> - <div id="target" style="width:800px;height:250px;background:green"></div> - </div> - <div class="spacer"></div> - </body> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerlock/pointerevent_movementxy_with_pointerlock.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerlock/pointerevent_movementxy_with_pointerlock.html new file mode 100644 index 0000000..376d0e6 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerlock/pointerevent_movementxy_with_pointerlock.html
@@ -0,0 +1,127 @@ +<!doctype html> +<html> + <head> + <title>Pointer Events pointer lock tests</title> + <meta name="viewport" content="width=device-width"> + <link rel="stylesheet" type="text/css" href="/external/wpt/pointerevents/pointerevent_styles.css"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/resources/testdriver.js"></script> + <script src="/resources/testdriver-actions.js"></script> + <script src="/resources/testdriver-vendor.js"></script> + <script type="text/javascript" src="../pointerevent_support.js"></script> + <style> + #testContainer { + touch-action: none; + user-select: none; + position: relative; + } + </style> + <script> + PhaseEnum = { + BeforeLocked: 0, + PointerLocked: 1, + PointerUnlocked: 2, + Done: 3, + }; + var phase = PhaseEnum.BeforeLocked; + var last_event; + var mouseeventMovements = [] + var pointereventMovements = [] + + function resetTestState() { + } + + function run() { + var test_pointerEvent = setup_pointerevent_test("pointerevent movementX/Y with pointerlock test", ['mouse']); + + function testPointerMoves(event) { + if (last_event) { + if (phase == PhaseEnum.PointerLocked){ + test_pointerEvent.step(function() { + assert_equals(event.screenX, last_event.screenX); + assert_equals(event.screenY, last_event.screenY); + }); + } else { // BeforeLocked || Unlocked + test_pointerEvent.step(function() { + assert_equals(event.screenX - last_event.screenX, event.movementX); + assert_equals(event.screenY - last_event.screenY, event.movementY); + }); + } + } + last_event = event; + } + + on_event(target, 'click', function(event) { + if (phase == PhaseEnum.BeforeLocked) + target.requestPointerLock(); + else if (phase == PhaseEnum.PointerLocked) + document.exitPointerLock(); + else if (phase == PhaseEnum.PointerUnlocked) + test_pointerEvent.done(); + }); + on_event(target, 'pointermove', function(event) { + if (phase == PhaseEnum.PointerLocked) { + pointereventMovements.push(`${event.movementX}, ${event.movementY}`); + } + testPointerMoves(event); + }); + on_event(target, 'mousemove', function(event) { + if (phase == PhaseEnum.PointerLocked) { + mouseeventMovements.push(`${event.movementX}, ${event.movementY}`); + } + }); + on_event(document, 'pointerlockchange', function(event) { + phase++; + if (phase == PhaseEnum.PointerLocked) { + test_pointerEvent.step(function() { + assert_equals(document.pointerLockElement, target, "document.pointerLockElement should be target."); + }); + } else if (phase == PhaseEnum.PointerUnlocked) { + test_pointerEvent.step(function() { + assert_equals(document.pointerLockElement, null, "document.pointerLockElement should be null."); + assert_not_equals(mouseeventMovements.length, 0); + assert_array_equals(pointereventMovements, mouseeventMovements, "pointermove should have movementX/Y same as mousemove"); + }); + } + }); + + // Inject mouse inputs. + pointerHoverInTarget('mouse', target, 'right').then(function() { + return clickInTarget("mouse", target); + }).then(function() { + return pointerHoverInTarget('mouse', target, 'right'); + }).then(function() { + return clickInTarget("mouse", target); + }).then(function() { + return pointerHoverInTarget('mouse', target, 'right'); + }).then(function() { + return clickInTarget("mouse", target); + }); + } + </script> + </head> + <body onload="run()"> + <h1>Pointer Events movement with pointerlock test</h1> + <h2 id="pointerTypeDescription"></h2> + <h4> + Test Description: This test checks pointerevent movementX/Y value with pointerlock. + It checks whether movement X/Y matches event.screenX/Y - last_event.screenX/Y when pointer is not locked; + And if pointermove.movementX/Y matches mousemove.movementX/Y when pointer is locked. + <ol> + <li>Move the mouse inside the green rectangle.</li> + <li>Click left button on the green rectangle.(Enter pointerlock)</li> + <li>Move the mouse around.</li> + <li>Click left button again</li> + <li>Move the mouse inside the green rectangle.</li> + <li>Click left button again to end the test.</li> + </ol> + + Test passes if the proper behavior of the events is observed. + </h4> + <div id="testContainer"> + <div id="target" style="width:800px;height:250px;background:green"></div> + </div> + <div class="spacer"></div> + </body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/block-eval.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/block-eval.tentative.html new file mode 100644 index 0000000..e1a6a69 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/trusted-types/block-eval.tentative.html
@@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html> +<head> + <script nonce="abc" src="/resources/testharness.js"></script> + <script nonce="abc" src="/resources/testharnessreport.js"></script> + <script nonce="abc" src="support/helper.sub.js"></script> + + <!-- Note: Trusted Types enforcement, and a CSP that does not blanket-allow eval. --> + <meta http-equiv="Content-Security-Policy" content="script-src 'nonce-abc'; trusted-types *"> +</head> +<body> +<script nonce="abc"> + let p = createScript_policy(window, 1); + test(t => { + assert_throws(new EvalError(), _ => { + eval('"hello there"') }); + }, "eval with plain string throws."); + + test(t => { + let s = eval(p.createScript('"Hello transformed string"')); + assert_equals(s, "Hello a cat string"); + }, "eval with TrustedScript works."); + + TrustedTypes.createPolicy("default", { createScript: createScriptJS }, true); + test(t => { + let s = eval('"Hello transformed untrusted string"'); + assert_equals(s, "Hello a cat untrusted string"); + }, "eval obeys default policy."); +</script> +
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/eval-with-permissive-csp.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/eval-with-permissive-csp.tentative.html new file mode 100644 index 0000000..68d119a5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/trusted-types/eval-with-permissive-csp.tentative.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<html> +<head> + <script nonce="abc" src="/resources/testharness.js"></script> + <script nonce="abc" src="/resources/testharnessreport.js"></script> + <script nonce="abc" src="support/helper.sub.js"></script> + + <!-- Note: Trusted Types enforcement, and a CSP that allows all eval. --> + <meta http-equiv="Content-Security-Policy" + content="script-src 'nonce-abc' 'unsafe-eval'; trusted-types *"> +</head> +<body> +<script nonce="abc"> + let p = createScript_policy(window, 1); + test(t => { + let s = eval('"hello there"'); + assert_equals(s, "hello there"); + }, "eval with plain string with Trusted Types and permissive CSP works."); + + test(t => { + let s = eval(p.createScript('"Hello transformed string"')); + assert_equals("" + s, "Hello a cat string"); + }, "eval with TrustedScript and permissive CSP works."); + + TrustedTypes.createPolicy("default", { createScript: createScriptJS }, true); + test(t => { + let s = eval('"Hello transformed untrusted string"'); + assert_equals(s, "Hello a cat untrusted string"); + }, "eval with default policy and permissive CSP still obeys default policy."); +</script> +
diff --git a/third_party/blink/web_tests/external/wpt/wake-lock/idlharness.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/wake-lock/idlharness.https.any-expected.txt deleted file mode 100644 index 4c1af702..0000000 --- a/third_party/blink/web_tests/external/wpt/wake-lock/idlharness.https.any-expected.txt +++ /dev/null
@@ -1,12 +0,0 @@ -This is a testharness.js-based test. -PASS idl_test setup -PASS WakeLock interface: existence and properties of interface object -PASS WakeLock interface object length -PASS WakeLock interface object name -PASS WakeLock interface: existence and properties of interface prototype object -PASS WakeLock interface: existence and properties of interface prototype object's "constructor" property -PASS WakeLock interface: existence and properties of interface prototype object's @@unscopables property -FAIL WakeLock interface: operation requestPermission(WakeLockType) assert_own_property: interface object missing static operation expected property "requestPermission" missing -PASS WakeLock interface: operation request(WakeLockType, WakeLockRequestOptions) -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/fast/canvas/canvas-fillText-getImageData-expected.html b/third_party/blink/web_tests/fast/canvas/canvas-fillText-getImageData-expected.html new file mode 100644 index 0000000..303420e --- /dev/null +++ b/third_party/blink/web_tests/fast/canvas/canvas-fillText-getImageData-expected.html
@@ -0,0 +1,14 @@ +<html> +<body> +<canvas id="c" width=50 height=20></canvas> +<script> +var c = document.getElementById('c'); +var ctx = c.getContext("2d", {alpha: false}); +ctx.fillStyle = "white"; +ctx.fillRect(0,0,500,500); +ctx.font = " 20px sans-serif"; +ctx.fillStyle = "black"; +ctx.fillText("Test", 0, 16); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/fast/canvas/canvas-fillText-getImageData.html b/third_party/blink/web_tests/fast/canvas/canvas-fillText-getImageData.html new file mode 100644 index 0000000..1956329c --- /dev/null +++ b/third_party/blink/web_tests/fast/canvas/canvas-fillText-getImageData.html
@@ -0,0 +1,15 @@ +<html> +<body> +<canvas id="c" width=50 height=20></canvas> +<script> +var c = document.getElementById('c'); +var ctx = c.getContext("2d", {alpha: false}); +ctx.fillStyle = "white"; +ctx.fillRect(0,0,500,500); +ctx.font = " 20px sans-serif"; +ctx.fillStyle = "black"; +ctx.fillText("Test", 0, 16); +var imdData = ctx.getImageData(0,0,10,10).data; +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/fast/canvas/canvas-fillText-todataUrl-expected.html b/third_party/blink/web_tests/fast/canvas/canvas-fillText-todataUrl-expected.html new file mode 100644 index 0000000..303420e --- /dev/null +++ b/third_party/blink/web_tests/fast/canvas/canvas-fillText-todataUrl-expected.html
@@ -0,0 +1,14 @@ +<html> +<body> +<canvas id="c" width=50 height=20></canvas> +<script> +var c = document.getElementById('c'); +var ctx = c.getContext("2d", {alpha: false}); +ctx.fillStyle = "white"; +ctx.fillRect(0,0,500,500); +ctx.font = " 20px sans-serif"; +ctx.fillStyle = "black"; +ctx.fillText("Test", 0, 16); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/fast/canvas/canvas-fillText-todataUrl.html b/third_party/blink/web_tests/fast/canvas/canvas-fillText-todataUrl.html new file mode 100644 index 0000000..932acc4a --- /dev/null +++ b/third_party/blink/web_tests/fast/canvas/canvas-fillText-todataUrl.html
@@ -0,0 +1,15 @@ +<html> +<body> +<canvas id="c" width=50 height=20></canvas> +<script> +var c = document.getElementById('c'); +var ctx = c.getContext("2d", {alpha: false}); +ctx.fillStyle = "white"; +ctx.fillRect(0,0,500,500); +ctx.font = " 20px sans-serif"; +ctx.fillStyle = "black"; +ctx.fillText("Test", 0, 16); +c.toDataURL(); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/fast/css/invalidation/first-line-change-inline-color-expected.html b/third_party/blink/web_tests/fast/css/invalidation/first-line-change-inline-color-expected.html new file mode 100644 index 0000000..09c518e --- /dev/null +++ b/third_party/blink/web_tests/fast/css/invalidation/first-line-change-inline-color-expected.html
@@ -0,0 +1,4 @@ +<!DOCTYPE html> +<!-- This expectation is wrong because of crbug.com/562418. + The inner span should have style="color: green". --> +<p style="color: red">Red <span>This text should be green.</span> Red</p>
diff --git a/third_party/blink/web_tests/fast/css/invalidation/first-line-change-inline-color-inherited-expected.html b/third_party/blink/web_tests/fast/css/invalidation/first-line-change-inline-color-inherited-expected.html new file mode 100644 index 0000000..09c518e --- /dev/null +++ b/third_party/blink/web_tests/fast/css/invalidation/first-line-change-inline-color-inherited-expected.html
@@ -0,0 +1,4 @@ +<!DOCTYPE html> +<!-- This expectation is wrong because of crbug.com/562418. + The inner span should have style="color: green". --> +<p style="color: red">Red <span>This text should be green.</span> Red</p>
diff --git a/third_party/blink/web_tests/fast/css/invalidation/first-line-change-inline-color-inherited.html b/third_party/blink/web_tests/fast/css/invalidation/first-line-change-inline-color-inherited.html new file mode 100644 index 0000000..e902e79 --- /dev/null +++ b/third_party/blink/web_tests/fast/css/invalidation/first-line-change-inline-color-inherited.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<style> + #block { color: green; } + #block::first-line { color: red; } + .green { color: green; } +</style> +<div id="block"> + <div> + <p>Red <span id="t"><span>This text should be green.<span></span> Red</p> + </div> +</div> +<script src="../../../resources/run-after-layout-and-paint.js"></script> +<script> +runAfterLayoutAndPaint(function() { + document.getElementById('t').className = 'green'; +}, true); +</script>
diff --git a/third_party/blink/web_tests/fast/css/invalidation/first-line-change-inline-color.html b/third_party/blink/web_tests/fast/css/invalidation/first-line-change-inline-color.html new file mode 100644 index 0000000..eeab74e0 --- /dev/null +++ b/third_party/blink/web_tests/fast/css/invalidation/first-line-change-inline-color.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<style> + #block { color: green; } + #block::first-line { color: red; } + .green { color: green; } +</style> +<div id="block"> + <div> + <p>Red <span id="t">This text should be green.</span> Red</p> + </div> +</div> +<script src="../../../resources/run-after-layout-and-paint.js"></script> +<script> +runAfterLayoutAndPaint(function() { + document.getElementById('t').className = 'green'; +}, true); +</script>
diff --git a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt index 909ae63..4b8110b 100644 --- a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt +++ b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt
@@ -62,8 +62,6 @@ PASS window.cached_navigator_userActivation.hasBeenActive is false PASS window.cached_navigator_userActivation.isActive is false PASS window.cached_navigator_xr.ondevicechange is null -PASS window.cached_performance.onelementtimingbufferfull is null -PASS window.cached_performance.oneventtimingbufferfull is null PASS window.cached_performance.onresourcetimingbufferfull is null PASS window.cached_performance_navigation.redirectCount is 0 PASS window.cached_performance_navigation.type is 0
diff --git a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt index a2c9564e..7d4a89b 100644 --- a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt +++ b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt
@@ -62,8 +62,6 @@ PASS window.cached_navigator_userActivation.hasBeenActive is false PASS window.cached_navigator_userActivation.isActive is false PASS window.cached_navigator_xr.ondevicechange is null -PASS window.cached_performance.onelementtimingbufferfull is null -PASS window.cached_performance.oneventtimingbufferfull is null PASS window.cached_performance.onresourcetimingbufferfull is null PASS window.cached_performance_navigation.redirectCount is 0 PASS window.cached_performance_navigation.type is 0
diff --git a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt index 6791306..a34fdf28 100644 --- a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt +++ b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt
@@ -62,8 +62,6 @@ PASS window.cached_navigator_userActivation.hasBeenActive is false PASS window.cached_navigator_userActivation.isActive is false PASS window.cached_navigator_xr.ondevicechange is null -PASS window.cached_performance.onelementtimingbufferfull is null -PASS window.cached_performance.oneventtimingbufferfull is null PASS window.cached_performance.onresourcetimingbufferfull is null PASS window.cached_performance_navigation.redirectCount is 0 PASS window.cached_performance_navigation.type is 0
diff --git a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt index 624fdfa..d076f51e 100644 --- a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt +++ b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt
@@ -191,8 +191,6 @@ PASS oldChildWindow.pageYOffset is newChildWindow.pageYOffset PASS oldChildWindow.performance.navigation.redirectCount is newChildWindow.performance.navigation.redirectCount PASS oldChildWindow.performance.navigation.type is newChildWindow.performance.navigation.type -PASS oldChildWindow.performance.onelementtimingbufferfull is newChildWindow.performance.onelementtimingbufferfull -PASS oldChildWindow.performance.oneventtimingbufferfull is newChildWindow.performance.oneventtimingbufferfull PASS oldChildWindow.performance.onresourcetimingbufferfull is newChildWindow.performance.onresourcetimingbufferfull PASS oldChildWindow.performance.timing.connectEnd is newChildWindow.performance.timing.connectEnd PASS oldChildWindow.performance.timing.connectStart is newChildWindow.performance.timing.connectStart
diff --git a/third_party/blink/web_tests/fast/dom/Window/window-properties-performance-expected.txt b/third_party/blink/web_tests/fast/dom/Window/window-properties-performance-expected.txt index a378d728..3c9f66b 100644 --- a/third_party/blink/web_tests/fast/dom/Window/window-properties-performance-expected.txt +++ b/third_party/blink/web_tests/fast/dom/Window/window-properties-performance-expected.txt
@@ -2,8 +2,6 @@ window.performance [object Performance] window.performance.addEventListener [function] -window.performance.clearElementTimings [function] -window.performance.clearEventTimings [function] window.performance.clearMarks [function] window.performance.clearMeasures [function] window.performance.clearResourceTimings [function] @@ -26,13 +24,9 @@ window.performance.navigation.toJSON [function] window.performance.navigation.type [number] window.performance.now [function] -window.performance.onelementtimingbufferfull [null] -window.performance.oneventtimingbufferfull [null] window.performance.onresourcetimingbufferfull [null] window.performance.profile [function] window.performance.removeEventListener [function] -window.performance.setElementTimingBufferMaxSize [function] -window.performance.setEventTimingBufferMaxSize [function] window.performance.setResourceTimingBufferSize [function] window.performance.timeOrigin [number] window.performance.timing [object PerformanceTiming]
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_mouse_pointercapture_inactivate_pointer.html b/third_party/blink/web_tests/fast/events/pointerevents/pointerevent_mouse_pointercapture_inactivate_pointer.html similarity index 79% rename from third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_mouse_pointercapture_inactivate_pointer.html rename to third_party/blink/web_tests/fast/events/pointerevents/pointerevent_mouse_pointercapture_inactivate_pointer.html index 524d19e..b50c96d 100644 --- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_mouse_pointercapture_inactivate_pointer.html +++ b/third_party/blink/web_tests/fast/events/pointerevents/pointerevent_mouse_pointercapture_inactivate_pointer.html
@@ -1,9 +1,9 @@ <!doctype html> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/resources/testdriver.js"></script> -<script src="/resources/testdriver-vendor.js"></script> -<script src="/resources/testdriver-actions.js"></script> +<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="../../../external/wpt/resources/testdriver-actions.js"></script> <style> iframe { width: 300px;
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/resources/pointerevent_mouse_pointercapture_inactivate_pointer-iframe.html b/third_party/blink/web_tests/fast/events/pointerevents/resources/pointerevent_mouse_pointercapture_inactivate_pointer-iframe.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/pointerevents/resources/pointerevent_mouse_pointercapture_inactivate_pointer-iframe.html rename to third_party/blink/web_tests/fast/events/pointerevents/resources/pointerevent_mouse_pointercapture_inactivate_pointer-iframe.html
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/absolute-inside-out-of-view-fixed-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/absolute-inside-out-of-view-fixed-expected.txt index 13bb291..740f2691 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/absolute-inside-out-of-view-fixed-expected.txt +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/absolute-inside-out-of-view-fixed-expected.txt
@@ -9,7 +9,14 @@ }, { "name": "VerticalScrollbar", - "bounds": [800, 600] + "position": [785, 0], + "bounds": [15, 600] + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [100, 100], + "contentsOpaque": true, + "backgroundColor": "#008000" } ], "transforms": [
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/layer-creation/fixed-position-out-of-view-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/layer-creation/fixed-position-out-of-view-expected.txt new file mode 100644 index 0000000..167a2155 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/layer-creation/fixed-position-out-of-view-expected.txt
@@ -0,0 +1,72 @@ +{ + "layers": [ + { + "name": "Scrolling background of LayoutView #document", + "bounds": [785, 1021], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF" + }, + { + "name": "VerticalScrollbar", + "position": [785, 0], + "bounds": [15, 600] + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 1 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 2 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 3 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0" + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [8, 1013, 0, 1] + ] + }, + { + "id": 2, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [8, -100, 0, 1] + ] + }, + { + "id": 3, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [1000, 0, 0, 1] + ] + } + ] +} +
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/layer-creation/fixed-position-out-of-view-scaled-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/layer-creation/fixed-position-out-of-view-scaled-expected.txt new file mode 100644 index 0000000..1e83a3d --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/layer-creation/fixed-position-out-of-view-scaled-expected.txt
@@ -0,0 +1,303 @@ +Not scaled: +{ + "layers": [ + { + "name": "Scrolling background of LayoutView #document", + "bounds": [4008, 4016], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF", + "transform": 1 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 2 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 3 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 4 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 5 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 1 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [0.5, 0, 0, 0], + [0, 0.5, 0, 0], + [0, 0, 1, 0], + [0, 0, 0, 1] + ], + "origin": [0, 0], + "flattenInheritedTransform": false + }, + { + "id": 2, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [8, -100, 0, 1] + ] + }, + { + "id": 3, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [8, 1008, 0, 1] + ] + }, + { + "id": 4, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [1000, 0, 0, 1] + ] + }, + { + "id": 5, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [600, 0, 0, 1] + ] + } + ] +} + +Scale=0.5: +{ + "layers": [ + { + "name": "Scrolling background of LayoutView #document", + "bounds": [4008, 4016], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF", + "transform": 1 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 2 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 3 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 4 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 5 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 1 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [0.5, 0, 0, 0], + [0, 0.5, 0, 0], + [0, 0, 1, 0], + [0, 0, 0, 1] + ], + "origin": [0, 0], + "flattenInheritedTransform": false + }, + { + "id": 2, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [8, -100, 0, 1] + ] + }, + { + "id": 3, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [8, 1008, 0, 1] + ] + }, + { + "id": 4, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [1000, 0, 0, 1] + ] + }, + { + "id": 5, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [600, 0, 0, 1] + ] + } + ] +} + +Scale=1.5: +{ + "layers": [ + { + "name": "Scrolling background of LayoutView #document", + "bounds": [4008, 4016], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF", + "transform": 1 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 2 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 3 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 4 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 5 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 1 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1.5, 0, 0, 0], + [0, 1.5, 0, 0], + [0, 0, 1, 0], + [0, 0, 0, 1] + ], + "origin": [0, 0], + "flattenInheritedTransform": false + }, + { + "id": 2, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [8, -100, 0, 1] + ] + }, + { + "id": 3, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [8, 1008, 0, 1] + ] + }, + { + "id": 4, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [1000, 0, 0, 1] + ] + }, + { + "id": 5, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [600, 0, 0, 1] + ] + } + ] +} +
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/layer-creation/fixed-position-out-of-view-scaled-scroll-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/layer-creation/fixed-position-out-of-view-scaled-scroll-expected.txt new file mode 100644 index 0000000..416cf3f --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/layer-creation/fixed-position-out-of-view-scaled-scroll-expected.txt
@@ -0,0 +1,333 @@ +Not scaled: +{ + "layers": [ + { + "name": "Scrolling background of LayoutView #document", + "bounds": [4008, 4016], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF", + "transform": 2 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 3 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 4 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 5 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 6 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 1 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [0.5, 0, 0, 0], + [0, 0.5, 0, 0], + [0, 0, 1, 0], + [0, 0, 0, 1] + ], + "origin": [0, 0], + "flattenInheritedTransform": false + }, + { + "id": 2, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [-100, -100, 0, 1] + ] + }, + { + "id": 3, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [8, -100, 0, 1] + ] + }, + { + "id": 4, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [8, 1008, 0, 1] + ] + }, + { + "id": 5, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [1000, 0, 0, 1] + ] + }, + { + "id": 6, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [600, 0, 0, 1] + ] + } + ] +} + +Scale=0.5: +{ + "layers": [ + { + "name": "Scrolling background of LayoutView #document", + "bounds": [4008, 4016], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF", + "transform": 2 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 3 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 4 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 5 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 6 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 1 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [0.5, 0, 0, 0], + [0, 0.5, 0, 0], + [0, 0, 1, 0], + [0, 0, 0, 1] + ], + "origin": [0, 0], + "flattenInheritedTransform": false + }, + { + "id": 2, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [-100, -100, 0, 1] + ] + }, + { + "id": 3, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [8, -100, 0, 1] + ] + }, + { + "id": 4, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [8, 1008, 0, 1] + ] + }, + { + "id": 5, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [1000, 0, 0, 1] + ] + }, + { + "id": 6, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [600, 0, 0, 1] + ] + } + ] +} + +Scale=1.5: +{ + "layers": [ + { + "name": "Scrolling background of LayoutView #document", + "bounds": [4008, 4016], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF", + "transform": 2 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 3 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 4 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 5 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 6 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", + "bounds": [10, 10], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "transform": 1 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1.5, 0, 0, 0], + [0, 1.5, 0, 0], + [0, 0, 1, 0], + [0, 0, 0, 1] + ], + "origin": [0, 0], + "flattenInheritedTransform": false + }, + { + "id": 2, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [-100, -100, 0, 1] + ] + }, + { + "id": 3, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [8, -100, 0, 1] + ] + }, + { + "id": 4, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [8, 1008, 0, 1] + ] + }, + { + "id": 5, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [1000, 0, 0, 1] + ] + }, + { + "id": 6, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [600, 0, 0, 1] + ] + } + ] +} +
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/layer-creation/fixed-position-under-transform-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/layer-creation/fixed-position-under-transform-expected.txt new file mode 100644 index 0000000..0a67a40 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/layer-creation/fixed-position-under-transform-expected.txt
@@ -0,0 +1,62 @@ +{ + "layers": [ + { + "name": "Scrolling background of LayoutView #document", + "bounds": [785, 5021], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF", + "transform": 1 + }, + { + "name": "VerticalScrollbar", + "position": [785, 0], + "bounds": [15, 600] + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV id='indicator'", + "position": [100, 100], + "bounds": [256, 256], + "contentsOpaque": true, + "backgroundColor": "#FF0000", + "transform": 3 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV id='overlap'", + "bounds": [500, 500], + "contentsOpaque": true, + "backgroundColor": "#008000" + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [0, -1000, 0, 1] + ] + }, + { + "id": 2, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [8, 13, 0, 1] + ] + }, + { + "id": 3, + "parent": 2, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [0, 1000, 0, 1] + ] + } + ] +} +
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/rtl/rtl-iframe-fixed-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/rtl/rtl-iframe-fixed-expected.txt new file mode 100644 index 0000000..0d4c363 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/rtl/rtl-iframe-fixed-expected.txt
@@ -0,0 +1,29 @@ +{ + "layers": [ + { + "name": "Scrolling background of LayoutView #document", + "bounds": [800, 600], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF" + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='positioned layer'", + "bounds": [100, 100], + "contentsOpaque": true, + "backgroundColor": "#008000", + "transform": 1 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [50, 50, 0, 1] + ] + } + ] +} +
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/squashing/no-squashing-into-fixed-position-that-clips-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/squashing/no-squashing-into-fixed-position-that-clips-expected.txt new file mode 100644 index 0000000..97a15e1 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/squashing/no-squashing-into-fixed-position-that-clips-expected.txt
@@ -0,0 +1,35 @@ +{ + "layers": [ + { + "name": "Scrolling background of LayoutView #document", + "bounds": [800, 600], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF" + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='compositedlayer'", + "bounds": [24, 100], + "contentsOpaque": true, + "backgroundColor": "#D3D3D3", + "transform": 1 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV class='notsquashedelement'", + "bounds": [800, 60], + "contentsOpaque": true, + "backgroundColor": "#008000" + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [400, 40, 0, 1] + ] + } + ] +} +
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/squashing/squash-above-fixed-2-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/squashing/squash-above-fixed-2-expected.txt new file mode 100644 index 0000000..f701bb3 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/squashing/squash-above-fixed-2-expected.txt
@@ -0,0 +1,77 @@ +This scenario verifies that the cyan "container" element scrolls properly with squashing enabled. The "container" element should not squash into a composited layer mapping owned by the fixed position layer or its descendant, since this would make it behave like a fixed position element during composited scrolling. + +CASE 1, original layer tree: +{ + "layers": [ + { + "name": "Scrolling background of LayoutView #document", + "bounds": [785, 4050], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF" + }, + { + "name": "VerticalScrollbar", + "position": [785, 0], + "bounds": [15, 600] + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV id='fixed'", + "bounds": [400, 200], + "contentsOpaque": true, + "backfaceVisibility": "hidden", + "backgroundColor": "#0000FF" + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV id='container'", + "position": [100, 50], + "bounds": [200, 4000], + "contentsOpaque": true, + "backgroundColor": "#00FFFF" + } + ] +} + +CASE 2, scrolling y to 80, the "container" element should remain positioned with respect to the scrolled document, the fixed-pos layer compensates for the new scroll position: +{ + "layers": [ + { + "name": "Scrolling background of LayoutView #document", + "bounds": [785, 4050], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF", + "transform": 1 + }, + { + "name": "VerticalScrollbar", + "position": [785, 0], + "bounds": [15, 600] + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV id='fixed'", + "bounds": [400, 200], + "contentsOpaque": true, + "backfaceVisibility": "hidden", + "backgroundColor": "#0000FF" + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV id='container'", + "position": [100, 50], + "bounds": [200, 4000], + "contentsOpaque": true, + "backgroundColor": "#00FFFF", + "transform": 1 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [0, -80, 0, 1] + ] + } + ] +} +
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/squashing/squash-paint-invalidation-fixed-position-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/squashing/squash-paint-invalidation-fixed-position-expected.txt new file mode 100644 index 0000000..565ddf0 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/compositing/squashing/squash-paint-invalidation-fixed-position-expected.txt
@@ -0,0 +1,83 @@ +{ + "layers": [ + { + "name": "Scrolling background of LayoutView #document", + "bounds": [800, 600], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF" + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV", + "bounds": [100, 5000], + "contentsOpaque": true, + "backgroundColor": "#ADD8E6", + "transform": 1 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV", + "position": [8, 25], + "bounds": [100, 125], + "backgroundColor": "#D3D3D3", + "paintInvalidations": [ + { + "object": "LayoutNGBlockFlow (positioned) DIV id='foo'", + "rect": [0, 25, 100, 100], + "reason": "background" + } + ] + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [8, 8, 0, 1] + ] + } + ] +} + { + "layers": [ + { + "name": "Scrolling background of LayoutView #document", + "bounds": [800, 600], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF" + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV", + "bounds": [100, 5000], + "contentsOpaque": true, + "backgroundColor": "#ADD8E6", + "transform": 1 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV", + "position": [8, 25], + "bounds": [100, 125], + "backgroundColor": "#D3D3D3", + "paintInvalidations": [ + { + "object": "LayoutNGBlockFlow (positioned) DIV id='foo'", + "rect": [0, 25, 100, 100], + "reason": "background" + } + ] + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [8, 8, 0, 1] + ] + } + ] +} +
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/paint/invalidation/position/absolute-position-changed-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/paint/invalidation/position/absolute-position-changed-expected.txt index 774089c..27c1b68 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/paint/invalidation/position/absolute-position-changed-expected.txt +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/paint/invalidation/position/absolute-position-changed-expected.txt
@@ -7,7 +7,7 @@ "backgroundColor": "#FFFFFF", "paintInvalidations": [ { - "object": "LayoutBlockFlow (positioned) DIV id='absoluteDiv' class='absolute green'", + "object": "LayoutNGBlockFlow (positioned) DIV id='absoluteDiv' class='absolute green'", "rect": [100, 500, 100, 100], "reason": "chunk disappeared" } @@ -15,20 +15,20 @@ "transform": 1 }, { - "name": "LayoutBlockFlow (positioned) DIV class='fixed red'", - "position": [100, 200], + "name": "LayoutNGBlockFlow (positioned) DIV class='fixed red'", "bounds": [100, 100], - "backgroundColor": "#FF0000" + "backgroundColor": "#FF0000", + "transform": 2 }, { - "name": "LayoutBlockFlow (positioned) DIV id='absoluteDiv' class='absolute green'", + "name": "LayoutNGBlockFlow (positioned) DIV id='absoluteDiv' class='absolute green'", "position": [100, 700], "bounds": [100, 100], "contentsOpaque": true, "backgroundColor": "#008000", "paintInvalidations": [ { - "object": "LayoutBlockFlow (positioned) DIV id='absoluteDiv' class='absolute green'", + "object": "LayoutNGBlockFlow (positioned) DIV id='absoluteDiv' class='absolute green'", "rect": [0, 0, 100, 100], "reason": "full layer" } @@ -45,6 +45,15 @@ [0, 0, 1, 0], [0, -500, 0, 1] ] + }, + { + "id": 2, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [100, 200, 0, 1] + ] } ] }
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-key-navigation-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-key-navigation-expected.txt index 416d87ff..97e697c 100644 --- a/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-key-navigation-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-key-navigation-expected.txt
@@ -4,7 +4,7 @@ Running: testBetweenViewportAndExternal Setting focus in prompt: -TEXTAREA:Code editor +TEXTAREA:Console prompt Shift+Tab: DIV:console-key-navigation.js:20 Message #99 @@ -16,11 +16,11 @@ DIV:console-key-navigation.js:20 Message #99 Tab: -TEXTAREA:Code editor +TEXTAREA:Console prompt Running: testBetweenViewportAndExternalWithSelectedItemNotInDOM Setting focus in prompt: -TEXTAREA:Code editor +TEXTAREA:Console prompt Shift+Tab: DIV:console-key-navigation.js:20 Message #99 @@ -35,7 +35,7 @@ DIV:console-key-navigation.js:20 Message #99 Setting focus in prompt: -TEXTAREA:Code editor +TEXTAREA:Console prompt Shift+Tab: DIV:console-key-navigation.js:20 Message #99 @@ -44,7 +44,7 @@ DIV.console-group.console-group-messages Tab: -TEXTAREA:Code editor +TEXTAREA:Console prompt Running: testMoveAcrossLogsWithinViewport @@ -79,22 +79,22 @@ Force selecting index 99 DIV:console-key-navigation.js:20 Message #99 Setting focus in prompt: -TEXTAREA:Code editor +TEXTAREA:Console prompt Scrolling to top of viewport -TEXTAREA:Code editor +TEXTAREA:Console prompt Scrolling to bottom of viewport -TEXTAREA:Code editor +TEXTAREA:Console prompt Running: testNewLogsShouldNotMoveFocus Setting focus in prompt: -TEXTAREA:Code editor +TEXTAREA:Console prompt Message count: 101 -TEXTAREA:Code editor +TEXTAREA:Console prompt Running: testClearingConsoleFocusesPrompt Console cleared: -TEXTAREA:Code editor +TEXTAREA:Console prompt
diff --git a/third_party/blink/web_tests/http/tests/dom/scripted-task-queue-posttask.html b/third_party/blink/web_tests/http/tests/dom/scripted-task-queue-posttask.html deleted file mode 100644 index 6d9e988..0000000 --- a/third_party/blink/web_tests/http/tests/dom/scripted-task-queue-posttask.html +++ /dev/null
@@ -1,29 +0,0 @@ -<!DOCTYPE html> - -<script src="../resources/testharness.js"></script> -<script src="../resources/testharnessreport.js"></script> - -<script> - -let resolved_promises = 0; - -function after_task() { - resolved_promises++; - - if (resolved_promises == 10) { - done(); - } -} - -function queue_tasks(task_type) { - let task_queue = TaskQueue.default(task_type); - for (var i = 1; i < 11; i++) { - task_queue.postTask(function() { - - }).then(after_task); - } -} - -queue_tasks('user-interaction'); - -</script>
diff --git a/third_party/blink/web_tests/http/tests/origin_trials/resources/origintrials.js b/third_party/blink/web_tests/http/tests/origin_trials/resources/origintrials.js index 89f216a..2c2c8bf 100644 --- a/third_party/blink/web_tests/http/tests/origin_trials/resources/origintrials.js +++ b/third_party/blink/web_tests/http/tests/origin_trials/resources/origintrials.js
@@ -1,5 +1,5 @@ // The sample API integrates origin trial checks at various entry points. -// References to "partial interface" mean that the [OriginTrialEnabled] +// References to "partial interface" mean that the [RuntimeEnabled] // IDL attribute is applied to an entire partial interface, instead of // applied to individual IDL members. @@ -202,7 +202,7 @@ }; // These tests should pass, regardless of the state of the trial. These are -// control tests for IDL members without the [OriginTrialEnabled] extended +// control tests for IDL members without the [RuntimeEnabled] extended // attribute. The control tests will vary for secure vs insecure context. expect_always_bindings = (insecure_context, opt_description_suffix) => { var description_suffix = opt_description_suffix || ''; @@ -298,7 +298,7 @@ if (insecure_context) { // Origin trials only work in secure contexts, so tests cannot distinguish - // between [OriginTrialEnabled] or [SecureContext] preventing exposure of + // between [RuntimeEnabled] or [SecureContext] preventing exposure of // IDL members. These tests at least ensure IDL members are not exposed in // insecure contexts, regardless of reason. test(() => { @@ -361,7 +361,7 @@ expect_input_dictionary_member('normalBool'); }, 'Method with input dictionary should access member value'); - // Tests for [OriginTrialEnabled] on partial interfaces + // Tests for [RuntimeEnabled] on partial interfaces test(() => { expect_member('normalAttributePartial', (testObject) => { return testObject.normalAttributePartial; @@ -392,7 +392,7 @@ }); }, 'Constant should exist on partial interface and return value'); - // Tests for combination of [OriginTrialEnabled] and [SecureContext] + // Tests for combination of [RuntimeEnabled] and [SecureContext] test(() => { expect_member('secureAttribute', (testObject) => { return testObject.secureAttribute; @@ -470,16 +470,16 @@ }, 'Method with input dictionary should not access member value, with trial disabled'); - // Tests for combination of [OriginTrialEnabled] and [SecureContext] + // Tests for combination of [RuntimeEnabled] and [SecureContext] if (insecure_context) { // Origin trials only work in secure contexts, so tests cannot distinguish - // between [OriginTrialEnabled] or [SecureContext] preventing exposure of + // between [RuntimeEnabled] or [SecureContext] preventing exposure of // IDL members. There are tests to ensure IDL members are not exposed in // insecure contexts in expect_success_bindings(). return; } - // Tests for [OriginTrialEnabled] on partial interfaces + // Tests for [RuntimeEnabled] on partial interfaces test(() => { expect_member_fails('normalAttributePartial'); }, 'Attribute should not exist on partial interface, with trial disabled'); @@ -496,7 +496,7 @@ expect_static_member_fails('CONSTANT_PARTIAL'); }, 'Constant should not exist on partial interface, with trial disabled'); - // Tests for combination of [OriginTrialEnabled] and [SecureContext] + // Tests for combination of [RuntimeEnabled] and [SecureContext] test(() => { expect_member_fails('secureAttribute'); }, 'Secure attribute should not exist, with trial disabled');
diff --git a/third_party/blink/web_tests/http/tests/origin_trials/webexposed/eventtiming-origin-trial-interfaces.html b/third_party/blink/web_tests/http/tests/origin_trials/webexposed/eventtiming-origin-trial-interfaces.html index 362286e7..0522c36c 100644 --- a/third_party/blink/web_tests/http/tests/origin_trials/webexposed/eventtiming-origin-trial-interfaces.html +++ b/third_party/blink/web_tests/http/tests/origin_trials/webexposed/eventtiming-origin-trial-interfaces.html
@@ -12,7 +12,6 @@ test(t => { OriginTrialsHelper.check_properties_exist(this, {'PerformanceEventTiming': ['processingStart', 'cancelable'], - 'Performance': ['clearEventTimings', 'setEventTimingBufferMaxSize', 'oneventtimingbufferfull'], }); }, 'EventTiming API interfaces and properties in Origin-Trial enabled document.'); </script>
diff --git a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index 989716d..c889d55 100644 --- a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -1004,12 +1004,8 @@ method respondWith interface Performance : EventTarget attribute @@toStringTag - getter onelementtimingbufferfull - getter oneventtimingbufferfull getter onresourcetimingbufferfull getter timeOrigin - method clearElementTimings - method clearEventTimings method clearMarks method clearMeasures method clearResourceTimings @@ -1021,12 +1017,8 @@ method measure method now method profile - method setElementTimingBufferMaxSize - method setEventTimingBufferMaxSize method setResourceTimingBufferSize method toJSON - setter onelementtimingbufferfull - setter oneventtimingbufferfull setter onresourcetimingbufferfull interface PerformanceEntry attribute @@toStringTag
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/css3/filters/backdrop-filter-browser-zoom-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/css3/filters/backdrop-filter-browser-zoom-expected.png new file mode 100644 index 0000000..d57edd36 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.10/css3/filters/backdrop-filter-browser-zoom-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/scalefactor200/css3/filters/backdrop-filter-clip-rect-zoom-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/scalefactor200/css3/filters/backdrop-filter-clip-rect-zoom-expected.png deleted file mode 100644 index 3b4a8ecb..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/scalefactor200/css3/filters/backdrop-filter-clip-rect-zoom-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/virtual/scalefactor200/css3/filters/backdrop-filter-clip-rect-zoom-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/virtual/scalefactor200/css3/filters/backdrop-filter-clip-rect-zoom-expected.png deleted file mode 100644 index 3b4a8ecb..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.11/virtual/scalefactor200/css3/filters/backdrop-filter-clip-rect-zoom-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/scalefactor200/css3/filters/backdrop-filter-clip-rect-zoom-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/scalefactor200/css3/filters/backdrop-filter-clip-rect-zoom-expected.png deleted file mode 100644 index 3b4a8ecb..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/scalefactor200/css3/filters/backdrop-filter-clip-rect-zoom-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-retina/virtual/scalefactor200/css3/filters/backdrop-filter-clip-rect-zoom-expected.png b/third_party/blink/web_tests/platform/mac-retina/virtual/scalefactor200/css3/filters/backdrop-filter-clip-rect-zoom-expected.png deleted file mode 100644 index 3b4a8ecb..0000000 --- a/third_party/blink/web_tests/platform/mac-retina/virtual/scalefactor200/css3/filters/backdrop-filter-clip-rect-zoom-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/scalefactor200/css3/filters/backdrop-filter-browser-zoom-expected.png b/third_party/blink/web_tests/platform/mac/virtual/scalefactor200/css3/filters/backdrop-filter-browser-zoom-expected.png index f0aa6cb..1b486cf 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/scalefactor200/css3/filters/backdrop-filter-browser-zoom-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/scalefactor200/css3/filters/backdrop-filter-browser-zoom-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/scalefactor200/css3/filters/backdrop-filter-clip-radius-zoom-expected.png b/third_party/blink/web_tests/platform/mac/virtual/scalefactor200/css3/filters/backdrop-filter-clip-radius-zoom-expected.png new file mode 100644 index 0000000..1066ca6a --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/virtual/scalefactor200/css3/filters/backdrop-filter-clip-radius-zoom-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/scalefactor200/css3/filters/backdrop-filter-clip-rect-zoom-expected.png b/third_party/blink/web_tests/platform/mac/virtual/scalefactor200/css3/filters/backdrop-filter-clip-rect-zoom-expected.png index 3b4a8ecb..f10b613 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/scalefactor200/css3/filters/backdrop-filter-clip-rect-zoom-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/scalefactor200/css3/filters/backdrop-filter-clip-rect-zoom-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/scalefactor200/css3/filters/backdrop-filter-transform-expected.png b/third_party/blink/web_tests/platform/mac/virtual/scalefactor200/css3/filters/backdrop-filter-transform-expected.png deleted file mode 100644 index 9d425786..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/scalefactor200/css3/filters/backdrop-filter-transform-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/scalefactor200/css3/filters/backdrop-filter-browser-zoom-expected.png b/third_party/blink/web_tests/platform/win/virtual/scalefactor200/css3/filters/backdrop-filter-browser-zoom-expected.png new file mode 100644 index 0000000..e888571d --- /dev/null +++ b/third_party/blink/web_tests/platform/win/virtual/scalefactor200/css3/filters/backdrop-filter-browser-zoom-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/scalefactor200/css3/filters/backdrop-filter-clip-radius-zoom-expected.png b/third_party/blink/web_tests/platform/win/virtual/scalefactor200/css3/filters/backdrop-filter-clip-radius-zoom-expected.png new file mode 100644 index 0000000..a892c65 --- /dev/null +++ b/third_party/blink/web_tests/platform/win/virtual/scalefactor200/css3/filters/backdrop-filter-clip-radius-zoom-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/scalefactor200/css3/filters/backdrop-filter-clip-rect-zoom-expected.png b/third_party/blink/web_tests/platform/win/virtual/scalefactor200/css3/filters/backdrop-filter-clip-rect-zoom-expected.png new file mode 100644 index 0000000..7a9d148 --- /dev/null +++ b/third_party/blink/web_tests/platform/win/virtual/scalefactor200/css3/filters/backdrop-filter-clip-rect-zoom-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/resources/gesture-util.js b/third_party/blink/web_tests/resources/gesture-util.js index 36863d0..f691934 100644 --- a/third_party/blink/web_tests/resources/gesture-util.js +++ b/third_party/blink/web_tests/resources/gesture-util.js
@@ -30,14 +30,14 @@ }); } -// Returns a promise that resolves when the given condition holds for 100 -// animation frames or rejects if the condition changes to false within 100 +// Returns a promise that resolves when the given condition holds for 10 +// animation frames or rejects if the condition changes to false within 10 // animation frames. function conditionHolds(condition, error_message = 'Condition is not true anymore.') { - const MAX_FRAME = 100; + const MAX_FRAME = 10; return new Promise((resolve, reject) => { function tick(frames) { - // We requestAnimationFrame either for 100 frames or until condition is + // We requestAnimationFrame either for 10 frames or until condition is // violated. if (frames >= MAX_FRAME) resolve();
diff --git a/third_party/blink/web_tests/virtual/scalefactor200/css3/filters/backdrop-filter-browser-zoom-expected.png b/third_party/blink/web_tests/virtual/scalefactor200/css3/filters/backdrop-filter-browser-zoom-expected.png deleted file mode 100644 index 557b0fc..0000000 --- a/third_party/blink/web_tests/virtual/scalefactor200/css3/filters/backdrop-filter-browser-zoom-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/virtual/scalefactor200/css3/filters/backdrop-filter-clip-rect-zoom-expected.png b/third_party/blink/web_tests/virtual/scalefactor200/css3/filters/backdrop-filter-clip-rect-zoom-expected.png deleted file mode 100644 index 4b960016..0000000 --- a/third_party/blink/web_tests/virtual/scalefactor200/css3/filters/backdrop-filter-clip-rect-zoom-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/virtual/scalefactor200/css3/filters/backdrop-filter-transform-expected.png b/third_party/blink/web_tests/virtual/scalefactor200/css3/filters/backdrop-filter-transform-expected.png index 23174df..9d425786 100644 --- a/third_party/blink/web_tests/virtual/scalefactor200/css3/filters/backdrop-filter-transform-expected.png +++ b/third_party/blink/web_tests/virtual/scalefactor200/css3/filters/backdrop-filter-transform-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/wake-lock/wakelock-document-hidden.https.html b/third_party/blink/web_tests/wake-lock/wakelock-document-hidden.https.html index 9e63987..10cdcad 100644 --- a/third_party/blink/web_tests/wake-lock/wakelock-document-hidden.https.html +++ b/third_party/blink/web_tests/wake-lock/wakelock-document-hidden.https.html
@@ -6,6 +6,8 @@ <script> 'use strict'; +self.testRunner.setPermission('wake-lock-screen', 'granted', location.origin, location.origin); + promise_test(t => { window.testRunner.setPageVisibility('hidden'); assert_true(document.hidden); @@ -15,8 +17,7 @@ promise_test(t => { window.testRunner.setPageVisibility('visible'); - const controller = new AbortController(); - const screenLock = WakeLock.request('screen', { signal: controller.signal }); + const screenLock = WakeLock.request('screen'); window.testRunner.setPageVisibility('hidden'); assert_true(document.hidden); return promise_rejects(t, "AbortError", screenLock);
diff --git a/third_party/blink/web_tests/wake-lock/wakelock-request-denied.html b/third_party/blink/web_tests/wake-lock/wakelock-request-denied.html new file mode 100644 index 0000000..adecbf0 --- /dev/null +++ b/third_party/blink/web_tests/wake-lock/wakelock-request-denied.html
@@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<body> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script> +'use strict'; + +promise_test(t => { + self.testRunner.setPermission('wake-lock-screen', 'denied', location.origin, location.origin); + return promise_rejects(t, "NotAllowedError", WakeLock.request('screen')); +}, 'Denied requests should abort with NotAllowedError'); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/wake-lock/wakelock-requestPermission.https.html b/third_party/blink/web_tests/wake-lock/wakelock-requestPermission.https.html new file mode 100644 index 0000000..be7df136 --- /dev/null +++ b/third_party/blink/web_tests/wake-lock/wakelock-requestPermission.https.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> +<body> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script> +'use strict'; + +promise_test(async t => { + self.testRunner.setPermission('wake-lock-screen', 'granted', location.origin, location.origin); + const status = await WakeLock.requestPermission('screen'); + assert_equals(status, 'granted'); +}, 'WakeLock.requestPermission() returns "granted" for allowed requests'); + +promise_test(async t => { + self.testRunner.setPermission('wake-lock-system', 'denied', location.origin, location.origin); + const status = await WakeLock.requestPermission('system'); + assert_equals(status, 'denied'); +}, 'WakeLock.requestPermission() returns "denied" for blocked requests'); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt index 48253350..21bdea7 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -962,12 +962,8 @@ [Worker] method set [Worker] interface Performance : EventTarget [Worker] attribute @@toStringTag -[Worker] getter onelementtimingbufferfull -[Worker] getter oneventtimingbufferfull [Worker] getter onresourcetimingbufferfull [Worker] getter timeOrigin -[Worker] method clearElementTimings -[Worker] method clearEventTimings [Worker] method clearMarks [Worker] method clearMeasures [Worker] method clearResourceTimings @@ -979,12 +975,8 @@ [Worker] method measure [Worker] method now [Worker] method profile -[Worker] method setElementTimingBufferMaxSize -[Worker] method setEventTimingBufferMaxSize [Worker] method setResourceTimingBufferSize [Worker] method toJSON -[Worker] setter onelementtimingbufferfull -[Worker] setter oneventtimingbufferfull [Worker] setter onresourcetimingbufferfull [Worker] interface PerformanceEntry [Worker] attribute @@toStringTag
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 543c2222..69e48ef9 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
@@ -4398,11 +4398,17 @@ setter target interface LargestContentfulPaint : PerformanceEntry attribute @@toStringTag + getter element + getter id + getter responseEnd getter size + getter url method constructor method toJSON interface LayoutShift : PerformanceEntry attribute @@toStringTag + getter hadRecentInput + getter lastInputTime getter value method constructor method toJSON @@ -5368,13 +5374,9 @@ attribute @@toStringTag getter memory getter navigation - getter onelementtimingbufferfull - getter oneventtimingbufferfull getter onresourcetimingbufferfull getter timeOrigin getter timing - method clearElementTimings - method clearEventTimings method clearMarks method clearMeasures method clearResourceTimings @@ -5386,12 +5388,8 @@ method measure method now method profile - method setElementTimingBufferMaxSize - method setEventTimingBufferMaxSize method setResourceTimingBufferSize method toJSON - setter onelementtimingbufferfull - setter oneventtimingbufferfull setter onresourcetimingbufferfull interface PerformanceElementTiming : PerformanceEntry attribute @@toStringTag @@ -7298,14 +7296,6 @@ getter onaudioprocess method constructor setter onaudioprocess -interface ScriptedTaskQueue - attribute @@toStringTag - method constructor - method postTask -interface ScriptedTaskQueueController - attribute @@toStringTag - method constructor - method default interface ScrollTimeline : AnimationTimeline attribute @@toStringTag getter endScrollOffset @@ -8182,6 +8172,7 @@ setter onscroll interface WakeLock static method request + static method requestPermission attribute @@toStringTag method constructor interface WaveShaperNode : AudioNode @@ -10956,7 +10947,6 @@ attribute textInputController attribute top attribute window - getter TaskQueue getter TrustedTypes getter applicationCache getter caches @@ -11164,7 +11154,6 @@ method webkitRequestAnimationFrame method webkitRequestFileSystem method webkitResolveLocalFileSystemURL - setter TaskQueue setter clientInformation setter cookieStore setter defaultStatus
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt index 185a304..54c127c 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -944,12 +944,8 @@ [Worker] method set [Worker] interface Performance : EventTarget [Worker] attribute @@toStringTag -[Worker] getter onelementtimingbufferfull -[Worker] getter oneventtimingbufferfull [Worker] getter onresourcetimingbufferfull [Worker] getter timeOrigin -[Worker] method clearElementTimings -[Worker] method clearEventTimings [Worker] method clearMarks [Worker] method clearMeasures [Worker] method clearResourceTimings @@ -961,12 +957,8 @@ [Worker] method measure [Worker] method now [Worker] method profile -[Worker] method setElementTimingBufferMaxSize -[Worker] method setEventTimingBufferMaxSize [Worker] method setResourceTimingBufferSize [Worker] method toJSON -[Worker] setter onelementtimingbufferfull -[Worker] setter oneventtimingbufferfull [Worker] setter onresourcetimingbufferfull [Worker] interface PerformanceEntry [Worker] attribute @@toStringTag
diff --git a/third_party/ced/DEPS b/third_party/ced/DEPS deleted file mode 100644 index e7074e0..0000000 --- a/third_party/ced/DEPS +++ /dev/null
@@ -1,5 +0,0 @@ -specific_include_rules = { - 'compact_enc_det_fuzzer\.cc': [ - '+base/test/fuzzed_data_provider.h', - ], -}
diff --git a/third_party/libprotobuf-mutator/BUILD.gn b/third_party/libprotobuf-mutator/BUILD.gn index 733c5c1..021f988 100644 --- a/third_party/libprotobuf-mutator/BUILD.gn +++ b/third_party/libprotobuf-mutator/BUILD.gn
@@ -36,8 +36,8 @@ ] # Let ClusterFuzz builders know to not build targets that depend on - # libprotobuf-mutator for AFL. - if (use_afl) { + # libprotobuf-mutator for AFL or Chrome OS. + if (use_afl || current_toolchain == "//build/toolchain/cros:target") { all_dependent_configs = [ "//testing/libfuzzer:no_clusterfuzz" ] } }
diff --git a/third_party/libprotobuf-mutator/fuzzable_proto_library.gni b/third_party/libprotobuf-mutator/fuzzable_proto_library.gni index 677e4eab..a24bf24 100644 --- a/third_party/libprotobuf-mutator/fuzzable_proto_library.gni +++ b/third_party/libprotobuf-mutator/fuzzable_proto_library.gni
@@ -15,7 +15,9 @@ import("//third_party/protobuf/proto_library.gni") template("fuzzable_proto_library") { - if (use_libfuzzer) { + # Only make the proto library fuzzable if we are doing a build that we can + # use LPM on (i.e. libFuzzer not on Chrome OS). + if (use_libfuzzer && current_toolchain != "//build/toolchain/cros:target") { proto_library("proto_library_" + target_name) { forward_variables_from(invoker, "*") assert(current_toolchain == host_toolchain)
diff --git a/third_party/libvpx/README.chromium b/third_party/libvpx/README.chromium index b2f661e..4114164 100644 --- a/third_party/libvpx/README.chromium +++ b/third_party/libvpx/README.chromium
@@ -5,9 +5,9 @@ License File: source/libvpx/LICENSE Security Critical: yes -Date: Wednesday June 26 2019 +Date: Monday July 01 2019 Branch: master -Commit: 30e7f9d856eb1cc6df895f6d9562493e04f6116d +Commit: cd9f1763c861edfd86d2814e029a34f3ce821e72 Description: Contains the sources used to compile libvpx binaries used by Google Chrome and
diff --git a/third_party/libvpx/source/config/vpx_version.h b/third_party/libvpx/source/config/vpx_version.h index 144bceee..f6b1609 100644 --- a/third_party/libvpx/source/config/vpx_version.h +++ b/third_party/libvpx/source/config/vpx_version.h
@@ -2,7 +2,7 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 8 #define VERSION_PATCH 0 -#define VERSION_EXTRA "575-g30e7f9d85" +#define VERSION_EXTRA "589-gcd9f1763c8" #define VERSION_PACKED ((VERSION_MAJOR<<16)|(VERSION_MINOR<<8)|(VERSION_PATCH)) -#define VERSION_STRING_NOSP "v1.8.0-575-g30e7f9d85" -#define VERSION_STRING " v1.8.0-575-g30e7f9d85" +#define VERSION_STRING_NOSP "v1.8.0-589-gcd9f1763c8" +#define VERSION_STRING " v1.8.0-589-gcd9f1763c8"
diff --git a/tools/accessibility/DEPS b/tools/accessibility/DEPS index 02d3a21c..8efc528 100644 --- a/tools/accessibility/DEPS +++ b/tools/accessibility/DEPS
@@ -1,3 +1,4 @@ include_rules = [ "+content/browser/accessibility", + "+content/public/browser", ]
diff --git a/tools/accessibility/inspect/ax_tree_server.cc b/tools/accessibility/inspect/ax_tree_server.cc index 58b30d1..fa7e29c 100644 --- a/tools/accessibility/inspect/ax_tree_server.cc +++ b/tools/accessibility/inspect/ax_tree_server.cc
@@ -14,8 +14,10 @@ #include "base/path_service.h" #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" +#include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" namespace content {
diff --git a/tools/accessibility/inspect/ax_tree_server.h b/tools/accessibility/inspect/ax_tree_server.h index 40ec00d..57d20c1 100644 --- a/tools/accessibility/inspect/ax_tree_server.h +++ b/tools/accessibility/inspect/ax_tree_server.h
@@ -9,7 +9,7 @@ #include "base/process/process_handle.h" #include "build/build_config.h" -#include "content/browser/accessibility/accessibility_tree_formatter.h" +#include "content/public/browser/accessibility_tree_formatter.h" #if defined(OS_WIN) #include "base/win/scoped_com_initializer.h"
diff --git a/tools/clang/stack_maps/OWNERS b/tools/clang/stack_maps/OWNERS new file mode 100644 index 0000000..2212c51 --- /dev/null +++ b/tools/clang/stack_maps/OWNERS
@@ -0,0 +1,4 @@ +mlippautz@chromium.org + +# TEAM: v8-dev@chromium.org +# COMPONENT: Blink>JavaScript>GC
diff --git a/tools/clang/stack_maps/README b/tools/clang/stack_maps/README new file mode 100644 index 0000000..c7219f88 --- /dev/null +++ b/tools/clang/stack_maps/README
@@ -0,0 +1,4 @@ +Prototype and playground for generating stack maps to garbage-collected objects +using clang/llvm infrastructure. + +Design doc: https://bit.ly/chromium-stack-maps
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index cc72d73..53b461c 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -87,16 +87,6 @@ 'x86 Emulator Tester': 'android_debug_static_bot_x86', }, - # TODO(bpastene): Remove 'chromium.chrome' when it's been switched to 'chrome' - 'chromium.chrome': { - 'chromeos-amd64-generic-google-rel': 'official_cros_chrome_sdk', - 'chromeos-betty-google-rel': 'official_cros_chrome_sdk_headless_ozone', - 'linux-chromeos-google-rel': 'official_goma_chromeos_minimal_symbols', - 'linux-google-rel': 'official_goma', - 'mac-google-rel': 'official_goma', - 'win-google-rel': 'official_goma_x86', - }, - 'chromium.chromedriver': { 'Win7': 'release_bot_x86', 'Mac 10.6': 'release_bot', @@ -687,12 +677,6 @@ 'win_chrome_official': 'official_goma_x86', }, - 'tryserver.chromium.chrome': { - 'chromeos-betty-chrome': 'official_cros_chrome_sdk_headless_ozone', - 'linux-chrome': 'official_goma', - 'linux-chromeos-chrome': 'official_goma_chromeos_minimal_symbols', - }, - 'tryserver.chromium.chromiumos': { # TODO(crbug.com/913750): Enable DCHECKS on the two amd64-generic bots # and two kevin bots when the PFQ has it enabled. @@ -864,10 +848,6 @@ 'win_upload_clang': 'release_bot', }, - 'tryserver.chrome.win': { - 'win_chrome_official': 'official_goma_x86', - }, - 'tryserver.v8': { 'v8_linux_blink_rel': 'release_trybot', 'v8_linux_chromium_gn_rel': 'release_trybot',
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 3e6d2d0..22e9359 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -23799,6 +23799,18 @@ <int value="2940" label="CSSAtRuleProperty"/> <int value="2941" label="ServiceWorkerInterceptedRequestFromOriginDirtyStyleSheet"/> + <int value="2942" label="WebkitMarginBeforeCollapseDiscard"/> + <int value="2943" label="WebkitMarginBeforeCollapseSeparate"/> + <int value="2944" + label="WebkitMarginBeforeCollapseSeparateMaybeDoesSomething"/> + <int value="2945" label="WebkitMarginAfterCollapseDiscard"/> + <int value="2946" label="WebkitMarginAfterCollapseSeparate"/> + <int value="2947" + label="WebkitMarginAfterCollapseSeparateMaybeDoesSomething"/> + <int value="2948" label="CredentialManagerCreateWithUVM"/> + <int value="2949" label="CredentialManagerGetWithUVM"/> + <int value="2950" label="CredentialManagerCreateSuccessWithUVM"/> + <int value="2951" label="CredentialManagerGetSuccessWithUVM"/> </enum> <enum name="FeaturePolicyAllowlistType"> @@ -29875,6 +29887,10 @@ <int value="7" label="Cache startup eviction finished"/> <int value="8" label="Java in-memory cache hit"/> <int value="9" label="Java disk cache hit"/> + <int value="10" label="Image queued for transcoding was decoded."/> + <int value="11" + label="Image queued for transcoding was stored back to cache."/> + <int value="12" label="Load image metadata"/> </enum> <enum name="IMECommitType"> @@ -34805,6 +34821,7 @@ <int value="-250822813" label="PwaImprovedSplashScreen:enabled"/> <int value="-250721831" label="AndroidAutofillAccessibility:disabled"/> <int value="-248223420" label="AutofillKeyboardAccessory:disabled"/> + <int value="-243323793" label="OmniboxOnDeviceHeadProvider:enabled"/> <int value="-241353344" label="MidiManagerWinrt:disabled"/> <int value="-240531943" label="ContextualSearchRankerQuery:disabled"/> <int value="-239616243" label="HighDynamicRange:enabled"/> @@ -35011,6 +35028,7 @@ <int value="44088203" label="ExpensiveBackgroundTimerThrottling:enabled"/> <int value="48159177" label="reduced-referrer-granularity"/> <int value="48223610" label="SiteSettings:disabled"/> + <int value="49113130" label="OmniboxOnDeviceHeadProvider:disabled"/> <int value="51793504" label="protect-sync-credential-on-reauth:disabled"/> <int value="52368742" label="enable-pixel-canvas-recording:disabled"/> <int value="54571864" label="EnableDisplayZoomSetting:enabled"/> @@ -45916,6 +45934,30 @@ <int value="2" label="Other Aborted"/> </enum> +<enum name="PaymentRequestMissingContactFields"> + <summary> + A bit field value that shows the missing fields of contact info section in + payment sheet. The cardinality is not too high since the total number of + used bits is less than 4. + </summary> +</enum> + +<enum name="PaymentRequestMissingPaymentFields"> + <summary> + A bit field value that shows the missing fields of payment section in + payment sheet. The cardinality is not too high since the total number of + used bits is less than 6. + </summary> +</enum> + +<enum name="PaymentRequestMissingShippingFields"> + <summary> + A bit field value that shows the missing fields of shipping section in + payment sheet. The cardinality is not too high since the total number of + used bits is less than 4. + </summary> +</enum> + <enum name="PaymentRequestNoShowReason"> <int value="0" label="NoMatchingPaymentMethod"/> <int value="1" label="NoSupportedPaymentMethod"/> @@ -53555,6 +53597,12 @@ <int value="5" label="Authenticated channel dropped"/> </enum> +<enum name="SMSReceiverOutcome"> + <int value="0" label="Success"/> + <int value="1" label="Timed out"/> + <int value="2" label="Connection Error"/> +</enum> + <enum name="SnackbarIdentifier"> <int value="-2" label="TEST_SNACKBAR"/> <int value="-1" label="UNKNOWN"/> @@ -53590,6 +53638,7 @@ <int value="29" label="UMA_AUTOFILL_ASSISTANT_STOP_UNDO"/> <int value="30" label="UMA_TAB_CLOSE_MULTIPLE_UNDO"/> <int value="31" label="UMA_SEARCH_ENGINE_CHOICE_NOTIFICATION"/> + <int value="32" label="UMA_TAB_GROUP_MANUAL_CREATION_UNDO"/> </enum> <enum name="SnippetOpenMethod">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index dbba78e6..a433eb10 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -1806,7 +1806,7 @@ </histogram> <histogram name="Android.DarkTheme.EnabledReason" enum="DarkThemeEnabledReason" - expires_after="M78"> + expires_after="M90"> <owner>huayinz@chromium.org</owner> <owner>chrome-android-app@chromium.org</owner> <summary> @@ -1816,7 +1816,7 @@ </histogram> <histogram name="Android.DarkTheme.EnabledState" enum="BooleanEnabled" - expires_after="M78"> + expires_after="M90"> <owner>huayinz@chromium.org</owner> <owner>chrome-android-app@chromium.org</owner> <summary> @@ -1826,7 +1826,7 @@ </histogram> <histogram name="Android.DarkTheme.Preference.State" - enum="DarkThemePreferences" expires_after="M78"> + enum="DarkThemePreferences" expires_after="M90"> <owner>huayinz@chromium.org</owner> <owner>chrome-android-app@chromium.org</owner> <summary> @@ -13916,6 +13916,22 @@ </summary> </histogram> +<histogram name="Blink.Sms.Receive.Outcome" enum="SMSReceiverOutcome"> + <owner>goto@chromium.org</owner> + <owner>reillyg@chromium.org</owner> + <owner>ayui@chromium.org</owner> + <summary>Records the result of a call to the SmsReceiver API.</summary> +</histogram> + +<histogram name="Blink.Sms.Receive.TimeSuccess" units="ms"> + <owner>goto@chromium.org</owner> + <owner>reillyg@chromium.org</owner> + <owner>ayui@chromium.org</owner> + <summary> + Records how long it takes for the API to successfully receive the SMS. + </summary> +</histogram> + <histogram name="Blink.SpatialNavigation.Advance" units="microseconds"> <owner>bokan@chromium.org</owner> <summary> @@ -14095,9 +14111,9 @@ </histogram> <histogram name="Blink.UseCounter.FeaturePolicy.ImageDownscalingRatio" - units="%" expires_after="M77"> - <owner>loonybear@chromium.org</owner> + units="%" expires_after="M80"> <owner>iclelland@chromium.org</owner> + <owner>feature-control@chromium.org</owner> <summary> Logs downscaling ratio in percentage for images enforced by feature policy oversized-images policy going into origin trials in M75. If an image's @@ -14108,9 +14124,9 @@ </histogram> <histogram name="Blink.UseCounter.FeaturePolicy.ImageFormats" - enum="FeaturePolicyImageCompressionFormat" expires_after="M77"> - <owner>loonybear@chromium.org</owner> + enum="FeaturePolicyImageCompressionFormat" expires_after="M80"> <owner>iclelland@chromium.org</owner> + <owner>feature-control@chromium.org</owner> <summary> Counts ImageFileFormats (lossy, lossless, webp animation, others) of images enforced by feature policy unoptimized-images policy going into origin @@ -14119,9 +14135,9 @@ </histogram> <histogram name="Blink.UseCounter.FeaturePolicy.LosslessImageCompression" - units="%" expires_after="M77"> - <owner>loonybear@chromium.org</owner> + units="%" expires_after="M80"> <owner>iclelland@chromium.org</owner> + <owner>feature-control@chromium.org</owner> <summary> Logs compression ratio in percentage with 1KB overhead for lossless type images enforced by feature policy unoptimized-lossless-images policy going @@ -14133,9 +14149,9 @@ </histogram> <histogram name="Blink.UseCounter.FeaturePolicy.LossyImageCompression" - units="%" expires_after="M77"> - <owner>loonybear@chromium.org</owner> + units="%" expires_after="M80"> <owner>iclelland@chromium.org</owner> + <owner>feature-control@chromium.org</owner> <summary> Logs compression ratio with 1KB overhead for lossy type images enforced by feature policy unoptimized-lossy-images policy going into origin trials in @@ -14160,9 +14176,9 @@ </histogram> <histogram name="Blink.UseCounter.FeaturePolicy.StrictLosslessImageCompression" - units="%" expires_after="M77"> - <owner>loonybear@chromium.org</owner> + units="%" expires_after="M80"> <owner>iclelland@chromium.org</owner> + <owner>feature-control@chromium.org</owner> <summary> Logs compression ratio with 10KB overhead for lossless type images enforced by feature policy unoptimized-lossless-images-strict policy going into @@ -14701,6 +14717,9 @@ <histogram name="BloatedRenderer.HandlingInBrowser" enum="BloatedRendererHandlingInBrowser"> + <obsolete> + Obsolete as of 05/2019. + </obsolete> <owner>ulan@chromium.org</owner> <summary> Records how a bloated renderer was handled in the browser process. @@ -14709,6 +14728,9 @@ <histogram name="BloatedRenderer.HandlingInResourceCoordinator" enum="BloatedRendererHandlingInResourceCoordinator"> + <obsolete> + Obsolete as of 05/2019. + </obsolete> <owner>ulan@chromium.org</owner> <summary> Records how a bloated renderer was handled in the resource coordinator @@ -14718,6 +14740,9 @@ <histogram name="BloatedRenderer.V8.NearV8HeapLimitHandling" enum="NearV8HeapLimitHandling"> + <obsolete> + Obsolete as of 05/2019. + </obsolete> <owner>ulan@chromium.org</owner> <summary> Records how a bloated V8 heap was handled in the renderer process. It is @@ -16492,6 +16517,15 @@ </summary> </histogram> +<histogram name="CachedImageFetcher.LoadImageMetadata" units="ms" + expires_after="2020-06-30"> + <owner>fgorski@chromium.org</owner> + <owner>wylieb@chromium.org</owner> + <summary> + The time it takes to load an image's metadata from the metadata store. + </summary> +</histogram> + <histogram name="CachedImageFetcher.TimeSinceLastCacheLRUEviction" units="ms" expires_after="2019-12-01"> <owner>fgorski@chromium.org</owner> @@ -18132,7 +18166,7 @@ </histogram> <histogram name="ChromiumAndroidLinker.BrowserLoadTime" units="ms" - expires_after="M77"> + expires_after="M99"> <owner>rsesek@chromium.org</owner> <summary> The amount of time it took to load the native libraries in the browser @@ -18198,7 +18232,7 @@ </histogram> <histogram name="ChromiumAndroidLinker.RendererLoadTime" units="ms" - expires_after="M77"> + expires_after="M99"> <owner>rsesek@chromium.org</owner> <summary> The amount of time it took to load the native libraries in the renderer @@ -19178,6 +19212,19 @@ </summary> </histogram> +<histogram name="Compositing.Display.DrawToSwapUs" units="microseconds" + expires_after="2020-07-02"> + <owner>backer@chromium.org</owner> + <owner>rjkroege@chromium.org</owner> + <summary> + This is logged once per frame, if the output surface provides timing + information. It measures the time from the display compositor starting a + draw on the Viz Compositor thread to issuing all related draw calls to the + driver on the Gpu Main thread. Only reported for platforms supporting high + resolution clocks. + </summary> +</histogram> + <histogram name="Compositing.DisplayListRecordingSource.UpdateInvalidatedAreaPerMs" units="pixels/ms"> @@ -23690,7 +23737,10 @@ </summary> </histogram> -<histogram name="Cryptohome.TimeToMountAsync" units="ms" expires_after="M77"> +<histogram name="Cryptohome.TimeToMountAsync" units="ms"> + <obsolete> + Deprecated 07/2019 as it is not used since crrev.com/c/1393048 + </obsolete> <owner>apronin@chromium.org</owner> <owner>cros-hwsec@chromium.org</owner> <summary> @@ -53382,7 +53432,7 @@ </histogram> <histogram name="ManagedUsers.FilteringResult" - enum="SupervisedUserSafetyFilterResult" expires_after="M77"> + enum="SupervisedUserSafetyFilterResult" expires_after="M85"> <owner>treib@chromium.org</owner> <owner>escordeiro@chromium.org</owner> <owner>menegola@chromium.org</owner> @@ -53440,7 +53490,7 @@ </histogram> <histogram name="ManagedUsers.SafetyFilter" - enum="SupervisedUserSafetyFilterResult" expires_after="M77"> + enum="SupervisedUserSafetyFilterResult" expires_after="M85"> <owner>treib@chromium.org</owner> <owner>escordeiro@chromium.org</owner> <owner>menegola@chromium.org</owner> @@ -53454,7 +53504,7 @@ </histogram> <histogram name="ManagedUsers.Whitelist.Count" units="whitelists" - expires_after="M77"> + expires_after="M85"> <owner>treib@chromium.org</owner> <owner>escordeiro@chromium.org</owner> <owner>menegola@chromium.org</owner> @@ -72830,7 +72880,7 @@ </histogram> <histogram name="Net.QuicSession.ConnectionIpPooled" enum="Boolean" - expires_after="2019-06-30"> + expires_after="2020-06-30"> <owner>renjietang@chromium.org</owner> <owner>rch@chromium.org</owner> <summary> @@ -91566,6 +91616,9 @@ <histogram name="PageSerialization.MhtmlGeneration.PopupOverlaySkipped" enum="BooleanSkipped" expires_after="2018-08-30"> + <obsolete> + Deprecated 6/2019. No longer used. + </obsolete> <owner>jianli@chromium.org</owner> <owner>offline-dev@chromium.org</owner> <summary> @@ -94232,6 +94285,16 @@ </summary> </histogram> +<histogram name="PasswordProtection.DomFeatureParsing" enum="BooleanSuccess" + expires_after="M78"> + <owner>drubery@chromium.org</owner> + <owner>chrome-safebrowsing-alerts@google.com</owner> + <summary> + Records whether the DOM features were parsed successfully when returned from + the renderer. This is logged on every PhishGuard ping. + </summary> +</histogram> + <histogram name="PasswordProtection.GaiaPasswordReusesBeforeGaiaPasswordChanged" units="reuses"> @@ -94623,6 +94686,42 @@ </summary> </histogram> +<histogram name="PaymentRequest.MissingContactFields" + enum="PaymentRequestMissingContactFields"> + <owner>sahel@chromium.org</owner> + <summary> + A bitfield representing different missing fields of the contact section in + payment sheet. This only gets recorded when no complete contact profile is + available. In case of multiple partially complete profiles, this is only + recorded for the most complete one which is also the first profile in the + suggestion list. + </summary> +</histogram> + +<histogram name="PaymentRequest.MissingPaymentFields" + enum="PaymentRequestMissingPaymentFields"> + <owner>sahel@chromium.org</owner> + <summary> + A bitfield representing different missing fields of the payment info section + in the payment sheet. This only gets recorded when no complete payment + instrument is available (SW based instruments are always considered as + complete). In case of multiple partially complete cards this is only + recorded for the first card in the suggestion list. + </summary> +</histogram> + +<histogram name="PaymentRequest.MissingShippingFields" + enum="PaymentRequestMissingShippingFields"> + <owner>sahel@chromium.org</owner> + <summary> + A bitfield representing different missing fields of the shipping section in + the payment sheet. This only gets recorded when no complete shipping profile + is available. In case of multiple partially complete profiles, this is only + recorded for the most complete one which is also the first profile in the + suggestion list. + </summary> +</histogram> + <histogram name="PaymentRequest.NumberOfSelectionAdds"> <owner>sebsg@chromium.org</owner> <summary> @@ -100971,6 +101070,9 @@ <histogram name="PrefService.NetworkPredictionEnabled" enum="BooleanEnabled" expires_after="M77"> + <obsolete> + Removed as of 7/2019. No longer needed. + </obsolete> <owner>petewil@chromium.org</owner> <summary> Count events where Network Prediction was enabled or disabled. @@ -128953,6 +129055,9 @@ <histogram name="SubresourceFilter.DocumentLoad.ActivationComputingDelay" units="microseconds" expires_after="M77"> + <obsolete> + Deprecated July 2019. + </obsolete> <owner>csharrison@chromium.org</owner> <summary> Records the total time the activation state navigation throttle within a @@ -128969,6 +129074,9 @@ <histogram name="SubresourceFilter.DocumentLoad.ActivationComputingDelay.MainFrame" units="microseconds" expires_after="M78"> + <obsolete> + Deprecated July 2019. + </obsolete> <owner>csharrison@chromium.org</owner> <summary> Records the total time the activation state navigation throttle within a @@ -140927,7 +141035,7 @@ </summary> </histogram> -<histogram name="V8.SharedArrayAllocationSizes" units="MB" expires_after="M77"> +<histogram name="V8.SharedArrayAllocationSizes" units="MB" expires_after="M80"> <owner>gdeepti@chromium.org</owner> <owner>titzer@chromium.org</owner> <summary> @@ -149943,8 +150051,10 @@ </summary> </histogram> -<histogram name="WorkerScheduler.WorkerThreadLoad" units="%" - expires_after="M77"> +<histogram name="WorkerScheduler.WorkerThreadLoad" units="%"> + <obsolete> + Removed July 2019. + </obsolete> <owner>kinuko@chromium.org</owner> <summary> Worker thread load, i.e. percentage of time spent on running tasks. This @@ -149971,7 +150081,10 @@ <summary>Records the exit code of WorkerThread.</summary> </histogram> -<histogram name="WorkerThread.Runtime" units="ms" expires_after="M77"> +<histogram name="WorkerThread.Runtime" units="ms"> + <obsolete> + Removed July 2019. + </obsolete> <owner>kinuko@chromium.org</owner> <summary> The amount of time a worker thread ran for. Starts recording when a worker
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index 744ad53a..8a09e8f5 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -2056,6 +2056,9 @@ </event> <event name="BloatedRenderer"> + <obsolete> + Deprecated as of 03/2019. + </obsolete> <owner>ulan@chromium.org</owner> <summary> Metrics related to a bloated renderer that is close to out-of-memory. They @@ -2941,7 +2944,7 @@ <summary> Logged when the FindInPage returns a user search request result. </summary> - <metric name="HasMatches"> + <metric name="HasMatches" enum="Boolean"> <summary> True if there were matches. </summary> @@ -5900,6 +5903,20 @@ that a non-zero value in this field implies previews_likely. </summary> </metric> + <metric name="defer_all_script" enum="Boolean"> + <summary> + Set to 1 when a user is shown a DeferAllScript preview on a page load. + </summary> + </metric> + <metric name="defer_all_script_eligibility_reason" + enum="PreviewsEligibilityReason"> + <summary> + Set to the value of the last known reason a DeferAllScript preview was not + eligible on this page load. The value of this metric corresponds to the + PreviewsEligibilityReason enum. This metric is only set when it is + non-zero. + </summary> + </metric> <metric name="lite_page"> <summary> Set to 1 when a user is shown a lite page in page load.
diff --git a/tools/traffic_annotation/auditor/BUILD.gn b/tools/traffic_annotation/auditor/BUILD.gn index 6e2e467..8c9f65c5 100644 --- a/tools/traffic_annotation/auditor/BUILD.gn +++ b/tools/traffic_annotation/auditor/BUILD.gn
@@ -113,7 +113,6 @@ "tests/extractor_outputs/good_partial_annotation.txt", "tests/extractor_outputs/good_test_annotation.txt", "tests/extractor_outputs/missing_annotation.txt", - "tests/extractor_outputs/no_annotation.txt", "tests/git_list.txt", "tests/gn_list_negative.txt", "tests/gn_list_positive.txt",
diff --git a/tools/traffic_annotation/auditor/auditor_result.h b/tools/traffic_annotation/auditor/auditor_result.h index 880dda16..4b331864f 100644 --- a/tools/traffic_annotation/auditor/auditor_result.h +++ b/tools/traffic_annotation/auditor/auditor_result.h
@@ -17,6 +17,8 @@ ERROR_MISSING_TAG_USED, // A function is called with // MISSING_TRAFFIC_ANNOTATION tag. ERROR_NO_ANNOTATION, // A function is called with NO_ANNOTATION tag. + // Deprecated, as NO_ANNOTATION is now undefined on + // supported platforms. ERROR_SYNTAX, // Annotation syntax is not right. ERROR_RESERVED_ID_HASH_CODE, // An id has a hash code equal to a reserved // word.
diff --git a/tools/traffic_annotation/auditor/instance.cc b/tools/traffic_annotation/auditor/instance.cc index 140a01c..256d6d9a 100644 --- a/tools/traffic_annotation/auditor/instance.cc +++ b/tools/traffic_annotation/auditor/instance.cc
@@ -171,14 +171,6 @@ file_path, line_number); } - // Process undefined tags. - if (unique_id_hash_code == NO_TRAFFIC_ANNOTATION_YET.unique_id_hash_code || - unique_id_hash_code == - NO_PARTIAL_TRAFFIC_ANNOTATION_YET.unique_id_hash_code) { - return AuditorResult(AuditorResult::Type::ERROR_NO_ANNOTATION, "", - file_path, line_number); - } - // Process missing tag. if (unique_id_hash_code == MISSING_TRAFFIC_ANNOTATION.unique_id_hash_code) return AuditorResult(AuditorResult::Type::ERROR_MISSING_TAG_USED, "",
diff --git a/tools/traffic_annotation/auditor/safe_list.txt b/tools/traffic_annotation/auditor/safe_list.txt index c22b137..bc9d41a 100644 --- a/tools/traffic_annotation/auditor/safe_list.txt +++ b/tools/traffic_annotation/auditor/safe_list.txt
@@ -1,8 +1,12 @@ # This is a comma separated file, specifying the safe list for network traffic # anntotation auditor. Please refer to README.md for more details. all,tools/*,*test*,*fuzzer*,*mock*,*fake* +missing,remoting/host/token_validator_factory_impl.cc +missing,components/cronet/cronet_url_request.cc +missing,net/tools/quic/quic_http_proxy_backend_stream.cc missing,net/url_request/url_fetcher.cc missing,net/url_request/url_request_context.cc mutable_tag,components/download/internal/background_service/proto_conversions.cc test_annotation,components/safe_search_api/stub_url_checker.cc test_annotation,net/quic/quic_chromium_client_session_peer.cc +test_annotation,net/tools/quic/quic_http_proxy_backend_stream.cc
diff --git a/tools/traffic_annotation/auditor/tests/extractor_outputs/no_annotation.txt b/tools/traffic_annotation/auditor/tests/extractor_outputs/no_annotation.txt deleted file mode 100644 index e8b2838..0000000 --- a/tools/traffic_annotation/auditor/tests/extractor_outputs/no_annotation.txt +++ /dev/null
@@ -1,7 +0,0 @@ -components/download/internal/controller_impl.cc -download::ControllerImpl::UpdateDriverState -656 -Definition -undefined - -Nothing here yet. \ No newline at end of file
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc b/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc index efc1ac9..8eb0699c 100644 --- a/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc +++ b/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc
@@ -36,7 +36,6 @@ std::map<int, std::string> kReservedAnnotations = { {TRAFFIC_ANNOTATION_FOR_TESTS.unique_id_hash_code, "test"}, {PARTIAL_TRAFFIC_ANNOTATION_FOR_TESTS.unique_id_hash_code, "test_partial"}, - {NO_TRAFFIC_ANNOTATION_YET.unique_id_hash_code, "undefined"}, {MISSING_TRAFFIC_ANNOTATION.unique_id_hash_code, "missing"}}; struct AnnotationID {
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_auditor_unittest.cc b/tools/traffic_annotation/auditor/traffic_annotation_auditor_unittest.cc index 085cc5e6..7b0d3ad 100644 --- a/tools/traffic_annotation/auditor/traffic_annotation_auditor_unittest.cc +++ b/tools/traffic_annotation/auditor/traffic_annotation_auditor_unittest.cc
@@ -306,7 +306,6 @@ AnnotationInstance::Type::ANNOTATION_PARTIAL}, {"good_test_annotation.txt", AuditorResult::Type::ERROR_TEST_ANNOTATION}, {"missing_annotation.txt", AuditorResult::Type::ERROR_MISSING_TAG_USED}, - {"no_annotation.txt", AuditorResult::Type::ERROR_NO_ANNOTATION}, {"fatal_annotation1.txt", AuditorResult::Type::ERROR_FATAL}, {"fatal_annotation2.txt", AuditorResult::Type::ERROR_FATAL}, {"fatal_annotation3.txt", AuditorResult::Type::ERROR_FATAL}, @@ -402,8 +401,6 @@ int expected_ids[] = { TRAFFIC_ANNOTATION_FOR_TESTS.unique_id_hash_code, PARTIAL_TRAFFIC_ANNOTATION_FOR_TESTS.unique_id_hash_code, - NO_TRAFFIC_ANNOTATION_YET.unique_id_hash_code, - NO_PARTIAL_TRAFFIC_ANNOTATION_YET.unique_id_hash_code, MISSING_TRAFFIC_ANNOTATION.unique_id_hash_code}; std::map<int, std::string> reserved_words =
diff --git a/tools/traffic_annotation/bin/linux64/traffic_annotation_auditor.sha1 b/tools/traffic_annotation/bin/linux64/traffic_annotation_auditor.sha1 index 1b43dcba..36278a7b 100644 --- a/tools/traffic_annotation/bin/linux64/traffic_annotation_auditor.sha1 +++ b/tools/traffic_annotation/bin/linux64/traffic_annotation_auditor.sha1
@@ -1 +1 @@ -b7c7913c62ac2423106fe2f35e45d3f5dcdff190 \ No newline at end of file +73004f4964def13577f9d060d77908d51c30d521 \ No newline at end of file
diff --git a/tools/traffic_annotation/bin/win32/traffic_annotation_auditor.exe.sha1 b/tools/traffic_annotation/bin/win32/traffic_annotation_auditor.exe.sha1 index f784177..8e82538 100644 --- a/tools/traffic_annotation/bin/win32/traffic_annotation_auditor.exe.sha1 +++ b/tools/traffic_annotation/bin/win32/traffic_annotation_auditor.exe.sha1
@@ -1 +1 @@ -e37f10baabd3f87f6d7236e0dc32b100af415f0d \ No newline at end of file +e3c00e2607fbe0d5758e60bc42c6802feacdea08 \ No newline at end of file
diff --git a/tools/traffic_annotation/scripts/extractor.py b/tools/traffic_annotation/scripts/extractor.py index b76da3b..b2572af 100755 --- a/tools/traffic_annotation/scripts/extractor.py +++ b/tools/traffic_annotation/scripts/extractor.py
@@ -23,7 +23,6 @@ 'CreateMutableNetworkTrafficAnnotationTag': 'Mutable', } - # Regex that matches an annotation definition. CALL_DETECTION_REGEX = re.compile(r''' \b @@ -37,16 +36,22 @@ \( ''', re.VERBOSE | re.DOTALL) +# Regex that matches an annotation that should only be used in test files. +TEST_ANNOTATION_REGEX = re.compile( + r'\b(PARTIAL_)?TRAFFIC_ANNOTATION_FOR_TESTS\b') + +# Regex that matches a placeholder annotation for a few whitelisted files. +MISSING_ANNOTATION_REGEX = re.compile(r'\bMISSING_TRAFFIC_ANNOTATION\b') class Annotation: """A network annotation definition in C++ code.""" - def __init__(self, file_path, re_match): - """Parses the annotation and populates object fields. + def __init__(self, file_path, line_number, type_name='', unique_id='', + extra_id='', text=''): + """Constructs an Annotation object with the given field values. Args: file_path: Path to the file that contains this annotation. - re_match: A MatchObject obtained from CALL_DETECTION_REGEX. """ self.file_path = file_path # TODO(crbug/966883): Remove function_name from here and from the clang @@ -56,21 +61,28 @@ # compatibility with the clang tool. Use an obviously wrong function name # in case this details ends up in auditor output. self.function_name = "XXX_UNIMPLEMENTED_XXX" - self.line_number = get_line_number_at(re_match.string, re_match.start()) + self.line_number = line_number + self.type_name = type_name + self.unique_id = unique_id + self.extra_id = extra_id + self.text = text + def parse_definition(self, re_match): + """Parses the annotation and populates object fields. + + Args: + file_path: Path to the file that contains this annotation. + re_match: A MatchObject obtained from CALL_DETECTION_REGEX. + """ definition_function = re_match.group(1) self.type_name = ANNOTATION_TYPES[definition_function] - # These are populated by _parse_body(). - self.unique_id = '' - self.extra_id = '' - self.text = '' - # Parse the arguments given to the definition function, populating # |unique_id|, |text| and (possibly) |extra_id|. body = re_match.string[re_match.end():] self._parse_body(body) + def clang_tool_output_string(self): """Returns a string formatted for clang-tool-style output.""" return "\n".join(map(str, [ @@ -150,10 +162,49 @@ contents = f.read() defs = [] + + # Check for function calls (e.g. DefineNetworkTrafficAnnotation(...)) for re_match in CALL_DETECTION_REGEX.finditer(contents): if is_inside_comment(re_match.string, re_match.start()): continue - defs.append(Annotation(file_path, re_match)) + line_number = get_line_number_at(contents, re_match.start()) + annotation = Annotation(file_path, line_number) + annotation.parse_definition(re_match) + defs.append(annotation) + + # Check for test annotations (e.g. TRAFFIC_ANNOTATION_FOR_TESTS) + for re_match in TEST_ANNOTATION_REGEX.finditer(contents): + if is_inside_comment(re_match.string, re_match.start()): + continue + line_number = get_line_number_at(contents, re_match.start()) + + is_partial = bool(re_match.group(1)) + if is_partial: + type_name = 'Partial' + unique_id = 'test_partial' + extra_id = 'test' + else: + type_name = 'Definition' + unique_id = 'test' + extra_id = '' + + annotation = Annotation( + file_path, line_number, type_name=type_name, + unique_id=unique_id, extra_id=extra_id, + text='Traffic annotation for unit, browser and other tests') + defs.append(annotation) + + # Check for MISSING_TRAFFIC_ANNOTATION. + for re_match in MISSING_ANNOTATION_REGEX.finditer(contents): + if is_inside_comment(re_match.string, re_match.start()): + continue + line_number = get_line_number_at(contents, re_match.start()) + + annotation = Annotation( + file_path, line_number, type_name='Definition', unique_id='missing', + text='Function called without traffic annotation.') + defs.append(annotation) + return defs
diff --git a/tools/traffic_annotation/scripts/test_data/valid_file-stdout.txt b/tools/traffic_annotation/scripts/test_data/valid_file-stdout.txt index 51d4c2e..b98d267 100644 --- a/tools/traffic_annotation/scripts/test_data/valid_file-stdout.txt +++ b/tools/traffic_annotation/scripts/test_data/valid_file-stdout.txt
@@ -78,9 +78,27 @@ ==== NEW ANNOTATION ==== valid_file.cc XXX_UNIMPLEMENTED_XXX -121 +126 Mutable ==== ANNOTATION ENDS ==== +==== NEW ANNOTATION ==== +valid_file.cc +XXX_UNIMPLEMENTED_XXX +86 +Definition +test + +Traffic annotation for unit, browser and other tests +==== ANNOTATION ENDS ==== +==== NEW ANNOTATION ==== +valid_file.cc +XXX_UNIMPLEMENTED_XXX +88 +Partial +test_partial +test +Traffic annotation for unit, browser and other tests +==== ANNOTATION ENDS ====
diff --git a/tools/traffic_annotation/scripts/test_data/valid_file.cc b/tools/traffic_annotation/scripts/test_data/valid_file.cc index 32a1e9f5..fc03c18f 100644 --- a/tools/traffic_annotation/scripts/test_data/valid_file.cc +++ b/tools/traffic_annotation/scripts/test_data/valid_file.cc
@@ -81,6 +81,11 @@ net::URLFetcher::Create(0, GURL(), net::URLFetcher::RequestType::TEST_VALUE, delegate, NO_TRAFFIC_ANNOTATION_YET); + + net::URLFetcher::Create(GURL(), net::URLFetcher::RequestType::TEST_VALUE, + delegate, TRAFFIC_ANNOTATION_FOR_TESTS); + + SetPartialNetworkTrafficAnnotation(PARTIAL_TRAFFIC_ANNOTATION_FOR_TESTS); } void TestCreateRequest() {
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index 6ab62f2..377c38a7 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -101,7 +101,7 @@ <item id="external_policy_fetcher" hash_code="9459438" type="0" content_hash_code="64260484" os_list="linux,windows" file_path="components/policy/core/common/cloud/external_policy_data_fetcher.cc"/> <item id="family_info" hash_code="30913825" type="0" content_hash_code="25369370" os_list="linux,windows" file_path="chrome/browser/supervised_user/child_accounts/family_info_fetcher.cc"/> <item id="favicon_loader" hash_code="112189210" type="0" content_hash_code="70773116" os_list="linux,windows" file_path="content/renderer/loader/web_url_loader_impl.cc"/> - <item id="favicon_request_handler_get_favicon" hash_code="18468467" type="0" content_hash_code="72011341" os_list="linux,windows" file_path="components/favicon/core/favicon_request_handler.cc"/> + <item id="history_ui_favicon_request_handler_get_favicon" hash_code="17562717" type="0" content_hash_code="64054629" os_list="linux,windows" file_path="components/favicon/core/history_ui_favicon_request_handler_impl.cc"/> <item id="feed_image_fetcher" hash_code="87439531" type="0" deprecated="2019-01-04" content_hash_code="26756208" file_path=""/> <item id="gaia_auth_check_connection_info" hash_code="4598626" type="0" content_hash_code="57347000" os_list="linux,windows" file_path="google_apis/gaia/gaia_auth_fetcher.cc"/> <item id="gaia_auth_exchange_cookies" hash_code="134289752" type="0" deprecated="2018-09-11" content_hash_code="66433230" file_path=""/>
diff --git a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc index 3c0b696..5c06ac2 100644 --- a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc +++ b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc
@@ -423,6 +423,8 @@ ui::AXNodeData line_break1_data; line_break1_data.id = 5; line_break1_data.role = ax::mojom::Role::kLineBreak; + line_break1_data.AddBoolAttribute( + ax::mojom::BoolAttribute::kIsLineBreakingObject, true); line_break1_data.SetName("\n"); ui::AXNodeData standalone_text_data; @@ -440,6 +442,8 @@ ui::AXNodeData line_break2_data; line_break2_data.id = 7; line_break2_data.role = ax::mojom::Role::kLineBreak; + line_break2_data.AddBoolAttribute( + ax::mojom::BoolAttribute::kIsLineBreakingObject, true); line_break2_data.SetName("\n"); group2_data.child_ids = {5, 6, 7}; @@ -466,6 +470,8 @@ ui::AXNodeData paragraph1_data; paragraph1_data.id = 9; paragraph1_data.role = ax::mojom::Role::kParagraph; + paragraph1_data.AddBoolAttribute( + ax::mojom::BoolAttribute::kIsLineBreakingObject, true); ui::AXNodeData paragraph1_text_data; paragraph1_text_data.id = 10; @@ -483,6 +489,8 @@ ui::AXNodeData paragraph2_data; paragraph2_data.id = 11; paragraph2_data.role = ax::mojom::Role::kParagraph; + paragraph2_data.AddBoolAttribute( + ax::mojom::BoolAttribute::kIsLineBreakingObject, true); ui::AXNodeData paragraph2_text_data; paragraph2_text_data.id = 12; @@ -1672,7 +1680,125 @@ ComPtr<ITextRangeProvider> text_range_provider; GetTextRangeProviderFromTextNode(text_range_provider, root_node); - // TODO(https://crbug.com/928948): add tests + // Moving by 0 should have no effect. + EXPECT_UIA_MOVE( + text_range_provider, TextUnit_Paragraph, + /*count*/ 0, + /*expected_text*/ + L"First line of text\nStandalone line\nbold textParagraph 1Paragraph 2", + /*expected_count*/ 0); + + EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT( + text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Paragraph, + /*count*/ -4, + /*expected_text*/ L"First line of text\n", + /*expected_count*/ -4); + + // Move forward. + EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph, + /*count*/ 1, + /*expected_text*/ L"Standalone line\n", + /*expected_count*/ 1); + EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph, + /*count*/ 2, + /*expected_text*/ L"Paragraph 1", + /*expected_count*/ 2); + EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph, + /*count*/ 1, + /*expected_text*/ L"Paragraph 2", + /*expected_count*/ 1); + + // Trying to move past the last format should have no effect. + EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph, + /*count*/ 1, + /*expected_text*/ L"Paragraph 2", + /*expected_count*/ 0); + + // Move backward. + EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph, + /*count*/ -3, + /*expected_text*/ L"Standalone line\n", + /*expected_count*/ -3); + EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph, + /*count*/ -1, + /*expected_text*/ L"First line of text\n", + /*expected_count*/ -1); + + // Moving backward by any number of paragraphs at the start of document + // should have no effect. + EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph, + /*count*/ -1, + /*expected_text*/ + L"First line of text\n", + /*expected_count*/ 0); + + // Test degenerate range creation at the beginning of the document. + EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT( + text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Paragraph, + /*count*/ -1, + /*expected_text*/ L"", + /*expected_count*/ -1); + EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT( + text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Paragraph, + /*count*/ 1, + /*expected_text*/ L"First line of text\n", + /*expected_count*/ 1); + + // Test degenerate range creation at the end of the document. + EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph, + /*count*/ 5, + /*expected_text*/ L"Paragraph 2", + /*expected_count*/ 4); + EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT( + text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Paragraph, + /*count*/ 1, + /*expected_text*/ L"", + /*expected_count*/ 1); + EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT( + text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Paragraph, + /*count*/ -1, + /*expected_text*/ L"Paragraph 2", + /*expected_count*/ -1); + EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT( + text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Paragraph, + /*count*/ 1, + /*expected_text*/ L"", + /*expected_count*/ 1); + EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT( + text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Paragraph, + /*count*/ -1, + /*expected_text*/ L"Paragraph 2", + /*expected_count*/ -1); + + // Degenerate range moves. + EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph, + /*count*/ -6, + /*expected_text*/ L"First line of text\n", + /*expected_count*/ -5); + EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT( + text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Paragraph, + /*count*/ -1, + /*expected_text*/ L"", + /*expected_count*/ -1); + EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph, + /*count*/ 3, + /*expected_text*/ L"", + /*expected_count*/ 3); + EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph, + /*count*/ 70, + /*expected_text*/ L"", + /*expected_count*/ 2); + + // Trying to move past the last paragraph should have no effect. + EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph, + /*count*/ 70, + /*expected_text*/ L"", + /*expected_count*/ 0); + EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph, + /*count*/ -2, + /*expected_text*/ L"", + /*expected_count*/ -2); + AXNodePosition::SetTreeForTesting(nullptr); }
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn index f41661ae..68e24a1c 100644 --- a/ui/base/BUILD.gn +++ b/ui/base/BUILD.gn
@@ -1055,7 +1055,8 @@ ] } - if (use_aura || toolkit_views) { + # TODO(crbug.com/980371): Implement OSExchangeDataProvider for Fuchsia. + if ((use_aura || toolkit_views) && !is_fuchsia) { sources += [ "dragdrop/os_exchange_data_unittest.cc" ] deps += [
diff --git a/ui/base/dragdrop/os_exchange_data_provider_factory.cc b/ui/base/dragdrop/os_exchange_data_provider_factory.cc index 30a259cb1d..4c5fbfb 100644 --- a/ui/base/dragdrop/os_exchange_data_provider_factory.cc +++ b/ui/base/dragdrop/os_exchange_data_provider_factory.cc
@@ -30,7 +30,7 @@ #elif defined(OS_WIN) return std::make_unique<OSExchangeDataProviderWin>(); #elif defined(OS_FUCHSIA) - // TODO(fuchsia): Implement this when UI support is added. (crbug.com/750934) + // TODO(crbug.com/980371): Implement OSExchangeDataProvider for Fuchsia. NOTIMPLEMENTED(); return nullptr; #else
diff --git a/ui/file_manager/file_manager/foreground/elements/files_format_dialog.html b/ui/file_manager/file_manager/foreground/elements/files_format_dialog.html index 70995d5..465b05c 100644 --- a/ui/file_manager/file_manager/foreground/elements/files_format_dialog.html +++ b/ui/file_manager/file_manager/foreground/elements/files_format_dialog.html
@@ -45,7 +45,7 @@ </style> <cr-dialog id="dialog" show-close-button - close-text="[[i18n('CLOSE_LABEL')]]"> + close-text="[[i18n('CLOSE_LABEL')]]" exportparts="dialog"> <div slot="title"> [[i18n('FORMAT_DIALOG_TITLE', volumeInfo_.label)]] </div>
diff --git a/ui/file_manager/file_manager/main.html b/ui/file_manager/file_manager/main.html index de86a70..2650ee9 100644 --- a/ui/file_manager/file_manager/main.html +++ b/ui/file_manager/file_manager/main.html
@@ -74,10 +74,8 @@ --files-ripple-bg-color: black; } - files-format-dialog { - --cr-dialog-native: { - border-radius: 2px; - } + files-format-dialog::part(dialog) { + border-radius: 2px; } </style> </custom-style>
diff --git a/ui/message_center/views/notification_control_buttons_view.cc b/ui/message_center/views/notification_control_buttons_view.cc index 69b1fba..cff9ebb 100644 --- a/ui/message_center/views/notification_control_buttons_view.cc +++ b/ui/message_center/views/notification_control_buttons_view.cc
@@ -97,9 +97,9 @@ gfx::CreateVectorIcon(kNotificationSnoozeButtonIcon, gfx::kChromeIconGrey)); snooze_button_->SetAccessibleName(l10n_util::GetStringUTF16( - IDS_MESSAGE_NOTIFICATION_SETTINGS_BUTTON_ACCESSIBLE_NAME)); + IDS_MESSAGE_CENTER_NOTIFICATION_SNOOZE_BUTTON_TOOLTIP)); snooze_button_->SetTooltipText(l10n_util::GetStringUTF16( - IDS_MESSAGE_NOTIFICATION_SETTINGS_BUTTON_ACCESSIBLE_NAME)); + IDS_MESSAGE_CENTER_NOTIFICATION_SNOOZE_BUTTON_TOOLTIP)); snooze_button_->SetBackground( views::CreateSolidBackground(SK_ColorTRANSPARENT));
diff --git a/ui/ozone/demo/vulkan_renderer.cc b/ui/ozone/demo/vulkan_renderer.cc index 945937f..2650398f 100644 --- a/ui/ozone/demo/vulkan_renderer.cc +++ b/ui/ozone/demo/vulkan_renderer.cc
@@ -223,8 +223,8 @@ /* .color = */ {/* .float32 = */ {.5f, 1.f - NextFraction(), .5f, 1.f}}}; gpu::VulkanSwapChain* vulkan_swap_chain = vulkan_surface_->GetSwapChain(); - const uint32_t image = vulkan_swap_chain->current_image(); gpu::VulkanSwapChain::ScopedWrite scoped_write(vulkan_swap_chain); + const uint32_t image = scoped_write.image_index(); { auto& framebuffer = framebuffers_[image]; if (!framebuffer) { @@ -305,7 +305,7 @@ device_queue_->GetFenceHelper()->EnqueueSemaphoreCleanupForSubmittedWork( begin_semaphore); } - vulkan_swap_chain->SwapBuffers(); + vulkan_surface_->SwapBuffers(); PostRenderFrameTask(); }
diff --git a/ui/ozone/platform/x11/DEPS b/ui/ozone/platform/x11/DEPS index 8d59099..3b6346a6 100644 --- a/ui/ozone/platform/x11/DEPS +++ b/ui/ozone/platform/x11/DEPS
@@ -1,3 +1,4 @@ include_rules = [ "+ui/base/x", + "+ui/base", ]
diff --git a/ui/ozone/platform/x11/x11_window_ozone.cc b/ui/ozone/platform/x11/x11_window_ozone.cc index e9ce3e7..b02c487a9 100644 --- a/ui/ozone/platform/x11/x11_window_ozone.cc +++ b/ui/ozone/platform/x11/x11_window_ozone.cc
@@ -4,36 +4,240 @@ #include "ui/ozone/platform/x11/x11_window_ozone.h" +#include <algorithm> +#include <string> +#include <vector> + #include "base/bind.h" +#include "base/strings/utf_string_conversions.h" +#include "ui/base/platform_window_defaults.h" +#include "ui/base/x/x11_util.h" #include "ui/events/event.h" #include "ui/events/event_utils.h" #include "ui/events/ozone/events_ozone.h" #include "ui/events/platform/x11/x11_event_source.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/x/x11.h" +#include "ui/gfx/x/x11_atom_cache.h" #include "ui/ozone/platform/x11/x11_cursor_ozone.h" #include "ui/ozone/platform/x11/x11_window_manager_ozone.h" namespace ui { +namespace { + +XID FindXEventTarget(const XEvent& xev) { + XID target = xev.xany.window; + if (xev.type == GenericEvent) + target = static_cast<XIDeviceEvent*>(xev.xcookie.data)->event; + return target; +} + +} // namespace X11WindowOzone::X11WindowOzone(X11WindowManagerOzone* window_manager, PlatformWindowDelegate* delegate, const gfx::Rect& bounds) - : X11WindowBase(delegate, bounds), window_manager_(window_manager) { - DCHECK(window_manager); + : window_manager_(window_manager), + delegate_(delegate), + xdisplay_(gfx::GetXDisplay()), + xroot_window_(DefaultRootWindow(xdisplay_)), + xwindow_(x11::None), + mapped_(false), + bounds_(bounds), + state_(ui::PlatformWindowState::PLATFORM_WINDOW_STATE_UNKNOWN) { + DCHECK(delegate_); + DCHECK(window_manager_); + + Create(); + pointer_barriers_.fill(x11::None); + auto* event_source = X11EventSourceLibevent::GetInstance(); if (event_source) event_source->AddXEventDispatcher(this); } X11WindowOzone::~X11WindowOzone() { - X11WindowOzone::PrepareForShutdown(); + PrepareForShutdown(); + UnconfineCursor(); + Destroy(); } -void X11WindowOzone::PrepareForShutdown() { - auto* event_source = X11EventSourceLibevent::GetInstance(); - if (event_source) - event_source->RemoveXEventDispatcher(this); +void X11WindowOzone::Destroy() { + if (xwindow_ == x11::None) + return; + + // Stop processing events. + XID xwindow = xwindow_; + XDisplay* xdisplay = xdisplay_; + SetXWindow(x11::None); + + delegate_->OnClosed(); + XDestroyWindow(xdisplay, xwindow); +} + +void X11WindowOzone::Create() { + DCHECK(!bounds_.size().IsEmpty()); + DCHECK_NE(xdisplay_, nullptr); + + XID xwindow = CreateXWindow(); + DCHECK(xwindow); + + SetXWindow(xwindow); +} + +XID X11WindowOzone::CreateXWindow() { + XID xwindow = x11::None; + XSetWindowAttributes swa; + memset(&swa, 0, sizeof(swa)); + swa.background_pixmap = x11::None; + swa.bit_gravity = NorthWestGravity; + swa.override_redirect = UseTestConfigForPlatformWindows(); + xwindow = + XCreateWindow(xdisplay_, xroot_window_, bounds_.x(), bounds_.y(), + bounds_.width(), bounds_.height(), + 0, // border width + CopyFromParent, // depth + InputOutput, + CopyFromParent, // visual + CWBackPixmap | CWBitGravity | CWOverrideRedirect, &swa); + + // Setup XInput event mask. + long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask | + KeyPressMask | KeyReleaseMask | EnterWindowMask | + LeaveWindowMask | ExposureMask | VisibilityChangeMask | + StructureNotifyMask | PropertyChangeMask | + PointerMotionMask; + xwindow_events_.reset(new ui::XScopedEventSelector(xwindow, event_mask)); + + // Setup XInput2 event mask. + unsigned char mask[XIMaskLen(XI_LASTEVENT)]; + memset(mask, 0, sizeof(mask)); + + XISetMask(mask, XI_TouchBegin); + XISetMask(mask, XI_TouchUpdate); + XISetMask(mask, XI_TouchEnd); + XISetMask(mask, XI_ButtonPress); + XISetMask(mask, XI_ButtonRelease); + XISetMask(mask, XI_Motion); + XISetMask(mask, XI_KeyPress); + XISetMask(mask, XI_KeyRelease); + XISetMask(mask, XI_HierarchyChanged); + + XIEventMask evmask; + evmask.deviceid = XIAllDevices; + evmask.mask_len = sizeof(mask); + evmask.mask = mask; + XISelectEvents(xdisplay_, xwindow, &evmask, 1); + XFlush(xdisplay_); + + XAtom protocols[] = {gfx::GetAtom("WM_DELETE_WINDOW"), + gfx::GetAtom("_NET_WM_PING")}; + XSetWMProtocols(xdisplay_, xwindow, protocols, 2); + + // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with + // the desktop environment. + XSetWMProperties(xdisplay_, xwindow, NULL, NULL, NULL, 0, NULL, NULL, NULL); + + // Likewise, the X server needs to know this window's pid so it knows which + // program to kill if the window hangs. XChangeProperty() expects "pid" to be + // long. + static_assert(sizeof(long) >= sizeof(pid_t), + "pid_t should not be larger than long"); + long pid = getpid(); + XChangeProperty(xdisplay_, xwindow, gfx::GetAtom("_NET_WM_PID"), XA_CARDINAL, + 32, PropModeReplace, reinterpret_cast<unsigned char*>(&pid), + 1); + // Before we map the window, set size hints. Otherwise, some window managers + // will ignore toplevel XMoveWindow commands. + XSizeHints size_hints; + size_hints.flags = PPosition | PWinGravity; + size_hints.x = bounds_.x(); + size_hints.y = bounds_.y(); + // Set StaticGravity so that the window position is not affected by the + // frame width when running with window manager. + size_hints.win_gravity = StaticGravity; + XSetWMNormalHints(xdisplay_, xwindow, &size_hints); + + return xwindow; +} + +void X11WindowOzone::Show() { + if (mapped_) + return; + + XMapWindow(xdisplay_, xwindow_); + XFlush(xdisplay_); + mapped_ = true; +} + +void X11WindowOzone::Hide() { + if (!mapped_) + return; + + XWithdrawWindow(xdisplay_, xwindow_, 0); + mapped_ = false; +} + +void X11WindowOzone::Close() { + Destroy(); +} + +void X11WindowOzone::SetBounds(const gfx::Rect& bounds) { + DCHECK(!bounds.size().IsEmpty()); + + if (xwindow_ != x11::None) { + XWindowChanges changes = {0}; + unsigned value_mask = 0; + + if (bounds_.size() != bounds.size()) { + changes.width = bounds.width(); + changes.height = bounds.height(); + value_mask |= CWHeight | CWWidth; + } + + if (bounds_.origin() != bounds.origin()) { + changes.x = bounds.x(); + changes.y = bounds.y(); + value_mask |= CWX | CWY; + } + + if (value_mask) + XConfigureWindow(xdisplay_, xwindow_, value_mask, &changes); + } + + // Assume that the resize will go through as requested, which should be the + // case if we're running without a window manager. If there's a window + // manager, it can modify or ignore the request, but (per ICCCM) we'll get a + // (possibly synthetic) ConfigureNotify about the actual size and correct + // |bounds_| later. + bounds_ = bounds; + + // Even if the pixel bounds didn't change this call to the delegate should + // still happen. The device scale factor may have changed which effectively + // changes the bounds. + delegate_->OnBoundsChanged(bounds_); +} + +gfx::Rect X11WindowOzone::GetBounds() { + return bounds_; +} + +void X11WindowOzone::SetTitle(const base::string16& title) { + if (window_title_ == title) + return; + window_title_ = title; + std::string utf8str = base::UTF16ToUTF8(title); + XChangeProperty(xdisplay_, xwindow_, gfx::GetAtom("_NET_WM_NAME"), + gfx::GetAtom("UTF8_STRING"), 8, PropModeReplace, + reinterpret_cast<const unsigned char*>(utf8str.c_str()), + utf8str.size()); + XTextProperty xtp; + char* c_utf8_str = const_cast<char*>(utf8str.c_str()); + if (Xutf8TextListToTextProperty(xdisplay_, &c_utf8_str, 1, XUTF8StringStyle, + &xtp) == x11::Success) { + XSetWMName(xdisplay_, xwindow_, &xtp); + XFree(xtp.value); + } } void X11WindowOzone::SetCapture() { @@ -48,13 +252,107 @@ return window_manager_->event_grabber() == this; } +void X11WindowOzone::ToggleFullscreen() { + ui::SetWMSpecState(xwindow_, !IsFullscreen(), + gfx::GetAtom("_NET_WM_STATE_FULLSCREEN"), x11::None); +} + +void X11WindowOzone::Maximize() { + if (IsFullscreen()) + ToggleFullscreen(); + + ui::SetWMSpecState(xwindow_, true, + gfx::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"), + gfx::GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ")); +} + +void X11WindowOzone::Minimize() { + XIconifyWindow(xdisplay_, xwindow_, 0); +} + +void X11WindowOzone::Restore() { + if (IsFullscreen()) + ToggleFullscreen(); + + if (IsMaximized()) { + ui::SetWMSpecState(xwindow_, false, + gfx::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"), + gfx::GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ")); + } +} + +PlatformWindowState X11WindowOzone::GetPlatformWindowState() const { + return state_; +} + +void X11WindowOzone::MoveCursorTo(const gfx::Point& location) { + XWarpPointer(xdisplay_, x11::None, xroot_window_, 0, 0, 0, 0, + bounds_.x() + location.x(), bounds_.y() + location.y()); +} + +void X11WindowOzone::ConfineCursorToBounds(const gfx::Rect& bounds) { + UnconfineCursor(); + + if (bounds.IsEmpty()) + return; + + gfx::Rect barrier = bounds + bounds_.OffsetFromOrigin(); + + // Top horizontal barrier. + pointer_barriers_[0] = XFixesCreatePointerBarrier( + xdisplay_, xroot_window_, barrier.x(), barrier.y(), barrier.right(), + barrier.y(), BarrierPositiveY, 0, XIAllDevices); + // Bottom horizontal barrier. + pointer_barriers_[1] = XFixesCreatePointerBarrier( + xdisplay_, xroot_window_, barrier.x(), barrier.bottom(), barrier.right(), + barrier.bottom(), BarrierNegativeY, 0, XIAllDevices); + // Left vertical barrier. + pointer_barriers_[2] = XFixesCreatePointerBarrier( + xdisplay_, xroot_window_, barrier.x(), barrier.y(), barrier.x(), + barrier.bottom(), BarrierPositiveX, 0, XIAllDevices); + // Right vertical barrier. + pointer_barriers_[3] = XFixesCreatePointerBarrier( + xdisplay_, xroot_window_, barrier.right(), barrier.y(), barrier.right(), + barrier.bottom(), BarrierNegativeX, 0, XIAllDevices); + + has_pointer_barriers_ = true; +} + +void X11WindowOzone::SetRestoredBoundsInPixels(const gfx::Rect& bounds) { + // TODO(crbug.com/848131): Restore bounds on restart + NOTIMPLEMENTED_LOG_ONCE(); +} + +gfx::Rect X11WindowOzone::GetRestoredBoundsInPixels() const { + // TODO(crbug.com/848131): Restore bounds on restart + NOTIMPLEMENTED_LOG_ONCE(); + return gfx::Rect(); +} + +void X11WindowOzone::UnconfineCursor() { + if (!has_pointer_barriers_) + return; + + for (XID pointer_barrier : pointer_barriers_) + XFixesDestroyPointerBarrier(xdisplay_, pointer_barrier); + pointer_barriers_.fill(x11::None); + + has_pointer_barriers_ = false; +} + +void X11WindowOzone::PrepareForShutdown() { + auto* event_source = X11EventSourceLibevent::GetInstance(); + if (event_source) + event_source->RemoveXEventDispatcher(this); +} + void X11WindowOzone::SetCursor(PlatformCursor cursor) { X11CursorOzone* cursor_ozone = static_cast<X11CursorOzone*>(cursor); - XDefineCursor(xdisplay(), xwindow(), cursor_ozone->xcursor()); + XDefineCursor(xdisplay_, xwindow_, cursor_ozone->xcursor()); } void X11WindowOzone::CheckCanDispatchNextPlatformEvent(XEvent* xev) { - handle_next_event_ = xwindow() == x11::None ? false : IsEventForXWindow(*xev); + handle_next_event_ = xwindow_ == x11::None ? false : IsEventForXWindow(*xev); } void X11WindowOzone::PlatformEventDispatchFinished() { @@ -84,7 +382,7 @@ // (eg. double click) are broken. DispatchEventFromNativeUiEvent( event, base::BindOnce(&PlatformWindowDelegate::DispatchEvent, - base::Unretained(delegate()))); + base::Unretained(delegate_))); return POST_DISPATCH_STOP_PROPAGATION; } @@ -99,7 +397,129 @@ } void X11WindowOzone::OnLostCapture() { - delegate()->OnLostCapture(); + delegate_->OnLostCapture(); +} + +// Private methods + +void X11WindowOzone::SetXWindow(XID xid) { + xwindow_ = xid; + + // In spite of being defined in Xlib as `unsigned long`, XID (|xwindow_|'s + // type) is fixed at 32-bits (CARD32) in X11 Protocol, therefore can't be + // larger than 32 bits values on the wire (see https://crbug.com/607014 for + // more details). So, It's safe to use static_cast here. + widget_ = static_cast<gfx::AcceleratedWidget>(xwindow_); + if (widget_ != gfx::kNullAcceleratedWidget) + delegate_->OnAcceleratedWidgetAvailable(widget_); +} + +bool X11WindowOzone::IsEventForXWindow(const XEvent& xev) const { + return xwindow_ != x11::None && FindXEventTarget(xev) == xwindow_; +} + +void X11WindowOzone::ProcessXWindowEvent(XEvent* xev) { + switch (xev->type) { + case Expose: { + gfx::Rect damage_rect(xev->xexpose.x, xev->xexpose.y, xev->xexpose.width, + xev->xexpose.height); + delegate_->OnDamageRect(damage_rect); + break; + } + + case x11::FocusOut: + if (xev->xfocus.mode != NotifyGrab) + delegate_->OnLostCapture(); + break; + + case ConfigureNotify: { + DCHECK_EQ(xwindow_, xev->xconfigure.event); + DCHECK_EQ(xwindow_, xev->xconfigure.window); + // It's possible that the X window may be resized by some other means than + // from within aura (e.g. the X window manager can change the size). Make + // sure the root window size is maintained properly. + int translated_x_in_pixels = xev->xconfigure.x; + int translated_y_in_pixels = xev->xconfigure.y; + if (!xev->xconfigure.send_event && !xev->xconfigure.override_redirect) { + Window unused; + XTranslateCoordinates(xdisplay_, xwindow_, xroot_window_, 0, 0, + &translated_x_in_pixels, &translated_y_in_pixels, + &unused); + } + gfx::Rect bounds(translated_x_in_pixels, translated_y_in_pixels, + xev->xconfigure.width, xev->xconfigure.height); + if (bounds_ != bounds) { + bounds_ = bounds; + delegate_->OnBoundsChanged(bounds_); + } + break; + } + + case ClientMessage: { + Atom message = static_cast<Atom>(xev->xclient.data.l[0]); + if (message == gfx::GetAtom("WM_DELETE_WINDOW")) { + delegate_->OnCloseRequest(); + } else if (message == gfx::GetAtom("_NET_WM_PING")) { + XEvent reply_event = *xev; + reply_event.xclient.window = xroot_window_; + + XSendEvent(xdisplay_, reply_event.xclient.window, x11::False, + SubstructureRedirectMask | SubstructureNotifyMask, + &reply_event); + XFlush(xdisplay_); + } + break; + } + case PropertyNotify: { + XAtom changed_atom = xev->xproperty.atom; + if (changed_atom == gfx::GetAtom("_NET_WM_STATE")) + OnWMStateUpdated(); + break; + } + } +} + +void X11WindowOzone::OnWMStateUpdated() { + std::vector<XAtom> atom_list; + // Ignore the return value of ui::GetAtomArrayProperty(). Fluxbox removes the + // _NET_WM_STATE property when no _NET_WM_STATE atoms are set. + ui::GetAtomArrayProperty(xwindow_, "_NET_WM_STATE", &atom_list); + + window_properties_.clear(); + std::copy(atom_list.begin(), atom_list.end(), + inserter(window_properties_, window_properties_.begin())); + + // Propagate the window state information to the client. + // Note that the order of checks is important here, because window can have + // several proprties at the same time. + ui::PlatformWindowState old_state = state_; + if (ui::HasWMSpecProperty(window_properties_, + gfx::GetAtom("_NET_WM_STATE_HIDDEN"))) { + state_ = ui::PlatformWindowState::PLATFORM_WINDOW_STATE_MINIMIZED; + } else if (ui::HasWMSpecProperty(window_properties_, + gfx::GetAtom("_NET_WM_STATE_FULLSCREEN"))) { + state_ = ui::PlatformWindowState::PLATFORM_WINDOW_STATE_FULLSCREEN; + } else if (ui::HasWMSpecProperty( + window_properties_, + gfx::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT")) && + ui::HasWMSpecProperty( + window_properties_, + gfx::GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ"))) { + state_ = ui::PlatformWindowState::PLATFORM_WINDOW_STATE_MAXIMIZED; + } else { + state_ = ui::PlatformWindowState::PLATFORM_WINDOW_STATE_NORMAL; + } + + if (old_state != state_) + delegate_->OnWindowStateChanged(state_); +} + +bool X11WindowOzone::IsMaximized() const { + return state_ == ui::PlatformWindowState::PLATFORM_WINDOW_STATE_MAXIMIZED; +} + +bool X11WindowOzone::IsFullscreen() const { + return state_ == ui::PlatformWindowState::PLATFORM_WINDOW_STATE_FULLSCREEN; } } // namespace ui
diff --git a/ui/ozone/platform/x11/x11_window_ozone.h b/ui/ozone/platform/x11/x11_window_ozone.h index ab45885..6188274c 100644 --- a/ui/ozone/platform/x11/x11_window_ozone.h +++ b/ui/ozone/platform/x11/x11_window_ozone.h
@@ -5,17 +5,24 @@ #ifndef UI_OZONE_PLATFORM_X11_X11_WINDOW_OZONE_H_ #define UI_OZONE_PLATFORM_X11_X11_WINDOW_OZONE_H_ +#include <array> +#include <memory> + +#include "base/containers/flat_set.h" #include "base/macros.h" +#include "ui/base/x/x11_window_event_manager.h" #include "ui/events/platform/platform_event_dispatcher.h" #include "ui/events/platform/x11/x11_event_source_libevent.h" -#include "ui/platform_window/x11/x11_window_base.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/x/x11_types.h" +#include "ui/platform_window/platform_window.h" namespace ui { class X11WindowManagerOzone; // PlatformWindow implementation for X11 Ozone. PlatformEvents are ui::Events. -class X11WindowOzone : public X11WindowBase, +class X11WindowOzone : public PlatformWindow, public PlatformEventDispatcher, public XEventDispatcher { public: @@ -28,6 +35,21 @@ void OnLostCapture(); // PlatformWindow: + void Show() override; + void Hide() override; + void Close() override; + void SetBounds(const gfx::Rect& bounds) override; + gfx::Rect GetBounds() override; + void SetTitle(const base::string16& title) override; + void ToggleFullscreen() override; + void Maximize() override; + void Minimize() override; + void Restore() override; + PlatformWindowState GetPlatformWindowState() const override; + void MoveCursorTo(const gfx::Point& location) override; + void ConfineCursorToBounds(const gfx::Rect& bounds) override; + void SetRestoredBoundsInPixels(const gfx::Rect& bounds) override; + gfx::Rect GetRestoredBoundsInPixels() const override; void PrepareForShutdown() override; void SetCapture() override; void ReleaseCapture() override; @@ -45,12 +67,39 @@ bool CanDispatchEvent(const PlatformEvent& event) override; uint32_t DispatchEvent(const PlatformEvent& event) override; + void Create(); + void Destroy(); + XID CreateXWindow(); + void SetXWindow(XID xwindow); + bool IsMaximized() const; + bool IsFullscreen() const; + bool IsEventForXWindow(const XEvent& xev) const; + void ProcessXWindowEvent(XEvent* xev); + void OnWMStateUpdated(); + void UnconfineCursor(); + X11WindowManagerOzone* window_manager_; + PlatformWindowDelegate* const delegate_; + XDisplay* xdisplay_; + XID xroot_window_; + XID xwindow_; + bool mapped_; + gfx::Rect bounds_; + base::string16 window_title_; + ui::PlatformWindowState state_; + base::flat_set<XAtom> window_properties_; // Tells if this dispatcher can process next translated event based on a // previous check in ::CheckCanDispatchNextPlatformEvent based on a XID // target. bool handle_next_event_ = false; + std::unique_ptr<ui::XScopedEventSelector> xwindow_events_; + + // Keep track of barriers to confine cursor. + bool has_pointer_barriers_ = false; + std::array<XID, 4> pointer_barriers_; + + gfx::AcceleratedWidget widget_ = gfx::kNullAcceleratedWidget; DISALLOW_COPY_AND_ASSIGN(X11WindowOzone); };
diff --git a/ui/strings/ui_strings.grd b/ui/strings/ui_strings.grd index 703cf1c2..f6d9c56 100644 --- a/ui/strings/ui_strings.grd +++ b/ui/strings/ui_strings.grd
@@ -758,6 +758,9 @@ <message name="IDS_MESSAGE_CENTER_CLOSE_NOTIFICATION_BUTTON_TOOLTIP" desc="The tooltip text for the close button in a notification."> Close </message> + <message name="IDS_MESSAGE_CENTER_NOTIFICATION_SNOOZE_BUTTON_TOOLTIP" desc="The tooltip and spoken feedback text for the snooze button in a notification. Usually 'button' is suffixed to this text automatically during spoken feedback."> + Snooze + </message> <message name="IDS_MESSAGE_NOTIFICATION_SETTINGS_BUTTON_ACCESSIBLE_NAME" desc="The spoken feedback text for the settings button in a notification. Usually 'button' is suffixed to this text automatically."> Notification settings </message>
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn index a146912..864dac20 100644 --- a/ui/views/BUILD.gn +++ b/ui/views/BUILD.gn
@@ -201,8 +201,11 @@ "layout/flex_layout.h", "layout/flex_layout_types.h", "layout/grid_layout.h", + "layout/interpolating_layout_manager.h", "layout/layout_manager.h", + "layout/layout_manager_base.h", "layout/layout_provider.h", + "layout/layout_types.h", "masked_targeter_delegate.h", "metadata/metadata_cache.h", "metadata/metadata_header_macros.h", @@ -405,8 +408,11 @@ "layout/flex_layout_types.cc", "layout/flex_layout_types_internal.cc", "layout/grid_layout.cc", + "layout/interpolating_layout_manager.cc", "layout/layout_manager.cc", + "layout/layout_manager_base.cc", "layout/layout_provider.cc", + "layout/layout_types.cc", "masked_targeter_delegate.cc", "metadata/metadata_cache.cc", "metadata/metadata_types.cc", @@ -1032,6 +1038,8 @@ "layout/fill_layout_unittest.cc", "layout/flex_layout_unittest.cc", "layout/grid_layout_unittest.cc", + "layout/interpolating_layout_manager_unittest.cc", + "layout/layout_manager_base_unittest.cc", "metadata/metadata_unittest.cc", "metadata/type_conversion_unittest.cc", "paint_info_unittest.cc",
diff --git a/ui/views/layout/flex_layout_types.cc b/ui/views/layout/flex_layout_types.cc index 7100e688..6950570 100644 --- a/ui/views/layout/flex_layout_types.cc +++ b/ui/views/layout/flex_layout_types.cc
@@ -9,7 +9,6 @@ #include <utility> #include "base/bind.h" -#include "base/strings/stringprintf.h" #include "ui/gfx/geometry/size.h" #include "ui/views/view.h" @@ -17,12 +16,6 @@ namespace { -std::string OptionalToString(const base::Optional<int>& opt) { - if (!opt.has_value()) - return "_"; - return base::StringPrintf("%d", opt.value()); -} - // Default Flex Rules ---------------------------------------------------------- // Interpolates a size between minimum, preferred size, and upper bound based on @@ -97,7 +90,9 @@ // Note that this is an adjustment made for practical considerations, and may // not be "correct" in some absolute sense. Let's revisit at some point. const int preferred_height = - std::max(preferred.height(), view->GetHeightForWidth(width)); + width >= preferred.width() + ? preferred.height() + : std::max(preferred.height(), view->GetHeightForWidth(width)); if (!maximum_size.height()) { // Not having a maximum size is different from having a large available @@ -120,44 +115,6 @@ } // namespace -// SizeBounds ------------------------------------------------------------------ - -SizeBounds::SizeBounds() = default; - -SizeBounds::SizeBounds(const base::Optional<int>& width, - const base::Optional<int>& height) - : width_(width), height_(height) {} - -SizeBounds::SizeBounds(const SizeBounds& other) - : width_(other.width()), height_(other.height()) {} - -SizeBounds::SizeBounds(const gfx::Size& other) - : width_(other.width()), height_(other.height()) {} - -void SizeBounds::Enlarge(int width, int height) { - if (width_) - width_ = std::max(0, *width_ + width); - if (height_) - height_ = std::max(0, *height_ + height); -} - -bool SizeBounds::operator==(const SizeBounds& other) const { - return width_ == other.width_ && height_ == other.height_; -} - -bool SizeBounds::operator!=(const SizeBounds& other) const { - return !(*this == other); -} - -bool SizeBounds::operator<(const SizeBounds& other) const { - return std::tie(height_, width_) < std::tie(other.height_, other.width_); -} - -std::string SizeBounds::ToString() const { - return base::StringPrintf("%s x %s", OptionalToString(width()).c_str(), - OptionalToString(height()).c_str()); -} - // FlexSpecification ----------------------------------------------------------- FlexSpecification::FlexSpecification() : rule_(GetDefaultFlexRule()) {} @@ -193,4 +150,112 @@ return FlexSpecification(rule_, order, weight_); } +// Inset1D --------------------------------------------------------------------- + +void Inset1D::SetInsets(int leading, int trailing) { + leading_ = leading; + trailing_ = trailing; +} + +void Inset1D::Expand(int leading, int trailing) { + leading_ += leading; + trailing_ += trailing; +} + +bool Inset1D::operator==(const Inset1D& other) const { + return leading_ == other.leading_ && trailing_ == other.trailing_; +} + +bool Inset1D::operator!=(const Inset1D& other) const { + return !(*this == other); +} + +bool Inset1D::operator<(const Inset1D& other) const { + return std::tie(leading_, trailing_) < + std::tie(other.leading_, other.trailing_); +} + +std::string Inset1D::ToString() const { + return base::StringPrintf("%d, %d", leading(), trailing()); +} + +// Span ------------------------------------------------------------------------ + +void Span::SetSpan(int start, int length) { + start_ = start; + length_ = std::max(0, length); +} + +void Span::Expand(int leading, int trailing) { + const int end = this->end(); + set_start(start_ - leading); + set_end(end + trailing); +} + +void Span::Inset(int leading, int trailing) { + Expand(-leading, -trailing); +} + +void Span::Inset(const Inset1D& insets) { + Inset(insets.leading(), insets.trailing()); +} + +void Span::Center(const Span& container, const Inset1D& margins) { + int remaining = container.length() - length(); + + // Case 1: no room for any margins. Just center the span in the container, + // with equal overflow on each side. + if (remaining <= 0) { + set_start(container.start() + std::ceil(remaining * 0.5f)); + return; + } + + // Case 2: room for only part of the margins. + if (margins.size() > remaining) { + float scale = float{remaining} / float{margins.size()}; + set_start(container.start() + std::roundf(scale * margins.leading())); + return; + } + + // Case 3: room for both span and margins. Center the whole unit. + remaining -= margins.size(); + set_start(container.start() + remaining / 2 + margins.leading()); +} + +void Span::Align(const Span& container, + LayoutAlignment alignment, + const Inset1D& margins) { + switch (alignment) { + case LayoutAlignment::kStart: + set_start(container.start() + margins.leading()); + break; + case LayoutAlignment::kEnd: + set_start(container.end() - (margins.trailing() + length())); + break; + case LayoutAlignment::kCenter: + Center(container, margins); + break; + case LayoutAlignment::kStretch: + SetSpan(container.start() + margins.leading(), + std::max(0, container.length() - margins.size())); + break; + } +} + +bool Span::operator==(const Span& other) const { + return start_ == other.start_ && length_ == other.length_; +} + +bool Span::operator!=(const Span& other) const { + return !(*this == other); +} + +bool Span::operator<(const Span& other) const { + return std::tie(start_, length_) < std::tie(other.start_, other.length_); +} + +std::string Span::ToString() const { + return base::StringPrintf("%d [%d]", start(), length()); +} + } // namespace views
diff --git a/ui/views/layout/flex_layout_types.h b/ui/views/layout/flex_layout_types.h index f018d6ab..d74f11ad 100644 --- a/ui/views/layout/flex_layout_types.h +++ b/ui/views/layout/flex_layout_types.h
@@ -5,11 +5,13 @@ #ifndef UI_VIEWS_LAYOUT_FLEX_LAYOUT_TYPES_H_ #define UI_VIEWS_LAYOUT_FLEX_LAYOUT_TYPES_H_ +#include <algorithm> #include <memory> #include <string> #include "base/callback.h" #include "base/optional.h" +#include "ui/views/layout/layout_types.h" #include "ui/views/views_export.h" namespace gfx { @@ -20,46 +22,9 @@ class View; -// Whether a layout is oriented horizontally or vertically. -enum class LayoutOrientation { - kHorizontal, - kVertical, -}; - // Describes how elements should be aligned within a layout. enum class LayoutAlignment { kStart, kCenter, kEnd, kStretch }; -// Stores an optional width and height upper bound. Used when calculating the -// preferred size of a layout pursuant to a maximum available size. -class VIEWS_EXPORT SizeBounds { - public: - SizeBounds(); - SizeBounds(const base::Optional<int>& width, - const base::Optional<int>& height); - explicit SizeBounds(const gfx::Size& size); - SizeBounds(const SizeBounds& other); - - const base::Optional<int>& width() const { return width_; } - void set_width(const base::Optional<int>& width) { width_ = width; } - - const base::Optional<int>& height() const { return height_; } - void set_height(const base::Optional<int>& height) { height_ = height; } - - // Enlarges (or shrinks, if negative) each upper bound that is present by the - // specified amounts. - void Enlarge(int width, int height); - - bool operator==(const SizeBounds& other) const; - bool operator!=(const SizeBounds& other) const; - bool operator<(const SizeBounds& other) const; - - std::string ToString() const; - - private: - base::Optional<int> width_; - base::Optional<int> height_; -}; - // Callback used to specify the size of a child view based on its size bounds. // Create your own custom rules, or use the Minimum|MaximumFlexSizeRule // constants below for common behaviors. @@ -159,6 +124,85 @@ int weight_ = 0; }; +// Represents insets in a single dimension. +class Inset1D { + public: + constexpr Inset1D() = default; + constexpr explicit Inset1D(int all) : leading_(all), trailing_(all) {} + constexpr Inset1D(int leading, int trailing) + : leading_(leading), trailing_(trailing) {} + + constexpr int leading() const { return leading_; } + void set_leading(int leading) { leading_ = leading; } + + constexpr int trailing() const { return trailing_; } + void set_trailing(int trailing) { trailing_ = trailing; } + + constexpr int size() const { return leading_ + trailing_; } + + void SetInsets(int leading, int trailing); + void Expand(int delta_leading, int delta_trailing); + + constexpr bool is_empty() const { return leading_ == 0 && trailing_ == 0; } + bool operator==(const Inset1D& other) const; + bool operator!=(const Inset1D& other) const; + bool operator<(const Inset1D& other) const; + + std::string ToString() const; + + private: + int leading_ = 0; + int trailing_ = 0; +}; + +// Represents a line segment in one dimension with a starting point and length. +class Span { + public: + constexpr Span() = default; + constexpr Span(int start, int length) : start_(start), length_(length) {} + + constexpr int start() const { return start_; } + void set_start(int start) { start_ = start; } + + constexpr int length() const { return length_; } + void set_length(int length) { length_ = std::max(0, length); } + + constexpr int end() const { return start_ + length_; } + void set_end(int end) { set_length(end - start_); } + + void SetSpan(int start, int length); + + // Expands the span by |leading| at the front (reducing the value of start() + // if |leading| is positive) and by |trailing| at the end (increasing the + // value of end() if |trailing| is positive). + void Expand(int leading, int trailing); + + // Opposite of Expand(). Shrinks each end of the span by the specified amount. + void Inset(int leading, int trailing); + void Inset(const Inset1D& insets); + + // Centers the span in another span, with optional margins. + // Overflow is handled gracefully. + void Center(const Span& container, const Inset1D& margins = Inset1D()); + + // Aligns the span in another span, with optional margins, using the specified + // alignment. Overflow is handled gracefully. + void Align(const Span& container, + LayoutAlignment alignment, + const Inset1D& margins = Inset1D()); + + constexpr bool is_empty() const { return length_ == 0; } + bool operator==(const Span& other) const; + bool operator!=(const Span& other) const; + bool operator<(const Span& other) const; + + std::string ToString() const; + + private: + int start_ = 0; + int length_ = 0; +}; + } // namespace views #endif // UI_VIEWS_LAYOUT_FLEX_LAYOUT_TYPES_H_
diff --git a/ui/views/layout/flex_layout_types_internal.cc b/ui/views/layout/flex_layout_types_internal.cc index aef1542f..bb104c4 100644 --- a/ui/views/layout/flex_layout_types_internal.cc +++ b/ui/views/layout/flex_layout_types_internal.cc
@@ -27,114 +27,6 @@ } // namespace -// Span ------------------------------------------------------------------------ - -void Span::SetSpan(int start, int length) { - start_ = start; - length_ = std::max(0, length); -} - -void Span::Expand(int leading, int trailing) { - const int end = this->end(); - set_start(start_ - leading); - set_end(end + trailing); -} - -void Span::Inset(int leading, int trailing) { - Expand(-leading, -trailing); -} - -void Span::Inset(const Inset1D& insets) { - Inset(insets.leading(), insets.trailing()); -} - -void Span::Center(const Span& container, const Inset1D& margins) { - int remaining = container.length() - length(); - - // Case 1: no room for any margins. Just center the span in the container, - // with equal overflow on each side. - if (remaining <= 0) { - set_start(std::ceil(remaining * 0.5f)); - return; - } - - // Case 2: room for only part of the margins. - if (margins.size() > remaining) { - float scale = float{remaining} / float{margins.size()}; - set_start(std::roundf(scale * margins.leading())); - return; - } - - // Case 3: room for both span and margins. Center the whole unit. - remaining -= margins.size(); - set_start(remaining / 2 + margins.leading()); -} - -void Span::Align(const Span& container, - LayoutAlignment alignment, - const Inset1D& margins) { - switch (alignment) { - case LayoutAlignment::kStart: - set_start(container.start() + margins.leading()); - break; - case LayoutAlignment::kEnd: - set_start(container.end() - (margins.trailing() + length())); - break; - case LayoutAlignment::kCenter: - Center(container, margins); - break; - case LayoutAlignment::kStretch: - SetSpan(container.start() + margins.leading(), - std::max(0, container.length() - margins.size())); - break; - } -} - -bool Span::operator==(const Span& other) const { - return start_ == other.start_ && length_ == other.length_; -} - -bool Span::operator!=(const Span& other) const { - return !(*this == other); -} - -bool Span::operator<(const Span& other) const { - return std::tie(start_, length_) < std::tie(other.start_, other.length_); -} - -std::string Span::ToString() const { - return base::StringPrintf("%d [%d]", start(), length()); -} - -// Inset1D --------------------------------------------------------------------- - -void Inset1D::SetInsets(int leading, int trailing) { - leading_ = leading; - trailing_ = trailing; -} - -void Inset1D::Expand(int delta_leading, int delta_trailing) { - leading_ += delta_leading; - trailing_ += delta_trailing; -} - -bool Inset1D::operator==(const Inset1D& other) const { - return leading_ == other.leading_ && trailing_ == other.trailing_; -} - -bool Inset1D::operator!=(const Inset1D& other) const { - return !(*this == other); -} - -bool Inset1D::operator<(const Inset1D& other) const { - return std::tie(leading_, trailing_) < - std::tie(other.leading_, other.trailing_); -} - -std::string Inset1D::ToString() const { - return base::StringPrintf("%d, %d", leading(), trailing()); -} - // NormalizedPoint ------------------------------------------------------------- void NormalizedPoint::SetPoint(int main, int cross) {
diff --git a/ui/views/layout/flex_layout_types_internal.h b/ui/views/layout/flex_layout_types_internal.h index 80b0231f..7a44d1f 100644 --- a/ui/views/layout/flex_layout_types_internal.h +++ b/ui/views/layout/flex_layout_types_internal.h
@@ -23,91 +23,6 @@ namespace internal { -// Represents insets in a single dimension. -class Inset1D { - public: - constexpr Inset1D() = default; - constexpr explicit Inset1D(int all) : leading_(all), trailing_(all) {} - constexpr Inset1D(int leading, int trailing) - : leading_(leading), trailing_(trailing) {} - - constexpr int leading() const { return leading_; } - void set_leading(int leading) { leading_ = leading; } - - constexpr int trailing() const { return trailing_; } - void set_trailing(int trailing) { trailing_ = trailing; } - - constexpr int size() const { return leading_ + trailing_; } - - void SetInsets(int leading, int trailing); - void Expand(int delta_leading, int delta_trailing); - - constexpr bool is_empty() const { return leading_ == 0 && trailing_ == 0; } - bool operator==(const Inset1D& other) const; - bool operator!=(const Inset1D& other) const; - bool operator<(const Inset1D& other) const; - - std::string ToString() const; - - private: - int leading_ = 0; - int trailing_ = 0; -}; - -// Represents a line segment in one dimension with a starting point and length. -class Span { - public: - constexpr Span() = default; - constexpr Span(int start, int length) : start_(start), length_(length) {} - - constexpr int start() const { return start_; } - void set_start(int start) { start_ = start; } - - constexpr int length() const { return length_; } - void set_length(int length) { - DCHECK_GE(length, 0); - length_ = length; - } - - constexpr int end() const { return start_ + length_; } - void set_end(int end) { - DCHECK_GE(end, start_); - length_ = end - start_; - } - - void SetSpan(int start, int length); - - // Expands the span by |leading| at the front (reducing the value of start() - // if |leading| is positive) and by |trailing| at the end (increasing the - // value of end() if |trailing| is positive). - void Expand(int leading, int trailing); - - // Opposite of Expand(). Shrinks each end of the span by the specified amount. - void Inset(int leading, int trailing); - void Inset(const Inset1D& insets); - - // Centers the span in another span, with optional margins. - // Overflow is handled gracefully. - void Center(const Span& container, const Inset1D& margins = Inset1D()); - - // Aligns the span in another span, with optional margins, using the specified - // alignment. Overflow is handled gracefully. - void Align(const Span& container, - LayoutAlignment alignment, - const Inset1D& margins = Inset1D()); - - constexpr bool is_empty() const { return length_ == 0; } - bool operator==(const Span& other) const; - bool operator!=(const Span& other) const; - bool operator<(const Span& other) const; - - std::string ToString() const; - - private: - int start_ = 0; - int length_ = 0; -}; - // Represents a point in layout space - that is, a point on the main and cross // axes of the layout (regardless of whether it is vertically or horizontally // oriented.
diff --git a/ui/views/layout/interpolating_layout_manager.cc b/ui/views/layout/interpolating_layout_manager.cc new file mode 100644 index 0000000..65f126e5 --- /dev/null +++ b/ui/views/layout/interpolating_layout_manager.cc
@@ -0,0 +1,165 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/views/layout/interpolating_layout_manager.h" + +#include <memory> +#include <utility> + +#include "ui/views/view.h" + +namespace views { + +namespace { + +using ChildLayout = LayoutManagerBase::ChildLayout; +using ProposedLayout = LayoutManagerBase::ProposedLayout; + +int InterpolateValue(int first, int second) { + return (first + second) / 2; +} + +gfx::Size InterpolateSize(const gfx::Size& first, const gfx::Size& second) { + return gfx::Size(InterpolateValue(first.width(), second.width()), + InterpolateValue(first.height(), second.height())); +} + +gfx::Rect InterpolateRect(const gfx::Rect& first, const gfx::Rect& second) { + return gfx::Rect(InterpolateValue(first.x(), second.x()), + InterpolateValue(first.y(), second.y()), + InterpolateValue(first.width(), second.width()), + InterpolateValue(first.height(), second.height())); +} + +// static +ProposedLayout Interpolate(const ProposedLayout& left, + const ProposedLayout& right) { + ProposedLayout layout; + const size_t num_children = left.child_layouts.size(); + DCHECK_EQ(num_children, right.child_layouts.size()); + layout.host_size = InterpolateSize(left.host_size, right.host_size); + for (size_t i = 0; i < num_children; ++i) { + const ChildLayout& left_child = left.child_layouts[i]; + const ChildLayout& right_child = right.child_layouts[i]; + DCHECK_EQ(left_child.child_view, right_child.child_view); + layout.child_layouts.emplace_back( + ChildLayout{left_child.child_view, + InterpolateRect(left_child.bounds, right_child.bounds), + left_child.visible && right_child.visible}); + } + return layout; +} + +} // namespace + +InterpolatingLayoutManager::InterpolatingLayoutManager() {} +InterpolatingLayoutManager::~InterpolatingLayoutManager() = default; + +InterpolatingLayoutManager& InterpolatingLayoutManager::SetOrientation( + LayoutOrientation orientation) { + if (orientation_ != orientation) { + orientation_ = orientation; + InvalidateLayout(); + } + return *this; +} + +void InterpolatingLayoutManager::AddLayoutInternal( + std::unique_ptr<LayoutManagerBase> engine, + const Span& interpolation_range) { + DCHECK(engine); + + SyncStateTo(engine.get()); + auto result = embedded_layouts_.emplace( + std::make_pair(interpolation_range, std::move(engine))); + DCHECK(result.second) << "Cannot replace existing layout manager for " + << interpolation_range.ToString(); + +#if DCHECK_IS_ON() + // Sanity checking to ensure interpolation ranges do not overlap (we can only + // interpolate between two layouts currently). + auto next = result.first; + ++next; + if (next != embedded_layouts_.end()) + DCHECK_GE(next->first.start(), interpolation_range.end()); + if (result.first != embedded_layouts_.begin()) { + auto prev = result.first; + --prev; + DCHECK_LE(prev->first.end(), interpolation_range.start()); + } +#endif // DCHECK_IS_ON() +} + +LayoutManagerBase::ProposedLayout InterpolatingLayoutManager::GetProposedLayout( + const SizeBounds& size_bounds) const { + // Make sure a default engine is set. + DCHECK(embedded_layouts_.find({0, 0}) != embedded_layouts_.end()); + + ProposedLayout layout; + + const base::Optional<int> dimension = + orientation_ == LayoutOrientation::kHorizontal ? size_bounds.width() + : size_bounds.height(); + + // Find the larger layout that overlaps the target size. + auto right_match = dimension ? embedded_layouts_.upper_bound({*dimension, 0}) + : embedded_layouts_.end(); + DCHECK(right_match != embedded_layouts_.begin()); + --right_match; + ProposedLayout right = right_match->second->GetProposedLayout(size_bounds); + + // If the target size falls in an interpolation range, get the other layout. + if (dimension && right_match->first.end() > *dimension) { + DCHECK(right_match != embedded_layouts_.begin()); + auto left_match = --(right_match); + ProposedLayout left = left_match->second->GetProposedLayout(size_bounds); + layout = Interpolate(left, right); + } else { + layout = std::move(right); + } + + return layout; +} + +void InterpolatingLayoutManager::InvalidateLayout() { + LayoutManagerBase::InvalidateLayout(); + for (auto& embedded : embedded_layouts_) + embedded.second->InvalidateLayout(); +} + +void InterpolatingLayoutManager::SetChildViewIgnoredByLayout(View* child_view, + bool ignored) { + LayoutManagerBase::SetChildViewIgnoredByLayout(child_view, ignored); + for (auto& embedded : embedded_layouts_) + embedded.second->SetChildViewIgnoredByLayout(child_view, ignored); +} + +void InterpolatingLayoutManager::Installed(View* host_view) { + LayoutManagerBase::Installed(host_view); + for (auto& embedded : embedded_layouts_) + embedded.second->Installed(host_view); +} + +void InterpolatingLayoutManager::ViewAdded(View* host_view, View* child_view) { + LayoutManagerBase::ViewAdded(host_view, child_view); + for (auto& embedded : embedded_layouts_) + embedded.second->ViewAdded(host_view, child_view); +} + +void InterpolatingLayoutManager::ViewRemoved(View* host_view, + View* child_view) { + LayoutManagerBase::ViewRemoved(host_view, child_view); + for (auto& embedded : embedded_layouts_) + embedded.second->ViewRemoved(host_view, child_view); +} + +void InterpolatingLayoutManager::ViewVisibilitySet(View* host, + View* view, + bool visible) { + LayoutManagerBase::ViewVisibilitySet(host, view, visible); + for (auto& embedded : embedded_layouts_) + embedded.second->ViewVisibilitySet(host, view, visible); +} + +} // namespace views
diff --git a/ui/views/layout/interpolating_layout_manager.h b/ui/views/layout/interpolating_layout_manager.h new file mode 100644 index 0000000..fbecde0 --- /dev/null +++ b/ui/views/layout/interpolating_layout_manager.h
@@ -0,0 +1,109 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_VIEWS_LAYOUT_INTERPOLATING_LAYOUT_MANAGER_H_ +#define UI_VIEWS_LAYOUT_INTERPOLATING_LAYOUT_MANAGER_H_ + +#include <map> +#include <memory> +#include <utility> + +#include "ui/views/layout/flex_layout_types.h" +#include "ui/views/layout/layout_manager_base.h" + +namespace views { + +// Layout which interpolates between multiple embedded LayoutManagerBase +// layouts. +// +// An InterpolatingLayoutManager has a default layout, which applies at the +// smallest layout size along the layout's major axis (defined by |orientation|) +// and additional layouts, which phase in at some larger size. If only the +// default layout is set, the layout is functionally equivalent to the default +// layout. +// +// An example: +// +// InterpolatingLayoutManager* e = +// new InterpolatingLayoutManager(LayoutOrientation::kHorizontal); +// e->SetDefaultLayout(std::make_unique<CompactLayout>()); +// e->AddLayout(std::make_unique<NormalLayout>(), 50, 50); +// e->AddLayout(std::make_unique<SpaciousLayout>(), 100, 150); +// +// Now as the view expands, the different layouts are used: +// +// 0 50 100 150 +// | Compact | Normal | Norm <~> Spa | Spacious -> +// +// In the range from 100 to 150 (exclusive), an interpolation of the Normal and +// Spacious layouts is used. When interpolation happens in this way, the +// visibility of views is the conjunction of the visibilities in each layout, so +// if either layout hides a view then the interpolated layout also hides it. +// Since this can produce some unwanted visual results, we recommend making sure +// that over the interpolation range, visibility matches up between the layouts +// on either side. +// +// Note that behavior when interpolation ranges overlap is undefined, but will +// be guaranteed to at least be the result of mixing two adjacent layouts that +// fall over the range in a way that is not completely irrational. +class VIEWS_EXPORT InterpolatingLayoutManager : public LayoutManagerBase { + public: + InterpolatingLayoutManager(); + ~InterpolatingLayoutManager() override; + + InterpolatingLayoutManager& SetOrientation(LayoutOrientation orientation); + LayoutOrientation orientation() const { return orientation_; } + + // Sets the default layout, which takes effect at zero size on the layout's + // main axis, and continues to be active until the next layout phases in. + // + // This object retains ownership of the layout engine, but the method returns + // a typed raw pointer to the added layout engine. + template <class T> + T* SetDefaultLayout(std::unique_ptr<T> layout_manager) { + T* const temp = layout_manager.get(); + AddLayoutInternal(std::move(layout_manager), Span()); + return temp; + } + + // Adds an additional layout which starts and finished phasing in at + // |start_interpolation| and |end_interpolation|, respectively. Currently, + // having more than one layout's interpolation range overlapping results in + // undefined behavior. + // + // This object retains ownership of the layout engine, but the method returns + // a typed raw pointer to the added layout engine. + template <class T> + T* AddLayout(std::unique_ptr<T> layout_manager, + const Span& interpolation_range) { + T* const temp = layout_manager.get(); + AddLayoutInternal(std::move(layout_manager), interpolation_range); + return temp; + } + + // CachingLayout: + void InvalidateLayout() override; + void SetChildViewIgnoredByLayout(View* child_view, bool ignored) override; + void Installed(View* host_view) override; + void ViewAdded(View* host_view, View* child_view) override; + void ViewRemoved(View* host_view, View* child_view) override; + void ViewVisibilitySet(View* host, View* view, bool visible) override; + ProposedLayout GetProposedLayout( + const SizeBounds& size_bounds) const override; + + private: + void AddLayoutInternal(std::unique_ptr<LayoutManagerBase> layout, + const Span& interpolation_range); + + LayoutOrientation orientation_ = LayoutOrientation::kHorizontal; + + // Maps from interpolation range to embedded layout. + std::map<Span, std::unique_ptr<LayoutManagerBase>> embedded_layouts_; + + DISALLOW_COPY_AND_ASSIGN(InterpolatingLayoutManager); +}; + +} // namespace views + +#endif // UI_VIEWS_LAYOUT_INTERPOLATING_LAYOUT_MANAGER_H_
diff --git a/ui/views/layout/interpolating_layout_manager_unittest.cc b/ui/views/layout/interpolating_layout_manager_unittest.cc new file mode 100644 index 0000000..169544efb --- /dev/null +++ b/ui/views/layout/interpolating_layout_manager_unittest.cc
@@ -0,0 +1,186 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/views/layout/interpolating_layout_manager.h" + +#include <memory> + +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/views/test/test_views.h" +#include "ui/views/view.h" + +namespace views { + +namespace { + +class TestLayout : public LayoutManagerBase { + public: + int num_layouts_generated() const { return num_layouts_generated_; } + + ProposedLayout GetProposedLayout( + const SizeBounds& size_bounds) const override { + ++num_layouts_generated_; + ProposedLayout layout; + layout.host_size = gfx::Size(10, 11); + for (auto it = host_view()->children().begin(); + it != host_view()->children().end(); ++it) { + if (!IsChildIncludedInLayout(*it)) + continue; + ChildLayout child_layout; + child_layout.child_view = *it; + child_layout.visible = true; + child_layout.bounds = gfx::Rect(1, 1, 1, 1); + layout.child_layouts.push_back(child_layout); + } + return layout; + } + + private: + mutable int num_layouts_generated_ = 0; +}; + +} // anonymous namespace + +class InterpolatingLayoutManagerTest : public testing::Test { + public: + void SetUp() override { + host_view_ = std::make_unique<View>(); + layout_manager_ = host_view_->SetLayoutManager( + std::make_unique<InterpolatingLayoutManager>()); + } + + InterpolatingLayoutManager* layout_manager() { return layout_manager_; } + View* host_view() { return host_view_.get(); } + + private: + InterpolatingLayoutManager* layout_manager_ = nullptr; + std::unique_ptr<View> host_view_; +}; + +TEST_F(InterpolatingLayoutManagerTest, SetDefaultLayout) { + TestLayout* const default_layout = + layout_manager()->SetDefaultLayout(std::make_unique<TestLayout>()); + EXPECT_EQ(0, default_layout->num_layouts_generated()); + layout_manager()->GetProposedLayout(SizeBounds()); + EXPECT_EQ(1, default_layout->num_layouts_generated()); +} + +TEST_F(InterpolatingLayoutManagerTest, AddLayout_CheckZeroAndUnbounded) { + TestLayout* const default_layout = + layout_manager()->SetDefaultLayout(std::make_unique<TestLayout>()); + TestLayout* const other_layout = + layout_manager()->AddLayout(std::make_unique<TestLayout>(), {5, 0}); + EXPECT_EQ(0, default_layout->num_layouts_generated()); + EXPECT_EQ(0, other_layout->num_layouts_generated()); + layout_manager()->GetProposedLayout(SizeBounds()); + EXPECT_EQ(0, default_layout->num_layouts_generated()); + EXPECT_EQ(1, other_layout->num_layouts_generated()); + layout_manager()->GetProposedLayout(SizeBounds(0, 0)); + EXPECT_EQ(1, default_layout->num_layouts_generated()); + EXPECT_EQ(1, other_layout->num_layouts_generated()); +} + +TEST_F(InterpolatingLayoutManagerTest, GetProposedLayout_HardBoundary) { + TestLayout* const default_layout = + layout_manager()->SetDefaultLayout(std::make_unique<TestLayout>()); + TestLayout* const other_layout = + layout_manager()->AddLayout(std::make_unique<TestLayout>(), {5, 0}); + EXPECT_EQ(0, default_layout->num_layouts_generated()); + EXPECT_EQ(0, other_layout->num_layouts_generated()); + layout_manager()->GetProposedLayout(SizeBounds(5, 2)); + EXPECT_EQ(0, default_layout->num_layouts_generated()); + EXPECT_EQ(1, other_layout->num_layouts_generated()); + layout_manager()->GetProposedLayout(SizeBounds(4, 2)); + EXPECT_EQ(1, default_layout->num_layouts_generated()); + EXPECT_EQ(1, other_layout->num_layouts_generated()); +} + +TEST_F(InterpolatingLayoutManagerTest, GetProposedLayout_SoftBoudnary) { + TestLayout* const default_layout = + layout_manager()->SetDefaultLayout(std::make_unique<TestLayout>()); + TestLayout* const other_layout = + layout_manager()->AddLayout(std::make_unique<TestLayout>(), {4, 2}); + EXPECT_EQ(0, default_layout->num_layouts_generated()); + EXPECT_EQ(0, other_layout->num_layouts_generated()); + layout_manager()->GetProposedLayout(SizeBounds(5, 2)); + EXPECT_EQ(1, default_layout->num_layouts_generated()); + EXPECT_EQ(1, other_layout->num_layouts_generated()); + layout_manager()->GetProposedLayout(SizeBounds(4, 2)); + EXPECT_EQ(2, default_layout->num_layouts_generated()); + EXPECT_EQ(1, other_layout->num_layouts_generated()); + layout_manager()->GetProposedLayout(SizeBounds(6, 6)); + EXPECT_EQ(2, default_layout->num_layouts_generated()); + EXPECT_EQ(2, other_layout->num_layouts_generated()); +} + +TEST_F(InterpolatingLayoutManagerTest, GetProposedLayout_MultipleLayouts) { + TestLayout* const default_layout = + layout_manager()->SetDefaultLayout(std::make_unique<TestLayout>()); + TestLayout* const other_layout1 = + layout_manager()->AddLayout(std::make_unique<TestLayout>(), {4, 2}); + TestLayout* const other_layout2 = + layout_manager()->AddLayout(std::make_unique<TestLayout>(), {6, 2}); + EXPECT_EQ(0, default_layout->num_layouts_generated()); + EXPECT_EQ(0, other_layout1->num_layouts_generated()); + EXPECT_EQ(0, other_layout2->num_layouts_generated()); + layout_manager()->GetProposedLayout(SizeBounds(5, 2)); + EXPECT_EQ(1, default_layout->num_layouts_generated()); + EXPECT_EQ(1, other_layout1->num_layouts_generated()); + EXPECT_EQ(0, other_layout2->num_layouts_generated()); + layout_manager()->GetProposedLayout(SizeBounds(6, 3)); + EXPECT_EQ(1, default_layout->num_layouts_generated()); + EXPECT_EQ(2, other_layout1->num_layouts_generated()); + EXPECT_EQ(0, other_layout2->num_layouts_generated()); + layout_manager()->GetProposedLayout(SizeBounds(7, 6)); + EXPECT_EQ(1, default_layout->num_layouts_generated()); + EXPECT_EQ(3, other_layout1->num_layouts_generated()); + EXPECT_EQ(1, other_layout2->num_layouts_generated()); + layout_manager()->GetProposedLayout(SizeBounds(20, 3)); + EXPECT_EQ(1, default_layout->num_layouts_generated()); + EXPECT_EQ(3, other_layout1->num_layouts_generated()); + EXPECT_EQ(2, other_layout2->num_layouts_generated()); +} + +TEST_F(InterpolatingLayoutManagerTest, InvalidateLayout) { + static const gfx::Size kLayoutSize(5, 5); + + TestLayout* const default_layout = + layout_manager()->SetDefaultLayout(std::make_unique<TestLayout>()); + TestLayout* const other_layout = + layout_manager()->AddLayout(std::make_unique<TestLayout>(), {4, 2}); + host_view()->SetSize(kLayoutSize); + EXPECT_EQ(1, default_layout->num_layouts_generated()); + EXPECT_EQ(1, other_layout->num_layouts_generated()); + host_view()->Layout(); + EXPECT_EQ(1, default_layout->num_layouts_generated()); + EXPECT_EQ(1, other_layout->num_layouts_generated()); + layout_manager()->InvalidateLayout(); + host_view()->Layout(); + EXPECT_EQ(2, default_layout->num_layouts_generated()); + EXPECT_EQ(2, other_layout->num_layouts_generated()); + host_view()->Layout(); + EXPECT_EQ(2, default_layout->num_layouts_generated()); + EXPECT_EQ(2, other_layout->num_layouts_generated()); +} + +TEST_F(InterpolatingLayoutManagerTest, SetOrientation) { + TestLayout* const default_layout = + layout_manager()->SetDefaultLayout(std::make_unique<TestLayout>()); + TestLayout* const other_layout = + layout_manager()->AddLayout(std::make_unique<TestLayout>(), {4, 2}); + layout_manager()->SetOrientation(LayoutOrientation::kVertical); + EXPECT_EQ(0, default_layout->num_layouts_generated()); + EXPECT_EQ(0, other_layout->num_layouts_generated()); + layout_manager()->GetProposedLayout(SizeBounds(2, 6)); + EXPECT_EQ(0, default_layout->num_layouts_generated()); + EXPECT_EQ(1, other_layout->num_layouts_generated()); + layout_manager()->GetProposedLayout(SizeBounds(3, 5)); + EXPECT_EQ(1, default_layout->num_layouts_generated()); + EXPECT_EQ(2, other_layout->num_layouts_generated()); + layout_manager()->GetProposedLayout(SizeBounds(10, 3)); + EXPECT_EQ(2, default_layout->num_layouts_generated()); + EXPECT_EQ(2, other_layout->num_layouts_generated()); +} + +} // namespace views
diff --git a/ui/views/layout/layout_manager_base.cc b/ui/views/layout/layout_manager_base.cc new file mode 100644 index 0000000..49e95ed0e --- /dev/null +++ b/ui/views/layout/layout_manager_base.cc
@@ -0,0 +1,166 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/views/layout/layout_manager_base.h" + +#include <utility> + +#include "base/logging.h" +#include "ui/views/view.h" + +namespace views { + +LayoutManagerBase::ProposedLayout::ProposedLayout() = default; +LayoutManagerBase::ProposedLayout::ProposedLayout(const ProposedLayout& other) = + default; +LayoutManagerBase::ProposedLayout::ProposedLayout(ProposedLayout&& other) = + default; +LayoutManagerBase::ProposedLayout::~ProposedLayout() = default; +LayoutManagerBase::ProposedLayout& LayoutManagerBase::ProposedLayout::operator=( + const ProposedLayout& other) = default; +LayoutManagerBase::ProposedLayout& LayoutManagerBase::ProposedLayout::operator=( + ProposedLayout&& other) = default; + +LayoutManagerBase::~LayoutManagerBase() = default; + +gfx::Size LayoutManagerBase::GetPreferredSize(const View* host) const { + DCHECK_EQ(host_view_, host); + if (!preferred_size_) + preferred_size_ = GetProposedLayout(SizeBounds()).host_size; + return *preferred_size_; +} + +gfx::Size LayoutManagerBase::GetMinimumSize(const View* host) const { + DCHECK_EQ(host_view_, host); + if (!minimum_size_) + minimum_size_ = GetProposedLayout(SizeBounds(0, 0)).host_size; + return *minimum_size_; +} + +int LayoutManagerBase::GetPreferredHeightForWidth(const View* host, + int width) const { + if (!last_height_for_width_ || last_height_for_width_->width() != width) { + const int height = + GetProposedLayout(SizeBounds(width, base::nullopt)).host_size.height(); + last_height_for_width_ = gfx::Size(width, height); + } + + return last_height_for_width_->height(); +} + +void LayoutManagerBase::Layout(View* host) { + DCHECK_EQ(host_view_, host); + const gfx::Size size = host->size(); + if (!last_requested_size_ || *last_requested_size_ != size) { + last_requested_size_ = size; + last_layout_ = GetProposedLayout(SizeBounds(size)); + } + ApplyLayout(last_layout_); +} + +void LayoutManagerBase::InvalidateLayout() { + minimum_size_.reset(); + preferred_size_.reset(); + last_height_for_width_.reset(); + last_requested_size_.reset(); +} + +void LayoutManagerBase::SetChildViewIgnoredByLayout(View* child_view, + bool ignored) { + auto it = child_infos_.find(child_view); + DCHECK(it != child_infos_.end()); + if (it->second.ignored == ignored) + return; + + it->second.ignored = ignored; + InvalidateLayout(); +} + +bool LayoutManagerBase::IsChildViewIgnoredByLayout( + const View* child_view) const { + auto it = child_infos_.find(child_view); + DCHECK(it != child_infos_.end()); + return it->second.ignored; +} + +void LayoutManagerBase::Installed(View* host_view) { + DCHECK(host_view); + DCHECK(!host_view_); + DCHECK(child_infos_.empty()); + + host_view_ = host_view; + for (auto it = host_view->children().begin(); + it != host_view->children().end(); ++it) { + child_infos_.emplace(*it, ChildInfo{(*it)->GetVisible(), false}); + } +} + +void LayoutManagerBase::ViewAdded(View* host, View* view) { + DCHECK_EQ(host_view_, host); + DCHECK(!base::Contains(child_infos_, view)); + ChildInfo to_add{view->GetVisible(), false}; + child_infos_.emplace(view, to_add); + if (to_add.can_be_visible) + InvalidateLayout(); +} + +void LayoutManagerBase::ViewRemoved(View* host, View* view) { + DCHECK_EQ(host_view_, host); + auto it = child_infos_.find(view); + DCHECK(it != child_infos_.end()); + const bool removed_visible = it->second.can_be_visible && !it->second.ignored; + child_infos_.erase(it); + if (removed_visible) + InvalidateLayout(); +} + +void LayoutManagerBase::ViewVisibilitySet(View* host, + View* view, + bool visible) { + DCHECK_EQ(host_view_, host); + auto it = child_infos_.find(view); + DCHECK(it != child_infos_.end()); + if (it->second.can_be_visible == visible) + return; + + it->second.can_be_visible = visible; + if (!it->second.ignored) + InvalidateLayout(); +} + +LayoutManagerBase::LayoutManagerBase() = default; + +bool LayoutManagerBase::IsChildIncludedInLayout(const View* child) const { + const auto it = child_infos_.find(child); + DCHECK(it != child_infos_.end()); + return !it->second.ignored && it->second.can_be_visible; +} + +void LayoutManagerBase::ApplyLayout(const ProposedLayout& layout) { + for (auto& child_layout : layout.child_layouts) { + DCHECK_EQ(host_view_, child_layout.child_view->parent()); + + // Since we have a non-const reference to the parent here, we can safely use + // a non-const reference to the child. + View* const child_view = child_layout.child_view; + if (child_view->GetVisible() != child_layout.visible) + SetViewVisibility(child_view, child_layout.visible); + if (child_layout.visible) + child_view->SetBoundsRect(child_layout.bounds); + } +} + +void LayoutManagerBase::SyncStateTo(LayoutManagerBase* other) const { + if (host_view_) { + other->Installed(host_view_); + for (View* child_view : host_view_->children()) { + const ChildInfo& child_info = child_infos_.find(child_view)->second; + other->SetChildViewIgnoredByLayout(child_view, child_info.ignored); + other->ViewVisibilitySet(host_view_, child_view, + child_info.can_be_visible); + } + } +} + +} // namespace views
diff --git a/ui/views/layout/layout_manager_base.h b/ui/views/layout/layout_manager_base.h new file mode 100644 index 0000000..48421d1 --- /dev/null +++ b/ui/views/layout/layout_manager_base.h
@@ -0,0 +1,122 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_VIEWS_LAYOUT_LAYOUT_MANAGER_BASE_H_ +#define UI_VIEWS_LAYOUT_LAYOUT_MANAGER_BASE_H_ + +#include <map> +#include <memory> +#include <set> +#include <utility> +#include <vector> + +#include "base/optional.h" +#include "ui/gfx/geometry/insets.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/size.h" +#include "ui/views/layout/layout_manager.h" +#include "ui/views/layout/layout_types.h" +#include "ui/views/views_export.h" + +namespace views { + +class View; + +// Base class for layout managers that can do layout calculation separately +// from layout application. Derived classes must implement GetProposedLayout(). +// Used in interpolating and animating layouts. +class VIEWS_EXPORT LayoutManagerBase : public LayoutManager { + public: + // Represents layout information for a child view within a host being laid + // out. + struct VIEWS_EXPORT ChildLayout { + View* child_view = nullptr; + gfx::Rect bounds; + bool visible = false; + }; + + // Contains a full layout specification for the children of the host view. + struct VIEWS_EXPORT ProposedLayout { + ProposedLayout(); + ~ProposedLayout(); + ProposedLayout(const ProposedLayout& other); + ProposedLayout(ProposedLayout&& other); + ProposedLayout& operator=(const ProposedLayout& other); + ProposedLayout& operator=(ProposedLayout&& other); + + // The size of the host view given the size bounds for this layout. If both + // dimensions of the size bounds are specified, this will be the same size. + gfx::Size host_size; + + // Contains an entry for each child view included in the layout. + std::vector<ChildLayout> child_layouts; + }; + + ~LayoutManagerBase() override; + + View* host_view() { return host_view_; } + const View* host_view() const { return host_view_; } + + // Creates a proposed layout for the host view, including bounds and + // visibility for all children currently included in the layout, or returns a + // cached layout that was previously created. + virtual ProposedLayout GetProposedLayout( + const SizeBounds& size_bounds) const = 0; + + // Excludes a specific view from the layout when doing layout calculations. + // Useful when a child view is meant to be displayed but has its size and + // position managed elsewhere in code. By default, all child views are + // included in the layout unless they are hidden. + virtual void SetChildViewIgnoredByLayout(View* child_view, bool ignored); + virtual bool IsChildViewIgnoredByLayout(const View* child_view) const; + + // LayoutManager: + gfx::Size GetPreferredSize(const View* host) const final; + gfx::Size GetMinimumSize(const View* host) const final; + int GetPreferredHeightForWidth(const View* host, int width) const final; + void Layout(View* host) final; + void InvalidateLayout() override; + void Installed(View* host) override; + void ViewAdded(View* host, View* view) override; + void ViewRemoved(View* host, View* view) override; + void ViewVisibilitySet(View* host, View* view, bool visible) override; + + protected: + LayoutManagerBase(); + + bool IsChildIncludedInLayout(const View* child) const; + + // Applies |layout| to the children of the host view. + void ApplyLayout(const ProposedLayout& layout); + + // Can be used by derived classes to ensure that state is correctly + // transferred to child LayoutManagerBase instances in a composite layout + // (interpolating or animating layouts, etc.) + void SyncStateTo(LayoutManagerBase* other) const; + + private: + // Holds bookkeeping data used to determine inclusion of children in the + // layout. + struct ChildInfo { + bool can_be_visible = true; + bool ignored = false; + }; + + View* host_view_ = nullptr; + std::map<const View*, ChildInfo> child_infos_; + + // Do some really simple caching because layout generation can cost as much + // as 1ms or more for complex views. + mutable base::Optional<gfx::Size> minimum_size_; + mutable base::Optional<gfx::Size> preferred_size_; + mutable base::Optional<gfx::Size> last_height_for_width_; + mutable base::Optional<gfx::Size> last_requested_size_; + mutable ProposedLayout last_layout_; + + DISALLOW_COPY_AND_ASSIGN(LayoutManagerBase); +}; + +} // namespace views + +#endif // UI_VIEWS_LAYOUT_LAYOUT_MANAGER_BASE_H_
diff --git a/ui/views/layout/layout_manager_base_unittest.cc b/ui/views/layout/layout_manager_base_unittest.cc new file mode 100644 index 0000000..4d373e7 --- /dev/null +++ b/ui/views/layout/layout_manager_base_unittest.cc
@@ -0,0 +1,479 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/views/layout/layout_manager_base.h" + +#include <algorithm> + +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/views/test/test_layout_manager.h" +#include "ui/views/test/test_views.h" +#include "ui/views/view.h" + +namespace views { + +// Test LayoutManagerBase-specific functionality: + +namespace { + +constexpr gfx::Size kMinimumSize(40, 50); +constexpr gfx::Size kPreferredSize(100, 90); + +// Dummy class that minimally implements LayoutManagerBase for basic +// functionality testing. +class TestLayoutManagerBase : public LayoutManagerBase { + public: + std::vector<const View*> GetIncludedChildViews() const { + std::vector<const View*> included; + std::copy_if(host_view()->children().begin(), host_view()->children().end(), + std::back_inserter(included), [=](const View* child) { + return IsChildIncludedInLayout(child); + }); + return included; + } + + // LayoutManagerBase: + ProposedLayout GetProposedLayout( + const SizeBounds& size_bounds) const override { + ProposedLayout layout; + layout.host_size.set_width( + std::max(kMinimumSize.width(), + size_bounds.width().value_or(kPreferredSize.width()))); + layout.host_size.set_height( + std::max(kMinimumSize.height(), + size_bounds.height().value_or(kPreferredSize.height()))); + return layout; + } +}; + +void ExpectSameViews(const std::vector<const View*>& expected, + const std::vector<const View*>& actual) { + EXPECT_EQ(expected.size(), actual.size()); + for (size_t i = 0; i < expected.size(); ++i) { + EXPECT_EQ(expected[i], actual[i]); + } +} + +} // namespace + +TEST(LayoutManagerBaseTest, GetMinimumSize) { + TestLayoutManagerBase layout; + EXPECT_EQ(kMinimumSize, layout.GetMinimumSize(nullptr)); +} + +TEST(LayoutManagerBaseTest, GetPreferredSize) { + TestLayoutManagerBase layout; + EXPECT_EQ(kPreferredSize, layout.GetPreferredSize(nullptr)); +} + +TEST(LayoutManagerBaseTest, GetPreferredHeightForWidth) { + constexpr int kWidth = 45; + TestLayoutManagerBase layout; + EXPECT_EQ(kPreferredSize.height(), + layout.GetPreferredHeightForWidth(nullptr, kWidth)); +} + +TEST(LayoutManagerBaseTest, Installed) { + TestLayoutManagerBase layout; + EXPECT_EQ(nullptr, layout.host_view()); + + View view; + layout.Installed(&view); + EXPECT_EQ(&view, layout.host_view()); +} + +TEST(LayoutManagerBaseTest, SetChildIncludedInLayout) { + View view; + View* const child1 = view.AddChildView(std::make_unique<View>()); + View* const child2 = view.AddChildView(std::make_unique<View>()); + View* const child3 = view.AddChildView(std::make_unique<View>()); + + TestLayoutManagerBase layout; + layout.Installed(&view); + + // All views should be present. + ExpectSameViews({child1, child2, child3}, layout.GetIncludedChildViews()); + + // Remove one. + layout.SetChildViewIgnoredByLayout(child2, true); + ExpectSameViews({child1, child3}, layout.GetIncludedChildViews()); + + // Remove another. + layout.SetChildViewIgnoredByLayout(child1, true); + ExpectSameViews({child3}, layout.GetIncludedChildViews()); + + // Removing it again should have no effect. + layout.SetChildViewIgnoredByLayout(child1, true); + ExpectSameViews({child3}, layout.GetIncludedChildViews()); + + // Add one back. + layout.SetChildViewIgnoredByLayout(child1, false); + ExpectSameViews({child1, child3}, layout.GetIncludedChildViews()); + + // Adding it back again should have no effect. + layout.SetChildViewIgnoredByLayout(child1, false); + ExpectSameViews({child1, child3}, layout.GetIncludedChildViews()); + + // Add the other view back. + layout.SetChildViewIgnoredByLayout(child2, false); + ExpectSameViews({child1, child2, child3}, layout.GetIncludedChildViews()); +} + +// Test LayoutManager functionality of LayoutManagerBase: + +namespace { + +constexpr int kChildViewPadding = 5; +constexpr gfx::Size kSquarishSize(10, 11); +constexpr gfx::Size kLongSize(20, 8); +constexpr gfx::Size kTallSize(4, 22); +constexpr gfx::Size kLargeSize(30, 28); + +// This layout layout lays out included child views in the upper-left of the +// host view with kChildViewPadding around them. Views that will not fit are +// made invisible. Child views are expected to overlap as they all have the +// same top-left corner. +class MockLayoutManagerBase : public LayoutManagerBase { + public: + int num_invalidations() const { return num_invalidations_; } + int num_layouts_generated() const { return num_layouts_generated_; } + + // LayoutManagerBase: + ProposedLayout GetProposedLayout( + const SizeBounds& size_bounds) const override { + ProposedLayout layout; + layout.host_size = {kChildViewPadding, kChildViewPadding}; + for (auto it = host_view()->children().begin(); + it != host_view()->children().end(); ++it) { + if (!IsChildIncludedInLayout(*it)) + continue; + const gfx::Size preferred_size = (*it)->GetPreferredSize(); + bool visible = false; + gfx::Rect bounds; + const int required_width = preferred_size.width() + 2 * kChildViewPadding; + const int required_height = + preferred_size.height() + 2 * kChildViewPadding; + if ((!size_bounds.width() || required_width <= *size_bounds.width()) && + (!size_bounds.height() || required_height <= *size_bounds.height())) { + visible = true; + bounds = gfx::Rect(kChildViewPadding, kChildViewPadding, + preferred_size.width(), preferred_size.height()); + layout.host_size.set_width(std::max( + layout.host_size.width(), bounds.right() + kChildViewPadding)); + layout.host_size.set_height(std::max( + layout.host_size.height(), bounds.bottom() + kChildViewPadding)); + } + layout.child_layouts.push_back({*it, bounds, visible}); + } + ++num_layouts_generated_; + return layout; + } + + void InvalidateLayout() override { + LayoutManagerBase::InvalidateLayout(); + ++num_invalidations_; + } + + using LayoutManagerBase::ApplyLayout; + + private: + mutable int num_layouts_generated_ = 0; + mutable int num_invalidations_ = 0; +}; + +// Base for tests that evaluate the LayoutManager functionality of +// LayoutManagerBase (rather than the LayoutManagerBase-specific behavior). +class LayoutManagerBaseManagerTest : public testing::Test { + public: + void SetUp() override { + host_view_ = std::make_unique<View>(); + layout_manager_ = + host_view_->SetLayoutManager(std::make_unique<MockLayoutManagerBase>()); + } + + View* AddChildView(gfx::Size preferred_size) { + auto child = std::make_unique<StaticSizedView>(preferred_size); + return host_view_->AddChildView(std::move(child)); + } + + View* host_view() { return host_view_.get(); } + MockLayoutManagerBase* layout_manager() { return layout_manager_; } + View* child(int index) { return host_view_->children().at(index); } + + private: + std::unique_ptr<View> host_view_; + MockLayoutManagerBase* layout_manager_; +}; + +} // namespace + +TEST_F(LayoutManagerBaseManagerTest, ApplyLayout) { + AddChildView(gfx::Size()); + AddChildView(gfx::Size()); + AddChildView(gfx::Size()); + + // We don't want to set the size of the host view because it will trigger a + // superfluous layout, so we'll just keep the old size and make sure it + // doesn't change. + const gfx::Size old_size = host_view()->size(); + + LayoutManagerBase::ProposedLayout layout; + // This should be ignored. + layout.host_size = {123, 456}; + + // Set the child visibility and bounds. + constexpr gfx::Rect kChild1Bounds(3, 4, 10, 15); + constexpr gfx::Rect kChild3Bounds(20, 21, 12, 14); + layout.child_layouts.push_back( + LayoutManagerBase::ChildLayout{child(0), kChild1Bounds, true}); + layout.child_layouts.push_back( + LayoutManagerBase::ChildLayout{child(1), gfx::Rect(), false}); + layout.child_layouts.push_back( + LayoutManagerBase::ChildLayout{child(2), kChild3Bounds, true}); + + layout_manager()->ApplyLayout(layout); + + EXPECT_TRUE(child(0)->GetVisible()); + EXPECT_EQ(kChild1Bounds, child(0)->bounds()); + EXPECT_FALSE(child(1)->GetVisible()); + EXPECT_TRUE(child(2)->GetVisible()); + EXPECT_EQ(kChild3Bounds, child(2)->bounds()); + EXPECT_EQ(old_size, host_view()->size()); +} + +TEST_F(LayoutManagerBaseManagerTest, ApplyLayout_SkipsOmittedViews) { + AddChildView(gfx::Size()); + AddChildView(gfx::Size()); + AddChildView(gfx::Size()); + + LayoutManagerBase::ProposedLayout layout; + // Set the child visibility and bounds. + constexpr gfx::Rect kChild1Bounds(3, 4, 10, 15); + constexpr gfx::Rect kChild2Bounds(1, 2, 3, 4); + layout.child_layouts.push_back( + LayoutManagerBase::ChildLayout{child(0), kChild1Bounds, true}); + layout.child_layouts.push_back( + LayoutManagerBase::ChildLayout{child(2), gfx::Rect(), false}); + + // We'll set the second child separately. + child(1)->SetVisible(true); + child(1)->SetBoundsRect(kChild2Bounds); + + layout_manager()->ApplyLayout(layout); + + EXPECT_TRUE(child(0)->GetVisible()); + EXPECT_EQ(kChild1Bounds, child(0)->bounds()); + EXPECT_TRUE(child(1)->GetVisible()); + EXPECT_EQ(kChild2Bounds, child(1)->bounds()); + EXPECT_FALSE(child(2)->GetVisible()); +} + +TEST_F(LayoutManagerBaseManagerTest, Install) { + EXPECT_EQ(host_view(), layout_manager()->host_view()); +} + +TEST_F(LayoutManagerBaseManagerTest, GetMinimumSize) { + AddChildView(kSquarishSize); + AddChildView(kLongSize); + AddChildView(kTallSize); + EXPECT_EQ(gfx::Size(kChildViewPadding, kChildViewPadding), + host_view()->GetMinimumSize()); +} + +TEST_F(LayoutManagerBaseManagerTest, GetPreferredSize) { + AddChildView(kSquarishSize); + AddChildView(kLongSize); + AddChildView(kTallSize); + const gfx::Size expected(kLongSize.width() + 2 * kChildViewPadding, + kTallSize.height() + 2 * kChildViewPadding); + EXPECT_EQ(expected, host_view()->GetPreferredSize()); +} + +TEST_F(LayoutManagerBaseManagerTest, GetPreferredHeightForWidth) { + AddChildView(kSquarishSize); + AddChildView(kLargeSize); + const int expected = kSquarishSize.height() + 2 * kChildViewPadding; + EXPECT_EQ(expected, + layout_manager()->GetPreferredHeightForWidth(host_view(), 20)); + EXPECT_EQ(1, layout_manager()->num_layouts_generated()); + layout_manager()->GetPreferredHeightForWidth(host_view(), 20); + EXPECT_EQ(1, layout_manager()->num_layouts_generated()); + layout_manager()->GetPreferredHeightForWidth(host_view(), 25); + EXPECT_EQ(2, layout_manager()->num_layouts_generated()); +} + +TEST_F(LayoutManagerBaseManagerTest, InvalidateLayout) { + // Some invalidation could have been triggered during setup. + const int old_num_invalidations = layout_manager()->num_invalidations(); + + host_view()->InvalidateLayout(); + EXPECT_EQ(old_num_invalidations + 1, layout_manager()->num_invalidations()); +} + +TEST_F(LayoutManagerBaseManagerTest, Layout) { + constexpr gfx::Point kUpperLeft(kChildViewPadding, kChildViewPadding); + AddChildView(kSquarishSize); + AddChildView(kLongSize); + AddChildView(kTallSize); + + // This should fit all of the child views and trigger layout. + host_view()->SetSize({40, 40}); + EXPECT_EQ(1, layout_manager()->num_layouts_generated()); + EXPECT_EQ(gfx::Rect(kUpperLeft, child(0)->GetPreferredSize()), + child(0)->bounds()); + EXPECT_TRUE(child(0)->GetVisible()); + EXPECT_EQ(gfx::Rect(kUpperLeft, child(1)->GetPreferredSize()), + child(1)->bounds()); + EXPECT_TRUE(child(1)->GetVisible()); + EXPECT_EQ(gfx::Rect(kUpperLeft, child(2)->GetPreferredSize()), + child(2)->bounds()); + EXPECT_TRUE(child(2)->GetVisible()); + + // This should drop out some children. + host_view()->SetSize({25, 25}); + EXPECT_EQ(2, layout_manager()->num_layouts_generated()); + EXPECT_EQ(gfx::Rect(kUpperLeft, child(0)->GetPreferredSize()), + child(0)->bounds()); + EXPECT_TRUE(child(0)->GetVisible()); + EXPECT_FALSE(child(1)->GetVisible()); + EXPECT_FALSE(child(2)->GetVisible()); +} + +TEST_F(LayoutManagerBaseManagerTest, ChildViewIgnoredByLayout) { + AddChildView(kSquarishSize); + AddChildView(kLongSize); + AddChildView(kTallSize); + + EXPECT_FALSE(layout_manager()->IsChildViewIgnoredByLayout(child(0))); + EXPECT_FALSE(layout_manager()->IsChildViewIgnoredByLayout(child(1))); + EXPECT_FALSE(layout_manager()->IsChildViewIgnoredByLayout(child(2))); + + layout_manager()->SetChildViewIgnoredByLayout(child(1), true); + + EXPECT_FALSE(layout_manager()->IsChildViewIgnoredByLayout(child(0))); + EXPECT_TRUE(layout_manager()->IsChildViewIgnoredByLayout(child(1))); + EXPECT_FALSE(layout_manager()->IsChildViewIgnoredByLayout(child(2))); +} + +TEST_F(LayoutManagerBaseManagerTest, + ChildViewIgnoredByLayout_IgnoresChildView) { + AddChildView(kSquarishSize); + AddChildView(kLongSize); + AddChildView(kTallSize); + + layout_manager()->SetChildViewIgnoredByLayout(child(1), true); + + child(1)->SetSize(kLargeSize); + + // Makes enough room for all views, and triggers layout. + host_view()->SetSize({50, 50}); + + EXPECT_EQ(child(0)->GetPreferredSize(), child(0)->size()); + EXPECT_EQ(kLargeSize, child(1)->size()); + EXPECT_EQ(child(2)->GetPreferredSize(), child(2)->size()); +} + +TEST_F(LayoutManagerBaseManagerTest, ViewVisibilitySet) { + AddChildView(kSquarishSize); + AddChildView(kLongSize); + AddChildView(kTallSize); + + child(1)->SetVisible(false); + + // Makes enough room for all views, and triggers layout. + host_view()->SetSize({50, 50}); + + EXPECT_TRUE(child(0)->GetVisible()); + EXPECT_EQ(child(0)->GetPreferredSize(), child(0)->size()); + EXPECT_FALSE(child(1)->GetVisible()); + EXPECT_TRUE(child(2)->GetVisible()); + EXPECT_EQ(child(2)->GetPreferredSize(), child(2)->size()); + + // Turn the second child view back on and verify it's present in the layout + // again. + child(1)->SetVisible(true); + host_view()->Layout(); + + EXPECT_TRUE(child(0)->GetVisible()); + EXPECT_EQ(child(0)->GetPreferredSize(), child(0)->size()); + EXPECT_TRUE(child(1)->GetVisible()); + EXPECT_EQ(child(1)->GetPreferredSize(), child(1)->size()); + EXPECT_TRUE(child(2)->GetVisible()); + EXPECT_EQ(child(2)->GetPreferredSize(), child(2)->size()); +} + +TEST_F(LayoutManagerBaseManagerTest, ViewAdded) { + AddChildView(kLongSize); + AddChildView(kTallSize); + + // Makes enough room for all views, and triggers layout. + host_view()->SetSize({50, 50}); + + EXPECT_TRUE(child(0)->GetVisible()); + EXPECT_EQ(child(0)->GetPreferredSize(), child(0)->size()); + EXPECT_TRUE(child(1)->GetVisible()); + EXPECT_EQ(child(1)->GetPreferredSize(), child(1)->size()); + + // Add a new view and verify it is being laid out. + View* new_view = AddChildView(kSquarishSize); + host_view()->Layout(); + + EXPECT_TRUE(new_view->GetVisible()); + EXPECT_EQ(new_view->GetPreferredSize(), new_view->size()); +} + +TEST_F(LayoutManagerBaseManagerTest, ViewAdded_NotVisible) { + AddChildView(kLongSize); + AddChildView(kTallSize); + + // Makes enough room for all views, and triggers layout. + host_view()->SetSize({50, 50}); + + EXPECT_TRUE(child(0)->GetVisible()); + EXPECT_EQ(child(0)->GetPreferredSize(), child(0)->size()); + EXPECT_TRUE(child(1)->GetVisible()); + EXPECT_EQ(child(1)->GetPreferredSize(), child(1)->size()); + + // Add a new view that is not visible and ensure that the layout manager + // doesn't touch it during layout. + View* new_view = new StaticSizedView(kSquarishSize); + new_view->SetVisible(false); + host_view()->AddChildView(new_view); + host_view()->Layout(); + + EXPECT_FALSE(new_view->GetVisible()); +} + +TEST_F(LayoutManagerBaseManagerTest, ViewRemoved) { + AddChildView(kSquarishSize); + View* const child_view = AddChildView(kLongSize); + AddChildView(kTallSize); + + // Makes enough room for all views, and triggers layout. + host_view()->SetSize({50, 50}); + + EXPECT_TRUE(child(0)->GetVisible()); + EXPECT_EQ(child(0)->GetPreferredSize(), child(0)->size()); + EXPECT_TRUE(child(1)->GetVisible()); + EXPECT_EQ(child(1)->GetPreferredSize(), child(1)->size()); + EXPECT_TRUE(child(2)->GetVisible()); + EXPECT_EQ(child(2)->GetPreferredSize(), child(2)->size()); + + host_view()->RemoveChildView(child_view); + child_view->SetSize(kLargeSize); + host_view()->Layout(); + + EXPECT_TRUE(child(0)->GetVisible()); + EXPECT_EQ(child(0)->GetPreferredSize(), child(0)->size()); + EXPECT_TRUE(child(1)->GetVisible()); + EXPECT_EQ(child(1)->GetPreferredSize(), child(1)->size()); + + EXPECT_TRUE(child_view->GetVisible()); + EXPECT_EQ(kLargeSize, child_view->size()); + + // Required since we removed it from the parent view. + delete child_view; +} + +} // namespace views
diff --git a/ui/views/layout/layout_types.cc b/ui/views/layout/layout_types.cc new file mode 100644 index 0000000..67e4a77 --- /dev/null +++ b/ui/views/layout/layout_types.cc
@@ -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. + +#include "ui/views/layout/layout_types.h" + +#include <algorithm> + +#include "base/strings/stringprintf.h" +#include "ui/gfx/geometry/size.h" + +namespace views { + +namespace { + +std::string OptionalToString(const base::Optional<int>& opt) { + if (!opt.has_value()) + return "_"; + return base::StringPrintf("%d", opt.value()); +} + +} // namespace + +// SizeBounds ------------------------------------------------------------------ + +SizeBounds::SizeBounds() = default; + +SizeBounds::SizeBounds(const base::Optional<int>& width, + const base::Optional<int>& height) + : width_(width), height_(height) {} + +SizeBounds::SizeBounds(const SizeBounds& other) + : width_(other.width()), height_(other.height()) {} + +SizeBounds::SizeBounds(const gfx::Size& other) + : width_(other.width()), height_(other.height()) {} + +void SizeBounds::Enlarge(int width, int height) { + if (width_) + width_ = std::max(0, *width_ + width); + if (height_) + height_ = std::max(0, *height_ + height); +} + +bool SizeBounds::operator==(const SizeBounds& other) const { + return width_ == other.width_ && height_ == other.height_; +} + +bool SizeBounds::operator!=(const SizeBounds& other) const { + return !(*this == other); +} + +bool SizeBounds::operator<(const SizeBounds& other) const { + return std::tie(height_, width_) < std::tie(other.height_, other.width_); +} + +std::string SizeBounds::ToString() const { + return base::StringPrintf("%s x %s", OptionalToString(width()).c_str(), + OptionalToString(height()).c_str()); +} + +} // namespace views
diff --git a/ui/views/layout/layout_types.h b/ui/views/layout/layout_types.h new file mode 100644 index 0000000..24b3383f --- /dev/null +++ b/ui/views/layout/layout_types.h
@@ -0,0 +1,58 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_VIEWS_LAYOUT_LAYOUT_TYPES_H_ +#define UI_VIEWS_LAYOUT_LAYOUT_TYPES_H_ + +#include <string> + +#include "base/optional.h" +#include "ui/views/views_export.h" + +namespace gfx { +class Size; +} // namespace gfx + +namespace views { + +// Whether a layout is oriented horizontally or vertically. +enum class LayoutOrientation { + kHorizontal, + kVertical, +}; + +// Stores an optional width and height upper bound. Used when calculating the +// preferred size of a layout pursuant to a maximum available size. +class VIEWS_EXPORT SizeBounds { + public: + SizeBounds(); + SizeBounds(const base::Optional<int>& width, + const base::Optional<int>& height); + explicit SizeBounds(const gfx::Size& size); + SizeBounds(const SizeBounds& other); + + const base::Optional<int>& width() const { return width_; } + void set_width(const base::Optional<int>& width) { width_ = width; } + + const base::Optional<int>& height() const { return height_; } + void set_height(const base::Optional<int>& height) { height_ = height; } + + // Enlarges (or shrinks, if negative) each upper bound that is present by the + // specified amounts. + void Enlarge(int width, int height); + + bool operator==(const SizeBounds& other) const; + bool operator!=(const SizeBounds& other) const; + bool operator<(const SizeBounds& other) const; + + std::string ToString() const; + + private: + base::Optional<int> width_; + base::Optional<int> height_; +}; + +} // namespace views + +#endif // UI_VIEWS_LAYOUT_LAYOUT_TYPES_H_
diff --git a/ui/views_content_client/views_content_client_main_parts.cc b/ui/views_content_client/views_content_client_main_parts.cc index c1a83aa..e7fa6743 100644 --- a/ui/views_content_client/views_content_client_main_parts.cc +++ b/ui/views_content_client/views_content_client_main_parts.cc
@@ -33,7 +33,7 @@ void ViewsContentClientMainParts::PreMainMessageLoopRun() { ui::MaterialDesignController::Initialize(); ui::InitializeInputMethodForTesting(); - browser_context_.reset(new content::ShellBrowserContext(false, NULL)); + browser_context_.reset(new content::ShellBrowserContext(false)); std::unique_ptr<views::TestViewsDelegate> test_views_delegate( new views::DesktopTestViewsDelegate);
diff --git a/ui/webui/resources/cr_elements/cr_slider/cr_slider.html b/ui/webui/resources/cr_elements/cr_slider/cr_slider.html index 0d4ea45..c321370 100644 --- a/ui/webui/resources/cr_elements/cr_slider/cr_slider.html +++ b/ui/webui/resources/cr_elements/cr_slider/cr_slider.html
@@ -114,7 +114,6 @@ #bar { border-top-color: var(--cr-slider-active-color); - width: 0; } :host([transiting_]) #bar { @@ -206,7 +205,7 @@ box-shadow: unset; } </style> - <div id="container"> + <div id="container" hidden> <div id="bar"></div> <div id="markers" hidden$="[[!markerCount]]"> <template is="dom-repeat" items="[[getMarkers_(markerCount)]]">
diff --git a/ui/webui/resources/cr_elements/cr_slider/cr_slider.js b/ui/webui/resources/cr_elements/cr_slider/cr_slider.js index 92471e2..2da0101c 100644 --- a/ui/webui/resources/cr_elements/cr_slider/cr_slider.js +++ b/ui/webui/resources/cr_elements/cr_slider/cr_slider.js
@@ -132,10 +132,7 @@ value: () => [], }, - value: { - type: Number, - value: 0, - }, + value: Number, /** @private */ label_: { @@ -179,7 +176,7 @@ observers: [ 'onTicksChanged_(ticks.*)', 'updateUi_(ticks.*, value, min, max)', - 'updateValue_(value, min, max)', + 'onValueMinMaxChange_(value, min, max)', ], listeners: { @@ -211,7 +208,10 @@ this.draggingEventTracker_ = new EventTracker(); }, - /** @private */ + /** + * @return {boolean} + * @private + */ computeDisabled_: function() { return this.disabled || this.ticks.length == 1; }, @@ -381,7 +381,9 @@ this.max = this.ticks.length - 1; this.min = 0; } - this.updateValue_(this.value); + if (this.value !== undefined) { + this.updateValue_(this.value); + } }, /** @private */ @@ -390,6 +392,15 @@ }, /** @private */ + onValueMinMaxChange_: function() { + if (this.value == undefined || this.min == undefined || + this.max == undefined) { + return; + } + this.updateValue_(this.value); + }, + + /** @private */ updateUi_: function() { const percent = `${this.getRatio() * 100}%`; this.$.bar.style.width = percent; @@ -420,6 +431,7 @@ * @private */ updateValue_: function(value) { + this.$.container.hidden = false; if (this.snaps) { // Skip update if |value| has not passed the next value .8 units away. // The value will update as the drag approaches the next value.