diff --git a/DEPS b/DEPS index c06f3ac..f47f043d 100644 --- a/DEPS +++ b/DEPS
@@ -138,11 +138,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': 'eca66b32fdb91344b2a22d98c405794c3fded66a', + 'skia_revision': 'fec9b902a626c4e9fa5aa13c03c5b1261666f45c', # 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': 'ddbb5499b8722f494df8daa5b5e21e3f5e2b6f64', + 'v8_revision': 'd6158eea40c4b8863977f863a26aeb8f423b17b8', # 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. @@ -150,11 +150,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '98f2167125a8d204ed120d483d79a7af577806ca', + 'angle_revision': '4a75741655d330e257b2f20d7404cce1e51ef72e', # 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': 'bb575d48d5f9f96cef08a5d23b0d51ce3c57ae1a', + 'swiftshader_revision': '75841d73c2de727355d48d8d9af9f6cd7e3f7738', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -201,7 +201,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': '58f6c4682e28f328945fa14a616d6b4e1cdde6ad', + 'catapult_revision': '1c7a411305c552836f51768b3ad613d8d500b17a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -257,11 +257,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. - 'spv_tools_revision': '699e167d78eee66232f140d4dcf5e9453de2dc74', + 'spv_tools_revision': '2c0111e6eba779cf30e8c7f5a733ea0762895ba0', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'spv_headers_revision': '903d447d96eb3973bdf95e9d16581b704784a0e3', + 'spv_headers_revision': '8b911bd2ba37677037b38c9bd286c7c05701bcda', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -807,7 +807,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '6e80eaeb04000f78322820e286e91aa474e8d0f8', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '062420146dfd839935afb7147f6a52128b4f8f5a', 'condition': 'checkout_linux', }, @@ -1350,7 +1350,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '6f0b34abee8dba611c253738d955c59f703c147a', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '114e8bb7a68f239b5611f71414ca99058ae02464', + Var('webrtc_git') + '/src.git' + '@' + '102b7289a9f2db72f74884a7788605187a2ddfee', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 5415b00..1126a666 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -467,7 +467,6 @@ '^ui/events/', '^ui/gfx/', '^ui/message_center/', - '^ui/ozone/', '^ui/snapshot/', '^ui/views_content_client/', '^ui/wm/', @@ -923,6 +922,7 @@ r'.*_ios\.(cc|h)$', r'^net[\\/].*\.(cc|h)$', r'.*[\\/]tools[\\/].*\.(cc|h)$', + r'^fuchsia/engine/web_engine_debug_integration_test\.cc$', ), ), (
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn index dccaa63..ecc438d5 100644 --- a/android_webview/BUILD.gn +++ b/android_webview/BUILD.gn
@@ -612,6 +612,8 @@ "browser/net/input_stream_reader.h", "browser/network_service/android_stream_reader_url_loader.cc", "browser/network_service/android_stream_reader_url_loader.h", + "browser/network_service/aw_proxying_restricted_cookie_manager.cc", + "browser/network_service/aw_proxying_restricted_cookie_manager.h", "browser/network_service/aw_proxying_url_loader_factory.cc", "browser/network_service/aw_proxying_url_loader_factory.h", "browser/network_service/aw_url_loader_throttle.cc",
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc index 1b08fcfe..7369a5e 100644 --- a/android_webview/browser/aw_content_browser_client.cc +++ b/android_webview/browser/aw_content_browser_client.cc
@@ -29,6 +29,7 @@ #include "android_webview/browser/cookie_manager.h" #include "android_webview/browser/net/aw_proxy_config_monitor.h" #include "android_webview/browser/net/aw_url_request_context_getter.h" +#include "android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.h" #include "android_webview/browser/network_service/aw_proxying_url_loader_factory.h" #include "android_webview/browser/network_service/aw_url_loader_throttle.h" #include "android_webview/browser/network_service/net_helpers.h" @@ -1043,6 +1044,23 @@ } } +void AwContentBrowserClient::WillCreateRestrictedCookieManager( + const url::Origin& origin, + bool is_service_worker, + int process_id, + int routing_id, + network::mojom::RestrictedCookieManagerRequest* request) { + network::mojom::RestrictedCookieManagerRequest orig_request = + std::move(*request); + + network::mojom::RestrictedCookieManagerPtrInfo target_rcm_info; + *request = mojo::MakeRequest(&target_rcm_info); + + AwProxyingRestrictedCookieManager::CreateAndBind( + std::move(target_rcm_info), is_service_worker, process_id, routing_id, + std::move(orig_request)); +} + std::string AwContentBrowserClient::GetProduct() const { return android_webview::GetProduct(); }
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h index 2c06509..64116c9b 100644 --- a/android_webview/browser/aw_content_browser_client.h +++ b/android_webview/browser/aw_content_browser_client.h
@@ -238,6 +238,12 @@ network::mojom::AuthenticationHandlerPtr* authentication_handler, network::mojom::TrustedHeaderClientPtr* header_client, uint32_t* options) override; + void WillCreateRestrictedCookieManager( + const url::Origin& origin, + bool is_service_worker, + int process_id, + int routing_id, + network::mojom::RestrictedCookieManagerRequest* request) override; std::string GetProduct() const override; std::string GetUserAgent() const override; ContentBrowserClient::WideColorGamutHeuristic GetWideColorGamutHeuristic()
diff --git a/android_webview/browser/aw_download_manager_delegate.cc b/android_webview/browser/aw_download_manager_delegate.cc index 63c263a0..0c3daa2c 100644 --- a/android_webview/browser/aw_download_manager_delegate.cc +++ b/android_webview/browser/aw_download_manager_delegate.cc
@@ -13,6 +13,7 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents.h" +#include "services/network/public/cpp/features.h" namespace android_webview { @@ -71,6 +72,9 @@ const std::string& request_origin, int64_t content_length, content::WebContents* web_contents) { + if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) + return false; + if (!web_contents) return false;
diff --git a/android_webview/browser/net/aw_cookie_change_dispatcher_wrapper.cc b/android_webview/browser/net/aw_cookie_change_dispatcher_wrapper.cc index de3ea504..5202e93 100644 --- a/android_webview/browser/net/aw_cookie_change_dispatcher_wrapper.cc +++ b/android_webview/browser/net/aw_cookie_change_dispatcher_wrapper.cc
@@ -41,7 +41,13 @@ public: SubscriptionWrapper() : weak_factory_(this) {} + enum Mode { + kByCookie, + kByUrl, + }; + std::unique_ptr<net::CookieChangeSubscription> Subscribe( + Mode mode, const GURL& url, const std::string& name, net::CookieChangeCallback callback) { @@ -49,7 +55,7 @@ DCHECK(callback_list_.empty()); nested_subscription_ = - NestedSubscription::Create(url, name, weak_factory_.GetWeakPtr()); + NestedSubscription::Create(mode, url, name, weak_factory_.GetWeakPtr()); return std::make_unique<AwCookieChangeSubscription>( callback_list_.Add(std::move(callback))); } @@ -62,13 +68,14 @@ : public base::RefCountedDeleteOnSequence<NestedSubscription> { public: static scoped_refptr<NestedSubscription> Create( + Mode mode, const GURL& url, const std::string& name, base::WeakPtr<SubscriptionWrapper> subscription_wrapper) { auto subscription = base::WrapRefCounted( new NestedSubscription(std::move(subscription_wrapper))); PostTaskToCookieStoreTaskRunner(base::BindOnce( - &NestedSubscription::Subscribe, subscription, url, name)); + &NestedSubscription::Subscribe, subscription, mode, url, name)); return subscription; } @@ -85,11 +92,20 @@ ~NestedSubscription() {} - void Subscribe(const GURL& url, const std::string& name) { - subscription_ = - GetCookieStore()->GetChangeDispatcher().AddCallbackForCookie( - url, name, - base::BindRepeating(&NestedSubscription::OnChanged, this)); + void Subscribe(Mode mode, const GURL& url, const std::string& name) { + switch (mode) { + case kByCookie: + subscription_ = + GetCookieStore()->GetChangeDispatcher().AddCallbackForCookie( + url, name, + base::BindRepeating(&NestedSubscription::OnChanged, this)); + break; + case kByUrl: + subscription_ = + GetCookieStore()->GetChangeDispatcher().AddCallbackForUrl( + url, + base::BindRepeating(&NestedSubscription::OnChanged, this)); + } } void OnChanged(const net::CanonicalCookie& cookie, @@ -149,16 +165,21 @@ // subscription when the AwCookieStoreWrapper is destroyed a bit ugly. // TODO(mmenke): Still worth adding a DCHECK? SubscriptionWrapper* subscription = new SubscriptionWrapper(); - return subscription->Subscribe(url, name, std::move(callback)); + return subscription->Subscribe(SubscriptionWrapper::kByCookie, url, name, + std::move(callback)); } std::unique_ptr<net::CookieChangeSubscription> AwCookieChangeDispatcherWrapper::AddCallbackForUrl( const GURL& url, net::CookieChangeCallback callback) { - // Implement when needed by Android Webview consumers. - NOTIMPLEMENTED(); - return nullptr; +#if DCHECK_IS_ON() + DCHECK(client_task_runner_->RunsTasksInCurrentSequence()); +#endif // DCHECK_IS_ON() + + SubscriptionWrapper* subscription = new SubscriptionWrapper(); + return subscription->Subscribe(SubscriptionWrapper::kByUrl, url, + /* name=, ignored */ "", std::move(callback)); } std::unique_ptr<net::CookieChangeSubscription>
diff --git a/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.cc b/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.cc new file mode 100644 index 0000000..2bc32c5c --- /dev/null +++ b/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.cc
@@ -0,0 +1,159 @@ +// 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 "android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.h" + +#include "android_webview/browser/aw_cookie_access_policy.h" +#include "base/memory/ptr_util.h" +#include "base/task/post_task.h" +#include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" +#include "mojo/public/cpp/bindings/strong_binding.h" + +namespace android_webview { + +class AwProxyingRestrictedCookieManagerListener + : public network::mojom::CookieChangeListener { + public: + AwProxyingRestrictedCookieManagerListener( + const GURL& url, + const GURL& site_for_cookies, + base::WeakPtr<AwProxyingRestrictedCookieManager> + aw_restricted_cookie_manager, + network::mojom::CookieChangeListenerPtr client_listener) + : url_(url), + site_for_cookies_(site_for_cookies), + aw_restricted_cookie_manager_(aw_restricted_cookie_manager), + client_listener_(std::move(client_listener)) {} + + void OnCookieChange(const net::CanonicalCookie& cookie, + network::mojom::CookieChangeCause cause) override { + if (aw_restricted_cookie_manager_ && + aw_restricted_cookie_manager_->AllowCookies(url_, site_for_cookies_)) + client_listener_->OnCookieChange(cookie, cause); + } + + private: + const GURL url_; + const GURL site_for_cookies_; + base::WeakPtr<AwProxyingRestrictedCookieManager> + aw_restricted_cookie_manager_; + network::mojom::CookieChangeListenerPtr client_listener_; +}; + +// static +void AwProxyingRestrictedCookieManager::CreateAndBind( + network::mojom::RestrictedCookieManagerPtrInfo underlying_rcm, + bool is_service_worker, + int process_id, + int frame_id, + network::mojom::RestrictedCookieManagerRequest request) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + base::PostTaskWithTraits( + FROM_HERE, {content::BrowserThread::IO}, + base::BindOnce( + &AwProxyingRestrictedCookieManager::CreateAndBindOnIoThread, + std::move(underlying_rcm), is_service_worker, process_id, frame_id, + std::move(request))); +} + +AwProxyingRestrictedCookieManager::~AwProxyingRestrictedCookieManager() { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); +} + +void AwProxyingRestrictedCookieManager::GetAllForUrl( + const GURL& url, + const GURL& site_for_cookies, + network::mojom::CookieManagerGetOptionsPtr options, + GetAllForUrlCallback callback) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + + if (AllowCookies(url, site_for_cookies)) { + underlying_restricted_cookie_manager_->GetAllForUrl( + url, site_for_cookies, std::move(options), std::move(callback)); + } else { + std::move(callback).Run(std::vector<net::CanonicalCookie>()); + } +} + +void AwProxyingRestrictedCookieManager::SetCanonicalCookie( + const net::CanonicalCookie& cookie, + const GURL& url, + const GURL& site_for_cookies, + SetCanonicalCookieCallback callback) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + + if (AllowCookies(url, site_for_cookies)) { + underlying_restricted_cookie_manager_->SetCanonicalCookie( + cookie, url, site_for_cookies, std::move(callback)); + } else { + std::move(callback).Run(false); + } +} + +void AwProxyingRestrictedCookieManager::AddChangeListener( + const GURL& url, + const GURL& site_for_cookies, + network::mojom::CookieChangeListenerPtr listener, + AddChangeListenerCallback callback) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + + network::mojom::CookieChangeListenerPtr proxy_listener_ptr; + auto proxy_listener = + std::make_unique<AwProxyingRestrictedCookieManagerListener>( + url, site_for_cookies, weak_factory_.GetWeakPtr(), + std::move(listener)); + + mojo::MakeStrongBinding(std::move(proxy_listener), + mojo::MakeRequest(&proxy_listener_ptr)); + + underlying_restricted_cookie_manager_->AddChangeListener( + url, site_for_cookies, std::move(proxy_listener_ptr), + std::move(callback)); +} + +AwProxyingRestrictedCookieManager::AwProxyingRestrictedCookieManager( + network::mojom::RestrictedCookieManagerPtr + underlying_restricted_cookie_manager, + bool is_service_worker, + int process_id, + int frame_id) + : underlying_restricted_cookie_manager_( + std::move(underlying_restricted_cookie_manager)), + is_service_worker_(is_service_worker), + process_id_(process_id), + frame_id_(frame_id), + weak_factory_(this) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); +} + +// static +void AwProxyingRestrictedCookieManager::CreateAndBindOnIoThread( + network::mojom::RestrictedCookieManagerPtrInfo underlying_rcm, + bool is_service_worker, + int process_id, + int frame_id, + network::mojom::RestrictedCookieManagerRequest request) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + auto wrapper = base::WrapUnique(new AwProxyingRestrictedCookieManager( + network::mojom::RestrictedCookieManagerPtr(std::move(underlying_rcm)), + is_service_worker, process_id, frame_id)); + mojo::MakeStrongBinding(std::move(wrapper), std::move(request)); +} + +bool AwProxyingRestrictedCookieManager::AllowCookies( + const GURL& url, + const GURL& site_for_cookies) const { + if (is_service_worker_) { + // Service worker cookies are always first-party, so only need to check + // the global toggle. + return AwCookieAccessPolicy::GetInstance()->GetShouldAcceptCookies(); + } else { + return AwCookieAccessPolicy::GetInstance()->AllowCookies( + url, site_for_cookies, process_id_, frame_id_); + } +} + +} // namespace android_webview
diff --git a/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.h b/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.h new file mode 100644 index 0000000..65b89a7 --- /dev/null +++ b/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.h
@@ -0,0 +1,78 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ANDROID_WEBVIEW_BROWSER_NETWORK_SERVICE_AW_PROXYING_RESTRICTED_COOKIE_MANAGER_H_ +#define ANDROID_WEBVIEW_BROWSER_NETWORK_SERVICE_AW_PROXYING_RESTRICTED_COOKIE_MANAGER_H_ + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "services/network/public/mojom/restricted_cookie_manager.mojom.h" +#include "url/gurl.h" + +namespace android_webview { + +// A RestrictedCookieManager which conditionally proxies to an underlying +// RestrictedCookieManager, first consulting WebView's cookie settings. +class AwProxyingRestrictedCookieManager + : public network::mojom::RestrictedCookieManager { + public: + // Creates a AwProxyingRestrictedCookieManager that lives on IO thread, + // binding it to handle communications from |request|. The requests will be + // delegated to |underlying_rcm|. The resulting object will be owned by the + // pipe corresponding to |request| and will in turn own |underlying_rcm|. + // + // Expects to be called on the UI thread. + static void CreateAndBind( + network::mojom::RestrictedCookieManagerPtrInfo underlying_rcm, + bool is_service_worker, + int process_id, + int frame_id, + network::mojom::RestrictedCookieManagerRequest request); + + ~AwProxyingRestrictedCookieManager() override; + + // network::mojom::RestrictedCookieManager interface: + void GetAllForUrl(const GURL& url, + const GURL& site_for_cookies, + network::mojom::CookieManagerGetOptionsPtr options, + GetAllForUrlCallback callback) override; + void SetCanonicalCookie(const net::CanonicalCookie& cookie, + const GURL& url, + const GURL& site_for_cookies, + SetCanonicalCookieCallback callback) override; + void AddChangeListener(const GURL& url, + const GURL& site_for_cookies, + network::mojom::CookieChangeListenerPtr listener, + AddChangeListenerCallback callback) override; + + bool AllowCookies(const GURL& url, const GURL& site_for_cookies) const; + + private: + AwProxyingRestrictedCookieManager(network::mojom::RestrictedCookieManagerPtr + underlying_restricted_cookie_manager, + bool is_service_worker, + int process_id, + int frame_id); + + static void CreateAndBindOnIoThread( + network::mojom::RestrictedCookieManagerPtrInfo underlying_rcm, + bool is_service_worker, + int process_id, + int frame_id, + network::mojom::RestrictedCookieManagerRequest request); + + network::mojom::RestrictedCookieManagerPtr + underlying_restricted_cookie_manager_; + bool is_service_worker_; + int process_id_; + int frame_id_; + + base::WeakPtrFactory<AwProxyingRestrictedCookieManager> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(AwProxyingRestrictedCookieManager); +}; + +} // namespace android_webview + +#endif // ANDROID_WEBVIEW_BROWSER_NETWORK_SERVICE_AW_PROXYING_RESTRICTED_COOKIE_MANAGER_H_
diff --git a/android_webview/java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java b/android_webview/java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java index f535fba..53e9df3 100644 --- a/android_webview/java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java +++ b/android_webview/java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java
@@ -76,12 +76,15 @@ private static JobScheduler getScheduler() { if (sMockJobScheduler != null) return sMockJobScheduler; + + // This may be null due to vendor framework bugs. https://crbug.com/968636 return (JobScheduler) ContextUtils.getApplicationContext().getSystemService( Context.JOB_SCHEDULER_SERVICE); } public static void scheduleIfNeeded() { JobScheduler scheduler = getScheduler(); + if (scheduler == null) return; // Check if it's already scheduled. if (getPendingJob(scheduler, JOB_ID) != null) {
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerTest.java index a21570c4..cfdb79ad 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerTest.java
@@ -23,6 +23,7 @@ import org.chromium.android_webview.test.util.CookieUtils.TestCallback; import org.chromium.android_webview.test.util.JSUtils; import org.chromium.base.Callback; +import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Feature; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.test.util.JavaScriptUtils; @@ -97,7 +98,8 @@ throws Throwable { mCookieManager.setAcceptCookie(acceptCookieValue); - TestWebServer webServer = TestWebServer.start(); + // Using SSL server here since CookieStore API requires a secure schema. + TestWebServer webServer = TestWebServer.startSsl(); try { String path = "/cookie_test.html"; String responseStr = @@ -106,7 +108,7 @@ mActivityTestRule.loadUrlSync( mAwContents, mContentsClient.getOnPageFinishedHelper(), url); final String jsCookieName = "js-test" + cookieSuffix; - setCookieWithJavaScript(jsCookieName, "value"); + setCookieWithDocumentCookieAPI(jsCookieName, "value"); if (acceptCookieValue) { waitForCookie(url); assertHasCookies(url); @@ -115,6 +117,16 @@ assertNoCookies(url); } + final String cookieStoreCookieName = "cookiestore-test" + cookieSuffix; + setCookieWithCookieStoreAPI(cookieStoreCookieName, "value"); + if (acceptCookieValue) { + waitForCookie(url); + assertHasCookies(url); + validateCookies(url, jsCookieName, cookieStoreCookieName); + } else { + assertNoCookies(url); + } + final List<Pair<String, String>> responseHeaders = new ArrayList<Pair<String, String>>(); final String headerCookieName = "header-test" + cookieSuffix; @@ -126,7 +138,7 @@ if (acceptCookieValue) { waitForCookie(url); assertHasCookies(url); - validateCookies(url, jsCookieName, headerCookieName); + validateCookies(url, jsCookieName, cookieStoreCookieName, headerCookieName); } else { assertNoCookies(url); } @@ -138,6 +150,8 @@ @Test @MediumTest @Feature({"AndroidWebView", "Privacy"}) + @CommandLineFlags.Add({"enable-blink-features=CookieStore"}) + // TODO(https://crbug.com/968649) Remove switch when CookieStore launched. public void testAcceptCookie_falseWontSetCookies() throws Throwable { testAcceptCookieHelper(false, "-disabled"); } @@ -145,6 +159,8 @@ @Test @MediumTest @Feature({"AndroidWebView", "Privacy"}) + @CommandLineFlags.Add({"enable-blink-features=CookieStore"}) + // TODO(https://crbug.com/968649) Remove switch when CookieStore launched. public void testAcceptCookie_trueWillSetCookies() throws Throwable { testAcceptCookieHelper(true, "-enabled"); } @@ -209,7 +225,7 @@ } } - private void setCookieWithJavaScript(final String name, final String value) + private void setCookieWithDocumentCookieAPI(final String name, final String value) throws Throwable { JSUtils.executeJavaScriptAndWaitForResult(InstrumentationRegistry.getInstrumentation(), mAwContents, mContentsClient.getOnEvaluateJavaScriptResultHelper(), @@ -219,6 +235,16 @@ + "; expires=' + expirationDate.toUTCString();"); } + private void setCookieWithCookieStoreAPI(final String name, final String value) + throws Throwable { + JavaScriptUtils.runJavascriptWithAsyncResult(mAwContents.getWebContents(), + "async function doSet() {" + + makeCookieStoreSetFragment("'" + name + "'", "'" + value + "'", + "window.domAutomationController.send(true);") + + "}\n" + + "doSet()"); + } + private String getCookieWithJavaScript(final String name) throws Throwable { return JSUtils.executeJavaScriptAndWaitForResult( InstrumentationRegistry.getInstrumentation(), mAwContents, @@ -556,6 +582,51 @@ @Test @MediumTest @Feature({"AndroidWebView", "Privacy"}) + @CommandLineFlags.Add({"enable-blink-features=CookieStore"}) + // TODO(https://crbug.com/968649) Remove switch when CookieStore launched. + public void testCookieStoreListener() throws Throwable { + TestWebServer webServer = TestWebServer.startSsl(); + try { + allowFirstPartyCookies(); + + String url = makeCookieScriptUrl(webServer, "/cookie_1.html", "test1", "value1"); + mActivityTestRule.loadUrlSync( + mAwContents, mContentsClient.getOnPageFinishedHelper(), url); + + // Add a listener... + JSUtils.executeJavaScriptAndWaitForResult(InstrumentationRegistry.getInstrumentation(), + mAwContents, mContentsClient.getOnEvaluateJavaScriptResultHelper(), + "window.events = [];" + + "cookieStore.addEventListener('change', (event) => {" + + " for (let d of event.deleted)" + + " window.events.push({'del': d.name});" + + " for (let c of event.changed)" + + " window.events.push({'change': c.name});" + + "})"); + + // Clearing all cookies with cookies disabled shouldn't report anything. + blockAllCookies(); + clearCookies(); + + // Re-enable cookies, set one. + allowFirstPartyCookies(); + setCookieWithDocumentCookieAPI("test2", "value2"); + + // Look up the result. Should see the second set, but not the + // delete, based on whether cookie access was permitted or not + // at the time. + String reported = JSUtils.executeJavaScriptAndWaitForResult( + InstrumentationRegistry.getInstrumentation(), mAwContents, + mContentsClient.getOnEvaluateJavaScriptResultHelper(), "window.events"); + Assert.assertEquals("[{\"change\":\"test2\"}]", reported); + } finally { + webServer.shutdown(); + } + } + + @Test + @MediumTest + @Feature({"AndroidWebView", "Privacy"}) public void testThirdPartyCookie_redirectFromThirdPartyToFirst() throws Throwable { TestWebServer webServer = TestWebServer.start(); try { @@ -750,8 +821,11 @@ @Test @MediumTest @Feature({"AndroidWebView", "Privacy"}) + @CommandLineFlags.Add({"enable-blink-features=CookieStore"}) + // TODO(https://crbug.com/968649) Remove switch when CookieStore launched. public void testThirdPartyJavascriptCookie() throws Throwable { - TestWebServer webServer = TestWebServer.start(); + // Using SSL server here since CookieStore API requires a secure schema. + TestWebServer webServer = TestWebServer.startSsl(); try { // This test again uses 127.0.0.1/localhost trick to simulate a third party. ThirdPartyCookiesTestHelper thirdParty = @@ -775,8 +849,11 @@ @Test @MediumTest @Feature({"AndroidWebView", "Privacy"}) + @CommandLineFlags.Add({"enable-blink-features=CookieStore"}) + // TODO(https://crbug.com/968649) Remove switch when CookieStore launched. public void testThirdPartyCookiesArePerWebview() throws Throwable { - TestWebServer webServer = TestWebServer.start(); + // Using SSL server here since CookieStore API requires a secure schema. + TestWebServer webServer = TestWebServer.startSsl(); try { allowFirstPartyCookies(); mCookieManager.removeAllCookies(); @@ -905,6 +982,7 @@ void assertThirdPartyIFrameCookieResult(String suffix, boolean expectedResult) throws Throwable { String key = "test" + suffix; + String cookieStoreKey = "cookieStoreTest" + suffix; String value = "value" + suffix; String iframePath = "/iframe_" + suffix + ".html"; String pagePath = "/content_" + suffix + ".html"; @@ -925,6 +1003,17 @@ assertNoCookies(cookieUrl); } + // Try to set via CookieStore API as well. + JavaScriptUtils.runJavascriptWithAsyncResult( + mAwContents.getWebContents(), "callIframe('" + cookieStoreKey + "')"); + + if (expectedResult) { + assertHasCookies(cookieUrl); + validateCookies(cookieUrl, key, cookieStoreKey); + } else { + assertNoCookies(cookieUrl); + } + // Clear the cookies. clearCookies(); Assert.assertFalse(mCookieManager.hasCookies()); @@ -932,15 +1021,25 @@ } /** - * Creates a response on the TestWebServer which attempts to set a cookie when fetched. + * Creates a response on the TestWebServer which load a given URL in an iframe, + * and provides helpers for forwarding JavaScript calls to that iframe via postMessage. * @param webServer the webServer on which to create the response * @param path the path component of the url (e.g "/my_thing_with_iframe.html") * @param url the url which which should appear as the src of the iframe. * @return the url which gets the response */ private String makeIframeUrl(TestWebServer webServer, String path, String url) { - String responseStr = "<html><head><title>Content!</title></head>" - + "<body><iframe src=" + url + "></iframe></body></html>"; + String responseStr = "<html><head><title>Content!</title>" + + "<script>" + + "window.onmessage = function(ev) { " + + " window.domAutomationController.send(ev.data); " + + "}\n" + + "function callIframe(data) { " + + " document.getElementById('if').contentWindow.postMessage(" + + " data, '*'); " + + "}" + + "</script>" + + "</head><body><iframe id=if src=" + url + "></iframe></body></html>"; return webServer.setResponse(path, responseStr, null); } @@ -955,11 +1054,33 @@ private String makeCookieScriptUrl(TestWebServer webServer, String path, String key, String value) { String response = "<html><head></head><body>" - + "<script>document.cookie = \"" + key + "=" + value + "\";</script></body></html>"; + + "<script>document.cookie = \"" + key + "=" + value + "\";" + + "window.onmessage = async function(ev) {" + + makeCookieStoreSetFragment( + "ev.data", "'" + value + "'", "ev.source.postMessage(true, '*');") + + "}" + + "</script></body></html>"; return webServer.setResponse(path, response, null); } /** + * Returns code fragment to be embedded into an async function to set a cookie with CookieStore + * API + * @param name name of cookie to set + * @param value value to set the cookie to + * @param finallyAction code to run once set finishes, regardless of success or failure + */ + private String makeCookieStoreSetFragment(String name, String value, String finallyAction) { + return "try {" + + " await window.cookieStore.set(" + + " " + name + ", " + value + ", " + + " { expires: Date.now() + 3600*1000," + + " sameSite: 'unrestricted' });" + + "} finally {" + + " " + finallyAction + "}\n"; + } + + /** * Makes a url look as if it comes from a different host. * @param url the url to fake. * @return the resulting url after faking.
diff --git a/android_webview/tools/apk_merger.py b/android_webview/tools/apk_merger.py index 5b95d3d..7be38cdb 100755 --- a/android_webview/tools/apk_merger.py +++ b/android_webview/tools/apk_merger.py
@@ -3,19 +3,31 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" Merges a 64-bit and a 32-bit APK into a single APK +""" Merges a 32-bit APK into a 32/64-bit APK. -This script is used to merge two APKs which have only 32-bit or 64-bit -binaries respectively into a APK that has both 32-bit and 64-bit binaries -for 64-bit Android platform. +This script is used to make the 32-bit parts of a pure 32-bit APK identical to +those of an APK built on a 64-bit configuration (whether adding 32-bit parts to +a pure 64-bit build, or replacing 32-bit parts in a multi-architecture build to +ensurce consistency with pure 32-bit builds). -You normally don't need this script because GN 64-bit build generates -such APK for you. +In an ideal world, the libraries and assets in a pure 32-bit APK would be +identical to the 32-bit equivalents in a 64-bit-generated APK (with secondary +ABI). However, this isn't reality. For example, subtle differences due to paths +yield different native libraries (a benign difference). Accidental differences +in build configuration yield legitimate differences (impacting functionality and +binary size). This script overwrites parts of the 64-bit APK with pieces from +the 32-bit APK, so that the two versions are identical from a 32-bit +perspective. + +Longer term, the 64-bit build configuration should be updated to generate pure +32-bit APKs. While slightly counter-intuitive, this would ensure that 32-bit +pieces are identical across the different versions without having to merge +anything. To use this script, you need to 1. Build 32-bit APK as usual. 2. Build 64-bit APK with GN variable build_apk_secondary_abi=false OR true. -3. Use this script to merge 2 APKs. +3. Use this script to merge the 2 APKs. """ @@ -25,7 +37,6 @@ import logging import os import pprint -import re import shutil import sys import tempfile @@ -102,27 +113,19 @@ return copy_files -def CheckFilesExpected(actual_files, expected_files, component_build): +def CheckFilesExpected(actual_files, expected_files): """ Check that the lists of actual and expected files are the same. """ actual_file_names = collections.defaultdict(int) for f in actual_files: - actual_file_names[os.path.basename(f)] += 1 + actual_file_names[f] += 1 actual_file_set = set(actual_file_names.iterkeys()) - expected_file_set = set(expected_files.iterkeys()) + expected_file_set = set(expected_files) unexpected_file_set = actual_file_set.difference(expected_file_set) - if component_build: - unexpected_file_set = set( - f for f in unexpected_file_set if not f.endswith('.so')) missing_file_set = expected_file_set.difference(actual_file_set) duplicate_file_set = set( f for f, n in actual_file_names.iteritems() if n > 1) - # TODO(crbug.com/839191): Remove this once we're plumbing the lib correctly. - missing_file_set = set( - f for f in missing_file_set if not os.path.basename(f) == - 'libarcore_sdk_c.so') - errors = [] if unexpected_file_set: errors.append( @@ -137,81 +140,38 @@ "Files don't match expectations:\n%s" % '\n'.join(errors)) -def AddDiffFiles(diff_files, tmp_dir_32, out_zip, expected_files, - component_build, uncompress_shared_libraries): +def AddDiffFiles(diff_files, tmp_dir_32, out_zip, uncompress_shared_libraries): """ Insert files only present in 32-bit APK into 64-bit APK (tmp_apk). """ for diff_file in diff_files: - if component_build and diff_file.endswith('.so'): - compress = not uncompress_shared_libraries - else: - compress = expected_files[os.path.basename(diff_file)] + compress = not uncompress_shared_libraries and diff_file.endswith('.so') build_utils.AddToZipHermetic(out_zip, diff_file, os.path.join(tmp_dir_32, diff_file), compress=compress) -def GetTargetAbiPath(apk_path, shared_library): - with zipfile.ZipFile(apk_path) as z: - matches = [p for p in z.namelist() if p.endswith(shared_library)] - if len(matches) != 1: - raise ApkMergeFailure('Found multiple/no libs for %s: %s' % ( - shared_library, matches)) - return matches[0] - - -def GetSecondaryAbi(apk_zipfile, shared_library): - ret = '' - for name in apk_zipfile.namelist(): - if os.path.basename(name) == shared_library: - abi = re.search('(^lib/)(.+)(/' + shared_library + '$)', name).group(2) - # Intentionally not to add 64bit abi because they are not used. - if abi == 'armeabi-v7a' or abi == 'armeabi': - ret = 'arm64-v8a' - elif abi == 'mips': - ret = 'mips64' - elif abi == 'x86': - ret = 'x86_64' - else: - raise ApkMergeFailure('Unsupported abi ' + abi) - if ret == '': - raise ApkMergeFailure('Failed to find secondary abi') - return ret - def MergeApk(args, tmp_apk, tmp_dir_32, tmp_dir_64): - # Expected files to copy from 32- to 64-bit APK together with whether to - # compress within the .apk. - expected_files = {'snapshot_blob_32.bin': False} - if args.shared_library: - expected_files[args.shared_library] = not args.uncompress_shared_libraries - if args.has_unwind_cfi: - expected_files['unwind_cfi_32'] = False + # expected_files is the set of 32-bit related files that we expect to differ + # between a 32- and 64-bit build. Hence, they will be skipped when seeding the + # generated APK with the original 64-bit version, and explicitly copied in + # from the 32-bit version. + expected_files = [] - # TODO(crbug.com/839191): we should pass this in via script arguments. - if not args.loadable_module_32: - args.loadable_module_32.append('libarcore_sdk_c.so') - - for f in args.loadable_module_32: - expected_files[f] = not args.uncompress_shared_libraries - - for f in args.loadable_module_64: - expected_files[f] = not args.uncompress_shared_libraries - - # need to unpack APKs to compare their contents assets_path = 'base/assets' if args.bundle else 'assets' - exclude_files_64 = ['%s/snapshot_blob_32.bin' % assets_path, - GetTargetAbiPath(args.apk_32bit, args.shared_library)] - if 'libcrashpad_handler.so' in expected_files: - exclude_files_64.append( - GetTargetAbiPath(args.apk_32bit, 'libcrashpad_handler.so')) - if 'libcrashpad_handler_trampoline.so' in expected_files: - exclude_files_64.append( - GetTargetAbiPath(args.apk_32bit, 'libcrashpad_handler_trampoline.so')) - if args.has_unwind_cfi: - exclude_files_64.append('%s/unwind_cfi_32' % assets_path) - UnpackApk(args.apk_64bit, tmp_dir_64, exclude_files_64) - UnpackApk(args.apk_32bit, tmp_dir_32) + expected_files.append('%s/snapshot_blob_32.bin' % assets_path) + if args.has_unwind_cfi: + expected_files.append('%s/unwind_cfi_32' % assets_path) + + # All native libraries are assumed to differ, and will be merged. + with zipfile.ZipFile(args.apk_32bit) as z: + expected_files.extend([p for p in z.namelist() if p.endswith('.so')]) + + UnpackApk(args.apk_32bit, tmp_dir_32) + UnpackApk(args.apk_64bit, tmp_dir_64, expected_files) + + # These are files that we know will be different, and we will hence ignore in + # the file comparison. ignores = ['META-INF', 'AndroidManifest.xml'] if args.ignore_classes_dex: ignores += ['classes.dex', 'classes2.dex', 'classes3.dex'] @@ -232,26 +192,26 @@ # Check that diff_files match exactly those files we want to insert into # the 64-bit APK. - CheckFilesExpected(diff_files, expected_files, args.component_build) + CheckFilesExpected(diff_files, expected_files) with zipfile.ZipFile(tmp_apk, 'w') as out_zip: - exclude_patterns = ['META-INF/*'] + exclude_files_64 + exclude_patterns = ['META-INF/*'] + expected_files - # If there are libraries for which we don't want the 32 bit versions, we - # should remove them here. - if args.loadable_module_32: - exclude_patterns.extend(['*' + f for f in args.loadable_module_32 if - f not in args.loadable_module_64]) - + # Build the initial merged APK from the 64-bit APK, excluding all files we + # will pull from the 32-bit APK. path_transform = ( lambda p: None if build_utils.MatchesGlob(p, exclude_patterns) else p) build_utils.MergeZips( out_zip, [args.apk_64bit], path_transform=path_transform) - AddDiffFiles(diff_files, tmp_dir_32, out_zip, expected_files, - args.component_build, args.uncompress_shared_libraries) + + # Add the files from the 32-bit APK. + AddDiffFiles(diff_files, tmp_dir_32, out_zip, + args.uncompress_shared_libraries) def main(): + # TODO(cjgrant): Remove obsolete arguments once the build scripts stop + # specifying them. parser = argparse.ArgumentParser( description='Merge a 32-bit APK into a 64-bit APK') # Using type=os.path.abspath converts file paths to absolute paths so that @@ -263,15 +223,13 @@ parser.add_argument('--keystore_path', required=True, type=os.path.abspath) parser.add_argument('--key_name', required=True) parser.add_argument('--key_password', required=True) - group = parser.add_mutually_exclusive_group(required=True) - group.add_argument('--component-build', action='store_true') - group.add_argument('--shared_library') + parser.add_argument('--component-build', action='store_true') + parser.add_argument('--shared_library') parser.add_argument('--page-align-shared-libraries', action='store_true', help='Obsolete, but remains for backwards compatibility') parser.add_argument('--uncompress-shared-libraries', action='store_true') parser.add_argument('--bundle', action='store_true') parser.add_argument('--debug', action='store_true') - # This option shall only used in debug build, see http://crbug.com/631494. parser.add_argument('--ignore-classes-dex', action='store_true') parser.add_argument('--has-unwind-cfi', action='store_true', help='Specifies if the 32-bit apk has unwind_cfi file')
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 09daa9b..d33d422 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -1404,7 +1404,6 @@ "//ui/native_theme", "//ui/ozone", "//ui/platform_window", - "//ui/platform_window/mojo", "//ui/platform_window/stub", "//ui/snapshot", "//ui/views/window/vector_icons",
diff --git a/ash/host/ash_window_tree_host_platform.cc b/ash/host/ash_window_tree_host_platform.cc index 775aa644..bbc1888 100644 --- a/ash/host/ash_window_tree_host_platform.cc +++ b/ash/host/ash_window_tree_host_platform.cc
@@ -24,7 +24,6 @@ #include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/geometry/rect_f.h" #include "ui/gfx/transform.h" -#include "ui/platform_window/mojo/ime_type_converters.h" #include "ui/platform_window/platform_ime_controller.h" #include "ui/platform_window/platform_window.h" #include "ui/platform_window/platform_window_init_properties.h"
diff --git a/ash/login/login_screen_controller.cc b/ash/login/login_screen_controller.cc index 9a101d1..48eb189 100644 --- a/ash/login/login_screen_controller.cc +++ b/ash/login/login_screen_controller.cc
@@ -301,6 +301,20 @@ return &login_data_dispatcher_; } +void LoginScreenController::ShowGuestButtonInOobe(bool show) { + Shelf::ForWindow(Shell::Get()->GetPrimaryRootWindow()) + ->shelf_widget() + ->login_shelf_view() + ->ShowGuestButtonInOobe(show); +} + +void LoginScreenController::ShowParentAccessButton(bool show) { + Shelf::ForWindow(Shell::Get()->GetPrimaryRootWindow()) + ->shelf_widget() + ->login_shelf_view() + ->ShowParentAccessButton(show); +} + void LoginScreenController::ShowParentAccessWidget( const AccountId& child_account_id, base::RepeatingCallback<void(bool success)> callback) { @@ -314,7 +328,7 @@ void LoginScreenController::ShowLockScreen(ShowLockScreenCallback on_shown) { OnShow(); - ash::LockScreen::Show(ash::LockScreen::ScreenType::kLock); + LockScreen::Show(LockScreen::ScreenType::kLock); std::move(on_shown).Run(true); } @@ -330,22 +344,11 @@ } OnShow(); - // TODO(jdufault): rename ash::LockScreen to ash::LoginScreen. - ash::LockScreen::Show(ash::LockScreen::ScreenType::kLogin); + // TODO(jdufault): rename LockScreen to LoginScreen. + LockScreen::Show(LockScreen::ScreenType::kLogin); std::move(on_shown).Run(true); } -void LoginScreenController::ShowErrorMessage(int32_t login_attempts, - const std::string& error_text, - const std::string& help_link_text, - int32_t help_topic_id) { - NOTIMPLEMENTED(); -} - -void LoginScreenController::ClearErrors() { - NOTIMPLEMENTED(); -} - void LoginScreenController::IsReadyForPassword( IsReadyForPasswordCallback callback) { std::move(callback).Run(LockScreen::HasInstance() && !IsAuthenticating()); @@ -366,24 +369,6 @@ ->SetAllowLoginAsGuest(allow_guest); } -void LoginScreenController::SetShowGuestButtonInOobe(bool show) { - Shelf::ForWindow(Shell::Get()->GetPrimaryRootWindow()) - ->shelf_widget() - ->login_shelf_view() - ->SetShowGuestButtonInOobe(show); -} - -void LoginScreenController::SetShowParentAccessButton(bool show) { - Shelf::ForWindow(Shell::Get()->GetPrimaryRootWindow()) - ->shelf_widget() - ->login_shelf_view() - ->SetShowParentAccessButton(show); -} - -void LoginScreenController::SetShowParentAccessDialog(bool show) { - login_data_dispatcher_.SetShowParentAccessDialog(show); -} - void LoginScreenController::FocusLoginShelf(bool reverse) { Shelf* shelf = Shelf::ForWindow(Shell::Get()->GetPrimaryRootWindow()); // Tell the focus direction to the status area or the shelf so they can focus
diff --git a/ash/login/login_screen_controller.h b/ash/login/login_screen_controller.h index ce29018..da03b8c 100644 --- a/ash/login/login_screen_controller.h +++ b/ash/login/login_screen_controller.h
@@ -110,6 +110,8 @@ // LoginScreen: LoginScreenModel* GetModel() override; + void ShowGuestButtonInOobe(bool show) override; + void ShowParentAccessButton(bool show) override; void ShowParentAccessWidget( const AccountId& child_account_id, base::RepeatingCallback<void(bool success)> callback) override; @@ -118,19 +120,11 @@ void SetClient(mojom::LoginScreenClientPtr client) override; void ShowLockScreen(ShowLockScreenCallback on_shown) override; void ShowLoginScreen(ShowLoginScreenCallback on_shown) override; - void ShowErrorMessage(int32_t login_attempts, - const std::string& error_text, - const std::string& help_link_text, - int32_t help_topic_id) override; - void ClearErrors() override; void IsReadyForPassword(IsReadyForPasswordCallback callback) override; void ShowKioskAppError(const std::string& message) override; void SetAddUserButtonEnabled(bool enable) override; void SetShutdownButtonEnabled(bool enable) override; void SetAllowLoginAsGuest(bool allow_guest) override; - void SetShowGuestButtonInOobe(bool show) override; - void SetShowParentAccessButton(bool show) override; - void SetShowParentAccessDialog(bool show) override; void FocusLoginShelf(bool reverse) override; // KioskAppMenu:
diff --git a/ash/login/ui/lock_contents_view.cc b/ash/login/ui/lock_contents_view.cc index f2bccf8..f40661a 100644 --- a/ash/login/ui/lock_contents_view.cc +++ b/ash/login/ui/lock_contents_view.cc
@@ -545,6 +545,18 @@ } } +void LockContentsView::ShowParentAccessDialog(bool show) { + if (!primary_big_view_) + return; + + if (show) + primary_big_view_->ShowParentAccessView(); + else + primary_big_view_->HideParentAccessView(); + + Layout(); +} + void LockContentsView::Layout() { View::Layout(); LayoutTopHeader(); @@ -1074,19 +1086,6 @@ GetWidget()->GetFocusManager()->ClearFocus(); } -void LockContentsView::OnSetShowParentAccessDialog(bool show) { - if (!primary_big_view_) - return; - - if (show) { - primary_big_view_->ShowParentAccessView(); - } else { - primary_big_view_->HideParentAccessView(); - } - - Layout(); -} - void LockContentsView::OnFocusLeavingLockScreenApps(bool reverse) { if (!reverse || lock_screen_apps_active_) FocusNextWidget(reverse); @@ -1735,7 +1734,7 @@ } void LockContentsView::OnParentAccessValidationFinished(bool access_granted) { - OnSetShowParentAccessDialog(false); + ShowParentAccessDialog(false); } keyboard::KeyboardController* LockContentsView::GetKeyboardControllerForView()
diff --git a/ash/login/ui/lock_contents_view.h b/ash/login/ui/lock_contents_view.h index c47b282..ccfcac3c 100644 --- a/ash/login/ui/lock_contents_view.h +++ b/ash/login/ui/lock_contents_view.h
@@ -124,6 +124,7 @@ void FocusNextUser(); void FocusPreviousUser(); + void ShowParentAccessDialog(bool show); // views::View: void Layout() override; @@ -172,7 +173,6 @@ bool show_full_management_disclosure) override; void OnDetachableBasePairingStatusChanged( DetachableBasePairingStatus pairing_status) override; - void OnSetShowParentAccessDialog(bool show) override; void OnFocusLeavingLockScreenApps(bool reverse) override; void OnOobeDialogStateChanged(OobeDialogState state) override;
diff --git a/ash/login/ui/lock_contents_view_unittest.cc b/ash/login/ui/lock_contents_view_unittest.cc index 7c21325..e7a22a5 100644 --- a/ash/login/ui/lock_contents_view_unittest.cc +++ b/ash/login/ui/lock_contents_view_unittest.cc
@@ -1946,7 +1946,7 @@ .textfield() ->HasFocus()); - DataDispatcher()->SetShowParentAccessDialog(true); + contents->ShowParentAccessDialog(true); EXPECT_TRUE(primary_view->auth_user()); EXPECT_TRUE(primary_view->parent_access()); @@ -1957,7 +1957,7 @@ ParentAccessView::TestApi(primary_view->parent_access()) .access_code_view())); - DataDispatcher()->SetShowParentAccessDialog(false); + contents->ShowParentAccessDialog(false); EXPECT_TRUE(primary_view->auth_user()); EXPECT_FALSE(primary_view->parent_access());
diff --git a/ash/login/ui/lock_debug_view.cc b/ash/login/ui/lock_debug_view.cc index 98819c2..1c2b09e 100644 --- a/ash/login/ui/lock_debug_view.cc +++ b/ash/login/ui/lock_debug_view.cc
@@ -1036,7 +1036,7 @@ // Toggle parent access view. if (sender->GetID() == ButtonId::kGlobalToggleParentAccess) { is_parent_access_shown_ = !is_parent_access_shown_; - lock_->OnSetShowParentAccessDialog(is_parent_access_shown_); + lock_->ShowParentAccessDialog(is_parent_access_shown_); } }
diff --git a/ash/login/ui/lock_screen.cc b/ash/login/ui/lock_screen.cc index 7eedb40..f6db4af 100644 --- a/ash/login/ui/lock_screen.cc +++ b/ash/login/ui/lock_screen.cc
@@ -145,6 +145,10 @@ contents_view_->FocusPreviousUser(); } +void LockScreen::ShowParentAccessDialog() { + contents_view_->ShowParentAccessDialog(true); +} + void LockScreen::OnLockScreenNoteStateChanged(mojom::TrayActionState state) { Shell::Get() ->login_screen_controller()
diff --git a/ash/login/ui/lock_screen.h b/ash/login/ui/lock_screen.h index 89df403..05761e2 100644 --- a/ash/login/ui/lock_screen.h +++ b/ash/login/ui/lock_screen.h
@@ -62,6 +62,7 @@ void FocusNextUser(); void FocusPreviousUser(); + void ShowParentAccessDialog(); // TrayActionObserver: void OnLockScreenNoteStateChanged(mojom::TrayActionState state) override;
diff --git a/ash/login/ui/login_data_dispatcher.cc b/ash/login/ui/login_data_dispatcher.cc index 4ca7fbb..644a02a 100644 --- a/ash/login/ui/login_data_dispatcher.cc +++ b/ash/login/ui/login_data_dispatcher.cc
@@ -79,8 +79,6 @@ void LoginDataDispatcher::Observer::OnDetachableBasePairingStatusChanged( DetachableBasePairingStatus pairing_status) {} -void LoginDataDispatcher::Observer::OnSetShowParentAccessDialog(bool show) {} - void LoginDataDispatcher::Observer::OnFocusLeavingLockScreenApps(bool reverse) { } @@ -228,11 +226,6 @@ observer.OnDetachableBasePairingStatusChanged(pairing_status); } -void LoginDataDispatcher::SetShowParentAccessDialog(bool show) { - for (auto& observer : observers_) - observer.OnSetShowParentAccessDialog(show); -} - void LoginDataDispatcher::HandleFocusLeavingLockScreenApps(bool reverse) { for (auto& observer : observers_) observer.OnFocusLeavingLockScreenApps(reverse);
diff --git a/ash/login/ui/login_data_dispatcher.h b/ash/login/ui/login_data_dispatcher.h index fe66da28..64f8dad 100644 --- a/ash/login/ui/login_data_dispatcher.h +++ b/ash/login/ui/login_data_dispatcher.h
@@ -127,9 +127,6 @@ virtual void OnDetachableBasePairingStatusChanged( DetachableBasePairingStatus pairing_status); - // Called when parent access code input dialog visibility should change. - virtual void OnSetShowParentAccessDialog(bool show); - // Called when focus is leaving a lock screen app window due to tabbing. // |reverse| - whether the tab order is reversed. virtual void OnFocusLeavingLockScreenApps(bool reverse); @@ -187,7 +184,6 @@ bool show_full_management_disclosure) override; void SetDetachableBasePairingStatus( DetachableBasePairingStatus pairing_status); - void SetShowParentAccessDialog(bool show); void HandleFocusLeavingLockScreenApps(bool reverse) override; void NotifyOobeDialogState(OobeDialogState state) override;
diff --git a/ash/mojo_interface_factory.cc b/ash/mojo_interface_factory.cc index a0f351fb..cec4b408 100644 --- a/ash/mojo_interface_factory.cc +++ b/ash/mojo_interface_factory.cc
@@ -34,7 +34,6 @@ #include "ash/system/night_light/night_light_controller.h" #include "ash/tray_action/tray_action.h" #include "ash/voice_interaction/voice_interaction_controller.h" -#include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "base/bind.h" #include "base/command_line.h" #include "base/lazy_instance.h" @@ -147,11 +146,6 @@ Shell::Get()->shutdown_controller()->BindRequest(std::move(request)); } -void BindTabletModeRequestOnMainThread( - mojom::TabletModeControllerRequest request) { - Shell::Get()->tablet_mode_controller()->BindRequest(std::move(request)); -} - void BindTrayActionRequestOnMainThread(mojom::TrayActionRequest request) { Shell::Get()->tray_action()->BindRequest(std::move(request)); } @@ -233,9 +227,6 @@ base::BindRepeating(&BindShutdownControllerRequestOnMainThread), main_thread_task_runner); registry->AddInterface( - base::BindRepeating(&BindTabletModeRequestOnMainThread), - main_thread_task_runner); - registry->AddInterface( base::BindRepeating(&BindTrayActionRequestOnMainThread), main_thread_task_runner); registry->AddInterface(
diff --git a/ash/public/cpp/BUILD.gn b/ash/public/cpp/BUILD.gn index ee82c1e..7ae5f27b 100644 --- a/ash/public/cpp/BUILD.gn +++ b/ash/public/cpp/BUILD.gn
@@ -151,6 +151,7 @@ "system_tray_focus_observer.h", "tablet_mode.cc", "tablet_mode.h", + "tablet_mode_toggle_observer.h", "touch_uma.cc", "touch_uma.h", "wallpaper_controller.cc",
diff --git a/ash/public/cpp/caption_buttons/frame_caption_button_container_view.cc b/ash/public/cpp/caption_buttons/frame_caption_button_container_view.cc index 8be9d51..b19c9c6e 100644 --- a/ash/public/cpp/caption_buttons/frame_caption_button_container_view.cc +++ b/ash/public/cpp/caption_buttons/frame_caption_button_container_view.cc
@@ -403,7 +403,7 @@ } } else if (sender == close_button_) { frame_->Close(); - if (TabletMode::IsEnabled()) + if (TabletMode::Get()->IsEnabled()) RecordAction(UserMetricsAction("Tablet_WindowCloseFromCaptionButton")); else RecordAction(UserMetricsAction("CloseButton_Clk"));
diff --git a/ash/public/cpp/login_screen.h b/ash/public/cpp/login_screen.h index 920979d..36ba948 100644 --- a/ash/public/cpp/login_screen.h +++ b/ash/public/cpp/login_screen.h
@@ -26,6 +26,12 @@ virtual LoginScreenModel* GetModel() = 0; + // Shows or hides the guest button on the login shelf during OOBE. + virtual void ShowGuestButtonInOobe(bool show) = 0; + + // Shows or hides the parent access button on the login shelf. + virtual void ShowParentAccessButton(bool show) = 0; + // Shows a standalone Parent Access dialog. If |child_account_id| is valid, it // validates the parent access code for that child only, when it is empty it // validates the code for any child signed in the device. |callback| is
diff --git a/ash/public/cpp/manifest.cc b/ash/public/cpp/manifest.cc index 704e1e8..6a1d01e6 100644 --- a/ash/public/cpp/manifest.cc +++ b/ash/public/cpp/manifest.cc
@@ -21,7 +21,6 @@ #include "ash/public/interfaces/night_light_controller.mojom.h" #include "ash/public/interfaces/shelf_integration_test_api.mojom.h" #include "ash/public/interfaces/shutdown.mojom.h" -#include "ash/public/interfaces/tablet_mode.mojom.h" #include "ash/public/interfaces/tray_action.mojom.h" #include "ash/public/interfaces/voice_interaction_controller.mojom.h" #include "ash/public/interfaces/vpn_list.mojom.h" @@ -70,8 +69,8 @@ mojom::KeyboardController, mojom::LocaleUpdateController, mojom::LoginScreen, mojom::MediaController, mojom::NightLightController, mojom::ShutdownController, - mojom::TabletModeController, mojom::TrayAction, - mojom::VoiceInteractionController, mojom::VpnList>()) + mojom::TrayAction, mojom::VoiceInteractionController, + mojom::VpnList>()) .ExposeCapability("test", service_manager::Manifest::InterfaceList< mojom::ShelfIntegrationTestApi>()) .RequireCapability("*", "accessibility")
diff --git a/ash/public/cpp/tablet_mode.cc b/ash/public/cpp/tablet_mode.cc index 91efb38..a0e5be2 100644 --- a/ash/public/cpp/tablet_mode.cc +++ b/ash/public/cpp/tablet_mode.cc
@@ -4,29 +4,26 @@ #include "ash/public/cpp/tablet_mode.h" -#include "base/callback.h" -#include "base/no_destructor.h" +#include "base/logging.h" namespace ash { namespace { - -TabletMode::TabletModeCallback* GetCallback() { - static base::NoDestructor<TabletMode::TabletModeCallback> callback; - return callback.get(); +TabletMode* g_instance = nullptr; } -} // namespace - -// static -void TabletMode::SetCallback(TabletModeCallback callback) { - DCHECK(GetCallback()->is_null() || callback.is_null()); - *GetCallback() = std::move(callback); +TabletMode* TabletMode::Get() { + return g_instance; } -// static -bool TabletMode::IsEnabled() { - return GetCallback()->Run(); +TabletMode::TabletMode() { + DCHECK_EQ(nullptr, g_instance); + g_instance = this; +} + +TabletMode::~TabletMode() { + DCHECK_EQ(this, g_instance); + g_instance = nullptr; } } // namespace ash
diff --git a/ash/public/cpp/tablet_mode.h b/ash/public/cpp/tablet_mode.h index ac59f37..d330e2e 100644 --- a/ash/public/cpp/tablet_mode.h +++ b/ash/public/cpp/tablet_mode.h
@@ -6,25 +6,29 @@ #define ASH_PUBLIC_CPP_TABLET_MODE_H_ #include "ash/public/cpp/ash_public_export.h" -#include "base/callback_forward.h" -#include "base/macros.h" namespace ash { -// A utility to allow code in //ash/public/cpp to access the tablet mode state, -// regardless of what process it's running in. -class TabletMode { - public: - using TabletModeCallback = base::RepeatingCallback<bool(void)>; +class TabletModeToggleObserver; - // Sets the callback to be run by IsEnabled(). - static void ASH_PUBLIC_EXPORT SetCallback(TabletModeCallback callback); +// An interface implemented by Ash that allows Chrome to be informed of changes +// to tablet mode state. +class ASH_PUBLIC_EXPORT TabletMode { + public: + // Returns the singleton instance. + static TabletMode* Get(); + + virtual void SetTabletModeToggleObserver( + TabletModeToggleObserver* observer) = 0; // Returns whether the system is in tablet mode. - static bool IsEnabled(); + virtual bool IsEnabled() const = 0; - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(TabletMode); + virtual void SetEnabledForTest(bool enabled) = 0; + + protected: + TabletMode(); + virtual ~TabletMode(); }; } // namespace ash
diff --git a/ash/public/cpp/tablet_mode_toggle_observer.h b/ash/public/cpp/tablet_mode_toggle_observer.h new file mode 100644 index 0000000..4bd0d20 --- /dev/null +++ b/ash/public/cpp/tablet_mode_toggle_observer.h
@@ -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. + +#ifndef ASH_PUBLIC_CPP_TABLET_MODE_TOGGLE_OBSERVER_H_ +#define ASH_PUBLIC_CPP_TABLET_MODE_TOGGLE_OBSERVER_H_ + +#include "ash/public/cpp/ash_public_export.h" + +namespace ash { + +// A simplified observer which allows Ash to inform Chrome when tablet mode has +// been enabled or disabled. +class ASH_PUBLIC_EXPORT TabletModeToggleObserver { + public: + // Fired after the tablet mode has been toggled. + virtual void OnTabletModeToggled(bool enabled) = 0; + + protected: + virtual ~TabletModeToggleObserver() = default; +}; + +} // namespace ash + +#endif // ASH_PUBLIC_CPP_TABLET_MODE_TOGGLE_OBSERVER_H_
diff --git a/ash/public/interfaces/BUILD.gn b/ash/public/interfaces/BUILD.gn index 4b68ddc..41cb9a7 100644 --- a/ash/public/interfaces/BUILD.gn +++ b/ash/public/interfaces/BUILD.gn
@@ -37,7 +37,6 @@ "night_light_controller.mojom", "shelf_integration_test_api.mojom", "shutdown.mojom", - "tablet_mode.mojom", "tray_action.mojom", "update.mojom", "voice_interaction_controller.mojom",
diff --git a/ash/public/interfaces/login_screen.mojom b/ash/public/interfaces/login_screen.mojom index a194c40..67e5d53 100644 --- a/ash/public/interfaces/login_screen.mojom +++ b/ash/public/interfaces/login_screen.mojom
@@ -24,21 +24,6 @@ // successfully displayed. ShowLoginScreen() => (bool did_show); - // Requests to show error message in the ash lock screen. - // TODO(xiaoyinh): login_attempts is probably not needed from chrome, - // remove it when we start to count the login attempts in ash lock screen. - // |login_attempts|: The number of the login authentication attempts. - // |error_text|: The error text to be shown in lock screen. - // |help_link_text|: The help link to be shown in lock screen. - // |help_topic_id|: The id of the help app topic regarding this error. - ShowErrorMessage(int32 login_attempts, - string error_text, - string help_link_text, - int32 help_topic_id); - - // Requests to close any displayed error messages in ash lock screen. - ClearErrors(); - // Check if the login/lock screen is ready for a password. IsReadyForPassword() => (bool is_ready); @@ -55,15 +40,6 @@ // true the button may still not be visible. SetAllowLoginAsGuest(bool allow_guest); - // Sets if the guest button on the login shelf can be shown during OOBE. - SetShowGuestButtonInOobe(bool show); - - // Sets whether parent access button can be shown on the login shelf. - SetShowParentAccessButton(bool show); - - // Sets whether parent access code input dialog is shown on the lock screen. - SetShowParentAccessDialog(bool show); - // Transitions focus to the shelf area. If |reverse|, focuses the status area. FocusLoginShelf(bool reverse); };
diff --git a/ash/public/interfaces/tablet_mode.mojom b/ash/public/interfaces/tablet_mode.mojom deleted file mode 100644 index 0e98802..0000000 --- a/ash/public/interfaces/tablet_mode.mojom +++ /dev/null
@@ -1,21 +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. - -module ash.mojom; - -// Controls tablet mode state in a client app (e.g. chrome). -interface TabletModeClient { - // Fired after the tablet mode has been toggled. - OnTabletModeToggled(bool enabled); -}; - -// Controls tablet mode state in ash. -interface TabletModeController { - // Sets a client (e.g. chrome). Triggers OnTabletModeToggled() to provide - // the initial state. - SetClient(TabletModeClient client); - - // Enables or disables tablet mode. For testing only. - SetTabletModeEnabledForTesting(bool enabled) => (bool enabled); -};
diff --git a/ash/shelf/login_shelf_view.cc b/ash/shelf/login_shelf_view.cc index d62ae0f..6b14e1d 100644 --- a/ash/shelf/login_shelf_view.cc +++ b/ash/shelf/login_shelf_view.cc
@@ -496,7 +496,7 @@ StartAddUser(); break; case kParentAccess: - Shell::Get()->login_screen_controller()->SetShowParentAccessDialog(true); + LockScreen::Get()->ShowParentAccessDialog(); break; default: NOTREACHED(); @@ -549,12 +549,12 @@ UpdateUi(); } -void LoginShelfView::SetShowParentAccessButton(bool show) { +void LoginShelfView::ShowParentAccessButton(bool show) { show_parent_access_ = show; UpdateUi(); } -void LoginShelfView::SetShowGuestButtonInOobe(bool show) { +void LoginShelfView::ShowGuestButtonInOobe(bool show) { allow_guest_in_oobe_ = show; UpdateUi(); }
diff --git a/ash/shelf/login_shelf_view.h b/ash/shelf/login_shelf_view.h index 56215e63..398426e 100644 --- a/ash/shelf/login_shelf_view.h +++ b/ash/shelf/login_shelf_view.h
@@ -90,11 +90,11 @@ void SetAllowLoginAsGuest(bool allow_guest); // Sets whether parent access button can be shown on the login shelf. - void SetShowParentAccessButton(bool show); + void ShowParentAccessButton(bool show); // Sets if the guest button on the login shelf can be shown during gaia // signin screen. - void SetShowGuestButtonInOobe(bool show); + void ShowGuestButtonInOobe(bool show); // Sets whether users can be added from the login screen. void SetAddUserButtonEnabled(bool enable_add_user);
diff --git a/ash/shelf/login_shelf_view_unittest.cc b/ash/shelf/login_shelf_view_unittest.cc index cfec9bf..e23ebd26 100644 --- a/ash/shelf/login_shelf_view_unittest.cc +++ b/ash/shelf/login_shelf_view_unittest.cc
@@ -525,7 +525,7 @@ TEST_F(LoginShelfViewTest, ParentAccessButtonVisibility) { // Parent access button should only be visible on lock screen. - Shell::Get()->login_screen_controller()->SetShowParentAccessButton(true); + Shell::Get()->login_screen_controller()->ShowParentAccessButton(true); NotifySessionStateChanged(SessionState::LOGIN_PRIMARY); EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown, @@ -556,12 +556,12 @@ EXPECT_TRUE( ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut})); - Shell::Get()->login_screen_controller()->SetShowParentAccessButton(true); + Shell::Get()->login_screen_controller()->ShowParentAccessButton(true); EXPECT_TRUE( ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut, LoginShelfView::kParentAccess})); - Shell::Get()->login_screen_controller()->SetShowParentAccessButton(false); + Shell::Get()->login_screen_controller()->ShowParentAccessButton(false); EXPECT_TRUE( ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut})); }
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc index 1db757b..69ce386d 100644 --- a/ash/shelf/shelf_layout_manager.cc +++ b/ash/shelf/shelf_layout_manager.cc
@@ -699,6 +699,16 @@ is_home_launcher_shown_ = shown; is_home_launcher_target_position_shown_ = false; MaybeUpdateShelfBackground(AnimationChangeType::IMMEDIATE); + + // Cancel ongoing drag when self is hidden on home screen to prevent + // visibility issues. + if (shown && drag_status_ != kDragNone && + !Shell::Get() + ->home_screen_controller() + ->delegate() + ->ShouldShowShelfOnHomeScreen()) { + CancelDrag(); + } } void ShelfLayoutManager::OnWindowActivated(ActivationReason reason,
diff --git a/ash/test/ash_test_helper.cc b/ash/test/ash_test_helper.cc index b545db8..e87e1da 100644 --- a/ash/test/ash_test_helper.cc +++ b/ash/test/ash_test_helper.cc
@@ -111,7 +111,8 @@ bluez_dbus_manager_initialized_ = true; } - chromeos::PowerManagerClient::InitializeFake(); + if (!chromeos::PowerManagerClient::Get()) + chromeos::PowerManagerClient::InitializeFake(); if (!chromeos::PowerPolicyController::IsInitialized()) { chromeos::PowerPolicyController::Initialize(
diff --git a/ash/wm/tablet_mode/tablet_mode_controller.cc b/ash/wm/tablet_mode/tablet_mode_controller.cc index 8ccb240..e7fe0a7 100644 --- a/ash/wm/tablet_mode/tablet_mode_controller.cc +++ b/ash/wm/tablet_mode/tablet_mode_controller.cc
@@ -12,6 +12,7 @@ #include "ash/public/cpp/ash_switches.h" #include "ash/public/cpp/fps_counter.h" #include "ash/public/cpp/tablet_mode.h" +#include "ash/public/cpp/tablet_mode_toggle_observer.h" #include "ash/root_window_controller.h" #include "ash/shell.h" #include "ash/shell_delegate.h" @@ -109,7 +110,7 @@ kNoisyMagnitudeDeviation; } -bool IsEnabled() { +bool ShouldInitTabletModeController() { return base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kAshEnableTabletMode); } @@ -171,10 +172,7 @@ TabletModeController::TabletModeController() : event_blocker_(new InternalInputDevicesEventBlocker), tablet_mode_usage_interval_start_time_(base::Time::Now()), - tick_clock_(base::DefaultTickClock::GetInstance()), - binding_(this), - scoped_session_observer_(this), - weak_factory_(this) { + tick_clock_(base::DefaultTickClock::GetInstance()) { Shell::Get()->AddShellObserver(this); base::RecordAction(base::UserMetricsAction("Touchview_Initially_Disabled")); @@ -182,7 +180,7 @@ // unavailable. This will require refactoring // IsTabletModeWindowManagerEnabled to check for the existence of the // controller. - if (IsEnabled()) { + if (ShouldInitTabletModeController()) { Shell::Get()->window_tree_host_manager()->AddObserver(this); AccelerometerReader::GetInstance()->AddObserver(this); ui::InputDeviceManager::GetInstance()->AddObserver(this); @@ -199,10 +197,6 @@ power_manager_client->AddObserver(this); power_manager_client->GetSwitchStates(base::BindOnce( &TabletModeController::OnGetSwitchStates, weak_factory_.GetWeakPtr())); - - TabletMode::SetCallback(base::BindRepeating( - &TabletModeController::IsTabletModeWindowManagerEnabled, - base::Unretained(this))); } TabletModeController::~TabletModeController() { @@ -222,7 +216,7 @@ Shell::Get()->RemoveShellObserver(this); Shell::Get()->kiosk_next_shell_controller()->RemoveObserver(this); - if (IsEnabled()) { + if (ShouldInitTabletModeController()) { Shell::Get()->window_tree_host_manager()->RemoveObserver(this); AccelerometerReader::GetInstance()->RemoveObserver(this); ui::InputDeviceManager::GetInstance()->RemoveObserver(this); @@ -231,8 +225,6 @@ for (auto& observer : tablet_mode_observers_) observer.OnTabletControllerDestroyed(); - - TabletMode::SetCallback(TabletMode::TabletModeCallback()); } // TODO(jcliang): Hide or remove EnableTabletModeWindowManager @@ -273,8 +265,8 @@ } state_ = State::kInTabletMode; - if (client_) // Null at startup and in tests. - client_->OnTabletModeToggled(true); + if (toggle_observer_) // Null at startup and in tests. + toggle_observer_->OnTabletModeToggled(true); VLOG(1) << "Enter tablet mode."; } else { state_ = State::kExitingTabletMode; @@ -292,8 +284,8 @@ observer.OnTabletModeEnded(); state_ = State::kInClamshellMode; - if (client_) // Null at startup and in tests. - client_->OnTabletModeToggled(false); + if (toggle_observer_) // Null at startup and in tests. + toggle_observer_->OnTabletModeToggled(false); VLOG(1) << "Exit tablet mode."; } @@ -309,12 +301,6 @@ tablet_mode_window_manager_->AddWindow(window); } -void TabletModeController::BindRequest( - mojom::TabletModeControllerRequest request) { - DCHECK(!binding_.is_bound()) << "Only one client allowed."; - binding_.Bind(std::move(request)); -} - void TabletModeController::AddObserver(TabletModeObserver* observer) { tablet_mode_observers_.AddObserver(observer); } @@ -337,10 +323,6 @@ return event_blocker_->should_be_blocked(); } -void TabletModeController::FlushForTesting() { - binding_.FlushForTesting(); -} - bool TabletModeController::TriggerRecordLidAngleTimerForTesting() { if (!record_lid_angle_timer_.IsRunning()) return false; @@ -380,6 +362,28 @@ window->layer()->GetCompositor(), entering_tablet_mode); } +void TabletModeController::SetTabletModeToggleObserver( + TabletModeToggleObserver* observer) { + DCHECK(observer); + DCHECK(!toggle_observer_); + toggle_observer_ = observer; +} + +bool TabletModeController::IsEnabled() const { + return IsTabletModeWindowManagerEnabled(); +} + +void TabletModeController::SetEnabledForTest(bool enabled) { + // Disable Accelerometer and PowerManagerClient observers to prevent possible + // tablet mode overrides. It won't be possible to physically switch to/from + // tablet mode after calling this function. This is needed for tests that + // run on DUTs and require switching to/back tablet mode in runtime, like some + // ARC++ Tast tests. + AccelerometerReader::GetInstance()->RemoveObserver(this); + chromeos::PowerManagerClient::Get()->RemoveObserver(this); + EnableTabletModeWindowManager(enabled); +} + void TabletModeController::OnShellInitialized() { force_ui_mode_ = GetTabletMode(); if (force_ui_mode_ == UiMode::kTabletMode) @@ -519,7 +523,7 @@ // Stop listening to any incoming input device changes during suspend as the // input devices may be removed during suspend and cause the device enter/exit // tablet mode unexpectedly. - if (IsEnabled()) { + if (ShouldInitTabletModeController()) { ui::InputDeviceManager::GetInstance()->RemoveObserver(this); bluetooth_devices_observer_.reset(); } @@ -530,7 +534,7 @@ tablet_mode_usage_interval_start_time_ = base::Time::Now(); // Start listening to the input device changes again. - if (IsEnabled()) { + if (ShouldInitTabletModeController()) { bluetooth_devices_observer_ = std::make_unique<BluetoothDevicesObserver>(base::BindRepeating( &TabletModeController::OnBluetoothAdapterOrDeviceChanged, @@ -748,26 +752,6 @@ return TABLET_MODE_INTERVAL_INACTIVE; } -void TabletModeController::SetClient(mojom::TabletModeClientPtr client) { - client_ = std::move(client); - client_->OnTabletModeToggled(IsTabletModeWindowManagerEnabled()); -} - -// Used for testing. Called via Mojo. -void TabletModeController::SetTabletModeEnabledForTesting( - bool enabled, - SetTabletModeEnabledForTestingCallback callback) { - // Disable Accelerometer and PowerManagerClient observers to prevent possible - // tablet mode overrides. It won't be possible to physically switch to/from - // tablet mode after calling this function. This is needed for tests that - // run on DUTs and require switching to/back tablet mode in runtime, like some - // ARC++ Tast tests. - AccelerometerReader::GetInstance()->RemoveObserver(this); - chromeos::PowerManagerClient::Get()->RemoveObserver(this); - EnableTabletModeWindowManager(enabled); - std::move(callback).Run(IsTabletModeWindowManagerEnabled()); -} - bool TabletModeController::AllowUiModeChange() const { return force_ui_mode_ == UiMode::kNone && !kiosk_next_enabled_; }
diff --git a/ash/wm/tablet_mode/tablet_mode_controller.h b/ash/wm/tablet_mode/tablet_mode_controller.h index ac41bc8..4893d59 100644 --- a/ash/wm/tablet_mode/tablet_mode_controller.h +++ b/ash/wm/tablet_mode/tablet_mode_controller.h
@@ -13,7 +13,7 @@ #include "ash/bluetooth_devices_observer.h" #include "ash/display/window_tree_host_manager.h" #include "ash/kiosk_next/kiosk_next_shell_observer.h" -#include "ash/public/interfaces/tablet_mode.mojom.h" +#include "ash/public/cpp/tablet_mode.h" #include "ash/session/session_observer.h" #include "ash/shell_observer.h" #include "base/compiler_specific.h" @@ -24,8 +24,6 @@ #include "base/time/time.h" #include "base/timer/timer.h" #include "chromeos/dbus/power/power_manager_client.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "mojo/public/cpp/bindings/interface_ptr_set.h" #include "ui/aura/window_observer.h" #include "ui/aura/window_occlusion_tracker.h" #include "ui/compositor/layer_animation_observer.h" @@ -65,7 +63,7 @@ class ASH_EXPORT TabletModeController : public AccelerometerReader::Observer, public chromeos::PowerManagerClient::Observer, - public mojom::TabletModeController, + public TabletMode, public ShellObserver, public WindowTreeHostManager::Observer, public SessionObserver, @@ -107,9 +105,6 @@ // If the tablet mode is not enabled no action will be performed. void AddWindow(aura::Window* window); - // Binds the mojom::TabletModeController interface request to this object. - void BindRequest(mojom::TabletModeControllerRequest request); - void AddObserver(TabletModeObserver* observer); void RemoveObserver(TabletModeObserver* observer); @@ -119,9 +114,6 @@ // Whether the events from the internal mouse/keyboard are blocked. bool AreInternalInputDeviceEventsBlocked() const; - // Flushes the mojo message pipe to chrome. - void FlushForTesting(); - // If |record_lid_angle_timer_| is running, invokes its task and returns true. // Otherwise, returns false. bool TriggerRecordLidAngleTimerForTesting() WARN_UNUSED_RESULT; @@ -129,6 +121,11 @@ // Called from a WindowState object when the bounds of |window| changes. void MaybeObserveBoundsAnimation(aura::Window* window); + // TabletMode: + void SetTabletModeToggleObserver(TabletModeToggleObserver* observer) override; + bool IsEnabled() const override; + void SetEnabledForTest(bool enabled) override; + // ShellObserver: void OnShellInitialized() override; @@ -238,12 +235,6 @@ // otherwise returns TABLET_MODE_INTERNAL_INACTIVE. TabletModeIntervalType CurrentTabletModeIntervalType(); - // mojom::TabletModeController: - void SetClient(mojom::TabletModeClientPtr client) override; - void SetTabletModeEnabledForTesting( - bool enabled, - SetTabletModeEnabledForTestingCallback callback) override; - // Checks whether we want to allow change the current ui mode to tablet mode // or clamshell mode. This returns false if the user set a flag for the // software to behave in a certain way regardless of configuration. @@ -351,11 +342,9 @@ gfx::Vector3dF base_smoothed_; gfx::Vector3dF lid_smoothed_; - // Binding for the TabletModeController interface. - mojo::Binding<mojom::TabletModeController> binding_; - - // Client interface (e.g. in chrome). - mojom::TabletModeClientPtr client_; + // A simplified observer that only gets notified of entering or exiting tablet + // mode. + TabletModeToggleObserver* toggle_observer_ = nullptr; // Tracks whether a flag is used to force ui mode. UiMode force_ui_mode_ = UiMode::kNone; @@ -365,7 +354,7 @@ // Calls RecordLidAngle() periodically. base::RepeatingTimer record_lid_angle_timer_; - ScopedSessionObserver scoped_session_observer_; + ScopedSessionObserver scoped_session_observer_{this}; std::unique_ptr<aura::WindowOcclusionTracker::ScopedPause> occlusion_tracker_pauser_; @@ -385,7 +374,7 @@ base::ObserverList<TabletModeObserver>::Unchecked tablet_mode_observers_; - base::WeakPtrFactory<TabletModeController> weak_factory_; + base::WeakPtrFactory<TabletModeController> weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(TabletModeController); };
diff --git a/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc b/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc index 159052a..e6c8b35 100644 --- a/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc +++ b/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc
@@ -665,20 +665,26 @@ // Tests that when a TabletModeController is created that cached tablet mode // state will trigger a mode update. -TEST_F(TabletModeControllerTest, InitializedWhileTabletModeSwitchOn) { - base::RunLoop().RunUntilIdle(); - power_manager_client()->SetTabletMode( - chromeos::PowerManagerClient::TabletMode::ON, base::TimeTicks::Now()); +class TabletModeControllerInitedFromPowerManagerClientTest + : public TabletModeControllerTest { + public: + TabletModeControllerInitedFromPowerManagerClientTest() = default; + ~TabletModeControllerInitedFromPowerManagerClientTest() override = default; - // Clear the callback that was set by the original TabletModeController. - TabletMode::SetCallback({}); + void SetUp() override { + chromeos::PowerManagerClient::InitializeFake(); + power_manager_client()->SetTabletMode( + chromeos::PowerManagerClient::TabletMode::ON, base::TimeTicks::Now()); + TabletModeControllerTest::SetUp(); + } +}; - TabletModeController controller; - controller.OnShellInitialized(); - EXPECT_FALSE(controller.IsTabletModeWindowManagerEnabled()); +TEST_F(TabletModeControllerInitedFromPowerManagerClientTest, + InitializedWhileTabletModeSwitchOn) { + EXPECT_FALSE(tablet_mode_controller()->IsTabletModeWindowManagerEnabled()); // PowerManagerClient callback is a posted task. base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(controller.IsTabletModeWindowManagerEnabled()); + EXPECT_TRUE(tablet_mode_controller()->IsTabletModeWindowManagerEnabled()); } TEST_F(TabletModeControllerTest, RestoreAfterExit) {
diff --git a/ash/wm/window_mirror_view.cc b/ash/wm/window_mirror_view.cc index 7006a4c..fc988f4 100644 --- a/ash/wm/window_mirror_view.cc +++ b/ash/wm/window_mirror_view.cc
@@ -102,17 +102,14 @@ target_ = GetWidget()->GetNativeWindow(); target_->TrackOcclusionState(); - force_occlusion_tracker_visible_.reset(); - env_observer_.RemoveAll(); - - // Wait for window-occlusion tracker to be running before forcing visibility. - // This is done to minimize the amount of work during the initial animation - // when entering overview. In particular, telling the remote client it is - // visible is likely to result in a fair amount of work. - if (aura::Env::GetInstance()->GetWindowOcclusionTracker()->IsPaused()) - env_observer_.Add(aura::Env::GetInstance()); - else - ForceVisibilityAndOcclusion(); + if (source_) { + // Force the occlusion tracker to treat the source as visible. + force_occlusion_tracker_visible_ = + std::make_unique<aura::WindowOcclusionTracker::ScopedForceVisible>( + source_); + } else { + force_occlusion_tracker_visible_.reset(); + } } void WindowMirrorView::RemovedFromWidget() { @@ -163,26 +160,5 @@ return client_view->ConvertRectToWidget(client_view->GetLocalBounds()); } -void WindowMirrorView::ForceVisibilityAndOcclusion() { - // Force the occlusion tracker to treat the source (or the desk container if - // source_ is on an inactive desk) as visible. - aura::Window* window_to_force_visible = source_; - aura::Window* desk_container = - desks_util::GetDeskContainerForContext(source_); - if (desk_container && !desks_util::IsActiveDeskContainer(desk_container)) - window_to_force_visible = desk_container; - - force_occlusion_tracker_visible_ = - std::make_unique<aura::WindowOcclusionTracker::ScopedForceVisible>( - window_to_force_visible); -} - -void WindowMirrorView::OnWindowOcclusionTrackingResumed() { - // Skip if the source_ has already been removed. - if (source_) - ForceVisibilityAndOcclusion(); - env_observer_.RemoveAll(); -} - } // namespace wm } // namespace ash
diff --git a/ash/wm/window_mirror_view.h b/ash/wm/window_mirror_view.h index d682a42..cdd0062 100644 --- a/ash/wm/window_mirror_view.h +++ b/ash/wm/window_mirror_view.h
@@ -9,9 +9,6 @@ #include "ash/ash_export.h" #include "base/macros.h" -#include "base/scoped_observer.h" -#include "ui/aura/env.h" -#include "ui/aura/env_observer.h" #include "ui/aura/window_observer.h" #include "ui/aura/window_occlusion_tracker.h" #include "ui/views/view.h" @@ -29,8 +26,7 @@ // A view that mirrors the client area of a single (source) window. class ASH_EXPORT WindowMirrorView : public views::View, - public aura::WindowObserver, - public aura::EnvObserver { + public aura::WindowObserver { public: WindowMirrorView(aura::Window* source, bool trilinear_filtering_on_init); ~WindowMirrorView() override; @@ -63,11 +59,6 @@ // coordinate space. gfx::Rect GetClientAreaBounds() const; - void ForceVisibilityAndOcclusion(); - - // aura::EnvObserver: - void OnWindowOcclusionTrackingResumed() override; - // The original window that is being represented by |this|. aura::Window* source_; @@ -85,8 +76,6 @@ std::unique_ptr<aura::WindowOcclusionTracker::ScopedForceVisible> force_occlusion_tracker_visible_; - ScopedObserver<aura::Env, aura::EnvObserver> env_observer_{this}; - DISALLOW_COPY_AND_ASSIGN(WindowMirrorView); };
diff --git a/ash/wm/workspace/multi_window_resize_controller_unittest.cc b/ash/wm/workspace/multi_window_resize_controller_unittest.cc index 9edb6f7..5b6fd5c7 100644 --- a/ash/wm/workspace/multi_window_resize_controller_unittest.cc +++ b/ash/wm/workspace/multi_window_resize_controller_unittest.cc
@@ -320,14 +320,38 @@ gfx::Rect bounds(resize_widget()->GetWindowBoundsInScreen()); generator->MoveMouseTo(bounds.x() + 1, bounds.y() + 1); generator->PressLeftButton(); + + // Test that when drag starts, drag details are created for each window. + EXPECT_TRUE(wm::GetWindowState(w1.get())->is_dragged()); + EXPECT_TRUE(wm::GetWindowState(w2.get())->is_dragged()); + EXPECT_TRUE(wm::GetWindowState(w3.get())->is_dragged()); + // Test the window components for each window. + EXPECT_EQ(wm::GetWindowState(w1.get())->drag_details()->window_component, + HTRIGHT); + EXPECT_EQ(wm::GetWindowState(w2.get())->drag_details()->window_component, + HTLEFT); + EXPECT_EQ(wm::GetWindowState(w3.get())->drag_details()->window_component, + HTLEFT); + generator->MoveMouseTo(bounds.x() + 11, bounds.y() + 10); + // Drag details should exist during dragging. + EXPECT_TRUE(wm::GetWindowState(w1.get())->is_dragged()); + EXPECT_TRUE(wm::GetWindowState(w2.get())->is_dragged()); + EXPECT_TRUE(wm::GetWindowState(w3.get())->is_dragged()); + EXPECT_TRUE(HasTarget(w3.get())); // Release the mouse. The resizer should still be visible and a subsequent // press should not trigger a DCHECK. generator->ReleaseLeftButton(); EXPECT_TRUE(IsShowing()); + + // Test that drag details are correctly deleted after dragging. + EXPECT_FALSE(wm::GetWindowState(w1.get())->is_dragged()); + EXPECT_FALSE(wm::GetWindowState(w2.get())->is_dragged()); + EXPECT_FALSE(wm::GetWindowState(w3.get())->is_dragged()); + generator->PressLeftButton(); }
diff --git a/ash/wm/workspace/workspace_window_resizer.cc b/ash/wm/workspace/workspace_window_resizer.cc index 8d55bda..b3def8d 100644 --- a/ash/wm/workspace/workspace_window_resizer.cc +++ b/ash/wm/workspace/workspace_window_resizer.cc
@@ -487,6 +487,7 @@ ::wm::ConvertPointToScreen(GetTarget()->parent(), &last_mouse_location_in_screen); window_state()->OnCompleteDrag(last_mouse_location_in_screen); + EndDragForAttachedWindows(/*revert_drag=*/false); if (!did_move_or_resize_) return; @@ -550,6 +551,7 @@ ::wm::ConvertPointToScreen(GetTarget()->parent(), &last_mouse_location_in_screen); window_state()->OnRevertDrag(last_mouse_location_in_screen); + EndDragForAttachedWindows(/*revert_drag=*/true); window_state()->set_bounds_changed_by_user(initial_bounds_changed_by_user_); snap_phantom_window_controller_.reset(); @@ -687,6 +689,7 @@ pre_drag_window_bounds_ = window_state->window()->bounds(); window_state->OnDragStarted(details().window_component); + StartDragForAttachedWindows(); } void WorkspaceWindowResizer::LayoutAttachedWindows(gfx::Rect* bounds) { @@ -1195,4 +1198,43 @@ } } +void WorkspaceWindowResizer::StartDragForAttachedWindows() { + if (attached_windows_.empty()) + return; + + // The component of the attached windows is always the opposite component of + // the main window. + const int main_window_component = details().window_component; + DCHECK(main_window_component == HTRIGHT || main_window_component == HTBOTTOM); + + int window_component = HTNOWHERE; + if (main_window_component == HTRIGHT) + window_component = HTLEFT; + else if (main_window_component == HTBOTTOM) + window_component = HTTOP; + DCHECK(window_component == HTLEFT || window_component == HTTOP); + + for (auto* window : attached_windows_) { + wm::WindowState* window_state = wm::GetWindowState(window); + window_state->CreateDragDetails(details().initial_location_in_parent, + window_component, + ::wm::WINDOW_MOVE_SOURCE_MOUSE); + window_state->OnDragStarted(window_component); + } +} + +void WorkspaceWindowResizer::EndDragForAttachedWindows(bool revert_drag) { + if (attached_windows_.empty()) + return; + + for (auto* window : attached_windows_) { + wm::WindowState* window_state = wm::GetWindowState(window); + if (revert_drag) + window_state->OnRevertDrag(last_mouse_location_); + else + window_state->OnCompleteDrag(last_mouse_location_); + window_state->DeleteDragDetails(); + } +} + } // namespace ash
diff --git a/ash/wm/workspace/workspace_window_resizer.h b/ash/wm/workspace/workspace_window_resizer.h index 15afd7d..54b854a 100644 --- a/ash/wm/workspace/workspace_window_resizer.h +++ b/ash/wm/workspace/workspace_window_resizer.h
@@ -166,6 +166,10 @@ void SetWindowStateTypeFromGesture(aura::Window* window, WindowStateType new_state_type); + // Start/End drag for attached windows if there is any. + void StartDragForAttachedWindows(); + void EndDragForAttachedWindows(bool revert_drag); + wm::WindowState* window_state() { return window_state_; } const std::vector<aura::Window*> attached_windows_;
diff --git a/base/BUILD.gn b/base/BUILD.gn index c7f96f21..ba25074 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -2961,6 +2961,7 @@ "files/file_descriptor_watcher_posix_unittest.cc", "fuchsia/file_utils_unittest.cc", "fuchsia/filtered_service_directory_unittest.cc", + "fuchsia/scoped_service_binding_unittest.cc", "fuchsia/service_directory_test_base.cc", "fuchsia/service_directory_test_base.h", "fuchsia/service_directory_unittest.cc",
diff --git a/base/fuchsia/scoped_service_binding.h b/base/fuchsia/scoped_service_binding.h index efdc30d8..efbd7346 100644 --- a/base/fuchsia/scoped_service_binding.h +++ b/base/fuchsia/scoped_service_binding.h
@@ -51,6 +51,57 @@ DISALLOW_COPY_AND_ASSIGN(ScopedServiceBinding); }; +// Scoped service binding which allows only a single client to be connected +// at any time. By default a new connection will disconnect an existing client. +enum class ScopedServiceBindingPolicy { kPreferNew, kPreferExisting }; + +template <typename Interface, + ScopedServiceBindingPolicy Policy = + ScopedServiceBindingPolicy::kPreferNew> +class ScopedSingleClientServiceBinding { + public: + // |service_directory| and |impl| must outlive the binding. + ScopedSingleClientServiceBinding(ServiceDirectory* service_directory, + Interface* impl) + : directory_(service_directory), binding_(impl) { + directory_->AddService(BindRepeating( + &ScopedSingleClientServiceBinding::BindClient, Unretained(this))); + } + + ~ScopedSingleClientServiceBinding() { + directory_->RemoveService(Interface::Name_); + } + + typename Interface::EventSender_& events() { return binding_.events(); } + + void SetOnLastClientCallback(base::OnceClosure on_last_client_callback) { + on_last_client_callback_ = std::move(on_last_client_callback); + binding_.set_error_handler(fit::bind_member( + this, &ScopedSingleClientServiceBinding::OnBindingEmpty)); + } + + bool has_clients() const { return binding_.is_bound(); } + + private: + void BindClient(fidl::InterfaceRequest<Interface> request) { + if (Policy == ScopedServiceBindingPolicy::kPreferExisting && + binding_.is_bound()) + return; + binding_.Bind(std::move(request)); + } + + void OnBindingEmpty() { + binding_.set_error_handler(nullptr); + std::move(on_last_client_callback_).Run(); + } + + ServiceDirectory* const directory_; + fidl::Binding<Interface> binding_; + base::OnceClosure on_last_client_callback_; + + DISALLOW_COPY_AND_ASSIGN(ScopedSingleClientServiceBinding); +}; + } // namespace fuchsia } // namespace base
diff --git a/base/fuchsia/scoped_service_binding_unittest.cc b/base/fuchsia/scoped_service_binding_unittest.cc new file mode 100644 index 0000000..3858ae2b --- /dev/null +++ b/base/fuchsia/scoped_service_binding_unittest.cc
@@ -0,0 +1,94 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/fuchsia/scoped_service_binding.h" + +#include "base/fuchsia/service_directory_test_base.h" +#include "base/run_loop.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace base { +namespace fuchsia { + +class ScopedServiceBindingTest : public ServiceDirectoryTestBase {}; + +// Verifies that ScopedServiceBinding allows connection more than once. +TEST_F(ScopedServiceBindingTest, ConnectTwice) { + auto stub = public_service_directory_client_ + ->ConnectToService<testfidl::TestInterface>(); + auto stub2 = public_service_directory_client_ + ->ConnectToService<testfidl::TestInterface>(); + VerifyTestInterface(&stub, ZX_OK); + VerifyTestInterface(&stub2, ZX_OK); +} + +// Verify that if we connect twice to a prefer-new bound service, the existing +// connection gets closed. +TEST_F(ScopedServiceBindingTest, SingleClientPreferNew) { + // Teardown the default multi-client binding and create a prefer-new one. + service_binding_ = nullptr; + ScopedSingleClientServiceBinding<testfidl::TestInterface, + ScopedServiceBindingPolicy::kPreferNew> + binding(service_directory_.get(), &test_service_); + + // Connect the first client, and verify that it is functional. + auto existing_client = public_service_directory_client_ + ->ConnectToService<testfidl::TestInterface>(); + VerifyTestInterface(&existing_client, ZX_OK); + + // Connect the second client, so the existing one should be disconnected and + // the new should be functional. + auto new_client = public_service_directory_client_ + ->ConnectToService<testfidl::TestInterface>(); + RunLoop().RunUntilIdle(); + EXPECT_FALSE(existing_client); + VerifyTestInterface(&new_client, ZX_OK); +} + +// Verify that if we connect twice to a prefer-existing bound service, the new +// connection gets closed. +TEST_F(ScopedServiceBindingTest, SingleClientPreferExisting) { + // Teardown the default multi-client binding and create a prefer-existing one. + service_binding_ = nullptr; + ScopedSingleClientServiceBinding<testfidl::TestInterface, + ScopedServiceBindingPolicy::kPreferExisting> + binding(service_directory_.get(), &test_service_); + + // Connect the first client, and verify that it is functional. + auto existing_client = public_service_directory_client_ + ->ConnectToService<testfidl::TestInterface>(); + VerifyTestInterface(&existing_client, ZX_OK); + + // Connect the second client, then verify that the it gets closed and the + // existing one remains functional. + auto new_client = public_service_directory_client_ + ->ConnectToService<testfidl::TestInterface>(); + RunLoop().RunUntilIdle(); + EXPECT_FALSE(new_client); + VerifyTestInterface(&existing_client, ZX_OK); +} + +// Verify that the default single-client binding policy is prefer-new. +TEST_F(ScopedServiceBindingTest, SingleClientDefaultIsPreferNew) { + // Teardown the default multi-client binding and create a prefer-new one. + service_binding_ = nullptr; + ScopedSingleClientServiceBinding<testfidl::TestInterface> binding( + service_directory_.get(), &test_service_); + + // Connect the first client, and verify that it is functional. + auto existing_client = public_service_directory_client_ + ->ConnectToService<testfidl::TestInterface>(); + VerifyTestInterface(&existing_client, ZX_OK); + + // Connect the second client, so the existing one should be disconnected and + // the new should be functional. + auto new_client = public_service_directory_client_ + ->ConnectToService<testfidl::TestInterface>(); + RunLoop().RunUntilIdle(); + EXPECT_FALSE(existing_client); + VerifyTestInterface(&new_client, ZX_OK); +} + +} // namespace fuchsia +} // namespace base
diff --git a/base/fuchsia/service_directory_test_base.cc b/base/fuchsia/service_directory_test_base.cc index 35fc351a..050e1a13 100644 --- a/base/fuchsia/service_directory_test_base.cc +++ b/base/fuchsia/service_directory_test_base.cc
@@ -7,10 +7,16 @@ #include <lib/fdio/directory.h> #include <utility> +#include "base/bind.h" +#include "base/test/test_timeouts.h" + namespace base { namespace fuchsia { -ServiceDirectoryTestBase::ServiceDirectoryTestBase() { +ServiceDirectoryTestBase::ServiceDirectoryTestBase() + : run_timeout_(TestTimeouts::action_timeout(), BindRepeating([]() { + ADD_FAILURE() << "Run() timed out."; + })) { // TODO(https://crbug.com/920920): Remove the ServiceDirectory's implicit // "public" sub-directory and update this setup logic. @@ -61,7 +67,7 @@ fidl::InterfacePtr<testfidl::TestInterface>* stub, zx_status_t expected_error) { // Call the service and wait for response. - base::RunLoop run_loop; + RunLoop run_loop; zx_status_t actual_error = ZX_OK; stub->set_error_handler([&run_loop, &actual_error](zx_status_t status) {
diff --git a/base/fuchsia/service_directory_test_base.h b/base/fuchsia/service_directory_test_base.h index 8099b830..900b008 100644 --- a/base/fuchsia/service_directory_test_base.h +++ b/base/fuchsia/service_directory_test_base.h
@@ -5,7 +5,7 @@ #ifndef BASE_FUCHSIA_SERVICE_DIRECTORY_TEST_BASE_H_ #define BASE_FUCHSIA_SERVICE_DIRECTORY_TEST_BASE_H_ -#include <lib/zx/channel.h> +#include <zircon/types.h> #include <memory> #include "base/fuchsia/scoped_service_binding.h" @@ -13,6 +13,7 @@ #include "base/fuchsia/test_interface_impl.h" #include "base/fuchsia/testfidl/cpp/fidl.h" #include "base/message_loop/message_loop.h" +#include "base/run_loop.h" #include "testing/gtest/include/gtest/gtest.h" namespace base { @@ -27,6 +28,8 @@ zx_status_t expected_error); protected: + const RunLoop::ScopedRunTimeoutForTest run_timeout_; + MessageLoopForIO message_loop_; std::unique_ptr<ServiceDirectory> service_directory_;
diff --git a/base/fuchsia/service_directory_unittest.cc b/base/fuchsia/service_directory_unittest.cc index 8bf9688..505ad7d 100644 --- a/base/fuchsia/service_directory_unittest.cc +++ b/base/fuchsia/service_directory_unittest.cc
@@ -4,17 +4,10 @@ #include "base/fuchsia/service_directory.h" -#include <lib/fdio/fdio.h> -#include <lib/zx/channel.h> #include <utility> -#include "base/bind.h" #include "base/fuchsia/service_directory_test_base.h" -#include "base/location.h" #include "base/run_loop.h" -#include "base/task_runner.h" -#include "base/test/test_timeouts.h" -#include "base/threading/thread_task_runner_handle.h" #include "testing/gtest/include/gtest/gtest.h" namespace base { @@ -30,19 +23,9 @@ ->ConnectToService<testfidl::TestInterface>(); VerifyTestInterface(&stub, ZX_OK); - base::RunLoop run_loop; + RunLoop run_loop; service_binding_->SetOnLastClientCallback(run_loop.QuitClosure()); - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, - base::BindOnce( - [](base::RunLoop* run_loop) { - ADD_FAILURE(); - run_loop->Quit(); - }, - &run_loop), - TestTimeouts::action_timeout()); - stub.Unbind(); run_loop.Run(); }
diff --git a/base/process/process_metrics.h b/base/process/process_metrics.h index ec40c3d..a50f638 100644 --- a/base/process/process_metrics.h +++ b/base/process/process_metrics.h
@@ -106,23 +106,6 @@ BASE_EXPORT TotalsSummary GetTotalsSummary() const; #endif -#if defined(OS_MACOSX) - struct TaskVMInfo { - // Only available on macOS 10.12+. - // Anonymous, non-discardable memory, including non-volatile IOKit. - // Measured in bytes. - uint64_t phys_footprint = 0; - - // Anonymous, non-discardable, non-compressed memory, excluding IOKit. - // Measured in bytes. - uint64_t internal = 0; - - // Compressed memory measured in bytes. - uint64_t compressed = 0; - }; - TaskVMInfo GetTaskVMInfo() const; -#endif - // Returns the percentage of time spent executing, across all threads of the // process, in the interval since the last time the method was called. Since // this considers the total execution time across all threads in a process,
diff --git a/base/process/process_metrics_mac.cc b/base/process/process_metrics_mac.cc index cbb5e93..d05e1228 100644 --- a/base/process/process_metrics_mac.cc +++ b/base/process/process_metrics_mac.cc
@@ -25,37 +25,6 @@ namespace { -#if !defined(MAC_OS_X_VERSION_10_11) || \ - MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_11 -// The |phys_footprint| field was introduced in 10.11. -struct ChromeTaskVMInfo { - mach_vm_size_t virtual_size; - integer_t region_count; - integer_t page_size; - mach_vm_size_t resident_size; - mach_vm_size_t resident_size_peak; - mach_vm_size_t device; - mach_vm_size_t device_peak; - mach_vm_size_t internal; - mach_vm_size_t internal_peak; - mach_vm_size_t external; - mach_vm_size_t external_peak; - mach_vm_size_t reusable; - mach_vm_size_t reusable_peak; - mach_vm_size_t purgeable_volatile_pmap; - mach_vm_size_t purgeable_volatile_resident; - mach_vm_size_t purgeable_volatile_virtual; - mach_vm_size_t compressed; - mach_vm_size_t compressed_peak; - mach_vm_size_t compressed_lifetime; - mach_vm_size_t phys_footprint; -}; -#else -using ChromeTaskVMInfo = task_vm_info; -#endif // MAC_OS_X_VERSION_10_11 -mach_msg_type_number_t ChromeTaskVMInfoCount = - sizeof(ChromeTaskVMInfo) / sizeof(natural_t); - bool GetTaskInfo(mach_port_t task, task_basic_info_64* task_info_data) { if (task == MACH_PORT_NULL) return false; @@ -105,23 +74,6 @@ return WrapUnique(new ProcessMetrics(process, port_provider)); } -ProcessMetrics::TaskVMInfo ProcessMetrics::GetTaskVMInfo() const { - TaskVMInfo info; - ChromeTaskVMInfo task_vm_info; - mach_msg_type_number_t count = ChromeTaskVMInfoCount; - kern_return_t result = - task_info(TaskForPid(process_), TASK_VM_INFO, - reinterpret_cast<task_info_t>(&task_vm_info), &count); - if (result != KERN_SUCCESS) - return info; - - info.internal = task_vm_info.internal; - info.compressed = task_vm_info.compressed; - if (count == ChromeTaskVMInfoCount) - info.phys_footprint = task_vm_info.phys_footprint; - return info; -} - #define TIME_VALUE_TO_TIMEVAL(a, r) do { \ (r)->tv_sec = (a)->seconds; \ (r)->tv_usec = (a)->microseconds; \
diff --git a/base/task/OWNERS b/base/task/OWNERS index 42f0e57..75024e6 100644 --- a/base/task/OWNERS +++ b/base/task/OWNERS
@@ -3,6 +3,7 @@ robliao@chromium.org alexclarke@chromium.org altimin@chromium.org +carlscab@google.com skyosti@lchromium.org # TEAM: scheduler-dev@chromium.org
diff --git a/base/task/sequence_manager/OWNERS b/base/task/sequence_manager/OWNERS index 2ef3011..b9ec8df 100644 --- a/base/task/sequence_manager/OWNERS +++ b/base/task/sequence_manager/OWNERS
@@ -1,5 +1,6 @@ altimin@chromium.org alexclarke@chromium.org +carlscab@google.com skyostil@chromium.org # TEAM: scheduler-dev@chromium.org
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index ab2e4008..27e1bee 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -8911706893625634704 \ No newline at end of file +8911678666757206080 \ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index b527f1a..db6eda30 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -8911702506200835040 \ No newline at end of file +8911678778624735728 \ No newline at end of file
diff --git a/build/sanitizers/tsan_suppressions.cc b/build/sanitizers/tsan_suppressions.cc index f8e3203..60f4cad 100644 --- a/build/sanitizers/tsan_suppressions.cc +++ b/build/sanitizers/tsan_suppressions.cc
@@ -128,9 +128,6 @@ "race:sctp_express_handle_sack\n" "race:system_base_info\n" - // http://crbug.com/374135 - "race:media::AlsaWrapper::PcmWritei\n" - // False positive in libc's tzset_internal, http://crbug.com/379738. "race:tzset_internal\n"
diff --git a/build/toolchain/mac/BUILD.gn b/build/toolchain/mac/BUILD.gn index b9c65b0..22316c9 100644 --- a/build/toolchain/mac/BUILD.gn +++ b/build/toolchain/mac/BUILD.gn
@@ -432,21 +432,10 @@ # constructed using shell variable $OLDPWD (automatically set when # cd is used) as computing the relative path is a bit complex and # using pwd would requires a sub-shell to be created. - # - # A special case exists for copying symbolic links. The pax command, - # as noted above, preserves symbolic links but only if they are a child - # node of source. But if the source itself is a symbolic link to a - # directory, the cd into it will copy it as a logical tree rather than - # a symbolic link. Similarly, if source is a symbolic link to a file, - # then the copy_command hard link will not produce a symbolic link, it - # would hard link the file pointed to by the symbolic link. _copydir = "mkdir -p {{output}} && cd {{source}} && " + "pax -rwl . \"\$OLDPWD\"/{{output}}" - _copylink = "ln -s \$(readlink {{source}}) {{output}}" - command = "rm -rf {{output}} && " + - "if [[ -L {{source}} ]]; then $_copylink; " + - "elif [[ -d {{source}} ]]; then $_copydir; " + - "else $copy_command; fi" + command = "rm -rf {{output}} && if [[ -d {{source}} ]]; then " + + _copydir + "; else " + copy_command + "; fi" description = "COPY_BUNDLE_DATA {{source}} {{output}}" pool = ":bundle_pool($default_toolchain)"
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 2239c19..9ff8474 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -2467,6 +2467,7 @@ "java/src/org/chromium/chrome/browser/autofill/PhoneNumberUtil.java", "java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTask.java", "java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTaskScheduler.java", + "java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncPwaDetector.java", "java/src/org/chromium/chrome/browser/banners/AppBannerManager.java", "java/src/org/chromium/chrome/browser/banners/AppBannerUiDelegateAndroid.java", "java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index c785aa3..3e169e6 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -103,6 +103,7 @@ "java/src/org/chromium/chrome/browser/autofill/PhoneNumberUtil.java", "java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTaskScheduler.java", "java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTask.java", + "java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncPwaDetector.java", "java/src/org/chromium/chrome/browser/background_task_scheduler/NativeBackgroundTask.java", "java/src/org/chromium/chrome/browser/banners/AppBannerManager.java", "java/src/org/chromium/chrome/browser/banners/AppBannerUiDelegateAndroid.java",
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/carousel/AssistantActionsDecoration.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/carousel/AssistantActionsDecoration.java index cff21bb..4faa613 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/carousel/AssistantActionsDecoration.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/carousel/AssistantActionsDecoration.java
@@ -132,9 +132,13 @@ canvas.drawRect(mChildRect, mOverlayPaint); } + View beforeLastChild = parent.getChildAt(parent.getChildCount() - 2); + // Draw a fixed size white-to-transparent linear gradient from left to right. mGradientDrawable.setBounds( 0, mVerticalSpacing, mGradientWidth, parent.getHeight() - mVerticalSpacing); + mGradientDrawable.setAlpha(Math.round(getBoundedLinearValue( + beforeLastChild.getLeft(), lastChild.getLeft(), lastChild.getRight(), 255, 0))); mGradientDrawable.draw(canvas); canvas.restore(); @@ -148,7 +152,6 @@ // Draw shadow composed of 4 layers of colors around the last child. We multiply the // original alpha of the shadow color by alphaRatio to hide the shadow when there is no // child behind the last child. - View beforeLastChild = parent.getChildAt(parent.getChildCount() - 2); float alphaRatio = getBoundedLinearValue( beforeLastChild.getLeft(), lastChild.getLeft(), lastChild.getRight(), 1, 0);
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayCoordinator.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayCoordinator.java index 68b1943..dcee28f 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayCoordinator.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayCoordinator.java
@@ -39,6 +39,10 @@ model.addObserver((source, propertyKey) -> { if (AssistantOverlayModel.STATE == propertyKey) { setState(model.get(AssistantOverlayModel.STATE)); + } else if (AssistantOverlayModel.VISUAL_VIEWPORT == propertyKey) { + RectF rect = model.get(AssistantOverlayModel.VISUAL_VIEWPORT); + mEventFilter.setVisualViewport(rect); + mDrawable.setVisualViewport(rect); } else if (AssistantOverlayModel.TOUCHABLE_AREA == propertyKey) { List<RectF> area = model.get(AssistantOverlayModel.TOUCHABLE_AREA); mEventFilter.setTouchableArea(area); @@ -47,8 +51,6 @@ AssistantOverlayDelegate delegate = model.get(AssistantOverlayModel.DELEGATE); mEventFilter.setDelegate(delegate); mDrawable.setDelegate(delegate); - } else if (AssistantOverlayModel.WEB_CONTENTS == propertyKey) { - mDrawable.setWebContents(model.get(AssistantOverlayModel.WEB_CONTENTS)); } else if (AssistantOverlayModel.BACKGROUND_COLOR == propertyKey) { mDrawable.setBackgroundColor(model.get(AssistantOverlayModel.BACKGROUND_COLOR)); } else if (AssistantOverlayModel.HIGHLIGHT_BORDER_COLOR == propertyKey) {
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayDrawable.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayDrawable.java index de12d78e..aadec199 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayDrawable.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayDrawable.java
@@ -29,9 +29,6 @@ import org.chromium.chrome.browser.compositor.CompositorViewResizer; import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager; import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager.FullscreenListener; -import org.chromium.content_public.browser.GestureListenerManager; -import org.chromium.content_public.browser.GestureStateListener; -import org.chromium.content_public.browser.WebContents; import org.chromium.ui.interpolators.BakedBezierInterpolator; import java.lang.annotation.Retention; @@ -49,8 +46,8 @@ * <p>While scrolling, it keeps track of the current scrolling offset and avoids drawing on top of * the top bar which is can be, during animations, just drawn on top of the compositor. */ -class AssistantOverlayDrawable extends Drawable - implements FullscreenListener, GestureStateListener, CompositorViewResizer.Observer { +class AssistantOverlayDrawable + extends Drawable implements FullscreenListener, CompositorViewResizer.Observer { private static final int FADE_DURATION_MS = 250; /** Default background color and alpha. */ @@ -83,7 +80,18 @@ /** When in partial mode, don't draw on {@link #mTransparentArea}. */ private boolean mPartial; - private List<Box> mTransparentArea = new ArrayList<>(); + /** + * Coordinates of the visual viewport within the page, if known, in CSS pixels relative to the + * origin of the page. + * + * The visual viewport includes the portion of the page that is really visible, excluding any + * area not fully visible because of the current zoom value. + * + * Only relevant in partial mode, when the transparent area is non-empty. + */ + private final RectF mVisualViewport = new RectF(); + + private final List<Box> mTransparentArea = new ArrayList<>(); /** Padding added between the element area and the grayed-out area. */ private final float mPaddingPx; @@ -94,32 +102,6 @@ /** A single RectF instance used for drawing, to avoid creating many instances when drawing. */ private final RectF mDrawRect = new RectF(); - /** True while the browser is scrolling. */ - private boolean mBrowserScrolling; - - /** - * Scrolling offset to use while scrolling right after scrolling. - * - * <p>This value shifts the transparent area by that many pixels while scrolling. - */ - private int mBrowserScrollOffsetY; - - /** - * Offset reported at the beginning of a scroll. - * - * <p>This is used to interpret the offsets reported by subsequent calls to {@link - * #onScrollOffsetOrExtentChanged} or {@link #onScrollEnded}. - */ - private int mInitialBrowserScrollOffsetY; - - /** - * Current offset that applies on mTransparentArea. - * - * <p>This value shifts the transparent area by that many pixels after the end of a scroll and - * before the next update, which resets this value. - */ - private int mOffsetY; - /** * Current top margin of this view. * @@ -137,7 +119,6 @@ private int mMarginBottom; private AssistantOverlayDelegate mDelegate; - private GestureListenerManager mGestureListenerManager; AssistantOverlayDrawable(Context context, ChromeFullscreenManager fullscreenManager, CompositorViewResizer viewResizer) { @@ -203,19 +184,7 @@ mDelegate = delegate; } - void setWebContents(@Nullable WebContents webContents) { - if (mGestureListenerManager != null) { - mGestureListenerManager.removeListener(this); - mGestureListenerManager = null; - } - if (webContents != null) { - mGestureListenerManager = GestureListenerManager.fromWebContents(webContents); - mGestureListenerManager.addListener(this); - } - } - void destroy() { - setWebContents(null); mFullscreenManager.removeListener(this); mViewResizer.removeObserver(this); mDelegate = null; @@ -242,6 +211,11 @@ invalidateSelf(); } + void setVisualViewport(RectF visualViewport) { + mVisualViewport.set(visualViewport); + invalidateSelf(); + } + /** Set or updates the transparent area. */ void setTransparentArea(List<RectF> transparentArea) { // Add or update boxes for each rectangle in the area. @@ -276,9 +250,6 @@ } } - mOffsetY = 0; - mInitialBrowserScrollOffsetY += mBrowserScrollOffsetY; - mBrowserScrollOffsetY = 0; invalidateSelf(); } @@ -310,8 +281,14 @@ canvas.drawPaint(mBackground); + if (mVisualViewport.isEmpty()) return; + + // Ratio of to use to convert zoomed CSS pixels, to physical pixels. Aspect ratio is + // conserved, so width and height are always converted with the same value. Using width + // here, since viewport width always corresponds to the overlay width. + float cssPixelsToPhysical = ((float) width) / ((float) mVisualViewport.width()); + int yTop = (int) mFullscreenManager.getContentOffset(); - int height = yBottom - yTop; for (Box box : mTransparentArea) { RectF rect = box.getRectToDraw(); if (rect.isEmpty() || (!mPartial && box.mAnimationType != AnimationType.FADE_IN)) { @@ -322,12 +299,13 @@ int fillAlpha = (int) (mBackgroundAlpha * (1f - box.getVisibility())); mBoxFill.setAlpha(fillAlpha); - mDrawRect.left = rect.left * width - mPaddingPx; + mDrawRect.left = (rect.left - mVisualViewport.left) * cssPixelsToPhysical - mPaddingPx; mDrawRect.top = - yTop + rect.top * height - mPaddingPx - mBrowserScrollOffsetY - mOffsetY; - mDrawRect.right = rect.right * width + mPaddingPx; + yTop + (rect.top - mVisualViewport.top) * cssPixelsToPhysical - mPaddingPx; + mDrawRect.right = + (rect.right - mVisualViewport.left) * cssPixelsToPhysical + mPaddingPx; mDrawRect.bottom = - yTop + rect.bottom * height + mPaddingPx - mBrowserScrollOffsetY - mOffsetY; + yTop + (rect.bottom - mVisualViewport.top) * cssPixelsToPhysical + mPaddingPx; if (mDrawRect.left <= 0 && mDrawRect.right >= width) { // Rounded corners look strange in the case where the rectangle takes exactly the // width of the screen. @@ -362,48 +340,14 @@ @Override public void onUpdateViewportSize() { + askForTouchableAreaUpdate(); invalidateSelf(); } @Override public void onHeightChanged(int height) { - invalidateSelf(); - } - - /** Called at the beginning of a scroll gesture triggered by the browser. */ - @Override - public void onScrollStarted(int scrollOffsetY, int scrollExtentY) { - mBrowserScrolling = true; - mInitialBrowserScrollOffsetY = scrollOffsetY; - mBrowserScrollOffsetY = 0; - invalidateSelf(); - } - - /** Called during a scroll gesture triggered by the browser. */ - @Override - public void onScrollOffsetOrExtentChanged(int scrollOffsetY, int scrollExtentY) { - if (!mBrowserScrolling) { - // onScrollOffsetOrExtentChanged will be called alone, without onScrollStarted during a - // Javascript-initiated scroll. - askForTouchableAreaUpdate(); - return; - } - mBrowserScrollOffsetY = scrollOffsetY - mInitialBrowserScrollOffsetY; - invalidateSelf(); askForTouchableAreaUpdate(); - } - - /** Called at the end of a scroll gesture triggered by the browser. */ - @Override - public void onScrollEnded(int scrollOffsetY, int scrollExtentY) { - if (!mBrowserScrolling) { - return; - } - mOffsetY += (scrollOffsetY - mInitialBrowserScrollOffsetY); - mBrowserScrollOffsetY = 0; - mBrowserScrolling = false; invalidateSelf(); - askForTouchableAreaUpdate(); } private void askForTouchableAreaUpdate() {
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayEventFilter.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayEventFilter.java index b05c468..aff95267 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayEventFilter.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayEventFilter.java
@@ -59,6 +59,16 @@ */ private boolean mPartial; + /** + * Coordinates of the visual viewport within the page, if known, in CSS pixels relative to the + * origin of the page. This is used to convert pixel coordinates to CSS coordinates. + * + * The visual viewport includes the portion of the page that is really visible, excluding any + * area not fully visible because of the current zoom value. + */ + private final RectF mVisualViewport = new RectF(); + + /** Touchable area, expressed in CSS pixels relative to the layout viewport. */ private List<RectF> mTouchableArea = Collections.emptyList(); /** @@ -141,6 +151,11 @@ mTouchableArea = touchableArea; } + /** Sets the visual viewport. */ + void setVisualViewport(RectF visualViewport) { + mVisualViewport.set(visualViewport); + } + @Override protected boolean onInterceptTouchEventInternal(MotionEvent event, boolean isKeyboardShowing) { // All events should be sent to onTouchEvent(). @@ -297,8 +312,7 @@ private boolean shouldLetEventThrough(MotionEvent event) { int yTop = (int) mFullscreenManager.getContentOffset(); int height = mCompositorView.getHeight() - getBottomBarHeight() - yTop; - return isInTouchableArea(((float) event.getX()) / mCompositorView.getWidth(), - (((float) event.getY() - yTop) / height)); + return isInTouchableArea(event.getX(), event.getY() - yTop); } /** Considers whether to let the client know about unexpected taps. */ @@ -317,17 +331,18 @@ } } - private void askForTouchableAreaUpdate() { - if (mDelegate != null) { - mDelegate.updateTouchableArea(); - } - } - private boolean isInTouchableArea(float x, float y) { + if (mVisualViewport.isEmpty() || mTouchableArea.isEmpty()) return false; + + // Ratio of to use to convert physical pixels to zoomed CSS pixels. Aspect ratio is + // conserved, so width and height are always converted with the same value. Using width + // here, since viewport width always corresponds to the overlay width. + float physicalPixelsToCss = + ((float) mVisualViewport.width()) / ((float) mCompositorView.getWidth()); + float absoluteXCss = (x * physicalPixelsToCss) + mVisualViewport.left; + float absoluteYCss = (y * physicalPixelsToCss) + mVisualViewport.top; for (RectF rect : mTouchableArea) { - if (rect.contains(x, y, x, y)) { - return true; - } + if (rect.contains(absoluteXCss, absoluteYCss)) return true; } return false; }
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayModel.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayModel.java index 55ed5b1..e212489 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayModel.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayModel.java
@@ -10,7 +10,6 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; -import org.chromium.content_public.browser.WebContents; import org.chromium.ui.modelutil.PropertyModel; import java.util.ArrayList; @@ -23,15 +22,13 @@ public class AssistantOverlayModel extends PropertyModel { public static final WritableIntPropertyKey STATE = new WritableIntPropertyKey(); - // Skipping equality as a way of fixing offset issues. See b/129048184. - // TODO(b/129050125): Handle offsets properly and remove. public static final WritableObjectPropertyKey<List<RectF>> TOUCHABLE_AREA = - new WritableObjectPropertyKey<>(/* skipEquality= */ true); - - public static final WritableObjectPropertyKey<AssistantOverlayDelegate> DELEGATE = new WritableObjectPropertyKey<>(); - public static final WritableObjectPropertyKey<WebContents> WEB_CONTENTS = + public static final WritableObjectPropertyKey<RectF> VISUAL_VIEWPORT = + new WritableObjectPropertyKey<>(); + + public static final WritableObjectPropertyKey<AssistantOverlayDelegate> DELEGATE = new WritableObjectPropertyKey<>(); public static final WritableObjectPropertyKey<Integer> BACKGROUND_COLOR = @@ -41,7 +38,7 @@ new WritableObjectPropertyKey<>(); public AssistantOverlayModel() { - super(STATE, TOUCHABLE_AREA, DELEGATE, WEB_CONTENTS, BACKGROUND_COLOR, + super(STATE, TOUCHABLE_AREA, VISUAL_VIEWPORT, DELEGATE, BACKGROUND_COLOR, HIGHLIGHT_BORDER_COLOR); } @@ -51,6 +48,11 @@ } @CalledByNative + private void setVisualViewport(float left, float top, float right, float bottom) { + set(VISUAL_VIEWPORT, new RectF(left, top, right, bottom)); + } + + @CalledByNative private void setTouchableArea(float[] coords) { List<RectF> boxes = new ArrayList<>(); for (int i = 0; i < coords.length; i += 4) { @@ -66,11 +68,6 @@ } @CalledByNative - private void setWebContents(WebContents webContents) { - set(WEB_CONTENTS, webContents); - } - - @CalledByNative private boolean setBackgroundColor(String colorString) { return setColor(BACKGROUND_COLOR, colorString); }
diff --git a/chrome/android/java/res/drawable/data_reduction_illustration.xml b/chrome/android/java/res/drawable/data_reduction_illustration.xml index ec8e23f6..f5a18fc 100644 --- a/chrome/android/java/res/drawable/data_reduction_illustration.xml +++ b/chrome/android/java/res/drawable/data_reduction_illustration.xml
@@ -9,104 +9,88 @@ xmlns:tools="http://schemas.android.com/tools" tools:targetApi="21" tools:ignore="VectorRaster" - android:width="232dp" + android:width="224dp" android:height="107dp" - android:viewportWidth="232" + android:viewportWidth="224" android:viewportHeight="107"> - <path + <path android:fillColor="#F1F3F4" + android:fillType="nonZero" android:pathData="M156.91,3.733l18.155,31.59l-90.126,-1.508l12.968,-31.662z" - android:strokeWidth="1" - android:fillColor="#F1F3F4" + android:strokeColor="#00000000" + android:strokeWidth="1"/> + <path android:fillColor="#E1741F" android:fillType="nonZero" - android:strokeColor="#00000000"/> - <path - android:pathData="M227.729,52.338L225.928,52.338C224.703,52.338 223.694,51.333 223.694,50.113L223.694,44.369C223.694,43.149 224.703,42.144 225.928,42.144L227.729,42.144C228.954,42.144 229.962,43.149 229.962,44.369L229.962,50.113C230.034,51.333 229.026,52.338 227.729,52.338Z" - android:strokeWidth="1" - android:fillColor="#E1741F" + android:pathData="M220.729,52.338L218.928,52.338C217.703,52.338 216.694,51.333 216.694,50.113L216.694,44.369C216.694,43.149 217.703,42.144 218.928,42.144L220.729,42.144C221.954,42.144 222.962,43.149 222.962,44.369L222.962,50.113C223.034,51.333 222.026,52.338 220.729,52.338Z" + android:strokeColor="#00000000" + android:strokeWidth="1"/> + <path android:fillColor="#DADCE0" android:fillType="nonZero" - android:strokeColor="#00000000"/> - <path android:pathData="M115.125,1.149h2.089v39.056h-2.089z" - android:strokeWidth="1" - android:fillColor="#DADCE0" + android:strokeColor="#00000000" + android:strokeWidth="1"/> + <path android:fillColor="#F9BB2D" android:fillType="nonZero" - android:strokeColor="#00000000"/> - <path - android:pathData="M49.638,81.128L205.612,81.128C217.283,81.128 226.72,71.723 226.72,60.092L226.72,37.836C226.72,35.467 224.775,33.528 222.398,33.528L32.419,33.528C30.186,33.528 28.313,35.323 28.313,37.621L28.313,59.949C28.313,71.651 37.895,81.128 49.638,81.128Z" - android:strokeWidth="1" - android:fillColor="#F9BB2D" + android:pathData="M48.842,81.128L198.992,81.128C210.228,81.128 219.313,71.723 219.313,60.092L219.313,37.836C219.313,35.467 217.44,33.528 215.152,33.528L32.266,33.528C30.116,33.528 28.313,35.323 28.313,37.621L28.313,59.949C28.313,71.651 37.537,81.128 48.842,81.128Z" + android:strokeColor="#00000000" + android:strokeWidth="1"/> + <path android:fillColor="#494C4F" android:fillType="nonZero" - android:strokeColor="#00000000"/> - <path android:pathData="M74.764,106.115a25.924,22.906 104.033,1 0,12.573 -50.301a25.924,22.906 104.033,1 0,-12.573 50.301z" - android:strokeWidth="1" - android:fillColor="#3C4043" + android:strokeColor="#00000000" + android:strokeWidth="1"/> + <path android:fillColor="#DADCE0" android:fillType="nonZero" - android:strokeColor="#00000000"/> - <path android:pathData="M78.334,91.832a11.203,9.94 104.033,1 0,5.433 -21.737a11.203,9.94 104.033,1 0,-5.433 21.737z" - android:strokeWidth="1" - android:fillColor="#DADCE0" + android:strokeColor="#00000000" + android:strokeWidth="1"/> + <path android:fillColor="#494C4F" android:fillType="nonZero" - android:strokeColor="#00000000"/> - <path - android:pathData="M175.629,106.111a25.924,22.906 104.033,1 0,12.573 -50.301a25.924,22.906 104.033,1 0,-12.573 50.301z" - android:strokeWidth="1" - android:fillColor="#3C4043" + android:pathData="M161.629,106.111a25.924,22.906 104.033,1 0,12.573 -50.301a25.924,22.906 104.033,1 0,-12.573 50.301z" + android:strokeColor="#00000000" + android:strokeWidth="1"/> + <path android:fillColor="#DADCE0" android:fillType="nonZero" - android:strokeColor="#00000000"/> - <path - android:pathData="M179.199,91.828a11.203,9.94 104.033,1 0,5.433 -21.737a11.203,9.94 104.033,1 0,-5.433 21.737z" - android:strokeWidth="1" - android:fillColor="#DADCE0" + android:pathData="M165.199,91.828a11.203,9.94 104.033,1 0,5.433 -21.737a11.203,9.94 104.033,1 0,-5.433 21.737z" + android:strokeColor="#00000000" + android:strokeWidth="1"/> + <path android:fillColor="#BDC1C6" android:fillType="nonZero" - android:strokeColor="#00000000"/> - <path - android:pathData="M227.801,77.682L223.118,77.682C221.101,77.682 219.444,76.031 219.444,74.021L219.444,71.149C219.444,69.138 221.101,67.487 223.118,67.487L227.801,67.487C229.818,67.487 231.475,69.138 231.475,71.149L231.475,74.021C231.475,76.031 229.818,77.682 227.801,77.682Z" - android:strokeWidth="1" - android:fillColor="#BDC1C6" + android:pathData="M219.801,77.682L215.118,77.682C213.101,77.682 211.444,76.031 211.444,74.021L211.444,71.149C211.444,69.138 213.101,67.487 215.118,67.487L219.801,67.487C221.818,67.487 223.475,69.138 223.475,71.149L223.475,74.021C223.475,76.031 221.818,77.682 219.801,77.682Z" + android:strokeColor="#00000000" + android:strokeWidth="1"/> + <path android:fillColor="#BDC1C6" android:fillType="nonZero" - android:strokeColor="#00000000"/> - <path android:pathData="M38.975,77.682L26.728,77.682C24.567,77.682 22.766,75.887 22.766,73.733L22.766,71.364C22.766,69.21 24.567,67.415 26.728,67.415L38.903,67.415C41.065,67.415 42.866,69.21 42.866,71.364L42.866,73.733C42.938,75.959 41.137,77.682 38.975,77.682Z" - android:strokeWidth="1" - android:fillColor="#BDC1C6" + android:strokeColor="#00000000" + android:strokeWidth="1"/> + <path android:fillColor="#DADCE0" android:fillType="nonZero" - android:strokeColor="#00000000"/> - <path android:pathData="M79.752,12.851L14.697,12.851C12.752,12.851 11.239,11.272 11.239,9.405L11.239,9.405C11.239,7.467 12.824,5.959 14.697,5.959L79.752,5.959C81.697,5.959 83.21,7.538 83.21,9.405L83.21,9.405C83.21,11.272 81.697,12.851 79.752,12.851Z" - android:strokeWidth="1" - android:fillColor="#DADCE0" + android:strokeColor="#00000000" + android:strokeWidth="1"/> + <path android:fillColor="#DADCE0" android:fillType="nonZero" - android:strokeColor="#00000000"/> - <path android:pathData="M12.608,30.872L3.962,30.872C2.017,30.872 0.504,29.292 0.504,27.426L0.504,27.426C0.504,25.487 2.089,23.979 3.962,23.979L12.608,23.979C14.553,23.979 16.066,25.559 16.066,27.426L16.066,27.426C16.138,29.292 14.553,30.872 12.608,30.872Z" - android:strokeWidth="1" - android:fillColor="#DADCE0" + android:strokeColor="#00000000" + android:strokeWidth="1"/> + <path android:fillColor="#DADCE0" android:fillType="nonZero" - android:strokeColor="#00000000"/> - <path android:pathData="M37.967,48.821L12.103,48.821C10.158,48.821 8.645,47.241 8.645,45.374L8.645,45.374C8.645,43.436 10.23,41.928 12.103,41.928L37.967,41.928C39.912,41.928 41.425,43.508 41.425,45.374L41.425,45.374C41.497,47.313 39.912,48.821 37.967,48.821Z" - android:strokeWidth="1" - android:fillColor="#DADCE0" + android:strokeColor="#00000000" + android:strokeWidth="1"/> + <path android:fillColor="#DADCE0" android:fillType="nonZero" - android:strokeColor="#00000000"/> - <path android:pathData="M98.267,48.821L52.664,48.821C50.718,48.821 49.206,47.241 49.206,45.374L49.206,45.374C49.206,43.436 50.791,41.928 52.664,41.928L98.267,41.928C100.212,41.928 101.725,43.508 101.725,45.374L101.725,45.374C101.725,47.313 100.212,48.821 98.267,48.821Z" - android:strokeWidth="1" - android:fillColor="#DADCE0" + android:strokeColor="#00000000" + android:strokeWidth="1"/> + <path android:fillColor="#5B5D5F" android:fillType="nonZero" - android:strokeColor="#00000000"/> - <path android:pathData="M47.765,35.897C47.188,35.897 46.9,35.395 47.188,34.964L72.115,3.949C74.133,1.436 77.158,-0 80.328,-0L157.198,-0C158.207,-0 159,0.862 159,1.867L159,2.154C159,3.159 158.207,4.021 157.198,4.021L105.039,4.021C102.374,4.021 99.996,5.528 98.771,7.897L84.939,34.892C84.651,35.467 83.93,35.897 83.138,35.897L47.765,35.897L47.765,35.897Z" - android:strokeWidth="1" - android:fillColor="#3C4043" + android:strokeColor="#00000000" + android:strokeWidth="1"/> + <path android:fillColor="#DADCE0" android:fillType="nonZero" - android:strokeColor="#00000000"/> - <path android:pathData="M96.394,30.872L26.584,30.872C24.639,30.872 23.126,29.292 23.126,27.426L23.126,27.426C23.126,25.487 24.711,23.979 26.584,23.979L96.394,23.979C98.339,23.979 99.852,25.559 99.852,27.426L99.852,27.426C99.924,29.292 98.339,30.872 96.394,30.872Z" - android:strokeWidth="1" - android:fillColor="#DADCE0" - android:fillType="nonZero" - android:strokeColor="#00000000"/> + android:strokeColor="#00000000" + android:strokeWidth="1"/> </vector>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncPwaDetector.java b/chrome/android/java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncPwaDetector.java new file mode 100644 index 0000000..aa7ef9f5 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncPwaDetector.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.browser.background_sync; + +import org.chromium.base.annotations.CalledByNative; +import org.chromium.chrome.browser.webapps.WebappRegistry; + +import java.util.Locale; + +/** + * The {@link BackgroundSyncPwaDetector} singleton is responsible for detecting + * installed PWAs (TWA and WebAPK) on Android. + * This is used to limit access to Periodic Background Sync APIs. + * + * Thread model: This class is to be run on the UI thread only. + */ +public class BackgroundSyncPwaDetector { + /** + * Returns true if there's a PWA installed for the given origin, false otherwise. + * @param origin The origin for which to look for a PWA. + */ + @CalledByNative + public static boolean isPwaInstalled(String origin) { + return WebappRegistry.getInstance().hasWebApkForUrl( + origin.toLowerCase(Locale.getDefault())); + } + + /** + * Returns true if there's a TWA installed for the given origin, false otherwise. + * @param origin The origin for which to look for a TWA. + */ + @CalledByNative + public static boolean isTwaInstalled(String origin) { + return WebappRegistry.getInstance().getTrustedWebActivityPermissionStore().isTwaInstalled( + origin.toLowerCase(Locale.getDefault())); + } +} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionStore.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionStore.java index 4091985a..0d9cd36 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionStore.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionStore.java
@@ -106,6 +106,11 @@ } } + /** Returns true if there's a registered TWA for the origin. */ + public boolean isTwaInstalled(String origin) { + return getStoredOrigins().contains(origin); + } + /** * Sets the notification state for the origin. * Returns whether {@code true} if state was changed, {@code false} if the provided state was
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java index e2c1a51..44e79c6b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java
@@ -8,6 +8,7 @@ import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.PorterDuff; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.support.annotation.IntDef; @@ -22,6 +23,7 @@ import android.widget.ImageView; import android.widget.TextView; +import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.R; import org.chromium.chrome.browser.favicon.FaviconHelper.DefaultFaviconHelper; @@ -505,6 +507,9 @@ Drawable drawable = getRoundedFavicon(historyIcon, mActivity.getResources().getDimensionPixelSize( R.dimen.tile_view_icon_size_modern)); + drawable.setColorFilter(ApiCompatibilityUtils.getColor(mActivity.getResources(), + R.color.default_icon_color), + PorterDuff.Mode.SRC_IN); viewHolder.imageView.setImageDrawable(drawable); viewHolder.itemLayout.getLayoutParams().height = mActivity.getResources().getDimensionPixelSize(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java index d7795d8..ac4c3be 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java
@@ -176,6 +176,25 @@ } /** + * Returns true if a WebAPK is found whose scope matches the provided URL. + * @param url The URL to search a WebAPK for. + */ + public boolean hasWebApkForUrl(String url) { + for (HashMap.Entry<String, WebappDataStorage> entry : mStorages.entrySet()) { + WebappDataStorage storage = entry.getValue(); + if (!storage.getId().startsWith(WebApkConstants.WEBAPK_ID_PREFIX)) continue; + + String scope = storage.getScope(); + + // Scope shouldn't be empty. + assert (!scope.isEmpty()); + + if (url.startsWith(scope)) return true; + } + return false; + } + + /** * Returns the list of WebAPK IDs with pending updates. Filters out WebAPKs which have been * uninstalled. * */
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index bb08c7d..4c679bd 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -3755,7 +3755,7 @@ </message> <if expr="enable_vr"> - <part file="../../../app/xr_consent_ui_strings.grdp" /> + <part file="xr_consent_ui_strings_java.grdp" /> </if> <if expr="enable_arcore">
diff --git a/chrome/android/java/strings/xr_consent_ui_strings_java.grdp b/chrome/android/java/strings/xr_consent_ui_strings_java.grdp new file mode 100644 index 0000000..2f6a0a64 --- /dev/null +++ b/chrome/android/java/strings/xr_consent_ui_strings_java.grdp
@@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- XR specific strings (included from generated_resources.grd and android_chrome_strings.grd). --> +<!-- These strings are used in the consent flow dialog. --> +<grit-part> + <!-- XR consent dialog. --> + <message name="IDS_XR_CONSENT_DIALOG_TITLE" desc="Title of the user consent dialog displayed before allowing a website to start a VR presentation"> + Allow this site to access your VR sensors? + </message> + <message name="IDS_XR_CONSENT_DIALOG_DESCRIPTION" desc="Body of the user consent dialog displayed before allowing a website to start a VR presentation"> + Sensor data will only be shared while you're in this VR experience. The site may be able to learn about you using certain info, such as: + - Your location + - Your physical features, like eye position + - Your movements, like how you walk + +Make sure you trust this site before you allow access. + </message> + <message name="IDS_XR_CONSENT_DIALOG_BUTTON_DENY_VR" desc="Text on the button of a user consent dialog which denies a website from starting a VR presentation"> + Don't allow + </message> + <message name="IDS_XR_CONSENT_DIALOG_BUTTON_ALLOW_AND_ENTER_VR" desc="Text on the button of a user consent dialog which allows a website to start a VR presentation"> + Allow & enter VR + </message> +</grit-part>
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionsTest.java index 962d43e..a4e691f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionsTest.java
@@ -5,9 +5,12 @@ package org.chromium.chrome.browser.browserservices.permissiondelegation; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; +import android.support.test.filters.SmallTest; import org.junit.After; import org.junit.Before; @@ -21,6 +24,7 @@ import org.chromium.base.test.util.CommandLineFlags; import org.chromium.chrome.browser.ChromeApplication; import org.chromium.chrome.browser.ChromeSwitches; +import org.chromium.chrome.browser.background_sync.BackgroundSyncPwaDetector; import org.chromium.chrome.browser.browserservices.Origin; import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule; import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils; @@ -105,6 +109,17 @@ assertEquals("\"default\"", getNotificationPermission()); } + @Test + @SmallTest + public void detectTwa() throws TimeoutException, InterruptedException { + TestThreadUtils.runOnUiThreadBlocking( + () -> mPermissionManager.register(mOrigin, mPackage, true)); + assertTrue(BackgroundSyncPwaDetector.isTwaInstalled(mOrigin.toString())); + + TestThreadUtils.runOnUiThreadBlocking(() -> { mPermissionManager.unregister(mOrigin); }); + assertFalse(BackgroundSyncPwaDetector.isTwaInstalled(mOrigin.toString())); + } + private String getNotificationPermission() throws TimeoutException, InterruptedException { return mCustomTabActivityTestRule.runJavaScriptCodeInCurrentTab("Notification.permission"); }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappRegistryTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappRegistryTest.java index 6c9fb2a..2dd4de1 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappRegistryTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappRegistryTest.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.webapps; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -671,6 +672,25 @@ assertEquals(webappId, storage2.getId()); } + @Test + @Feature({"WebApk"}) + public void testHasWebApkForUrl() throws Exception { + final String startUrl = START_URL; + final String testUrl = START_URL + "/index.html"; + + assertFalse(WebappRegistry.getInstance().hasWebApkForUrl(testUrl)); + + String webappId = "webapp"; + registerWebapp(webappId, new FetchStorageCallback(createShortcutIntent(startUrl))); + assertFalse(WebappRegistry.getInstance().hasWebApkForUrl(testUrl)); + + String webApkId = WebApkConstants.WEBAPK_ID_PREFIX + "WebApk"; + registerWebapp(webApkId, + new FetchStorageCallback( + createWebApkIntent(webApkId, startUrl, "org.chromium.webapk"))); + assertTrue(WebappRegistry.getInstance().hasWebApkForUrl(testUrl)); + } + private Set<String> addWebappsToRegistry(String... webapps) { final Set<String> expected = new HashSet<>(Arrays.asList(webapps)); mSharedPreferences.edit().putStringSet(WebappRegistry.KEY_WEBAPP_SET, expected).apply();
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 7386ba4..1a0d63f8 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -903,8 +903,8 @@ <message name="IDS_SAVE_PAGE" desc="The text label of the Save Page As menu item"> Save page &as... </message> - <message name="IDS_DISTILL_PAGE" desc="The text label of the 'Distill page' menu item"> - Distill page + <message name="IDS_DISTILL_PAGE" desc="The text label of the 'Toggle distilled page contents' menu item"> + Toggle distilled page contents </message> <message name="IDS_MORE_TOOLS_MENU" desc="The text label of the Tools submenu for touch"> More too&ls
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 616c5bb..beab18d 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -628,8 +628,6 @@ "lifetime/application_lifetime_mac.mm", "lifetime/browser_shutdown.cc", "lifetime/browser_shutdown.h", - "loader/chrome_navigation_data.cc", - "loader/chrome_navigation_data.h", "lookalikes/lookalike_url_allowlist.cc", "lookalikes/lookalike_url_allowlist.h", "lookalikes/lookalike_url_controller_client.cc", @@ -1094,6 +1092,11 @@ "performance_manager/persistence/site_data/leveldb_site_data_store.h", "performance_manager/persistence/site_data/noop_site_data_writer.cc", "performance_manager/persistence/site_data/noop_site_data_writer.h", + "performance_manager/persistence/site_data/site_data_cache.h", + "performance_manager/persistence/site_data/site_data_cache_impl.cc", + "performance_manager/persistence/site_data/site_data_cache_impl.h", + "performance_manager/persistence/site_data/site_data_cache_inspector.cc", + "performance_manager/persistence/site_data/site_data_cache_inspector.h", "performance_manager/persistence/site_data/site_data_impl.cc", "performance_manager/persistence/site_data/site_data_impl.h", "performance_manager/persistence/site_data/site_data_reader.cc", @@ -2898,6 +2901,8 @@ "download/download_shelf_controller.h", "enterprise_reporting/prefs.cc", "enterprise_reporting/prefs.h", + "enterprise_reporting/report_scheduler.cc", + "enterprise_reporting/report_scheduler.h", "enterprise_reporting/report_uploader.cc", "enterprise_reporting/report_uploader.h", "enterprise_reporting/request_timer.cc", @@ -5428,8 +5433,6 @@ "chromeos/policy/fake_device_cloud_policy_manager.h", "chromeos/settings/device_settings_test_helper.cc", "chromeos/settings/device_settings_test_helper.h", - "ui/ash/tablet_mode_client_test_util.cc", - "ui/ash/tablet_mode_client_test_util.h", ] configs += [ "//build/config/linux/dbus" ] deps += [ "//chromeos:test_support" ]
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.cc b/chrome/browser/android/autofill_assistant/ui_controller_android.cc index e4adf9f..906088e 100644 --- a/chrome/browser/android/autofill_assistant/ui_controller_android.cc +++ b/chrome/browser/android/autofill_assistant/ui_controller_android.cc
@@ -120,8 +120,6 @@ java_web_contents); Java_AssistantPaymentRequestModel_setWebContents( env, GetPaymentRequestModel(), java_web_contents); - Java_AssistantOverlayModel_setWebContents(env, GetOverlayModel(), - java_web_contents); if (ui_delegate->GetState() != AutofillAssistantState::INACTIVE) { // The UI was created for an existing Controller. OnStatusMessageChanged(ui_delegate->GetStatusMessage()); @@ -137,7 +135,9 @@ std::vector<RectF> area; ui_delegate->GetTouchableArea(&area); - OnTouchableAreaChanged(area); + RectF visual_viewport; + ui_delegate->GetVisualViewport(&visual_viewport); + OnTouchableAreaChanged(visual_viewport, area); OnResizeViewportChanged(ui_delegate->GetResizeViewport()); OnPeekModeChanged(ui_delegate->GetPeekMode()); OnFormChanged(ui_delegate->GetForm()); @@ -529,8 +529,13 @@ } void UiControllerAndroid::OnTouchableAreaChanged( + const RectF& visual_viewport, const std::vector<RectF>& areas) { JNIEnv* env = AttachCurrentThread(); + Java_AssistantOverlayModel_setVisualViewport( + env, GetOverlayModel(), visual_viewport.left, visual_viewport.top, + visual_viewport.right, visual_viewport.bottom); + std::vector<float> flattened; for (const auto& rect : areas) { flattened.emplace_back(rect.left);
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.h b/chrome/browser/android/autofill_assistant/ui_controller_android.h index 9de00b01..cabcf97 100644 --- a/chrome/browser/android/autofill_assistant/ui_controller_android.h +++ b/chrome/browser/android/autofill_assistant/ui_controller_android.h
@@ -73,7 +73,8 @@ void OnInfoBoxChanged(const InfoBox* info_box) override; void OnProgressChanged(int progress) override; void OnProgressVisibilityChanged(bool visible) override; - void OnTouchableAreaChanged(const std::vector<RectF>& areas) override; + void OnTouchableAreaChanged(const RectF& visual_viewport, + const std::vector<RectF>& areas) override; void OnResizeViewportChanged(bool resize_viewport) override; void OnPeekModeChanged( ConfigureBottomSheetProto::PeekMode peek_mode) override;
diff --git a/chrome/browser/background_sync/periodic_background_sync_permission_context.cc b/chrome/browser/background_sync/periodic_background_sync_permission_context.cc index dda667d..2157e27 100644 --- a/chrome/browser/background_sync/periodic_background_sync_permission_context.cc +++ b/chrome/browser/background_sync/periodic_background_sync_permission_context.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/background_sync/periodic_background_sync_permission_context.h" -#include "build/build_config.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/profiles/profile.h" @@ -13,22 +12,44 @@ #include "content/public/browser/browser_thread.h" #include "content/public/common/content_features.h" +#if defined(OS_ANDROID) +#include "base/android/jni_string.h" +#include "base/android/scoped_java_ref.h" +#include "base/strings/utf_string_conversions.h" +#include "jni/BackgroundSyncPwaDetector_jni.h" +#endif + PeriodicBackgroundSyncPermissionContext:: PeriodicBackgroundSyncPermissionContext(Profile* profile) : PermissionContextBase(profile, CONTENT_SETTINGS_TYPE_PERIODIC_BACKGROUND_SYNC, blink::mojom::FeaturePolicyFeature::kNotFound) {} +PeriodicBackgroundSyncPermissionContext:: + ~PeriodicBackgroundSyncPermissionContext() = default; + bool PeriodicBackgroundSyncPermissionContext::IsPwaInstalled( const GURL& url) const { #if defined(OS_ANDROID) - // TODO(crbug.com/925297): Add logic to detect PWAs on Android. - return false; + JNIEnv* env = base::android::AttachCurrentThread(); + base::android::ScopedJavaLocalRef<jstring> java_url = + base::android::ConvertUTF8ToJavaString(env, url.spec()); + return Java_BackgroundSyncPwaDetector_isPwaInstalled(env, java_url); #else return extensions::util::GetInstalledPwaForUrl(profile(), url); #endif } +#if defined(OS_ANDROID) +bool PeriodicBackgroundSyncPermissionContext::IsTwaInstalled( + const GURL& url) const { + JNIEnv* env = base::android::AttachCurrentThread(); + base::android::ScopedJavaLocalRef<jstring> java_url = + base::android::ConvertUTF8ToJavaString(env, url.spec()); + return Java_BackgroundSyncPwaDetector_isTwaInstalled(env, java_url); +} +#endif + bool PeriodicBackgroundSyncPermissionContext::IsRestrictedToSecureOrigins() const { return true; @@ -44,8 +65,10 @@ if (!base::FeatureList::IsEnabled(features::kPeriodicBackgroundSync)) return CONTENT_SETTING_BLOCK; - // TODO(crbug.com/925297): If there's a TWA installed for the origin, grant - // permission. +#if defined(OS_ANDROID) + if (IsTwaInstalled(requesting_origin)) + return CONTENT_SETTING_ALLOW; +#endif if (!IsPwaInstalled(requesting_origin)) return CONTENT_SETTING_BLOCK;
diff --git a/chrome/browser/background_sync/periodic_background_sync_permission_context.h b/chrome/browser/background_sync/periodic_background_sync_permission_context.h index 1331e0c8..d2363b22 100644 --- a/chrome/browser/background_sync/periodic_background_sync_permission_context.h +++ b/chrome/browser/background_sync/periodic_background_sync_permission_context.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_BACKGROUND_SYNC_PERIODIC_BACKGROUND_SYNC_PERMISSION_CONTEXT_H_ #include "base/macros.h" +#include "build/build_config.h" #include "chrome/browser/permissions/permission_context_base.h" #include "components/content_settings/core/common/content_settings.h" @@ -20,14 +21,24 @@ // by disabling the (one-shot) Background Sync permission from content settings // UI. The periodic Background Sync content setting can be disabled via Finch, // and will prevent usage of the API. +// The permission decision is made as follows: +// If the feature is disabled, deny. +// If we're on Android, and there's a TWA installed for the origin, grant +// permission. +// For other platforms, if there's no PWA installed for the origin, deny. +// If there is a PWA installed, grant/deny permission based on whether the +// one-shot Background Sync content setting is set to allow/block. class PeriodicBackgroundSyncPermissionContext : public PermissionContextBase { public: explicit PeriodicBackgroundSyncPermissionContext(Profile* profile); - ~PeriodicBackgroundSyncPermissionContext() override = default; + ~PeriodicBackgroundSyncPermissionContext() override; protected: // Virtual for testing. virtual bool IsPwaInstalled(const GURL& url) const; +#if defined(OS_ANDROID) + virtual bool IsTwaInstalled(const GURL& url) const; +#endif private: // PermissionContextBase implementation.
diff --git a/chrome/browser/background_sync/periodic_background_sync_permission_context_unittest.cc b/chrome/browser/background_sync/periodic_background_sync_permission_context_unittest.cc index e060c4d..9ff079c 100644 --- a/chrome/browser/background_sync/periodic_background_sync_permission_context_unittest.cc +++ b/chrome/browser/background_sync/periodic_background_sync_permission_context_unittest.cc
@@ -8,6 +8,7 @@ #include "base/macros.h" #include "base/test/scoped_feature_list.h" +#include "build/build_config.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/common/web_application_info.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" @@ -30,13 +31,26 @@ void InstallPwa(const GURL& url) { installed_pwas_.insert(url); } +#if defined(OS_ANDROID) + void InstallTwa(const GURL& url) { installed_twas_.insert(url); } +#endif + // PeriodicBackgroundSyncPermissionContext overrides: bool IsPwaInstalled(const GURL& url) const override { return installed_pwas_.find(url) != installed_pwas_.end(); } +#if defined(OS_ANDROID) + bool IsTwaInstalled(const GURL& url) const override { + return installed_twas_.find(url) != installed_twas_.end(); + } +#endif + private: std::set<GURL> installed_pwas_; +#if defined(OS_ANDROID) + std::set<GURL> installed_twas_; +#endif }; class PeriodicBackgroundSyncPermissionContextTest @@ -84,6 +98,9 @@ } void InstallPwa(const GURL& url) { permission_context_->InstallPwa(url); } +#if defined(OS_ANDROID) + void InstallTwa(const GURL& url) { permission_context_->InstallTwa(url); } +#endif void SetUpPwaAndContentSettings(const GURL& url) { InstallPwa(url); @@ -131,7 +148,7 @@ CONTENT_SETTING_ALLOW); } -TEST_F(PeriodicBackgroundSyncPermissionContextTest, DesktopPWA) { +TEST_F(PeriodicBackgroundSyncPermissionContextTest, DesktopPwa) { base::test::ScopedFeatureList feature_list; feature_list.InitAndEnableFeature(features::kPeriodicBackgroundSync); GURL url("https://example.com"); @@ -144,4 +161,18 @@ EXPECT_EQ(GetPermissionStatus(url), CONTENT_SETTING_BLOCK); } +#if defined(OS_ANDROID) +TEST_F(PeriodicBackgroundSyncPermissionContextTest, Twa) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature(features::kPeriodicBackgroundSync); + GURL url("https://example.com"); + + // No TWA or PWA installed. + EXPECT_EQ(GetPermissionStatus(url), CONTENT_SETTING_BLOCK); + + InstallTwa(url); + EXPECT_EQ(GetPermissionStatus(url), CONTENT_SETTING_ALLOW); +} +#endif + } // namespace
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index d6113f2..b257db8a 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc
@@ -1273,9 +1273,9 @@ #if !defined(OS_ANDROID) if (base::FeatureList::IsEnabled(features::kWebUsb)) { web_usb_detector_.reset(new WebUsbDetector()); - BrowserThread::PostAfterStartupTask( + base::PostTaskWithTraits( FROM_HERE, - base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}), + {content::BrowserThread::UI, base::TaskPriority::BEST_EFFORT}, base::BindOnce(&WebUsbDetector::Initialize, base::Unretained(web_usb_detector_.get()))); }
diff --git a/chrome/browser/chrome_browser_main_win.cc b/chrome/browser/chrome_browser_main_win.cc index 37e8fff..0a40f3a9 100644 --- a/chrome/browser/chrome_browser_main_win.cc +++ b/chrome/browser/chrome_browser_main_win.cc
@@ -434,10 +434,9 @@ void MaybePostSettingsResetPrompt() { if (base::FeatureList::IsEnabled(safe_browsing::kSettingsResetPrompt)) { - content::BrowserThread::PostAfterStartupTask( + base::PostTaskWithTraits( FROM_HERE, - base::CreateSingleThreadTaskRunnerWithTraits( - {content::BrowserThread::UI}), + {content::BrowserThread::UI, base::TaskPriority::BEST_EFFORT}, base::Bind(safe_browsing::MaybeShowSettingsResetPromptWithDelay)); } }
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 99141ce..54ab3740 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -62,7 +62,6 @@ #include "chrome/browser/font_family_cache.h" #include "chrome/browser/language/translate_frame_binder.h" #include "chrome/browser/lifetime/browser_shutdown.h" -#include "chrome/browser/loader/chrome_navigation_data.h" #include "chrome/browser/lookalikes/lookalike_url_navigation_throttle.h" #include "chrome/browser/media/router/media_router_feature.h" #include "chrome/browser/media/router/presentation/presentation_service_delegate_impl.h"
diff --git a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc index b6c8216..c3fe806 100644 --- a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc +++ b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc
@@ -212,10 +212,12 @@ service_->Shutdown(); chrome_keyboard_controller_client_test_helper_.reset(); profile_.reset(); - tablet_mode_client_.reset(nullptr); chromeos::input_method::InputMethodManager::Shutdown(); ui::IMEBridge::Shutdown(); ChromeAshTestBase::TearDown(); + // To match ChromeBrowserMainExtraPartsAsh, shut down the TabletModeClient + // after Shell. + tablet_mode_client_.reset(); } private:
diff --git a/chrome/browser/chromeos/child_accounts/screen_time_controller.cc b/chrome/browser/chromeos/child_accounts/screen_time_controller.cc index c81f7eb..8b088f1 100644 --- a/chrome/browser/chromeos/child_accounts/screen_time_controller.cc +++ b/chrome/browser/chromeos/child_accounts/screen_time_controller.cc
@@ -8,6 +8,7 @@ #include <string> #include <utility> +#include "ash/public/cpp/login_screen.h" #include "base/bind.h" #include "base/feature_list.h" #include "base/time/clock.h" @@ -19,7 +20,6 @@ #include "chrome/browser/chromeos/login/lock/screen_locker.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/ash/login_screen_client.h" #include "chrome/browser/ui/ash/media_client.h" #include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" @@ -286,7 +286,7 @@ // Add parent access code button. if (base::FeatureList::IsEnabled(features::kParentAccessCode)) - LoginScreenClient::Get()->login_screen()->SetShowParentAccessButton(true); + ash::LoginScreen::Get()->ShowParentAccessButton(true); // Prevent media from continuing to play after device is locked. MediaClient::Get()->SuspendMediaSessions(); @@ -302,7 +302,7 @@ ->GetAccountId(); ScreenLocker::default_screen_locker()->EnableAuthForUser(account_id); if (base::FeatureList::IsEnabled(features::kParentAccessCode)) - LoginScreenClient::Get()->login_screen()->SetShowParentAccessButton(false); + ash::LoginScreen::Get()->ShowParentAccessButton(false); } void ScreenTimeController::OnPolicyChanged() {
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc index 5f15e8c..cb2a213 100644 --- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc +++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
@@ -10,6 +10,7 @@ #include "ash/public/cpp/ash_pref_names.h" #include "ash/public/cpp/shelf_item.h" +#include "ash/public/cpp/tablet_mode.h" #include "ash/public/interfaces/ash_message_center_controller.mojom.h" #include "ash/public/interfaces/constants.mojom.h" #include "ash/shell.h" @@ -1586,17 +1587,9 @@ std::unique_ptr<api::autotest_private::SetTabletModeEnabled::Params> params( api::autotest_private::SetTabletModeEnabled::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params); - TabletModeClient::Get()->SetTabletModeEnabledForTesting( - params->enabled, - base::BindOnce( - &AutotestPrivateSetTabletModeEnabledFunction::OnSetTabletModeEnabled, - this)); - return RespondLater(); -} - -void AutotestPrivateSetTabletModeEnabledFunction::OnSetTabletModeEnabled( - bool enabled) { - Respond(OneArgument(std::make_unique<base::Value>(enabled))); + ash::TabletMode::Get()->SetEnabledForTest(params->enabled); + return RespondNow(OneArgument( + std::make_unique<base::Value>(ash::TabletMode::Get()->IsEnabled()))); } ///////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h index 49badeb..f0766dc 100644 --- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h +++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h
@@ -620,7 +620,6 @@ AUTOTESTPRIVATE_SETTABLETMODEENABLED) private: - void OnSetTabletModeEnabled(bool enabled); ~AutotestPrivateSetTabletModeEnabledFunction() override; ResponseAction Run() override; };
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc index 8363cbe..85d16bd 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
@@ -47,7 +47,6 @@ #include "chrome/browser/sync_file_system/sync_file_system_service_factory.h" #include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "chrome/browser/ui/app_list/search/launcher_search/launcher_search_provider.h" -#include "chrome/browser/ui/ash/tablet_mode_client_test_util.h" #include "chrome/browser/ui/views/extensions/extension_dialog.h" #include "chrome/browser/ui/views/select_file_dialog_extension.h" #include "chrome/common/chrome_features.h" @@ -2185,7 +2184,7 @@ } if (name == "enableTabletMode") { - ::test::SetAndWaitForTabletMode(true); + ash::ShellTestApi().EnableTabletModeWindowManager(true); *output = "tabletModeEnabled"; return; }
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_service_regular.cc b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_service_regular.cc index 4d03a0b..836b2fd3 100644 --- a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_service_regular.cc +++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_service_regular.cc
@@ -385,6 +385,7 @@ void EasyUnlockServiceRegular::ShutdownInternal() { pref_manager_.reset(); + notification_controller_.reset(); proximity_auth::ScreenlockBridge::Get()->RemoveObserver(this);
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_service_signin_chromeos.cc b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_service_signin_chromeos.cc index 59bda93a..576bc89 100644 --- a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_service_signin_chromeos.cc +++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_service_signin_chromeos.cc
@@ -321,6 +321,10 @@ return; service_active_ = false; + remote_device_cache_.reset(); + challenge_wrapper_.reset(); + pref_manager_.reset(); + weak_ptr_factory_.InvalidateWeakPtrs(); proximity_auth::ScreenlockBridge::Get()->RemoveObserver(this); user_data_.clear();
diff --git a/chrome/browser/chromeos/login/lock/views_screen_locker.cc b/chrome/browser/chromeos/login/lock/views_screen_locker.cc index 554a309..6cb3ee6 100644 --- a/chrome/browser/chromeos/login/lock/views_screen_locker.cc +++ b/chrome/browser/chromeos/login/lock/views_screen_locker.cc
@@ -142,13 +142,11 @@ int error_msg_id, HelpAppLauncher::HelpTopic help_topic_id) { // TODO(xiaoyinh): Complete the implementation here. - LoginScreenClient::Get()->login_screen()->ShowErrorMessage( - 0 /* login_attempts */, std::string(), std::string(), - static_cast<int>(help_topic_id)); + NOTIMPLEMENTED(); } void ViewsScreenLocker::ClearErrors() { - LoginScreenClient::Get()->login_screen()->ClearErrors(); + NOTIMPLEMENTED(); } void ViewsScreenLocker::OnAshLockAnimationFinished() {
diff --git a/chrome/browser/chromeos/login/signin/oauth2_login_verifier.cc b/chrome/browser/chromeos/login/signin/oauth2_login_verifier.cc index bd19f8b..07cf5015 100644 --- a/chrome/browser/chromeos/login/signin/oauth2_login_verifier.cc +++ b/chrome/browser/chromeos/login/signin/oauth2_login_verifier.cc
@@ -7,6 +7,7 @@ #include <vector> #include "base/logging.h" +#include "components/signin/core/browser/gaia_cookie_manager_service.h" #include "content/public/browser/browser_thread.h" #include "services/identity/public/cpp/accounts_cookie_mutator.h"
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc index 08de5dc1..3c6124a 100644 --- a/chrome/browser/chromeos/login/wizard_controller.cc +++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -13,6 +13,7 @@ #include <vector> #include "ash/public/cpp/ash_switches.h" +#include "ash/public/cpp/login_screen.h" #include "base/bind.h" #include "base/callback_helpers.h" #include "base/command_line.h" @@ -1509,7 +1510,7 @@ } void WizardController::OnGuestModePolicyUpdated() { - LoginScreenClient::Get()->login_screen()->SetShowGuestButtonInOobe( + ash::LoginScreen::Get()->ShowGuestButtonInOobe( user_manager::UserManager::Get()->IsGuestSessionAllowed()); }
diff --git a/chrome/browser/chromeos/settings/device_oauth2_token_service_delegate.cc b/chrome/browser/chromeos/settings/device_oauth2_token_service_delegate.cc index d804bcc..833e9ca 100644 --- a/chrome/browser/chromeos/settings/device_oauth2_token_service_delegate.cc +++ b/chrome/browser/chromeos/settings/device_oauth2_token_service_delegate.cc
@@ -83,19 +83,32 @@ bool DeviceOAuth2TokenServiceDelegate::RefreshTokenIsAvailable( const std::string& account_id) const { + auto accounts = GetAccounts(); + return std::find(accounts.begin(), accounts.end(), account_id) != + accounts.end(); +} + +std::vector<std::string> DeviceOAuth2TokenServiceDelegate::GetAccounts() { + return static_cast<const DeviceOAuth2TokenServiceDelegate&>(*this) + .GetAccounts(); +} + +std::vector<std::string> DeviceOAuth2TokenServiceDelegate::GetAccounts() const { + std::vector<std::string> accounts; switch (state_) { case STATE_NO_TOKEN: case STATE_TOKEN_INVALID: - return false; + return accounts; case STATE_LOADING: case STATE_VALIDATION_PENDING: case STATE_VALIDATION_STARTED: case STATE_TOKEN_VALID: - return account_id == GetRobotAccountId(); + accounts.push_back(GetRobotAccountId()); + return accounts; } NOTREACHED() << "Unhandled state " << state_; - return false; + return accounts; } std::string DeviceOAuth2TokenServiceDelegate::GetRobotAccountId() const {
diff --git a/chrome/browser/chromeos/settings/device_oauth2_token_service_delegate.h b/chrome/browser/chromeos/settings/device_oauth2_token_service_delegate.h index be434be..3636bde 100644 --- a/chrome/browser/chromeos/settings/device_oauth2_token_service_delegate.h +++ b/chrome/browser/chromeos/settings/device_oauth2_token_service_delegate.h
@@ -61,6 +61,8 @@ scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, OAuth2AccessTokenConsumer* consumer) override; + std::vector<std::string> GetAccounts() override; + // gaia::GaiaOAuthClient::Delegate implementation. void OnRefreshTokenResponse(const std::string& access_token, int expires_in_seconds) override; @@ -94,6 +96,8 @@ STATE_TOKEN_VALID, }; + std::vector<std::string> GetAccounts() const; + // Invoked by CrosSettings when the robot account ID becomes available. void OnServiceAccountIdentityChanged();
diff --git a/chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.cc b/chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.cc index 8416e517..a691da6 100644 --- a/chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.cc +++ b/chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.cc
@@ -20,7 +20,6 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_content_browser_client.h" #include "chrome/browser/data_use_measurement/chrome_data_use_measurement.h" -#include "chrome/browser/loader/chrome_navigation_data.h" #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" #include "chrome/browser/previews/previews_service.h" #include "chrome/browser/previews/previews_service_factory.h" @@ -270,17 +269,9 @@ DataReductionProxyChromeSettings::CreateDataFromNavigationHandle( content::NavigationHandle* handle, const net::HttpResponseHeaders* headers) { - ChromeNavigationData* chrome_navigation_data = - static_cast<ChromeNavigationData*>(handle->GetNavigationData()); - if (chrome_navigation_data) { - if (chrome_navigation_data->GetDataReductionProxyData()) - return chrome_navigation_data->GetDataReductionProxyData()->DeepCopy(); - return nullptr; - } - // Some unit tests don't have data_reduction_proxy_service() set. if (!data_reduction_proxy_service()) - return nullptr; + return test_data_ ? std::move(test_data_) : nullptr; // TODO(721403): Need to fill in: // - request_info_ @@ -342,6 +333,11 @@ return data; } +void DataReductionProxyChromeSettings::SetDataForNextCommitForTesting( + std::unique_ptr<data_reduction_proxy::DataReductionProxyData> data) { + test_data_ = std::move(data); +} + // static data_reduction_proxy::Client DataReductionProxyChromeSettings::GetClient() { #if defined(OS_ANDROID)
diff --git a/chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h b/chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h index 27c3e415..8470118 100644 --- a/chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h +++ b/chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h
@@ -99,6 +99,11 @@ CreateDataFromNavigationHandle(content::NavigationHandle* handle, const net::HttpResponseHeaders* headers); + // This data will be used on the next commit if it's HTTP/HTTPS and the page + // is not an error page.. + void SetDataForNextCommitForTesting( + std::unique_ptr<data_reduction_proxy::DataReductionProxyData> data); + private: // Helper method for migrating the Data Reduction Proxy away from using the // proxy pref. Returns the ProxyPrefMigrationResult value indicating the @@ -109,6 +114,8 @@ // Null before InitDataReductionProxySettings is called. Profile* profile_; + std::unique_ptr<data_reduction_proxy::DataReductionProxyData> test_data_; + DISALLOW_COPY_AND_ASSIGN(DataReductionProxyChromeSettings); };
diff --git a/chrome/browser/dom_distiller/tab_utils.cc b/chrome/browser/dom_distiller/tab_utils.cc index 6c17d5f..f767aa33 100644 --- a/chrome/browser/dom_distiller/tab_utils.cc +++ b/chrome/browser/dom_distiller/tab_utils.cc
@@ -185,3 +185,22 @@ StartNavigationToDistillerViewer(destination_web_contents, source_web_contents->GetLastCommittedURL()); } + +void ReturnToOriginalPage(content::WebContents* distilled_web_contents) { + DCHECK(distilled_web_contents); + DCHECK(dom_distiller::url_utils::IsDistilledPage( + distilled_web_contents->GetLastCommittedURL())); + + GURL distilled_url = distilled_web_contents->GetLastCommittedURL(); + GURL source_url = + dom_distiller::url_utils::GetOriginalUrlFromDistillerUrl(distilled_url); + DCHECK_NE(source_url, distilled_url) + << "Could not retrieve original page for distilled URL: " + << distilled_url; + + // TODO(https://crbug.com/925965): Consider saving & retrieving the original + // page web contents instead of reloading the page. + content::NavigationController::LoadURLParams params(source_url); + params.transition_type = ui::PAGE_TRANSITION_AUTO_BOOKMARK; + distilled_web_contents->GetController().LoadURLWithParams(params); +}
diff --git a/chrome/browser/dom_distiller/tab_utils.h b/chrome/browser/dom_distiller/tab_utils.h index e5364bb7..7200d8a 100644 --- a/chrome/browser/dom_distiller/tab_utils.h +++ b/chrome/browser/dom_distiller/tab_utils.h
@@ -24,4 +24,9 @@ void DistillAndView(content::WebContents* source_web_contents, content::WebContents* destination_web_contents); +// Navigates back to the original page from which this page was distilled. +// |distilled_web_contents| must not be null and must point to an already +// distilled page. This method does not take ownership of the web contents. +void ReturnToOriginalPage(content::WebContents* distilled_web_contents); + #endif // CHROME_BROWSER_DOM_DISTILLER_TAB_UTILS_H_
diff --git a/chrome/browser/dom_distiller/tab_utils_browsertest.cc b/chrome/browser/dom_distiller/tab_utils_browsertest.cc index fc0db4bc..5fd39092 100644 --- a/chrome/browser/dom_distiller/tab_utils_browsertest.cc +++ b/chrome/browser/dom_distiller/tab_utils_browsertest.cc
@@ -45,19 +45,44 @@ return new_web_contents; } -// DistilledPageObserver is used to detect if a distilled page has -// finished loading. This is done by checking how many times the title has -// been set rather than using "DidFinishLoad" directly due to the content -// being set by JavaScript. -class DistilledPageObserver : public content::WebContentsObserver { +// Helper class that blocks test execution until |observed_contents| enters a +// certain state. Subclasses specify the precise state by calling +// |new_url_loaded_runner_|.QuitClosure().Run() when |observed_contents| is +// ready. +class NavigationObserver : public content::WebContentsObserver { public: - explicit DistilledPageObserver(content::WebContents* observed_contents) - : title_set_count_(0), loaded_distiller_page_(false) { + explicit NavigationObserver(content::WebContents* observed_contents) { content::WebContentsObserver::Observe(observed_contents); } void WaitUntilFinishedLoading() { new_url_loaded_runner_.Run(); } + protected: + base::RunLoop new_url_loaded_runner_; +}; + +class OriginalPageNavigationObserver : public NavigationObserver { + public: + using NavigationObserver::NavigationObserver; + + void DidFinishLoad(content::RenderFrameHost* render_frame_host, + const GURL& validated_url) override { + if (!render_frame_host->GetParent()) + new_url_loaded_runner_.QuitClosure().Run(); + } +}; + +// DistilledPageObserver is used to detect if a distilled page has +// finished loading. This is done by checking how many times the title has +// been set rather than using "DidFinishLoad" directly due to the content +// being set by JavaScript. +class DistilledPageObserver : public NavigationObserver { + public: + explicit DistilledPageObserver(content::WebContents* observed_contents) + : NavigationObserver(observed_contents), + title_set_count_(0), + loaded_distiller_page_(false) {} + void DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url) override { if (!render_frame_host->GetParent() && @@ -76,7 +101,6 @@ } private: - base::RunLoop new_url_loaded_runner_; int title_set_count_; bool loaded_distiller_page_; }; @@ -164,5 +188,32 @@ destroyed_watcher.Wait(); } +IN_PROC_BROWSER_TEST_F(DomDistillerTabUtilsBrowserTest, ToggleOriginalPage) { + content::WebContents* source_web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + // This blocks until the navigation has completely finished. + ui_test_utils::NavigateToURL(browser(), article_url()); + + // Create and navigate to the distilled page. + browser()->tab_strip_model()->AppendWebContents( + NewContentsWithSameParamsAs(source_web_contents), + /* foreground = */ true); + content::WebContents* destination_web_contents = + browser()->tab_strip_model()->GetWebContentsAt(1); + + DistillAndView(source_web_contents, destination_web_contents); + DistilledPageObserver(destination_web_contents).WaitUntilFinishedLoading(); + ASSERT_TRUE(url_utils::IsDistilledPage( + destination_web_contents->GetLastCommittedURL())); + + // Now return to the original page. + ReturnToOriginalPage(destination_web_contents); + OriginalPageNavigationObserver(destination_web_contents) + .WaitUntilFinishedLoading(); + EXPECT_EQ(source_web_contents->GetLastCommittedURL(), + destination_web_contents->GetLastCommittedURL()); +} + } // namespace } // namespace dom_distiller
diff --git a/chrome/browser/enterprise_reporting/report_scheduler.cc b/chrome/browser/enterprise_reporting/report_scheduler.cc new file mode 100644 index 0000000..ca13c06 --- /dev/null +++ b/chrome/browser/enterprise_reporting/report_scheduler.cc
@@ -0,0 +1,129 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/enterprise_reporting/report_scheduler.h" + +#include <utility> +#include <vector> + +#include "base/task/post_task.h" +#include "base/time/time.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/enterprise_reporting/prefs.h" +#include "chrome/browser/enterprise_reporting/request_timer.h" +#include "chrome/browser/net/system_network_context_manager.h" +#include "chrome/browser/policy/browser_dm_token_storage.h" +#include "chrome/browser/policy/chrome_browser_policy_connector.h" +#include "chrome/common/pref_names.h" +#include "components/policy/core/common/cloud/cloud_policy_client.h" +#include "components/policy/core/common/cloud/device_management_service.h" +#include "components/prefs/pref_service.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" + +namespace em = enterprise_management; + +namespace enterprise_reporting { +namespace { +const int kDefaultUploadIntervalHours = + 24; // Default upload interval is 24 hours. + +// Reads DM token and client id. Returns true if boths are non empty. +bool GetDMTokenAndDeviceId(std::string* dm_token, std::string* client_id) { + DCHECK(dm_token && client_id); + *dm_token = policy::BrowserDMTokenStorage::Get()->RetrieveDMToken(); + *client_id = policy::BrowserDMTokenStorage::Get()->RetrieveClientId(); + + if (dm_token->empty() || client_id->empty()) { + VLOG(1) + << "Enterprise reporting is disabled because device is not enrolled."; + return false; + } + return true; +} + +// Returns true if cloud reporting is enabled. +bool IsReportingEnabled() { + return g_browser_process->local_state()->GetBoolean( + prefs::kCloudReportingEnabled); +} + +} // namespace + +ReportScheduler::ReportScheduler( + std::unique_ptr<policy::CloudPolicyClient> client, + std::unique_ptr<RequestTimer> request_timer) + : cloud_policy_client_(std::move(client)), + request_timer_(std::move(request_timer)) { + RegisterPerfObserver(); +} + +ReportScheduler::~ReportScheduler() = default; + +void ReportScheduler::RegisterPerfObserver() { + pref_change_registrar_.Init(g_browser_process->local_state()); + pref_change_registrar_.Add( + prefs::kCloudReportingEnabled, + base::BindRepeating(&ReportScheduler::OnReportEnabledPerfChanged, + base::Unretained(this))); + // Trigger first perf check during launch process. + OnReportEnabledPerfChanged(); +} + +void ReportScheduler::OnReportEnabledPerfChanged() { + std::string dm_token; + std::string client_id; + if (!IsReportingEnabled() || !GetDMTokenAndDeviceId(&dm_token, &client_id)) { + if (request_timer_) + request_timer_->Stop(); + return; + } + + if (!cloud_policy_client_->is_registered()) { + cloud_policy_client_->SetupRegistration(dm_token, client_id, + std::vector<std::string>()); + } + + Start(); +} + +void ReportScheduler::Start() { + base::TimeDelta upload_interval = + base::TimeDelta::FromHours(kDefaultUploadIntervalHours); + base::TimeDelta first_request_delay = + upload_interval - + (base::Time::Now() - + g_browser_process->local_state()->GetTime(kLastUploadTimestamp)); + // The first report delay is based on the |lastUploadTimestamp| in the + // |local_state|, after that, it's 24 hours for each succeeded upload. + request_timer_->Start( + FROM_HERE, first_request_delay, upload_interval, + base::BindRepeating(&ReportScheduler::GenerateAndUploadReport, + base::Unretained(this))); +} + +void ReportScheduler::GenerateAndUploadReport() { + VLOG(1) << "Uploading enterprise report."; + // TODO(zmin): Generates a real request. + std::unique_ptr<em::ChromeDesktopReportRequest> request = + std::make_unique<em::ChromeDesktopReportRequest>(); + cloud_policy_client_->UploadChromeDesktopReport( + std::move(request), + base::BindRepeating(&ReportScheduler::OnReportUploaded, + base::Unretained(this))); +} + +void ReportScheduler::OnReportUploaded(bool status) { + if (status) { + VLOG(1) << "The enterprise report has been uploaded."; + g_browser_process->local_state()->SetTime(kLastUploadTimestamp, + base::Time::Now()); + if (IsReportingEnabled()) + request_timer_->Reset(); + return; + } + VLOG(1) << "The enterprise report has not been uploaded."; + // TODO(zmin): Implement retry logic +} + +} // namespace enterprise_reporting
diff --git a/chrome/browser/enterprise_reporting/report_scheduler.h b/chrome/browser/enterprise_reporting/report_scheduler.h new file mode 100644 index 0000000..98a8a666 --- /dev/null +++ b/chrome/browser/enterprise_reporting/report_scheduler.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 CHROME_BROWSER_ENTERPRISE_REPORTING_REPORT_SCHEDULER_H_ +#define CHROME_BROWSER_ENTERPRISE_REPORTING_REPORT_SCHEDULER_H_ + +#include <memory> +#include <string> + +#include "base/macros.h" +#include "components/prefs/pref_change_registrar.h" + +namespace policy { +class CloudPolicyClient; +} // namespace policy + +namespace enterprise_reporting { + +class RequestTimer; + +// Schedules the next report and handles retry in case of error. It also cancels +// all pending uploads if the report policy is turned off. +class ReportScheduler { + public: + ReportScheduler(std::unique_ptr<policy::CloudPolicyClient> client, + std::unique_ptr<RequestTimer> request_timer); + + ~ReportScheduler(); + + private: + // Observes CloudReportingEnabled policy. + void RegisterPerfObserver(); + + // Handles kCloudReportingEnabled policy value change, including the first + // policy value check during startup. + void OnReportEnabledPerfChanged(); + + // Schedules the first update request. + void Start(); + + // Generates a report and uploads it. + void GenerateAndUploadReport(); + + // Callback once report upload request is finished. + void OnReportUploaded(bool status); + + // Policy value watcher + PrefChangeRegistrar pref_change_registrar_; + + std::unique_ptr<policy::CloudPolicyClient> cloud_policy_client_; + + std::unique_ptr<RequestTimer> request_timer_; + + DISALLOW_COPY_AND_ASSIGN(ReportScheduler); +}; + +} // namespace enterprise_reporting + +#endif // CHROME_BROWSER_ENTERPRISE_REPORTING_REPORT_SCHEDULER_H_
diff --git a/chrome/browser/enterprise_reporting/report_scheduler_unittest.cc b/chrome/browser/enterprise_reporting/report_scheduler_unittest.cc new file mode 100644 index 0000000..6e821d30 --- /dev/null +++ b/chrome/browser/enterprise_reporting/report_scheduler_unittest.cc
@@ -0,0 +1,278 @@ +// 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/enterprise_reporting/report_scheduler.h" + +#include <utility> + +#include "base/test/scoped_feature_list.h" +#include "base/test/scoped_task_environment.h" +#include "chrome/browser/enterprise_reporting/prefs.h" +#include "chrome/browser/enterprise_reporting/request_timer.h" +#include "chrome/browser/policy/fake_browser_dm_token_storage.h" +#include "chrome/common/chrome_features.h" +#include "chrome/common/pref_names.h" +#include "chrome/test/base/scoped_testing_local_state.h" +#include "chrome/test/base/testing_browser_process.h" +#include "components/policy/core/common/cloud/mock_cloud_policy_client.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::_; +using ::testing::Invoke; +using ::testing::WithArgs; + +namespace em = enterprise_management; + +namespace enterprise_reporting { +namespace { +constexpr char kDMToken[] = "dm_token"; +constexpr char kClientId[] = "client_id"; +const int kDefaultUploadInterval = 24; +} // namespace +class FakeRequestTimer : public RequestTimer { + public: + FakeRequestTimer() = default; + ~FakeRequestTimer() override = default; + void Start(const base::Location& posted_from, + base::TimeDelta first_delay, + base::TimeDelta repeat_delay, + base::RepeatingClosure user_task) override { + first_delay_ = first_delay; + repeat_delay_ = repeat_delay; + user_task_ = user_task; + is_running_ = true; + } + + void Stop() override { is_running_ = false; } + + void Reset() override { is_running_ = true; } + + void Fire() { + EXPECT_TRUE(is_running_); + user_task_.Run(); + is_running_ = false; + } + + bool is_running() { return is_running_; } + + base::TimeDelta first_delay() { return first_delay_; } + + base::TimeDelta repeat_delay() { return repeat_delay_; } + + private: + base::TimeDelta first_delay_; + base::TimeDelta repeat_delay_; + base::RepeatingClosure user_task_; + bool is_running_ = false; + DISALLOW_COPY_AND_ASSIGN(FakeRequestTimer); +}; + +class ReportSchedulerTest : public ::testing::Test { + public: + ReportSchedulerTest() + : scoped_task_environment_( + base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME, + base::test::ScopedTaskEnvironment::NowSource:: + MAIN_THREAD_MOCK_TIME), + local_state_(TestingBrowserProcess::GetGlobal()) {} + ~ReportSchedulerTest() override = default; + void SetUp() override { + scoped_feature_list_.InitAndEnableFeature( + features::kEnterpriseReportingInBrowser); + RegisterPrefs(local_state_.Get()->registry()); + client_ptr_ = std::make_unique<policy::MockCloudPolicyClient>(); + client_ = client_ptr_.get(); + timer_ptr_ = std::make_unique<FakeRequestTimer>(); + timer_ = timer_ptr_.get(); + Init(true, kDMToken, kClientId); + } + + void Init(bool policy_enabled, + const std::string& dm_token, + const std::string& client_id) { + ToggleCloudReport(policy_enabled); + storage_.SetDMToken(dm_token); + storage_.SetClientId(client_id); + } + + void CreateScheduler() { + scheduler_ = std::make_unique<ReportScheduler>(std::move(client_ptr_), + std::move(timer_ptr_)); + } + + void SetLastUploadInHour(int gap) { + previous_set_last_upload_timestamp_ = + base::Time::Now() - base::TimeDelta::FromHours(gap); + local_state_.Get()->SetTime(kLastUploadTimestamp, + previous_set_last_upload_timestamp_); + } + + void ToggleCloudReport(bool enabled) { + local_state_.Get()->SetManagedPref(prefs::kCloudReportingEnabled, + std::make_unique<base::Value>(enabled)); + } + + // If lastUploadTimestamp is updated recently, it should be updated as Now(). + // Otherwise, it should be same as previous set timestamp. + void ExpectLastUploadTimestampUpdated(bool is_updated) { + auto current_last_upload_timestamp = + local_state_.Get()->GetTime(kLastUploadTimestamp); + if (is_updated) { + EXPECT_EQ(base::Time::Now(), current_last_upload_timestamp); + } else { + EXPECT_EQ(previous_set_last_upload_timestamp_, + current_last_upload_timestamp); + } + } + + base::test::ScopedFeatureList scoped_feature_list_; + base::test::ScopedTaskEnvironment scoped_task_environment_; + ScopedTestingLocalState local_state_; + + std::unique_ptr<ReportScheduler> scheduler_; + FakeRequestTimer* timer_; + policy::MockCloudPolicyClient* client_; + policy::FakeBrowserDMTokenStorage storage_; + base::Time previous_set_last_upload_timestamp_; + + private: + std::unique_ptr<policy::MockCloudPolicyClient> client_ptr_; + std::unique_ptr<FakeRequestTimer> timer_ptr_; + DISALLOW_COPY_AND_ASSIGN(ReportSchedulerTest); +}; + +TEST_F(ReportSchedulerTest, NoReportWithoutPolicy) { + Init(false, kDMToken, kClientId); + CreateScheduler(); + EXPECT_FALSE(timer_->is_running()); +} + +TEST_F(ReportSchedulerTest, NoReportWithoutDMToken) { + Init(true, "", kClientId); + CreateScheduler(); + EXPECT_FALSE(timer_->is_running()); +} + +TEST_F(ReportSchedulerTest, NoReportWithoutClientId) { + Init(true, kDMToken, ""); + CreateScheduler(); + EXPECT_FALSE(timer_->is_running()); +} + +TEST_F(ReportSchedulerTest, UploadReportSucceeded) { + EXPECT_CALL(*client_, SetupRegistration(kDMToken, kClientId, _)); + EXPECT_CALL(*client_, UploadChromeDesktopReportProxy(_, _)) + .WillOnce(WithArgs<1>(policy::ScheduleStatusCallback(true))); + + CreateScheduler(); + EXPECT_TRUE(timer_->is_running()); + + timer_->Fire(); + + // timer is paused until the report is finished. + EXPECT_FALSE(timer_->is_running()); + + // Run pending task. + scoped_task_environment_.FastForwardBy(base::TimeDelta()); + + // Next report is scheduled. + EXPECT_TRUE(timer_->is_running()); + ExpectLastUploadTimestampUpdated(true); + + ::testing::Mock::VerifyAndClearExpectations(client_); +} + +TEST_F(ReportSchedulerTest, UploadFailed) { + EXPECT_CALL(*client_, SetupRegistration(kDMToken, kClientId, _)); + EXPECT_CALL(*client_, UploadChromeDesktopReportProxy(_, _)) + .WillOnce(WithArgs<1>(policy::ScheduleStatusCallback(false))); + + CreateScheduler(); + EXPECT_TRUE(timer_->is_running()); + + timer_->Fire(); + + // timer is paused until the report is finished. + EXPECT_FALSE(timer_->is_running()); + + // Run pending task. + scoped_task_environment_.FastForwardBy(base::TimeDelta()); + + // Next report is not scheduled. + EXPECT_FALSE(timer_->is_running()); + ExpectLastUploadTimestampUpdated(false); + + ::testing::Mock::VerifyAndClearExpectations(client_); +} + +TEST_F(ReportSchedulerTest, TimerDelayWithLastUploadTimestamp) { + int gap = 10; + SetLastUploadInHour(gap); + + EXPECT_CALL(*client_, SetupRegistration(kDMToken, kClientId, _)); + + CreateScheduler(); + EXPECT_TRUE(timer_->is_running()); + + EXPECT_EQ(base::TimeDelta::FromHours(kDefaultUploadInterval - gap), + timer_->first_delay()); + EXPECT_EQ(base::TimeDelta::FromHours(kDefaultUploadInterval), + timer_->repeat_delay()); + + ::testing::Mock::VerifyAndClearExpectations(client_); +} + +TEST_F(ReportSchedulerTest, TimerDelayWithoutLastUploadTimestamp) { + EXPECT_CALL(*client_, SetupRegistration(kDMToken, kClientId, _)); + + CreateScheduler(); + EXPECT_TRUE(timer_->is_running()); + + EXPECT_GT(base::TimeDelta(), timer_->first_delay()); + EXPECT_EQ(base::TimeDelta::FromHours(kDefaultUploadInterval), + timer_->repeat_delay()); + + ::testing::Mock::VerifyAndClearExpectations(client_); +} + +TEST_F(ReportSchedulerTest, + ReportingIsDisabledWhileNewReportIsScheduledButNotPosted) { + EXPECT_CALL(*client_, SetupRegistration(kDMToken, kClientId, _)); + + CreateScheduler(); + EXPECT_TRUE(timer_->is_running()); + + ToggleCloudReport(false); + + // Next report is not scheduled. + EXPECT_FALSE(timer_->is_running()); + ExpectLastUploadTimestampUpdated(false); + + ::testing::Mock::VerifyAndClearExpectations(client_); +} + +TEST_F(ReportSchedulerTest, ReportingIsDisabledWhileNewReportIsPosted) { + EXPECT_CALL(*client_, SetupRegistration(kDMToken, kClientId, _)); + EXPECT_CALL(*client_, UploadChromeDesktopReportProxy(_, _)) + .WillOnce(WithArgs<1>(policy::ScheduleStatusCallback(true))); + + CreateScheduler(); + EXPECT_TRUE(timer_->is_running()); + + timer_->Fire(); + ToggleCloudReport(false); + EXPECT_FALSE(timer_->is_running()); + + // Run pending task. + scoped_task_environment_.FastForwardBy(base::TimeDelta()); + + ExpectLastUploadTimestampUpdated(true); + // Next report is not scheduled. + EXPECT_FALSE(timer_->is_running()); + + ::testing::Mock::VerifyAndClearExpectations(client_); +} + +} // namespace enterprise_reporting
diff --git a/chrome/browser/enterprise_reporting/request_timer.h b/chrome/browser/enterprise_reporting/request_timer.h index 48f2a2e..2522d5a 100644 --- a/chrome/browser/enterprise_reporting/request_timer.h +++ b/chrome/browser/enterprise_reporting/request_timer.h
@@ -17,22 +17,22 @@ class RequestTimer { public: RequestTimer(); - ~RequestTimer(); + virtual ~RequestTimer(); // Starts the timer. The first task will be ran after |first_delay|. The // following task will be ran with |repeat_delay|. If |first_delay| is larger // than the |repeat_delay|, the first request will be fired after // |repeat_delay| instead. Also, please note that the repeating task is ran // once per Reset call. - void Start(const base::Location& posted_from, - base::TimeDelta first_delay, - base::TimeDelta repeat_delay, - base::RepeatingClosure user_task); + virtual void Start(const base::Location& posted_from, + base::TimeDelta first_delay, + base::TimeDelta repeat_delay, + base::RepeatingClosure user_task); // Stops the timer. The running task will not be abandon. - void Stop(); + virtual void Stop(); // Resets the timer, ran the task again after |repat_delay| that is set in // Start(); This is only available after the first task is ran. - void Reset(); + virtual void Reset(); bool IsRepeatTimerRunning() const; bool IsFirstTimerRunning() const;
diff --git a/chrome/browser/extensions/system_display/display_info_provider_chromeos_unittest.cc b/chrome/browser/extensions/system_display/display_info_provider_chromeos_unittest.cc index 86d1373..cdc589f 100644 --- a/chrome/browser/extensions/system_display/display_info_provider_chromeos_unittest.cc +++ b/chrome/browser/extensions/system_display/display_info_provider_chromeos_unittest.cc
@@ -80,14 +80,21 @@ new DisplayInfoProviderChromeOS(connector_.get())); tablet_mode_client_ = std::make_unique<TabletModeClient>(); - ash::mojom::TabletModeControllerPtr controller; - ash::Shell::Get()->tablet_mode_controller()->BindRequest( - mojo::MakeRequest(&controller)); - tablet_mode_client_->InitForTesting(std::move(controller)); - // We must flush the TabletModeClient as we are waiting for the initial - // value to be set, as the TabletModeController sends an initial message on - // startup when it observes the PowerManagerClient. - tablet_mode_client_->FlushForTesting(); + tablet_mode_client_->Init(); + + // Wait for TabletModeController to take its initial state from the power + // manager. + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(ash::Shell::Get() + ->tablet_mode_controller() + ->IsTabletModeWindowManagerEnabled()); + } + + void TearDown() override { + ChromeAshTestBase::TearDown(); + // To match ChromeBrowserMainExtraPartsAsh, shut down the TabletModeClient + // after Shell. + tablet_mode_client_.reset(); } void AddCrosDisplayConfigControllerBinding( @@ -123,7 +130,6 @@ ash::TabletModeController* controller = ash::Shell::Get()->tablet_mode_controller(); controller->EnableTabletModeWindowManager(enable); - tablet_mode_client_->FlushForTesting(); } display::DisplayManager* GetDisplayManager() const { @@ -1571,6 +1577,9 @@ // Entering tablet mode will cause DisplayConfigurationObserver to set // forced mirror mode. https://crbug.com/733092. EnableTabletMode(true); + // DisplayConfigurationObserver enables mirror mode asynchronously after + // tablet mode is enabled. + base::RunLoop().RunUntilIdle(); EXPECT_TRUE(display_manager()->IsInMirrorMode()); result = GetAllDisplaysInfo(); ASSERT_EQ(1u, result.size());
diff --git a/chrome/browser/loader/chrome_navigation_data.cc b/chrome/browser/loader/chrome_navigation_data.cc deleted file mode 100644 index 679838b0..0000000 --- a/chrome/browser/loader/chrome_navigation_data.cc +++ /dev/null
@@ -1,60 +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 "chrome/browser/loader/chrome_navigation_data.h" - -#include "base/memory/ptr_util.h" -#include "base/supports_user_data.h" -#include "net/url_request/url_request.h" - -const void* const kChromeNavigationDataUserDataKey = - &kChromeNavigationDataUserDataKey; - -namespace { - -// UserData object that owns ChromeNavigationData. This is used rather than -// having ChromeNavigationData directly extend base::SupportsUserData::Data to -// avoid naming conflicts between Data::Clone() and -// content::NavigationData::Clone(). -class NavigationDataOwner : public base::SupportsUserData::Data { - public: - NavigationDataOwner() = default; - ~NavigationDataOwner() override = default; - - ChromeNavigationData* data() { return &data_; } - - private: - ChromeNavigationData data_; - - DISALLOW_COPY_AND_ASSIGN(NavigationDataOwner); -}; - -} // namespace - -ChromeNavigationData::ChromeNavigationData() {} - -ChromeNavigationData::~ChromeNavigationData() {} - -// static -ChromeNavigationData* ChromeNavigationData::GetDataAndCreateIfNecessary( - net::URLRequest* request) { - if (!request) - return nullptr; - NavigationDataOwner* data_owner_ptr = static_cast<NavigationDataOwner*>( - request->GetUserData(kChromeNavigationDataUserDataKey)); - if (data_owner_ptr) - return data_owner_ptr->data(); - std::unique_ptr<NavigationDataOwner> data_owner = - std::make_unique<NavigationDataOwner>(); - data_owner_ptr = data_owner.get(); - request->SetUserData(kChromeNavigationDataUserDataKey, std::move(data_owner)); - return data_owner_ptr->data(); -} - -std::unique_ptr<content::NavigationData> ChromeNavigationData::Clone() { - std::unique_ptr<ChromeNavigationData> copy(new ChromeNavigationData()); - if (data_reduction_proxy_data_) - copy->SetDataReductionProxyData(data_reduction_proxy_data_->DeepCopy()); - return std::move(copy); -}
diff --git a/chrome/browser/loader/chrome_navigation_data.h b/chrome/browser/loader/chrome_navigation_data.h deleted file mode 100644 index 923e3f3..0000000 --- a/chrome/browser/loader/chrome_navigation_data.h +++ /dev/null
@@ -1,52 +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 CHROME_BROWSER_LOADER_CHROME_NAVIGATION_DATA_H_ -#define CHROME_BROWSER_LOADER_CHROME_NAVIGATION_DATA_H_ - -#include <memory> - -#include "base/macros.h" -#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h" -#include "content/public/browser/navigation_data.h" - -namespace net { -class URLRequest; -} - -class ChromeNavigationData : public content::NavigationData { - public: - ChromeNavigationData(); - ~ChromeNavigationData() override; - - // Creates a new ChromeNavigationData that is a deep copy of the original. Any - // changes to the original after the clone is created will not be reflected in - // the clone. - // |data_reduction_proxy_data_| is deep copied. - std::unique_ptr<content::NavigationData> Clone() override; - - // Takes ownership of |data_reduction_proxy_data|. - void SetDataReductionProxyData( - std::unique_ptr<data_reduction_proxy::DataReductionProxyData> - data_reduction_proxy_data) { - data_reduction_proxy_data_ = std::move(data_reduction_proxy_data); - } - - data_reduction_proxy::DataReductionProxyData* GetDataReductionProxyData() - const { - return data_reduction_proxy_data_.get(); - } - - static ChromeNavigationData* GetDataAndCreateIfNecessary( - net::URLRequest* request); - - private: - // Manages the lifetime of optional DataReductionProxy information. - std::unique_ptr<data_reduction_proxy::DataReductionProxyData> - data_reduction_proxy_data_; - - DISALLOW_COPY_AND_ASSIGN(ChromeNavigationData); -}; - -#endif // CHROME_BROWSER_LOADER_CHROME_NAVIGATION_DATA_H_
diff --git a/chrome/browser/loader/chrome_navigation_data_unittest.cc b/chrome/browser/loader/chrome_navigation_data_unittest.cc deleted file mode 100644 index 5712222..0000000 --- a/chrome/browser/loader/chrome_navigation_data_unittest.cc +++ /dev/null
@@ -1,41 +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 "chrome/browser/loader/chrome_navigation_data.h" - -#include <memory> - -#include "base/memory/ptr_util.h" -#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h" -#include "content/public/browser/navigation_data.h" -#include "testing/gtest/include/gtest/gtest.h" - -class ChromeNavigationDataTest : public testing::Test { - public: - ChromeNavigationDataTest() {} - ~ChromeNavigationDataTest() override {} -}; - -TEST_F(ChromeNavigationDataTest, AddingDataReductionProxyData) { - std::unique_ptr<ChromeNavigationData> data(new ChromeNavigationData()); - data_reduction_proxy::DataReductionProxyData* data_reduction_proxy_data = - new data_reduction_proxy::DataReductionProxyData(); - data->SetDataReductionProxyData(base::WrapUnique(data_reduction_proxy_data)); - EXPECT_EQ(data_reduction_proxy_data, data->GetDataReductionProxyData()); -} - -TEST_F(ChromeNavigationDataTest, Clone) { - ChromeNavigationData data; - EXPECT_FALSE(data.GetDataReductionProxyData()); - data.SetDataReductionProxyData( - std::make_unique<data_reduction_proxy::DataReductionProxyData>()); - - std::unique_ptr<content::NavigationData> clone_data = data.Clone(); - ChromeNavigationData* clone_chrome_data = - static_cast<ChromeNavigationData*>(clone_data.get()); - EXPECT_NE(&data, clone_data.get()); - EXPECT_NE(&data, clone_chrome_data); - EXPECT_NE(data.GetDataReductionProxyData(), - clone_chrome_data->GetDataReductionProxyData()); -}
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 307086b..57042173 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
@@ -12,7 +12,6 @@ #include "base/time/time.h" #include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h" #include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings_factory.h" -#include "chrome/browser/loader/chrome_navigation_data.h" #include "chrome/browser/page_load_metrics/page_load_metrics_observer.h" #include "chrome/browser/page_load_metrics/page_load_metrics_util.h" #include "chrome/browser/previews/previews_ui_tab_helper.h" @@ -25,7 +24,6 @@ #include "components/data_reduction_proxy/proto/pageload_metrics.pb.h" #include "components/previews/content/previews_user_data.h" #include "content/public/browser/browser_context.h" -#include "content/public/browser/navigation_data.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" @@ -131,11 +129,6 @@ ukm::SourceId source_id) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // As documented in content/public/browser/navigation_handle.h, this - // NavigationData is a clone of the NavigationData instance returned from - // ResourceDispatcherHostDelegate::GetNavigationData during commit. - // Because ChromeResourceDispatcherHostDelegate always returns a - // ChromeNavigationData, it is safe to static_cast here. std::unique_ptr<DataReductionProxyData> data; auto* settings = DataReductionProxyChromeSettingsFactory::GetForBrowserContext(
diff --git a/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_base_unittest.cc b/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_base_unittest.cc index 8c5a827..d0edf45 100644 --- a/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_base_unittest.cc +++ b/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_base_unittest.cc
@@ -11,7 +11,8 @@ #include "base/process/kill.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" -#include "chrome/browser/loader/chrome_navigation_data.h" +#include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h" +#include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings_factory.h" #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h" #include "chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_test_utils.h" #include "chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h" @@ -26,6 +27,7 @@ #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h" #include "components/previews/content/previews_user_data.h" +#include "content/public/browser/web_contents.h" #include "content/public/test/web_contents_tester.h" #include "net/base/ip_endpoint.h" #include "services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h" @@ -61,13 +63,17 @@ // DataReductionProxyMetricsObserverBase: ObservePolicy OnCommitCalled(content::NavigationHandle* navigation_handle, ukm::SourceId source_id) override { - DataReductionProxyData* data = - DataForNavigationHandle(web_contents_, navigation_handle); + auto data = + std::make_unique<data_reduction_proxy::DataReductionProxyData>(); + data->set_request_url(navigation_handle->GetURL()); data->set_used_data_reduction_proxy(data_reduction_proxy_used_); data->set_was_cached_data_reduction_proxy_response( cached_data_reduction_proxy_used_); data->set_request_url(GURL(kDefaultTestUrl)); data->set_lite_page_received(lite_page_used_); + DataReductionProxyChromeSettingsFactory::GetForBrowserContext( + web_contents_->GetBrowserContext()) + ->SetDataForNextCommitForTesting(std::move(data)); auto* previews_data = PreviewsDataForNavigationHandle(navigation_handle); previews_data->set_black_listed_for_lite_page(black_listed_);
diff --git a/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_test_utils.cc b/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_test_utils.cc index 1d29d9d9..c66f3abf 100644 --- a/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_test_utils.cc +++ b/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_test_utils.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_test_utils.h" -#include "chrome/browser/loader/chrome_navigation_data.h" #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h" #include "chrome/browser/page_load_metrics/page_load_metrics_observer.h" #include "chrome/browser/page_load_metrics/page_load_tracker.h" @@ -13,20 +12,6 @@ namespace data_reduction_proxy { -DataReductionProxyData* DataForNavigationHandle( - content::WebContents* web_contents, - content::NavigationHandle* navigation_handle) { - auto chrome_navigation_data = std::make_unique<ChromeNavigationData>(); - - auto drp_data = std::make_unique<DataReductionProxyData>(); - DataReductionProxyData* data = drp_data.get(); - chrome_navigation_data->SetDataReductionProxyData(std::move(drp_data)); - - content::WebContentsTester::For(web_contents) - ->SetNavigationData(navigation_handle, std::move(chrome_navigation_data)); - return data; -} - previews::PreviewsUserData* PreviewsDataForNavigationHandle( content::NavigationHandle* navigation_handle) { PreviewsUITabHelper* ui_tab_helper =
diff --git a/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_test_utils.h b/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_test_utils.h index 290a0d6..cb7758c0 100644 --- a/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_test_utils.h +++ b/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_test_utils.h
@@ -19,7 +19,6 @@ #include "chrome/common/page_load_metrics/test/page_load_metrics_test_util.h" #include "components/data_reduction_proxy/content/browser/data_reduction_proxy_page_load_timing.h" #include "components/data_reduction_proxy/content/browser/data_reduction_proxy_pingback_client_impl.h" -#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h" #include "components/previews/content/previews_user_data.h" #include "net/nqe/effective_connection_type.h" #include "third_party/blink/public/platform/web_input_event.h" @@ -29,12 +28,6 @@ const char kDefaultTestUrl[] = "http://google.com"; const int kMemoryKb = 1024; -// Attaches a new |DataReductionProxyData| to |navigation_handle|'s navigation -// data. -DataReductionProxyData* DataForNavigationHandle( - content::WebContents* web_contents, - content::NavigationHandle* navigation_handle); - // Attaches a new |PreviewsUserData| to the given |navigation_handle|. previews::PreviewsUserData* PreviewsDataForNavigationHandle( content::NavigationHandle* navigation_handle);
diff --git a/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_unittest.cc index c1eb752c..682edef 100644 --- a/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_unittest.cc +++ b/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_unittest.cc
@@ -10,12 +10,15 @@ #include "base/metrics/field_trial.h" #include "base/time/time.h" +#include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h" +#include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings_factory.h" #include "chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_test_utils.h" #include "chrome/browser/page_load_metrics/observers/histogram_suffixes.h" #include "chrome/browser/page_load_metrics/page_load_tracker.h" #include "components/data_reduction_proxy/content/browser/data_reduction_proxy_pingback_client_impl.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h" #include "components/previews/content/previews_user_data.h" +#include "content/public/browser/web_contents.h" namespace data_reduction_proxy { @@ -43,13 +46,17 @@ // DataReductionProxyMetricsObserver: ObservePolicy OnCommitCalled(content::NavigationHandle* navigation_handle, ukm::SourceId source_id) override { - DataReductionProxyData* data = - DataForNavigationHandle(web_contents_, navigation_handle); + auto data = + std::make_unique<data_reduction_proxy::DataReductionProxyData>(); + data->set_request_url(navigation_handle->GetURL()); data->set_used_data_reduction_proxy(data_reduction_proxy_used_); data->set_was_cached_data_reduction_proxy_response( cached_data_reduction_proxy_used_); data->set_request_url(GURL(kDefaultTestUrl)); data->set_lite_page_received(lite_page_used_); + DataReductionProxyChromeSettingsFactory::GetForBrowserContext( + web_contents_->GetBrowserContext()) + ->SetDataForNextCommitForTesting(std::move(data)); auto* previews_data = PreviewsDataForNavigationHandle(navigation_handle); previews_data->set_black_listed_for_lite_page(black_listed_);
diff --git a/chrome/browser/page_load_metrics/observers/previews_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/previews_page_load_metrics_observer.cc index 147d208..2a4a2b4 100644 --- a/chrome/browser/page_load_metrics/observers/previews_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/previews_page_load_metrics_observer.cc
@@ -10,7 +10,6 @@ #include "base/time/time.h" #include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h" #include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings_factory.h" -#include "chrome/browser/loader/chrome_navigation_data.h" #include "chrome/browser/page_load_metrics/page_load_metrics_observer.h" #include "chrome/browser/page_load_metrics/page_load_metrics_util.h" #include "chrome/browser/previews/previews_content_util.h"
diff --git a/chrome/browser/page_load_metrics/observers/previews_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/previews_page_load_metrics_observer_unittest.cc index 59c49b89..cda6175 100644 --- a/chrome/browser/page_load_metrics/observers/previews_page_load_metrics_observer_unittest.cc +++ b/chrome/browser/page_load_metrics/observers/previews_page_load_metrics_observer_unittest.cc
@@ -15,7 +15,6 @@ #include "base/optional.h" #include "base/test/scoped_feature_list.h" #include "base/time/time.h" -#include "chrome/browser/loader/chrome_navigation_data.h" #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"
diff --git a/chrome/browser/password_manager/password_accessory_controller_impl.cc b/chrome/browser/password_manager/password_accessory_controller_impl.cc index 16416aa..90777fd 100644 --- a/chrome/browser/password_manager/password_accessory_controller_impl.cc +++ b/chrome/browser/password_manager/password_accessory_controller_impl.cc
@@ -186,6 +186,14 @@ void PasswordAccessoryControllerImpl::RefreshSuggestionsForField( FocusedFieldType focused_field_type, bool is_manual_generation_available) { + // Prevent crashing by not acting at all if frame became unfocused at any + // point. The next time a focus event happens, this will be called again and + // ensure we show correct data. + if (web_contents_->GetFocusedFrame() == nullptr) + return; + url::Origin origin = GetFocusedFrameOrigin(); + if (origin.opaque()) + return; // Don't proceed for invalid origins. std::vector<UserInfo> info_to_add; std::vector<FooterCommand> footer_commands_to_add; @@ -219,10 +227,10 @@ GetManualFillingController()->RefreshSuggestionsForField( focused_field_type, - autofill::CreateAccessorySheetData( - autofill::AccessoryTabType::PASSWORDS, - GetTitle(has_suggestions, GetFocusedFrameOrigin()), - std::move(info_to_add), std::move(footer_commands_to_add))); + autofill::CreateAccessorySheetData(autofill::AccessoryTabType::PASSWORDS, + GetTitle(has_suggestions, origin), + std::move(info_to_add), + std::move(footer_commands_to_add))); if (is_password_field) { GetManualFillingController()->ShowWhenKeyboardIsVisible( @@ -243,6 +251,8 @@ base::OnceCallback<void(const gfx::Image&)> icon_callback) { url::Origin origin = GetFocusedFrameOrigin(); // Copy origin in case it changes. + if (origin.opaque()) + return; // Don't proceed for invalid origins. // Check whether this request can be immediately answered with a cached icon. // It is empty if there wasn't at least one request that found an icon yet. FaviconRequestData* icon_request = &icons_request_data_[origin]; @@ -314,6 +324,8 @@ const base::string16& suggestion, bool is_password, const url::Origin& origin) const { + if (origin.opaque()) + return false; // Don't proceed for invalid origins. for (const PasswordAccessorySuggestion& element : origin_suggestions_.at(origin)) { const base::string16& candidate = @@ -333,6 +345,11 @@ } url::Origin PasswordAccessoryControllerImpl::GetFocusedFrameOrigin() const { + if (web_contents_->GetFocusedFrame() == nullptr) { + LOG(DFATAL) << "Tried to get retrieve origin without focused " + "frame."; + return url::Origin(); // Nonce! + } return web_contents_->GetFocusedFrame()->GetLastCommittedOrigin(); }
diff --git a/chrome/browser/performance_manager/decorators/frozen_frame_aggregator.cc b/chrome/browser/performance_manager/decorators/frozen_frame_aggregator.cc index 8dc9f42..ead87197 100644 --- a/chrome/browser/performance_manager/decorators/frozen_frame_aggregator.cc +++ b/chrome/browser/performance_manager/decorators/frozen_frame_aggregator.cc
@@ -34,8 +34,7 @@ } static void NotifyAllFramesInProcessFrozen(ProcessNodeImpl* process_node) { - for (auto& observer : process_node->observers()) - observer.OnAllFramesInProcessFrozen(process_node); + process_node->OnAllFramesInProcessFrozen(); } };
diff --git a/chrome/browser/performance_manager/decorators/frozen_frame_aggregator.h b/chrome/browser/performance_manager/decorators/frozen_frame_aggregator.h index 496f1e1..07dbac0 100644 --- a/chrome/browser/performance_manager/decorators/frozen_frame_aggregator.h +++ b/chrome/browser/performance_manager/decorators/frozen_frame_aggregator.h
@@ -16,7 +16,7 @@ // The FrozenFrameAggregator is responsible for tracking frame frozen states, // and aggregating this property to the page and process nodes. -class FrozenFrameAggregator : public GraphObserverDefaultImpl { +class FrozenFrameAggregator : public GraphImplObserverDefaultImpl { public: struct Data;
diff --git a/chrome/browser/performance_manager/decorators/frozen_frame_aggregator_unittest.cc b/chrome/browser/performance_manager/decorators/frozen_frame_aggregator_unittest.cc index df27098..7f182e9 100644 --- a/chrome/browser/performance_manager/decorators/frozen_frame_aggregator_unittest.cc +++ b/chrome/browser/performance_manager/decorators/frozen_frame_aggregator_unittest.cc
@@ -20,7 +20,7 @@ using LifecycleState = PageNodeImpl::LifecycleState; -class LenientMockGraphObserver : public GraphObserverDefaultImpl { +class LenientMockGraphObserver : public GraphImplObserverDefaultImpl { public: LenientMockGraphObserver() = default; ~LenientMockGraphObserver() override = default;
diff --git a/chrome/browser/performance_manager/decorators/page_almost_idle_decorator.h b/chrome/browser/performance_manager/decorators/page_almost_idle_decorator.h index 67dfcdc..f9a9672 100644 --- a/chrome/browser/performance_manager/decorators/page_almost_idle_decorator.h +++ b/chrome/browser/performance_manager/decorators/page_almost_idle_decorator.h
@@ -19,7 +19,7 @@ // reached an "almost idle" state after initial load, based on CPU and network // quiescence, as well as an absolute timeout. This state is then updated on // PageNodes in a graph. -class PageAlmostIdleDecorator : public GraphObserverDefaultImpl { +class PageAlmostIdleDecorator : public GraphImplObserverDefaultImpl { public: class Data;
diff --git a/chrome/browser/performance_manager/graph/frame_node.cc b/chrome/browser/performance_manager/graph/frame_node.cc index 1b36b7bc..fda0f77 100644 --- a/chrome/browser/performance_manager/graph/frame_node.cc +++ b/chrome/browser/performance_manager/graph/frame_node.cc
@@ -12,4 +12,10 @@ FrameNode::FrameNode() = default; FrameNode::~FrameNode() = default; +FrameNodeObserver::FrameNodeObserver() = default; +FrameNodeObserver::~FrameNodeObserver() = default; + +FrameNode::ObserverDefaultImpl::ObserverDefaultImpl() = default; +FrameNode::ObserverDefaultImpl::~ObserverDefaultImpl() = default; + } // namespace performance_manager
diff --git a/chrome/browser/performance_manager/graph/frame_node_impl.cc b/chrome/browser/performance_manager/graph/frame_node_impl.cc index b8db546..0e0e18b 100644 --- a/chrome/browser/performance_manager/graph/frame_node_impl.cc +++ b/chrome/browser/performance_manager/graph/frame_node_impl.cc
@@ -11,9 +11,6 @@ namespace performance_manager { -FrameNodeImplObserver::FrameNodeImplObserver() = default; -FrameNodeImplObserver::~FrameNodeImplObserver() = default; - FrameNodeImpl::FrameNodeImpl(GraphImpl* graph, ProcessNodeImpl* process_node, PageNodeImpl* page_node, @@ -104,6 +101,8 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); for (auto& observer : observers()) observer.OnNonPersistentNotificationCreated(this); + for (auto* observer : GetObservers()) + observer->OnNonPersistentNotificationCreated(this); } FrameNodeImpl* FrameNodeImpl::parent_frame_node() const { @@ -363,7 +362,4 @@ network_almost_idle.SetAndMaybeNotify(frame_node, false); } -FrameNodeImpl::ObserverDefaultImpl::ObserverDefaultImpl() = default; -FrameNodeImpl::ObserverDefaultImpl::~ObserverDefaultImpl() = default; - } // namespace performance_manager
diff --git a/chrome/browser/performance_manager/graph/frame_node_impl.h b/chrome/browser/performance_manager/graph/frame_node_impl.h index 8167cee1..0c8c628 100644 --- a/chrome/browser/performance_manager/graph/frame_node_impl.h +++ b/chrome/browser/performance_manager/graph/frame_node_impl.h
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/unguessable_token.h" #include "chrome/browser/performance_manager/graph/node_base.h" +#include "chrome/browser/performance_manager/observers/graph_observer.h" #include "chrome/browser/performance_manager/public/graph/frame_node.h" #include "url/gurl.h" @@ -20,37 +21,6 @@ class PageNodeImpl; class ProcessNodeImpl; -// Observer interface for FrameNodeImpl objects. This must be declared first as -// the type is referenced by members of FrameNodeImpl. -class FrameNodeImplObserver { - public: - FrameNodeImplObserver(); - virtual ~FrameNodeImplObserver(); - - // Notifications of property changes. - - // Invoked when the |is_current| property changes. - virtual void OnIsCurrentChanged(FrameNodeImpl* frame_node) = 0; - - // Invoked when the |network_almost_idle| property changes. - virtual void OnNetworkAlmostIdleChanged(FrameNodeImpl* frame_node) = 0; - - // Invoked when the |lifecycle_state| property changes. - virtual void OnLifecycleStateChanged(FrameNodeImpl* frame_node) = 0; - - // Invoked when the |url| property changes. - virtual void OnURLChanged(FrameNodeImpl* frame_node) = 0; - - // Events with no property changes. - - // Invoked when a non-persistent notification has been issued by the frame. - virtual void OnNonPersistentNotificationCreated( - FrameNodeImpl* frame_node) = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(FrameNodeImplObserver); -}; - // Frame nodes form a tree structure, each FrameNode at most has one parent that // is a FrameNode. Conceptually, a frame corresponds to a // content::RenderFrameHost in the browser, and a content::RenderFrameImpl / @@ -75,14 +45,12 @@ // active frame. class FrameNodeImpl : public PublicNodeImpl<FrameNodeImpl, FrameNode>, - public TypedNodeBase<FrameNodeImpl, FrameNodeImplObserver>, + public TypedNodeBase<FrameNodeImpl, + GraphImplObserver, + FrameNode, + FrameNodeObserver>, public resource_coordinator::mojom::DocumentCoordinationUnit { public: - // A do-nothing implementation of the observer. Derive from this if you want - // to selectively override a few methods and not have to worry about - // continuously updating your implementation as new methods are added. - class ObserverDefaultImpl; - static constexpr NodeTypeEnum Type() { return NodeTypeEnum::kFrame; } // Construct a frame node associated with a |process_node|, a |page_node| and @@ -160,14 +128,19 @@ void Reset(FrameNodeImpl* frame_node, const GURL& url_in); - ObservedProperty::NotifiesOnlyOnChanges<GURL, &Observer::OnURLChanged> url; + ObservedProperty::NotifiesOnlyOnChanges<GURL, + &GraphImplObserver::OnURLChanged, + &FrameNodeObserver::OnURLChanged> + url; bool has_nonempty_beforeunload = false; // Network is considered almost idle when there are no more than 2 network // connections. - ObservedProperty:: - NotifiesOnlyOnChanges<bool, &Observer::OnNetworkAlmostIdleChanged> - network_almost_idle{false}; + ObservedProperty::NotifiesOnlyOnChanges< + bool, + &GraphImplObserver::OnNetworkAlmostIdleChanged, + &FrameNodeObserver::OnNetworkAlmostIdleChanged> + network_almost_idle{false}; }; // Invoked by subframes on joining/leaving the graph. @@ -208,13 +181,17 @@ // Does *not* change when a navigation is committed. ObservedProperty::NotifiesOnlyOnChanges< resource_coordinator::mojom::LifecycleState, - &Observer::OnLifecycleStateChanged> + &GraphImplObserver::OnLifecycleStateChanged, + &FrameNodeObserver::OnLifecycleStateChanged> lifecycle_state_{resource_coordinator::mojom::LifecycleState::kRunning}; // This is a one way switch. Once marked an ad-frame, always an ad-frame. bool is_ad_frame_ = false; - ObservedProperty::NotifiesOnlyOnChanges<bool, &Observer::OnIsCurrentChanged> + ObservedProperty::NotifiesOnlyOnChanges< + bool, + &GraphImplObserver::OnIsCurrentChanged, + &FrameNodeObserver::OnIsCurrentChanged> is_current_{false}; // Intervention policy for this frame. These are communicated from the @@ -238,23 +215,6 @@ DISALLOW_COPY_AND_ASSIGN(FrameNodeImpl); }; -// A do-nothing default implementation of a FrameNodeImpl::Observer. -class FrameNodeImpl::ObserverDefaultImpl : public FrameNodeImpl::Observer { - public: - ObserverDefaultImpl(); - ~ObserverDefaultImpl() override; - - // FrameNodeImplObserver implementation: - void OnIsCurrentChanged(FrameNodeImpl* frame_node) override {} - void OnNetworkAlmostIdleChanged(FrameNodeImpl* frame_node) override {} - void OnLifecycleStateChanged(FrameNodeImpl* frame_node) override {} - void OnNonPersistentNotificationCreated(FrameNodeImpl* frame_node) override {} - void OnURLChanged(FrameNodeImpl* frame_node) override {} - - private: - DISALLOW_COPY_AND_ASSIGN(ObserverDefaultImpl); -}; - } // namespace performance_manager #endif // CHROME_BROWSER_PERFORMANCE_MANAGER_GRAPH_FRAME_NODE_IMPL_H_
diff --git a/chrome/browser/performance_manager/graph/frame_node_impl_unittest.cc b/chrome/browser/performance_manager/graph/frame_node_impl_unittest.cc index f77b99e..40a3d6f 100644 --- a/chrome/browser/performance_manager/graph/frame_node_impl_unittest.cc +++ b/chrome/browser/performance_manager/graph/frame_node_impl_unittest.cc
@@ -10,6 +10,7 @@ #include "chrome/browser/performance_manager/graph/page_node_impl.h" #include "chrome/browser/performance_manager/graph/process_node_impl.h" #include "chrome/browser/performance_manager/performance_manager_clock.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" namespace performance_manager { @@ -109,4 +110,97 @@ EXPECT_TRUE(frame_node->is_ad_frame()); } +namespace { + +class LenientMockObserver : public FrameNodeImpl::Observer { + public: + LenientMockObserver() {} + ~LenientMockObserver() override {} + + MOCK_METHOD1(OnFrameNodeAdded, void(const FrameNode*)); + MOCK_METHOD1(OnBeforeFrameNodeRemoved, void(const FrameNode*)); + MOCK_METHOD1(OnIsCurrentChanged, void(const FrameNode*)); + MOCK_METHOD1(OnNetworkAlmostIdleChanged, void(const FrameNode*)); + MOCK_METHOD1(OnLifecycleStateChanged, void(const FrameNode*)); + MOCK_METHOD1(OnNonPersistentNotificationCreated, void(const FrameNode*)); + MOCK_METHOD1(OnURLChanged, void(const FrameNode*)); + + void SetNotifiedFrameNode(const FrameNode* frame_node) { + notified_frame_node_ = frame_node; + } + + const FrameNode* TakeNotifiedFrameNode() { + const FrameNode* node = notified_frame_node_; + notified_frame_node_ = nullptr; + return node; + } + + private: + const FrameNode* notified_frame_node_ = nullptr; +}; + +using MockObserver = ::testing::StrictMock<LenientMockObserver>; + +using testing::_; +using testing::Invoke; + +} // namespace + +TEST_F(FrameNodeImplTest, ObserverWorks) { + auto process = CreateNode<ProcessNodeImpl>(); + auto page = CreateNode<PageNodeImpl>(); + + MockObserver obs; + graph()->AddFrameNodeObserver(&obs); + + // Create a frame node and expect a matching call to "OnFrameNodeAdded". + EXPECT_CALL(obs, OnFrameNodeAdded(_)) + .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedFrameNode)); + auto frame_node = CreateNode<FrameNodeImpl>(process.get(), page.get()); + const FrameNode* raw_frame_node = frame_node.get(); + EXPECT_EQ(raw_frame_node, obs.TakeNotifiedFrameNode()); + + // Invoke "SetIsCurrent" and expect a "OnIsCurrentChanged" callback. + EXPECT_CALL(obs, OnIsCurrentChanged(_)) + .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedFrameNode)); + frame_node->SetIsCurrent(true); + EXPECT_EQ(raw_frame_node, obs.TakeNotifiedFrameNode()); + + // Invoke "SetNetworkAlmostIdle" and expect an "OnNetworkAlmostIdleChanged" + // callback. + EXPECT_CALL(obs, OnNetworkAlmostIdleChanged(_)) + .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedFrameNode)); + frame_node->SetNetworkAlmostIdle(); + EXPECT_EQ(raw_frame_node, obs.TakeNotifiedFrameNode()); + + // Invoke "SetLifecycleState" and expect an "OnLifecycleStateChanged" + // callback. + EXPECT_CALL(obs, OnLifecycleStateChanged(_)) + .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedFrameNode)); + frame_node->SetLifecycleState( + resource_coordinator::mojom::LifecycleState::kFrozen); + EXPECT_EQ(raw_frame_node, obs.TakeNotifiedFrameNode()); + + // Invoke "OnNonPersistentNotificationCreated" and expect an + // "OnNonPersistentNotificationCreated" callback. + EXPECT_CALL(obs, OnNonPersistentNotificationCreated(_)) + .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedFrameNode)); + frame_node->OnNonPersistentNotificationCreated(); + EXPECT_EQ(raw_frame_node, obs.TakeNotifiedFrameNode()); + + // Invoke "OnNavigationCommitted" and expect an "OnURLChanged" callback. + EXPECT_CALL(obs, OnURLChanged(_)) + .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedFrameNode)); + frame_node->OnNavigationCommitted(GURL("https://foo.com/"), true); + EXPECT_EQ(raw_frame_node, obs.TakeNotifiedFrameNode()); + + // Release the frame node and expect a call to "OnBeforeFrameNodeRemoved". + EXPECT_CALL(obs, OnBeforeFrameNodeRemoved(_)) + .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedFrameNode)); + frame_node.reset(); + EXPECT_EQ(raw_frame_node, obs.TakeNotifiedFrameNode()); + + graph()->RemoveFrameNodeObserver(&obs); +} + } // namespace performance_manager
diff --git a/chrome/browser/performance_manager/graph/graph.cc b/chrome/browser/performance_manager/graph/graph.cc index beda5cc..27a6cf9e 100644 --- a/chrome/browser/performance_manager/graph/graph.cc +++ b/chrome/browser/performance_manager/graph/graph.cc
@@ -9,4 +9,7 @@ Graph::Graph() = default; Graph::~Graph() = default; +GraphObserver::GraphObserver() = default; +GraphObserver::~GraphObserver() = default; + } // namespace performance_manager
diff --git a/chrome/browser/performance_manager/graph/graph_impl.cc b/chrome/browser/performance_manager/graph/graph_impl.cc index af510f4..1453d8e8 100644 --- a/chrome/browser/performance_manager/graph/graph_impl.cc +++ b/chrome/browser/performance_manager/graph/graph_impl.cc
@@ -4,12 +4,15 @@ #include "chrome/browser/performance_manager/graph/graph_impl.h" +#include <algorithm> #include <utility> #include "base/bind.h" #include "base/bind_helpers.h" #include "base/containers/flat_set.h" +#include "base/logging.h" #include "base/macros.h" +#include "base/stl_util.h" #include "chrome/browser/performance_manager/graph/frame_node_impl.h" #include "chrome/browser/performance_manager/graph/node_base.h" #include "chrome/browser/performance_manager/graph/page_node_impl.h" @@ -28,6 +31,30 @@ // A unique type ID for this implementation. const uintptr_t kGraphImplType = reinterpret_cast<uintptr_t>(&kGraphImplType); +template <typename NodeObserverType> +void AddObserverImpl(std::vector<NodeObserverType*>* observers, + NodeObserverType* observer) { + DCHECK(observers); + DCHECK(observer); + auto it = std::find(observers->begin(), observers->end(), observer); + DCHECK(it == observers->end()); + observers->push_back(observer); +} + +template <typename NodeObserverType> +void RemoveObserverImpl(std::vector<NodeObserverType*>* observers, + NodeObserverType* observer) { + DCHECK(observers); + DCHECK(observer); + // We expect to find the observer in the array. + auto it = std::find(observers->begin(), observers->end(), observer); + DCHECK(it != observers->end()); + observers->erase(it); + // There should only have been one copy of the observer. + it = std::find(observers->begin(), observers->end(), observer); + DCHECK(it == observers->end()); +} + } // namespace GraphImpl::GraphImpl() { @@ -37,20 +64,87 @@ GraphImpl::~GraphImpl() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // Notify graph observers that the graph is being destroyed. + for (auto* observer : graph_observers_) + observer->OnBeforeGraphDestroyed(this); + // All observers should have been removed before the graph is deleted. + // TODO(chrisha): This will disappear, as new observers are allowed to stay + // attached at graph death. DCHECK(observers_.empty()); // All process nodes should have been removed already. DCHECK(processes_by_pid_.empty()); // Remove the system node from the graph, this should be the only node left. - if (system_node_.get()) { - RemoveNode(system_node_.get()); - system_node_.reset(); - } + ReleaseSystemNode(); DCHECK(nodes_.empty()); } +void GraphImpl::AddGraphObserver(GraphObserver* observer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + AddObserverImpl(&graph_observers_, observer); +} + +void GraphImpl::AddFrameNodeObserver(FrameNodeObserver* observer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + AddObserverImpl(&frame_node_observers_, observer); +} + +void GraphImpl::AddPageNodeObserver(PageNodeObserver* observer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + AddObserverImpl(&page_node_observers_, observer); +} + +void GraphImpl::AddProcessNodeObserver(ProcessNodeObserver* observer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + AddObserverImpl(&process_node_observers_, observer); +} + +void GraphImpl::AddSystemNodeObserver(SystemNodeObserver* observer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + AddObserverImpl(&system_node_observers_, observer); +} + +void GraphImpl::RemoveGraphObserver(GraphObserver* observer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + RemoveObserverImpl(&graph_observers_, observer); +} + +void GraphImpl::RemoveFrameNodeObserver(FrameNodeObserver* observer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + RemoveObserverImpl(&frame_node_observers_, observer); +} + +void GraphImpl::RemovePageNodeObserver(PageNodeObserver* observer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + RemoveObserverImpl(&page_node_observers_, observer); +} + +void GraphImpl::RemoveProcessNodeObserver(ProcessNodeObserver* observer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + RemoveObserverImpl(&process_node_observers_, observer); +} + +void GraphImpl::RemoveSystemNodeObserver(SystemNodeObserver* observer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + RemoveObserverImpl(&system_node_observers_, observer); +} + +void GraphImpl::RegisterObserver(GraphImplObserver* observer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + observer->SetGraph(this); + AddObserverImpl(&observers_, observer); + observer->OnRegistered(); +} + +void GraphImpl::UnregisterObserver(GraphImplObserver* observer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + RemoveObserverImpl(&observers_, observer); + observer->OnUnregistered(); + observer->SetGraph(nullptr); +} + uintptr_t GraphImpl::GetImplType() const { return kGraphImplType; } @@ -65,30 +159,10 @@ return reinterpret_cast<GraphImpl*>(const_cast<void*>(graph->GetImpl())); } -void GraphImpl::RegisterObserver(GraphObserver* observer) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - observer->SetGraph(this); - observers_.push_back(observer); - observer->OnRegistered(); -} - -void GraphImpl::UnregisterObserver(GraphObserver* observer) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - bool removed = false; - for (auto it = observers_.begin(); it != observers_.end(); ++it) { - if (*it == observer) { - observers_.erase(it); - removed = true; - observer->OnUnregistered(); - observer->SetGraph(nullptr); - break; - } - } - DCHECK(removed); -} - void GraphImpl::OnNodeAdded(NodeBase* node) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + // This handles legacy GraphImplObserver implementation. for (auto* observer : observers_) { if (observer->ShouldObserve(node)) { // TODO(chrisha): Remove this logic once all observers have been migrated. @@ -112,53 +186,74 @@ observer->OnNodeAdded(node); } } + + // This handles the strongly typed observer notifications. + switch (node->type()) { + case NodeTypeEnum::kFrame: { + auto* frame_node = FrameNodeImpl::FromNodeBase(node); + for (auto* observer : frame_node_observers_) + observer->OnFrameNodeAdded(frame_node); + } break; + case NodeTypeEnum::kPage: { + auto* page_node = PageNodeImpl::FromNodeBase(node); + for (auto* observer : page_node_observers_) + observer->OnPageNodeAdded(page_node); + } break; + case NodeTypeEnum::kProcess: { + auto* process_node = ProcessNodeImpl::FromNodeBase(node); + for (auto* observer : process_node_observers_) + observer->OnProcessNodeAdded(process_node); + } break; + case NodeTypeEnum::kSystem: { + auto* system_node = SystemNodeImpl::FromNodeBase(node); + for (auto* observer : system_node_observers_) + observer->OnSystemNodeAdded(system_node); + } break; + case NodeTypeEnum::kInvalidType: { + NOTREACHED(); + } break; + } } void GraphImpl::OnBeforeNodeRemoved(NodeBase* node) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // TODO(chrisha): Kill this logic once observer implementations use distinct - // interfaces. + // This handles the strongly typed observer notifications. switch (node->type()) { case NodeTypeEnum::kFrame: { - OnBeforeNodeRemovedImpl(FrameNodeImpl::FromNodeBase(node)); + auto* frame_node = FrameNodeImpl::FromNodeBase(node); + for (auto* observer : frame_node_observers_) + observer->OnBeforeFrameNodeRemoved(frame_node); } break; case NodeTypeEnum::kPage: { - OnBeforeNodeRemovedImpl(PageNodeImpl::FromNodeBase(node)); + auto* page_node = PageNodeImpl::FromNodeBase(node); + for (auto* observer : page_node_observers_) + observer->OnBeforePageNodeRemoved(page_node); } break; case NodeTypeEnum::kProcess: { - OnBeforeNodeRemovedImpl(ProcessNodeImpl::FromNodeBase(node)); + auto* process_node = ProcessNodeImpl::FromNodeBase(node); + for (auto* observer : process_node_observers_) + observer->OnBeforeProcessNodeRemoved(process_node); } break; case NodeTypeEnum::kSystem: { - OnBeforeNodeRemovedImpl(SystemNodeImpl::FromNodeBase(node)); + auto* system_node = SystemNodeImpl::FromNodeBase(node); + for (auto* observer : system_node_observers_) + observer->OnBeforeSystemNodeRemoved(system_node); } break; case NodeTypeEnum::kInvalidType: { NOTREACHED(); } break; } + // Dispatch to the legacy observers. + for (auto& observer : node->observers()) + observer.OnBeforeNodeRemoved(node); + // Leave the graph only after the OnBeforeNodeRemoved notification so that the // node still observes the graph invariant during that callback. node->LeaveGraph(); } -template <typename NodeType> -void GraphImpl::OnBeforeNodeRemovedImpl(NodeType* node) { - // The current observer logic ensures that OnBeforeNodeRemoved is only fired - // for nodes that had an observer added via ShouldObserve. This logic will - // be disappearing entirely, but emulate it for correctness right now. - - base::flat_set<typename NodeType::Observer*> node_observers; - for (auto& observer : node->observers()) - node_observers.insert(&observer); - - for (auto* observer : observers_) { - typename NodeType::Observer* node_observer = observer; - if (base::ContainsKey(node_observers, node_observer)) - observer->OnBeforeNodeRemoved(node); - } -} - int64_t GraphImpl::GetNextNodeSerializationId() { return ++current_node_serialization_id_; } @@ -275,14 +370,11 @@ return ret; } -GraphImpl::Observer::Observer() = default; -GraphImpl::Observer::~Observer() = default; - -GraphImpl::ObserverDefaultImpl::ObserverDefaultImpl() = default; -GraphImpl::ObserverDefaultImpl::~ObserverDefaultImpl() = default; - -void GraphImpl::ObserverDefaultImpl::SetGraph(GraphImpl* graph) { - graph_ = graph; +void GraphImpl::ReleaseSystemNode() { + if (!system_node_.get()) + return; + RemoveNode(system_node_.get()); + system_node_.reset(); } } // namespace performance_manager
diff --git a/chrome/browser/performance_manager/graph/graph_impl.h b/chrome/browser/performance_manager/graph/graph_impl.h index 48416908..937cb684 100644 --- a/chrome/browser/performance_manager/graph/graph_impl.h +++ b/chrome/browser/performance_manager/graph/graph_impl.h
@@ -23,9 +23,9 @@ namespace performance_manager { -class NodeBase; -class GraphObserver; class FrameNodeImpl; +class GraphImplObserver; +class NodeBase; class PageNodeImpl; class ProcessNodeImpl; class SystemNodeImpl; @@ -38,12 +38,7 @@ // Pure virtual observer interface. Derive from this if you want to manually // implement the whole interface, and have the compiler enforce that as new // methods are added. - class Observer; - - // A do-nothing implementation of the observer. Derive from this if you want - // to selectively override a few methods and not have to worry about - // continuously updating your implementation as new methods are added. - class ObserverDefaultImpl; + using Observer = GraphObserver; using NodeSet = std::unordered_set<NodeBase*>; @@ -51,6 +46,16 @@ ~GraphImpl() override; // Graph implementation: + void AddGraphObserver(GraphObserver* observer) override; + void AddFrameNodeObserver(FrameNodeObserver* observer) override; + void AddPageNodeObserver(PageNodeObserver* observer) override; + void AddProcessNodeObserver(ProcessNodeObserver* observer) override; + void AddSystemNodeObserver(SystemNodeObserver* observer) override; + void RemoveGraphObserver(GraphObserver* observer) override; + void RemoveFrameNodeObserver(FrameNodeObserver* observer) override; + void RemovePageNodeObserver(PageNodeObserver* observer) override; + void RemoveProcessNodeObserver(ProcessNodeObserver* observer) override; + void RemoveSystemNodeObserver(SystemNodeObserver* observer) override; uintptr_t GetImplType() const override; const void* GetImpl() const override; @@ -64,11 +69,11 @@ ukm::UkmRecorder* ukm_recorder() const { return ukm_recorder_; } // Register |observer| on the graph. - void RegisterObserver(GraphObserver* observer); + void RegisterObserver(GraphImplObserver* observer); // Unregister |observer| from observing graph changes. Note that this does not // unregister |observer| from any nodes it's subscribed to. - void UnregisterObserver(GraphObserver* observer); + void UnregisterObserver(GraphImplObserver* observer); SystemNodeImpl* FindOrCreateSystemNode(); std::vector<ProcessNodeImpl*> GetAllProcessNodes(); @@ -82,7 +87,9 @@ // Returns true if |node| is in this graph. bool NodeInGraph(const NodeBase* node); - std::vector<GraphObserver*>& observers_for_testing() { return observers_; } + std::vector<GraphImplObserver*>& observers_for_testing() { + return observers_; + } // Management functions for node owners, any node added to the graph must be // removed from the graph before it's deleted. @@ -95,17 +102,39 @@ size_t GetNodeAttachedDataCountForTesting(NodeBase* node, const void* key) const; + // Allows explicitly invoking SystemNode destruction for testing. + void ReleaseSystemNodeForTesting() { ReleaseSystemNode(); } + + protected: + friend class NodeBase; + + // Provides access to per-node-class typed observers. Exposed to nodes via + // TypedNodeBase. + template <typename Observer> + const std::vector<Observer*>& GetObservers() const; + template <> + const std::vector<FrameNodeObserver*>& GetObservers() const { + return frame_node_observers_; + } + template <> + const std::vector<PageNodeObserver*>& GetObservers() const { + return page_node_observers_; + } + template <> + const std::vector<ProcessNodeObserver*>& GetObservers() const { + return process_node_observers_; + } + template <> + const std::vector<SystemNodeObserver*>& GetObservers() const { + return system_node_observers_; + } + private: using ProcessByPidMap = std::unordered_map<base::ProcessId, ProcessNodeImpl*>; void OnNodeAdded(NodeBase* node); void OnBeforeNodeRemoved(NodeBase* node); - // Templated helper functions for removed nodes. - // TODO(chrisha): Kill this off after the observer migration. - template <typename NodeType> - void OnBeforeNodeRemovedImpl(NodeType* node); - // Returns a new serialization ID. friend class NodeBase; int64_t GetNextNodeSerializationId(); @@ -118,12 +147,23 @@ template <typename NodeType> std::vector<NodeType*> GetAllNodesOfType(); + void ReleaseSystemNode(); + std::unique_ptr<SystemNodeImpl> system_node_; NodeSet nodes_; ProcessByPidMap processes_by_pid_; - std::vector<GraphObserver*> observers_; + std::vector<GraphImplObserver*> observers_; ukm::UkmRecorder* ukm_recorder_ = nullptr; + // Typed observers. + // TODO(chrisha): We should wrap these containers in something that catches + // invalid reentrant usage in DCHECK builds. + std::vector<GraphObserver*> graph_observers_; + std::vector<FrameNodeObserver*> frame_node_observers_; + std::vector<PageNodeObserver*> page_node_observers_; + std::vector<ProcessNodeObserver*> process_node_observers_; + std::vector<SystemNodeObserver*> system_node_observers_; + // User data storage for the graph. friend class NodeAttachedDataMapHelper; using NodeAttachedDataKey = std::pair<const NodeBase*, const void*>; @@ -138,54 +178,6 @@ DISALLOW_COPY_AND_ASSIGN(GraphImpl); }; -// Observer interface for GraphImpl objects. -class GraphImpl::Observer { - public: - Observer(); - virtual ~Observer(); - - // Invoked when an observer is added to or removed from the graph. This is a - // convenient place for observers to initialize any necessary state, validate - // graph invariants, etc. - virtual void OnRegistered() = 0; - virtual void OnUnregistered() = 0; - - // Called whenever a node has been added to the graph. - virtual void OnNodeAdded(NodeBase* node) = 0; - - // Called when the |node| is about to be removed from the graph. - virtual void OnBeforeNodeRemoved(NodeBase* node) = 0; - - // This will be called with a non-null |graph| when the observer is attached - // to a graph, and then again with a null |graph| when the observer is - // removed. - virtual void SetGraph(GraphImpl* graph) = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(Observer); -}; - -// A do-nothing default implementation of a GraphImplObserver. -class GraphImpl::ObserverDefaultImpl : public GraphImpl::Observer { - public: - ObserverDefaultImpl(); - ~ObserverDefaultImpl() override; - - // GraphImplObserver implementation: - void OnRegistered() override {} - void OnUnregistered() override {} - void OnNodeAdded(NodeBase* node) override {} - void OnBeforeNodeRemoved(NodeBase* node) override {} - void SetGraph(GraphImpl* graph) override; - - GraphImpl* graph() const { return graph_; } - - private: - GraphImpl* graph_ = nullptr; - - DISALLOW_COPY_AND_ASSIGN(ObserverDefaultImpl); -}; - } // namespace performance_manager #endif // CHROME_BROWSER_PERFORMANCE_MANAGER_GRAPH_GRAPH_IMPL_H_
diff --git a/chrome/browser/performance_manager/graph/graph_impl_unittest.cc b/chrome/browser/performance_manager/graph/graph_impl_unittest.cc index 4a01e059..dc62b1a 100644 --- a/chrome/browser/performance_manager/graph/graph_impl_unittest.cc +++ b/chrome/browser/performance_manager/graph/graph_impl_unittest.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/performance_manager/graph/graph_impl.h" +#include "base/memory/ptr_util.h" #include "base/process/process.h" #include "base/time/time.h" #include "chrome/browser/performance_manager/graph/frame_node_impl.h" @@ -11,6 +12,7 @@ #include "chrome/browser/performance_manager/graph/mock_graphs.h" #include "chrome/browser/performance_manager/graph/process_node_impl.h" #include "chrome/browser/performance_manager/graph/system_node_impl.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" namespace performance_manager { @@ -129,4 +131,34 @@ NodeBase::GetSerializationId(system)); } +namespace { + +class LenientMockObserver : public GraphObserver { + public: + LenientMockObserver() {} + ~LenientMockObserver() override {} + + MOCK_METHOD1(OnBeforeGraphDestroyed, void(const Graph*)); +}; + +using MockObserver = ::testing::StrictMock<LenientMockObserver>; + +using testing::_; +using testing::Invoke; + +} // namespace + +TEST(GraphImplTest, ObserverWorks) { + std::unique_ptr<GraphImpl> graph = base::WrapUnique(new GraphImpl()); + const Graph* raw_graph = graph.get(); + + MockObserver obs; + graph->AddGraphObserver(&obs); + graph->RemoveGraphObserver(&obs); + graph->AddGraphObserver(&obs); + + EXPECT_CALL(obs, OnBeforeGraphDestroyed(raw_graph)); + graph.reset(); +} + } // namespace performance_manager
diff --git a/chrome/browser/performance_manager/graph/node_base.cc b/chrome/browser/performance_manager/graph/node_base.cc index 715b53e..bee720f 100644 --- a/chrome/browser/performance_manager/graph/node_base.cc +++ b/chrome/browser/performance_manager/graph/node_base.cc
@@ -37,22 +37,6 @@ return node->serialization_id_; } -// TODO(chrisha): Remove this! -void NodeBase::RemoveObserver(GraphObserver* observer) { - switch (type()) { - case NodeTypeEnum::kFrame: - return FrameNodeImpl::FromNodeBase(this)->RemoveObserver(observer); - case NodeTypeEnum::kPage: - return PageNodeImpl::FromNodeBase(this)->RemoveObserver(observer); - case NodeTypeEnum::kProcess: - return ProcessNodeImpl::FromNodeBase(this)->RemoveObserver(observer); - case NodeTypeEnum::kSystem: - return SystemNodeImpl::FromNodeBase(this)->RemoveObserver(observer); - case NodeTypeEnum::kInvalidType: - NOTREACHED(); - } -} - void NodeBase::JoinGraph() { DCHECK(graph_->NodeInGraph(this)); }
diff --git a/chrome/browser/performance_manager/graph/node_base.h b/chrome/browser/performance_manager/graph/node_base.h index a7af0b0..d8ecf3e5 100644 --- a/chrome/browser/performance_manager/graph/node_base.h +++ b/chrome/browser/performance_manager/graph/node_base.h
@@ -24,8 +24,8 @@ namespace performance_manager { -// TODO(chrisha): Remove all of these when GraphObserver is killed. -class GraphObserver; +// TODO(chrisha): Remove this when GraphImplObserver is killed. +class GraphImplObserver; // NodeBase implements shared functionality among different types of graph // nodes. A specific type of graph node will derive from this class and can @@ -35,6 +35,9 @@ // All methods not documented otherwise are single-threaded. class NodeBase { public: + using ObserverList = + typename base::ObserverList<GraphImplObserver>::Unchecked; + // TODO(siggi): Don't store the node type, expose it on a virtual function // instead. NodeBase(NodeTypeEnum type, GraphImpl* graph); @@ -51,14 +54,27 @@ // provide a stable ID for serialization. static int64_t GetSerializationId(NodeBase* node); - // TODO(chrisha): Remove this after observer migration. - // Implementations of these are provided in the *_node_impl.cc translation - // units for now. - void RemoveObserver(GraphObserver* observer); + // TODO(chrisha): Remove these functions once we've moved to typed observers. + void AddObserver(GraphImplObserver* observer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + observers_.AddObserver(observer); + } + void RemoveObserver(GraphImplObserver* observer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + observers_.RemoveObserver(observer); + } + const ObserverList& observers() const { return observers_; } protected: friend class GraphImpl; + // Helper function for TypedNodeBase to access the list of typed observers + // stored in the graph. + template <typename Observer> + static const std::vector<Observer*>& GetObservers(const GraphImpl* graph) { + return graph->GetObservers<Observer>(); + } + // Called just before joining |graph_|, a good opportunity to initialize // node state. virtual void JoinGraph(); @@ -75,6 +91,9 @@ SEQUENCE_CHECKER(sequence_checker_); private: + // TODO(chrisha): Remove this once we've moved to typed observers. + ObserverList observers_; + DISALLOW_COPY_AND_ASSIGN(NodeBase); }; @@ -95,14 +114,16 @@ } }; -template <class NodeImplClass, class NodeImplObserverClass> +template <class NodeImplClass, + class NodeImplObserverClass, + class NodeClass, + class NodeObserverClass> class TypedNodeBase : public NodeBase { public: - using Observer = NodeImplObserverClass; - using ObserverList = - typename base::ObserverList<NodeImplObserverClass>::Unchecked; - using ObservedProperty = - ObservedPropertyImpl<NodeImplClass, NodeImplObserverClass>; + using ObservedProperty = ObservedPropertyImpl<NodeImplClass, + NodeImplObserverClass, + NodeClass, + NodeObserverClass>; explicit TypedNodeBase(GraphImpl* graph) : NodeBase(NodeImplClass::Type(), graph) {} @@ -117,21 +138,15 @@ return static_cast<NodeImplClass*>(node); } - void AddObserver(Observer* observer) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - observers_.AddObserver(observer); + // Convenience accessor to the per-node-class list of observers that is stored + // in the graph. + const std::vector<NodeObserverClass*>& GetObservers() const { + // Mediate through NodeBase, as it's the class that is friended by the + // GraphImpl in order to provide access. + return NodeBase::GetObservers<NodeObserverClass>(graph()); } - void RemoveObserver(Observer* observer) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - observers_.RemoveObserver(observer); - } - - const ObserverList& observers() const { return observers_; } - private: - ObserverList observers_; - DISALLOW_COPY_AND_ASSIGN(TypedNodeBase); };
diff --git a/chrome/browser/performance_manager/graph/page_node.cc b/chrome/browser/performance_manager/graph/page_node.cc index 62039887..b8f9a6ab 100644 --- a/chrome/browser/performance_manager/graph/page_node.cc +++ b/chrome/browser/performance_manager/graph/page_node.cc
@@ -12,4 +12,10 @@ PageNode::PageNode() = default; PageNode::~PageNode() = default; +PageNodeObserver::PageNodeObserver() = default; +PageNodeObserver::~PageNodeObserver() = default; + +PageNode::ObserverDefaultImpl::ObserverDefaultImpl() = default; +PageNode::ObserverDefaultImpl::~ObserverDefaultImpl() = default; + } // namespace performance_manager
diff --git a/chrome/browser/performance_manager/graph/page_node_impl.cc b/chrome/browser/performance_manager/graph/page_node_impl.cc index 7da1a30..c007d90 100644 --- a/chrome/browser/performance_manager/graph/page_node_impl.cc +++ b/chrome/browser/performance_manager/graph/page_node_impl.cc
@@ -42,9 +42,6 @@ } // namespace -PageNodeImplObserver::PageNodeImplObserver() = default; -PageNodeImplObserver::~PageNodeImplObserver() = default; - PageNodeImpl::PageNodeImpl(GraphImpl* graph, const WebContentsProxy& contents_proxy, bool is_visible) @@ -113,12 +110,16 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); for (auto& observer : observers()) observer.OnFaviconUpdated(this); + for (auto* observer : GetObservers()) + observer->OnFaviconUpdated(this); } void PageNodeImpl::OnTitleUpdated() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); for (auto& observer : observers()) observer.OnTitleUpdated(this); + for (auto* observer : GetObservers()) + observer->OnTitleUpdated(this); } void PageNodeImpl::OnMainFrameNavigationCommitted( @@ -131,6 +132,8 @@ navigation_id_ = navigation_id; for (auto& observer : observers()) observer.OnMainFrameNavigationCommitted(this); + for (auto* observer : GetObservers()) + observer->OnMainFrameNavigationCommitted(this); } base::flat_set<ProcessNodeImpl*> PageNodeImpl::GetAssociatedProcessNodes() @@ -441,7 +444,4 @@ ForFrameAndDescendents(main_frame_node, map_function); } -PageNodeImpl::ObserverDefaultImpl::ObserverDefaultImpl() = default; -PageNodeImpl::ObserverDefaultImpl::~ObserverDefaultImpl() = default; - } // namespace performance_manager
diff --git a/chrome/browser/performance_manager/graph/page_node_impl.h b/chrome/browser/performance_manager/graph/page_node_impl.h index 374abcc0..df08f37 100644 --- a/chrome/browser/performance_manager/graph/page_node_impl.h +++ b/chrome/browser/performance_manager/graph/page_node_impl.h
@@ -13,6 +13,7 @@ #include "base/time/time.h" #include "chrome/browser/performance_manager/graph/node_attached_data.h" #include "chrome/browser/performance_manager/graph/node_base.h" +#include "chrome/browser/performance_manager/observers/graph_observer.h" #include "chrome/browser/performance_manager/public/graph/page_node.h" #include "chrome/browser/performance_manager/public/web_contents_proxy.h" #include "services/metrics/public/cpp/ukm_source_id.h" @@ -24,56 +25,12 @@ class PageNodeImpl; class ProcessNodeImpl; -// Observer interface for PageNodeImpl objects. This must be declared first as -// the type is referenced by members of PageNodeImpl. -class PageNodeImplObserver { - public: - PageNodeImplObserver(); - virtual ~PageNodeImplObserver(); - - // Notifications of property changes. - - // Invoked when the |is_visible| property changes. - virtual void OnIsVisibleChanged(PageNodeImpl* page_node) = 0; - - // Invoked when the |is_loading| property changes. - virtual void OnIsLoadingChanged(PageNodeImpl* page_node) = 0; - - // Invoked when the |ukm_source_id| property changes. - virtual void OnUkmSourceIdChanged(PageNodeImpl* page_node) = 0; - - // Invoked when the |lifecycle_state| property changes. - virtual void OnLifecycleStateChanged(PageNodeImpl* page_node) = 0; - - // Invoked when the |page_almost_idle| property changes. - virtual void OnPageAlmostIdleChanged(PageNodeImpl* page_node) = 0; - - // This is fired when a main frame navigation commits. It indicates that the - // |navigation_id| and |main_frame_url| properties have changed. - virtual void OnMainFrameNavigationCommitted(PageNodeImpl* page_node) = 0; - - // Events with no property changes. - - // Fired when the tab title associated with a page changes. This property is - // not directly reflected on the node. - virtual void OnTitleUpdated(PageNodeImpl* page_node) = 0; - - // Fired when the favicon associated with a page is updated. This property is - // not directly reflected on the node. - virtual void OnFaviconUpdated(PageNodeImpl* page_node) = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(PageNodeImplObserver); -}; - class PageNodeImpl : public PublicNodeImpl<PageNodeImpl, PageNode>, - public TypedNodeBase<PageNodeImpl, PageNodeImplObserver> { + public TypedNodeBase<PageNodeImpl, + GraphImplObserver, + PageNode, + PageNodeObserver> { public: - // A do-nothing implementation of the observer. Derive from this if you want - // to selectively override a few methods and not have to worry about - // continuously updating your implementation as new methods are added. - class ObserverDefaultImpl; - using LifecycleState = resource_coordinator::mojom::LifecycleState; static constexpr NodeTypeEnum Type() { return NodeTypeEnum::kPage; } @@ -172,6 +129,10 @@ return intervention_policy_frames_reported_; } + void SetLifecycleStateForTesting(LifecycleState lifecycle_state) { + SetLifecycleState(lifecycle_state); + } + void SetPageAlmostIdleForTesting(bool page_almost_idle) { SetPageAlmostIdle(page_almost_idle); } @@ -270,25 +231,37 @@ // Page almost idle state. This is the output that is driven by the // PageAlmostIdleDecorator. - ObservedProperty::NotifiesOnlyOnChanges<bool, - &Observer::OnPageAlmostIdleChanged> + ObservedProperty::NotifiesOnlyOnChanges< + bool, + &GraphImplObserver::OnPageAlmostIdleChanged, + &PageNodeObserver::OnPageAlmostIdleChanged> page_almost_idle_{false}; // Whether or not the page is visible. Driven by browser instrumentation. // Initialized on construction. - ObservedProperty::NotifiesOnlyOnChanges<bool, &Observer::OnIsVisibleChanged> - is_visible_; + ObservedProperty::NotifiesOnlyOnChanges< + bool, + &GraphImplObserver::OnIsVisibleChanged, + &PageNodeObserver::OnIsVisibleChanged> + is_visible_{false}; // The loading state. This is driven by instrumentation in the browser // process. - ObservedProperty::NotifiesOnlyOnChanges<bool, &Observer::OnIsLoadingChanged> + ObservedProperty::NotifiesOnlyOnChanges< + bool, + &GraphImplObserver::OnIsLoadingChanged, + &PageNodeObserver::OnIsLoadingChanged> is_loading_{false}; // The UKM source ID associated with the URL of the main frame of this page. - ObservedProperty::NotifiesOnlyOnChanges<ukm::SourceId, - &Observer::OnUkmSourceIdChanged> + ObservedProperty::NotifiesOnlyOnChanges< + ukm::SourceId, + &GraphImplObserver::OnUkmSourceIdChanged, + &PageNodeObserver::OnUkmSourceIdChanged> ukm_source_id_{ukm::kInvalidSourceId}; // The lifecycle state of this page. This is aggregated from the lifecycle // state of each frame in the frame tree. - ObservedProperty::NotifiesOnlyOnChanges<LifecycleState, - &Observer::OnLifecycleStateChanged> + ObservedProperty::NotifiesOnlyOnChanges< + LifecycleState, + &GraphImplObserver::OnLifecycleStateChanged, + &PageNodeObserver::OnLifecycleStateChanged> lifecycle_state_{LifecycleState::kRunning}; // Storage for PageAlmostIdle user data. @@ -300,26 +273,6 @@ DISALLOW_COPY_AND_ASSIGN(PageNodeImpl); }; -// A do-nothing default implementation of a PageNodeImpl::Observer. -class PageNodeImpl::ObserverDefaultImpl : public PageNodeImpl::Observer { - public: - ObserverDefaultImpl(); - ~ObserverDefaultImpl() override; - - // PageNodeImpl::Observer implementation: - void OnIsVisibleChanged(PageNodeImpl* page_node) override {} - void OnIsLoadingChanged(PageNodeImpl* page_node) override {} - void OnUkmSourceIdChanged(PageNodeImpl* page_node) override {} - void OnLifecycleStateChanged(PageNodeImpl* page_node) override {} - void OnPageAlmostIdleChanged(PageNodeImpl* page_node) override {} - void OnMainFrameNavigationCommitted(PageNodeImpl* page_node) override {} - void OnTitleUpdated(PageNodeImpl* page_node) override {} - void OnFaviconUpdated(PageNodeImpl* page_node) override {} - - private: - DISALLOW_COPY_AND_ASSIGN(ObserverDefaultImpl); -}; - } // namespace performance_manager #endif // CHROME_BROWSER_PERFORMANCE_MANAGER_GRAPH_PAGE_NODE_IMPL_H_
diff --git a/chrome/browser/performance_manager/graph/page_node_impl_unittest.cc b/chrome/browser/performance_manager/graph/page_node_impl_unittest.cc index 17f5416..41abf3d1 100644 --- a/chrome/browser/performance_manager/graph/page_node_impl_unittest.cc +++ b/chrome/browser/performance_manager/graph/page_node_impl_unittest.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/performance_manager/graph/page_node_impl.h" #include "chrome/browser/performance_manager/graph/process_node_impl.h" #include "chrome/browser/performance_manager/performance_manager_clock.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" namespace performance_manager { @@ -391,4 +392,106 @@ resource_coordinator::mojom::InterventionPolicy::kOptIn, page.get()); } +namespace { + +class LenientMockObserver : public PageNodeImpl::Observer { + public: + LenientMockObserver() {} + ~LenientMockObserver() override {} + + MOCK_METHOD1(OnPageNodeAdded, void(const PageNode*)); + MOCK_METHOD1(OnBeforePageNodeRemoved, void(const PageNode*)); + MOCK_METHOD1(OnIsVisibleChanged, void(const PageNode*)); + MOCK_METHOD1(OnIsLoadingChanged, void(const PageNode*)); + MOCK_METHOD1(OnUkmSourceIdChanged, void(const PageNode*)); + MOCK_METHOD1(OnLifecycleStateChanged, void(const PageNode*)); + MOCK_METHOD1(OnPageAlmostIdleChanged, void(const PageNode*)); + MOCK_METHOD1(OnMainFrameNavigationCommitted, void(const PageNode*)); + MOCK_METHOD1(OnTitleUpdated, void(const PageNode*)); + MOCK_METHOD1(OnFaviconUpdated, void(const PageNode*)); + + void SetNotifiedPageNode(const PageNode* page_node) { + notified_page_node_ = page_node; + } + + const PageNode* TakeNotifiedPageNode() { + const PageNode* node = notified_page_node_; + notified_page_node_ = nullptr; + return node; + } + + private: + const PageNode* notified_page_node_ = nullptr; +}; + +using MockObserver = ::testing::StrictMock<LenientMockObserver>; + +using testing::_; +using testing::Invoke; + +} // namespace + +TEST_F(PageNodeImplTest, ObserverWorks) { + auto process = CreateNode<ProcessNodeImpl>(); + + MockObserver obs; + graph()->AddPageNodeObserver(&obs); + + // Create a page node and expect a matching call to "OnPageNodeAdded". + EXPECT_CALL(obs, OnPageNodeAdded(_)) + .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedPageNode)); + auto page_node = CreateNode<PageNodeImpl>(); + const PageNode* raw_page_node = page_node.get(); + EXPECT_EQ(raw_page_node, obs.TakeNotifiedPageNode()); + + EXPECT_CALL(obs, OnIsVisibleChanged(_)) + .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedPageNode)); + page_node->SetIsVisible(true); + EXPECT_EQ(raw_page_node, obs.TakeNotifiedPageNode()); + + EXPECT_CALL(obs, OnIsLoadingChanged(_)) + .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedPageNode)); + page_node->SetIsLoading(true); + EXPECT_EQ(raw_page_node, obs.TakeNotifiedPageNode()); + + EXPECT_CALL(obs, OnUkmSourceIdChanged(_)) + .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedPageNode)); + page_node->SetUkmSourceId(static_cast<ukm::SourceId>(0x1234)); + EXPECT_EQ(raw_page_node, obs.TakeNotifiedPageNode()); + + EXPECT_CALL(obs, OnLifecycleStateChanged(_)) + .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedPageNode)); + page_node->SetLifecycleStateForTesting(PageNodeImpl::LifecycleState::kFrozen); + EXPECT_EQ(raw_page_node, obs.TakeNotifiedPageNode()); + + EXPECT_CALL(obs, OnPageAlmostIdleChanged(_)) + .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedPageNode)); + page_node->SetPageAlmostIdleForTesting(true); + EXPECT_EQ(raw_page_node, obs.TakeNotifiedPageNode()); + + EXPECT_CALL(obs, OnMainFrameNavigationCommitted(_)) + .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedPageNode)); + page_node->OnMainFrameNavigationCommitted(base::TimeTicks::Now(), 0x1234ull, + GURL("https://foo.com/")); + EXPECT_EQ(raw_page_node, obs.TakeNotifiedPageNode()); + + EXPECT_CALL(obs, OnTitleUpdated(_)) + .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedPageNode)); + page_node->OnTitleUpdated(); + EXPECT_EQ(raw_page_node, obs.TakeNotifiedPageNode()); + + EXPECT_CALL(obs, OnFaviconUpdated(_)) + .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedPageNode)); + page_node->OnFaviconUpdated(); + EXPECT_EQ(raw_page_node, obs.TakeNotifiedPageNode()); + + // Release the page node and expect a call to "OnBeforePageNodeRemoved". + EXPECT_CALL(obs, OnBeforePageNodeRemoved(_)) + .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedPageNode)); + page_node.reset(); + EXPECT_EQ(raw_page_node, obs.TakeNotifiedPageNode()); + + graph()->RemovePageNodeObserver(&obs); +} + } // namespace performance_manager
diff --git a/chrome/browser/performance_manager/graph/process_node.cc b/chrome/browser/performance_manager/graph/process_node.cc index ed3a2f3..df489e6 100644 --- a/chrome/browser/performance_manager/graph/process_node.cc +++ b/chrome/browser/performance_manager/graph/process_node.cc
@@ -12,4 +12,10 @@ ProcessNode::ProcessNode() = default; ProcessNode::~ProcessNode() = default; +ProcessNodeObserver::ProcessNodeObserver() = default; +ProcessNodeObserver::~ProcessNodeObserver() = default; + +ProcessNode::ObserverDefaultImpl::ObserverDefaultImpl() = default; +ProcessNode::ObserverDefaultImpl::~ObserverDefaultImpl() = default; + } // namespace performance_manager
diff --git a/chrome/browser/performance_manager/graph/process_node_impl.cc b/chrome/browser/performance_manager/graph/process_node_impl.cc index f515d6f..c6ce2afa 100644 --- a/chrome/browser/performance_manager/graph/process_node_impl.cc +++ b/chrome/browser/performance_manager/graph/process_node_impl.cc
@@ -11,9 +11,6 @@ namespace performance_manager { -ProcessNodeImplObserver::ProcessNodeImplObserver() = default; -ProcessNodeImplObserver::~ProcessNodeImplObserver() = default; - ProcessNodeImpl::ProcessNodeImpl(GraphImpl* graph) : TypedNodeBase(graph), binding_(this) { DETACH_FROM_SEQUENCE(sequence_checker_); @@ -131,6 +128,13 @@ cumulative_cpu_usage_ = base::TimeDelta(); } +void ProcessNodeImpl::OnAllFramesInProcessFrozen() { + for (auto& observer : observers()) + observer.OnAllFramesInProcessFrozen(this); + for (auto* observer : GetObservers()) + observer->OnAllFramesInProcessFrozen(this); +} + void ProcessNodeImpl::LeaveGraph() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); NodeBase::LeaveGraph(); @@ -144,7 +148,4 @@ DCHECK(frame_nodes_.empty()); } -ProcessNodeImpl::ObserverDefaultImpl::ObserverDefaultImpl() = default; -ProcessNodeImpl::ObserverDefaultImpl::~ObserverDefaultImpl() = default; - } // namespace performance_manager
diff --git a/chrome/browser/performance_manager/graph/process_node_impl.h b/chrome/browser/performance_manager/graph/process_node_impl.h index 4fd27bc..a3c2247 100644 --- a/chrome/browser/performance_manager/graph/process_node_impl.h +++ b/chrome/browser/performance_manager/graph/process_node_impl.h
@@ -14,6 +14,7 @@ #include "chrome/browser/performance_manager/graph/node_attached_data.h" #include "chrome/browser/performance_manager/graph/node_base.h" #include "chrome/browser/performance_manager/graph/properties.h" +#include "chrome/browser/performance_manager/observers/graph_observer.h" #include "chrome/browser/performance_manager/public/graph/process_node.h" namespace performance_manager { @@ -21,31 +22,6 @@ class FrameNodeImpl; class ProcessNodeImpl; -// Observer interface for ProcessNodeImpl objects. This must be declared first -// as the type is referenced by members of ProcessNodeImpl. -class ProcessNodeImplObserver { - public: - ProcessNodeImplObserver(); - virtual ~ProcessNodeImplObserver(); - - // Notifications of property changes. - - // Invoked when a new |expected_task_queueing_duration| sample is available. - virtual void OnExpectedTaskQueueingDurationSample( - ProcessNodeImpl* process_node) = 0; - - // Invoked when the |main_thread_task_load_is_low| property changes. - virtual void OnMainThreadTaskLoadIsLow(ProcessNodeImpl* process_node) = 0; - - // Events with no property changes. - - // Fired when all frames in a process have transitioned to being frozen. - virtual void OnAllFramesInProcessFrozen(ProcessNodeImpl* process_node) = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(ProcessNodeImplObserver); -}; - // A process node follows the lifetime of a RenderProcessHost. // It may reference zero or one processes at a time, but during its lifetime, it // may reference more than one process. This can happen if the associated @@ -58,14 +34,12 @@ // 4. Back to 2. class ProcessNodeImpl : public PublicNodeImpl<ProcessNodeImpl, ProcessNode>, - public TypedNodeBase<ProcessNodeImpl, ProcessNodeImplObserver>, + public TypedNodeBase<ProcessNodeImpl, + GraphImplObserver, + ProcessNode, + ProcessNodeObserver>, public resource_coordinator::mojom::ProcessCoordinationUnit { public: - // A do-nothing implementation of the observer. Derive from this if you want - // to selectively override a few methods and not have to worry about - // continuously updating your implementation as new methods are added. - class ObserverDefaultImpl; - static constexpr NodeTypeEnum Type() { return NodeTypeEnum::kProcess; } explicit ProcessNodeImpl(GraphImpl* graph); @@ -126,6 +100,8 @@ // from the destructor of FrameNodeImpl. void RemoveFrame(FrameNodeImpl* frame_node); + void OnAllFramesInProcessFrozenForTesting() { OnAllFramesInProcessFrozen(); } + protected: void SetProcessImpl(base::Process process, base::ProcessId process_id, @@ -134,6 +110,8 @@ private: friend class FrozenFrameAggregatorAccess; + void OnAllFramesInProcessFrozen(); + void LeaveGraph() override; mojo::Binding<resource_coordinator::mojom::ProcessCoordinationUnit> binding_; @@ -148,10 +126,13 @@ ObservedProperty::NotifiesAlways< base::TimeDelta, - &Observer::OnExpectedTaskQueueingDurationSample> + &GraphImplObserver::OnExpectedTaskQueueingDurationSample, + &ProcessNodeObserver::OnExpectedTaskQueueingDurationSample> expected_task_queueing_duration_; - ObservedProperty::NotifiesOnlyOnChanges<bool, - &Observer::OnMainThreadTaskLoadIsLow> + ObservedProperty::NotifiesOnlyOnChanges< + bool, + &GraphImplObserver::OnMainThreadTaskLoadIsLow, + &ProcessNodeObserver::OnMainThreadTaskLoadIsLow> main_thread_task_load_is_low_{false}; double cpu_usage_ = 0; @@ -163,22 +144,6 @@ DISALLOW_COPY_AND_ASSIGN(ProcessNodeImpl); }; -// A do-nothing default implementation of a ProcessNodeImpl::Observer. -class ProcessNodeImpl::ObserverDefaultImpl : public ProcessNodeImpl::Observer { - public: - ObserverDefaultImpl(); - ~ObserverDefaultImpl() override; - - // ProcessNodeImpl::Observer implementation: - void OnExpectedTaskQueueingDurationSample( - ProcessNodeImpl* process_node) override {} - void OnMainThreadTaskLoadIsLow(ProcessNodeImpl* process_node) override {} - void OnAllFramesInProcessFrozen(ProcessNodeImpl* process_node) override {} - - private: - DISALLOW_COPY_AND_ASSIGN(ObserverDefaultImpl); -}; - } // namespace performance_manager #endif // CHROME_BROWSER_PERFORMANCE_MANAGER_GRAPH_PROCESS_NODE_IMPL_H_
diff --git a/chrome/browser/performance_manager/graph/process_node_impl_unittest.cc b/chrome/browser/performance_manager/graph/process_node_impl_unittest.cc index 33ca033..497e6801 100644 --- a/chrome/browser/performance_manager/graph/process_node_impl_unittest.cc +++ b/chrome/browser/performance_manager/graph/process_node_impl_unittest.cc
@@ -107,4 +107,74 @@ } } +namespace { + +class LenientMockObserver : public ProcessNodeImpl::Observer { + public: + LenientMockObserver() {} + ~LenientMockObserver() override {} + + MOCK_METHOD1(OnProcessNodeAdded, void(const ProcessNode*)); + MOCK_METHOD1(OnBeforeProcessNodeRemoved, void(const ProcessNode*)); + MOCK_METHOD1(OnExpectedTaskQueueingDurationSample, void(const ProcessNode*)); + MOCK_METHOD1(OnMainThreadTaskLoadIsLow, void(const ProcessNode*)); + MOCK_METHOD1(OnAllFramesInProcessFrozen, void(const ProcessNode*)); + + void SetNotifiedProcessNode(const ProcessNode* process_node) { + notified_process_node_ = process_node; + } + + const ProcessNode* TakeNotifiedProcessNode() { + const ProcessNode* node = notified_process_node_; + notified_process_node_ = nullptr; + return node; + } + + private: + const ProcessNode* notified_process_node_ = nullptr; +}; + +using MockObserver = ::testing::StrictMock<LenientMockObserver>; + +using testing::_; +using testing::Invoke; + +} // namespace + +TEST_F(ProcessNodeImplTest, ObserverWorks) { + MockObserver obs; + graph()->AddProcessNodeObserver(&obs); + + // Create a page node and expect a matching call to "OnProcessNodeAdded". + EXPECT_CALL(obs, OnProcessNodeAdded(_)) + .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedProcessNode)); + auto process_node = CreateNode<ProcessNodeImpl>(); + const ProcessNode* raw_process_node = process_node.get(); + EXPECT_EQ(raw_process_node, obs.TakeNotifiedProcessNode()); + + EXPECT_CALL(obs, OnExpectedTaskQueueingDurationSample(_)) + .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedProcessNode)); + process_node->SetExpectedTaskQueueingDuration( + base::TimeDelta::FromSeconds(1)); + EXPECT_EQ(raw_process_node, obs.TakeNotifiedProcessNode()); + + EXPECT_CALL(obs, OnMainThreadTaskLoadIsLow(_)) + .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedProcessNode)); + process_node->SetMainThreadTaskLoadIsLow(true); + EXPECT_EQ(raw_process_node, obs.TakeNotifiedProcessNode()); + + EXPECT_CALL(obs, OnAllFramesInProcessFrozen(_)) + .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedProcessNode)); + process_node->OnAllFramesInProcessFrozenForTesting(); + EXPECT_EQ(raw_process_node, obs.TakeNotifiedProcessNode()); + + // Release the page node and expect a call to "OnBeforeProcessNodeRemoved". + EXPECT_CALL(obs, OnBeforeProcessNodeRemoved(_)) + .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedProcessNode)); + process_node.reset(); + EXPECT_EQ(raw_process_node, obs.TakeNotifiedProcessNode()); + + graph()->RemoveProcessNodeObserver(&obs); +} + } // namespace performance_manager
diff --git a/chrome/browser/performance_manager/graph/properties.h b/chrome/browser/performance_manager/graph/properties.h index b2211a55..0a8e7b2 100644 --- a/chrome/browser/performance_manager/graph/properties.h +++ b/chrome/browser/performance_manager/graph/properties.h
@@ -7,19 +7,26 @@ namespace performance_manager { +// TODO(chrisha): Deprecate the private observer type and have everyone use the +// public observers! + // Helper classes for setting properties and invoking observer callbacks based // on the value change. Note that by contract the NodeType must have a member // function "observers()" that returns an iterable collection of // ObserverType pointers. This is templated on the observer type to allow // easy testing. -template <typename NodeType, typename ObserverType> +template <typename NodeImplType, + typename ImplObserverType, + typename NodeType, + typename ObserverType> class ObservedPropertyImpl { public: // Helper class for node properties that represent measurements that are taken // periodically, and for which a notification should be sent every time a // new sample is recorded, even if identical in value to the last. template <typename PropertyType, - void (ObserverType::*NotifyFunctionPtr)(NodeType*)> + void (ImplObserverType::*ImplNotifyFunctionPtr)(NodeImplType*), + void (ObserverType::*NotifyFunctionPtr)(const NodeType*)> class NotifiesAlways { public: NotifiesAlways() {} @@ -29,10 +36,12 @@ ~NotifiesAlways() {} // Sets the property and sends a notification. - void SetAndNotify(NodeType* node, PropertyType value) { + void SetAndNotify(NodeImplType* node, PropertyType value) { value_ = value; for (auto& observer : node->observers()) - ((observer).*(NotifyFunctionPtr))(node); + ((observer).*(ImplNotifyFunctionPtr))(node); + for (auto* observer : node->GetObservers()) + ((observer)->*(NotifyFunctionPtr))(node); } const PropertyType& value() const { return value_; } @@ -46,7 +55,8 @@ // changes. Calls to SetAndMaybeNotify do not notify if the provided value is // the same as the current value. template <typename PropertyType, - void (ObserverType::*NotifyFunctionPtr)(NodeType*)> + void (ImplObserverType::*ImplNotifyFunctionPtr)(NodeImplType*), + void (ObserverType::*NotifyFunctionPtr)(const NodeType*)> class NotifiesOnlyOnChanges { public: NotifiesOnlyOnChanges() {} @@ -57,12 +67,14 @@ // Sets the property and sends a notification if needed. Returns true if a // notification was sent, false otherwise. - bool SetAndMaybeNotify(NodeType* node, PropertyType value) { + bool SetAndMaybeNotify(NodeImplType* node, PropertyType value) { if (value_ == value) return false; value_ = value; for (auto& observer : node->observers()) - ((observer).*(NotifyFunctionPtr))(node); + ((observer).*(ImplNotifyFunctionPtr))(node); + for (auto* observer : node->GetObservers()) + ((observer)->*(NotifyFunctionPtr))(node); return true; }
diff --git a/chrome/browser/performance_manager/graph/properties_unittest.cc b/chrome/browser/performance_manager/graph/properties_unittest.cc index fe9ddc5..b78e13a 100644 --- a/chrome/browser/performance_manager/graph/properties_unittest.cc +++ b/chrome/browser/performance_manager/graph/properties_unittest.cc
@@ -21,6 +21,8 @@ MOCK_METHOD1(NotifyAlways, void(DummyNode*)); MOCK_METHOD1(NotifyOnlyOnChanges, void(DummyNode*)); + MOCK_METHOD1(NotifyAlwaysConst, void(const DummyNode*)); + MOCK_METHOD1(NotifyOnlyOnChangesConst, void(const DummyNode*)); }; class DummyNode { @@ -30,12 +32,15 @@ void AddObserver(DummyObserver* observer) { observers_.AddObserver(observer); + new_observers_.push_back(observer); } base::ObserverList<DummyObserver>::Unchecked& observers() { return observers_; } + const std::vector<DummyObserver*>& GetObservers() { return new_observers_; } + bool observed_always() const { return observed_always_.value(); } bool observed_only_on_changes() const { return observed_only_on_changes_.value(); @@ -49,15 +54,21 @@ } private: - using ObservedProperty = ObservedPropertyImpl<DummyNode, DummyObserver>; + using ObservedProperty = + ObservedPropertyImpl<DummyNode, DummyObserver, DummyNode, DummyObserver>; - ObservedProperty::NotifiesAlways<bool, &DummyObserver::NotifyAlways> + ObservedProperty::NotifiesAlways<bool, + &DummyObserver::NotifyAlways, + &DummyObserver::NotifyAlwaysConst> observed_always_{false}; - ObservedProperty::NotifiesOnlyOnChanges<bool, - &DummyObserver::NotifyOnlyOnChanges> + ObservedProperty::NotifiesOnlyOnChanges< + bool, + &DummyObserver::NotifyOnlyOnChanges, + &DummyObserver::NotifyOnlyOnChangesConst> observed_only_on_changes_{false}; base::ObserverList<DummyObserver>::Unchecked observers_; + std::vector<DummyObserver*> new_observers_; }; class GraphPropertiesTest : public ::testing::Test { @@ -80,16 +91,19 @@ EXPECT_EQ(false, node_.observed_always()); EXPECT_CALL(observer_, NotifyAlways(&node_)); + EXPECT_CALL(observer_, NotifyAlwaysConst(&node_)); node_.SetObservedAlways(false); testing::Mock::VerifyAndClear(&observer_); EXPECT_EQ(false, node_.observed_always()); EXPECT_CALL(observer_, NotifyAlways(&node_)); + EXPECT_CALL(observer_, NotifyAlwaysConst(&node_)); node_.SetObservedAlways(true); testing::Mock::VerifyAndClear(&observer_); EXPECT_EQ(true, node_.observed_always()); EXPECT_CALL(observer_, NotifyAlways(&node_)); + EXPECT_CALL(observer_, NotifyAlwaysConst(&node_)); node_.SetObservedAlways(true); testing::Mock::VerifyAndClear(&observer_); EXPECT_EQ(true, node_.observed_always()); @@ -104,6 +118,7 @@ EXPECT_EQ(false, node_.observed_only_on_changes()); EXPECT_CALL(observer_, NotifyOnlyOnChanges(&node_)); + EXPECT_CALL(observer_, NotifyOnlyOnChangesConst(&node_)); EXPECT_TRUE(node_.SetObservedOnlyOnChanges(true)); testing::Mock::VerifyAndClear(&observer_); EXPECT_EQ(true, node_.observed_only_on_changes());
diff --git a/chrome/browser/performance_manager/graph/system_node.cc b/chrome/browser/performance_manager/graph/system_node.cc index 26127fc..809a95f 100644 --- a/chrome/browser/performance_manager/graph/system_node.cc +++ b/chrome/browser/performance_manager/graph/system_node.cc
@@ -12,4 +12,10 @@ SystemNode::SystemNode() = default; SystemNode::~SystemNode() = default; +SystemNodeObserver::SystemNodeObserver() = default; +SystemNodeObserver::~SystemNodeObserver() = default; + +SystemNode::ObserverDefaultImpl::ObserverDefaultImpl() = default; +SystemNode::ObserverDefaultImpl::~ObserverDefaultImpl() = default; + } // namespace performance_manager
diff --git a/chrome/browser/performance_manager/graph/system_node_impl.cc b/chrome/browser/performance_manager/graph/system_node_impl.cc index 95a3a9a..6a36b125 100644 --- a/chrome/browser/performance_manager/graph/system_node_impl.cc +++ b/chrome/browser/performance_manager/graph/system_node_impl.cc
@@ -17,9 +17,6 @@ namespace performance_manager { -SystemNodeImplObserver::SystemNodeImplObserver() = default; -SystemNodeImplObserver::~SystemNodeImplObserver() = default; - ProcessResourceMeasurement::ProcessResourceMeasurement() = default; ProcessResourceMeasurementBatch::ProcessResourceMeasurementBatch() = default; ProcessResourceMeasurementBatch::~ProcessResourceMeasurementBatch() = default; @@ -156,9 +153,8 @@ for (auto& observer : observers()) observer.OnProcessCPUUsageReady(this); + for (auto* observer : GetObservers()) + observer->OnProcessCPUUsageReady(this); } -SystemNodeImpl::ObserverDefaultImpl::ObserverDefaultImpl() = default; -SystemNodeImpl::ObserverDefaultImpl::~ObserverDefaultImpl() = default; - } // namespace performance_manager
diff --git a/chrome/browser/performance_manager/graph/system_node_impl.h b/chrome/browser/performance_manager/graph/system_node_impl.h index 1f7cf43..8bba25d 100644 --- a/chrome/browser/performance_manager/graph/system_node_impl.h +++ b/chrome/browser/performance_manager/graph/system_node_impl.h
@@ -13,28 +13,11 @@ #include "base/process/process_handle.h" #include "base/time/time.h" #include "chrome/browser/performance_manager/graph/node_base.h" +#include "chrome/browser/performance_manager/observers/graph_observer.h" #include "chrome/browser/performance_manager/public/graph/system_node.h" namespace performance_manager { -// Observer interface for SystemNodeImpl objects. This must be declared first as -// the type is referenced by members of SystemNodeImpl. -class SystemNodeImplObserver { - public: - SystemNodeImplObserver(); - virtual ~SystemNodeImplObserver(); - - // Events with no property changes. - - // Fired when a batch of consistent process CPU measurements is available on - // the graph. - // TODO(siggi): Deprecate this as the CPU measurement code is reworked. - virtual void OnProcessCPUUsageReady(SystemNodeImpl* system_node) = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(SystemNodeImplObserver); -}; - // TODO(siggi): In the end game, this should be private implementation detail // of the performance measurement graph decorator. It's here for now because // there's still a thread hop to get the measurement results into the graph. @@ -64,15 +47,12 @@ std::vector<ProcessResourceMeasurement> measurements; }; -class SystemNodeImpl - : public PublicNodeImpl<SystemNodeImpl, SystemNode>, - public TypedNodeBase<SystemNodeImpl, SystemNodeImplObserver> { +class SystemNodeImpl : public PublicNodeImpl<SystemNodeImpl, SystemNode>, + public TypedNodeBase<SystemNodeImpl, + GraphImplObserver, + SystemNode, + SystemNodeObserver> { public: - // A do-nothing implementation of the observer. Derive from this if you want - // to selectively override a few methods and not have to worry about - // continuously updating your implementation as new methods are added. - class ObserverDefaultImpl; - static constexpr NodeTypeEnum Type() { return NodeTypeEnum::kSystem; } explicit SystemNodeImpl(GraphImpl* graph); @@ -97,19 +77,6 @@ DISALLOW_COPY_AND_ASSIGN(SystemNodeImpl); }; -// A do-nothing default implementation of a SystemNodeImpl::Observer. -class SystemNodeImpl::ObserverDefaultImpl : public SystemNodeImpl::Observer { - public: - ObserverDefaultImpl(); - ~ObserverDefaultImpl() override; - - // SystemNodeImpl::Observer implementation: - void OnProcessCPUUsageReady(SystemNodeImpl* system_node) override {} - - private: - DISALLOW_COPY_AND_ASSIGN(ObserverDefaultImpl); -}; - } // namespace performance_manager #endif // CHROME_BROWSER_PERFORMANCE_MANAGER_GRAPH_SYSTEM_NODE_IMPL_H_
diff --git a/chrome/browser/performance_manager/graph/system_node_impl_unittest.cc b/chrome/browser/performance_manager/graph/system_node_impl_unittest.cc index 900c1b46..958cd1d 100644 --- a/chrome/browser/performance_manager/graph/system_node_impl_unittest.cc +++ b/chrome/browser/performance_manager/graph/system_node_impl_unittest.cc
@@ -13,6 +13,7 @@ #include "chrome/browser/performance_manager/graph/system_node_impl.h" #include "chrome/browser/performance_manager/observers/graph_observer.h" #include "chrome/browser/performance_manager/performance_manager_clock.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" namespace performance_manager { @@ -20,14 +21,9 @@ namespace { // Observer used to make sure that signals are dispatched correctly. -class SystemAndProcessObserver : public GraphObserverDefaultImpl { +class SystemObserver : public SystemNodeImpl::ObserverDefaultImpl { public: - // GraphObserver implementation: - bool ShouldObserve(const NodeBase* node) override { - return node->type() == SystemNodeImpl::Type(); - } - - void OnProcessCPUUsageReady(SystemNodeImpl* system_node) override { + void OnProcessCPUUsageReady(const SystemNode* system_node) override { ++system_event_seen_count_; } @@ -87,11 +83,9 @@ } TEST_F(SystemNodeImplTest, DistributeMeasurementBatch) { - SystemAndProcessObserver observer; + SystemObserver observer; MockMultiplePagesWithMultipleProcessesGraph mock_graph(graph()); - mock_graph.system->AddObserver(&observer); - mock_graph.process->AddObserver(&observer); - mock_graph.other_process->AddObserver(&observer); + graph()->AddSystemNodeObserver(&observer); EXPECT_EQ(0u, observer.system_event_seen_count()); @@ -168,7 +162,60 @@ mock_graph.other_page->cumulative_cpu_usage_estimate()); EXPECT_EQ(50u, mock_graph.other_page->private_footprint_kb_estimate()); - mock_graph.system->RemoveObserver(&observer); + graph()->RemoveSystemNodeObserver(&observer); +} + +namespace { + +class LenientMockObserver : public SystemNodeImpl::Observer { + public: + LenientMockObserver() {} + ~LenientMockObserver() override {} + + MOCK_METHOD1(OnSystemNodeAdded, void(const SystemNode*)); + MOCK_METHOD1(OnBeforeSystemNodeRemoved, void(const SystemNode*)); + MOCK_METHOD1(OnProcessCPUUsageReady, void(const SystemNode*)); + + void SetNotifiedSystemNode(const SystemNode* system_node) { + notified_system_node_ = system_node; + } + + const SystemNode* TakeNotifiedSystemNode() { + const SystemNode* node = notified_system_node_; + notified_system_node_ = nullptr; + return node; + } + + private: + const SystemNode* notified_system_node_ = nullptr; +}; + +using MockObserver = ::testing::StrictMock<LenientMockObserver>; + +using testing::_; +using testing::Invoke; + +} // namespace + +TEST_F(SystemNodeImplTest, ObserverWorks) { + MockObserver obs; + graph()->AddSystemNodeObserver(&obs); + + // Fetch the system node and expect a matching call to "OnSystemNodeAdded". + EXPECT_CALL(obs, OnSystemNodeAdded(_)) + .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedSystemNode)); + const SystemNode* system_node = graph()->FindOrCreateSystemNode(); + EXPECT_EQ(system_node, obs.TakeNotifiedSystemNode()); + + // "OnProcessCPUUsageReady" is tested explicitly in the above unittests. + + // Release the system node and expect a call to "OnBeforeSystemNodeRemoved". + EXPECT_CALL(obs, OnBeforeSystemNodeRemoved(_)) + .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedSystemNode)); + graph()->ReleaseSystemNodeForTesting(); + EXPECT_EQ(system_node, obs.TakeNotifiedSystemNode()); + + graph()->RemoveSystemNodeObserver(&obs); } } // namespace performance_manager
diff --git a/chrome/browser/performance_manager/observers/graph_observer.cc b/chrome/browser/performance_manager/observers/graph_observer.cc index ec0bae9..4619cc03 100644 --- a/chrome/browser/performance_manager/observers/graph_observer.cc +++ b/chrome/browser/performance_manager/observers/graph_observer.cc
@@ -6,18 +6,18 @@ namespace performance_manager { -GraphObserver::GraphObserver() = default; +GraphImplObserver::GraphImplObserver() = default; -GraphObserver::~GraphObserver() = default; +GraphImplObserver::~GraphImplObserver() = default; -GraphObserverDefaultImpl::GraphObserverDefaultImpl() = default; +GraphImplObserverDefaultImpl::GraphImplObserverDefaultImpl() = default; -GraphObserverDefaultImpl::~GraphObserverDefaultImpl() { +GraphImplObserverDefaultImpl::~GraphImplObserverDefaultImpl() { // This observer should have left the graph before being destroyed. DCHECK(!graph_); } -void GraphObserverDefaultImpl::SetGraph(GraphImpl* graph) { +void GraphImplObserverDefaultImpl::SetGraph(GraphImpl* graph) { // We can only be going from null to non-null, and vice-versa. DCHECK(!graph || !graph_); graph_ = graph;
diff --git a/chrome/browser/performance_manager/observers/graph_observer.h b/chrome/browser/performance_manager/observers/graph_observer.h index 245ccea..464d60fb 100644 --- a/chrome/browser/performance_manager/observers/graph_observer.h +++ b/chrome/browser/performance_manager/observers/graph_observer.h
@@ -6,15 +6,17 @@ #define CHROME_BROWSER_PERFORMANCE_MANAGER_OBSERVERS_GRAPH_OBSERVER_H_ #include "base/macros.h" -#include "chrome/browser/performance_manager/graph/frame_node_impl.h" -#include "chrome/browser/performance_manager/graph/graph_impl.h" -#include "chrome/browser/performance_manager/graph/page_node_impl.h" -#include "chrome/browser/performance_manager/graph/process_node_impl.h" -#include "chrome/browser/performance_manager/graph/system_node_impl.h" #include "services/resource_coordinator/public/mojom/coordination_unit.mojom.h" namespace performance_manager { +class FrameNodeImpl; +class GraphImpl; +class NodeBase; +class PageNodeImpl; +class ProcessNodeImpl; +class SystemNodeImpl; + // An observer API for the graph. // // Observers are generally instantiated when the graph is empty, and outlive it, @@ -27,16 +29,12 @@ // (3) Before destruction, unregister by calling on // |graph().UnregisterObserver|. // -// NOTE: This interface is deprecated. Please use the individual interfaces -// that this class is implementing. -class GraphObserver : public GraphImpl::Observer, - public FrameNodeImpl::Observer, - public PageNodeImpl::Observer, - public ProcessNodeImpl::Observer, - public SystemNodeImpl::Observer { +// NOTE: This interface is deprecated. Please use the public observer interfaces +// directly! +class GraphImplObserver { public: - GraphObserver(); - ~GraphObserver() override; + GraphImplObserver(); + virtual ~GraphImplObserver(); // Determines whether or not the observer should be registered with, and // invoked for, the |node|. @@ -44,17 +42,61 @@ // actual observer implementations. virtual bool ShouldObserve(const NodeBase* node) = 0; + // Invoked when an observer is added to or removed from the graph. This is a + // convenient place for observers to initialize any necessary state, validate + // graph invariants, etc. + virtual void OnRegistered() = 0; + virtual void OnUnregistered() = 0; + + // Called whenever a node has been added to the graph. + virtual void OnNodeAdded(NodeBase* node) = 0; + + // Called when the |node| is about to be removed from the graph. + virtual void OnBeforeNodeRemoved(NodeBase* node) = 0; + + // This will be called with a non-null |graph| when the observer is attached + // to a graph, and then again with a null |graph| when the observer is + // removed. + virtual void SetGraph(GraphImpl* graph) = 0; + + // FrameNodeObserver analogs: + virtual void OnIsCurrentChanged(FrameNodeImpl* frame_node) = 0; + virtual void OnNetworkAlmostIdleChanged(FrameNodeImpl* frame_node) = 0; + virtual void OnLifecycleStateChanged(FrameNodeImpl* frame_node) = 0; + virtual void OnURLChanged(FrameNodeImpl* frame_node) = 0; + virtual void OnNonPersistentNotificationCreated( + FrameNodeImpl* frame_node) = 0; + + // PageNodeObserver analogs: + virtual void OnIsVisibleChanged(PageNodeImpl* page_node) = 0; + virtual void OnIsLoadingChanged(PageNodeImpl* page_node) = 0; + virtual void OnUkmSourceIdChanged(PageNodeImpl* page_node) = 0; + virtual void OnLifecycleStateChanged(PageNodeImpl* page_node) = 0; + virtual void OnPageAlmostIdleChanged(PageNodeImpl* page_node) = 0; + virtual void OnFaviconUpdated(PageNodeImpl* page_node) = 0; + virtual void OnTitleUpdated(PageNodeImpl* page_node) = 0; + virtual void OnMainFrameNavigationCommitted(PageNodeImpl* page_node) = 0; + + // ProcessNodeObserver analogs: + virtual void OnExpectedTaskQueueingDurationSample( + ProcessNodeImpl* process_node) = 0; + virtual void OnMainThreadTaskLoadIsLow(ProcessNodeImpl* process_node) = 0; + virtual void OnAllFramesInProcessFrozen(ProcessNodeImpl* process_node) = 0; + + // SystemNodeObserver analogs: + virtual void OnProcessCPUUsageReady(SystemNodeImpl* system_node) = 0; + private: - DISALLOW_COPY_AND_ASSIGN(GraphObserver); + DISALLOW_COPY_AND_ASSIGN(GraphImplObserver); }; // An empty implementation of the interface. -class GraphObserverDefaultImpl : public GraphObserver { +class GraphImplObserverDefaultImpl : public GraphImplObserver { public: - GraphObserverDefaultImpl(); - ~GraphObserverDefaultImpl() override; + GraphImplObserverDefaultImpl(); + ~GraphImplObserverDefaultImpl() override; - // GraphImplObserver implementation: + // GraphObserver implementation: void OnRegistered() override {} void OnUnregistered() override {} void OnNodeAdded(NodeBase* node) override {} @@ -92,7 +134,7 @@ private: GraphImpl* graph_ = nullptr; - DISALLOW_COPY_AND_ASSIGN(GraphObserverDefaultImpl); + DISALLOW_COPY_AND_ASSIGN(GraphImplObserverDefaultImpl); }; } // namespace performance_manager
diff --git a/chrome/browser/performance_manager/observers/graph_observer_unittest.cc b/chrome/browser/performance_manager/observers/graph_observer_unittest.cc index cd4db49..173778c 100644 --- a/chrome/browser/performance_manager/observers/graph_observer_unittest.cc +++ b/chrome/browser/performance_manager/observers/graph_observer_unittest.cc
@@ -20,7 +20,7 @@ class GraphObserverTest : public GraphTestHarness {}; -class TestGraphObserver : public GraphObserverDefaultImpl { +class TestGraphObserver : public GraphImplObserverDefaultImpl { public: TestGraphObserver() {} ~TestGraphObserver() override {}
diff --git a/chrome/browser/performance_manager/observers/isolation_context_metrics.h b/chrome/browser/performance_manager/observers/isolation_context_metrics.h index 40ec2842..60d6cf2 100644 --- a/chrome/browser/performance_manager/observers/isolation_context_metrics.h +++ b/chrome/browser/performance_manager/observers/isolation_context_metrics.h
@@ -24,7 +24,7 @@ // (2) How common it is for pages to be in browsing instances with other pages, // as opposed to in browsing instances on their own. This is for estimating // the impact of extending freezing logic to entire browsing instances. -class IsolationContextMetrics : public GraphObserverDefaultImpl { +class IsolationContextMetrics : public GraphImplObserverDefaultImpl { public: IsolationContextMetrics(); ~IsolationContextMetrics() override;
diff --git a/chrome/browser/performance_manager/observers/metrics_collector.h b/chrome/browser/performance_manager/observers/metrics_collector.h index 25eabb70..11a5560f 100644 --- a/chrome/browser/performance_manager/observers/metrics_collector.h +++ b/chrome/browser/performance_manager/observers/metrics_collector.h
@@ -29,7 +29,7 @@ extern const int kDefaultFrequencyUkmEQTReported; // The MetricsCollector is a graph observer that reports UMA/UKM. -class MetricsCollector : public GraphObserverDefaultImpl { +class MetricsCollector : public GraphImplObserverDefaultImpl { public: MetricsCollector(); ~MetricsCollector() override;
diff --git a/chrome/browser/performance_manager/observers/working_set_trimmer_win.h b/chrome/browser/performance_manager/observers/working_set_trimmer_win.h index 56f246bb4..092a881 100644 --- a/chrome/browser/performance_manager/observers/working_set_trimmer_win.h +++ b/chrome/browser/performance_manager/observers/working_set_trimmer_win.h
@@ -26,7 +26,7 @@ // to be compressed and/or written to disk preemptively, which makes more // memory available quickly for foreground processes and improves global // browser performance. -class WorkingSetTrimmer : public GraphObserverDefaultImpl { +class WorkingSetTrimmer : public GraphImplObserverDefaultImpl { public: WorkingSetTrimmer(); ~WorkingSetTrimmer() override;
diff --git a/chrome/browser/performance_manager/performance_manager.cc b/chrome/browser/performance_manager/performance_manager.cc index fdd3e30..0bed066 100644 --- a/chrome/browser/performance_manager/performance_manager.cc +++ b/chrome/browser/performance_manager/performance_manager.cc
@@ -130,7 +130,7 @@ } void PerformanceManager::RegisterObserver( - std::unique_ptr<GraphObserver> observer) { + std::unique_ptr<GraphImplObserver> observer) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); graph_.RegisterObserver(observer.get()); observers_.push_back(std::move(observer)); @@ -263,7 +263,7 @@ std::unique_ptr<service_manager::Connector> connector) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // Register new |GraphObserver| implementations here. + // Register new |GraphImplObserver| implementations here. RegisterObserver(std::make_unique<MetricsCollector>()); RegisterObserver(std::make_unique<PageAlmostIdleDecorator>()); RegisterObserver(std::make_unique<FrozenFrameAggregator>());
diff --git a/chrome/browser/performance_manager/performance_manager.h b/chrome/browser/performance_manager/performance_manager.h index c79944d..bfd619b0 100644 --- a/chrome/browser/performance_manager/performance_manager.h +++ b/chrome/browser/performance_manager/performance_manager.h
@@ -110,7 +110,7 @@ // resource_coordinator migration, so do not use this unless you know what // you're doing! Must be called from the performance manager sequence. // TODO(chrisha): Kill this dead. - void RegisterObserver(std::unique_ptr<GraphObserver> observer); + void RegisterObserver(std::unique_ptr<GraphImplObserver> observer); private: using InterfaceRegistry = service_manager::BinderRegistryWithArgs< @@ -146,7 +146,7 @@ GraphImpl graph_; // The registered graph observers. - std::vector<std::unique_ptr<GraphObserver>> observers_; + std::vector<std::unique_ptr<GraphImplObserver>> observers_; // Provided to |graph_|. // TODO(siggi): This no longer needs to go through mojo.
diff --git a/chrome/browser/performance_manager/persistence/site_data/site_data_cache.h b/chrome/browser/performance_manager/persistence/site_data/site_data_cache.h new file mode 100644 index 0000000..1c158d6 --- /dev/null +++ b/chrome/browser/performance_manager/persistence/site_data/site_data_cache.h
@@ -0,0 +1,47 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_PERFORMANCE_MANAGER_PERSISTENCE_SITE_DATA_SITE_DATA_CACHE_H_ +#define CHROME_BROWSER_PERFORMANCE_MANAGER_PERSISTENCE_SITE_DATA_SITE_DATA_CACHE_H_ + +#include <memory> + +#include "base/macros.h" +#include "chrome/browser/performance_manager/persistence/site_data/site_data_reader.h" +#include "chrome/browser/performance_manager/persistence/site_data/site_data_writer.h" +#include "chrome/browser/performance_manager/persistence/site_data/tab_visibility.h" +#include "url/origin.h" + +namespace performance_manager { + +// Pure virtual interface for a site data cache. +class SiteDataCache { + public: + SiteDataCache() = default; + ~SiteDataCache() = default; + + // Returns a SiteDataReader for the given origin. + virtual std::unique_ptr<SiteDataReader> GetReaderForOrigin( + const url::Origin& origin) = 0; + + // Returns a SiteDataWriter for the given origin. + // + // |tab_visibility| indicates the current visibility of the tab. The writer + // starts in an unloaded state, NotifyTabLoaded() must be called explicitly + // afterwards if the site is loaded. + virtual std::unique_ptr<SiteDataWriter> GetWriterForOrigin( + const url::Origin& origin, + performance_manager::TabVisibility tab_visibility) = 0; + + // Indicate if the SiteDataWriter served by this data cache + // actually persist information. + virtual bool IsRecordingForTesting() = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(SiteDataCache); +}; + +} // namespace performance_manager + +#endif // CHROME_BROWSER_PERFORMANCE_MANAGER_PERSISTENCE_SITE_DATA_SITE_DATA_CACHE_H_
diff --git a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl.cc b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl.cc new file mode 100644 index 0000000..e0b0dff --- /dev/null +++ b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl.cc
@@ -0,0 +1,145 @@ +// 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/performance_manager/persistence/site_data/site_data_cache_impl.h" + +#include <set> + +#include "base/feature_list.h" +#include "base/memory/ptr_util.h" +#include "base/stl_util.h" +#include "chrome/browser/performance_manager/persistence/site_data/leveldb_site_data_store.h" +#include "chrome/browser/performance_manager/persistence/site_data/site_data_reader.h" +#include "chrome/browser/performance_manager/persistence/site_data/site_data_writer.h" +#include "content/public/browser/browser_context.h" + +namespace performance_manager { + +namespace { + +constexpr char kDataStoreDBName[] = "Site Characteristics Database"; + +} // namespace + +SiteDataCacheImpl::SiteDataCacheImpl(content::BrowserContext* browser_context) + : browser_context_(browser_context) { + data_store_ = std::make_unique<LevelDBSiteDataStore>( + browser_context->GetPath().AppendASCII(kDataStoreDBName)); + + // Register the debug interface against the browser context. + SiteDataCacheInspector::SetForBrowserContext(this, browser_context); +} + +SiteDataCacheImpl::~SiteDataCacheImpl() { + SiteDataCacheInspector::SetForBrowserContext(nullptr, browser_context_); +} + +std::unique_ptr<SiteDataReader> SiteDataCacheImpl::GetReaderForOrigin( + const url::Origin& origin) { + internal::SiteDataImpl* impl = GetOrCreateFeatureImpl(origin); + DCHECK(impl); + SiteDataReader* data_reader = new SiteDataReader(impl); + return base::WrapUnique(data_reader); +} + +std::unique_ptr<SiteDataWriter> SiteDataCacheImpl::GetWriterForOrigin( + const url::Origin& origin, + performance_manager::TabVisibility tab_visibility) { + internal::SiteDataImpl* impl = GetOrCreateFeatureImpl(origin); + DCHECK(impl); + SiteDataWriter* data_writer = new SiteDataWriter(impl, tab_visibility); + return base::WrapUnique(data_writer); +} + +bool SiteDataCacheImpl::IsRecordingForTesting() { + return true; +} + +const char* SiteDataCacheImpl::GetDataCacheName() { + return "SiteDataCache"; +} + +std::vector<url::Origin> SiteDataCacheImpl::GetAllInMemoryOrigins() { + std::vector<url::Origin> ret; + + ret.reserve(origin_data_map_.size()); + for (const auto& entry : origin_data_map_) + ret.push_back(entry.first); + + return ret; +} + +void SiteDataCacheImpl::GetDataStoreSize(DataStoreSizeCallback on_have_data) { + data_store_->GetStoreSize(std::move(on_have_data)); +} + +bool SiteDataCacheImpl::GetDataForOrigin(const url::Origin& origin, + bool* is_dirty, + std::unique_ptr<SiteDataProto>* data) { + DCHECK_NE(nullptr, data); + const auto it = origin_data_map_.find(origin); + if (it == origin_data_map_.end()) + return false; + + std::unique_ptr<SiteDataProto> ret = std::make_unique<SiteDataProto>(); + ret->CopyFrom(it->second->FlushStateToProto()); + *is_dirty = it->second->is_dirty(); + *data = std::move(ret); + return true; +} + +SiteDataCacheImpl* SiteDataCacheImpl::GetDataCache() { + return this; +} + +internal::SiteDataImpl* SiteDataCacheImpl::GetOrCreateFeatureImpl( + const url::Origin& origin) { + // Start by checking if there's already an entry for this origin. + auto iter = origin_data_map_.find(origin); + if (iter != origin_data_map_.end()) + return iter->second; + + // If not create a new one and add it to the map. + internal::SiteDataImpl* site_data = + new internal::SiteDataImpl(origin, this, data_store_.get()); + + // internal::SiteDataImpl is a ref-counted object, it's safe to store a raw + // pointer to it here as this class will get notified when it's about to be + // destroyed and it'll be removed from the map. + origin_data_map_.insert(std::make_pair(origin, site_data)); + return site_data; +} + +void SiteDataCacheImpl::OnSiteDataImplDestroyed(internal::SiteDataImpl* impl) { + DCHECK(impl); + DCHECK(base::ContainsKey(origin_data_map_, impl->origin())); + // Remove the entry for this origin as this is about to get destroyed. + auto num_erased = origin_data_map_.erase(impl->origin()); + DCHECK_EQ(1U, num_erased); +} + +void SiteDataCacheImpl::ClearSiteDataForOrigins( + const std::vector<url::Origin>& origins_to_remove) { + // It's not necessary to invalidate the pending DB write operations as they + // run on a sequenced task and so it's guaranteed that the remove operations + // posted here will run after any other pending operation. + for (const auto& it : origins_to_remove) { + auto map_iter = origin_data_map_.find(it); + if (map_iter != origin_data_map_.end()) + map_iter->second->ClearObservationsAndInvalidateReadOperation(); + } + + data_store_->RemoveSiteDataFromStore(origins_to_remove); +} + +void SiteDataCacheImpl::ClearAllSiteData() { + // It's not necessary to invalidate the pending DB write operations as they + // run on a sequenced task and so it's guaranteed that the remove operations + // posted here will run after any other pending operation. + for (auto& data : origin_data_map_) + data.second->ClearObservationsAndInvalidateReadOperation(); + data_store_->ClearStore(); +} + +} // namespace performance_manager
diff --git a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl.h b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl.h new file mode 100644 index 0000000..cd361010 --- /dev/null +++ b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl.h
@@ -0,0 +1,95 @@ +// 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_PERFORMANCE_MANAGER_PERSISTENCE_SITE_DATA_SITE_DATA_CACHE_IMPL_H_ +#define CHROME_BROWSER_PERFORMANCE_MANAGER_PERSISTENCE_SITE_DATA_SITE_DATA_CACHE_IMPL_H_ + +#include <memory> +#include <utility> +#include <vector> + +#include "base/containers/flat_map.h" +#include "base/gtest_prod_util.h" +#include "base/macros.h" +#include "base/scoped_observer.h" +#include "base/sequence_checker.h" +#include "chrome/browser/performance_manager/persistence/site_data/site_data_cache.h" +#include "chrome/browser/performance_manager/persistence/site_data/site_data_cache_inspector.h" +#include "chrome/browser/performance_manager/persistence/site_data/site_data_impl.h" + +namespace content { +class BrowserContext; +} + +namespace performance_manager { + +// Implementation of a SiteDataCache that serves normal reader and writers. +// +// This class should never be used for off the record profiles, the +// NonRecordingSiteDataCache class should be used instead. +class SiteDataCacheImpl : public SiteDataCache, + public SiteDataCacheInspector, + public internal::SiteDataImpl::OnDestroyDelegate { + public: + using SiteDataMap = base::flat_map<url::Origin, internal::SiteDataImpl*>; + + explicit SiteDataCacheImpl(content::BrowserContext* browser_context); + virtual ~SiteDataCacheImpl(); + + // SiteCharacteristicDataCache: + std::unique_ptr<SiteDataReader> GetReaderForOrigin( + const url::Origin& origin) override; + std::unique_ptr<SiteDataWriter> GetWriterForOrigin( + const url::Origin& origin, + performance_manager::TabVisibility tab_visibility) override; + bool IsRecordingForTesting() override; + + const SiteDataMap& origin_data_map_for_testing() const { + return origin_data_map_; + } + + // NOTE: This should be called before creating any SiteDataImpl object (this + // doesn't update the data store used by these objects). + void SetDataStoreForTesting(std::unique_ptr<SiteDataStore> data_store) { + data_store_ = std::move(data_store); + } + + // SiteDataCacheImplInspector: + const char* GetDataCacheName() override; + std::vector<url::Origin> GetAllInMemoryOrigins() override; + void GetDataStoreSize(DataStoreSizeCallback on_have_data) override; + bool GetDataForOrigin(const url::Origin& origin, + bool* is_dirty, + std::unique_ptr<SiteDataProto>* data) override; + SiteDataCacheImpl* GetDataCache() override; + + // Remove a specific set of entries from the cache and the on-disk store. + void ClearSiteDataForOrigins( + const std::vector<url::Origin>& origins_to_remove); + + // Clear the data cache and the on-disk store. + void ClearAllSiteData(); + + private: + // Returns a pointer to the SiteDataImpl object associated with |origin|, + // create one and add it to |origin_data_map_| if it doesn't exist. + internal::SiteDataImpl* GetOrCreateFeatureImpl(const url::Origin& origin); + + // internal::SiteDataImpl::OnDestroyDelegate: + void OnSiteDataImplDestroyed(internal::SiteDataImpl* impl) override; + + // Map an origin to a SiteDataImpl pointer. + SiteDataMap origin_data_map_; + + std::unique_ptr<SiteDataStore> data_store_; + + // The browser context this data store is associated with. + content::BrowserContext* browser_context_; + + DISALLOW_COPY_AND_ASSIGN(SiteDataCacheImpl); +}; + +} // namespace performance_manager + +#endif // CHROME_BROWSER_PERFORMANCE_MANAGER_PERSISTENCE_SITE_DATA_SITE_DATA_CACHE_IMPL_H_
diff --git a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl_unittest.cc b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl_unittest.cc new file mode 100644 index 0000000..abba180 --- /dev/null +++ b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl_unittest.cc
@@ -0,0 +1,269 @@ +// 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/performance_manager/persistence/site_data/site_data_cache_impl.h" + +#include <set> + +#include "base/macros.h" +#include "base/test/scoped_feature_list.h" +#include "base/test/simple_test_tick_clock.h" +#include "chrome/browser/performance_manager/performance_manager_clock.h" +#include "chrome/browser/performance_manager/persistence/site_data/site_data_cache_inspector.h" +#include "chrome/browser/performance_manager/persistence/site_data/site_data_impl.h" +#include "chrome/browser/performance_manager/persistence/site_data/unittest_utils.h" +#include "chrome/test/base/testing_profile.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace performance_manager { + +namespace { + +const url::Origin kTestOrigin = url::Origin::Create(GURL("http://www.foo.com")); +const url::Origin kTestOrigin2 = + url::Origin::Create(GURL("http://www.bar.com")); + +constexpr base::TimeDelta kDelay = base::TimeDelta::FromMinutes(1); + +class MockSiteCache : public testing::NoopSiteDataStore { + public: + MockSiteCache() = default; + ~MockSiteCache() = default; + + MOCK_METHOD1(RemoveSiteDataFromStore, void(const std::vector<url::Origin>&)); + MOCK_METHOD0(ClearStore, void()); + + private: + DISALLOW_COPY_AND_ASSIGN(MockSiteCache); +}; + +} // namespace + +class SiteDataCacheImplTest : public ::testing::Test { + protected: + SiteDataCacheImplTest() { + PerformanceManagerClock::SetClockForTesting(&test_clock_); + data_cache_ = std::make_unique<SiteDataCacheImpl>(&profile_); + mock_db_ = new ::testing::StrictMock<MockSiteCache>(); + data_cache_->SetDataStoreForTesting(base::WrapUnique(mock_db_)); + test_clock_.SetNowTicks(base::TimeTicks::UnixEpoch()); + test_clock_.Advance(base::TimeDelta::FromHours(1)); + WaitForAsyncOperationsToComplete(); + } + + ~SiteDataCacheImplTest() override { + PerformanceManagerClock::ResetClockForTesting(); + } + + void TearDown() override { WaitForAsyncOperationsToComplete(); } + + void WaitForAsyncOperationsToComplete() { + test_browser_thread_bundle_.RunUntilIdle(); + } + + // Populates |writer_|, |reader_| and |data_| to refer to a tab navigated to + // |kTestOrigin| that updated its title in background. Populates |writer2_|, + // |reader2_| and |data2_| to refer to a tab navigated to |kTestOrigin2| that + // updates its favicon in background. + void SetupTwoSitesUsingFeaturesInBackground() { + // Load a first origin, and then make use of a feature on it. + ASSERT_FALSE(reader_); + reader_ = data_cache_->GetReaderForOrigin(kTestOrigin); + EXPECT_TRUE(reader_); + + ASSERT_FALSE(writer_); + writer_ = data_cache_->GetWriterForOrigin( + kTestOrigin, performance_manager::TabVisibility::kBackground); + EXPECT_TRUE(writer_); + + ASSERT_FALSE(data_); + data_ = + data_cache_->origin_data_map_for_testing().find(kTestOrigin)->second; + EXPECT_TRUE(data_); + + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, + reader_->UpdatesTitleInBackground()); + writer_->NotifySiteLoaded(); + writer_->NotifyUpdatesTitleInBackground(); + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, + reader_->UpdatesTitleInBackground()); + test_clock_.Advance(kDelay); + + // Load a second origin, make use of a feature on it too. + ASSERT_FALSE(reader2_); + reader2_ = data_cache_->GetReaderForOrigin(kTestOrigin2); + EXPECT_TRUE(reader2_); + + ASSERT_FALSE(writer2_); + writer2_ = data_cache_->GetWriterForOrigin( + kTestOrigin2, performance_manager::TabVisibility::kBackground); + EXPECT_TRUE(writer2_); + + ASSERT_FALSE(data2_); + data2_ = + data_cache_->origin_data_map_for_testing().find(kTestOrigin2)->second; + EXPECT_TRUE(data2_); + + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, + reader2_->UpdatesFaviconInBackground()); + writer2_->NotifySiteLoaded(); + writer2_->NotifyUpdatesFaviconInBackground(); + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, + reader2_->UpdatesFaviconInBackground()); + test_clock_.Advance(kDelay); + } + + base::SimpleTestTickClock test_clock_; + content::TestBrowserThreadBundle test_browser_thread_bundle_; + base::test::ScopedFeatureList scoped_feature_list_; + TestingProfile profile_; + + // Owned by |data_cache_|. + ::testing::StrictMock<MockSiteCache>* mock_db_ = nullptr; + std::unique_ptr<SiteDataCacheImpl> data_cache_; + + std::unique_ptr<SiteDataReader> reader_; + std::unique_ptr<SiteDataWriter> writer_; + internal::SiteDataImpl* data_ = nullptr; + + std::unique_ptr<SiteDataReader> reader2_; + std::unique_ptr<SiteDataWriter> writer2_; + internal::SiteDataImpl* data2_ = nullptr; +}; + +TEST_F(SiteDataCacheImplTest, EndToEnd) { + auto reader = data_cache_->GetReaderForOrigin(kTestOrigin); + EXPECT_TRUE(reader); + auto writer = data_cache_->GetWriterForOrigin( + kTestOrigin, performance_manager::TabVisibility::kBackground); + EXPECT_TRUE(writer); + + EXPECT_EQ(1U, data_cache_->origin_data_map_for_testing().size()); + + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, + reader->UpdatesTitleInBackground()); + writer->NotifySiteLoaded(); + writer->NotifyUpdatesTitleInBackground(); + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, + reader->UpdatesTitleInBackground()); + writer->NotifySiteUnloaded(); + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, + reader->UpdatesTitleInBackground()); + + auto reader_copy = data_cache_->GetReaderForOrigin(kTestOrigin); + EXPECT_EQ(1U, data_cache_->origin_data_map_for_testing().size()); + auto reader2 = data_cache_->GetReaderForOrigin(kTestOrigin2); + EXPECT_EQ(2U, data_cache_->origin_data_map_for_testing().size()); + reader2.reset(); + + WaitForAsyncOperationsToComplete(); + EXPECT_EQ(1U, data_cache_->origin_data_map_for_testing().size()); + reader_copy.reset(); + + reader.reset(); + writer.reset(); + EXPECT_TRUE(data_cache_->origin_data_map_for_testing().empty()); + + EXPECT_CALL(*mock_db_, ClearStore()); + data_cache_->ClearAllSiteData(); +} + +TEST_F(SiteDataCacheImplTest, ClearSiteDataForOrigins) { + SetupTwoSitesUsingFeaturesInBackground(); + + const base::TimeDelta last_loaded_time2_before_urls_deleted = + data2_->last_loaded_time_for_testing(); + + // Make sure that all data passed to |ClearSiteDataForOrigins| get passed to + // the database, even if they're not in the internal map used by the data + // cache. + const url::Origin kOriginNotInMap = + url::Origin::Create(GURL("http://www.url-not-in-map.com")); + std::vector<url::Origin> origins_to_remove = {kTestOrigin, kOriginNotInMap}; + EXPECT_CALL(*mock_db_, + RemoveSiteDataFromStore(::testing::WhenSorted( + ::testing::ElementsAre(kTestOrigin, kOriginNotInMap)))); + data_cache_->ClearSiteDataForOrigins(origins_to_remove); + ::testing::Mock::VerifyAndClear(mock_db_); + + // The information for the first site should have been cleared. The last + // loaded time should be equal to the current time. + EXPECT_EQ(data_->last_loaded_time_for_testing(), + test_clock_.NowTicks() - base::TimeTicks::UnixEpoch()); + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, + reader_->UpdatesTitleInBackground()); + // The second site shouldn't have been cleared. + EXPECT_EQ(data2_->last_loaded_time_for_testing(), + last_loaded_time2_before_urls_deleted); + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, + reader2_->UpdatesFaviconInBackground()); + + writer_->NotifySiteUnloaded(); + writer2_->NotifySiteUnloaded(); +} + +TEST_F(SiteDataCacheImplTest, ClearAllSiteData) { + SetupTwoSitesUsingFeaturesInBackground(); + + // Delete all the information stored in the data store. + EXPECT_CALL(*mock_db_, ClearStore()); + data_cache_->ClearAllSiteData(); + ::testing::Mock::VerifyAndClear(mock_db_); + + // The information for both sites should have been cleared. + EXPECT_EQ(data_->last_loaded_time_for_testing(), + test_clock_.NowTicks() - base::TimeTicks::UnixEpoch()); + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, + reader_->UpdatesTitleInBackground()); + EXPECT_EQ(data2_->last_loaded_time_for_testing(), + test_clock_.NowTicks() - base::TimeTicks::UnixEpoch()); + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, + reader2_->UpdatesFaviconInBackground()); + + writer_->NotifySiteUnloaded(); + writer2_->NotifySiteUnloaded(); +} + +TEST_F(SiteDataCacheImplTest, InspectorWorks) { + // Make sure the inspector interface was registered at construction. + SiteDataCacheInspector* inspector = + SiteDataCacheInspector::GetForBrowserContext(&profile_); + EXPECT_NE(nullptr, inspector); + EXPECT_EQ(data_cache_.get(), inspector); + + EXPECT_STREQ("SiteDataCache", inspector->GetDataCacheName()); + + // We expect an empty data store at the outset. + EXPECT_EQ(0U, inspector->GetAllInMemoryOrigins().size()); + std::unique_ptr<SiteDataProto> data; + bool is_dirty = false; + EXPECT_FALSE(inspector->GetDataForOrigin(kTestOrigin, &is_dirty, &data)); + EXPECT_FALSE(is_dirty); + EXPECT_EQ(nullptr, data.get()); + + { + // Add an entry, see that it's reflected in the inspector interface. + auto writer = data_cache_->GetWriterForOrigin( + kTestOrigin, performance_manager::TabVisibility::kBackground); + + EXPECT_EQ(1U, inspector->GetAllInMemoryOrigins().size()); + EXPECT_TRUE(inspector->GetDataForOrigin(kTestOrigin, &is_dirty, &data)); + EXPECT_FALSE(is_dirty); + ASSERT_NE(nullptr, data.get()); + + // Touch the underlying data, see that the dirty bit updates. + writer->NotifySiteLoaded(); + EXPECT_TRUE(inspector->GetDataForOrigin(kTestOrigin, &is_dirty, &data)); + EXPECT_TRUE(is_dirty); + } + + // Make sure the interface is unregistered from the profile on destruction. + data_cache_.reset(); + EXPECT_EQ(nullptr, SiteDataCacheInspector::GetForBrowserContext(&profile_)); +} + +} // namespace performance_manager
diff --git a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_inspector.cc b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_inspector.cc new file mode 100644 index 0000000..763c6eab --- /dev/null +++ b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_inspector.cc
@@ -0,0 +1,57 @@ +// 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/performance_manager/persistence/site_data/site_data_cache_inspector.h" + +#include "base/macros.h" +#include "content/public/browser/browser_context.h" + +namespace performance_manager { + +namespace { + +const void* const kSiteDataCacheInspectorUserKey = + &kSiteDataCacheInspectorUserKey; + +class SiteDataUserData : public base::SupportsUserData::Data { + public: + explicit SiteDataUserData(SiteDataCacheInspector* inspector) + : inspector_(inspector) {} + + SiteDataCacheInspector* inspector() const { return inspector_; } + + private: + SiteDataCacheInspector* inspector_; +}; + +} // namespace + +// static +SiteDataCacheInspector* SiteDataCacheInspector::GetForBrowserContext( + content::BrowserContext* browser_context) { + SiteDataUserData* data = static_cast<SiteDataUserData*>( + browser_context->GetUserData(kSiteDataCacheInspectorUserKey)); + + if (!data) + return nullptr; + + return data->inspector(); +} + +// static +void SiteDataCacheInspector::SetForBrowserContext( + SiteDataCacheInspector* inspector, + content::BrowserContext* browser_context) { + if (inspector) { + DCHECK_EQ(nullptr, GetForBrowserContext(browser_context)); + + browser_context->SetUserData(kSiteDataCacheInspectorUserKey, + std::make_unique<SiteDataUserData>(inspector)); + } else { + DCHECK_NE(nullptr, GetForBrowserContext(browser_context)); + browser_context->RemoveUserData(kSiteDataCacheInspectorUserKey); + } +} + +} // namespace performance_manager
diff --git a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_inspector.h b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_inspector.h new file mode 100644 index 0000000..f1fb469b --- /dev/null +++ b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_inspector.h
@@ -0,0 +1,79 @@ +// 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_PERFORMANCE_MANAGER_PERSISTENCE_SITE_DATA_SITE_DATA_CACHE_INSPECTOR_H_ +#define CHROME_BROWSER_PERFORMANCE_MANAGER_PERSISTENCE_SITE_DATA_SITE_DATA_CACHE_INSPECTOR_H_ + +#include <cstdint> +#include <memory> +#include <string> +#include <vector> + +#include "base/callback.h" +#include "base/optional.h" +#include "base/supports_user_data.h" +#include "chrome/browser/performance_manager/persistence/site_data/site_data.pb.h" +#include "url/origin.h" + +namespace content { +class BrowserContext; +} + +namespace performance_manager { + +class SiteDataCache; + +// An interface that allows LocalSite data cachess to expose diagnostic +// information for the associated web UI. +class SiteDataCacheInspector { + public: + // Retrieves the instance associated with a given browser context, or nullptr + // if none is associated with that browser context. + static SiteDataCacheInspector* GetForBrowserContext( + content::BrowserContext* browser_context); + + // Returns the name of the data cache, which should uniquely identify the kind + // of storage it implements. + virtual const char* GetDataCacheName() = 0; + + // Retrieves the origins that are current represented by in-memory data + // at the present time. + virtual std::vector<url::Origin> GetAllInMemoryOrigins() = 0; + + // Retrieves the number of rows and the on-disk size of the store. Invokes + // the |on_have_data| callback once the data has been collected, or once it's + // determined that the data can't be retrieved. + // On callback |num_rows| is the number of rows in the database, or -1 if + // the number can't be determined. |on_disk_size_kb| is the on-disk size of + // the database, or -1 if the on-disk size can't be determined. + using DataStoreSizeCallback = + base::OnceCallback<void(base::Optional<int64_t> num_rows, + base::Optional<int64_t> on_disk_size_kb)>; + virtual void GetDataStoreSize(DataStoreSizeCallback on_have_data) = 0; + + // Retrieves the in-memory data for a given origin. + // On return |data| contains the available data for |origin| if available, + // and |is_dirty| is true if the entry needs flushing to disk. + // Returns true if an entry exists for |origin|. + virtual bool GetDataForOrigin(const url::Origin& origin, + bool* is_dirty, + std::unique_ptr<SiteDataProto>* data) = 0; + + // Retrieves the data cache this inspector is associated with. + virtual SiteDataCache* GetDataCache() = 0; + + protected: + // Sets the inspector instance associated with a given browser context. + // If |inspector| is nullptr the association is cleared. + // The caller must ensure that |inspector|'s registration is cleared before + // |inspector| or |browser_context| are deleted. + // The intent is for this to be called from implementation class' constructors + // and destructors. + static void SetForBrowserContext(SiteDataCacheInspector* inspector, + content::BrowserContext* browser_context); +}; + +} // namespace performance_manager + +#endif // CHROME_BROWSER_PERFORMANCE_MANAGER_PERSISTENCE_SITE_DATA_SITE_DATA_CACHE_INSPECTOR_H_
diff --git a/chrome/browser/performance_manager/persistence/site_data/site_data_impl.h b/chrome/browser/performance_manager/persistence/site_data/site_data_impl.h index 15cd983..65f85c4 100644 --- a/chrome/browser/performance_manager/persistence/site_data/site_data_impl.h +++ b/chrome/browser/performance_manager/persistence/site_data/site_data_impl.h
@@ -24,6 +24,7 @@ namespace performance_manager { +class SiteDataCacheImpl; class SiteDataReaderTest; class SiteDataWriterTest; @@ -150,6 +151,7 @@ protected: friend class base::RefCounted<SiteDataImpl>; + friend class performance_manager::SiteDataCacheImpl; // Friend all the tests. friend class SiteDataImplTest;
diff --git a/chrome/browser/performance_manager/persistence/site_data/site_data_reader.h b/chrome/browser/performance_manager/persistence/site_data/site_data_reader.h index ccf7172..5571b4b 100644 --- a/chrome/browser/performance_manager/persistence/site_data/site_data_reader.h +++ b/chrome/browser/performance_manager/persistence/site_data/site_data_reader.h
@@ -45,7 +45,9 @@ const internal::SiteDataImpl* impl_for_testing() const { return impl_.get(); } private: + friend class SiteDataCacheImpl; friend class SiteDataReaderTest; + FRIEND_TEST_ALL_PREFIXES(SiteDataReaderTest, DestroyingReaderCancelsPendingCallbacks); FRIEND_TEST_ALL_PREFIXES(SiteDataReaderTest,
diff --git a/chrome/browser/performance_manager/persistence/site_data/site_data_writer.h b/chrome/browser/performance_manager/persistence/site_data/site_data_writer.h index 7ce97113..65bc2df 100644 --- a/chrome/browser/performance_manager/persistence/site_data/site_data_writer.h +++ b/chrome/browser/performance_manager/persistence/site_data/site_data_writer.h
@@ -43,7 +43,7 @@ protected: friend class SiteDataWriterTest; - friend class SiteDataStore; + friend class SiteDataCacheImpl; // Protected constructor, these objects are meant to be created by a site data // store.
diff --git a/chrome/browser/performance_manager/public/graph/frame_node.h b/chrome/browser/performance_manager/public/graph/frame_node.h index bdc8f62..d6fa1d5 100644 --- a/chrome/browser/performance_manager/public/graph/frame_node.h +++ b/chrome/browser/performance_manager/public/graph/frame_node.h
@@ -10,6 +10,7 @@ namespace performance_manager { class Graph; +class FrameNodeObserver; // Frame nodes form a tree structure, each FrameNode at most has one parent that // is a FrameNode. Conceptually, a frame corresponds to a @@ -35,6 +36,9 @@ // active frame. class FrameNode { public: + using Observer = FrameNodeObserver; + class ObserverDefaultImpl; + FrameNode(); virtual ~FrameNode(); @@ -49,6 +53,67 @@ DISALLOW_COPY_AND_ASSIGN(FrameNode); }; +// Pure virtual observer interface. Derive from this if you want to be forced to +// implement the entire interface. +class FrameNodeObserver { + public: + FrameNodeObserver(); + virtual ~FrameNodeObserver(); + + // Node lifetime notifications. + + // Called when a |frame_node| is added to the graph. + virtual void OnFrameNodeAdded(const FrameNode* frame_node) = 0; + + // Called before a |frame_node| is removed from the graph. + virtual void OnBeforeFrameNodeRemoved(const FrameNode* frame_node) = 0; + + // Notifications of property changes. + + // Invoked when the |is_current| property changes. + virtual void OnIsCurrentChanged(const FrameNode* frame_node) = 0; + + // Invoked when the |network_almost_idle| property changes. + virtual void OnNetworkAlmostIdleChanged(const FrameNode* frame_node) = 0; + + // Invoked when the |lifecycle_state| property changes. + virtual void OnLifecycleStateChanged(const FrameNode* frame_node) = 0; + + // Invoked when the |url| property changes. + virtual void OnURLChanged(const FrameNode* frame_node) = 0; + + // Events with no property changes. + + // Invoked when a non-persistent notification has been issued by the frame. + virtual void OnNonPersistentNotificationCreated( + const FrameNode* frame_node) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(FrameNodeObserver); +}; + +// Default implementation of observer that provides dummy versions of each +// function. Derive from this if you only need to implement a few of the +// functions. +class FrameNode::ObserverDefaultImpl : public FrameNodeObserver { + public: + ObserverDefaultImpl(); + ~ObserverDefaultImpl() override; + + // FrameNodeObserver implementation: + void OnFrameNodeAdded(const FrameNode* frame_node) override {} + void OnBeforeFrameNodeRemoved(const FrameNode* frame_node) override {} + void OnIsCurrentChanged(const FrameNode* frame_node) override {} + void OnNetworkAlmostIdleChanged(const FrameNode* frame_node) override {} + void OnLifecycleStateChanged(const FrameNode* frame_node) override {} + void OnURLChanged(const FrameNode* frame_node) override {} + void OnNonPersistentNotificationCreated( + const FrameNode* frame_node) override {} + + private: + DISALLOW_COPY_AND_ASSIGN(ObserverDefaultImpl); +}; + } // namespace performance_manager #endif // CHROME_BROWSER_PERFORMANCE_MANAGER_PUBLIC_GRAPH_FRAME_NODE_H_
diff --git a/chrome/browser/performance_manager/public/graph/graph.h b/chrome/browser/performance_manager/public/graph/graph.h index bcd66652..5bceb6c0 100644 --- a/chrome/browser/performance_manager/public/graph/graph.h +++ b/chrome/browser/performance_manager/public/graph/graph.h
@@ -11,14 +11,37 @@ namespace performance_manager { +class GraphObserver; +class FrameNodeObserver; +class PageNodeObserver; +class ProcessNodeObserver; +class SystemNodeObserver; + // Represents a graph of the nodes representing a single browser. Maintains a // set of nodes that can be retrieved in different ways, some indexed. Keeps // a list of observers that are notified of node addition and removal. class Graph { public: + using Observer = GraphObserver; + Graph(); virtual ~Graph(); + // Adds an |observer| on the graph. It is safe for observers to stay + // registered on the graph at the time of its death. + virtual void AddGraphObserver(GraphObserver* observer) = 0; + virtual void AddFrameNodeObserver(FrameNodeObserver* observer) = 0; + virtual void AddPageNodeObserver(PageNodeObserver* observer) = 0; + virtual void AddProcessNodeObserver(ProcessNodeObserver* observer) = 0; + virtual void AddSystemNodeObserver(SystemNodeObserver* observer) = 0; + + // Removes an |observer| from the graph. + virtual void RemoveGraphObserver(GraphObserver* observer) = 0; + virtual void RemoveFrameNodeObserver(FrameNodeObserver* observer) = 0; + virtual void RemovePageNodeObserver(PageNodeObserver* observer) = 0; + virtual void RemoveProcessNodeObserver(ProcessNodeObserver* observer) = 0; + virtual void RemoveSystemNodeObserver(SystemNodeObserver* observer) = 0; + // The following functions are implementation detail and should not need to be // used by external clients. They provide the ability to safely downcast to // the underlying implementation. @@ -29,6 +52,25 @@ DISALLOW_COPY_AND_ASSIGN(Graph); }; +// Observer interface for the graph. +class GraphObserver { + public: + GraphObserver(); + virtual ~GraphObserver(); + + // Called before the |graph| associated with this observer disappears. This + // allows the observer to do any necessary cleanup work. Note that the graph + // is in its destructor while this is being called, so the observer should + // refrain from uselessly modifying the graph. This is intended to be used to + // facilitate lifetime management of observers. + // TODO(chrisha): Make this run before the constructor! + // crbug.com/966840 + virtual void OnBeforeGraphDestroyed(const Graph* graph) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(GraphObserver); +}; + } // namespace performance_manager #endif // CHROME_BROWSER_PERFORMANCE_MANAGER_PUBLIC_GRAPH_GRAPH_H_
diff --git a/chrome/browser/performance_manager/public/graph/page_node.h b/chrome/browser/performance_manager/public/graph/page_node.h index a1d3a5e..c1999b0 100644 --- a/chrome/browser/performance_manager/public/graph/page_node.h +++ b/chrome/browser/performance_manager/public/graph/page_node.h
@@ -10,12 +10,16 @@ namespace performance_manager { class Graph; +class PageNodeObserver; // A PageNode represents the root of a FrameTree, or equivalently a WebContents. // These may correspond to normal tabs, WebViews, Portals, Chrome Apps or // Extensions. class PageNode { public: + using Observer = PageNodeObserver; + class ObserverDefaultImpl; + PageNode(); virtual ~PageNode(); @@ -30,6 +34,80 @@ DISALLOW_COPY_AND_ASSIGN(PageNode); }; +// Pure virtual observer interface. Derive from this if you want to be forced to +// implement the entire interface. +class PageNodeObserver { + public: + PageNodeObserver(); + virtual ~PageNodeObserver(); + + // Node lifetime notifications. + + // Called when a |page_node| is added to the graph. + virtual void OnPageNodeAdded(const PageNode* page_node) = 0; + + // Called before a |page_node| is removed from the graph. + virtual void OnBeforePageNodeRemoved(const PageNode* page_node) = 0; + + // Notifications of property changes. + + // Invoked when the |is_visible| property changes. + virtual void OnIsVisibleChanged(const PageNode* page_node) = 0; + + // Invoked when the |is_loading| property changes. + virtual void OnIsLoadingChanged(const PageNode* page_node) = 0; + + // Invoked when the |ukm_source_id| property changes. + virtual void OnUkmSourceIdChanged(const PageNode* page_node) = 0; + + // Invoked when the |lifecycle_state| property changes. + virtual void OnLifecycleStateChanged(const PageNode* page_node) = 0; + + // Invoked when the |page_almost_idle| property changes. + virtual void OnPageAlmostIdleChanged(const PageNode* page_node) = 0; + + // This is fired when a main frame navigation commits. It indicates that the + // |navigation_id| and |main_frame_url| properties have changed. + virtual void OnMainFrameNavigationCommitted(const PageNode* page_node) = 0; + + // Events with no property changes. + + // Fired when the tab title associated with a page changes. This property is + // not directly reflected on the node. + virtual void OnTitleUpdated(const PageNode* page_node) = 0; + + // Fired when the favicon associated with a page is updated. This property is + // not directly reflected on the node. + virtual void OnFaviconUpdated(const PageNode* page_node) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(PageNodeObserver); +}; + +// Default implementation of observer that provides dummy versions of each +// function. Derive from this if you only need to implement a few of the +// functions. +class PageNode::ObserverDefaultImpl : public PageNodeObserver { + public: + ObserverDefaultImpl(); + ~ObserverDefaultImpl() override; + + // PageNodeObserver implementation: + void OnPageNodeAdded(const PageNode* page_node) override {} + void OnBeforePageNodeRemoved(const PageNode* page_node) override {} + void OnIsVisibleChanged(const PageNode* page_node) override {} + void OnIsLoadingChanged(const PageNode* page_node) override {} + void OnUkmSourceIdChanged(const PageNode* page_node) override {} + void OnLifecycleStateChanged(const PageNode* page_node) override {} + void OnPageAlmostIdleChanged(const PageNode* page_node) override {} + void OnMainFrameNavigationCommitted(const PageNode* page_node) override {} + void OnTitleUpdated(const PageNode* page_node) override {} + void OnFaviconUpdated(const PageNode* page_node) override {} + + private: + DISALLOW_COPY_AND_ASSIGN(ObserverDefaultImpl); +}; + } // namespace performance_manager #endif // CHROME_BROWSER_PERFORMANCE_MANAGER_PUBLIC_GRAPH_PAGE_NODE_H_
diff --git a/chrome/browser/performance_manager/public/graph/process_node.h b/chrome/browser/performance_manager/public/graph/process_node.h index 9ab64761..03382aa 100644 --- a/chrome/browser/performance_manager/public/graph/process_node.h +++ b/chrome/browser/performance_manager/public/graph/process_node.h
@@ -10,6 +10,7 @@ namespace performance_manager { class Graph; +class ProcessNodeObserver; // A process node follows the lifetime of a RenderProcessHost. // It may reference zero or one processes at a time, but during its lifetime, it @@ -23,6 +24,9 @@ // 4. Back to 2. class ProcessNode { public: + using Observer = ProcessNodeObserver; + class ObserverDefaultImpl; + ProcessNode(); virtual ~ProcessNode(); @@ -37,6 +41,59 @@ DISALLOW_COPY_AND_ASSIGN(ProcessNode); }; +// Pure virtual observer interface. Derive from this if you want to be forced to +// implement the entire interface. +class ProcessNodeObserver { + public: + ProcessNodeObserver(); + virtual ~ProcessNodeObserver(); + + // Node lifetime notifications. + + // Called when a |process_node| is added to the graph. + virtual void OnProcessNodeAdded(const ProcessNode* process_node) = 0; + + // Called before a |process_node| is removed from the graph. + virtual void OnBeforeProcessNodeRemoved(const ProcessNode* process_node) = 0; + + // Notifications of property changes. + + // Invoked when a new |expected_task_queueing_duration| sample is available. + virtual void OnExpectedTaskQueueingDurationSample( + const ProcessNode* process_node) = 0; + + // Invoked when the |main_thread_task_load_is_low| property changes. + virtual void OnMainThreadTaskLoadIsLow(const ProcessNode* process_node) = 0; + + // Events with no property changes. + + // Fired when all frames in a process have transitioned to being frozen. + virtual void OnAllFramesInProcessFrozen(const ProcessNode* process_node) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(ProcessNodeObserver); +}; + +// Default implementation of observer that provides dummy versions of each +// function. Derive from this if you only need to implement a few of the +// functions. +class ProcessNode::ObserverDefaultImpl : public ProcessNodeObserver { + public: + ObserverDefaultImpl(); + ~ObserverDefaultImpl() override; + + // ProcessNodeObserver implementation: + void OnProcessNodeAdded(const ProcessNode* process_node) override {} + void OnBeforeProcessNodeRemoved(const ProcessNode* process_node) override {} + void OnExpectedTaskQueueingDurationSample( + const ProcessNode* process_node) override {} + void OnMainThreadTaskLoadIsLow(const ProcessNode* process_node) override {} + void OnAllFramesInProcessFrozen(const ProcessNode* process_node) override {} + + private: + DISALLOW_COPY_AND_ASSIGN(ObserverDefaultImpl); +}; + } // namespace performance_manager #endif // CHROME_BROWSER_PERFORMANCE_MANAGER_PUBLIC_GRAPH_PROCESS_NODE_H_
diff --git a/chrome/browser/performance_manager/public/graph/system_node.h b/chrome/browser/performance_manager/public/graph/system_node.h index 784ad39f..7ec6875 100644 --- a/chrome/browser/performance_manager/public/graph/system_node.h +++ b/chrome/browser/performance_manager/public/graph/system_node.h
@@ -10,11 +10,15 @@ namespace performance_manager { class Graph; +class SystemNodeObserver; // The SystemNode represents system-wide state. There is at most one system node // in a graph. class SystemNode { public: + using Observer = SystemNodeObserver; + class ObserverDefaultImpl; + SystemNode(); virtual ~SystemNode(); @@ -29,6 +33,49 @@ DISALLOW_COPY_AND_ASSIGN(SystemNode); }; +// Pure virtual observer interface. Derive from this if you want to be forced to +// implement the entire interface. +class SystemNodeObserver { + public: + SystemNodeObserver(); + virtual ~SystemNodeObserver(); + + // Node lifetime notifications. + + // Called when the |system_node| is added to the graph. + virtual void OnSystemNodeAdded(const SystemNode* system_node) = 0; + + // Called before the |system_node| is removed from the graph. + virtual void OnBeforeSystemNodeRemoved(const SystemNode* system_node) = 0; + + // Events with no property changes. + + // Fired when a batch of consistent process CPU measurements is available on + // the graph. + // TODO(siggi): Deprecate this as the CPU measurement code is reworked. + virtual void OnProcessCPUUsageReady(const SystemNode* system_node) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(SystemNodeObserver); +}; + +// Default implementation of observer that provides dummy versions of each +// function. Derive from this if you only need to implement a few of the +// functions. +class SystemNode::ObserverDefaultImpl : public SystemNodeObserver { + public: + ObserverDefaultImpl(); + ~ObserverDefaultImpl() override; + + // SystemNodeObserver implementation: + void OnSystemNodeAdded(const SystemNode* system_node) override {} + void OnBeforeSystemNodeRemoved(const SystemNode* system_node) override {} + void OnProcessCPUUsageReady(const SystemNode* system_node) override {} + + private: + DISALLOW_COPY_AND_ASSIGN(ObserverDefaultImpl); +}; + } // namespace performance_manager #endif // CHROME_BROWSER_PERFORMANCE_MANAGER_PUBLIC_GRAPH_SYSTEM_NODE_H_
diff --git a/chrome/browser/performance_manager/webui_graph_dump_impl.h b/chrome/browser/performance_manager/webui_graph_dump_impl.h index edd1a86..568d1d56 100644 --- a/chrome/browser/performance_manager/webui_graph_dump_impl.h +++ b/chrome/browser/performance_manager/webui_graph_dump_impl.h
@@ -16,7 +16,8 @@ class GraphImpl; -class WebUIGraphDumpImpl : public mojom::WebUIGraphDump, public GraphObserver { +class WebUIGraphDumpImpl : public mojom::WebUIGraphDump, + public GraphImplObserver { public: explicit WebUIGraphDumpImpl(GraphImpl* graph); ~WebUIGraphDumpImpl() override; @@ -29,42 +30,45 @@ void SubscribeToChanges( mojom::WebUIGraphChangeStreamPtr change_subscriber) override; - // GraphObserver implementation. void OnRegistered() override {} void OnUnregistered() override {} bool ShouldObserve(const NodeBase* node) override; void OnNodeAdded(NodeBase* node) override; void OnBeforeNodeRemoved(NodeBase* node) override; + void SetGraph(GraphImpl* graph) override; + + // Frame node functions. void OnIsCurrentChanged(FrameNodeImpl* frame_node) override; void OnNetworkAlmostIdleChanged(FrameNodeImpl* frame_node) override; void OnLifecycleStateChanged(FrameNodeImpl* frame_node) override; void OnURLChanged(FrameNodeImpl* frame_node) override; // Event notification. void OnNonPersistentNotificationCreated(FrameNodeImpl* frame_node) override {} + + // Page node functions. void OnIsVisibleChanged(PageNodeImpl* page_node) override; void OnIsLoadingChanged(PageNodeImpl* page_node) override; void OnUkmSourceIdChanged(PageNodeImpl* page_node) override; void OnLifecycleStateChanged(PageNodeImpl* page_node) override; void OnPageAlmostIdleChanged(PageNodeImpl* page_node) override; - // Event notification. void OnFaviconUpdated(PageNodeImpl* page_node) override; // Event notification. void OnTitleUpdated(PageNodeImpl* page_node) override {} - // Event notification that also implies the main_frame_url changed. void OnMainFrameNavigationCommitted(PageNodeImpl* page_node) override; + + // Process node functions. void OnExpectedTaskQueueingDurationSample( ProcessNodeImpl* process_node) override; void OnMainThreadTaskLoadIsLow(ProcessNodeImpl* process_node) override; // Event notification. void OnAllFramesInProcessFrozen(ProcessNodeImpl* process_node) override {} - // Ignored + // System node functions. + // Ignored. void OnProcessCPUUsageReady(SystemNodeImpl* system_node) override {} - void SetGraph(GraphImpl* graph) override; - private: // The favicon requests happen on the UI thread. This helper class // maintains the state required to do that.
diff --git a/chrome/browser/policy/e2e_test/.style.yapf b/chrome/browser/policy/e2e_test/.style.yapf new file mode 100644 index 0000000..5a64936 --- /dev/null +++ b/chrome/browser/policy/e2e_test/.style.yapf
@@ -0,0 +1,2 @@ +[style] +based_on_style = chromium \ No newline at end of file
diff --git a/chrome/browser/policy/e2e_test/test.py b/chrome/browser/policy/e2e_test/test.py new file mode 100644 index 0000000..e07c078 --- /dev/null +++ b/chrome/browser/policy/e2e_test/test.py
@@ -0,0 +1,103 @@ +# 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. +"""The test runner that runs enterprise end-to-end tests.""" + +import logging +import sys +import traceback +import warnings +from absl import app +from absl import flags +import chrome_ent_test.infra.controller as controller + +FLAGS = flags.FLAGS + +flags.DEFINE_string( + 'test', None, + 'The full class name of the EnterpriseTestCase class (w/ package)') +flags.mark_flag_as_required('test') + +flags.DEFINE_string('test_filter', None, + 'The name of the test to run in the test class') + +flags.DEFINE_string('host', None, + 'The full path to the *.host.textpb file to use') +flags.mark_flag_as_required('host') + +flags.DEFINE_string('cel_ctl', None, + 'Which binary to use to deploy the environment') +flags.mark_flag_as_required('cel_ctl') + +flags.DEFINE_bool( + 'deploy', True, 'Depoly the test environment. ' + 'Set to false to skip the deployment phase and go straight to tests') +flags.DEFINE_bool( + 'skip_before_all', False, 'True to skip @before_all methods. ' + 'Like --nodeploy, this is used to skip set up steps. ' + 'Useful when developing new tests.') +flags.DEFINE_bool('cleanup', False, + 'Clean up the host environment after the test') +flags.DEFINE_string('error_logs_dir', None, + 'Where to collect extra logs on test failures') +flags.DEFINE_multi_string('test_arg', None, 'Flags passed to tests') + + +def ConfigureLogging(): + # Filter out logs from low level loggers + errorOnlyLoggers = [ + 'googleapiclient.discovery_cache', 'google.auth', 'google_auth_httplib2' + ] + for logger in errorOnlyLoggers: + logging.getLogger(logger).setLevel(logging.ERROR) + message = 'We recommend that most server applications use service accounts.' + warnings.filterwarnings('ignore', '.*%s' % message) + + logging.error("%s: Logging level error is visible." % __file__) + logging.warning("%s: Logging level warning is visible." % __file__) + logging.info("%s: Logging level info is visible." % __file__) + logging.debug("%s: Logging level debug is visible." % __file__) + + +def main(argv): + ConfigureLogging() + + c = controller.SingleTestController( + FLAGS.test, + FLAGS.host, + FLAGS.cel_ctl, + test_filter=FLAGS.test_filter, + skip_before_all=FLAGS.skip_before_all) + + # Parse test specific flags. Note that we need to use a dummy element + # as the first element of the list since absl.flags ignores the first element + # during parsing. + if FLAGS.test_arg is not None: + FLAGS([''] + FLAGS.test_arg) + + success = False + should_write_logs = (FLAGS.error_logs_dir != None) + try: + if FLAGS.deploy: + c.DeployNewEnvironment() + + success = c.ExecuteTestCase() + except KeyboardInterrupt: + logging.error('Test aborted.') + except: + print(traceback.format_exc()) + logging.error('Test failed.') + finally: + if not success and should_write_logs: + print('Writing Compute logs to "%s"...' % FLAGS.error_logs_dir) + c.TryWriteComputeLogsTo(FLAGS.error_logs_dir) + + if FLAGS.cleanup: + print('Cleaning up host environment...') + c.TryCleanHostEnvironment() + + sys.exit(0 if success else 1) + + +if __name__ == '__main__': + app.run(main)
diff --git a/chrome/browser/policy/e2e_test/tests/__init__.py b/chrome/browser/policy/e2e_test/tests/__init__.py new file mode 100644 index 0000000..98057ef --- /dev/null +++ b/chrome/browser/policy/e2e_test/tests/__init__.py
@@ -0,0 +1,5 @@ +# 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. + +from force_google_safe_search.force_google_safe_search import *
diff --git a/chrome/browser/policy/e2e_test/tests/force_google_safe_search/__init__.py b/chrome/browser/policy/e2e_test/tests/force_google_safe_search/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/chrome/browser/policy/e2e_test/tests/force_google_safe_search/__init__.py
diff --git a/chrome/browser/policy/e2e_test/tests/force_google_safe_search/force_google_safe_search.py b/chrome/browser/policy/e2e_test/tests/force_google_safe_search/force_google_safe_search.py new file mode 100644 index 0000000..0da01b1 --- /dev/null +++ b/chrome/browser/policy/e2e_test/tests/force_google_safe_search/force_google_safe_search.py
@@ -0,0 +1,52 @@ +# 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. + +import os +import logging +from chrome_ent_test.infra.core import environment, before_all, test +from chrome_ent_test.ent_tests import ChromeEnterpriseTestCase +from absl import flags + +FLAGS = flags.FLAGS + + +@environment(file="../policy_test.asset.textpb") +class ForceGoogleSafeSearchTest(ChromeEnterpriseTestCase): + + @before_all + def setup(self): + self.InstallChrome('client2012') + self.InstallWebDriver('client2012') + + @test + def test_ForceGoogleSafeSearchEnabled(self): + # enable policy ForceGoogleSafeSearch + self.SetPolicy('win2012-dc', 'ForceGoogleSafeSearch', 1, 'DWORD') + self.RunCommand('client2012', 'gpupdate /force') + logging.info('ForceGoogleSafeSearch ENABLED') + d = os.path.dirname(os.path.abspath(__file__)) + output = self.RunWebDriverTest( + 'client2012', + os.path.join(d, 'force_google_safe_search_webdriver_test.py')) + logging.info('url used: %s', output) + + # assert that safe search is enabled + self.assertIn('safe=active', output) + self.assertIn('ssui=on', output) + + @test + def test_ForceGoogleSafeSearchDisabled(self): + # disable policy ForceGoogleSafeSearch + self.SetPolicy('win2012-dc', 'ForceGoogleSafeSearch', 0, 'DWORD') + self.RunCommand('client2012', 'gpupdate /force') + d = os.path.dirname(os.path.abspath(__file__)) + logging.info('ForceGoogleSafeSearch DISABLED') + output = self.RunWebDriverTest( + 'client2012', + os.path.join(d, 'force_google_safe_search_webdriver_test.py')) + logging.info('url used: %s', output) + + # assert that safe search is NOT enabled + self.assertNotIn('safe=active', output) + self.assertNotIn('ssui=on', output)
diff --git a/chrome/browser/policy/e2e_test/tests/force_google_safe_search/force_google_safe_search_webdriver_test.py b/chrome/browser/policy/e2e_test/tests/force_google_safe_search/force_google_safe_search_webdriver_test.py new file mode 100644 index 0000000..eba78c53 --- /dev/null +++ b/chrome/browser/policy/e2e_test/tests/force_google_safe_search/force_google_safe_search_webdriver_test.py
@@ -0,0 +1,31 @@ +# 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. + +import os + +from selenium import webdriver +from selenium.webdriver.common.by import By +from selenium.webdriver.support import expected_conditions as EC +from selenium.webdriver.support.ui import WebDriverWait + +os.environ["CHROME_LOG_FILE"] = r"c:\temp\chrome_log.txt" + +driver = webdriver.Chrome( + "C:/ProgramData/chocolatey/lib/chromedriver/tools/chromedriver.exe", + service_args=["--verbose", r"--log-path=c:\temp\chromedriver.log"]) +driver.get('http://www.google.com/xhtml') + +# wait for page to be loaded +wait = WebDriverWait(driver, 10) +wait.until(EC.visibility_of_element_located((By.NAME, 'q'))) + +search_box = driver.find_element_by_name('q') +search_box.send_keys('searchTerm') +search_box.submit() + +# wait for the search result page to be loaded +wait.until(EC.visibility_of_element_located((By.ID, 'search'))) + +print driver.current_url +driver.quit()
diff --git a/chrome/browser/policy/e2e_test/tests/policy_test.asset.textpb b/chrome/browser/policy/e2e_test/tests/policy_test.asset.textpb new file mode 100644 index 0000000..978fc119 --- /dev/null +++ b/chrome/browser/policy/e2e_test/tests/policy_test.asset.textpb
@@ -0,0 +1,29 @@ +# The test configuration used by most policy tests. +# It consists of one domain controller and one client. +network { + name: 'primary' +} + +# An ActiveDirectory domain. +ad_domain { + name: 'test1.com' + netbios_name: 'example' + + domain_controller { + windows_machine: 'win2012-dc' + } +} + +# the domain controller. +windows_machine { + name: 'win2012-dc' + machine_type: 'win2012r2' + network_interface { network: 'primary' } +} + +windows_machine { + name: 'client2012' + machine_type: 'win2012r2' + network_interface { network: 'primary' } + container { ad_domain: 'test1.com' } +} \ No newline at end of file
diff --git a/chrome/browser/previews/previews_browsertest.cc b/chrome/browser/previews/previews_browsertest.cc index 17191ca..7a9e09b 100644 --- a/chrome/browser/previews/previews_browsertest.cc +++ b/chrome/browser/previews/previews_browsertest.cc
@@ -7,12 +7,10 @@ #include "base/metrics/field_trial_param_associator.h" #include "base/metrics/field_trial_params.h" #include "base/run_loop.h" -#include "base/strings/stringprintf.h" #include "base/task/post_task.h" #include "base/task/thread_pool/thread_pool.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" -#include "base/test/values_test_util.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/metrics/subprocess_metrics_provider.h" @@ -20,7 +18,6 @@ #include "chrome/browser/previews/previews_service_factory.h" #include "chrome/browser/previews/previews_ui_tab_helper.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ssl/cert_verifier_browser_test.h" #include "chrome/browser/ui/browser.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" @@ -38,12 +35,9 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/test/browser_test_utils.h" #include "net/dns/mock_host_resolver.h" -#include "net/reporting/reporting_policy.h" -#include "net/test/embedded_test_server/controllable_http_response.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" -#include "services/network/public/cpp/features.h" #include "services/network/public/cpp/network_quality_tracker.h" namespace { @@ -428,147 +422,3 @@ EXPECT_TRUE(noscript_js_requested()); EXPECT_FALSE(noscript_css_requested()); } - -namespace { - -class PreviewsReportingBrowserTest : public CertVerifierBrowserTest { - public: - PreviewsReportingBrowserTest() - : https_server_(net::test_server::EmbeddedTestServer::TYPE_HTTPS) {} - ~PreviewsReportingBrowserTest() override = default; - - void SetUp() override { - scoped_feature_list_.InitWithFeatures( - {network::features::kReporting, previews::features::kPreviews, - previews::features::kClientLoFi, - data_reduction_proxy::features:: - kDataReductionProxyEnabledWithNetworkService}, - {network::features::kNetworkErrorLogging}); - CertVerifierBrowserTest::SetUp(); - // Make report delivery happen instantly. - net::ReportingPolicy policy; - policy.delivery_interval = base::TimeDelta::FromSeconds(0); - net::ReportingPolicy::UsePolicyForTesting(policy); - } - - void SetUpOnMainThread() override { - CertVerifierBrowserTest::SetUpOnMainThread(); - - g_browser_process->network_quality_tracker() - ->ReportEffectiveConnectionTypeForTesting( - net::EFFECTIVE_CONNECTION_TYPE_2G); - - host_resolver()->AddRule("*", "127.0.0.1"); - - main_frame_response_ = - std::make_unique<net::test_server::ControllableHttpResponse>( - server(), "/lofi_test"); - upload_response_ = - std::make_unique<net::test_server::ControllableHttpResponse>(server(), - "/upload"); - mock_cert_verifier()->set_default_result(net::OK); - ASSERT_TRUE(server()->Start()); - } - - void SetUpCommandLine(base::CommandLine* cmd) override { - CertVerifierBrowserTest::SetUpCommandLine(cmd); - cmd->AppendSwitch("enable-spdy-proxy-auth"); - - // Due to race conditions, it's possible that blacklist data is not loaded - // at the time of first navigation. That may prevent Preview from - // triggering, and causing the test to flake. - cmd->AppendSwitch(previews::switches::kIgnorePreviewsBlacklist); - } - - net::EmbeddedTestServer* server() { return &https_server_; } - int port() const { return https_server_.port(); } - - net::test_server::ControllableHttpResponse* main_frame_response() { - return main_frame_response_.get(); - } - - net::test_server::ControllableHttpResponse* upload_response() { - return upload_response_.get(); - } - - GURL GetReportingEnabledURL() const { - return GURL(base::StringPrintf("https://example.com:%d/lofi_test", port())); - } - - GURL GetCollectorURL() const { - return GURL(base::StringPrintf("https://example.com:%d/upload", port())); - } - - std::string GetReportToHeader() const { - return "Report-To: {\"endpoints\":[{\"url\":\"" + GetCollectorURL().spec() + - "\"}],\"max_age\":86400}\r\n"; - } - - private: - base::test::ScopedFeatureList scoped_feature_list_; - net::EmbeddedTestServer https_server_; - std::unique_ptr<net::test_server::ControllableHttpResponse> - main_frame_response_; - std::unique_ptr<net::test_server::ControllableHttpResponse> upload_response_; - - DISALLOW_COPY_AND_ASSIGN(PreviewsReportingBrowserTest); -}; - -std::unique_ptr<base::Value> ParseReportUpload(const std::string& payload) { - auto parsed_payload = base::test::ParseJsonDeprecated(payload); - // Clear out any non-reproducible fields. - for (auto& report : parsed_payload->GetList()) { - report.RemoveKey("age"); - auto* user_agent = - report.FindKeyOfType("user_agent", base::Value::Type::STRING); - if (user_agent != nullptr) - *user_agent = base::Value("Mozilla/1.0"); - } - return parsed_payload; -} - -} // namespace - -// Checks that the intervention is reported during a LoFi load. -IN_PROC_BROWSER_TEST_F(PreviewsReportingBrowserTest, - TestReportingHeadersSentForLoFiPreview) { - NavigateParams params(browser(), GetReportingEnabledURL(), - ui::PAGE_TRANSITION_LINK); - Navigate(¶ms); - - main_frame_response()->WaitForRequest(); - main_frame_response()->Send( - "HTTP/1.1 200 OK\r\n" - "Content-Type: text/html\r\n" - "Empty page \r\n"); - main_frame_response()->Send(GetReportToHeader()); - main_frame_response()->Send("\r\n"); - main_frame_response()->Done(); - - upload_response()->WaitForRequest(); - auto actual = ParseReportUpload(upload_response()->http_request()->content); - upload_response()->Send("HTTP/1.1 204 OK\r\n"); - upload_response()->Send("\r\n"); - upload_response()->Done(); - - // Verify the contents of the report that we received. - EXPECT_TRUE(actual != nullptr); - auto expected = base::test::ParseJsonDeprecated(base::StringPrintf( - R"text( - [ - { - "body": { - "id": "LitePageServed", - "message": "Modified page load behavior on the page because )text" - R"text(the page was expected to take a long amount of time to load. )text" - R"text(https://www.chromestatus.com/feature/5148050062311424" - }, - "type": "intervention", - "url": "https://example.com:%d/lofi_test", - "user_agent": "Mozilla/1.0" - } - ] - )text", - port())); - EXPECT_EQ(*expected, *actual); -}
diff --git a/chrome/browser/previews/previews_lite_page_browsertest.cc b/chrome/browser/previews/previews_lite_page_browsertest.cc index 10ab94a..209bec6 100644 --- a/chrome/browser/previews/previews_lite_page_browsertest.cc +++ b/chrome/browser/previews/previews_lite_page_browsertest.cc
@@ -23,6 +23,7 @@ #include "base/test/scoped_feature_list.h" #include "base/test/scoped_task_environment.h" #include "base/test/simple_test_tick_clock.h" +#include "base/test/values_test_util.h" #include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" @@ -79,6 +80,7 @@ #include "net/http/http_request_headers.h" #include "net/http/http_status_code.h" #include "net/nqe/effective_connection_type.h" +#include "net/reporting/reporting_policy.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" #include "services/metrics/public/cpp/ukm_builders.h" @@ -142,6 +144,9 @@ // Previews server will put Chrome into a redirect loop. kRedirectLoop = 8, + + // The URL that intervention reports should be sent to. + kInterventionReport = 9, }; void SetUpCommandLine(base::CommandLine* cmd) override { @@ -281,8 +286,9 @@ {previews::features::kPreviews, previews::features::kOptimizationHints, previews::features::kResourceLoadingHints, data_reduction_proxy::features:: - kDataReductionProxyEnabledWithNetworkService}, - {}); + kDataReductionProxyEnabledWithNetworkService, + network::features::kReporting}, + {network::features::kNetworkErrorLogging}); if (GetParam()) { url_loader_feature_list_.InitWithFeatures( @@ -308,6 +314,10 @@ decider->BlacklistBypassedHost(kBlacklistedHost, base::TimeDelta::FromHours(1)); + + net::ReportingPolicy policy; + policy.delivery_interval = base::TimeDelta::FromSeconds(0); + net::ReportingPolicy::UsePolicyForTesting(policy); } void InitializeOptimizationHints() { @@ -503,6 +513,17 @@ ->GetHttpOriginalContentLength(); } + base::Value ParsedInterventionReport() const { + base::Value parsed_payload = + base::test::ParseJson(intervention_report_content_); + // Clear out any non-reproducible fields. + for (auto& report : parsed_payload.GetList()) { + report.RemoveKey("age"); + report.RemoveKey("user_agent"); + } + return parsed_payload; + } + // Returns a HTTP URL that will respond with the given action and headers when // used by the previews server. The response can be delayed a number of // milliseconds by passing a value > 0 for |delay_ms| or pass -1 to make the @@ -582,6 +603,15 @@ run_loop.Run(); } + void WaitForInterventionReport() { + if (!intervention_report_content_.empty()) + return; + + base::RunLoop run_loop; + waiting_for_report_closure_ = run_loop.QuitClosure(); + run_loop.Run(); + } + private: std::unique_ptr<net::test_server::HttpResponse> HandleRedirectRequest( const net::test_server::HttpRequest& request) { @@ -669,6 +699,15 @@ return response; } + // If this request is for a intervention report, record the content. + if (request.GetURL().spec().find("upload_report") != std::string::npos) { + intervention_report_content_ = request.content; + response->set_code(net::HTTP_NO_CONTENT); + if (waiting_for_report_closure_) + std::move(waiting_for_report_closure_).Run(); + return response; + } + response->set_content_type("text/html"); std::string original_url_str; @@ -755,6 +794,12 @@ response->set_code(net::HTTP_OK); response->set_content("porgporgporgporgporg" /* length = 20 */); response->AddCustomHeader("chrome-proxy", "ofcl=60"); + // Use the Host header for the report because CORS. + response->AddCustomHeader( + "Report-To", + base::StringPrintf("{\"endpoints\":[{\"url\":\"https://%s/" + "?upload_report=true\"}],\"max_age\":86400}", + request.headers.find("Host")->second.c_str())); break; case kRedirectNonPreview: response->set_code(net::HTTP_TEMPORARY_REDIRECT); @@ -835,7 +880,9 @@ GURL slow_http_url_; uint64_t got_page_id_ = 0; int subresources_requested_ = 0; + std::string intervention_report_content_; base::OnceClosure waiting_for_pingback_closure_; + base::OnceClosure waiting_for_report_closure_; }; // True if testing using the URLLoader Interceptor implementation. @@ -1427,6 +1474,36 @@ WaitForPingback(); } +IN_PROC_BROWSER_TEST_P( + PreviewsLitePageServerBrowserTest, + DISABLE_ON_WIN_MAC_CHROMESOS(LitePageSendsInterventionReport)) { + ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess)); + VerifyPreviewLoaded(); + WaitForInterventionReport(); + + base::Value expected = base::test::ParseJson(base::StringPrintf( + R"text( + [ + { + "body": { + "id": "LitePageServed", + "message": "Modified page load behavior on the page because )text" + R"text(the page was expected to take a long amount of time to load. )text" + R"text(https://www.chromestatus.com/feature/5148050062311424" + }, + "type": "intervention", + "url": "%s", + } + ] + )text", + PreviewsLitePageNavigationThrottle::GetPreviewsURLForURL( + HttpsLitePageURL(kSuccess)) + .spec() + .c_str())); + + EXPECT_EQ(expected, ParsedInterventionReport()); +} + class TestDataReductionProxyPingbackClient : public data_reduction_proxy::DataReductionProxyPingbackClient { public:
diff --git a/chrome/browser/previews/previews_ui_tab_helper.cc b/chrome/browser/previews/previews_ui_tab_helper.cc index 9b1d29fb..d62ec8e5 100644 --- a/chrome/browser/previews/previews_ui_tab_helper.cc +++ b/chrome/browser/previews/previews_ui_tab_helper.cc
@@ -13,7 +13,6 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h" #include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings_factory.h" -#include "chrome/browser/loader/chrome_navigation_data.h" #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h" #include "chrome/browser/previews/previews_content_util.h" #include "chrome/browser/previews/previews_service.h"
diff --git a/chrome/browser/previews/previews_ui_tab_helper_unittest.cc b/chrome/browser/previews/previews_ui_tab_helper_unittest.cc index 38e53b0..0650b16 100644 --- a/chrome/browser/previews/previews_ui_tab_helper_unittest.cc +++ b/chrome/browser/previews/previews_ui_tab_helper_unittest.cc
@@ -16,7 +16,6 @@ #include "build/build_config.h" #include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h" #include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings_factory.h" -#include "chrome/browser/loader/chrome_navigation_data.h" #include "chrome/browser/previews/previews_lite_page_navigation_throttle.h" #include "chrome/browser/previews/previews_ui_tab_helper.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h"
diff --git a/chrome/browser/previews/resource_loading_hints/resource_loading_hints_web_contents_observer.cc b/chrome/browser/previews/resource_loading_hints/resource_loading_hints_web_contents_observer.cc index a4ef961..d87b08d4 100644 --- a/chrome/browser/previews/resource_loading_hints/resource_loading_hints_web_contents_observer.cc +++ b/chrome/browser/previews/resource_loading_hints/resource_loading_hints_web_contents_observer.cc
@@ -7,7 +7,6 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/metrics/histogram_macros.h" -#include "chrome/browser/loader/chrome_navigation_data.h" #include "chrome/browser/previews/previews_content_util.h" #include "chrome/browser/previews/previews_service.h" #include "chrome/browser/previews/previews_service_factory.h"
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_webcontents_observer.cc b/chrome/browser/resource_coordinator/local_site_characteristics_webcontents_observer.cc index f749399..945e65c9 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_webcontents_observer.cc +++ b/chrome/browser/resource_coordinator/local_site_characteristics_webcontents_observer.cc
@@ -36,7 +36,7 @@ } // namespace class LocalSiteCharacteristicsWebContentsObserver::GraphObserver - : public performance_manager::GraphObserverDefaultImpl { + : public performance_manager::GraphImplObserverDefaultImpl { public: using NodeBase = performance_manager::NodeBase; using FrameNodeImpl = performance_manager::FrameNodeImpl;
diff --git a/chrome/browser/resource_coordinator/tab_lifecycle_unit_source.cc b/chrome/browser/resource_coordinator/tab_lifecycle_unit_source.cc index daf4a72..9f587ea 100644 --- a/chrome/browser/resource_coordinator/tab_lifecycle_unit_source.cc +++ b/chrome/browser/resource_coordinator/tab_lifecycle_unit_source.cc
@@ -65,7 +65,7 @@ // TabLifecycleUnitSource on the UI thread. This is created on the UI thread // and ownership passed to the performance manager. class TabLifecycleStateObserver - : public performance_manager::GraphObserverDefaultImpl { + : public performance_manager::GraphImplObserverDefaultImpl { public: using NodeBase = performance_manager::NodeBase; using PageNodeImpl = performance_manager::PageNodeImpl;
diff --git a/chrome/browser/resource_coordinator/tab_manager_resource_coordinator_signal_observer.h b/chrome/browser/resource_coordinator/tab_manager_resource_coordinator_signal_observer.h index 4488dce..1fb43b9a 100644 --- a/chrome/browser/resource_coordinator/tab_manager_resource_coordinator_signal_observer.h +++ b/chrome/browser/resource_coordinator/tab_manager_resource_coordinator_signal_observer.h
@@ -17,7 +17,7 @@ // TODO(chrisha): Kill this thing entirely and move all of tab manager into the // performance manager. class TabManager::ResourceCoordinatorSignalObserver - : public performance_manager::GraphObserverDefaultImpl { + : public performance_manager::GraphImplObserverDefaultImpl { public: using NodeBase = performance_manager::NodeBase; using PageNodeImpl = performance_manager::PageNodeImpl;
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.css b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.css index 8e2790a..cd1296b 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.css +++ b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.css
@@ -10,7 +10,6 @@ #oauth-enrollment.saml { padding-top: 44px; - width: 562px; } #oauth-enroll-step-contents { @@ -65,7 +64,7 @@ .oauth-enroll-step-message { display: inline-block; padding-top: 20px; - text-align: left; + text-align: start; vertical-align: top; } @@ -117,14 +116,3 @@ top: 0; z-index: 1; } - -.oauth-enroll-state-signin #oauth-enroll-navigation, -.oauth-enroll-state-ad-join #oauth-enroll-navigation, -.oauth-enroll-state-working #oauth-enroll-navigation { - color: white; -} - -#oauth-enrollment.saml #oauth-enroll-navigation { - color: rgba(0, 0, 0, .54); -} -
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js index 287a098..868ec34 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js +++ b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js
@@ -220,11 +220,8 @@ this.navigation_.addEventListener('close', this.cancel.bind(this)); this.navigation_.addEventListener('refresh', this.cancel.bind(this)); - this.navigation_.addEventListener( - 'back', this.onBackButtonClicked_.bind(this, false)); - $('oobe-signin-back-button') - .addEventListener('tap', this.onBackButtonClicked_.bind(this, true)); + .addEventListener('tap', this.onBackButtonClicked_.bind(this)); $('oauth-enroll-learn-more-link') @@ -472,13 +469,12 @@ * Skips the device attribute update, * shows the successful enrollment step. */ - onBackButtonClicked_: function(cancelOnClick) { - this.navigation_.backVisible = false; + onBackButtonClicked_: function() { if (this.currentStep_ == STEP_SIGNIN) { if (this.lastBackMessageValue_) { this.lastBackMessageValue_ = false; $('oauth-enroll-auth-view').back(); - } else if (cancelOnClick) { + } else { this.cancel(); } } @@ -502,17 +498,15 @@ * @type {boolean} */ isAtTheBeginning: function() { - return !this.navigation_.backVisible && this.currentStep_ == STEP_SIGNIN; + return !this.lastBackMessageValue_ && this.currentStep_ == STEP_SIGNIN; }, /** * Updates visibility of navigation buttons. */ updateControlsState: function() { - this.navigation_.backVisible = - this.currentStep_ == STEP_SIGNIN && this.lastBackMessageValue_; this.navigation_.refreshVisible = - this.isAtTheBeginning() && !this.isManualEnrollment_; + this.isAtTheBeginning() && this.isManualEnrollment_ === false; this.navigation_.closeVisible = (this.currentStep_ == STEP_ERROR && !this.navigation_.refreshVisible) || this.currentStep_ == STEP_LICENSE_TYPE;
diff --git a/chrome/browser/resources/local_ntp/BUILD.gn b/chrome/browser/resources/local_ntp/BUILD.gn index 22531ae..9b5c638 100644 --- a/chrome/browser/resources/local_ntp/BUILD.gn +++ b/chrome/browser/resources/local_ntp/BUILD.gn
@@ -13,8 +13,8 @@ js_library("local_ntp") { sources = [ "animations.js", - "custom_backgrounds.js", "custom_links_edit.js", + "customize.js", "doodles.js", "local_ntp.js", "most_visited_single.js",
diff --git a/chrome/browser/resources/local_ntp/custom_backgrounds.css b/chrome/browser/resources/local_ntp/customize.css similarity index 100% rename from chrome/browser/resources/local_ntp/custom_backgrounds.css rename to chrome/browser/resources/local_ntp/customize.css
diff --git a/chrome/browser/resources/local_ntp/custom_backgrounds.js b/chrome/browser/resources/local_ntp/customize.js similarity index 100% rename from chrome/browser/resources/local_ntp/custom_backgrounds.js rename to chrome/browser/resources/local_ntp/customize.js
diff --git a/chrome/browser/resources/local_ntp/local_ntp.html b/chrome/browser/resources/local_ntp/local_ntp.html index 186659b8..3f67324 100644 --- a/chrome/browser/resources/local_ntp/local_ntp.html +++ b/chrome/browser/resources/local_ntp/local_ntp.html
@@ -6,7 +6,7 @@ <head> <link rel="stylesheet" href="chrome-search://local-ntp/animations.css"></link> <link rel="stylesheet" href="chrome-search://local-ntp/local-ntp-common.css"></link> - <link rel="stylesheet" href="chrome-search://local-ntp/custom-backgrounds.css"></link> + <link rel="stylesheet" href="chrome-search://local-ntp/customize.css"></link> <link rel="stylesheet" href="chrome-search://local-ntp/doodles.css"></link> <link rel="stylesheet" href="chrome-search://local-ntp/local-ntp.css"></link> <link rel="stylesheet" href="chrome-search://local-ntp/theme.css"></link> @@ -18,8 +18,8 @@ integrity="$i18n{animationsIntegrity}"></script> <script src="chrome-search://local-ntp/config.js" integrity="$i18n{configDataIntegrity}"></script> - <script src="chrome-search://local-ntp/custom-backgrounds.js" - integrity="$i18n{localNtpCustomBgIntegrity}"></script> + <script src="chrome-search://local-ntp/customize.js" + integrity="$i18n{localNtpCustomizeIntegrity}"></script> <script src="chrome-search://local-ntp/doodles.js" integrity="$i18n{doodlesIntegrity}"></script> <script src="chrome-search://local-ntp/local-ntp.js"
diff --git a/chrome/browser/resources/local_ntp/local_ntp_resources.grd b/chrome/browser/resources/local_ntp/local_ntp_resources.grd index edb2d731..ade6f64 100644 --- a/chrome/browser/resources/local_ntp/local_ntp_resources.grd +++ b/chrome/browser/resources/local_ntp/local_ntp_resources.grd
@@ -18,8 +18,8 @@ <include name="IDR_LOCAL_NTP_ANIMATIONS_CSS" file="animations.css" flattenhtml="true" type="BINDATA" /> <include name="IDR_LOCAL_NTP_ANIMATIONS_JS" file="animations.js" flattenhtml="true" type="BINDATA" /> <include name="IDR_LOCAL_NTP_CSS" file="local_ntp.css" flattenhtml="true" type="BINDATA" /> - <include name="IDR_LOCAL_NTP_CUSTOM_BACKGROUNDS_CSS" file="custom_backgrounds.css" flattenhtml="true" type="BINDATA" /> - <include name="IDR_LOCAL_NTP_CUSTOM_BACKGROUNDS_JS" file="custom_backgrounds.js" flattenhtml="true" type="BINDATA" /> + <include name="IDR_LOCAL_NTP_CUSTOMIZE_CSS" file="customize.css" flattenhtml="true" type="BINDATA" /> + <include name="IDR_LOCAL_NTP_CUSTOMIZE_JS" file="customize.js" flattenhtml="true" type="BINDATA" /> <include name="IDR_LOCAL_NTP_DOODLES_CSS" file="doodles.css" flattenhtml="true" type="BINDATA" /> <include name="IDR_LOCAL_NTP_DOODLES_JS" file="doodles.js" flattenhtml="true" type="BINDATA" /> <include name="IDR_LOCAL_NTP_HTML" file="local_ntp.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
diff --git a/chrome/browser/search/BUILD.gn b/chrome/browser/search/BUILD.gn index b9a569f..3fb355e 100644 --- a/chrome/browser/search/BUILD.gn +++ b/chrome/browser/search/BUILD.gn
@@ -2,13 +2,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/compiled_action.gni") + local_ntp_resources = "//chrome/browser/resources/local_ntp" action("local_ntp_code_generate") { script = "tools/generate_integrity_header.py" header_path = "$target_gen_dir/local_ntp_js_integrity.h" animations_js = local_ntp_resources + "/animations.js" - custom_bg_js = local_ntp_resources + "/custom_backgrounds.js" + customize_js = local_ntp_resources + "/customize.js" doodles_js = local_ntp_resources + "/doodles.js" local_ntp_js = local_ntp_resources + "/local_ntp.js" utils_js = local_ntp_resources + "/utils.js" @@ -16,7 +18,7 @@ inputs = [ animations_js, - custom_bg_js, + customize_js, doodles_js, local_ntp_js, utils_js, @@ -30,7 +32,7 @@ args = [ "--output_path=" + rebase_path(header_path, root_build_dir), rebase_path(animations_js, root_build_dir), - rebase_path(custom_bg_js, root_build_dir), + rebase_path(customize_js, root_build_dir), rebase_path(doodles_js, root_build_dir), rebase_path(local_ntp_js, root_build_dir), rebase_path(utils_js, root_build_dir), @@ -38,10 +40,30 @@ ] } +executable("generate_colors_info") { + sources = [ + "chrome_colors/generate_colors_info.cc", + "chrome_colors/selected_colors_info.h", + ] + deps = [ + "//base", + "//skia", + ] +} + +compiled_action("generate_chrome_colors_info") { + tool = ":generate_colors_info" + outputs = [ + "$target_gen_dir/chrome_colors/", + ] + args = rebase_path(outputs, root_build_dir) +} + source_set("generated") { sources = get_target_outputs(":local_ntp_code_generate") public_deps = [ + ":generate_chrome_colors_info", ":local_ntp_code_generate", ] }
diff --git a/chrome/browser/search/chrome_colors/generate_colors_info.cc b/chrome/browser/search/chrome_colors/generate_colors_info.cc new file mode 100644 index 0000000..f214cc8 --- /dev/null +++ b/chrome/browser/search/chrome_colors/generate_colors_info.cc
@@ -0,0 +1,135 @@ +// 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/base64.h" +#include "base/files/file_util.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" +#include "chrome/browser/search/chrome_colors/selected_colors_info.h" + +// TODO(gayane): Replace with real template. +// Template for the icon svg. +// $1 - primary color +// $2 - secondary color +const char kIconTemplate[] = + "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><!DOCTYPE svg " + "PUBLIC \"-//W3C//DTD SVG 1.1//EN\" " + "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"><svg version=\"1.1\" " + "xmlns=\"http://www.w3.org/2000/svg\" " + "xmlns:xlink=\"http://www.w3.org/1999/xlink\" " + "preserveAspectRatio=\"xMidYMid meet\" viewBox=\"0 0 640 640\" " + "width=\"640\" height=\"640\"><defs><path d=\"M0 0L640 0L640 640L0 640L0 " + "0Z\" id=\"a1Y0EmMoCp\"></path><path d=\"M499.23 317.62C499.23 396.82 " + "420.79 461.12 324.17 461.12C227.55 461.12 149.11 396.82 149.11 " + "317.62C149.11 238.42 227.55 174.12 324.17 174.12C420.79 174.12 499.23 " + "238.42 499.23 317.62Z\" id=\"f7eUC88KqB\"></path></defs><g><g><g " + "transform=\"matrix(1 0 0 1 0 0)\" " + "vector-effect=\"non-scaling-stroke\"><use xlink:href=\"#a1Y0EmMoCp\" " + "opacity=\"1\" fill=$1 fill-opacity=\"1\"></use></g><g><use " + "xlink:href=\"#f7eUC88KqB\" opacity=\"1\" fill=$2 " + "fill-opacity=\"1\"></use></g></g></g></svg>"; + +// Template for color info line. +// $1 - color id +// $2 - red value of primary color +// $3 - green value of primary color +// $4 - blue value of primary color +// $5 - color label +// $6 - icon data +const char kColorInfoLineTemplate[] = + " ColorInfo($1, SkColorSetRGB($2, $3, $4), \"$5\", " + "\"data:image/svg+xml;base64,$6\")"; + +// Template for the generated file content. +// $1 - lines for updated color info. +const char kFileContentTemplate[] = + "// Generated from generate_colors_info.cc. Do not edit!\n" + "\n" + "#ifndef CHROME_BROWSER_SEARCH_CHROME_COLORS_GENERATED_COLORS_INFO_H_\n" + "#define CHROME_BROWSER_SEARCH_CHROME_COLORS_GENERATED_COLORS_INFO_H_\n" + "\n" + "#include <stdint.h>\n" + "\n" + "#include \"chrome/common/search/instant_types.h\"\n" + "#include \"third_party/skia/include/core/SkColor.h\"\n" + "\n" + "namespace chrome_colors {\n" + "\n" + "// List of preselected colors with icon data to show in Chrome Colors" + " menu.\n" + "constexpr ColorInfo kGeneratedColorsInfo[] = {\n" + "$1\n" + "};\n" + "\n" + "} // namespace chrome_colors\n" + "\n" + "#endif // CHROME_BROWSER_SEARCH_CHROME_COLORS_GENERATED_COLORS_INFO_H_\n"; + +// Generated file name. +const base::FilePath::CharType kColorsInfoFilename[] = + FILE_PATH_LITERAL("generated_colors_info.h"); + +// Returns hex string representation for the |color| in "#FFFFFF" format. +std::string SkColorToHexString(SkColor color) { + return base::StringPrintf("\"#%02X%02X%02X\"", SkColorGetR(color), + SkColorGetG(color), SkColorGetB(color)); +} + +// Returns icon data for the given |color| as encoded svg. +// The returned string can be later directly set in JS with the following +// format: "data:image/svg+xml;base64<ENCODED_SVG>" +std::string GenerateIconDataForColor(SkColor color) { + std::vector<std::string> subst; + subst.push_back(SkColorToHexString(color)); + // TODO(gayane): Replace white will secondary color calculated using + // browser_theme_pack. + subst.push_back(SkColorToHexString(SK_ColorWHITE)); + + std::string svg_base64; + base::Base64Encode( + base::ReplaceStringPlaceholders(kIconTemplate, subst, NULL), &svg_base64); + return svg_base64; +} + +// Generates color info line in the following format: +// ColorInfo(ID, SkColorSetRGB(R, G, B), LABEL, ICON_DATA) +std::string GenerateColorLine(chrome_colors::ColorInfo color_info) { + std::vector<std::string> subst; + subst.push_back(base::NumberToString(color_info.id)); + subst.push_back(base::NumberToString(SkColorGetR(color_info.color))); + subst.push_back(base::NumberToString(SkColorGetG(color_info.color))); + subst.push_back(base::NumberToString(SkColorGetB(color_info.color))); + subst.push_back(color_info.label); + subst.push_back(GenerateIconDataForColor(color_info.color)); + return base::ReplaceStringPlaceholders(kColorInfoLineTemplate, subst, NULL); +} + +// Generates 'generated_colors_info.h' that contains selected colors from +// |chrome_colors::kSelectedColorsInfo| along with generated icon data. +void GenerateColorsInfoFile(std::string output_dir) { + std::vector<std::string> updated_color_info; + for (chrome_colors::ColorInfo color_info : chrome_colors::kSelectedColorsInfo) + updated_color_info.push_back(GenerateColorLine(color_info)); + + std::vector<std::string> subst; + subst.push_back(base::JoinString(updated_color_info, ",\n")); + std::string output = + base::ReplaceStringPlaceholders(kFileContentTemplate, subst, NULL); + + base::FilePath output_path = base::FilePath::FromUTF8Unsafe(output_dir); + if (!base::DirectoryExists(output_path)) + base::CreateDirectory(output_path); + + output_path = output_path.Append(kColorsInfoFilename); + if (base::WriteFile(output_path, output.c_str(), + static_cast<uint32_t>(output.size())) <= 0) { + LOG(ERROR) << "Failed to write output to " << output_path; + } +} + +int main(int argc, char* argv[]) { + GenerateColorsInfoFile(argv[1]); + return 0; +}
diff --git a/chrome/browser/search/chrome_colors/selected_colors_info.h b/chrome/browser/search/chrome_colors/selected_colors_info.h new file mode 100644 index 0000000..638b900 --- /dev/null +++ b/chrome/browser/search/chrome_colors/selected_colors_info.h
@@ -0,0 +1,34 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SEARCH_CHROME_COLORS_SELECTED_COLORS_INFO_H_ +#define CHROME_BROWSER_SEARCH_CHROME_COLORS_SELECTED_COLORS_INFO_H_ + +#include <stdint.h> + +#include "third_party/skia/include/core/SkColor.h" + +namespace chrome_colors { + +struct ColorInfo { + ColorInfo(int id, SkColor color, const char* label) + : id(id), color(color), label(label) {} + constexpr ColorInfo(int id, + SkColor color, + const char* label, + const char* icon_data) + : id(id), color(color), label(label), icon_data(icon_data) {} + int id; + SkColor color; + const char* label; + const char* icon_data; +}; + +// TODO(gayane): Add colors selected by UX. +// List of preselected colors to show in Chrome Colors menu. +const ColorInfo kSelectedColorsInfo[] = {}; + +} // namespace chrome_colors + +#endif // CHROME_BROWSER_SEARCH_CHROME_COLORS_SELECTED_COLORS_INFO_H_
diff --git a/chrome/browser/search/local_ntp_source.cc b/chrome/browser/search/local_ntp_source.cc index ae2acaf..57bf875 100644 --- a/chrome/browser/search/local_ntp_source.cc +++ b/chrome/browser/search/local_ntp_source.cc
@@ -117,10 +117,8 @@ {"animations.css", IDR_LOCAL_NTP_ANIMATIONS_CSS, "text/css"}, {"animations.js", IDR_LOCAL_NTP_ANIMATIONS_JS, "application/javascript"}, {"local-ntp-common.css", IDR_LOCAL_NTP_COMMON_CSS, "text/css"}, - {"custom-backgrounds.css", IDR_LOCAL_NTP_CUSTOM_BACKGROUNDS_CSS, - "text/css"}, - {"custom-backgrounds.js", IDR_LOCAL_NTP_CUSTOM_BACKGROUNDS_JS, - "application/javascript"}, + {"customize.css", IDR_LOCAL_NTP_CUSTOMIZE_CSS, "text/css"}, + {"customize.js", IDR_LOCAL_NTP_CUSTOMIZE_JS, "application/javascript"}, {"doodles.css", IDR_LOCAL_NTP_DOODLES_CSS, "text/css"}, {"doodles.js", IDR_LOCAL_NTP_DOODLES_JS, "application/javascript"}, {"images/close_3_mask.png", IDR_CLOSE_3_MASK, "image/png"}, @@ -979,8 +977,8 @@ base::StrCat({kSha256, ANIMATIONS_JS_INTEGRITY}); replacements["configDataIntegrity"] = base::StrCat( {kSha256, search_config_provider_->config_data_integrity()}); - replacements["localNtpCustomBgIntegrity"] = - base::StrCat({kSha256, CUSTOM_BACKGROUNDS_JS_INTEGRITY}); + replacements["localNtpCustomizeIntegrity"] = + base::StrCat({kSha256, CUSTOMIZE_JS_INTEGRITY}); replacements["doodlesIntegrity"] = base::StrCat({kSha256, DOODLES_JS_INTEGRITY}); replacements["localNtpIntegrity"] = @@ -1113,9 +1111,8 @@ std::string script_src_csp = base::StringPrintf( "script-src 'strict-dynamic' 'sha256-%s' 'sha256-%s' 'sha256-%s' " "'sha256-%s' 'sha256-%s' 'sha256-%s' 'sha256-%s';", - ANIMATIONS_JS_INTEGRITY, CUSTOM_BACKGROUNDS_JS_INTEGRITY, - DOODLES_JS_INTEGRITY, LOCAL_NTP_JS_INTEGRITY, UTILS_JS_INTEGRITY, - VOICE_JS_INTEGRITY, + ANIMATIONS_JS_INTEGRITY, CUSTOMIZE_JS_INTEGRITY, DOODLES_JS_INTEGRITY, + LOCAL_NTP_JS_INTEGRITY, UTILS_JS_INTEGRITY, VOICE_JS_INTEGRITY, search_config_provider_->config_data_integrity().c_str()); return GetContentSecurityPolicyObjectSrc() +
diff --git a/chrome/browser/signin/identity_manager_factory.cc b/chrome/browser/signin/identity_manager_factory.cc index a6f2dfc..89a9575 100644 --- a/chrome/browser/signin/identity_manager_factory.cc +++ b/chrome/browser/signin/identity_manager_factory.cc
@@ -16,6 +16,7 @@ #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/keyed_service/core/keyed_service.h" #include "components/pref_registry/pref_registry_syncable.h" +#include "components/signin/core/browser/gaia_cookie_manager_service.h" #include "components/signin/core/browser/identity_manager_wrapper.h" #include "components/signin/core/browser/signin_manager.h" #include "services/identity/public/cpp/accounts_cookie_mutator.h" @@ -80,20 +81,17 @@ std::unique_ptr<ConcreteSigninManager> BuildSigninManager( Profile* profile, AccountTrackerService* account_tracker_service, - ProfileOAuth2TokenService* token_service, - GaiaCookieManagerService* gaia_cookie_manager_service) { + ProfileOAuth2TokenService* token_service) { std::unique_ptr<ConcreteSigninManager> signin_manager; SigninClient* client = ChromeSigninClientFactory::GetInstance()->GetForProfile(profile); #if defined(OS_CHROMEOS) signin_manager = std::make_unique<ConcreteSigninManager>( client, token_service, account_tracker_service, - gaia_cookie_manager_service, AccountConsistencyModeManager::GetMethodForProfile(profile)); #else signin_manager = std::make_unique<ConcreteSigninManager>( client, token_service, account_tracker_service, - gaia_cookie_manager_service, AccountConsistencyModeManager::GetMethodForProfile(profile)); #endif signin_manager->Initialize(g_browser_process->local_state()); @@ -190,8 +188,7 @@ token_service.get(), ChromeSigninClientFactory::GetForProfile(profile)); std::unique_ptr<ConcreteSigninManager> signin_manager = BuildSigninManager( - profile, account_tracker_service.get(), token_service.get(), - gaia_cookie_manager_service.get()); + profile, account_tracker_service.get(), token_service.get()); std::unique_ptr<identity::PrimaryAccountMutator> primary_account_mutator = BuildPrimaryAccountMutator(profile, account_tracker_service.get(),
diff --git a/chrome/browser/spellchecker/spellcheck_service_browsertest.cc b/chrome/browser/spellchecker/spellcheck_service_browsertest.cc index c73a908..8d5ebe0 100644 --- a/chrome/browser/spellchecker/spellcheck_service_browsertest.cc +++ b/chrome/browser/spellchecker/spellcheck_service_browsertest.cc
@@ -27,6 +27,7 @@ #include "chrome/common/chrome_paths.h" #include "chrome/common/constants.mojom.h" #include "chrome/test/base/in_process_browser_test.h" +#include "components/browser_sync/browser_sync_switches.h" #include "components/language/core/browser/pref_names.h" #include "components/prefs/pref_service.h" #include "components/spellcheck/browser/pref_names.h" @@ -54,6 +55,16 @@ prefs_ = user_prefs::UserPrefs::Get(GetContext()); } + void SetUpCommandLine(base::CommandLine* command_line) override { + // Sync causes the SpellcheckService to be instantiated (and initialized) + // during startup. However, several tests rely on control over when exactly + // the SpellcheckService gets created (e.g. by calling + // GetEnableSpellcheckState() after InitSpellcheck(), which will wait + // forever if the service already existed). So disable sync of the custom + // dictionary for these tests. + command_line->AppendSwitchASCII(switches::kDisableSyncTypes, "Dictionary"); + } + void TearDownOnMainThread() override { binding_.Close(); prefs_ = nullptr;
diff --git a/chrome/browser/supervised_user/supervised_user_sync_model_type_controller.cc b/chrome/browser/supervised_user/supervised_user_sync_model_type_controller.cc index 90b066a..33e4c44 100644 --- a/chrome/browser/supervised_user/supervised_user_sync_model_type_controller.cc +++ b/chrome/browser/supervised_user/supervised_user_sync_model_type_controller.cc
@@ -17,10 +17,7 @@ : SyncableServiceBasedModelTypeController( type, sync_client->GetModelTypeStoreService()->GetStoreFactory(), - base::BindOnce( - &browser_sync::BrowserSyncClient::GetSyncableServiceForType, - base::Unretained(sync_client), - type), + sync_client->GetSyncableServiceForType(type), dump_stack), profile_(profile) { DCHECK(type == syncer::SUPERVISED_USER_SETTINGS ||
diff --git a/chrome/browser/sync/chrome_sync_client.cc b/chrome/browser/sync/chrome_sync_client.cc index 5c5838d..5341b4c 100644 --- a/chrome/browser/sync/chrome_sync_client.cc +++ b/chrome/browser/sync/chrome_sync_client.cc
@@ -152,6 +152,11 @@ return disabled_types; } +base::WeakPtr<syncer::SyncableService> GetWeakPtrOrNull( + syncer::SyncableService* service) { + return service ? service->AsWeakPtr() : nullptr; +} + } // namespace ChromeSyncClient::ChromeSyncClient(Profile* profile) : profile_(profile) { @@ -303,9 +308,7 @@ if (!disabled_types.Has(syncer::APPS)) { controllers.push_back(std::make_unique<ExtensionModelTypeController>( syncer::APPS, GetModelTypeStoreService()->GetStoreFactory(), - base::BindOnce(&ChromeSyncClient::GetSyncableServiceForType, - base::Unretained(this), syncer::APPS), - dump_stack, profile_)); + GetSyncableServiceForType(syncer::APPS), dump_stack, profile_)); } // Extension sync is enabled by default. Register unless explicitly @@ -313,9 +316,7 @@ if (!disabled_types.Has(syncer::EXTENSIONS)) { controllers.push_back(std::make_unique<ExtensionModelTypeController>( syncer::EXTENSIONS, GetModelTypeStoreService()->GetStoreFactory(), - base::BindOnce(&ChromeSyncClient::GetSyncableServiceForType, - base::Unretained(this), syncer::EXTENSIONS), - dump_stack, profile_)); + GetSyncableServiceForType(syncer::EXTENSIONS), dump_stack, profile_)); } // Extension setting sync is enabled by default. Register unless explicitly @@ -345,9 +346,7 @@ if (!disabled_types.Has(syncer::THEMES)) { controllers.push_back(std::make_unique<ExtensionModelTypeController>( syncer::THEMES, GetModelTypeStoreService()->GetStoreFactory(), - base::BindOnce(&ChromeSyncClient::GetSyncableServiceForType, - base::Unretained(this), syncer::THEMES), - dump_stack, profile_)); + GetSyncableServiceForType(syncer::THEMES), dump_stack, profile_)); } // Search Engine sync is enabled by default. Register unless explicitly @@ -357,9 +356,7 @@ std::make_unique<syncer::SyncableServiceBasedModelTypeController>( syncer::SEARCH_ENGINES, GetModelTypeStoreService()->GetStoreFactory(), - base::BindOnce(&ChromeSyncClient::GetSyncableServiceForType, - base::Unretained(this), syncer::SEARCH_ENGINES), - dump_stack)); + GetSyncableServiceForType(syncer::SEARCH_ENGINES), dump_stack)); } #endif // !defined(OS_ANDROID) @@ -367,9 +364,7 @@ controllers.push_back( std::make_unique<syncer::SyncableServiceBasedModelTypeController>( syncer::APP_LIST, GetModelTypeStoreService()->GetStoreFactory(), - base::BindOnce(&ChromeSyncClient::GetSyncableServiceForType, - base::Unretained(this), syncer::APP_LIST), - dump_stack)); + GetSyncableServiceForType(syncer::APP_LIST), dump_stack)); #endif // BUILDFLAG(ENABLE_APP_LIST) #if defined(OS_LINUX) || defined(OS_WIN) @@ -378,9 +373,7 @@ controllers.push_back( std::make_unique<syncer::SyncableServiceBasedModelTypeController>( syncer::DICTIONARY, GetModelTypeStoreService()->GetStoreFactory(), - base::BindOnce(&ChromeSyncClient::GetSyncableServiceForType, - base::Unretained(this), syncer::DICTIONARY), - dump_stack)); + GetSyncableServiceForType(syncer::DICTIONARY), dump_stack)); } #endif // defined(OS_LINUX) || defined(OS_WIN) @@ -389,9 +382,8 @@ !arc::IsArcAppSyncFlowDisabled()) { controllers.push_back(std::make_unique<ArcPackageSyncModelTypeController>( GetModelTypeStoreService()->GetStoreFactory(), - base::BindOnce(&ChromeSyncClient::GetSyncableServiceForType, - base::Unretained(this), syncer::ARC_PACKAGE), - dump_stack, sync_service, profile_)); + GetSyncableServiceForType(syncer::ARC_PACKAGE), dump_stack, + sync_service, profile_)); } #endif // defined(OS_CHROMEOS) @@ -438,21 +430,21 @@ profile_web_data_service_.get()) ->AsWeakPtr(); } - return base::WeakPtr<syncer::SyncableService>(); - case syncer::AUTOFILL_WALLET_METADATA: { + return nullptr; + case syncer::AUTOFILL_WALLET_METADATA: if (profile_web_data_service_) { return autofill::AutofillWalletMetadataSyncableService:: FromWebDataService(profile_web_data_service_.get()) ->AsWeakPtr(); } - return base::WeakPtr<syncer::SyncableService>(); - } + return nullptr; case syncer::SEARCH_ENGINES: - return TemplateURLServiceFactory::GetForProfile(profile_)->AsWeakPtr(); + return GetWeakPtrOrNull( + TemplateURLServiceFactory::GetForProfile(profile_)); #if BUILDFLAG(ENABLE_EXTENSIONS) case syncer::APPS: case syncer::EXTENSIONS: - return ExtensionSyncService::Get(profile_)->AsWeakPtr(); + return GetWeakPtrOrNull(ExtensionSyncService::Get(profile_)); // TODO(crbug.com/933874): Remove these two from here once the old // controllers are deleted. case syncer::APP_SETTINGS: @@ -462,8 +454,8 @@ #endif // BUILDFLAG(ENABLE_EXTENSIONS) #if BUILDFLAG(ENABLE_APP_LIST) case syncer::APP_LIST: - return app_list::AppListSyncableServiceFactory::GetForProfile(profile_)-> - AsWeakPtr(); + return GetWeakPtrOrNull( + app_list::AppListSyncableServiceFactory::GetForProfile(profile_)); #endif // BUILDFLAG(ENABLE_APP_LIST) #if !defined(OS_ANDROID) case syncer::THEMES: @@ -472,36 +464,35 @@ #endif // !defined(OS_ANDROID) case syncer::HISTORY_DELETE_DIRECTIVES: { history::HistoryService* history = GetHistoryService(); - return history ? history->GetDeleteDirectivesSyncableService() - : base::WeakPtr<syncer::SyncableService>(); + return history ? history->GetDeleteDirectivesSyncableService() : nullptr; } #if BUILDFLAG(ENABLE_SPELLCHECK) - case syncer::DICTIONARY: - return SpellcheckServiceFactory::GetForContext(profile_)-> - GetCustomDictionary()->AsWeakPtr(); + case syncer::DICTIONARY: { + SpellcheckService* spellcheck_service = + SpellcheckServiceFactory::GetForContext(profile_); + return spellcheck_service + ? spellcheck_service->GetCustomDictionary()->AsWeakPtr() + : nullptr; + } #endif // BUILDFLAG(ENABLE_SPELLCHECK) case syncer::FAVICON_IMAGES: - case syncer::FAVICON_TRACKING: { - sync_sessions::FaviconCache* favicons = - SessionSyncServiceFactory::GetForProfile(profile_)->GetFaviconCache(); - return favicons ? favicons->AsWeakPtr() - : base::WeakPtr<syncer::SyncableService>(); - } + case syncer::FAVICON_TRACKING: + return GetWeakPtrOrNull(SessionSyncServiceFactory::GetForProfile(profile_) + ->GetFaviconCache()); #if BUILDFLAG(ENABLE_SUPERVISED_USERS) case syncer::SUPERVISED_USER_SETTINGS: return SupervisedUserSettingsServiceFactory::GetForKey( profile_->GetProfileKey()) ->AsWeakPtr(); - case syncer::SUPERVISED_USER_WHITELISTS: { - SupervisedUserService* supervised_user_service = - SupervisedUserServiceFactory::GetForProfile(profile_); - return supervised_user_service->GetWhitelistService()->AsWeakPtr(); - } + case syncer::SUPERVISED_USER_WHITELISTS: + return SupervisedUserServiceFactory::GetForProfile(profile_) + ->GetWhitelistService() + ->AsWeakPtr(); #endif // BUILDFLAG(ENABLE_SUPERVISED_USERS) case syncer::PASSWORDS: { return password_store_.get() ? password_store_->GetPasswordSyncableService() - : base::WeakPtr<syncer::SyncableService>(); + : nullptr; } #if defined(OS_CHROMEOS) case syncer::ARC_PACKAGE: @@ -512,7 +503,7 @@ // syncer::SyncableService API: // Bookmarks NOTREACHED(); - return base::WeakPtr<syncer::SyncableService>(); + return nullptr; } }
diff --git a/chrome/browser/sync/glue/extension_model_type_controller.cc b/chrome/browser/sync/glue/extension_model_type_controller.cc index 7cd6f543..6dbc00a 100644 --- a/chrome/browser/sync/glue/extension_model_type_controller.cc +++ b/chrome/browser/sync/glue/extension_model_type_controller.cc
@@ -14,14 +14,13 @@ ExtensionModelTypeController::ExtensionModelTypeController( syncer::ModelType type, syncer::OnceModelTypeStoreFactory store_factory, - SyncableServiceProvider syncable_service_provider, + base::WeakPtr<syncer::SyncableService> syncable_service, const base::RepeatingClosure& dump_stack, Profile* profile) - : SyncableServiceBasedModelTypeController( - type, - std::move(store_factory), - std::move(syncable_service_provider), - dump_stack), + : SyncableServiceBasedModelTypeController(type, + std::move(store_factory), + syncable_service, + dump_stack), profile_(profile) { DCHECK(type == syncer::EXTENSIONS || type == syncer::APPS || type == syncer::THEMES);
diff --git a/chrome/browser/sync/glue/extension_model_type_controller.h b/chrome/browser/sync/glue/extension_model_type_controller.h index 83c4755..98c7fe4 100644 --- a/chrome/browser/sync/glue/extension_model_type_controller.h +++ b/chrome/browser/sync/glue/extension_model_type_controller.h
@@ -21,7 +21,7 @@ ExtensionModelTypeController( syncer::ModelType type, syncer::OnceModelTypeStoreFactory store_factory, - SyncableServiceProvider syncable_service_provider, + base::WeakPtr<syncer::SyncableService> syncable_service, const base::RepeatingClosure& dump_stack, Profile* profile); ~ExtensionModelTypeController() override;
diff --git a/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc b/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc index ebcb72b0..6538ed0 100644 --- a/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc
@@ -72,11 +72,11 @@ EXPECT_EQ( 1U, histogram_tester .GetAllSamples( - "Sync.NonReflectionUpdateFreshnessPossiblySkewed.PREFERENCE") + "Sync.NonReflectionUpdateFreshnessPossiblySkewed2.PREFERENCE") .size()); EXPECT_NE( 0U, histogram_tester - .GetAllSamples("Sync.NonReflectionUpdateFreshnessPossiblySkewed") + .GetAllSamples("Sync.NonReflectionUpdateFreshnessPossiblySkewed2") .size()); }
diff --git a/chrome/browser/ui/app_list/arc/arc_package_sync_model_type_controller.cc b/chrome/browser/ui/app_list/arc/arc_package_sync_model_type_controller.cc index 4685a3aa0..bf2ea04 100644 --- a/chrome/browser/ui/app_list/arc/arc_package_sync_model_type_controller.cc +++ b/chrome/browser/ui/app_list/arc/arc_package_sync_model_type_controller.cc
@@ -12,15 +12,14 @@ ArcPackageSyncModelTypeController::ArcPackageSyncModelTypeController( syncer::OnceModelTypeStoreFactory store_factory, - SyncableServiceProvider syncable_service_provider, + base::WeakPtr<syncer::SyncableService> syncable_service, const base::RepeatingClosure& dump_stack, syncer::SyncService* sync_service, Profile* profile) - : syncer::SyncableServiceBasedModelTypeController( - syncer::ARC_PACKAGE, - std::move(store_factory), - std::move(syncable_service_provider), - dump_stack), + : syncer::SyncableServiceBasedModelTypeController(syncer::ARC_PACKAGE, + std::move(store_factory), + syncable_service, + dump_stack), sync_service_(sync_service), profile_(profile) { arc::ArcSessionManager* arc_session_manager = arc::ArcSessionManager::Get();
diff --git a/chrome/browser/ui/app_list/arc/arc_package_sync_model_type_controller.h b/chrome/browser/ui/app_list/arc/arc_package_sync_model_type_controller.h index 1f47081..7b0f7f6 100644 --- a/chrome/browser/ui/app_list/arc/arc_package_sync_model_type_controller.h +++ b/chrome/browser/ui/app_list/arc/arc_package_sync_model_type_controller.h
@@ -24,7 +24,7 @@ // |dump_stack| is called when an unrecoverable error occurs. ArcPackageSyncModelTypeController( syncer::OnceModelTypeStoreFactory store_factory, - SyncableServiceProvider syncable_service_provider, + base::WeakPtr<syncer::SyncableService> syncable_service, const base::RepeatingClosure& dump_stack, syncer::SyncService* sync_service, Profile* profile);
diff --git a/chrome/browser/ui/ash/drag_to_overview_interactive_uitest.cc b/chrome/browser/ui/ash/drag_to_overview_interactive_uitest.cc index 13b4335..d5e992c9 100644 --- a/chrome/browser/ui/ash/drag_to_overview_interactive_uitest.cc +++ b/chrome/browser/ui/ash/drag_to_overview_interactive_uitest.cc
@@ -9,7 +9,6 @@ #include "base/run_loop.h" #include "base/task/post_task.h" #include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/ui/ash/tablet_mode_client_test_util.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/views/frame/browser_view.h" @@ -81,7 +80,7 @@ } void SetUpOnMainThread() override { UIPerformanceTest::SetUpOnMainThread(); - test::SetAndWaitForTabletMode(true); + ash::ShellTestApi().EnableTabletModeWindowManager(true); if (base::SysInfo::IsRunningOnChromeOS()) { base::RunLoop run_loop;
diff --git a/chrome/browser/ui/ash/fake_tablet_mode_controller.cc b/chrome/browser/ui/ash/fake_tablet_mode_controller.cc index e98cf63..d11940c 100644 --- a/chrome/browser/ui/ash/fake_tablet_mode_controller.cc +++ b/chrome/browser/ui/ash/fake_tablet_mode_controller.cc
@@ -6,24 +6,19 @@ #include <utility> -FakeTabletModeController::FakeTabletModeController() : binding_(this) {} +FakeTabletModeController::FakeTabletModeController() = default; FakeTabletModeController::~FakeTabletModeController() = default; -ash::mojom::TabletModeControllerPtr -FakeTabletModeController::CreateInterfacePtr() { - ash::mojom::TabletModeControllerPtr ptr; - binding_.Bind(mojo::MakeRequest(&ptr)); - return ptr; +void FakeTabletModeController::SetTabletModeToggleObserver( + ash::TabletModeToggleObserver* observer) { + observer_ = observer; } -void FakeTabletModeController::SetClient( - ash::mojom::TabletModeClientPtr client) { - was_client_set_ = true; +bool FakeTabletModeController::IsEnabled() const { + return enabled_; } -void FakeTabletModeController::SetTabletModeEnabledForTesting( - bool enabled, - SetTabletModeEnabledForTestingCallback callback) { - std::move(callback).Run(enabled); +void FakeTabletModeController::SetEnabledForTest(bool enabled) { + enabled_ = enabled; }
diff --git a/chrome/browser/ui/ash/fake_tablet_mode_controller.h b/chrome/browser/ui/ash/fake_tablet_mode_controller.h index 45e9c66..2418ba2 100644 --- a/chrome/browser/ui/ash/fake_tablet_mode_controller.h +++ b/chrome/browser/ui/ash/fake_tablet_mode_controller.h
@@ -5,32 +5,27 @@ #ifndef CHROME_BROWSER_UI_ASH_FAKE_TABLET_MODE_CONTROLLER_H_ #define CHROME_BROWSER_UI_ASH_FAKE_TABLET_MODE_CONTROLLER_H_ -#include "ash/public/interfaces/tablet_mode.mojom.h" +#include "ash/public/cpp/tablet_mode.h" #include "base/macros.h" -#include "mojo/public/cpp/bindings/binding.h" // Simulates the TabletModeController in ash. -class FakeTabletModeController : ash::mojom::TabletModeController { +class FakeTabletModeController : public ash::TabletMode { public: FakeTabletModeController(); ~FakeTabletModeController() override; - bool was_client_set() const { return was_client_set_; } - - // Returns a mojo interface pointer bound to this object. - ash::mojom::TabletModeControllerPtr CreateInterfacePtr(); + bool has_observer() const { return !!observer_; } // ash::mojom::TabletModeController: - void SetClient(ash::mojom::TabletModeClientPtr client) override; - void SetTabletModeEnabledForTesting( - bool enabled, - SetTabletModeEnabledForTestingCallback callback) override; + void SetTabletModeToggleObserver( + ash::TabletModeToggleObserver* observer) override; + bool IsEnabled() const override; + void SetEnabledForTest(bool enabled) override; private: - mojo::Binding<ash::mojom::TabletModeController> binding_; - - bool was_client_set_ = false; + bool enabled_ = false; + ash::TabletModeToggleObserver* observer_ = nullptr; DISALLOW_COPY_AND_ASSIGN(FakeTabletModeController); };
diff --git a/chrome/browser/ui/ash/launcher/launcher_context_menu_unittest.cc b/chrome/browser/ui/ash/launcher/launcher_context_menu_unittest.cc index e18fb4c..9c1b3b1 100644 --- a/chrome/browser/ui/ash/launcher/launcher_context_menu_unittest.cc +++ b/chrome/browser/ui/ash/launcher/launcher_context_menu_unittest.cc
@@ -26,7 +26,6 @@ #include "chrome/browser/ui/app_list/arc/arc_app_test.h" #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" #include "chrome/browser/ui/app_list/internal_app/internal_app_metadata.h" -#include "chrome/browser/ui/ash/fake_tablet_mode_controller.h" #include "chrome/browser/ui/ash/launcher/arc_app_shelf_id.h" #include "chrome/browser/ui/ash/launcher/arc_launcher_context_menu.h" #include "chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.h" @@ -81,8 +80,6 @@ std::make_unique<ChromeLauncherController>(&profile_, model_.get()); tablet_mode_client_ = std::make_unique<TabletModeClient>(); - tablet_mode_client_->InitForTesting( - fake_tablet_mode_controller_.CreateInterfacePtr()); // Disable safe icon decoding to ensure ArcAppShortcutRequests returns in // the test environment. @@ -141,6 +138,9 @@ void TearDown() override { launcher_controller_.reset(); ChromeAshTestBase::TearDown(); + // To match ChromeBrowserMainExtraPartsAsh, shut down the TabletModeClient + // after Shell. + tablet_mode_client_.reset(); } ArcAppTest& arc_test() { return arc_test_; } @@ -158,7 +158,6 @@ std::unique_ptr<ash::ShelfModel> model_; std::unique_ptr<ChromeLauncherController> launcher_controller_; - FakeTabletModeController fake_tablet_mode_controller_; std::unique_ptr<TabletModeClient> tablet_mode_client_; DISALLOW_COPY_AND_ASSIGN(LauncherContextMenuTest);
diff --git a/chrome/browser/ui/ash/overview_animations_interactive_uitest.cc b/chrome/browser/ui/ash/overview_animations_interactive_uitest.cc index 404bc617..1390f43 100644 --- a/chrome/browser/ui/ash/overview_animations_interactive_uitest.cc +++ b/chrome/browser/ui/ash/overview_animations_interactive_uitest.cc
@@ -6,7 +6,6 @@ #include "base/macros.h" #include "base/run_loop.h" #include "base/task/post_task.h" -#include "chrome/browser/ui/ash/tablet_mode_client_test_util.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/views/frame/browser_view.h" @@ -35,7 +34,7 @@ tablet_mode_ = std::get<2>(GetParam()); if (tablet_mode_) - test::SetAndWaitForTabletMode(true); + ash::ShellTestApi().EnableTabletModeWindowManager(true); GURL ntp_url("chrome://newtab"); // The default is blank page.
diff --git a/chrome/browser/ui/ash/overview_window_drag_interactive_uitest.cc b/chrome/browser/ui/ash/overview_window_drag_interactive_uitest.cc index 5246687..faa5b37 100644 --- a/chrome/browser/ui/ash/overview_window_drag_interactive_uitest.cc +++ b/chrome/browser/ui/ash/overview_window_drag_interactive_uitest.cc
@@ -9,7 +9,6 @@ #include "base/run_loop.h" #include "base/task/post_task.h" #include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/ui/ash/tablet_mode_client_test_util.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/views/frame/browser_view.h" @@ -77,7 +76,7 @@ // UIPerformanceTest: void SetUpOnMainThread() override { UIPerformanceTest::SetUpOnMainThread(); - test::SetAndWaitForTabletMode(true); + ash::ShellTestApi().EnableTabletModeWindowManager(true); int additional_browsers = std::get<0>(GetParam()) - 1; bool blank_page = std::get<1>(GetParam());
diff --git a/chrome/browser/ui/ash/screen_rotation_interactive_uitest.cc b/chrome/browser/ui/ash/screen_rotation_interactive_uitest.cc index 5ece549..42520d1 100644 --- a/chrome/browser/ui/ash/screen_rotation_interactive_uitest.cc +++ b/chrome/browser/ui/ash/screen_rotation_interactive_uitest.cc
@@ -10,7 +10,6 @@ #include "base/macros.h" #include "base/run_loop.h" #include "base/task/post_task.h" -#include "chrome/browser/ui/ash/tablet_mode_client_test_util.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/views/frame/browser_view.h" @@ -35,7 +34,7 @@ // UIPerformanceTest: void SetUpOnMainThread() override { UIPerformanceTest::SetUpOnMainThread(); - test::SetAndWaitForTabletMode(true); + ash::ShellTestApi().EnableTabletModeWindowManager(true); auto* pref = browser()->profile()->GetPrefs(); pref->SetBoolean( ash::prefs::kDisplayRotationAcceleratorDialogHasBeenAccepted, true);
diff --git a/chrome/browser/ui/ash/split_view_interactive_uitest.cc b/chrome/browser/ui/ash/split_view_interactive_uitest.cc index d01c2e9..f52e9c40 100644 --- a/chrome/browser/ui/ash/split_view_interactive_uitest.cc +++ b/chrome/browser/ui/ash/split_view_interactive_uitest.cc
@@ -11,7 +11,6 @@ #include "base/system/sys_info.h" #include "base/task/post_task.h" #include "base/test/bind_test_util.h" -#include "chrome/browser/ui/ash/tablet_mode_client_test_util.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/views/frame/browser_view.h" @@ -118,7 +117,7 @@ run_loop.Run(); } - test::SetAndWaitForTabletMode(true); + ash::ShellTestApi().EnableTabletModeWindowManager(true); views::Widget* browser_widget = BrowserView::GetBrowserViewForBrowser(browser())->GetWidget();
diff --git a/chrome/browser/ui/ash/tablet_mode_client.cc b/chrome/browser/ui/ash/tablet_mode_client.cc index 7fb8fd4..8e2dcea 100644 --- a/chrome/browser/ui/ash/tablet_mode_client.cc +++ b/chrome/browser/ui/ash/tablet_mode_client.cc
@@ -7,7 +7,6 @@ #include <utility> #include "ash/public/cpp/tablet_mode.h" -#include "ash/public/interfaces/constants.mojom.h" #include "base/bind.h" #include "chrome/browser/chromeos/arc/arc_web_contents_data.h" #include "chrome/browser/ui/ash/tablet_mode_client_observer.h" @@ -21,7 +20,6 @@ #include "content/public/common/service_manager_connection.h" #include "services/service_manager/public/cpp/connector.h" #include "ui/base/material_design/material_design_controller.h" -#include "ui/base/ui_base_features.h" namespace { @@ -29,33 +27,21 @@ } // namespace -TabletModeClient::TabletModeClient() : binding_(this) { +TabletModeClient::TabletModeClient() { DCHECK(!g_tablet_mode_client_instance); g_tablet_mode_client_instance = this; - if (features::IsMultiProcessMash()) { - ash::TabletMode::SetCallback(base::BindRepeating( - &TabletModeClient::tablet_mode_enabled, base::Unretained(this))); - } } TabletModeClient::~TabletModeClient() { DCHECK_EQ(this, g_tablet_mode_client_instance); g_tablet_mode_client_instance = nullptr; - if (features::IsMultiProcessMash()) - ash::TabletMode::SetCallback({}); + // The Ash Shell and TabletMode instance should have been destroyed by now. + DCHECK(!ash::TabletMode::Get()); } void TabletModeClient::Init() { - content::ServiceManagerConnection::GetForProcess() - ->GetConnector() - ->BindInterface(ash::mojom::kServiceName, &tablet_mode_controller_); - BindAndSetClient(); -} - -void TabletModeClient::InitForTesting( - ash::mojom::TabletModeControllerPtr controller) { - tablet_mode_controller_ = std::move(controller); - BindAndSetClient(); + ash::TabletMode::Get()->SetTabletModeToggleObserver(this); + OnTabletModeToggled(ash::TabletMode::Get()->IsEnabled()); } // static @@ -63,14 +49,6 @@ return g_tablet_mode_client_instance; } -void TabletModeClient::SetTabletModeEnabledForTesting( - bool enabled, - ash::mojom::TabletModeController::SetTabletModeEnabledForTestingCallback - callback) { - tablet_mode_controller_->SetTabletModeEnabledForTesting(enabled, - std::move(callback)); -} - void TabletModeClient::AddObserver(TabletModeClientObserver* observer) { observers_.AddObserver(observer); } @@ -112,16 +90,6 @@ contents.contents->NotifyPreferencesChanged(); } -void TabletModeClient::FlushForTesting() { - tablet_mode_controller_.FlushForTesting(); -} - -void TabletModeClient::BindAndSetClient() { - ash::mojom::TabletModeClientPtr client; - binding_.Bind(mojo::MakeRequest(&client)); - tablet_mode_controller_->SetClient(std::move(client)); -} - void TabletModeClient::SetMobileLikeBehaviorEnabled(bool enabled) { // Toggling tablet mode on/off should trigger refreshing the WebKit // preferences, since in tablet mode, we enable certain mobile-like features
diff --git a/chrome/browser/ui/ash/tablet_mode_client.h b/chrome/browser/ui/ash/tablet_mode_client.h index 60ec108..309f364a 100644 --- a/chrome/browser/ui/ash/tablet_mode_client.h +++ b/chrome/browser/ui/ash/tablet_mode_client.h
@@ -7,12 +7,11 @@ #include <memory> -#include "ash/public/interfaces/tablet_mode.mojom.h" +#include "ash/public/cpp/tablet_mode_toggle_observer.h" #include "base/macros.h" #include "base/observer_list.h" #include "chrome/browser/ui/browser_tab_strip_tracker_delegate.h" #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" -#include "mojo/public/cpp/bindings/binding.h" class BrowserTabStripTracker; class TabletModeClientObserver; @@ -20,7 +19,7 @@ // Holds tablet mode state in chrome. Observes ash for changes, then // synchronously fires all its observers. This allows all tablet mode code in // chrome to see a state change at the same time. -class TabletModeClient : public ash::mojom::TabletModeClient, +class TabletModeClient : public ash::TabletModeToggleObserver, public BrowserTabStripTrackerDelegate, public TabStripModelObserver { public: @@ -30,28 +29,16 @@ // Initializes and connects to ash. void Init(); - // Tests can provide a mock mojo interface for the ash controller. - void InitForTesting(ash::mojom::TabletModeControllerPtr controller); - static TabletModeClient* Get(); bool tablet_mode_enabled() const { return tablet_mode_enabled_; } - // Enables or disabled tablet mode. For testing only since it disables the - // Accelerometer and PowerManager observers from the TabletModeController. - // Thus preventing to physically switch to/from tablet mode. |callback| is - // called when the operation has completed. - void SetTabletModeEnabledForTesting( - bool enabled, - ash::mojom::TabletModeController::SetTabletModeEnabledForTestingCallback - callback); - // Adds the observer and immediately triggers it with the initial state. void AddObserver(TabletModeClientObserver* observer); void RemoveObserver(TabletModeClientObserver* observer); - // ash::mojom::TabletModeClient: + // ash::TabletModeToggleObserver: void OnTabletModeToggled(bool enabled) override; // BrowserTabStripTrackerDelegate: @@ -63,13 +50,7 @@ const TabStripModelChange& change, const TabStripSelectionChange& selection) override; - // Flushes the mojo pipe to ash. - void FlushForTesting(); - private: - // Binds this object to its mojo interface and sets it as the ash client. - void BindAndSetClient(); - // Enables/disables mobile-like behavior for webpages in existing browsers, as // well as starts observing new browser pages if |enabled| is true. void SetMobileLikeBehaviorEnabled(bool enabled); @@ -85,12 +66,6 @@ // a refresh of its WebKit prefs. std::unique_ptr<BrowserTabStripTracker> tab_strip_tracker_; - // Binds to the client interface in ash. - mojo::Binding<ash::mojom::TabletModeClient> binding_; - - // Keeps the interface pipe alive to receive mojo return values. - ash::mojom::TabletModeControllerPtr tablet_mode_controller_; - base::ObserverList<TabletModeClientObserver, true /* check_empty */>::Unchecked observers_;
diff --git a/chrome/browser/ui/ash/tablet_mode_client_test_util.cc b/chrome/browser/ui/ash/tablet_mode_client_test_util.cc deleted file mode 100644 index f6dca38..0000000 --- a/chrome/browser/ui/ash/tablet_mode_client_test_util.cc +++ /dev/null
@@ -1,59 +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 "ash/public/cpp/test/shell_test_api.h" -#include "base/run_loop.h" -#include "chrome/browser/ui/ash/tablet_mode_client.h" -#include "chrome/browser/ui/ash/tablet_mode_client_observer.h" -#include "content/public/common/service_manager_connection.h" -#include "services/service_manager/public/cpp/connector.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace test { - -namespace { - -// A helper used to wait for an expected change to the tablet mode state. -class TestTabletModeClientObserver : public TabletModeClientObserver { - public: - explicit TestTabletModeClientObserver(bool target_state) - : target_state_(target_state) { - TabletModeClient::Get()->AddObserver(this); - } - - ~TestTabletModeClientObserver() override { - TabletModeClient::Get()->RemoveObserver(this); - } - - void OnTabletModeToggled(bool enabled) override { - if (enabled == target_state_) - run_loop_.Quit(); - } - - base::RunLoop* run_loop() { return &run_loop_; } - - private: - const bool target_state_; - base::RunLoop run_loop_; - - DISALLOW_COPY_AND_ASSIGN(TestTabletModeClientObserver); -}; - -} // namespace - -// Enables or disables the tablet mode and waits until the change has made its -// way back into Chrome (from Ash). Should only be called to toggle the current -// mode. -void SetAndWaitForTabletMode(bool enabled) { - ASSERT_NE(enabled, TabletModeClient::Get()->tablet_mode_enabled()); - - ash::ShellTestApi().EnableTabletModeWindowManager(enabled); - - TestTabletModeClientObserver observer(enabled); - observer.run_loop()->Run(); - - ASSERT_EQ(enabled, TabletModeClient::Get()->tablet_mode_enabled()); -} - -} // namespace test
diff --git a/chrome/browser/ui/ash/tablet_mode_client_test_util.h b/chrome/browser/ui/ash/tablet_mode_client_test_util.h deleted file mode 100644 index ea25d0c..0000000 --- a/chrome/browser/ui/ash/tablet_mode_client_test_util.h +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_ASH_TABLET_MODE_CLIENT_TEST_UTIL_H_ -#define CHROME_BROWSER_UI_ASH_TABLET_MODE_CLIENT_TEST_UTIL_H_ - -namespace test { - -// Enables or disables the tablet mode and waits to until the change has made -// its way back into Chrome (from Ash). Should only be called to toggle the -// current mode. -void SetAndWaitForTabletMode(bool enabled); - -} // namespace test - -#endif // CHROME_BROWSER_UI_ASH_TABLET_MODE_CLIENT_TEST_UTIL_H_
diff --git a/chrome/browser/ui/ash/tablet_mode_client_unittest.cc b/chrome/browser/ui/ash/tablet_mode_client_unittest.cc index f698f49..ebf0bb6 100644 --- a/chrome/browser/ui/ash/tablet_mode_client_unittest.cc +++ b/chrome/browser/ui/ash/tablet_mode_client_unittest.cc
@@ -4,9 +4,7 @@ #include "chrome/browser/ui/ash/tablet_mode_client.h" -#include "ash/public/interfaces/tablet_mode.mojom.h" #include "base/macros.h" -#include "base/test/scoped_task_environment.h" #include "chrome/browser/ui/ash/fake_tablet_mode_controller.h" #include "chrome/browser/ui/ash/tablet_mode_client_observer.h" #include "testing/gtest/include/gtest/gtest.h" @@ -30,33 +28,29 @@ DISALLOW_COPY_AND_ASSIGN(TestTabletModeClientObserver); }; -class TabletModeClientTest : public testing::Test { - public: - TabletModeClientTest() = default; - ~TabletModeClientTest() override = default; - - private: - base::test::ScopedTaskEnvironment scoped_task_environment_; - - DISALLOW_COPY_AND_ASSIGN(TabletModeClientTest); -}; +using TabletModeClientTest = testing::Test; TEST_F(TabletModeClientTest, Construction) { + // In production, TabletModeController is constructed before TabletModeClient + // and destroyed before it too. Match that here. + auto controller = std::make_unique<FakeTabletModeController>(); TabletModeClient client; - FakeTabletModeController controller; - client.InitForTesting(controller.CreateInterfacePtr()); - client.FlushForTesting(); + client.Init(); // Singleton was initialized. EXPECT_EQ(&client, TabletModeClient::Get()); // Object was set as client. - EXPECT_TRUE(controller.was_client_set()); + EXPECT_TRUE(controller->has_observer()); + + controller = nullptr; } TEST_F(TabletModeClientTest, Observers) { - TabletModeClient client; + auto controller = std::make_unique<FakeTabletModeController>(); TestTabletModeClientObserver observer; + TabletModeClient client; + client.Init(); client.AddObserver(&observer); // Observer is not notified with state when added. @@ -72,6 +66,8 @@ EXPECT_FALSE(observer.last_toggle_); client.RemoveObserver(&observer); + + controller = nullptr; } } // namespace
diff --git a/chrome/browser/ui/ash/tablet_mode_transition_interactive_uitest.cc b/chrome/browser/ui/ash/tablet_mode_transition_interactive_uitest.cc index 72e2e49d..729792f1d 100644 --- a/chrome/browser/ui/ash/tablet_mode_transition_interactive_uitest.cc +++ b/chrome/browser/ui/ash/tablet_mode_transition_interactive_uitest.cc
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "ash/public/cpp/test/shell_test_api.h" #include "base/command_line.h" #include "base/macros.h" #include "base/run_loop.h" #include "base/task/post_task.h" -#include "chrome/browser/ui/ash/tablet_mode_client_test_util.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window.h" @@ -96,7 +96,7 @@ base::RunLoop run_loop; ui::LayerAnimator* animator = browser_window->layer()->GetAnimator(); TestLayerAnimationObserver waiter(animator, run_loop.QuitClosure()); - test::SetAndWaitForTabletMode(true); + ash::ShellTestApi().EnableTabletModeWindowManager(true); run_loop.Run(); } @@ -104,7 +104,7 @@ base::RunLoop run_loop; ui::LayerAnimator* animator = browser_window->layer()->GetAnimator(); TestLayerAnimationObserver waiter(animator, run_loop.QuitClosure()); - test::SetAndWaitForTabletMode(false); + ash::ShellTestApi().EnableTabletModeWindowManager(false); run_loop.Run(); } }
diff --git a/chrome/browser/ui/ash/test_login_screen.cc b/chrome/browser/ui/ash/test_login_screen.cc index 54b49b91..366dab6 100644 --- a/chrome/browser/ui/ash/test_login_screen.cc +++ b/chrome/browser/ui/ash/test_login_screen.cc
@@ -41,13 +41,6 @@ std::move(callback).Run(true); } -void TestLoginScreen::ShowErrorMessage(int32_t login_attempts, - const std::string& error_text, - const std::string& help_link_text, - int32_t help_topic_id) {} - -void TestLoginScreen::ClearErrors() {} - void TestLoginScreen::IsReadyForPassword(IsReadyForPasswordCallback callback) { std::move(callback).Run(true); } @@ -60,22 +53,20 @@ void TestLoginScreen::SetAllowLoginAsGuest(bool allow_guest) {} -void TestLoginScreen::SetShowGuestButtonInOobe(bool show) {} - -void TestLoginScreen::SetShowParentAccessButton(bool show) {} - -void TestLoginScreen::SetShowParentAccessDialog(bool show) {} - void TestLoginScreen::FocusLoginShelf(bool reverse) {} -void TestLoginScreen::ShowParentAccessWidget( - const AccountId& child_account_id, - base::RepeatingCallback<void(bool success)> callback) {} - ash::LoginScreenModel* TestLoginScreen::GetModel() { return &test_screen_model_; } +void TestLoginScreen::ShowGuestButtonInOobe(bool show) {} + +void TestLoginScreen::ShowParentAccessButton(bool show) {} + +void TestLoginScreen::ShowParentAccessWidget( + const AccountId& child_account_id, + base::RepeatingCallback<void(bool success)> callback) {} + void TestLoginScreen::Bind(mojo::ScopedMessagePipeHandle handle) { binding_.Bind(ash::mojom::LoginScreenRequest(std::move(handle))); }
diff --git a/chrome/browser/ui/ash/test_login_screen.h b/chrome/browser/ui/ash/test_login_screen.h index be8a34c..4449ae7 100644 --- a/chrome/browser/ui/ash/test_login_screen.h +++ b/chrome/browser/ui/ash/test_login_screen.h
@@ -31,26 +31,20 @@ void SetClient(ash::mojom::LoginScreenClientPtr client) override; void ShowLockScreen(ShowLockScreenCallback callback) override; void ShowLoginScreen(ShowLoginScreenCallback callback) override; - void ShowErrorMessage(int32_t login_attempts, - const std::string& error_text, - const std::string& help_link_text, - int32_t help_topic_id) override; - void ClearErrors() override; void IsReadyForPassword(IsReadyForPasswordCallback callback) override; void ShowKioskAppError(const std::string& message) override; void SetAddUserButtonEnabled(bool enable) override; void SetShutdownButtonEnabled(bool enable) override; void SetAllowLoginAsGuest(bool allow_guest) override; - void SetShowGuestButtonInOobe(bool show) override; - void SetShowParentAccessButton(bool show) override; - void SetShowParentAccessDialog(bool show) override; void FocusLoginShelf(bool reverse) override; - void ShowParentAccessWidget( - const AccountId& child_account_id, - base::RepeatingCallback<void(bool success)> callback) override; // ash::LoginScreen: ash::LoginScreenModel* GetModel() override; + void ShowGuestButtonInOobe(bool show) override; + void ShowParentAccessButton(bool show) override; + void ShowParentAccessWidget( + const AccountId& child_account_id, + base::RepeatingCallback<void(bool success)> callback) override; private: void Bind(mojo::ScopedMessagePipeHandle handle);
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc index 3a57b04..66dc103 100644 --- a/chrome/browser/ui/browser_command_controller.cc +++ b/chrome/browser/ui/browser_command_controller.cc
@@ -713,7 +713,7 @@ break; #endif case IDC_DISTILL_PAGE: - DistillCurrentPage(browser_); + ToggleDistilledView(browser_); break; case IDC_ROUTE_MEDIA: RouteMedia(browser_);
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc index 85f4b4dc..aa64b3d 100644 --- a/chrome/browser/ui/browser_commands.cc +++ b/chrome/browser/ui/browser_commands.cc
@@ -66,6 +66,7 @@ #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/browser/bookmark_utils.h" #include "components/bookmarks/common/bookmark_pref_names.h" +#include "components/dom_distiller/core/url_utils.h" #include "components/favicon/content/content_favicon_driver.h" #include "components/feature_engagement/buildflags.h" #include "components/google/core/common/google_util.h" @@ -1215,8 +1216,15 @@ } } -void DistillCurrentPage(Browser* browser) { - DistillCurrentPageAndView(browser->tab_strip_model()->GetActiveWebContents()); +void ToggleDistilledView(Browser* browser) { + auto* current_web_contents = + browser->tab_strip_model()->GetActiveWebContents(); + if (dom_distiller::url_utils::IsDistilledPage( + current_web_contents->GetLastCommittedURL())) { + ReturnToOriginalPage(current_web_contents); + } else { + DistillCurrentPageAndView(current_web_contents); + } } bool CanRequestTabletSite(WebContents* current_tab) {
diff --git a/chrome/browser/ui/browser_commands.h b/chrome/browser/ui/browser_commands.h index 6fb386e..c9a80095 100644 --- a/chrome/browser/ui/browser_commands.h +++ b/chrome/browser/ui/browser_commands.h
@@ -155,7 +155,7 @@ void ShowAppMenu(Browser* browser); void ShowAvatarMenu(Browser* browser); void OpenUpdateChromeDialog(Browser* browser); -void DistillCurrentPage(Browser* browser); +void ToggleDistilledView(Browser* browser); bool CanRequestTabletSite(content::WebContents* current_tab); bool IsRequestingTabletSite(Browser* browser); void ToggleRequestTabletSite(Browser* browser);
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash_browsertest.cc b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash_browsertest.cc index c92b6b5..71fd742 100644 --- a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash_browsertest.cc +++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash_browsertest.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.h" #include "ash/public/cpp/immersive/immersive_fullscreen_controller.h" +#include "ash/public/cpp/test/shell_test_api.h" #include "ash/public/cpp/window_properties.h" #include "base/macros.h" #include "base/run_loop.h" @@ -13,7 +14,6 @@ #include "chrome/browser/apps/platform_apps/app_browsertest_util.h" #include "chrome/browser/apps/platform_apps/app_window_interactive_uitest_base.h" #include "chrome/browser/ui/ash/tablet_mode_client.h" -#include "chrome/browser/ui/ash/tablet_mode_client_test_util.h" #include "chrome/test/base/interactive_test_utils.h" #include "chromeos/login/login_state/login_state.h" #include "chromeos/login/login_state/scoped_test_public_session_login_state.h" @@ -101,11 +101,11 @@ // Verify that since the auto hide title bars in tablet mode feature turned // on, immersive mode is enabled once tablet mode is entered, and disabled // once tablet mode is exited. - ASSERT_NO_FATAL_FAILURE(test::SetAndWaitForTabletMode(true)); + ash::ShellTestApi().EnableTabletModeWindowManager(true); EXPECT_TRUE(IsImmersiveActive()); ViewBoundsChangeWaiter::VerifyY(client_view, 0); - ASSERT_NO_FATAL_FAILURE(test::SetAndWaitForTabletMode(false)); + ash::ShellTestApi().EnableTabletModeWindowManager(false); EXPECT_FALSE(IsImmersiveActive()); ViewBoundsChangeWaiter::VerifyY(client_view, kFrameHeight); @@ -113,22 +113,22 @@ // will remain fullscreened after exiting tablet mode. app_window_->OSFullscreen(); EXPECT_TRUE(IsImmersiveActive()); - ASSERT_NO_FATAL_FAILURE(test::SetAndWaitForTabletMode(true)); + ash::ShellTestApi().EnableTabletModeWindowManager(true); EXPECT_TRUE(IsImmersiveActive()); - ASSERT_NO_FATAL_FAILURE(test::SetAndWaitForTabletMode(false)); + ash::ShellTestApi().EnableTabletModeWindowManager(false); EXPECT_TRUE(IsImmersiveActive()); app_window_->Restore(); // Verify that minimized windows do not have immersive mode enabled. app_window_->Minimize(); EXPECT_FALSE(IsImmersiveActive()); - ASSERT_NO_FATAL_FAILURE(test::SetAndWaitForTabletMode(true)); + ash::ShellTestApi().EnableTabletModeWindowManager(true); EXPECT_FALSE(IsImmersiveActive()); window()->Restore(); EXPECT_TRUE(IsImmersiveActive()); app_window_->Minimize(); EXPECT_FALSE(IsImmersiveActive()); - ASSERT_NO_FATAL_FAILURE(test::SetAndWaitForTabletMode(false)); + ash::ShellTestApi().EnableTabletModeWindowManager(false); EXPECT_FALSE(IsImmersiveActive()); // Verify that activation change should not change the immersive @@ -153,10 +153,10 @@ app_window_->OSFullscreen(); EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, window()->GetRestoredState()); - ASSERT_NO_FATAL_FAILURE(test::SetAndWaitForTabletMode(true)); + ash::ShellTestApi().EnableTabletModeWindowManager(true); EXPECT_TRUE(window()->IsFullscreen()); EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, window()->GetRestoredState()); - ASSERT_NO_FATAL_FAILURE(test::SetAndWaitForTabletMode(false)); + ash::ShellTestApi().EnableTabletModeWindowManager(false); EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, window()->GetRestoredState()); CloseAppWindow(app_window_); @@ -171,9 +171,9 @@ app_window_->ForcedFullscreen(); - ASSERT_NO_FATAL_FAILURE(test::SetAndWaitForTabletMode(true)); + ash::ShellTestApi().EnableTabletModeWindowManager(true); EXPECT_FALSE(IsImmersiveActive()); - ASSERT_NO_FATAL_FAILURE(test::SetAndWaitForTabletMode(false)); + ash::ShellTestApi().EnableTabletModeWindowManager(false); EXPECT_FALSE(IsImmersiveActive()); } @@ -207,7 +207,7 @@ EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, window()->GetRestoredState()); EXPECT_TRUE(window()->IsFullscreen()); EXPECT_TRUE(IsImmersiveActive()); - ASSERT_NO_FATAL_FAILURE(test::SetAndWaitForTabletMode(true)); + ash::ShellTestApi().EnableTabletModeWindowManager(true); EXPECT_TRUE(window()->IsFullscreen()); EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, window()->GetRestoredState()); @@ -219,7 +219,7 @@ // Immersive fullscreen should be disabled if window exits fullscreen in // clamshell mode. - ASSERT_NO_FATAL_FAILURE(test::SetAndWaitForTabletMode(false)); + ash::ShellTestApi().EnableTabletModeWindowManager(false); app_window_->OSFullscreen(); EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, window()->GetRestoredState()); EXPECT_TRUE(window()->IsFullscreen());
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc index 9dae288a..3f4bf8c 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc
@@ -11,6 +11,7 @@ #include "ash/public/cpp/frame_header.h" #include "ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.h" #include "ash/public/cpp/shelf_test_api.h" +#include "ash/public/cpp/test/shell_test_api.h" #include "ash/public/cpp/vector_icons/vector_icons.h" #include "ash/public/cpp/window_properties.h" #include "ash/public/interfaces/constants.mojom.h" @@ -36,7 +37,6 @@ #include "chrome/browser/ui/ash/multi_user/multi_user_util.h" #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_helper.h" #include "chrome/browser/ui/ash/multi_user/test_multi_user_window_manager.h" -#include "chrome/browser/ui/ash/tablet_mode_client_test_util.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_command_controller.h" #include "chrome/browser/ui/browser_commands.h" @@ -1400,7 +1400,8 @@ BrowserNonClientFrameViewAsh* frame_view = GetFrameViewAsh(browser_view); EXPECT_TRUE(frame_view->caption_button_container_->GetVisible()); - ASSERT_NO_FATAL_FAILURE(test::SetAndWaitForTabletMode(true)); + ASSERT_NO_FATAL_FAILURE( + ash::ShellTestApi().EnableTabletModeWindowManager(true)); EXPECT_FALSE(frame_view->caption_button_container_->GetVisible()); ToggleOverview(); @@ -1408,7 +1409,8 @@ ToggleOverview(); EXPECT_FALSE(frame_view->caption_button_container_->GetVisible()); - ASSERT_NO_FATAL_FAILURE(test::SetAndWaitForTabletMode(false)); + ASSERT_NO_FATAL_FAILURE( + ash::ShellTestApi().EnableTabletModeWindowManager(false)); EXPECT_TRUE(frame_view->caption_button_container_->GetVisible()); } @@ -1430,7 +1432,8 @@ EXPECT_TRUE(frame_view->caption_button_container_->GetVisible()); // Tablet mode doesn't affect app's caption button's visibility. - ASSERT_NO_FATAL_FAILURE(test::SetAndWaitForTabletMode(true)); + ASSERT_NO_FATAL_FAILURE( + ash::ShellTestApi().EnableTabletModeWindowManager(true)); EXPECT_TRUE(frame_view->caption_button_container_->GetVisible()); // However, overview mode does. @@ -1439,7 +1442,8 @@ ToggleOverview(); EXPECT_TRUE(frame_view->caption_button_container_->GetVisible()); - ASSERT_NO_FATAL_FAILURE(test::SetAndWaitForTabletMode(false)); + ASSERT_NO_FATAL_FAILURE( + ash::ShellTestApi().EnableTabletModeWindowManager(false)); EXPECT_TRUE(frame_view->caption_button_container_->GetVisible()); }
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc index c4c1e9c..42c984e3 100644 --- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc +++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc
@@ -4,13 +4,13 @@ #include "ash/public/cpp/caption_buttons/frame_caption_button_container_view.h" #include "ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.h" +#include "ash/public/cpp/test/shell_test_api.h" #include "base/macros.h" #include "base/test/test_mock_time_task_runner.h" #include "chrome/browser/extensions/extension_browsertest.h" #include "chrome/browser/profiles/profile_io_data.h" #include "chrome/browser/ssl/chrome_mock_cert_verifier.h" #include "chrome/browser/ui/ash/tablet_mode_client.h" -#include "chrome/browser/ui/ash/tablet_mode_client_test_util.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h" #include "chrome/browser/ui/exclusive_access/fullscreen_controller_test.h" @@ -219,7 +219,8 @@ // Verify that after entering tablet mode, immersive mode is enabled, and the // the associated window's top inset is 0 (the top of the window is not // visible). - ASSERT_NO_FATAL_FAILURE(test::SetAndWaitForTabletMode(true)); + ASSERT_NO_FATAL_FAILURE( + ash::ShellTestApi().EnableTabletModeWindowManager(true)); EXPECT_TRUE(controller()->IsEnabled()); EXPECT_EQ(0, aura_window->GetProperty(aura::client::kTopViewInset)); @@ -236,12 +237,14 @@ // mode. ToggleFullscreen(); EXPECT_TRUE(controller()->IsEnabled()); - ASSERT_NO_FATAL_FAILURE(test::SetAndWaitForTabletMode(false)); + ASSERT_NO_FATAL_FAILURE( + ash::ShellTestApi().EnableTabletModeWindowManager(false)); EXPECT_TRUE(controller()->IsEnabled()); // Verify that immersive mode remains if the browser was fullscreened when // entering tablet mode. - ASSERT_NO_FATAL_FAILURE(test::SetAndWaitForTabletMode(true)); + ASSERT_NO_FATAL_FAILURE( + ash::ShellTestApi().EnableTabletModeWindowManager(true)); EXPECT_TRUE(controller()->IsEnabled()); // Verify that if the browser is not fullscreened, upon exiting tablet mode, @@ -249,7 +252,8 @@ // greater than 0 (the top of the window is visible). ToggleFullscreen(); EXPECT_TRUE(controller()->IsEnabled()); - ASSERT_NO_FATAL_FAILURE(test::SetAndWaitForTabletMode(false)); + ASSERT_NO_FATAL_FAILURE( + ash::ShellTestApi().EnableTabletModeWindowManager(false)); EXPECT_FALSE(controller()->IsEnabled()); EXPECT_GT(aura_window->GetProperty(aura::client::kTopViewInset), 0); @@ -273,7 +277,7 @@ EXPECT_TRUE(frame_test_api.size_button()->GetVisible()); // Verify the size button is hidden in tablet mode. - test::SetAndWaitForTabletMode(true); + ash::ShellTestApi().EnableTabletModeWindowManager(true); frame_test_api.EndAnimations(); EXPECT_TRUE(frame_test_api.size_button()->GetVisible()); @@ -282,7 +286,7 @@ // Verify the size button is visible in clamshell mode, and that it does not // cover the other two buttons. - test::SetAndWaitForTabletMode(false); + ash::ShellTestApi().EnableTabletModeWindowManager(false); frame_test_api.EndAnimations(); EXPECT_TRUE(frame_test_api.size_button()->GetVisible()); @@ -299,7 +303,7 @@ IN_PROC_BROWSER_TEST_F(ImmersiveModeControllerAshHostedAppBrowserTest, FrameLayoutStartInTabletMode) { // Start in tablet mode - test::SetAndWaitForTabletMode(true); + ash::ShellTestApi().EnableTabletModeWindowManager(true); BrowserNonClientFrameViewAsh* frame_view = nullptr; { @@ -320,6 +324,6 @@ // Verify the size button is visible in clamshell mode, and that it does not // cover the other two buttons. - test::SetAndWaitForTabletMode(false); + ash::ShellTestApi().EnableTabletModeWindowManager(false); VerifyButtonsInImmersiveMode(frame_view); }
diff --git a/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc b/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc index 21966cd..c73ba58 100644 --- a/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc +++ b/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc
@@ -24,7 +24,6 @@ #include "chrome/browser/extensions/extension_browsertest.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.h" -#include "chrome/browser/ui/ash/tablet_mode_client_test_util.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/browser_navigator_params.h" @@ -372,7 +371,7 @@ ASSERT_NE(nullptr, owning_window); // Setup tablet mode. - test::SetAndWaitForTabletMode(true); + ash::ShellTestApi().EnableTabletModeWindowManager(true); // Open the file dialog on the default path. ASSERT_NO_FATAL_FAILURE(OpenDialog(ui::SelectFileDialog::SELECT_OPEN_FILE, @@ -459,7 +458,7 @@ ASSERT_NE(nullptr, owning_window); // Setup tablet mode. - test::SetAndWaitForTabletMode(true); + ash::ShellTestApi().EnableTabletModeWindowManager(true); // Enable the virtual keyboard. ash::ShellTestApi().EnableVirtualKeyboard();
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc index b6a6904c..3ad4e5f 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -75,7 +75,6 @@ #include "ash/wm/splitview/split_view_controller.h" #include "ash/wm/window_state.h" #include "base/test/simple_test_tick_clock.h" -#include "chrome/browser/ui/ash/tablet_mode_client_test_util.h" #include "chrome/browser/ui/views/frame/immersive_mode_controller.h" #include "chrome/browser/ui/views/frame/immersive_mode_controller_ash.h" #include "content/public/common/service_manager_connection.h" @@ -1747,7 +1746,7 @@ // bounds are different from the maximized bound's origin. browser()->window()->SetBounds(browser()->window()->GetBounds() + gfx::Vector2d(100, 50)); - test::SetAndWaitForTabletMode(true); + ash::ShellTestApi().EnableTabletModeWindowManager(true); DragWindowAndVerifyOffset(this, GetTabStripForBrowser(browser()), 1); ASSERT_FALSE(TabDragController::IsActive()); @@ -1755,7 +1754,7 @@ IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, OffsetForDraggingRightSnappedWindowInTabletMode) { - test::SetAndWaitForTabletMode(true); + ash::ShellTestApi().EnableTabletModeWindowManager(true); // Right snap the browser window. aura::Window* window = browser()->window()->GetNativeWindow(); @@ -2196,7 +2195,7 @@ TabStrip* tab_strip2 = GetTabStripForBrowser(browser2); EXPECT_EQ(2u, browser_list->size()); - test::SetAndWaitForTabletMode(true); + ash::ShellTestApi().EnableTabletModeWindowManager(true); // Move to the first tab of |browser2| and drag it toward to browser(). Note // dragging on |browser2| which only has one tab in tablet mode will open
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc index 59a9d6f..5e523cde 100644 --- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -7,6 +7,7 @@ #include <memory> #include "ash/public/cpp/ash_features.h" +#include "ash/public/cpp/login_screen.h" #include "base/bind.h" #include "base/bind_helpers.h" #include "base/callback.h" @@ -935,7 +936,7 @@ } void GaiaScreenHandler::HandleShowGuestInOobe(bool show) { - LoginScreenClient::Get()->login_screen()->SetShowGuestButtonInOobe(show); + ash::LoginScreen::Get()->ShowGuestButtonInOobe(show); } void GaiaScreenHandler::OnShowAddUser() {
diff --git a/chrome/browser/ui/webui/chromeos/login/supervision_transition_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/supervision_transition_screen_handler.cc index c1e7f2e..7b154e0 100644 --- a/chrome/browser/ui/webui/chromeos/login/supervision_transition_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/supervision_transition_screen_handler.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ui/webui/chromeos/login/supervision_transition_screen_handler.h" +#include "ash/public/cpp/login_screen.h" #include "base/bind.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" @@ -101,7 +102,7 @@ SystemTrayClient::Get()->SetPrimaryTrayEnabled(false); LoginScreenClient::Get()->login_screen()->SetShutdownButtonEnabled(false); LoginScreenClient::Get()->login_screen()->SetAllowLoginAsGuest(false); - LoginScreenClient::Get()->login_screen()->SetShowGuestButtonInOobe(false); + ash::LoginScreen::Get()->ShowGuestButtonInOobe(false); base::DictionaryValue data; data.SetBoolean("isRemovingSupervision",
diff --git a/chrome/browser/ui/webui/favicon_source.cc b/chrome/browser/ui/webui/favicon_source.cc index 1015ae96..c93c9e6 100644 --- a/chrome/browser/ui/webui/favicon_source.cc +++ b/chrome/browser/ui/webui/favicon_source.cc
@@ -171,7 +171,8 @@ &FaviconSource::OnFaviconDataAvailable, base::Unretained(this), IconRequest(callback, url, parsed.size_in_dip, parsed.device_scale_factor, unsafe_request_origin)), - unsafe_request_origin, favicon_service, + unsafe_request_origin, favicon::FaviconRequestPlatform::kDesktop, + favicon_service, LargeIconServiceFactory::GetForBrowserContext(profile_), /*icon_url_for_uma=*/ open_tabs ? open_tabs->GetIconUrlForPageUrl(url) : GURL(),
diff --git a/chrome/renderer/prerender/OWNERS b/chrome/renderer/prerender/OWNERS index e0db6795..b10effc74 100644 --- a/chrome/renderer/prerender/OWNERS +++ b/chrome/renderer/prerender/OWNERS
@@ -1,4 +1,5 @@ mmenke@chromium.org pasko@chromium.org +tbansal@chromium.org # COMPONENT: Internals>Preload
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 3812d68..72f8e0d 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2750,7 +2750,6 @@ "../browser/internal_auth_unittest.cc", "../browser/language/language_model_manager_factory_unittest.cc", "../browser/language/url_language_histogram_factory_unittest.cc", - "../browser/loader/chrome_navigation_data_unittest.cc", "../browser/logging_chrome_unittest.cc", "../browser/mac/exception_processor_unittest.mm", "../browser/mac/keystone_glue_unittest.mm", @@ -2869,6 +2868,7 @@ "../browser/performance_manager/performance_manager_unittest.cc", "../browser/performance_manager/persistence/site_data/exponential_moving_average_unittest.cc", "../browser/performance_manager/persistence/site_data/leveldb_site_data_store_unittest.cc", + "../browser/performance_manager/persistence/site_data/site_data_cache_impl_unittest.cc", "../browser/performance_manager/persistence/site_data/site_data_impl_unittest.cc", "../browser/performance_manager/persistence/site_data/site_data_reader_unittest.cc", "../browser/performance_manager/persistence/site_data/site_data_writer_unittest.cc", @@ -3391,6 +3391,7 @@ "../browser/diagnostics/diagnostics_model_unittest.cc", "../browser/download/download_commands_unittest.cc", "../browser/download/download_shelf_unittest.cc", + "../browser/enterprise_reporting/report_scheduler_unittest.cc", "../browser/enterprise_reporting/report_uploader_unittest.cc", "../browser/enterprise_reporting/request_timer_unittest.cc", "../browser/first_run/first_run_unittest.cc",
diff --git a/chrome/test/chromedriver/chrome/chrome.h b/chrome/test/chromedriver/chrome/chrome.h index d4d82c2..14d2daa 100644 --- a/chrome/test/chromedriver/chrome/chrome.h +++ b/chrome/test/chromedriver/chrome/chrome.h
@@ -16,6 +16,11 @@ class Chrome { public: + enum class WindowType { + kWindow, + kTab, + }; + virtual ~Chrome() {} virtual Status GetAsDesktop(ChromeDesktopImpl** desktop) = 0; @@ -37,6 +42,11 @@ // Return the WebView for the given id. virtual Status GetWebViewById(const std::string& id, WebView** web_view) = 0; + // Makes new window or tab. + virtual Status NewWindow(const std::string& target_id, + WindowType type, + std::string* window_handle) = 0; + // Gets the size of the specified WebView. virtual Status GetWindowSize(const std::string& id, int* width,
diff --git a/chrome/test/chromedriver/chrome/chrome_impl.cc b/chrome/test/chromedriver/chrome/chrome_impl.cc index 9fa588f..71d46c42 100644 --- a/chrome/test/chromedriver/chrome/chrome_impl.cc +++ b/chrome/test/chromedriver/chrome/chrome_impl.cc
@@ -117,6 +117,34 @@ return Status(kUnknownError, "web view not found"); } +Status ChromeImpl::NewWindow(const std::string& target_id, + WindowType type, + std::string* window_handle) { + Status status = devtools_websocket_client_->ConnectIfNecessary(); + if (status.IsError()) + return status; + + Window window; + status = GetWindow(target_id, &window); + if (status.IsError()) + return Status(kNoSuchWindow); + + base::DictionaryValue params; + params.SetString("url", "about:blank"); + params.SetBoolean("newWindow", type == WindowType::kWindow); + params.SetBoolean("background", true); + std::unique_ptr<base::DictionaryValue> result; + status = devtools_websocket_client_->SendCommandAndGetResult( + "Target.createTarget", params, &result); + if (status.IsError()) + return status; + + if (!result->GetString("targetId", window_handle)) + return Status(kUnknownError, "no targetId from createTarget"); + + return Status(kOk); +} + Status ChromeImpl::GetWindow(const std::string& target_id, Window* window) { Status status = devtools_websocket_client_->ConnectIfNecessary(); if (status.IsError())
diff --git a/chrome/test/chromedriver/chrome/chrome_impl.h b/chrome/test/chromedriver/chrome/chrome_impl.h index 0d9871d..3204a85 100644 --- a/chrome/test/chromedriver/chrome/chrome_impl.h +++ b/chrome/test/chromedriver/chrome/chrome_impl.h
@@ -35,6 +35,9 @@ Status GetWebViewIds(std::list<std::string>* web_view_ids, bool w3c_compliant) override; Status GetWebViewById(const std::string& id, WebView** web_view) override; + Status NewWindow(const std::string& target_id, + WindowType type, + std::string* window_handle) override; Status GetWindowSize(const std::string& id, int* width, int* height) override; Status SetWindowSize(const std::string& target_id, int width, int height) override;
diff --git a/chrome/test/chromedriver/chrome/stub_chrome.cc b/chrome/test/chromedriver/chrome/stub_chrome.cc index 0a46d39..471b9dc 100644 --- a/chrome/test/chromedriver/chrome/stub_chrome.cc +++ b/chrome/test/chromedriver/chrome/stub_chrome.cc
@@ -36,6 +36,12 @@ return Status(kOk); } +Status StubChrome::NewWindow(const std::string& target_id, + WindowType type, + std::string* window_handle) { + return Status(kOk); +} + Status StubChrome::GetWindowSize(const std::string& id, int* width, int* height) {
diff --git a/chrome/test/chromedriver/chrome/stub_chrome.h b/chrome/test/chromedriver/chrome/stub_chrome.h index 6e57d4d..067a8c0 100644 --- a/chrome/test/chromedriver/chrome/stub_chrome.h +++ b/chrome/test/chromedriver/chrome/stub_chrome.h
@@ -29,6 +29,9 @@ Status GetWebViewIds(std::list<std::string>* web_view_ids, bool w3c_compliant) override; Status GetWebViewById(const std::string& id, WebView** web_view) override; + Status NewWindow(const std::string& target_id, + WindowType type, + std::string* window_handle) override; Status GetWindowSize(const std::string& id, int* width, int* height) override; Status SetWindowSize(const std::string& id, int width, int height) override; Status SetWindowRect(const std::string& target_id,
diff --git a/chrome/test/chromedriver/chrome/web_view_impl.cc b/chrome/test/chromedriver/chrome/web_view_impl.cc index 740ef9e..5729872 100644 --- a/chrome/test/chromedriver/chrome/web_view_impl.cc +++ b/chrome/test/chromedriver/chrome/web_view_impl.cc
@@ -996,58 +996,14 @@ async_args.AppendString("return (" + function + ").apply(null, arguments);"); async_args.Append(args.CreateDeepCopy()); async_args.AppendBoolean(is_user_supplied); - async_args.AppendInteger(timeout.InMilliseconds()); std::unique_ptr<base::Value> tmp; Status status = CallFunctionWithTimeout(frame, kExecuteAsyncScriptScript, async_args, timeout, &tmp); if (status.IsError()) return status; - const char kDocUnloadError[] = "document unloaded while waiting for result"; - std::string kQueryResult = base::StringPrintf( - "function() {" - " var info = document.$chrome_asyncScriptInfo;" - " if (!info)" - " return {status: %d, value: '%s'};" - " var result = info.result;" - " if (!result)" - " return {status: 0};" - " delete info.result;" - " return result;" - "}", - kJavaScriptError, - kDocUnloadError); - - while (true) { - base::ListValue no_args; - std::unique_ptr<base::Value> query_value; - Status status = CallFunction(frame, kQueryResult, no_args, &query_value); - if (status.IsError()) { - if (status.code() == kNoSuchFrame) - return Status(kJavaScriptError, kDocUnloadError); - return status; - } - - base::DictionaryValue* result_info = NULL; - if (!query_value->GetAsDictionary(&result_info)) - return Status(kUnknownError, "async result info is not a dictionary"); - int status_code; - if (!result_info->GetInteger("status", &status_code)) - return Status(kUnknownError, "async result info has no int 'status'"); - if (status_code != kOk) { - std::string message; - result_info->GetString("value", &message); - return Status(static_cast<StatusCode>(status_code), message); - } - - base::Value* value = NULL; - if (result_info->Get("value", &value)) { - result->reset(value->DeepCopy()); - return Status(kOk); - } - - base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100)); - } + *result = std::move(tmp); + return status; } Status WebViewImpl::IsNotPendingNavigation(const std::string& frame_id,
diff --git a/chrome/test/chromedriver/client/chromedriver.py b/chrome/test/chromedriver/client/chromedriver.py index b3747b0..453f0b0 100644 --- a/chrome/test/chromedriver/client/chromedriver.py +++ b/chrome/test/chromedriver/client/chromedriver.py
@@ -520,6 +520,10 @@ {'windowHandle': 'current'}) return [size['width'], size['height']] + def NewWindow(self, window_type="window"): + return self.ExecuteCommand(Command.NEW_WINDOW, + {'type': window_type}) + def GetWindowRect(self): rect = self.ExecuteCommand(Command.GET_WINDOW_RECT) return [rect['width'], rect['height'], rect['x'], rect['y']]
diff --git a/chrome/test/chromedriver/client/command_executor.py b/chrome/test/chromedriver/client/command_executor.py index 47339d63..8e3075a 100644 --- a/chrome/test/chromedriver/client/command_executor.py +++ b/chrome/test/chromedriver/client/command_executor.py
@@ -83,6 +83,8 @@ GET_WINDOW_RECT = (_Method.GET, '/session/:sessionId/window/rect') GET_WINDOW_SIZE = ( _Method.GET, '/session/:sessionId/window/:windowHandle/size') + NEW_WINDOW = ( + _Method.POST, '/session/:sessionId/window/new') GET_WINDOW_POSITION = ( _Method.GET, '/session/:sessionId/window/:windowHandle/position') SET_WINDOW_SIZE = (
diff --git a/chrome/test/chromedriver/js/execute_async_script.js b/chrome/test/chromedriver/js/execute_async_script.js index b9dc8ab..f30fb4a7 100644 --- a/chrome/test/chromedriver/js/execute_async_script.js +++ b/chrome/test/chromedriver/js/execute_async_script.js
@@ -13,28 +13,9 @@ SCRIPT_TIMEOUT: 28, }; -/** - * Dictionary key for asynchronous script info. - * @const - */ -var ASYNC_INFO_KEY = '$chrome_asyncScriptInfo'; /** -* Return the information of asynchronous script execution. -* -* @return {Object<?>} Information of asynchronous script execution. -*/ -function getAsyncScriptInfo() { - if (!(ASYNC_INFO_KEY in document)) - document[ASYNC_INFO_KEY] = {'id': 0}; - return document[ASYNC_INFO_KEY]; -} - -/** -* Execute the given script and save its asynchronous result. -* -* If script1 finishes after script2 is executed, then script1's result will be -* discarded while script2's will be saved. +* Execute the given script and return a promise containing its result. * * @param {string} script The asynchronous script to be executed. The script * should be a proper function body. It will be wrapped in a function and @@ -45,57 +26,49 @@ * If not, UnknownError will be used instead of JavaScriptError if an * exception occurs during the script, and an additional error callback will * be supplied to the script. -* @param {?number} opt_timeoutMillis The timeout, in milliseconds, to use. -* If the timeout is exceeded and the callback has not been invoked, a error -* result will be saved and future invocation of the callback will be -* ignored. */ -function executeAsyncScript(script, args, isUserSupplied, opt_timeoutMillis) { - var info = getAsyncScriptInfo(); - info.id++; - delete info.result; - var id = info.id; +function executeAsyncScript(script, args, isUserSupplied) { + function isThenable(value) { + return typeof value === 'object' && typeof value.then === 'function'; + } + let resolveHandle; + let rejectHandle; + var promise = new Promise((resolve, reject) => { + resolveHandle = resolve; + rejectHandle = reject; + }); - function report(status, value) { - if (id != info.id) - return; - info.id++; - // Undefined value is skipped when the object is converted to JSON. - // Replace it with null so we don't lose the value. - if (value === undefined) - value = null; - info.result = {status: status, value: value}; - } - function reportValue(value) { - report(StatusCode.OK, value); - } - function reportScriptError(error) { - var code = isUserSupplied ? StatusCode.JAVASCRIPT_ERROR : - (error.code || StatusCode.UNKNOWN_ERROR); - var message = error.message; - if (error.stack) { - message += "\nJavaScript stack:\n" + error.stack; - } - report(code, message); - } - args.push(reportValue); + args.push(resolveHandle); // Append resolve to end of arguments list. if (!isUserSupplied) - args.push(reportScriptError); + args.push(rejectHandle); + // This confusing, round-about way accomplishing this script execution is to + // follow the W3C execute-async-script spec. try { - new Function(script).apply(null, args); - } catch (error) { - reportScriptError(error); - return; + // The assumption is that each script is an asynchronous script. + const scriptResult = new Function(script).apply(null, args); + + // First case is for user-scripts - they are all wrapped in an async + // function in order to allow for "await" commands. As a result, all async + // scripts from users will return a Promise that is thenable by default, + // even if it doesn't return anything. + if (isThenable(scriptResult)) { + const resolvedPromise = Promise.resolve(scriptResult); + resolvedPromise.then((value) => { + // Must be thenable if user-supplied. + if (!isUserSupplied || isThenable(value)) + resolveHandle(value); + }) + .catch(rejectHandle); + } + } catch(error) { + rejectHandle(error); } - if (typeof(opt_timeoutMillis) != 'undefined') { - window.setTimeout(function() { - var code = isUserSupplied ? StatusCode.SCRIPT_TIMEOUT : - StatusCode.UNKNOWN_ERROR; - var errorMsg = 'result was not received in ' + opt_timeoutMillis / 1000 + - ' seconds'; - report(code, errorMsg); - }, opt_timeoutMillis); - } + return promise.catch((error) => { + const code = isUserSupplied ? StatusCode.JAVASCRIPT_ERROR : + (error.code || StatusCode.UNKNOWN_ERROR); + error.code = code; + throw error; + }); }
diff --git a/chrome/test/chromedriver/js/execute_async_script_test.html b/chrome/test/chromedriver/js/execute_async_script_test.html index d1ebe26..2b0262b 100644 --- a/chrome/test/chromedriver/js/execute_async_script_test.html +++ b/chrome/test/chromedriver/js/execute_async_script_test.html
@@ -4,23 +4,28 @@ <script src='execute_async_script.js'></script> <script> -function resetAsyncScriptInfo() { - delete document[ASYNC_INFO_KEY]; +async function testScriptThrows() { + let promise = executeAsyncScript('f(123);', [], true).then((result) => { + assert(false); + }).catch((error) => { + assertEquals(StatusCode.JAVASCRIPT_ERROR, error.code); + return 1; + }); + + let result = await promise; + assertEquals(1, result); + + executeAsyncScript('f(123);', [], false).then((result) => { + assert(false); + }).catch((error) => { + assertEquals(StatusCode.UNKNOWN_ERROR, error.code); + return 1; + }); + result = await promise; + assertEquals(1, result); } -function testScriptThrows() { - resetAsyncScriptInfo(); - var info = getAsyncScriptInfo(); - - executeAsyncScript('f(123);', [], true); - assertEquals(StatusCode.JAVASCRIPT_ERROR, info.result.status); - executeAsyncScript('f(123);', [], false); - assertEquals(StatusCode.UNKNOWN_ERROR, info.result.status); -} - -function testUserScriptWithArgs() { - resetAsyncScriptInfo(); - +async function testUserScriptWithArgs() { var injectedArgs = null; function captureArguments(args) { injectedArgs = args; @@ -30,106 +35,49 @@ var script = 'var args = arguments; args[0](args); args[args.length - 1](args[1]);'; var script_args = [captureArguments, 1]; - executeAsyncScript(script, script_args, true); - + await executeAsyncScript(script, script_args, true).then((result) => { + assertEquals(1, result); + }); assertEquals(3, injectedArgs.length); assertEquals(captureArguments, injectedArgs[0]); assertEquals(1, injectedArgs[1]); - - var info = getAsyncScriptInfo(); - assertEquals(0, info.result.status); - assertEquals(1, info.result.value); - assertEquals(2, info.id); } -function testNonUserScript() { - resetAsyncScriptInfo(); - var info = getAsyncScriptInfo(); +async function testNonUserScript() { + await executeAsyncScript('arguments[1](arguments[0])', [33], + false).then((result) => { + assertEquals(33, result); + }); - executeAsyncScript('arguments[1](arguments[0])', [33], false); - assertEquals(0, info.result.status); - assertEquals(33, info.result.value); + await executeAsyncScript('arguments[2](new Error("ERR"))', [33], + false).then((result) => { + assert(false); + }).catch((error) => { + assertEquals(StatusCode.UNKNOWN_ERROR, error.code); + assertEquals(0, error.message.indexOf('ERR')); + }); - executeAsyncScript('arguments[2](new Error("ERR"))', [33], false); - assertEquals(StatusCode.UNKNOWN_ERROR, info.result.status); - assertEquals(0, info.result.value.indexOf('ERR')); - - executeAsyncScript('var e = new Error("ERR"); e.code = 111; arguments[1](e)', - [], false); - assertEquals(111, info.result.status); - assertEquals(0, info.result.value.indexOf('ERR')); + await executeAsyncScript(` + var e = new Error("ERR"); + e.code = 111; + arguments[1](e)`, + [], false).then((result) => { assert(false); }).catch((error) => { + assertEquals(111, error.code); + assertEquals(0, error.message.indexOf('ERR')); + }); } - -function testNoResultBeforeTimeout() { - resetAsyncScriptInfo(); - var info = getAsyncScriptInfo(); - +async function testFirstScriptFinishAfterSecondScriptExecute() { + let firstCompleted = false; executeAsyncScript( - 'var a = arguments; window.setTimeout(function() {a[0](33)}, 0);', - [], true, 0); - - assert(!info.result); -} - -function testZeroTimeout(runner) { - resetAsyncScriptInfo(); - var info = getAsyncScriptInfo(); - - executeAsyncScript( - 'var a = arguments; window.setTimeout(function() {a[0](33)}, 0);', - [], true, 0); - - window.setTimeout(function() { - assertEquals(0, info.result.status); - assertEquals(33, info.result.value); - runner.continueTesting(); - }, 0); - runner.waitForAsync(); -} - -function testUserScriptTimesOut(runner) { - resetAsyncScriptInfo(); - var info = getAsyncScriptInfo(); - - executeAsyncScript('', [], true, 500); - - window.setTimeout(function() { - assertEquals(StatusCode.SCRIPT_TIMEOUT, info.result.status); - assert(info.result.value.indexOf('0.5') != -1); - runner.continueTesting(); - }, 500); - - runner.waitForAsync(); -} - -function testNonUserScriptTimesOut(runner) { - resetAsyncScriptInfo(); - var info = getAsyncScriptInfo(); - - executeAsyncScript('', [], false, 500); - - window.setTimeout(function() { - assertEquals(StatusCode.UNKNOWN_ERROR, info.result.status); - assert(info.result.value.indexOf('0.5') != -1); - runner.continueTesting(); - }, 500); - - runner.waitForAsync(); -} - -function testFirstScriptFinishAfterSecondScriptExecute() { - resetAsyncScriptInfo(); - - executeAsyncScript( - 'var f = arguments[0]; setTimeout(function(){ f(1); }, 100000);', []); - var info = getAsyncScriptInfo(); - assert(!info.hasOwnProperty('result')); - assertEquals(1, info.id); - - executeAsyncScript('var fn = arguments[0]; fn(2);', []); - assertEquals(0, info.result.status); - assertEquals(2, info.result.value); - assertEquals(3, info.id); + `var f = arguments[0]; + setTimeout(function(){ f(1); }, 100000);`, []).then((result) => { + firstCompleted = true; + }); + await executeAsyncScript('var fn = arguments[0]; fn(2);', + []).then((result) => { + assert(!firstCompleted); + assertEquals(2, result); + }); } </script>
diff --git a/chrome/test/chromedriver/server/http_handler.cc b/chrome/test/chromedriver/server/http_handler.cc index 01b96bc8..b9cb1230 100644 --- a/chrome/test/chromedriver/server/http_handler.cc +++ b/chrome/test/chromedriver/server/http_handler.cc
@@ -185,6 +185,9 @@ kDelete, "session/:sessionId/window", WrapToCommand("CloseWindow", base::BindRepeating(&ExecuteClose))), CommandMapping( + kPost, "session/:sessionId/window/new", + WrapToCommand("NewWindow", base::BindRepeating(&ExecuteNewWindow))), + CommandMapping( kPost, "session/:sessionId/window", WrapToCommand("SwitchToWindow", base::BindRepeating(&ExecuteSwitchToWindow))),
diff --git a/chrome/test/chromedriver/session_commands.cc b/chrome/test/chromedriver/session_commands.cc index fdc007d..edff019 100644 --- a/chrome/test/chromedriver/session_commands.cc +++ b/chrome/test/chromedriver/session_commands.cc
@@ -57,22 +57,6 @@ const int k2GLatency = 300; const int k2GThroughput = 250 * 1024; -const char kWindowHandlePrefix[] = "CDwindow-"; - -std::string WebViewIdToWindowHandle(const std::string& web_view_id) { - return kWindowHandlePrefix + web_view_id; -} - -bool WindowHandleToWebViewId(const std::string& window_handle, - std::string* web_view_id) { - if (!base::StartsWith(window_handle, kWindowHandlePrefix, - base::CompareCase::SENSITIVE)) { - return false; - } - *web_view_id = window_handle.substr(sizeof(kWindowHandlePrefix) - 1); - return true; -} - Status EvaluateScriptAndIgnoreResult(Session* session, std::string expression) { WebView* web_view = nullptr; Status status = session->GetTargetWindow(&web_view);
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index 04b6927..36fa18c 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -159,6 +159,8 @@ 'PerfTest.*', # HeadlessInvalidCertificateTest is sometimes flaky. 'HeadlessInvalidCertificateTest.*', + # Similar issues with HeadlessChromeDriverTest. + 'HeadlessChromeDriverTest.*', # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2277 # RemoteBrowserTest requires extra setup. TODO(johnchen@chromium.org): # Modify the test so it runs correctly as isolated test. @@ -213,6 +215,7 @@ 'ChromeDriverTest.testCloseWindowUsingJavascript', # Android doesn't support headless mode 'HeadlessInvalidCertificateTest.*', + 'HeadlessChromeDriverTest.*', # Tests of the desktop Chrome launch process. 'LaunchDesktopTest.*', # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2737 @@ -413,6 +416,23 @@ def testGetCurrentWindowHandle(self): self._driver.GetCurrentWindowHandle() + def _newWindowDoesNotFocus(self, window_type='window'): + current_handles = self._driver.GetWindowHandles() + self._driver.Load(self.GetHttpUrlForFile( + '/chromedriver/focus_blur_test.html')) + new_window = self._driver.NewWindow(window_type=window_type) + text = self._driver.FindElement('css selector', '#result').GetText() + + self.assertTrue(new_window['handle'] not in current_handles) + self.assertTrue(new_window['handle'] in self._driver.GetWindowHandles()) + self.assertEquals(text, 'PASS') + + def testNewWindowDoesNotFocus(self): + self._newWindowDoesNotFocus(window_type='window') + + def testNewTabDoesNotFocus(self): + self._newWindowDoesNotFocus(window_type='tab') + def testCloseWindow(self): self._driver.Load(self.GetHttpUrlForFile('/chromedriver/page_test.html')) old_handles = self._driver.GetWindowHandles() @@ -3405,6 +3425,29 @@ self._driver.FindElement('css selector', '#link') +class HeadlessChromeDriverTest(ChromeDriverBaseTestWithWebServer): + """End to end tests for ChromeDriver.""" + + def setUp(self): + self._driver = self.CreateDriver(chrome_switches=['--headless']) + + def _newWindowDoesNotFocus(self, window_type='window'): + current_handles = self._driver.GetWindowHandles() + self._driver.Load(self.GetHttpUrlForFile( + '/chromedriver/focus_blur_test.html')) + new_window = self._driver.NewWindow(window_type=window_type) + text = self._driver.FindElement('css selector', '#result').GetText() + + self.assertTrue(new_window['handle'] not in current_handles) + self.assertTrue(new_window['handle'] in self._driver.GetWindowHandles()) + self.assertEquals(text, 'PASS') + + def testNewWindowDoesNotFocus(self): + self._newWindowDoesNotFocus(window_type='window') + + def testNewTabDoesNotFocus(self): + self._newWindowDoesNotFocus(window_type='tab') + class SupportIPv4AndIPv6(ChromeDriverBaseTest): def testSupportIPv4AndIPv6(self): has_ipv4 = False
diff --git a/chrome/test/chromedriver/util.cc b/chrome/test/chromedriver/util.cc index 4ff84c60..8ab5a54 100644 --- a/chrome/test/chromedriver/util.cc +++ b/chrome/test/chromedriver/util.cc
@@ -28,6 +28,8 @@ #include "chrome/test/chromedriver/session.h" #include "third_party/zlib/google/zip.h" +const char kWindowHandlePrefix[] = "CDwindow-"; + std::string GenerateId() { uint64_t msb = base::RandUint64(); uint64_t lsb = base::RandUint64(); @@ -547,3 +549,17 @@ else return dict->SetDouble(path, in_value_64); } + +std::string WebViewIdToWindowHandle(const std::string& web_view_id) { + return kWindowHandlePrefix + web_view_id; +} + +bool WindowHandleToWebViewId(const std::string& window_handle, + std::string* web_view_id) { + if (!base::StartsWith(window_handle, kWindowHandlePrefix, + base::CompareCase::SENSITIVE)) { + return false; + } + *web_view_id = window_handle.substr(sizeof(kWindowHandlePrefix) - 1); + return true; +}
diff --git a/chrome/test/chromedriver/util.h b/chrome/test/chromedriver/util.h index f36731c..277b9cf 100644 --- a/chrome/test/chromedriver/util.h +++ b/chrome/test/chromedriver/util.h
@@ -92,4 +92,11 @@ const base::StringPiece path, int64_t in_value_64); +// Provides WindowHandle to WebView method to maintain consistency across +// ChromeDriver. +std::string WebViewIdToWindowHandle(const std::string& web_view_id); + +bool WindowHandleToWebViewId(const std::string& window_handle, + std::string* web_view_id); + #endif // CHROME_TEST_CHROMEDRIVER_UTIL_H_
diff --git a/chrome/test/chromedriver/window_commands.cc b/chrome/test/chromedriver/window_commands.cc index 626c0d4..acf17a8f 100644 --- a/chrome/test/chromedriver/window_commands.cc +++ b/chrome/test/chromedriver/window_commands.cc
@@ -601,13 +601,45 @@ script = script + "\n"; Status status = web_view->CallUserAsyncFunction( - session->GetCurrentFrameId(), "function(){" + script + "}", *args, + session->GetCurrentFrameId(), "async function(){" + script + "}", *args, session->script_timeout, value); if (status.code() == kTimeout) return Status(kScriptTimeout); return status; } +Status ExecuteNewWindow(Session* session, + WebView* web_view, + const base::DictionaryValue& params, + std::unique_ptr<base::Value>* value, + Timeout* timeout) { + std::string type = ""; + // "type" can either be None or a string. + auto* type_param = params.FindKey("type"); + if (!(!type_param || type_param->is_none() || + params.GetString("type", &type))) + return Status(kInvalidArgument, "missing or invalid 'type'"); + + // By default, creates new tab. + Chrome::WindowType window_type = (type == "window") + ? Chrome::WindowType::kWindow + : Chrome::WindowType::kTab; + + std::string handle = ""; + Status status = + session->chrome->NewWindow(session->window, window_type, &handle); + + if (status.IsError()) + return status; + + auto results = std::make_unique<base::DictionaryValue>(); + results->SetString("handle", WebViewIdToWindowHandle(handle)); + results->SetString( + "type", (window_type == Chrome::WindowType::kWindow) ? "window" : "tab"); + *value = std::move(results); + return Status(kOk); +} + Status ExecuteSwitchToFrame(Session* session, WebView* web_view, const base::DictionaryValue& params,
diff --git a/chrome/test/chromedriver/window_commands.h b/chrome/test/chromedriver/window_commands.h index aa863ba..cc43012 100644 --- a/chrome/test/chromedriver/window_commands.h +++ b/chrome/test/chromedriver/window_commands.h
@@ -56,6 +56,13 @@ std::unique_ptr<base::Value>* value, Timeout* timeout); +// Creates a new window/tab. +Status ExecuteNewWindow(Session* session, + WebView* web_view, + const base::DictionaryValue& params, + std::unique_ptr<base::Value>* value, + Timeout* timeout); + // Changes the targeted frame for the given session. Status ExecuteSwitchToFrame(Session* session, WebView* web_view,
diff --git a/chrome/test/data/chromedriver/focus_blur_test.html b/chrome/test/data/chromedriver/focus_blur_test.html new file mode 100644 index 0000000..9f0c348 --- /dev/null +++ b/chrome/test/data/chromedriver/focus_blur_test.html
@@ -0,0 +1,15 @@ +<html> +<head> +<title>No blur test</title> +<!-- This simple page indicates whether or not this page ever loses focus. --> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +</head> +<body> + <p id="result">PASS</p> +</body> +<script> +window.onblur = function() { + document.getElementById("result").innerHTML = "FAIL"; +}; +</script> +</html>
diff --git a/chrome/test/data/local_ntp/local_ntp_browsertest.html b/chrome/test/data/local_ntp/local_ntp_browsertest.html index 837fcf4..3517f42 100644 --- a/chrome/test/data/local_ntp/local_ntp_browsertest.html +++ b/chrome/test/data/local_ntp/local_ntp_browsertest.html
@@ -7,13 +7,13 @@ <script>window.localNTPUnitTest = true;</script> <link rel="stylesheet" href="chrome-search://local-ntp/animations.css"></link> <link rel="stylesheet" href="chrome-search://local-ntp/local-ntp-common.css"></link> - <link rel="stylesheet" href="chrome-search://local-ntp/custom-backgrounds.css"></link> + <link rel="stylesheet" href="chrome-search://local-ntp/customize.css"></link> <link rel="stylesheet" href="chrome-search://local-ntp/doodles.css"></link> <link rel="stylesheet" href="chrome-search://local-ntp/local-ntp.css"></link> <link rel="stylesheet" href="chrome-search://local-ntp/voice.css"></link> <script src="chrome-search://local-ntp/animations.js" charset="utf-8"></script> <script src="chrome-search://local-ntp/config.js" charset="utf-8"></script> - <script src="chrome-search://local-ntp/custom-backgrounds.js" charset="utf-8"></script> + <script src="chrome-search://local-ntp/customize.js" charset="utf-8"></script> <script src="chrome-search://local-ntp/doodles.js" charset="utf-8"></script> <script src="chrome-search://local-ntp/local-ntp.js" charset="utf-8"></script> <script src="chrome-search://local-ntp/utils.js" charset="utf-8"></script>
diff --git a/chromeos/components/multidevice/debug_webui/proximity_auth_webui_handler.cc b/chromeos/components/multidevice/debug_webui/proximity_auth_webui_handler.cc index 8c42b21..eb1a490 100644 --- a/chromeos/components/multidevice/debug_webui/proximity_auth_webui_handler.cc +++ b/chromeos/components/multidevice/debug_webui/proximity_auth_webui_handler.cc
@@ -328,9 +328,15 @@ std::unique_ptr<base::Value> ProximityAuthWebUIHandler::GetTruncatedLocalDeviceId() { - return std::make_unique<base::Value>( - device_sync_client_->GetLocalDeviceMetadata() - ->GetTruncatedDeviceIdForLogs()); + base::Optional<multidevice::RemoteDeviceRef> local_device_metadata = + device_sync_client_->GetLocalDeviceMetadata(); + + std::string device_id = + local_device_metadata + ? local_device_metadata->GetTruncatedDeviceIdForLogs() + : "Missing Device ID"; + + return std::make_unique<base::Value>(device_id); } std::unique_ptr<base::ListValue>
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc index 2aaff6b9..19238d7 100644 --- a/chromeos/constants/chromeos_features.cc +++ b/chromeos/constants/chromeos_features.cc
@@ -58,7 +58,7 @@ // Enables or disables web push for background notifications in // Android Messages Integration on Chrome OS. const base::Feature kEnableMessagesWebPush{"EnableMessagesWebPush", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; // Enables the use of Mojo by Chrome-process code to communicate with Power // Manager. In order to use mojo, this feature must be turned on and a callsite @@ -117,7 +117,7 @@ // Use the messages.google.com domain as part of the "Messages" feature under // "Connected Devices" settings. const base::Feature kUseMessagesGoogleComDomain{ - "UseMessagesGoogleComDomain", base::FEATURE_DISABLED_BY_DEFAULT}; + "UseMessagesGoogleComDomain", base::FEATURE_ENABLED_BY_DEFAULT}; // Use the staging URL as part of the "Messages" feature under "Connected // Devices" settings.
diff --git a/components/autofill_assistant/browser/BUILD.gn b/components/autofill_assistant/browser/BUILD.gn index c770bf6b..c0b1614 100644 --- a/components/autofill_assistant/browser/BUILD.gn +++ b/components/autofill_assistant/browser/BUILD.gn
@@ -161,6 +161,7 @@ testonly = true sources = [ "actions/autofill_action_unittest.cc", + "actions/configure_bottom_sheet_action_unittest.cc", "actions/mock_action_delegate.cc", "actions/mock_action_delegate.h", "actions/prompt_action_unittest.cc",
diff --git a/components/autofill_assistant/browser/actions/action_delegate.h b/components/autofill_assistant/browser/actions/action_delegate.h index 702b3105..0d985f2 100644 --- a/components/autofill_assistant/browser/actions/action_delegate.h +++ b/components/autofill_assistant/browser/actions/action_delegate.h
@@ -246,9 +246,19 @@ // Set whether the viewport should be resized. virtual void SetResizeViewport(bool resize_viewport) = 0; + // Checks whether the viewport should be resized. + virtual bool GetResizeViewport() = 0; + // Set the peek mode. virtual void SetPeekMode(ConfigureBottomSheetProto::PeekMode peek_mode) = 0; + // Checks the current peek mode. + virtual ConfigureBottomSheetProto::PeekMode GetPeekMode() = 0; + + // Calls the callback once the main document window has been resized. + virtual void WaitForWindowHeightChange( + base::OnceCallback<void(const ClientStatus&)> callback) = 0; + // Returns the current client settings. virtual const ClientSettings& GetSettings() = 0;
diff --git a/components/autofill_assistant/browser/actions/configure_bottom_sheet_action.cc b/components/autofill_assistant/browser/actions/configure_bottom_sheet_action.cc index 447f6c6..d3fd092b 100644 --- a/components/autofill_assistant/browser/actions/configure_bottom_sheet_action.cc +++ b/components/autofill_assistant/browser/actions/configure_bottom_sheet_action.cc
@@ -4,33 +4,89 @@ #include "components/autofill_assistant/browser/actions/configure_bottom_sheet_action.h" +#include "base/bind.h" +#include "base/callback.h" #include "components/autofill_assistant/browser/actions/action_delegate.h" +#include "components/autofill_assistant/browser/client_status.h" namespace autofill_assistant { ConfigureBottomSheetAction::ConfigureBottomSheetAction(const ActionProto& proto) - : Action(proto) {} + : Action(proto), weak_ptr_factory_(this) {} ConfigureBottomSheetAction::~ConfigureBottomSheetAction() {} void ConfigureBottomSheetAction::InternalProcessAction( ActionDelegate* delegate, ProcessActionCallback callback) { - if (proto_.configure_bottom_sheet().viewport_resizing() == - ConfigureBottomSheetProto::RESIZE) { + const ConfigureBottomSheetProto& proto = proto_.configure_bottom_sheet(); + + if (proto.resize_timeout_ms() > 0) { + // When a window resize is expected, we want to wait for the size change to + // be visible to Javascript before moving on to another action. To do that, + // this action registers a callback *before* making any change and waits for + // a 'resize' event in the Javascript side. + bool resize = delegate->GetResizeViewport(); + bool expect_resize = + (!resize && + proto.viewport_resizing() == ConfigureBottomSheetProto::RESIZE) || + (resize && + (proto.viewport_resizing() == ConfigureBottomSheetProto::NO_RESIZE || + (proto.peek_mode() != + ConfigureBottomSheetProto::UNDEFINED_PEEK_MODE && + proto.peek_mode() != delegate->GetPeekMode()))); + if (expect_resize) { + callback_ = std::move(callback); + + timer_.Start(FROM_HERE, + base::TimeDelta::FromMilliseconds(proto.resize_timeout_ms()), + base::BindOnce(&ConfigureBottomSheetAction::OnTimeout, + weak_ptr_factory_.GetWeakPtr())); + + delegate->WaitForWindowHeightChange( + base::BindOnce(&ConfigureBottomSheetAction::OnWindowHeightChange, + weak_ptr_factory_.GetWeakPtr())); + } + } + + if (proto.viewport_resizing() == ConfigureBottomSheetProto::RESIZE) { delegate->SetResizeViewport(true); - } else if (proto_.configure_bottom_sheet().viewport_resizing() == + } else if (proto.viewport_resizing() == ConfigureBottomSheetProto::NO_RESIZE) { delegate->SetResizeViewport(false); } - if (proto_.configure_bottom_sheet().peek_mode() != - ConfigureBottomSheetProto::UNDEFINED_PEEK_MODE) { - delegate->SetPeekMode(proto_.configure_bottom_sheet().peek_mode()); + if (proto.peek_mode() != ConfigureBottomSheetProto::UNDEFINED_PEEK_MODE) { + delegate->SetPeekMode(proto.peek_mode()); } - UpdateProcessedAction(ACTION_APPLIED); - std::move(callback).Run(std::move(processed_action_proto_)); + if (callback) { + UpdateProcessedAction(OkClientStatus()); + std::move(callback).Run(std::move(processed_action_proto_)); + } +} + +void ConfigureBottomSheetAction::OnWindowHeightChange( + const ClientStatus& status) { + if (!callback_) + return; + + timer_.Stop(); + UpdateProcessedAction(status); + std::move(callback_).Run(std::move(processed_action_proto_)); +} + +void ConfigureBottomSheetAction::OnTimeout() { + if (!callback_) + return; + + DVLOG(2) + << __func__ + << " Timed out waiting for window height change. Continuing anyways."; + UpdateProcessedAction(OkClientStatus()); + processed_action_proto_->mutable_status_details()->set_original_status( + ProcessedActionStatusProto::TIMED_OUT); + std::move(callback_).Run(std::move(processed_action_proto_)); } } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/actions/configure_bottom_sheet_action.h b/components/autofill_assistant/browser/actions/configure_bottom_sheet_action.h index ec1247812..8637a3c 100644 --- a/components/autofill_assistant/browser/actions/configure_bottom_sheet_action.h +++ b/components/autofill_assistant/browser/actions/configure_bottom_sheet_action.h
@@ -6,6 +6,8 @@ #define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_CONFIGURE_BOTTOM_SHEET_ACTION_H_ #include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/timer/timer.h" #include "components/autofill_assistant/browser/actions/action.h" namespace autofill_assistant { @@ -21,6 +23,12 @@ void InternalProcessAction(ActionDelegate* delegate, ProcessActionCallback callback) override; + void OnWindowHeightChange(const ClientStatus& status); + void OnTimeout(); + + ProcessActionCallback callback_; + base::OneShotTimer timer_; + base::WeakPtrFactory<ConfigureBottomSheetAction> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(ConfigureBottomSheetAction); };
diff --git a/components/autofill_assistant/browser/actions/configure_bottom_sheet_action_unittest.cc b/components/autofill_assistant/browser/actions/configure_bottom_sheet_action_unittest.cc new file mode 100644 index 0000000..b96af79 --- /dev/null +++ b/components/autofill_assistant/browser/actions/configure_bottom_sheet_action_unittest.cc
@@ -0,0 +1,247 @@ +// 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/autofill_assistant/browser/actions/configure_bottom_sheet_action.h" + +#include <utility> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/test/bind_test_util.h" +#include "base/test/scoped_task_environment.h" +#include "components/autofill_assistant/browser/actions/mock_action_delegate.h" +#include "components/autofill_assistant/browser/mock_run_once_callback.h" +#include "components/autofill_assistant/browser/mock_web_controller.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace autofill_assistant { +namespace { + +using ::testing::_; +using ::testing::Eq; +using ::testing::Invoke; +using ::testing::IsEmpty; +using ::testing::IsNull; +using ::testing::Pointee; +using ::testing::Property; +using ::testing::SizeIs; + +class ConfigureBottomSheetActionTest : public testing::Test { + public: + ConfigureBottomSheetActionTest() + : task_env_( + base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME) {} + + void SetUp() override { + ON_CALL(mock_action_delegate_, GetResizeViewport()) + .WillByDefault(Invoke([this]() { return resize_viewport_; })); + ON_CALL(mock_action_delegate_, SetResizeViewport(_)) + .WillByDefault( + Invoke([this](bool value) { resize_viewport_ = value; })); + ON_CALL(mock_action_delegate_, GetPeekMode()) + .WillByDefault(Invoke([this]() { return peek_mode_; })); + ON_CALL(mock_action_delegate_, SetPeekMode(_)) + .WillByDefault( + Invoke([this](ConfigureBottomSheetProto::PeekMode peek_mode) { + peek_mode_ = peek_mode; + })); + ON_CALL(mock_action_delegate_, OnWaitForWindowHeightChange(_)) + .WillByDefault(Invoke( + [this](base::OnceCallback<void(const ClientStatus&)>& callback) { + on_resize_cb_ = std::move(callback); + })); + } + + protected: + // Runs the action defined in |proto_| and reports the result to |callback_|. + // + // Once it has run, the result of the action is available in + // |processed_action_|. Before the action has run, |processed_action_| status + // is UNKNOWN_ACTION_STATUS. + void Run() { + ActionProto action_proto; + *action_proto.mutable_configure_bottom_sheet() = proto_; + action_ = std::make_unique<ConfigureBottomSheetAction>(action_proto); + action_->ProcessAction( + &mock_action_delegate_, + base::BindOnce(base::BindLambdaForTesting( + [&](std::unique_ptr<ProcessedActionProto> result) { + processed_action_ = *result; + }))); + } + + // Runs an action that waits for a resize. + void RunWithTimeout() { + proto_.set_resize_timeout_ms(100); + Run(); + } + + // Fast forward time enough for an action created by RunWithTimeout() to time + // out. + void ForceTimeout() { + task_env_.FastForwardBy(base::TimeDelta::FromMilliseconds(100)); + task_env_.FastForwardBy(base::TimeDelta::FromMilliseconds(100)); + } + + // task_env_ must be first to guarantee other field + // creation run in that environment. + base::test::ScopedTaskEnvironment task_env_; + + MockActionDelegate mock_action_delegate_; + MockWebController mock_web_controller_; + ConfigureBottomSheetProto proto_; + bool resize_viewport_ = false; + base::OnceCallback<void(const ClientStatus&)> on_resize_cb_; + ConfigureBottomSheetProto::PeekMode peek_mode_ = + ConfigureBottomSheetProto::HANDLE; + std::unique_ptr<ConfigureBottomSheetAction> action_; + ProcessedActionProto processed_action_; +}; + +TEST_F(ConfigureBottomSheetActionTest, NoOp) { + Run(); + + EXPECT_EQ(ACTION_APPLIED, processed_action_.status()); + EXPECT_FALSE(resize_viewport_); + EXPECT_EQ(ConfigureBottomSheetProto::HANDLE, peek_mode_); +} + +TEST_F(ConfigureBottomSheetActionTest, ChangePeekMode) { + proto_.set_peek_mode(ConfigureBottomSheetProto::HANDLE_HEADER); + Run(); + + EXPECT_EQ(ACTION_APPLIED, processed_action_.status()); + EXPECT_FALSE(resize_viewport_); + EXPECT_EQ(ConfigureBottomSheetProto::HANDLE_HEADER, peek_mode_); +} + +TEST_F(ConfigureBottomSheetActionTest, EnableResize) { + proto_.set_viewport_resizing(ConfigureBottomSheetProto::RESIZE); + Run(); + + EXPECT_EQ(ACTION_APPLIED, processed_action_.status()); + EXPECT_TRUE(resize_viewport_); + EXPECT_EQ(ConfigureBottomSheetProto::HANDLE, peek_mode_); +} + +TEST_F(ConfigureBottomSheetActionTest, EnableResizeWithPeekMode) { + proto_.set_viewport_resizing(ConfigureBottomSheetProto::RESIZE); + proto_.set_peek_mode(ConfigureBottomSheetProto::HANDLE_HEADER); + Run(); + + EXPECT_EQ(ACTION_APPLIED, processed_action_.status()); + EXPECT_TRUE(resize_viewport_); + EXPECT_EQ(ConfigureBottomSheetProto::HANDLE_HEADER, peek_mode_); +} + +TEST_F(ConfigureBottomSheetActionTest, WaitAfterSettingResize) { + proto_.set_viewport_resizing(ConfigureBottomSheetProto::RESIZE); + + RunWithTimeout(); + + EXPECT_TRUE(resize_viewport_); + ASSERT_TRUE(on_resize_cb_); + + std::move(on_resize_cb_).Run(OkClientStatus()); + EXPECT_EQ(ACTION_APPLIED, processed_action_.status()); +} + +TEST_F(ConfigureBottomSheetActionTest, WaitFailsAfterSettingResize) { + proto_.set_viewport_resizing(ConfigureBottomSheetProto::RESIZE); + + RunWithTimeout(); + + ASSERT_TRUE(on_resize_cb_); + + std::move(on_resize_cb_).Run(ClientStatus(OTHER_ACTION_STATUS)); + + EXPECT_EQ(OTHER_ACTION_STATUS, processed_action_.status()); +} + +TEST_F(ConfigureBottomSheetActionTest, WaitTimesOut) { + proto_.set_viewport_resizing(ConfigureBottomSheetProto::RESIZE); + + RunWithTimeout(); + + ASSERT_TRUE(on_resize_cb_); + + ForceTimeout(); + + EXPECT_EQ(ACTION_APPLIED, processed_action_.status()); + EXPECT_EQ(TIMED_OUT, processed_action_.status_details().original_status()); +} + +TEST_F(ConfigureBottomSheetActionTest, TimesOutAfterWindowResized) { + proto_.set_viewport_resizing(ConfigureBottomSheetProto::RESIZE); + + RunWithTimeout(); + + ASSERT_TRUE(on_resize_cb_); + + std::move(on_resize_cb_).Run(OkClientStatus()); + ForceTimeout(); + + EXPECT_EQ(ACTION_APPLIED, processed_action_.status()); + EXPECT_TRUE(resize_viewport_); +} + +TEST_F(ConfigureBottomSheetActionTest, WindowResizedAfterTimeout) { + proto_.set_viewport_resizing(ConfigureBottomSheetProto::RESIZE); + + RunWithTimeout(); + + ASSERT_TRUE(on_resize_cb_); + + ForceTimeout(); + std::move(on_resize_cb_).Run(OkClientStatus()); + EXPECT_EQ(ACTION_APPLIED, processed_action_.status()); +} + +TEST_F(ConfigureBottomSheetActionTest, WaitAfterUnsettingResize) { + resize_viewport_ = true; + proto_.set_viewport_resizing(ConfigureBottomSheetProto::NO_RESIZE); + + RunWithTimeout(); + + ASSERT_TRUE(on_resize_cb_); +} + +TEST_F(ConfigureBottomSheetActionTest, WaitAfterChangingPeekModeInResizeMode) { + resize_viewport_ = true; + proto_.set_peek_mode(ConfigureBottomSheetProto::HANDLE_HEADER); + + RunWithTimeout(); + + EXPECT_EQ(ConfigureBottomSheetProto::HANDLE_HEADER, peek_mode_); + ASSERT_TRUE(on_resize_cb_); +} + +TEST_F(ConfigureBottomSheetActionTest, DontWaitAfterChangingPeekIfNoResize) { + proto_.set_peek_mode(ConfigureBottomSheetProto::HANDLE_HEADER); + + RunWithTimeout(); + + ASSERT_FALSE(on_resize_cb_); +} + +TEST_F(ConfigureBottomSheetActionTest, DontWaitIfPeekModeNotChanged) { + resize_viewport_ = true; + proto_.set_peek_mode(ConfigureBottomSheetProto::HANDLE); + + RunWithTimeout(); + + ASSERT_FALSE(on_resize_cb_); +} + +TEST_F(ConfigureBottomSheetActionTest, DontWaitIfResizeModeNotChanged) { + resize_viewport_ = true; + proto_.set_viewport_resizing(ConfigureBottomSheetProto::RESIZE); + + RunWithTimeout(); + + ASSERT_FALSE(on_resize_cb_); +} + +} // namespace +} // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/actions/mock_action_delegate.h b/components/autofill_assistant/browser/actions/mock_action_delegate.h index 79167ab..a446f28b 100644 --- a/components/autofill_assistant/browser/actions/mock_action_delegate.h +++ b/components/autofill_assistant/browser/actions/mock_action_delegate.h
@@ -161,13 +161,23 @@ MOCK_METHOD1(SetProgressVisible, void(bool visible)); MOCK_METHOD1(SetChips, void(std::unique_ptr<std::vector<Chip>> chips)); MOCK_METHOD1(SetResizeViewport, void(bool resize_viewport)); + MOCK_METHOD0(GetResizeViewport, bool()); MOCK_METHOD1(SetPeekMode, void(ConfigureBottomSheetProto::PeekMode peek_mode)); + MOCK_METHOD0(GetPeekMode, ConfigureBottomSheetProto::PeekMode()); MOCK_METHOD2( SetForm, bool(std::unique_ptr<FormProto> form, base::RepeatingCallback<void(const FormProto::Result*)> callback)); + void WaitForWindowHeightChange( + base::OnceCallback<void(const ClientStatus&)> callback) { + OnWaitForWindowHeightChange(callback); + } + + MOCK_METHOD1(OnWaitForWindowHeightChange, + void(base::OnceCallback<void(const ClientStatus&)>& callback)); + const ClientSettings& GetSettings() override { return client_settings_; } ClientSettings client_settings_;
diff --git a/components/autofill_assistant/browser/controller.cc b/components/autofill_assistant/browser/controller.cc index 04146487..45e6217a7 100644 --- a/components/autofill_assistant/browser/controller.cc +++ b/components/autofill_assistant/browser/controller.cc
@@ -785,7 +785,7 @@ } void Controller::UpdateTouchableArea() { - touchable_element_area()->UpdatePositions(); + touchable_element_area()->Update(); } void Controller::OnUserInteractionInsideTouchableArea() { @@ -947,6 +947,11 @@ touchable_element_area_->GetRectangles(area); } +void Controller::GetVisualViewport(RectF* visual_viewport) const { + if (touchable_element_area_) + touchable_element_area_->GetVisualViewport(visual_viewport); +} + void Controller::OnFatalError(const std::string& error_message, Metrics::DropOutReason reason) { LOG(ERROR) << "Autofill Assistant has encountered an error and is shutting " @@ -1120,8 +1125,9 @@ iter->second == "1"; } -void Controller::OnTouchableAreaChanged(const std::vector<RectF>& areas) { - GetUiController()->OnTouchableAreaChanged(areas); +void Controller::OnTouchableAreaChanged(const RectF& visual_viewport, + const std::vector<RectF>& areas) { + GetUiController()->OnTouchableAreaChanged(visual_viewport, areas); } void Controller::SetPaymentRequestOptions(
diff --git a/components/autofill_assistant/browser/controller.h b/components/autofill_assistant/browser/controller.h index 7053fada..2455ae14a 100644 --- a/components/autofill_assistant/browser/controller.h +++ b/components/autofill_assistant/browser/controller.h
@@ -127,6 +127,7 @@ void SetTermsAndConditions( TermsAndConditionsState terms_and_conditions) override; void GetTouchableArea(std::vector<RectF>* area) const override; + void GetVisualViewport(RectF* visual_viewport) const override; void OnFatalError(const std::string& error_message, Metrics::DropOutReason reason) override; bool GetResizeViewport() override; @@ -206,7 +207,8 @@ void OnWebContentsFocused( content::RenderWidgetHost* render_widget_host) override; - void OnTouchableAreaChanged(const std::vector<RectF>& areas); + void OnTouchableAreaChanged(const RectF& visual_viewport, + const std::vector<RectF>& areas); void SelectChip(std::vector<Chip>* chips, int chip_index); void SetOverlayColors(std::unique_ptr<OverlayColors> colors);
diff --git a/components/autofill_assistant/browser/element_area.cc b/components/autofill_assistant/browser/element_area.cc index bb55e3a..8a31f6b 100644 --- a/components/autofill_assistant/browser/element_area.cc +++ b/components/autofill_assistant/browser/element_area.cc
@@ -17,15 +17,14 @@ namespace autofill_assistant { ElementArea::ElementArea(ScriptExecutorDelegate* delegate) - : delegate_(delegate), scheduled_update_(false), weak_ptr_factory_(this) { + : delegate_(delegate), weak_ptr_factory_(this) { DCHECK(delegate_); } ElementArea::~ElementArea() = default; void ElementArea::Clear() { - rectangles_.clear(); - ReportUpdate(); + SetFromProto(ElementAreaProto()); } void ElementArea::SetFromProto(const ElementAreaProto& proto) { @@ -43,32 +42,57 @@ DVLOG(3) << " " << position.selector; } } - ReportUpdate(); - if (rectangles_.empty()) + if (rectangles_.empty()) { + timer_.Stop(); + ReportUpdate(); return; + } - if (!scheduled_update_) { - // Check once and schedule regular updates. - scheduled_update_ = true; - KeepUpdatingElementPositions(); - } else { - // If regular updates are already scheduled, just force a check of position - // right away and keep running the scheduled updates. - UpdatePositions(); + Update(); + if (!timer_.IsRunning()) { + timer_.Start( + FROM_HERE, delegate_->GetSettings().element_position_update_interval, + base::BindRepeating( + &ElementArea::Update, + // This ElementArea instance owns |update_element_positions_| + base::Unretained(this))); } } -void ElementArea::UpdatePositions() { +void ElementArea::Update() { if (rectangles_.empty()) return; + // If anything is still pending, skip the update. + if (visual_viewport_pending_update_) + return; + + for (auto& rectangle : rectangles_) { + if (rectangle.IsPending()) + return; + } + + // Mark everything as pending at the same time, to avoid reporting partial + // results. + visual_viewport_pending_update_ = true; for (auto& rectangle : rectangles_) { for (auto& position : rectangle.positions) { // To avoid reporting partial rectangles, all element positions become // pending at the same time. position.pending_update = true; } + } + + // Viewport and element positions are always queried, and so reported, at the + // same time. This allows supporting both elements whose position is relative + // (and move with a scroll) as elements whose position is absolute (and don't + // move with a scroll.) Being able to tell the difference would be more + // effective and allow refreshing element positions less aggressively. + delegate_->GetWebController()->GetVisualViewport(base::BindOnce( + &ElementArea::OnGetVisualViewport, weak_ptr_factory_.GetWeakPtr())); + + for (auto& rectangle : rectangles_) { for (auto& position : rectangle.positions) { delegate_->GetWebController()->GetElementPosition( position.selector, @@ -81,7 +105,7 @@ void ElementArea::GetRectangles(std::vector<RectF>* area) { for (auto& rectangle : rectangles_) { area->emplace_back(); - rectangle.FillRect(&area->back()); + rectangle.FillRect(&area->back(), visual_viewport_); } } @@ -102,11 +126,13 @@ return false; } -void ElementArea::Rectangle::FillRect(RectF* rect) const { +void ElementArea::Rectangle::FillRect(RectF* rect, + const RectF& visual_viewport) const { bool has_first_rect = false; for (const auto& position : positions) { - if (position.rect.empty()) + if (position.rect.empty()) { continue; + } if (!has_first_rect) { *rect = position.rect; @@ -119,26 +145,12 @@ rect->right = std::max(rect->right, position.rect.right); } if (has_first_rect && full_width) { - rect->left = 0.0; - rect->right = 1.0; + rect->left = visual_viewport.left; + rect->right = visual_viewport.right; } return; } -void ElementArea::KeepUpdatingElementPositions() { - if (rectangles_.empty()) { - scheduled_update_ = false; - return; - } - - UpdatePositions(); - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, - base::BindOnce(&ElementArea::KeepUpdatingElementPositions, - weak_ptr_factory_.GetWeakPtr()), - delegate_->GetSettings().element_position_update_interval); -} - void ElementArea::OnGetElementPosition(const Selector& selector, bool found, const RectF& rect) { @@ -153,6 +165,7 @@ } } } + if (updated) { ReportUpdate(); } @@ -160,10 +173,35 @@ // rectangles_. This is fine. } +void ElementArea::OnGetVisualViewport(bool success, const RectF& rect) { + if (!visual_viewport_pending_update_) + return; + + visual_viewport_pending_update_ = false; + if (!success) + return; + + visual_viewport_ = rect; + ReportUpdate(); +} + void ElementArea::ReportUpdate() { if (!on_update_) return; + if (rectangles_.empty()) { + // Reporting of visual viewport is best effort when reporting empty + // rectangles. It might also be empty. + on_update_.Run(visual_viewport_, {}); + return; + } + + // If there are rectangles, delay reporting until both the visual viewport + // size and the rectangles are available. + if (visual_viewport_pending_update_) { + return; + } + for (const auto& rectangle : rectangles_) { if (rectangle.IsPending()) { // We don't have everything we need yet @@ -173,7 +211,8 @@ std::vector<RectF> area; GetRectangles(&area); - on_update_.Run(area); + + on_update_.Run(visual_viewport_, area); } } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/element_area.h b/components/autofill_assistant/browser/element_area.h index 69c4014..cf13880 100644 --- a/components/autofill_assistant/browser/element_area.h +++ b/components/autofill_assistant/browser/element_area.h
@@ -11,6 +11,7 @@ #include "base/callback.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/timer/timer.h" #include "components/autofill_assistant/browser/client_settings.h" #include "components/autofill_assistant/browser/rectf.h" #include "components/autofill_assistant/browser/selector.h" @@ -36,14 +37,14 @@ // The area is updated asynchronously, so Contains will not work right away. void SetFromProto(const ElementAreaProto& proto); - // Forces an out-of-schedule update of the positions right away. + // Forces an out-of-schedule update of the viewport and positions right away. // // This method is never strictly necessary. It is useful to call it when // there's a reason to think the positions might have changed, to speed up // updates. // // Does nothing if the area is empty. - void UpdatePositions(); + void Update(); // Defines a callback that'll be run every time the set of element coordinates // changes. @@ -51,7 +52,8 @@ // The argument reports the areas that corresponds to currently known // elements, which might be empty. void SetOnUpdate( - base::RepeatingCallback<void(const std::vector<RectF>& rectangles)> cb) { + base::RepeatingCallback<void(const RectF& visual_viewport, + const std::vector<RectF>& rectangles)> cb) { on_update_ = cb; } @@ -64,6 +66,12 @@ // Note that the vector is not cleared before rectangles are added. void GetRectangles(std::vector<RectF>* area); + // Gets the coordinates of the visual viewport, in CSS pixels relative to the + // layout viewport. Empty if the size of the visual viewport is not known. + void GetVisualViewport(RectF* visual_viewport) { + *visual_viewport = visual_viewport_; + } + private: // A rectangle that corresponds to the area of the visual viewport covered by // an element. Coordinates are values between 0 and 1, relative to the size of @@ -97,22 +105,31 @@ bool IsPending() const; // Fills the given rectangle from the current state, if possible. - void FillRect(RectF* rect) const; + void FillRect(RectF* rect, const RectF& visual_viewport) const; }; - void KeepUpdatingElementPositions(); void OnGetElementPosition(const Selector& selector, bool found, const RectF& rect); + void OnGetVisualViewport(bool success, const RectF& rect); void ReportUpdate(); ScriptExecutorDelegate* const delegate_; std::vector<Rectangle> rectangles_; - // If true, regular updates are currently scheduled. - bool scheduled_update_; + // If true, update for the visual viewport position is currently scheduled. + bool visual_viewport_pending_update_ = false; - base::RepeatingCallback<void(const std::vector<RectF>& areas)> on_update_; + // Visual viewport coordinates, in CSS pixels, relative to the layout + // viewport. + RectF visual_viewport_; + + // While running, regularly calls Update(). + base::RepeatingTimer timer_; + + base::RepeatingCallback<void(const RectF& visual_viewport, + const std::vector<RectF>& rectangles)> + on_update_; base::WeakPtrFactory<ElementArea> weak_ptr_factory_;
diff --git a/components/autofill_assistant/browser/element_area_unittest.cc b/components/autofill_assistant/browser/element_area_unittest.cc index 441ea54..e928994 100644 --- a/components/autofill_assistant/browser/element_area_unittest.cc +++ b/components/autofill_assistant/browser/element_area_unittest.cc
@@ -71,8 +71,14 @@ base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME), element_area_(&delegate_) { delegate_.SetWebController(&mock_web_controller_); + delegate_.GetMutableSettings()->element_position_update_interval = + base::TimeDelta::FromMilliseconds(100); + ON_CALL(mock_web_controller_, OnGetElementPosition(_, _)) .WillByDefault(RunOnceCallback<1>(false, RectF())); + ON_CALL(mock_web_controller_, OnGetVisualViewport(_)) + .WillByDefault(RunOnceCallback<0>(true, RectF(0, 0, 200, 400))); + element_area_.SetOnUpdate(base::BindRepeating(&ElementAreaTest::OnUpdate, base::Unretained(this))); } @@ -83,7 +89,11 @@ element_area_.SetFromProto(area); } - void OnUpdate(const std::vector<RectF>& area) { reported_area_ = area; } + void OnUpdate(const RectF& visual_viewport, const std::vector<RectF>& area) { + on_update_call_count_++; + reported_visual_viewport_ = visual_viewport; + reported_area_ = area; + } // scoped_task_environment_ must be first to guarantee other field // creation run in that environment. @@ -92,6 +102,8 @@ MockWebController mock_web_controller_; FakeScriptExecutorDelegate delegate_; ElementArea element_area_; + int on_update_call_count_ = 0; + RectF reported_visual_viewport_; std::vector<RectF> reported_area_; }; @@ -101,6 +113,10 @@ std::vector<RectF> rectangles; element_area_.GetRectangles(&rectangles); EXPECT_THAT(rectangles, IsEmpty()); + + RectF viewport; + element_area_.GetVisualViewport(&viewport); + EXPECT_THAT(viewport, EmptyRectF()); } TEST_F(ElementAreaTest, ElementNotFound) { @@ -112,37 +128,72 @@ EXPECT_THAT(rectangles, ElementsAre(EmptyRectF())); } +TEST_F(ElementAreaTest, GetVisualViewport) { + SetElement("#some_element"); + RectF viewport; + element_area_.GetVisualViewport(&viewport); + EXPECT_THAT(viewport, MatchingRectF(0, 0, 200, 400)); +} + TEST_F(ElementAreaTest, OneRectangle) { EXPECT_CALL(mock_web_controller_, OnGetElementPosition(Eq(Selector({"#found"}).MustBeVisible()), _)) - .WillOnce(RunOnceCallback<1>(true, RectF(0.25f, 0.25f, 0.75f, 0.75f))); + .WillOnce(RunOnceCallback<1>(true, RectF(25, 25, 75, 75))); SetElement("#found"); std::vector<RectF> rectangles; element_area_.GetRectangles(&rectangles); - EXPECT_THAT(rectangles, - ElementsAre(MatchingRectF(0.25f, 0.25f, 0.75f, 0.75f))); + EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(25, 25, 75, 75))); } TEST_F(ElementAreaTest, CallOnUpdate) { EXPECT_CALL(mock_web_controller_, OnGetElementPosition(Eq(Selector({"#found"}).MustBeVisible()), _)) - .WillOnce(RunOnceCallback<1>(true, RectF(0.25f, 0.25f, 0.75f, 0.75f))); + .WillOnce(RunOnceCallback<1>(true, RectF(25, 25, 75, 75))); SetElement("#found"); - EXPECT_THAT(reported_area_, - ElementsAre(MatchingRectF(0.25f, 0.25f, 0.75f, 0.75f))); + EXPECT_EQ(on_update_call_count_, 1); + EXPECT_THAT(reported_visual_viewport_, MatchingRectF(0, 0, 200, 400)); + EXPECT_THAT(reported_area_, ElementsAre(MatchingRectF(25, 25, 75, 75))); +} + +TEST_F(ElementAreaTest, DontCallOnUpdateWhenViewportMissing) { + // Swallowing calls to OnGetVisualViewport guarantees that the viewport + // position will never be known. + EXPECT_CALL(mock_web_controller_, OnGetVisualViewport(_)) + .WillOnce(DoNothing()); + EXPECT_CALL(mock_web_controller_, + OnGetElementPosition(Eq(Selector({"#found"}).MustBeVisible()), _)) + .WillOnce(RunOnceCallback<1>(true, RectF(25, 25, 75, 75))); + + SetElement("#found"); + EXPECT_EQ(on_update_call_count_, 0); +} + +TEST_F(ElementAreaTest, CallOnUpdateWhenViewportMissingAndEmptyRect) { + EXPECT_CALL(mock_web_controller_, OnGetVisualViewport(_)) + .WillRepeatedly(RunOnceCallback<0>(false, RectF())); + + SetElement("#found"); + + // A newly empty element area should be reported. + on_update_call_count_ = 0; + element_area_.Clear(); + + EXPECT_EQ(on_update_call_count_, 1); + EXPECT_THAT(reported_visual_viewport_, EmptyRectF()); + EXPECT_THAT(reported_area_, IsEmpty()); } TEST_F(ElementAreaTest, TwoRectangles) { EXPECT_CALL( mock_web_controller_, OnGetElementPosition(Eq(Selector({"#top_left"}).MustBeVisible()), _)) - .WillOnce(RunOnceCallback<1>(true, RectF(0.0f, 0.0f, 0.25f, 0.25f))); + .WillOnce(RunOnceCallback<1>(true, RectF(0, 0, 25, 25))); EXPECT_CALL( mock_web_controller_, OnGetElementPosition(Eq(Selector({"#bottom_right"}).MustBeVisible()), _)) - .WillOnce(RunOnceCallback<1>(true, RectF(0.25f, 0.25f, 1.0f, 1.0f))); + .WillOnce(RunOnceCallback<1>(true, RectF(25, 25, 100, 100))); ElementAreaProto area_proto; area_proto.add_rectangles()->add_elements()->add_selectors("#top_left"); @@ -151,19 +202,19 @@ std::vector<RectF> rectangles; element_area_.GetRectangles(&rectangles); - EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.0f, 0.0f, 0.25f, 0.25f), - MatchingRectF(0.25f, 0.25f, 1.0f, 1.0f))); + EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0, 0, 25, 25), + MatchingRectF(25, 25, 100, 100))); } TEST_F(ElementAreaTest, OneRectangleTwoElements) { EXPECT_CALL( mock_web_controller_, OnGetElementPosition(Eq(Selector({"#element1"}).MustBeVisible()), _)) - .WillOnce(RunOnceCallback<1>(true, RectF(0.1f, 0.3f, 0.2f, 0.4f))); + .WillOnce(RunOnceCallback<1>(true, RectF(1, 3, 2, 4))); EXPECT_CALL( mock_web_controller_, OnGetElementPosition(Eq(Selector({"#element2"}).MustBeVisible()), _)) - .WillOnce(RunOnceCallback<1>(true, RectF(0.5f, 0.2f, 0.6f, 0.5f))); + .WillOnce(RunOnceCallback<1>(true, RectF(5, 2, 6, 5))); ElementAreaProto area_proto; auto* rectangle_proto = area_proto.add_rectangles(); @@ -173,14 +224,14 @@ std::vector<RectF> rectangles; element_area_.GetRectangles(&rectangles); - EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.1f, 0.2f, 0.6f, 0.5f))); + EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(1, 2, 6, 5))); } TEST_F(ElementAreaTest, DoNotReportIncompleteRectangles) { EXPECT_CALL( mock_web_controller_, OnGetElementPosition(Eq(Selector({"#element1"}).MustBeVisible()), _)) - .WillOnce(RunOnceCallback<1>(true, RectF(0.1f, 0.3f, 0.2f, 0.4f))); + .WillOnce(RunOnceCallback<1>(true, RectF(1, 3, 2, 4))); // Getting the position of #element2 neither succeeds nor fails, simulating an // intermediate state which shouldn't be reported to the callback. @@ -195,30 +246,30 @@ rectangle_proto->add_elements()->add_selectors("#element2"); element_area_.SetFromProto(area_proto); - EXPECT_THAT(reported_area_, ElementsAre(EmptyRectF())); + EXPECT_THAT(reported_area_, IsEmpty()); std::vector<RectF> rectangles; element_area_.GetRectangles(&rectangles); - EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.1f, 0.3f, 0.2f, 0.4f))); + EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(1, 3, 2, 4))); } TEST_F(ElementAreaTest, OneRectangleFourElements) { EXPECT_CALL( mock_web_controller_, OnGetElementPosition(Eq(Selector({"#element1"}).MustBeVisible()), _)) - .WillOnce(RunOnceCallback<1>(true, RectF(0.0f, 0.0f, 0.1f, 0.1f))); + .WillOnce(RunOnceCallback<1>(true, RectF(0, 0, 1, 1))); EXPECT_CALL( mock_web_controller_, OnGetElementPosition(Eq(Selector({"#element2"}).MustBeVisible()), _)) - .WillOnce(RunOnceCallback<1>(true, RectF(0.9f, 0.9f, 1.0f, 1.0f))); + .WillOnce(RunOnceCallback<1>(true, RectF(9, 9, 100, 100))); EXPECT_CALL( mock_web_controller_, OnGetElementPosition(Eq(Selector({"#element3"}).MustBeVisible()), _)) - .WillOnce(RunOnceCallback<1>(true, RectF(0.0f, 0.9f, 0.1f, 1.0f))); + .WillOnce(RunOnceCallback<1>(true, RectF(0, 9, 1, 100))); EXPECT_CALL( mock_web_controller_, OnGetElementPosition(Eq(Selector({"#element4"}).MustBeVisible()), _)) - .WillOnce(RunOnceCallback<1>(true, RectF(0.9f, 0.0f, 1.0f, 0.1f))); + .WillOnce(RunOnceCallback<1>(true, RectF(9, 0, 100, 1))); ElementAreaProto area_proto; auto* rectangle_proto = area_proto.add_rectangles(); @@ -230,14 +281,14 @@ std::vector<RectF> rectangles; element_area_.GetRectangles(&rectangles); - EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.0f, 0.0f, 1.0f, 1.0f))); + EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0, 0, 100, 100))); } TEST_F(ElementAreaTest, OneRectangleMissingElementsReported) { EXPECT_CALL( mock_web_controller_, OnGetElementPosition(Eq(Selector({"#element1"}).MustBeVisible()), _)) - .WillOnce(RunOnceCallback<1>(true, RectF(0.1f, 0.1f, 0.2f, 0.2f))); + .WillOnce(RunOnceCallback<1>(true, RectF(1, 1, 2, 2))); EXPECT_CALL( mock_web_controller_, OnGetElementPosition(Eq(Selector({"#element2"}).MustBeVisible()), _)) @@ -251,21 +302,22 @@ std::vector<RectF> rectangles; element_area_.GetRectangles(&rectangles); - EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.1f, 0.1f, 0.2f, 0.2f))); + EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(1, 1, 2, 2))); - EXPECT_THAT(reported_area_, - ElementsAre(MatchingRectF(0.1f, 0.1f, 0.2f, 0.2f))); + EXPECT_THAT(reported_area_, ElementsAre(MatchingRectF(1, 1, 2, 2))); } TEST_F(ElementAreaTest, FullWidthRectangle) { EXPECT_CALL( mock_web_controller_, OnGetElementPosition(Eq(Selector({"#element1"}).MustBeVisible()), _)) - .WillOnce(RunOnceCallback<1>(true, RectF(0.1f, 0.3f, 0.2f, 0.4f))); + .WillOnce(RunOnceCallback<1>(true, RectF(1, 3, 2, 4))); EXPECT_CALL( mock_web_controller_, OnGetElementPosition(Eq(Selector({"#element2"}).MustBeVisible()), _)) - .WillOnce(RunOnceCallback<1>(true, RectF(0.5f, 0.7f, 0.6f, 0.8f))); + .WillOnce(RunOnceCallback<1>(true, RectF(5, 7, 6, 8))); + EXPECT_CALL(mock_web_controller_, OnGetVisualViewport(_)) + .WillRepeatedly(RunOnceCallback<0>(true, RectF(100, 0, 200, 400))); ElementAreaProto area_proto; auto* rectangle_proto = area_proto.add_rectangles(); @@ -276,7 +328,10 @@ std::vector<RectF> rectangles; element_area_.GetRectangles(&rectangles); - EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.0f, 0.3f, 1.0f, 0.8f))); + + // left and right of the box come from the visual viewport, top from the 1st + // element, bottom from the 2nd. + EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(100, 3, 200, 8))); } TEST_F(ElementAreaTest, ElementMovesAfterUpdate) { @@ -284,24 +339,25 @@ EXPECT_CALL( mock_web_controller_, OnGetElementPosition(Eq(Selector({"#element"}).MustBeVisible()), _)) - .WillOnce(RunOnceCallback<1>(true, RectF(0.0f, 0.25f, 1.0f, 0.5f))) - .WillOnce(RunOnceCallback<1>(true, RectF(0.0f, 0.5f, 1.0f, 0.75f))); + .WillOnce(RunOnceCallback<1>(true, RectF(0, 25, 100, 50))) + .WillOnce(RunOnceCallback<1>(true, RectF(0, 50, 100, 75))); SetElement("#element"); - EXPECT_THAT(reported_area_, - ElementsAre(MatchingRectF(0.0f, 0.25f, 1.0f, 0.5f))); + std::vector<RectF> original; + element_area_.GetRectangles(&original); + EXPECT_THAT(original, ElementsAre(MatchingRectF(0, 25, 100, 50))); + EXPECT_THAT(reported_area_, ElementsAre(MatchingRectF(0, 25, 100, 50))); - element_area_.UpdatePositions(); + element_area_.Update(); // Updated area is available - std::vector<RectF> rectangles; - element_area_.GetRectangles(&rectangles); - EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.0f, 0.5f, 1.0f, 0.75f))); + std::vector<RectF> updated; + element_area_.GetRectangles(&updated); + EXPECT_THAT(updated, ElementsAre(MatchingRectF(0, 50, 100, 75))); // Updated area is reported - EXPECT_THAT(reported_area_, - ElementsAre(MatchingRectF(0.0f, 0.5f, 1.0f, 0.75f))); + EXPECT_THAT(reported_area_, ElementsAre(MatchingRectF(0, 50, 100, 75))); } TEST_F(ElementAreaTest, ElementMovesWithTime) { @@ -309,13 +365,12 @@ EXPECT_CALL( mock_web_controller_, OnGetElementPosition(Eq(Selector({"#element"}).MustBeVisible()), _)) - .WillOnce(RunOnceCallback<1>(true, RectF(0.0f, 0.25f, 1.0f, 0.5f))) - .WillOnce(RunOnceCallback<1>(true, RectF(0.0f, 0.5f, 1.0f, 0.75f))); + .WillOnce(RunOnceCallback<1>(true, RectF(0, 25, 100, 50))) + .WillRepeatedly(RunOnceCallback<1>(true, RectF(0, 50, 100, 75))); SetElement("#element"); - EXPECT_THAT(reported_area_, - ElementsAre(MatchingRectF(0.0f, 0.25f, 1.0f, 0.5f))); + EXPECT_THAT(reported_area_, ElementsAre(MatchingRectF(0, 25, 100, 50))); scoped_task_environment_.FastForwardBy( base::TimeDelta::FromMilliseconds(100)); @@ -323,11 +378,10 @@ // Updated area is available std::vector<RectF> rectangles; element_area_.GetRectangles(&rectangles); - EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.0f, 0.5f, 1.0f, 0.75f))); + EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0, 50, 100, 75))); // Updated area is reported - EXPECT_THAT(reported_area_, - ElementsAre(MatchingRectF(0.0f, 0.5f, 1.0f, 0.75f))); + EXPECT_THAT(reported_area_, ElementsAre(MatchingRectF(0, 50, 100, 75))); } } // namespace } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/fake_script_executor_delegate.cc b/components/autofill_assistant/browser/fake_script_executor_delegate.cc index 1559ec5..ee6b0e7 100644 --- a/components/autofill_assistant/browser/fake_script_executor_delegate.cc +++ b/components/autofill_assistant/browser/fake_script_executor_delegate.cc
@@ -93,10 +93,22 @@ payment_request_options_ = std::move(options); } -void FakeScriptExecutorDelegate::SetResizeViewport(bool resize_viewport) {} +void FakeScriptExecutorDelegate::SetResizeViewport(bool resize_viewport) { + resize_viewport_ = resize_viewport; +} + +bool FakeScriptExecutorDelegate::GetResizeViewport() { + return resize_viewport_; +} void FakeScriptExecutorDelegate::SetPeekMode( - ConfigureBottomSheetProto::PeekMode peek_mode) {} + ConfigureBottomSheetProto::PeekMode peek_mode) { + peek_mode_ = peek_mode; +} + +ConfigureBottomSheetProto::PeekMode FakeScriptExecutorDelegate::GetPeekMode() { + return peek_mode_; +} bool FakeScriptExecutorDelegate::HasNavigationError() { return navigation_error_;
diff --git a/components/autofill_assistant/browser/fake_script_executor_delegate.h b/components/autofill_assistant/browser/fake_script_executor_delegate.h index 671d27d..d9d766f 100644 --- a/components/autofill_assistant/browser/fake_script_executor_delegate.h +++ b/components/autofill_assistant/browser/fake_script_executor_delegate.h
@@ -48,7 +48,9 @@ void SetPaymentRequestOptions( std::unique_ptr<PaymentRequestOptions> options) override; void SetResizeViewport(bool resize_viewport) override; + bool GetResizeViewport() override; void SetPeekMode(ConfigureBottomSheetProto::PeekMode peek_mode) override; + ConfigureBottomSheetProto::PeekMode GetPeekMode() override; bool SetForm(std::unique_ptr<FormProto> form, base::RepeatingCallback<void(const FormProto::Result*)> callback) override; @@ -113,6 +115,9 @@ bool navigating_to_new_document_ = false; bool navigation_error_ = false; std::set<ScriptExecutorDelegate::Listener*> listeners_; + bool resize_viewport_ = false; + ConfigureBottomSheetProto::PeekMode peek_mode_ = + ConfigureBottomSheetProto::HANDLE; DISALLOW_COPY_AND_ASSIGN(FakeScriptExecutorDelegate); };
diff --git a/components/autofill_assistant/browser/mock_ui_controller.h b/components/autofill_assistant/browser/mock_ui_controller.h index a40ea6f..71f9762 100644 --- a/components/autofill_assistant/browser/mock_ui_controller.h +++ b/components/autofill_assistant/browser/mock_ui_controller.h
@@ -34,7 +34,8 @@ MOCK_METHOD1(OnInfoBoxChanged, void(const InfoBox* info_box)); MOCK_METHOD1(OnProgressChanged, void(int progress)); MOCK_METHOD1(OnProgressVisibilityChanged, void(bool visible)); - MOCK_METHOD1(OnTouchableAreaChanged, void(const std::vector<RectF>& areas)); + MOCK_METHOD2(OnTouchableAreaChanged, + void(const RectF&, const std::vector<RectF>& areas)); MOCK_CONST_METHOD0(Terminate, bool()); MOCK_CONST_METHOD0(GetDropOutReason, Metrics::DropOutReason()); MOCK_METHOD1(OnResizeViewportChanged, void(bool resize_viewport));
diff --git a/components/autofill_assistant/browser/mock_web_controller.h b/components/autofill_assistant/browser/mock_web_controller.h index 115dcd3..a725fd8d 100644 --- a/components/autofill_assistant/browser/mock_web_controller.h +++ b/components/autofill_assistant/browser/mock_web_controller.h
@@ -63,6 +63,13 @@ void(const Selector& selector, base::OnceCallback<void(bool, const std::string&)>& callback)); + void GetVisualViewport( + base::OnceCallback<void(bool, const RectF&)> callback) override { + OnGetVisualViewport(callback); + } + MOCK_METHOD1(OnGetVisualViewport, + void(base::OnceCallback<void(bool, const RectF&)>& callback)); + void GetElementPosition( const Selector& selector, base::OnceCallback<void(bool, const RectF&)> callback) override { @@ -82,6 +89,14 @@ } MOCK_METHOD0(ClearCookie, void()); + + void WaitForWindowHeightChange( + base::OnceCallback<void(const ClientStatus&)> callback) { + OnWaitForWindowHeightChange(callback); + } + + MOCK_METHOD1(OnWaitForWindowHeightChange, + void(base::OnceCallback<void(const ClientStatus&)>& callback)); }; } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/script_executor.cc b/components/autofill_assistant/browser/script_executor.cc index 06cee7c..678f3dd 100644 --- a/components/autofill_assistant/browser/script_executor.cc +++ b/components/autofill_assistant/browser/script_executor.cc
@@ -456,11 +456,24 @@ delegate_->SetResizeViewport(resize_viewport); } +bool ScriptExecutor::GetResizeViewport() { + return delegate_->GetResizeViewport(); +} + void ScriptExecutor::SetPeekMode( ConfigureBottomSheetProto::PeekMode peek_mode) { delegate_->SetPeekMode(peek_mode); } +ConfigureBottomSheetProto::PeekMode ScriptExecutor::GetPeekMode() { + return delegate_->GetPeekMode(); +} + +void ScriptExecutor::WaitForWindowHeightChange( + base::OnceCallback<void(const ClientStatus&)> callback) { + delegate_->GetWebController()->WaitForWindowHeightChange(std::move(callback)); +} + const ClientSettings& ScriptExecutor::GetSettings() { return delegate_->GetSettings(); }
diff --git a/components/autofill_assistant/browser/script_executor.h b/components/autofill_assistant/browser/script_executor.h index 0325853..f3bcedb2 100644 --- a/components/autofill_assistant/browser/script_executor.h +++ b/components/autofill_assistant/browser/script_executor.h
@@ -179,7 +179,11 @@ void SetProgress(int progress) override; void SetProgressVisible(bool visible) override; void SetResizeViewport(bool resize_viewport) override; + bool GetResizeViewport() override; void SetPeekMode(ConfigureBottomSheetProto::PeekMode peek_mode) override; + ConfigureBottomSheetProto::PeekMode GetPeekMode() override; + void WaitForWindowHeightChange( + base::OnceCallback<void(const ClientStatus&)> callback) override; const ClientSettings& GetSettings() override; bool SetForm(std::unique_ptr<FormProto> form, base::RepeatingCallback<void(const FormProto::Result*)> callback)
diff --git a/components/autofill_assistant/browser/script_executor_delegate.h b/components/autofill_assistant/browser/script_executor_delegate.h index 7da41dd..70c8c6b 100644 --- a/components/autofill_assistant/browser/script_executor_delegate.h +++ b/components/autofill_assistant/browser/script_executor_delegate.h
@@ -68,8 +68,10 @@ virtual void SetProgress(int progress) = 0; virtual void SetProgressVisible(bool visible) = 0; virtual void SetChips(std::unique_ptr<std::vector<Chip>> chips) = 0; + virtual bool GetResizeViewport() = 0; virtual void SetResizeViewport(bool resize_viewport) = 0; virtual void SetPeekMode(ConfigureBottomSheetProto::PeekMode peek_mode) = 0; + virtual ConfigureBottomSheetProto::PeekMode GetPeekMode() = 0; virtual bool SetForm( std::unique_ptr<FormProto> form, base::RepeatingCallback<void(const FormProto::Result*)> callback) = 0;
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto index 0d703458..e2cf26c1 100644 --- a/components/autofill_assistant/browser/service.proto +++ b/components/autofill_assistant/browser/service.proto
@@ -1231,6 +1231,10 @@ // resize_viewport is true or was set to true by a previous actions, the // viewport will be resized to match the new peek height. optional PeekMode peek_mode = 2; + + // Maximum time to wait for the window to resize before continuing with the + // script. If 0 or unset, the action doesn't wait. + optional int32 resize_timeout_ms = 3; } // Allow scripts to display a form with multiple inputs.
diff --git a/components/autofill_assistant/browser/ui_controller.cc b/components/autofill_assistant/browser/ui_controller.cc index c91e081e..a2819e78 100644 --- a/components/autofill_assistant/browser/ui_controller.cc +++ b/components/autofill_assistant/browser/ui_controller.cc
@@ -25,7 +25,8 @@ void UiController::OnInfoBoxChanged(const InfoBox* info_box) {} void UiController::OnProgressChanged(int progress) {} void UiController::OnProgressVisibilityChanged(bool visible) {} -void UiController::OnTouchableAreaChanged(const std::vector<RectF>& areas) {} +void UiController::OnTouchableAreaChanged(const RectF& visual_viewport, + const std::vector<RectF>& areas) {} void UiController::OnResizeViewportChanged(bool resize_viewport) {} void UiController::OnPeekModeChanged( ConfigureBottomSheetProto::PeekMode peek_mode) {}
diff --git a/components/autofill_assistant/browser/ui_controller.h b/components/autofill_assistant/browser/ui_controller.h index 2050eef5..adb0342 100644 --- a/components/autofill_assistant/browser/ui_controller.h +++ b/components/autofill_assistant/browser/ui_controller.h
@@ -76,10 +76,16 @@ // Updates the area of the visible viewport that is accessible when the // overlay state is OverlayState::PARTIAL. // + // |visual_viewport| contains the position and size of the visual viewport in + // the layout viewport. It might be empty if not known or the touchable area + // is empty. + // // |rectangles| contains one element per configured rectangles, though these - // can correspond to empty rectangles. Coordinates are relative to the width - // or height of the visible viewport, as a number between 0 and 1. - virtual void OnTouchableAreaChanged(const std::vector<RectF>& rectangles); + // can correspond to empty rectangles. + // + // All rectangles are expressed in absolute CSS coordinates. + virtual void OnTouchableAreaChanged(const RectF& visual_viewport, + const std::vector<RectF>& rectangles); // Called when the viewport resize flag has changed. virtual void OnResizeViewportChanged(bool resize_viewport);
diff --git a/components/autofill_assistant/browser/ui_delegate.h b/components/autofill_assistant/browser/ui_delegate.h index aa613620..288dd0fc 100644 --- a/components/autofill_assistant/browser/ui_delegate.h +++ b/components/autofill_assistant/browser/ui_delegate.h
@@ -109,12 +109,16 @@ // // At the end of this call, |rectangles| contains one element per configured // rectangles, though these can correspond to empty rectangles. Coordinates - // are relative to the width or height of the visible viewport, as a number - // between 0 and 1. + // absolute CSS coordinates. // // Note that the vector is not cleared before rectangles are added. virtual void GetTouchableArea(std::vector<RectF>* rectangles) const = 0; + // Returns the current size of the visual viewport. May be empty if unknown. + // + // The rectangle is expressed in absolute CSS coordinates. + virtual void GetVisualViewport(RectF* viewport) const = 0; + // Reports a fatal error to Autofill Assistant, which should then stop. virtual void OnFatalError(const std::string& error_message, Metrics::DropOutReason reason) = 0;
diff --git a/components/autofill_assistant/browser/web_controller.cc b/components/autofill_assistant/browser/web_controller.cc index 03aca28..9f9963b 100644 --- a/components/autofill_assistant/browser/web_controller.cc +++ b/components/autofill_assistant/browser/web_controller.cc
@@ -23,6 +23,7 @@ #include "components/autofill/core/common/autofill_constants.h" #include "components/autofill/core/common/form_data.h" #include "components/autofill_assistant/browser/client_settings.h" +#include "components/autofill_assistant/browser/client_status.h" #include "components/autofill_assistant/browser/rectf.h" #include "components/autofill_assistant/browser/string_conversions_util.h" #include "content/public/browser/browser_task_traits.h" @@ -46,11 +47,19 @@ const char* const kGetBoundingClientRectAsList = R"(function(node) { const r = node.getBoundingClientRect(); - const v = window.visualViewport; - return [r.left, r.top, r.right, r.bottom, - v.offsetLeft, v.offsetTop, v.width, v.height]; + return [window.scrollX + r.left, + window.scrollY + r.top, + window.scrollX + r.right, + window.scrollY + r.bottom]; })"; +const char* const kGetVisualViewport = + R"({ const v = window.visualViewport; + [v.pageLeft, + v.pageTop, + v.width, + v.height] })"; + const char* const kScrollIntoViewScript = R"(function(node) { node.scrollIntoViewIfNeeded(); @@ -189,6 +198,26 @@ selector.click(); })"; +// Javascript code that returns a promise that will succeed once the main +// document window has changed height. +// +// This ignores width changes, to filter out resizes caused by changes to the +// screen orientation. +const char* const kWaitForWindowHeightChange = R"( +new Promise((fulfill, reject) => { + var lastWidth = window.innerWidth; + var handler = function(event) { + if (window.innerWidth != lastWidth) { + lastWidth = window.innerWidth; + return + } + window.removeEventListener('resize', handler) + fulfill(true) + } + window.addEventListener('resize', handler) +}) +)"; + bool ConvertPseudoType(const PseudoType pseudo_type, dom::PseudoType* pseudo_type_output) { switch (pseudo_type) { @@ -1141,6 +1170,24 @@ std::move(callback).Run(status.ok()); } +void WebController::WaitForWindowHeightChange( + base::OnceCallback<void(const ClientStatus&)> callback) { + devtools_client_->GetRuntime()->Evaluate( + runtime::EvaluateParams::Builder() + .SetExpression(kWaitForWindowHeightChange) + .SetAwaitPromise(true) + .Build(), + base::BindOnce(&WebController::OnWaitForWindowHeightChange, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); +} + +void WebController::OnWaitForWindowHeightChange( + base::OnceCallback<void(const ClientStatus&)> callback, + std::unique_ptr<runtime::EvaluateResult> result) { + std::move(callback).Run( + CheckJavaScriptResult(result.get(), __FILE__, __LINE__)); +} + void WebController::FindElement(const Selector& selector, bool strict_mode, FindElementCallback callback) { @@ -1739,6 +1786,47 @@ weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } +void WebController::GetVisualViewport( + base::OnceCallback<void(bool, const RectF&)> callback) { + devtools_client_->GetRuntime()->Evaluate( + runtime::EvaluateParams::Builder() + .SetExpression(std::string(kGetVisualViewport)) + .SetReturnByValue(true) + .Build(), + base::BindOnce(&WebController::OnGetVisualViewport, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); +} + +void WebController::OnGetVisualViewport( + base::OnceCallback<void(bool, const RectF&)> callback, + std::unique_ptr<runtime::EvaluateResult> result) { + ClientStatus status = CheckJavaScriptResult(result.get(), __FILE__, __LINE__); + if (!status.ok() || !result->GetResult()->HasValue() || + !result->GetResult()->GetValue()->is_list() || + result->GetResult()->GetValue()->GetList().size() != 4u) { + DVLOG(1) << __func__ << " Failed to get visual viewport: " << status; + RectF empty; + std::move(callback).Run(false, empty); + return; + } + const auto& list = result->GetResult()->GetValue()->GetList(); + // Value::GetDouble() is safe to call without checking the value type; it'll + // return 0.0 if the value has the wrong type. + + float left = static_cast<float>(list[0].GetDouble()); + float top = static_cast<float>(list[1].GetDouble()); + float width = static_cast<float>(list[2].GetDouble()); + float height = static_cast<float>(list[3].GetDouble()); + + RectF rect; + rect.left = left; + rect.top = top; + rect.right = left + width; + rect.bottom = top + height; + + std::move(callback).Run(true, rect); +} + void WebController::GetElementPosition( const Selector& selector, base::OnceCallback<void(bool, const RectF&)> callback) { @@ -1776,9 +1864,10 @@ base::OnceCallback<void(bool, const RectF&)> callback, std::unique_ptr<runtime::CallFunctionOnResult> result) { ClientStatus status = CheckJavaScriptResult(result.get(), __FILE__, __LINE__); - if (!status.ok() || !result->GetResult()->GetValue() || + if (!status.ok() || !result->GetResult()->HasValue() || !result->GetResult()->GetValue()->is_list() || - result->GetResult()->GetValue()->GetList().size() != 8u) { + result->GetResult()->GetValue()->GetList().size() != 4u) { + DVLOG(2) << __func__ << " Failed to get element position: " << status; RectF empty; std::move(callback).Run(false, empty); return; @@ -1787,22 +1876,11 @@ // Value::GetDouble() is safe to call without checking the value type; it'll // return 0.0 if the value has the wrong type. - // getBoundingClientRect returns coordinates in the layout viewport. They need - // to be transformed into coordinates in the visual viewport, between 0 and 1. - float left_layout = static_cast<float>(list[0].GetDouble()); - float top_layout = static_cast<float>(list[1].GetDouble()); - float right_layout = static_cast<float>(list[2].GetDouble()); - float bottom_layout = static_cast<float>(list[3].GetDouble()); - float visual_left_offset = static_cast<float>(list[4].GetDouble()); - float visual_top_offset = static_cast<float>(list[5].GetDouble()); - float visual_w = static_cast<float>(list[6].GetDouble()); - float visual_h = static_cast<float>(list[7].GetDouble()); - RectF rect; - rect.left = (left_layout - visual_left_offset) / visual_w; - rect.top = (top_layout - visual_top_offset) / visual_h; - rect.right = (right_layout - visual_left_offset) / visual_w; - rect.bottom = (bottom_layout - visual_top_offset) / visual_h; + rect.left = static_cast<float>(list[0].GetDouble()); + rect.top = static_cast<float>(list[1].GetDouble()); + rect.right = static_cast<float>(list[2].GetDouble()); + rect.bottom = static_cast<float>(list[3].GetDouble()); std::move(callback).Run(true, rect); }
diff --git a/components/autofill_assistant/browser/web_controller.h b/components/autofill_assistant/browser/web_controller.h index 760fb4d3..e63a379 100644 --- a/components/autofill_assistant/browser/web_controller.h +++ b/components/autofill_assistant/browser/web_controller.h
@@ -153,13 +153,18 @@ base::OnceCallback<void(const ClientStatus&, const std::string&)> callback); + // Gets the visual viewport coordinates and size. + // + // The rectangle is expressed in absolute CSS coordinates. + virtual void GetVisualViewport( + base::OnceCallback<void(bool, const RectF&)> callback); + // Gets the position of the element identified by the selector. // // If unsuccessful, the callback gets (false, 0, 0, 0, 0). // // If successful, the callback gets (true, left, top, right, bottom), with - // coordinates expressed as numbers between 0 and 1, relative to the width or - // height of the visible viewport. + // coordinates expressed in absolute CSS coordinates. virtual void GetElementPosition( const Selector& selector, base::OnceCallback<void(bool, const RectF&)> callback); @@ -181,6 +186,10 @@ bool strict, base::OnceCallback<void(bool)> callback); + // Calls the callback once the main document window has been resized. + virtual void WaitForWindowHeightChange( + base::OnceCallback<void(const ClientStatus&)> callback); + private: friend class WebControllerBrowserTest; @@ -285,6 +294,9 @@ void OnFindElementForCheck(base::OnceCallback<void(bool)> callback, const ClientStatus& status, std::unique_ptr<FindElementResult> result); + void OnWaitForWindowHeightChange( + base::OnceCallback<void(const ClientStatus&)> callback, + std::unique_ptr<runtime::EvaluateResult> result); // Find the element given by |selector|. If multiple elements match // |selector| and if |strict_mode| is false, return the first one that is @@ -400,6 +412,9 @@ base::OnceCallback<void(bool, const RectF&)> callback, const ClientStatus& status, std::unique_ptr<FindElementResult> result); + void OnGetVisualViewport( + base::OnceCallback<void(bool, const RectF&)> callback, + std::unique_ptr<runtime::EvaluateResult> result); void OnGetElementPositionResult( base::OnceCallback<void(bool, const RectF&)> callback, std::unique_ptr<runtime::CallFunctionOnResult> result);
diff --git a/components/autofill_assistant/browser/web_controller_browsertest.cc b/components/autofill_assistant/browser/web_controller_browsertest.cc index 4253e4e..e123e5aae 100644 --- a/components/autofill_assistant/browser/web_controller_browsertest.cc +++ b/components/autofill_assistant/browser/web_controller_browsertest.cc
@@ -170,14 +170,14 @@ ClientStatus result; web_controller_->SelectOption( selector, option, - base::BindOnce(&WebControllerBrowserTest::OnSelectOption, + base::BindOnce(&WebControllerBrowserTest::OnClientStatus, base::Unretained(this), run_loop.QuitClosure(), &result)); run_loop.Run(); return result; } - void OnSelectOption(base::Closure done_callback, + void OnClientStatus(base::Closure done_callback, ClientStatus* result_output, const ClientStatus& status) { *result_output = status; @@ -188,20 +188,13 @@ base::RunLoop run_loop; ClientStatus result; web_controller_->HighlightElement( - selector, base::BindOnce(&WebControllerBrowserTest::OnHighlightElement, + selector, base::BindOnce(&WebControllerBrowserTest::OnClientStatus, base::Unretained(this), run_loop.QuitClosure(), &result)); run_loop.Run(); return result; } - void OnHighlightElement(base::Closure done_callback, - ClientStatus* result_output, - const ClientStatus& status) { - *result_output = status; - std::move(done_callback).Run(); - } - ClientStatus GetOuterHtml(const Selector& selector, std::string* html_output) { base::RunLoop run_loop; @@ -1089,4 +1082,17 @@ EXPECT_TRUE(SetCookie()); } +IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, WaitForHeightChange) { + base::RunLoop run_loop; + ClientStatus result; + web_controller_->WaitForWindowHeightChange( + base::BindOnce(&WebControllerBrowserTest::OnClientStatus, + base::Unretained(this), run_loop.QuitClosure(), &result)); + + EXPECT_TRUE( + content::ExecJs(shell(), "window.dispatchEvent(new Event('resize'))")); + run_loop.Run(); + EXPECT_EQ(ACTION_APPLIED, result.proto_status()); +} + } // namespace
diff --git a/components/bookmarks/browser/bookmark_model.cc b/components/bookmarks/browser/bookmark_model.cc index a6e358c781..1578f2e5 100644 --- a/components/bookmarks/browser/bookmark_model.cc +++ b/components/bookmarks/browser/bookmark_model.cc
@@ -294,7 +294,7 @@ BookmarkNode* mutable_old_parent = AsMutable(old_parent); std::unique_ptr<BookmarkNode> owned_node = - mutable_old_parent->Remove(AsMutable(node)); + mutable_old_parent->Remove(old_index); BookmarkNode* mutable_new_parent = AsMutable(new_parent); mutable_new_parent->Add(std::move(owned_node), index);
diff --git a/components/bookmarks/browser/bookmark_model_unittest.cc b/components/bookmarks/browser/bookmark_model_unittest.cc index 1a09c01c..24de891 100644 --- a/components/bookmarks/browser/bookmark_model_unittest.cc +++ b/components/bookmarks/browser/bookmark_model_unittest.cc
@@ -1043,10 +1043,10 @@ BookmarkNode* child1 = AsMutable(parent->GetChild(1)); child1->SetTitle(ASCIIToUTF16("a")); - child1->Remove(child1->GetChild(0)); + child1->Remove(0); BookmarkNode* child3 = AsMutable(parent->GetChild(3)); child3->SetTitle(ASCIIToUTF16("C")); - child3->Remove(child3->GetChild(0)); + child3->Remove(0); ClearCounts();
diff --git a/components/bookmarks/browser/url_index.cc b/components/bookmarks/browser/url_index.cc index 39f2130..4b87500 100644 --- a/components/bookmarks/browser/url_index.cc +++ b/components/bookmarks/browser/url_index.cc
@@ -41,7 +41,8 @@ } } } - return node->parent()->Remove(node); + BookmarkNode* parent = node->parent(); + return parent->Remove(parent->GetIndexOf(node)); } void UrlIndex::SetUrl(BookmarkNode* node, const GURL& url) {
diff --git a/components/browser_sync/profile_sync_components_factory_impl.cc b/components/browser_sync/profile_sync_components_factory_impl.cc index a4cf6436..2937ca96 100644 --- a/components/browser_sync/profile_sync_components_factory_impl.cc +++ b/components/browser_sync/profile_sync_components_factory_impl.cc
@@ -282,17 +282,13 @@ std::make_unique<SyncableServiceBasedModelTypeController>( syncer::FAVICON_IMAGES, sync_client_->GetModelTypeStoreService()->GetStoreFactory(), - base::BindOnce(&syncer::SyncClient::GetSyncableServiceForType, - base::Unretained(sync_client_), - syncer::FAVICON_IMAGES), + sync_client_->GetSyncableServiceForType(syncer::FAVICON_IMAGES), dump_stack)); controllers.push_back( std::make_unique<SyncableServiceBasedModelTypeController>( syncer::FAVICON_TRACKING, sync_client_->GetModelTypeStoreService()->GetStoreFactory(), - base::BindOnce(&syncer::SyncClient::GetSyncableServiceForType, - base::Unretained(sync_client_), - syncer::FAVICON_TRACKING), + sync_client_->GetSyncableServiceForType(syncer::FAVICON_TRACKING), dump_stack)); } } @@ -317,8 +313,7 @@ std::make_unique<SyncableServiceBasedModelTypeController>( syncer::PREFERENCES, sync_client_->GetModelTypeStoreService()->GetStoreFactory(), - base::BindOnce(&syncer::SyncClient::GetSyncableServiceForType, - base::Unretained(sync_client_), syncer::PREFERENCES), + sync_client_->GetSyncableServiceForType(syncer::PREFERENCES), dump_stack)); } @@ -327,9 +322,8 @@ std::make_unique<SyncableServiceBasedModelTypeController>( syncer::PRIORITY_PREFERENCES, sync_client_->GetModelTypeStoreService()->GetStoreFactory(), - base::BindOnce(&syncer::SyncClient::GetSyncableServiceForType, - base::Unretained(sync_client_), - syncer::PRIORITY_PREFERENCES), + sync_client_->GetSyncableServiceForType( + syncer::PRIORITY_PREFERENCES), dump_stack)); }
diff --git a/components/cdm/browser/cdm_message_filter_android.cc b/components/cdm/browser/cdm_message_filter_android.cc index ffcc775..73979875 100644 --- a/components/cdm/browser/cdm_message_filter_android.cc +++ b/components/cdm/browser/cdm_message_filter_android.cc
@@ -119,7 +119,8 @@ return handled; } -base::TaskRunner* CdmMessageFilterAndroid::OverrideTaskRunnerForMessage( +scoped_refptr<base::SequencedTaskRunner> +CdmMessageFilterAndroid::OverrideTaskRunnerForMessage( const IPC::Message& message) { // Move the IPC handling to FILE thread as it is not very cheap. if (message.type() == ChromeViewHostMsg_QueryKeySystemSupport::ID)
diff --git a/components/cdm/browser/cdm_message_filter_android.h b/components/cdm/browser/cdm_message_filter_android.h index 3c0e3b7..f5f3a16 100644 --- a/components/cdm/browser/cdm_message_filter_android.h +++ b/components/cdm/browser/cdm_message_filter_android.h
@@ -31,7 +31,7 @@ // BrowserMessageFilter implementation. bool OnMessageReceived(const IPC::Message& message) override; - base::TaskRunner* OverrideTaskRunnerForMessage( + scoped_refptr<base::SequencedTaskRunner> OverrideTaskRunnerForMessage( const IPC::Message& message) override; // Query the key system information.
diff --git a/components/favicon/core/favicon_request_handler.cc b/components/favicon/core/favicon_request_handler.cc index b9fe07dc..6d18c49 100644 --- a/components/favicon/core/favicon_request_handler.cc +++ b/components/favicon/core/favicon_request_handler.cc
@@ -79,8 +79,22 @@ const bool kFallbackToHost = true; // Parameter used for local bitmap queries by page url. -favicon_base::IconTypeSet GetIconTypesForLocalQuery() { - return favicon_base::IconTypeSet{favicon_base::IconType::kFavicon}; +favicon_base::IconTypeSet GetIconTypesForLocalQuery( + FaviconRequestPlatform platform) { + // The value must agree with the one written in the local data for retrieved + // server icons so that we can find them on the second lookup. This depends on + // whether the caller is a mobile UI or not. + switch (platform) { + case FaviconRequestPlatform::kMobile: + return favicon_base::IconTypeSet{ + favicon_base::IconType::kFavicon, favicon_base::IconType::kTouchIcon, + favicon_base::IconType::kTouchPrecomposedIcon, + favicon_base::IconType::kWebManifestIcon}; + case FaviconRequestPlatform::kDesktop: + return favicon_base::IconTypeSet{favicon_base::IconType::kFavicon}; + } + NOTREACHED(); + return favicon_base::IconTypeSet{}; } bool CanOriginQueryGoogleServer(FaviconRequestOrigin origin) { @@ -92,6 +106,7 @@ case FaviconRequestOrigin::UNKNOWN: return false; } + NOTREACHED(); return false; } @@ -101,18 +116,16 @@ return !icon_url.is_empty() ? icon_url : page_url; } -} // namespace - -// static -bool FaviconRequestHandler::CanQueryGoogleServer( - LargeIconService* large_icon_service, - FaviconRequestOrigin origin, - bool can_send_history_data) { +bool CanQueryGoogleServer(LargeIconService* large_icon_service, + FaviconRequestOrigin origin, + bool can_send_history_data) { return large_icon_service && CanOriginQueryGoogleServer(origin) && can_send_history_data && base::FeatureList::IsEnabled(kEnableHistoryFaviconsGoogleServerQuery); } +} // namespace + FaviconRequestHandler::FaviconRequestHandler() {} FaviconRequestHandler::~FaviconRequestHandler() {} @@ -122,6 +135,7 @@ int desired_size_in_pixel, favicon_base::FaviconRawBitmapCallback callback, FaviconRequestOrigin request_origin, + FaviconRequestPlatform request_platform, FaviconService* favicon_service, LargeIconService* large_icon_service, const GURL& icon_url_for_uma, @@ -137,14 +151,14 @@ // First attempt to find the icon locally. favicon_service->GetRawFaviconForPageURL( - page_url, GetIconTypesForLocalQuery(), desired_size_in_pixel, - kFallbackToHost, + page_url, GetIconTypesForLocalQuery(request_platform), + 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, - favicon_service, large_icon_service, icon_url_for_uma, - std::move(synced_favicon_getter), + request_platform, favicon_service, large_icon_service, + icon_url_for_uma, std::move(synced_favicon_getter), CanQueryGoogleServer(large_icon_service, request_origin, can_send_history_data), tracker), @@ -187,6 +201,7 @@ int desired_size_in_pixel, favicon_base::FaviconRawBitmapCallback response_callback, FaviconRequestOrigin origin, + FaviconRequestPlatform platform, FaviconService* favicon_service, LargeIconService* large_icon_service, const GURL& icon_url_for_uma, @@ -207,8 +222,15 @@ base::RepeatingCallback<void(const favicon_base::FaviconRawBitmapResult&)> repeating_response_callback = base::AdaptCallbackForRepeating(std::move(response_callback)); + // TODO(victorvianna): Set |min_source_size_in_pixel| correctly. + std::unique_ptr<FaviconServerFetcherParams> server_parameters = + platform == FaviconRequestPlatform::kMobile + ? FaviconServerFetcherParams::CreateForMobile( + page_url, /*min_source_size_in_pixel=*/1, + desired_size_in_pixel) + : FaviconServerFetcherParams::CreateForDesktop(page_url); RequestFromGoogleServer( - page_url, + page_url, std::move(server_parameters), /*empty_response_callback=*/ base::BindOnce(repeating_response_callback, favicon_base::FaviconRawBitmapResult()), @@ -216,8 +238,8 @@ base::BindOnce( base::IgnoreResult(&FaviconService::GetRawFaviconForPageURL), base::Unretained(favicon_service), page_url, - GetIconTypesForLocalQuery(), desired_size_in_pixel, kFallbackToHost, - repeating_response_callback, tracker), + GetIconTypesForLocalQuery(platform), desired_size_in_pixel, + kFallbackToHost, repeating_response_callback, tracker), large_icon_service, icon_url_for_uma, origin); return; } @@ -262,8 +284,10 @@ base::RepeatingCallback<void(const favicon_base::FaviconImageResult&)> repeating_response_callback = base::AdaptCallbackForRepeating(std::move(response_callback)); + // We use CreateForDesktop because GetFaviconImageForPageURL is only called + // by desktop. RequestFromGoogleServer( - page_url, + page_url, FaviconServerFetcherParams::CreateForDesktop(page_url), /*empty_response_callback=*/ base::BindOnce(repeating_response_callback, favicon_base::FaviconImageResult()), @@ -296,6 +320,7 @@ void FaviconRequestHandler::RequestFromGoogleServer( const GURL& page_url, + std::unique_ptr<FaviconServerFetcherParams> server_parameters, base::OnceClosure empty_response_callback, base::OnceClosure local_lookup_callback, LargeIconService* large_icon_service, @@ -345,7 +370,7 @@ /* default_value= */ false); large_icon_service ->GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache( - FaviconServerFetcherParams::CreateForDesktop(page_url), + std::move(server_parameters), /*may_page_url_be_private=*/true, should_trim_url_path, traffic_annotation, base::BindOnce(&FaviconRequestHandler::OnGoogleServerDataAvailable,
diff --git a/components/favicon/core/favicon_request_handler.h b/components/favicon/core/favicon_request_handler.h index 1833ef40..27d5e2cc 100644 --- a/components/favicon/core/favicon_request_handler.h +++ b/components/favicon/core/favicon_request_handler.h
@@ -16,16 +16,18 @@ namespace favicon { +class FaviconServerFetcherParams; 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, - // chrome://history. + // History page. HISTORY, - // chrome://history/syncedTabs. + // History synced tabs page (desktop only). HISTORY_SYNCED_TABS, // Recently closed tabs menu. RECENTLY_CLOSED_TABS, @@ -42,6 +44,12 @@ kMaxValue = kNotAvailable, }; +// Platform making the request. +enum class FaviconRequestPlatform { + kMobile, + kDesktop, +}; + // Class for handling favicon requests by page url, forwarding them to local // storage, sync or Google server accordingly. // TODO(victorvianna): Refactor LargeIconService to avoid having to pass both @@ -69,10 +77,12 @@ // that history sync is enabled and no custom passphrase is set). // 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, FaviconService* favicon_service, LargeIconService* large_icon_service, const GURL& icon_url_for_uma, @@ -88,6 +98,7 @@ // that history sync is enabled and no custom passphrase is set). // 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, @@ -99,10 +110,6 @@ base::CancelableTaskTracker* tracker); private: - static bool CanQueryGoogleServer(LargeIconService* large_icon_service, - FaviconRequestOrigin origin, - bool can_send_history_data); - // Called after the first attempt to retrieve the icon bitmap from local // storage. If request succeeded, sends the result. Otherwise attempts to // retrieve from sync or the Google favicon server depending whether @@ -112,6 +119,7 @@ int desired_size_in_pixel, favicon_base::FaviconRawBitmapCallback response_callback, FaviconRequestOrigin origin, + FaviconRequestPlatform platform, FaviconService* favicon_service, LargeIconService* large_icon_service, const GURL& icon_url_for_uma, @@ -139,12 +147,14 @@ // Requests an icon from Google favicon server. Since requests work by // populating local storage, a |local_lookup_callback| will be needed in case // of success and an |empty_response_callback| in case of failure. - void RequestFromGoogleServer(const GURL& page_url, - base::OnceClosure empty_response_callback, - base::OnceClosure local_lookup_callback, - LargeIconService* large_icon_service, - const GURL& icon_url_for_uma, - FaviconRequestOrigin origin); + void RequestFromGoogleServer( + const GURL& page_url, + std::unique_ptr<FaviconServerFetcherParams> server_parameters, + base::OnceClosure empty_response_callback, + base::OnceClosure local_lookup_callback, + LargeIconService* large_icon_service, + const GURL& icon_url_for_uma, + FaviconRequestOrigin origin); // Called once the request to the favicon server has finished. If the request // succeeded, |local_lookup_callback| is called to effectively retrieve the
diff --git a/components/favicon/core/favicon_request_handler_unittest.cc b/components/favicon/core/favicon_request_handler_unittest.cc index c83f832..fdbcd404 100644 --- a/components/favicon/core/favicon_request_handler_unittest.cc +++ b/components/favicon/core/favicon_request_handler_unittest.cc
@@ -29,6 +29,8 @@ const char kDummyPageUrl[] = "https://www.example.com"; const int kDesiredSizeInPixel = 16; +// TODO(victorvianna): Add unit tests specific for mobile. +const FaviconRequestPlatform kDummyPlatform = FaviconRequestPlatform::kDesktop; const SkColor kTestColor = SK_ColorRED; base::CancelableTaskTracker::TaskId kDummyTaskId = 1; @@ -136,7 +138,7 @@ favicon_request_handler_.GetRawFaviconForPageURL( GURL(kDummyPageUrl), kDesiredSizeInPixel, base::BindOnce(&StoreBitmap, &result), FaviconRequestOrigin::UNKNOWN, - &mock_favicon_service_, &mock_large_icon_service_, + kDummyPlatform, &mock_favicon_service_, &mock_large_icon_service_, /*icon_url_for_uma=*/GURL(), synced_favicon_getter_.Get(), /*can_send_history_data=*/true, &tracker_); EXPECT_FALSE(result.is_valid()); @@ -161,7 +163,7 @@ favicon_request_handler_.GetRawFaviconForPageURL( GURL(kDummyPageUrl), kDesiredSizeInPixel, base::BindOnce(&StoreBitmap, &result), FaviconRequestOrigin::UNKNOWN, - &mock_favicon_service_, &mock_large_icon_service_, + kDummyPlatform, &mock_favicon_service_, &mock_large_icon_service_, /*icon_url_for_uma=*/GURL(), synced_favicon_getter_.Get(), /*can_send_history_data=*/true, &tracker_); EXPECT_TRUE(result.is_valid()); @@ -185,7 +187,7 @@ favicon_request_handler_.GetRawFaviconForPageURL( GURL(kDummyPageUrl), kDesiredSizeInPixel, base::BindOnce(&StoreBitmap, &result), FaviconRequestOrigin::UNKNOWN, - &mock_favicon_service_, &mock_large_icon_service_, + kDummyPlatform, &mock_favicon_service_, &mock_large_icon_service_, /*icon_url_for_uma=*/GURL(), synced_favicon_getter_.Get(), /*can_send_history_data=*/true, &tracker_); EXPECT_TRUE(result.is_valid()); @@ -223,7 +225,7 @@ favicon_request_handler_.GetRawFaviconForPageURL( GURL(kDummyPageUrl), kDesiredSizeInPixel, base::BindOnce(&StoreBitmap, &result), FaviconRequestOrigin::HISTORY, - &mock_favicon_service_, &mock_large_icon_service_, + kDummyPlatform, &mock_favicon_service_, &mock_large_icon_service_, /*icon_url_for_uma=*/GURL(), synced_favicon_getter_.Get(), /*can_send_history_data=*/true, &tracker_); EXPECT_TRUE(result.is_valid()); @@ -259,7 +261,7 @@ favicon_request_handler_.GetRawFaviconForPageURL( GURL(kDummyPageUrl), kDesiredSizeInPixel, base::BindOnce(&StoreBitmap, &result), FaviconRequestOrigin::HISTORY, - &mock_favicon_service_, &mock_large_icon_service_, + kDummyPlatform, &mock_favicon_service_, &mock_large_icon_service_, /*icon_url_for_uma=*/GURL(), synced_favicon_getter_.Get(), /*can_send_history_data=*/true, &tracker_); EXPECT_TRUE(result.is_valid()); @@ -284,8 +286,9 @@ favicon_request_handler_.GetFaviconImageForPageURL( GURL(kDummyPageUrl), base::BindOnce(&StoreImage, &result), FaviconRequestOrigin::UNKNOWN, &mock_favicon_service_, - &mock_large_icon_service_, /*icon_url_for_uma=*/GURL(), - synced_favicon_getter_.Get(), /*can_send_history_data=*/true, &tracker_); + &mock_large_icon_service_, + /*icon_url_for_uma=*/GURL(), synced_favicon_getter_.Get(), + /*can_send_history_data=*/true, &tracker_); EXPECT_TRUE(result.image.IsEmpty()); histogram_tester_.ExpectUniqueSample("Sync.FaviconAvailability.UNKNOWN", FaviconAvailability::kNotAvailable, 1); @@ -306,8 +309,9 @@ favicon_request_handler_.GetFaviconImageForPageURL( GURL(kDummyPageUrl), base::BindOnce(&StoreImage, &result), FaviconRequestOrigin::UNKNOWN, &mock_favicon_service_, - &mock_large_icon_service_, /*icon_url_for_uma=*/GURL(), - synced_favicon_getter_.Get(), /*can_send_history_data=*/true, &tracker_); + &mock_large_icon_service_, + /*icon_url_for_uma=*/GURL(), synced_favicon_getter_.Get(), + /*can_send_history_data=*/true, &tracker_); EXPECT_FALSE(result.image.IsEmpty()); histogram_tester_.ExpectUniqueSample("Sync.FaviconAvailability.UNKNOWN", FaviconAvailability::kSync, 1); @@ -327,8 +331,9 @@ favicon_request_handler_.GetFaviconImageForPageURL( GURL(kDummyPageUrl), base::BindOnce(&StoreImage, &result), FaviconRequestOrigin::UNKNOWN, &mock_favicon_service_, - &mock_large_icon_service_, /*icon_url_for_uma=*/GURL(), - synced_favicon_getter_.Get(), /*can_send_history_data=*/true, &tracker_); + &mock_large_icon_service_, + /*icon_url_for_uma=*/GURL(), synced_favicon_getter_.Get(), + /*can_send_history_data=*/true, &tracker_); EXPECT_FALSE(result.image.IsEmpty()); histogram_tester_.ExpectUniqueSample("Sync.FaviconAvailability.UNKNOWN", FaviconAvailability::kLocal, 1); @@ -424,7 +429,7 @@ favicon_request_handler_.GetRawFaviconForPageURL( GURL(kDummyPageUrl), kDesiredSizeInPixel, base::BindOnce(&StoreBitmap, &result), FaviconRequestOrigin::HISTORY, - &mock_favicon_service_, &mock_large_icon_service_, + kDummyPlatform, &mock_favicon_service_, &mock_large_icon_service_, /*icon_url_for_uma=*/GURL(), synced_favicon_getter_.Get(), /*can_send_history_data=*/false, &tracker_); }
diff --git a/components/history/core/browser/sync/history_delete_directives_model_type_controller.cc b/components/history/core/browser/sync/history_delete_directives_model_type_controller.cc index 38b3467..8955d0f 100644 --- a/components/history/core/browser/sync/history_delete_directives_model_type_controller.cc +++ b/components/history/core/browser/sync/history_delete_directives_model_type_controller.cc
@@ -23,9 +23,8 @@ : SyncableServiceBasedModelTypeController( syncer::HISTORY_DELETE_DIRECTIVES, model_type_store_service->GetStoreFactory(), - base::BindOnce(&syncer::SyncClient::GetSyncableServiceForType, - base::Unretained(sync_client), - syncer::HISTORY_DELETE_DIRECTIVES), + sync_client->GetSyncableServiceForType( + syncer::HISTORY_DELETE_DIRECTIVES), dump_stack), sync_service_(sync_service) {}
diff --git a/components/signin/core/browser/gaia_cookie_manager_service.cc b/components/signin/core/browser/gaia_cookie_manager_service.cc index 50df29d..af75bff 100644 --- a/components/signin/core/browser/gaia_cookie_manager_service.cc +++ b/components/signin/core/browser/gaia_cookie_manager_service.cc
@@ -653,14 +653,6 @@ } } -void GaiaCookieManagerService::AddObserver(Observer* observer) { - observer_list_.AddObserver(observer); -} - -void GaiaCookieManagerService::RemoveObserver(Observer* observer) { - observer_list_.RemoveObserver(observer); -} - void GaiaCookieManagerService::CancelAll() { VLOG(1) << "GaiaCookieManagerService::CancelAll"; gaia_auth_fetcher_.reset(); @@ -694,8 +686,8 @@ if (cause == network::mojom::CookieChangeCause::EXPLICIT) { DCHECK(net::CookieChangeCauseIsDeletion(net::CookieChangeCause::EXPLICIT)); - for (auto& observer : observer_list_) { - observer.OnGaiaCookieDeletedByUserAction(); + if (gaia_cookie_deleted_by_user_action_callback_) { + gaia_cookie_deleted_by_user_action_callback_.Run(); } } @@ -743,6 +735,18 @@ requests_.front().RunSetAccountsInCookieCompletedCallback(result); } +void GaiaCookieManagerService::SetGaiaAccountsInCookieUpdatedCallback( + GaiaAccountsInCookieUpdatedCallback callback) { + DCHECK(!gaia_accounts_updated_in_cookie_callback_); + gaia_accounts_updated_in_cookie_callback_ = std::move(callback); +} + +void GaiaCookieManagerService::SetGaiaCookieDeletedByUserActionCallback( + GaiaCookieDeletedByUserActionCallback callback) { + DCHECK(!gaia_cookie_deleted_by_user_action_callback_); + gaia_cookie_deleted_by_user_action_callback_ = std::move(callback); +} + void GaiaCookieManagerService::OnUbertokenFetchComplete( GoogleServiceAuthError error, const std::string& uber_token) { @@ -851,8 +855,8 @@ // services, in response to OnGaiaAccountsInCookieUpdated, may try in return // to call ListAccounts, which would immediately return false if the // ListAccounts request is still sitting in queue. - for (auto& observer : observer_list_) { - observer.OnGaiaAccountsInCookieUpdated( + if (gaia_accounts_updated_in_cookie_callback_) { + gaia_accounts_updated_in_cookie_callback_.Run( listed_accounts_, signed_out_accounts_, GoogleServiceAuthError(GoogleServiceAuthError::NONE)); } @@ -880,10 +884,12 @@ } RecordListAccountsFailure(error.state()); - for (auto& observer : observer_list_) { - observer.OnGaiaAccountsInCookieUpdated(listed_accounts_, - signed_out_accounts_, error); + + if (gaia_accounts_updated_in_cookie_callback_) { + gaia_accounts_updated_in_cookie_callback_.Run(listed_accounts_, + signed_out_accounts_, error); } + HandleNextRequest(); }
diff --git a/components/signin/core/browser/gaia_cookie_manager_service.h b/components/signin/core/browser/gaia_cookie_manager_service.h index 13aeee1..626d1888 100644 --- a/components/signin/core/browser/gaia_cookie_manager_service.h +++ b/components/signin/core/browser/gaia_cookie_manager_service.h
@@ -86,6 +86,12 @@ const GoogleServiceAuthError&)> AddAccountToCookieCompletedCallback; + typedef base::RepeatingCallback<void(const std::vector<gaia::ListedAccount>&, + const std::vector<gaia::ListedAccount>&, + const GoogleServiceAuthError&)> + GaiaAccountsInCookieUpdatedCallback; + typedef base::RepeatingCallback<void()> GaiaCookieDeletedByUserActionCallback; + // Contains the information and parameters for any request. class GaiaCookieRequest { public: @@ -143,28 +149,6 @@ DISALLOW_COPY_AND_ASSIGN(GaiaCookieRequest); }; - class Observer { - public: - // Called whenever the GaiaCookieManagerService's list of GAIA accounts is - // updated. The GCMS monitors the APISID cookie and triggers a /ListAccounts - // call on change. The GCMS will also call ListAccounts upon the first call - // to ListAccounts(). The GCMS will delay calling ListAccounts if other - // requests are in queue that would modify the APISID cookie. - // If the ListAccounts call fails and the GCMS cannot recover, the reason - // is passed in |error|. - virtual void OnGaiaAccountsInCookieUpdated( - const std::vector<gaia::ListedAccount>& accounts, - const std::vector<gaia::ListedAccount>& signed_out_accounts, - const GoogleServiceAuthError& error) {} - - // Called when the Gaia cookie has been deleted explicitly by a user action, - // e.g. from the settings or by an extension. - virtual void OnGaiaCookieDeletedByUserAction() {} - - protected: - virtual ~Observer() {} - }; - // Class to retrieve the external connection check results from gaia. // Declared publicly for unit tests. class ExternalCcResultFetcher : public GaiaAuthConsumer { @@ -269,10 +253,6 @@ // service. Virtual for testing. virtual void ForceOnCookieChangeProcessing(); - // Add or remove observers of this helper. - void AddObserver(Observer* observer); - void RemoveObserver(Observer* observer); - // Cancel all login requests. void CancelAll(); @@ -294,6 +274,25 @@ list_accounts_stale_ = stale; } + // If set, this callback will be invoked whenever the + // GaiaCookieManagerService's list of GAIA accounts is updated. The GCMS + // monitors the APISID cookie and triggers a /ListAccounts call on change. + // The GCMS will also call ListAccounts upon the first call to + // ListAccounts(). The GCMS will delay calling ListAccounts if other + // requests are in queue that would modify the APISID cookie. + // If the ListAccounts call fails and the GCMS cannot recover, the reason + // is passed in |error|. + // This method can only be called once. + void SetGaiaAccountsInCookieUpdatedCallback( + GaiaAccountsInCookieUpdatedCallback callback); + + // If set, this callback will be invoked whenever the Gaia cookie has + // been deleted explicitly by a user action, e.g. from the settings or by an + // extension. + // This method can only be called once. + void SetGaiaCookieDeletedByUserActionCallback( + GaiaCookieDeletedByUserActionCallback callback); + // Returns a non-NULL pointer to its instance of net::BackoffEntry const net::BackoffEntry* GetBackoffEntry() { return &fetcher_backoff_; } @@ -360,6 +359,11 @@ OAuth2TokenService* token_service_; SigninClient* signin_client_; + GaiaAccountsInCookieUpdatedCallback gaia_accounts_updated_in_cookie_callback_; + GaiaCookieDeletedByUserActionCallback + gaia_cookie_deleted_by_user_action_callback_; + base::RepeatingCallback<scoped_refptr<network::SharedURLLoaderFactory>()> + shared_url_loader_factory_getter_; std::unique_ptr<GaiaAuthFetcher> gaia_auth_fetcher_; std::unique_ptr<signin::UbertokenFetcherImpl> uber_token_fetcher_; ExternalCcResultFetcher external_cc_result_fetcher_; @@ -385,10 +389,6 @@ // executed at a time. base::circular_deque<GaiaCookieRequest> requests_; - // List of observers to notify when merge session completes. - // Makes sure list is empty on destruction. - base::ObserverList<Observer, true>::Unchecked observer_list_; - // True once the ExternalCCResultFetcher has completed once. bool external_cc_result_fetched_;
diff --git a/components/signin/core/browser/gaia_cookie_manager_service_unittest.cc b/components/signin/core/browser/gaia_cookie_manager_service_unittest.cc index 80c2108c..5a27c8f 100644 --- a/components/signin/core/browser/gaia_cookie_manager_service_unittest.cc +++ b/components/signin/core/browser/gaia_cookie_manager_service_unittest.cc
@@ -38,21 +38,19 @@ using MockAddAccountToCookieCompletedCallback = base::MockCallback< GaiaCookieManagerService::AddAccountToCookieCompletedCallback>; -class MockObserver : public GaiaCookieManagerService::Observer { +class MockObserver { public: - explicit MockObserver(GaiaCookieManagerService* helper) : helper_(helper) { - helper_->AddObserver(this); + explicit MockObserver(GaiaCookieManagerService* helper) { + helper->SetGaiaAccountsInCookieUpdatedCallback(base::BindRepeating( + &MockObserver::OnGaiaAccountsInCookieUpdated, base::Unretained(this))); } - ~MockObserver() override { helper_->RemoveObserver(this); } - MOCK_METHOD3(OnGaiaAccountsInCookieUpdated, void(const std::vector<gaia::ListedAccount>&, const std::vector<gaia::ListedAccount>&, const GoogleServiceAuthError&)); private: - GaiaCookieManagerService* helper_; DISALLOW_COPY_AND_ASSIGN(MockObserver); };
diff --git a/components/signin/core/browser/identity_manager_wrapper.cc b/components/signin/core/browser/identity_manager_wrapper.cc index 2025ebc..fab2d43 100644 --- a/components/signin/core/browser/identity_manager_wrapper.cc +++ b/components/signin/core/browser/identity_manager_wrapper.cc
@@ -5,6 +5,7 @@ #include "components/signin/core/browser/identity_manager_wrapper.h" #include "components/keyed_service/core/keyed_service.h" +#include "components/signin/core/browser/gaia_cookie_manager_service.h" #include "services/identity/public/cpp/accounts_cookie_mutator.h" #include "services/identity/public/cpp/accounts_mutator.h" #include "services/identity/public/cpp/diagnostics_provider.h"
diff --git a/components/signin/core/browser/signin_manager.cc b/components/signin/core/browser/signin_manager.cc index 9de36b3..8f8a1100 100644 --- a/components/signin/core/browser/signin_manager.cc +++ b/components/signin/core/browser/signin_manager.cc
@@ -27,12 +27,10 @@ SigninClient* client, ProfileOAuth2TokenService* token_service, AccountTrackerService* account_tracker_service, - GaiaCookieManagerService* cookie_manager_service, signin::AccountConsistencyMethod account_consistency) : SigninManagerBase(client, token_service, account_tracker_service, - cookie_manager_service, account_consistency), weak_pointer_factory_(this) {} @@ -122,34 +120,6 @@ return identity::IsUsernameAllowedByPattern(username, pattern); } -void SigninManager::SignIn(const std::string& username) { - AccountInfo info = - account_tracker_service()->FindAccountInfoByEmail(username); - DCHECK(!info.gaia.empty()); - DCHECK(!info.email.empty()); - - bool reauth_in_progress = IsAuthenticated(); - - signin_client()->GetPrefs()->SetInt64( - prefs::kSignedInTime, - base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds()); - - SetAuthenticatedAccountInfo(info.gaia, info.email); - - if (!reauth_in_progress) - FireGoogleSigninSucceeded(); - - signin_metrics::LogSigninProfile(signin_client()->IsFirstRun(), - signin_client()->GetInstallDate()); -} - -void SigninManager::FireGoogleSigninSucceeded() { - const AccountInfo account_info = GetAuthenticatedAccountInfo(); - if (observer_ != nullptr) { - observer_->GoogleSigninSucceeded(account_info); - } -} - void SigninManager::OnRefreshTokensLoaded() { token_service()->RemoveObserver(this);
diff --git a/components/signin/core/browser/signin_manager.h b/components/signin/core/browser/signin_manager.h index 0b31e088..dfa3992a 100644 --- a/components/signin/core/browser/signin_manager.h +++ b/components/signin/core/browser/signin_manager.h
@@ -56,7 +56,6 @@ SigninManager(SigninClient* client, ProfileOAuth2TokenService* token_service, AccountTrackerService* account_tracker_service, - GaiaCookieManagerService* cookie_manager_service, signin::AccountConsistencyMethod account_consistency); ~SigninManager() override; @@ -71,10 +70,6 @@ void FinalizeInitBeforeLoadingRefreshTokens( PrefService* local_state) override; - // Signs a user in. SigninManager assumes that |username| can be used to look - // up the corresponding account_id and gaia_id for this email. - void SignIn(const std::string& username); - private: friend class identity::IdentityManager; FRIEND_TEST_ALL_PREFIXES(SigninManagerTest, Prohibited); @@ -83,9 +78,6 @@ // Returns true if a signin to Chrome is allowed (by policy or pref). bool IsSigninAllowed() const; - // Send all observers |GoogleSigninSucceeded| notifications. - void FireGoogleSigninSucceeded(); - // OAuth2TokenService::Observer: void OnRefreshTokensLoaded() override;
diff --git a/components/signin/core/browser/signin_manager_base.cc b/components/signin/core/browser/signin_manager_base.cc index 37ee807..be56c5d 100644 --- a/components/signin/core/browser/signin_manager_base.cc +++ b/components/signin/core/browser/signin_manager_base.cc
@@ -17,7 +17,6 @@ #include "components/prefs/pref_service.h" #include "components/signin/core/browser/account_info.h" #include "components/signin/core/browser/account_tracker_service.h" -#include "components/signin/core/browser/gaia_cookie_manager_service.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_client.h" #include "components/signin/core/browser/signin_pref_names.h" @@ -30,7 +29,6 @@ SigninClient* client, ProfileOAuth2TokenService* token_service, AccountTrackerService* account_tracker_service, - GaiaCookieManagerService* cookie_manager_service, signin::AccountConsistencyMethod account_consistency) : client_(client), token_service_(token_service), @@ -251,6 +249,27 @@ } #if !defined(OS_CHROMEOS) +void SigninManagerBase::SignIn(const std::string& username) { + AccountInfo info = + account_tracker_service()->FindAccountInfoByEmail(username); + DCHECK(!info.gaia.empty()); + DCHECK(!info.email.empty()); + + bool reauth_in_progress = IsAuthenticated(); + + signin_client()->GetPrefs()->SetInt64( + prefs::kSignedInTime, + base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds()); + + SetAuthenticatedAccountInfo(info.gaia, info.email); + + if (!reauth_in_progress && observer_ != nullptr) + observer_->GoogleSigninSucceeded(GetAuthenticatedAccountInfo()); + + signin_metrics::LogSigninProfile(signin_client()->IsFirstRun(), + signin_client()->GetInstallDate()); +} + void SigninManagerBase::SignOut( signin_metrics::ProfileSignout signout_source_metric, signin_metrics::SignoutDelete signout_delete_metric) {
diff --git a/components/signin/core/browser/signin_manager_base.h b/components/signin/core/browser/signin_manager_base.h index 9297ca09..6ae447f6 100644 --- a/components/signin/core/browser/signin_manager_base.h +++ b/components/signin/core/browser/signin_manager_base.h
@@ -39,7 +39,6 @@ #include "google_apis/gaia/google_service_auth_error.h" class AccountTrackerService; -class GaiaCookieManagerService; class PrefRegistrySimple; class PrefService; class ProfileOAuth2TokenService; @@ -85,7 +84,6 @@ SigninManagerBase(SigninClient* client, ProfileOAuth2TokenService* token_service, AccountTrackerService* account_tracker_service, - GaiaCookieManagerService* cookie_manager_service, signin::AccountConsistencyMethod account_consistency); #if !defined(OS_CHROMEOS) public: @@ -147,6 +145,15 @@ void SetObserver(Observer* observer); void ClearObserver(); + // Signin API surfaces. Not used on ChromeOS. + // TODO(https://crbug.com/814787): Go through this API to set the primary + // account on ChromeOS. +#if !defined(OS_CHROMEOS) + // Signs a user in. SigninManager assumes that |username| can be used to look + // up the corresponding account_id and gaia_id for this email. + void SignIn(const std::string& username); +#endif + // Signout API surfaces (not supported on ChromeOS, where signout is not // permitted). #if !defined(OS_CHROMEOS)
diff --git a/components/signin/core/browser/signin_manager_unittest.cc b/components/signin/core/browser/signin_manager_unittest.cc index f6f77f7..c3ca8c9 100644 --- a/components/signin/core/browser/signin_manager_unittest.cc +++ b/components/signin/core/browser/signin_manager_unittest.cc
@@ -23,7 +23,6 @@ #include "components/signin/core/browser/account_fetcher_service.h" #include "components/signin/core/browser/account_tracker_service.h" #include "components/signin/core/browser/device_id_helper.h" -#include "components/signin/core/browser/gaia_cookie_manager_service.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_pref_names.h" #include "components/signin/core/browser/test_signin_client.h" @@ -63,7 +62,6 @@ : test_signin_client_(&user_prefs_), token_service_(&user_prefs_, std::make_unique<FakeOAuth2TokenServiceDelegate>()), - cookie_manager_service_(&token_service_, &test_signin_client_), account_consistency_(signin::AccountConsistencyMethod::kDisabled) { AccountFetcherService::RegisterPrefs(user_prefs_.registry()); AccountTrackerService::RegisterPrefs(user_prefs_.registry()); @@ -82,7 +80,6 @@ } token_service_.Shutdown(); test_signin_client_.Shutdown(); - cookie_manager_service_.Shutdown(); account_tracker_.Shutdown(); account_fetcher_.Shutdown(); } @@ -107,7 +104,7 @@ DCHECK(!manager_); manager_ = std::make_unique<SigninManager>( &test_signin_client_, &token_service_, &account_tracker_, - &cookie_manager_service_, account_consistency_); + account_consistency_); manager_->Initialize(&local_state_); manager_->SetObserver(&test_observer_); } @@ -137,7 +134,6 @@ TestSigninClient test_signin_client_; ProfileOAuth2TokenService token_service_; AccountTrackerService account_tracker_; - GaiaCookieManagerService cookie_manager_service_; AccountFetcherService account_fetcher_; std::unique_ptr<SigninManager> manager_; TestSigninManagerObserver test_observer_;
diff --git a/components/sync/driver/non_ui_syncable_service_based_model_type_controller.cc b/components/sync/driver/non_ui_syncable_service_based_model_type_controller.cc index 68fe1d4..c480da6 100644 --- a/components/sync/driver/non_ui_syncable_service_based_model_type_controller.cc +++ b/components/sync/driver/non_ui_syncable_service_based_model_type_controller.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/bind.h" +#include "base/memory/weak_ptr.h" #include "components/sync/model_impl/client_tag_based_model_type_processor.h" #include "components/sync/model_impl/proxy_model_type_controller_delegate.h" #include "components/sync/model_impl/syncable_service_based_bridge.h" @@ -16,49 +17,64 @@ namespace { // Helper object that allows constructing and destructing the -// SyncableServiceBasedBridge lazily and on the model thread. -class LazyBridgeBuilder { +// SyncableServiceBasedBridge on the model thread. +class BridgeBuilder { public: - LazyBridgeBuilder( + BridgeBuilder( ModelType type, OnceModelTypeStoreFactory store_factory, NonUiSyncableServiceBasedModelTypeController::SyncableServiceProvider syncable_service_provider, const base::RepeatingClosure& dump_stack, scoped_refptr<base::SequencedTaskRunner> task_runner) - : type_(type), - store_factory_(std::move(store_factory)), - syncable_service_provider_(std::move(syncable_service_provider)), - dump_stack_(dump_stack), - bridge_(nullptr, base::OnTaskRunnerDeleter(std::move(task_runner))) { - DCHECK(store_factory_); - DCHECK(syncable_service_provider_); + : task_runner_(task_runner), + bridge_(nullptr, base::OnTaskRunnerDeleter(task_runner)), + weak_ptr_factory_(this) { + DCHECK(store_factory); + DCHECK(syncable_service_provider); + + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&BridgeBuilder::BuildBridgeDelegate, + weak_ptr_factory_.GetWeakPtr(), type, + std::move(store_factory), + std::move(syncable_service_provider), dump_stack)); } - base::WeakPtr<ModelTypeControllerDelegate> BuildOrGetBridgeDelegate() { - if (!bridge_) { - base::WeakPtr<SyncableService> syncable_service = - std::move(syncable_service_provider_).Run(); - DCHECK(syncable_service); - // std::make_unique() avoided here due to custom deleter. - bridge_.reset(new SyncableServiceBasedBridge( - type_, std::move(store_factory_), - std::make_unique<ClientTagBasedModelTypeProcessor>(type_, - dump_stack_), - syncable_service.get())); - } + base::WeakPtr<ModelTypeControllerDelegate> GetBridgeDelegate() { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + DCHECK(bridge_); return bridge_->change_processor()->GetControllerDelegate(); } private: - const ModelType type_; - OnceModelTypeStoreFactory store_factory_; - NonUiSyncableServiceBasedModelTypeController::SyncableServiceProvider - syncable_service_provider_; - const base::RepeatingClosure dump_stack_; + void BuildBridgeDelegate( + ModelType type, + OnceModelTypeStoreFactory store_factory, + NonUiSyncableServiceBasedModelTypeController::SyncableServiceProvider + syncable_service_provider, + const base::RepeatingClosure& dump_stack) { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + DCHECK(!bridge_); + + base::WeakPtr<SyncableService> syncable_service = + std::move(syncable_service_provider).Run(); + // |syncable_service| can be null in tests. + if (syncable_service) { + // std::make_unique() avoided here due to custom deleter. + bridge_.reset(new SyncableServiceBasedBridge( + type, std::move(store_factory), + std::make_unique<ClientTagBasedModelTypeProcessor>(type, dump_stack), + syncable_service.get())); + } + } + + scoped_refptr<base::SequencedTaskRunner> task_runner_; std::unique_ptr<ModelTypeSyncBridge, base::OnTaskRunnerDeleter> bridge_; - DISALLOW_COPY_AND_ASSIGN(LazyBridgeBuilder); + base::WeakPtrFactory<BridgeBuilder> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BridgeBuilder); }; } // namespace @@ -74,8 +90,8 @@ type, std::make_unique<ProxyModelTypeControllerDelegate>( task_runner, - base::BindRepeating(&LazyBridgeBuilder::BuildOrGetBridgeDelegate, - std::make_unique<LazyBridgeBuilder>( + base::BindRepeating(&BridgeBuilder::GetBridgeDelegate, + std::make_unique<BridgeBuilder>( type, std::move(store_factory), std::move(syncable_service_provider),
diff --git a/components/sync/driver/sync_session_durations_metrics_recorder.h b/components/sync/driver/sync_session_durations_metrics_recorder.h index f4860817..b69ed49 100644 --- a/components/sync/driver/sync_session_durations_metrics_recorder.h +++ b/components/sync/driver/sync_session_durations_metrics_recorder.h
@@ -20,8 +20,7 @@ // Tracks the active browsing time that the user spends signed in and/or syncing // as fraction of their total browsing time. class SyncSessionDurationsMetricsRecorder - : public GaiaCookieManagerService::Observer, - public syncer::SyncServiceObserver, + : public syncer::SyncServiceObserver, public identity::IdentityManager::Observer { public: // Callers must ensure that the parameters outlive this object.
diff --git a/components/sync/driver/syncable_service_based_model_type_controller.cc b/components/sync/driver/syncable_service_based_model_type_controller.cc index d90bbe3..4e90a70 100644 --- a/components/sync/driver/syncable_service_based_model_type_controller.cc +++ b/components/sync/driver/syncable_service_based_model_type_controller.cc
@@ -17,63 +17,56 @@ // reference to SyncableService in a lazy way, which is convenient for tests. class ControllerDelegate : public ModelTypeControllerDelegate { public: - using SyncableServiceProvider = - SyncableServiceBasedModelTypeController::SyncableServiceProvider; - ControllerDelegate(ModelType type, OnceModelTypeStoreFactory store_factory, - SyncableServiceProvider syncable_service_provider, + base::WeakPtr<SyncableService> syncable_service, const base::RepeatingClosure& dump_stack) : type_(type), store_factory_(std::move(store_factory)), - syncable_service_provider_(std::move(syncable_service_provider)), dump_stack_(dump_stack) { DCHECK(store_factory_); - DCHECK(syncable_service_provider_); - } - ~ControllerDelegate() override {} - - void OnSyncStarting(const DataTypeActivationRequest& request, - StartCallback callback) override { - BuildOrGetBridgeDelegate()->OnSyncStarting(request, std::move(callback)); - } - - void OnSyncStopping(SyncStopMetadataFate metadata_fate) override { - BuildOrGetBridgeDelegate()->OnSyncStopping(metadata_fate); - } - - void GetAllNodesForDebugging(AllNodesCallback callback) override { - BuildOrGetBridgeDelegate()->GetAllNodesForDebugging(std::move(callback)); - } - - void GetStatusCountersForDebugging(StatusCountersCallback callback) override { - BuildOrGetBridgeDelegate()->GetStatusCountersForDebugging( - std::move(callback)); - } - - void RecordMemoryUsageAndCountsHistograms() override { - BuildOrGetBridgeDelegate()->RecordMemoryUsageAndCountsHistograms(); - } - - private: - ModelTypeControllerDelegate* BuildOrGetBridgeDelegate() { - if (!bridge_) { - base::WeakPtr<SyncableService> syncable_service = - std::move(syncable_service_provider_).Run(); - DCHECK(syncable_service); + // The |syncable_service| can be null in tests. + if (syncable_service) { bridge_ = std::make_unique<SyncableServiceBasedBridge>( type_, std::move(store_factory_), std::make_unique<ClientTagBasedModelTypeProcessor>(type_, dump_stack_), syncable_service.get()); } + } + + ~ControllerDelegate() override {} + + void OnSyncStarting(const DataTypeActivationRequest& request, + StartCallback callback) override { + GetBridgeDelegate()->OnSyncStarting(request, std::move(callback)); + } + + void OnSyncStopping(SyncStopMetadataFate metadata_fate) override { + GetBridgeDelegate()->OnSyncStopping(metadata_fate); + } + + void GetAllNodesForDebugging(AllNodesCallback callback) override { + GetBridgeDelegate()->GetAllNodesForDebugging(std::move(callback)); + } + + void GetStatusCountersForDebugging(StatusCountersCallback callback) override { + GetBridgeDelegate()->GetStatusCountersForDebugging(std::move(callback)); + } + + void RecordMemoryUsageAndCountsHistograms() override { + GetBridgeDelegate()->RecordMemoryUsageAndCountsHistograms(); + } + + private: + ModelTypeControllerDelegate* GetBridgeDelegate() { + DCHECK(bridge_); return bridge_->change_processor()->GetControllerDelegate().get(); } const ModelType type_; OnceModelTypeStoreFactory store_factory_; - SyncableServiceProvider syncable_service_provider_; const base::RepeatingClosure dump_stack_; std::unique_ptr<ModelTypeSyncBridge> bridge_; @@ -86,14 +79,14 @@ SyncableServiceBasedModelTypeController( ModelType type, OnceModelTypeStoreFactory store_factory, - SyncableServiceProvider syncable_service_provider, + base::WeakPtr<SyncableService> syncable_service, const base::RepeatingClosure& dump_stack) - : ModelTypeController(type, - std::make_unique<ControllerDelegate>( - type, - std::move(store_factory), - std::move(syncable_service_provider), - dump_stack)) {} + : ModelTypeController( + type, + std::make_unique<ControllerDelegate>(type, + std::move(store_factory), + syncable_service, + dump_stack)) {} SyncableServiceBasedModelTypeController:: ~SyncableServiceBasedModelTypeController() {}
diff --git a/components/sync/driver/syncable_service_based_model_type_controller.h b/components/sync/driver/syncable_service_based_model_type_controller.h index 6daf3ff..f66eab2 100644 --- a/components/sync/driver/syncable_service_based_model_type_controller.h +++ b/components/sync/driver/syncable_service_based_model_type_controller.h
@@ -7,7 +7,6 @@ #include <memory> -#include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "components/sync/base/model_type.h" @@ -22,13 +21,11 @@ // a non-blocking datatype (USS), for datatypes living in the UI thread. class SyncableServiceBasedModelTypeController : public ModelTypeController { public: - using SyncableServiceProvider = - base::OnceCallback<base::WeakPtr<syncer::SyncableService>()>; - + // |syncable_service| may be null in tests. SyncableServiceBasedModelTypeController( ModelType type, OnceModelTypeStoreFactory store_factory, - SyncableServiceProvider syncable_service_provider, + base::WeakPtr<SyncableService> syncable_service, const base::RepeatingClosure& dump_stack); ~SyncableServiceBasedModelTypeController() override;
diff --git a/components/sync/model_impl/client_tag_based_model_type_processor.cc b/components/sync/model_impl/client_tag_based_model_type_processor.cc index 2d4da9cd..8541725 100644 --- a/components/sync/model_impl/client_tag_based_model_type_processor.cc +++ b/components/sync/model_impl/client_tag_based_model_type_processor.cc
@@ -44,13 +44,19 @@ base::Time remote_modification_time) { const base::TimeDelta latency = base::Time::Now() - remote_modification_time; - UMA_HISTOGRAM_LONG_TIMES("Sync.NonReflectionUpdateFreshnessPossiblySkewed", - latency); + UMA_HISTOGRAM_CUSTOM_TIMES("Sync.NonReflectionUpdateFreshnessPossiblySkewed2", + latency, + /*min=*/base::TimeDelta::FromMilliseconds(100), + /*max=*/base::TimeDelta::FromDays(7), + /*bucket_count=*/50); - base::UmaHistogramLongTimes( - std::string("Sync.NonReflectionUpdateFreshnessPossiblySkewed.") + + base::UmaHistogramCustomTimes( + std::string("Sync.NonReflectionUpdateFreshnessPossiblySkewed2.") + ModelTypeToHistogramSuffix(type), - latency); + latency, + /*min=*/base::TimeDelta::FromMilliseconds(100), + /*max=*/base::TimeDelta::FromDays(7), + /*bucket_count=*/50); } } // namespace
diff --git a/components/sync/model_impl/syncable_service_based_bridge.cc b/components/sync/model_impl/syncable_service_based_bridge.cc index 313451e..aadefe8e 100644 --- a/components/sync/model_impl/syncable_service_based_bridge.cc +++ b/components/sync/model_impl/syncable_service_based_bridge.cc
@@ -283,11 +283,13 @@ : ModelTypeSyncBridge(std::move(change_processor)), type_(type), syncable_service_(syncable_service), - store_factory_(std::move(store_factory)), syncable_service_started_(false), weak_ptr_factory_(this) { - DCHECK(store_factory_); DCHECK(syncable_service_); + + std::move(store_factory) + .Run(type_, base::BindOnce(&SyncableServiceBasedBridge::OnStoreCreated, + weak_ptr_factory_.GetWeakPtr())); } SyncableServiceBasedBridge::~SyncableServiceBasedBridge() { @@ -305,25 +307,6 @@ return ModelTypeStore::WriteBatch::CreateMetadataChangeList(); } -void SyncableServiceBasedBridge::OnSyncStarting( - const DataTypeActivationRequest& request) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(!syncable_service_started_); - - if (!store_factory_) { - // Sync was have been started earlier, and |store_| is guaranteed to be - // initialized because stopping of the datatype cannot be completed before - // ModelReadyToSync(). - DCHECK(store_); - ReportErrorIfSet(MaybeStartSyncableService()); - return; - } - - syncable_service_->WaitUntilReadyToSync( - base::BindOnce(&SyncableServiceBasedBridge::OnSyncableServiceReady, - weak_ptr_factory_.GetWeakPtr())); -} - base::Optional<ModelError> SyncableServiceBasedBridge::MergeSyncData( std::unique_ptr<MetadataChangeList> metadata_change_list, EntityChangeList entity_change_list) { @@ -337,10 +320,9 @@ std::move(entity_change_list)); // We ignore the output of previous call of StoreAndConvertRemoteChanges() at - // this point and let MaybeStartSyncableService() read from - // |in_memory_store_|, which has been updated above as part of - // StoreAndConvertRemoteChanges(). - return MaybeStartSyncableService(); + // this point and let StartSyncableService() read from |in_memory_store_|, + // which has been updated above as part of StoreAndConvertRemoteChanges(). + return StartSyncableService(); } base::Optional<ModelError> SyncableServiceBasedBridge::ApplySyncChanges( @@ -382,6 +364,7 @@ std::string SyncableServiceBasedBridge::GetClientTag( const EntityData& entity_data) { + // Not supported as per SupportsGetClientTag(). NOTREACHED(); return std::string(); } @@ -425,11 +408,15 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(store_); - if (delete_metadata_change_list) { - in_memory_store_.clear(); - store_->DeleteAllDataAndMetadata(base::DoNothing()); + // If Sync is being stopped only temporarily (i.e. we want to keep tracking + // metadata), then there's nothing to do here. + if (!delete_metadata_change_list) { + return; } + in_memory_store_.clear(); + store_->DeleteAllDataAndMetadata(base::DoNothing()); + if (syncable_service_started_) { syncable_service_->StopSyncing(type_); syncable_service_started_ = false; @@ -453,15 +440,6 @@ other); } -void SyncableServiceBasedBridge::OnSyncableServiceReady() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - std::move(store_factory_) - .Run(type_, base::BindOnce(&SyncableServiceBasedBridge::OnStoreCreated, - weak_ptr_factory_.GetWeakPtr())); - DCHECK(!store_factory_); -} - void SyncableServiceBasedBridge::OnStoreCreated( const base::Optional<ModelError>& error, std::unique_ptr<ModelTypeStore> store) { @@ -515,6 +493,16 @@ return; } + syncable_service_->WaitUntilReadyToSync(base::BindOnce( + &SyncableServiceBasedBridge::OnSyncableServiceReady, + weak_ptr_factory_.GetWeakPtr(), std::move(metadata_batch))); +} + +void SyncableServiceBasedBridge::OnSyncableServiceReady( + std::unique_ptr<MetadataBatch> metadata_batch) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(!syncable_service_started_); + // Guard against inconsistent state, and recover from it by starting from // scratch, which will cause the eventual refetching of all entities from the // server. @@ -529,19 +517,19 @@ change_processor()->ModelReadyToSync(std::move(metadata_batch)); - ReportErrorIfSet(MaybeStartSyncableService()); + // If sync was previously enabled according to the loaded metadata, then + // immediately start the SyncableService to track as many local changes as + // possible (regardless of whether sync actually starts or not). Otherwise, + // the SyncableService will be started from MergeSyncData(). + if (change_processor()->IsTrackingMetadata()) { + ReportErrorIfSet(StartSyncableService()); + } } -base::Optional<ModelError> -SyncableServiceBasedBridge::MaybeStartSyncableService() { - DCHECK(!syncable_service_started_); +base::Optional<ModelError> SyncableServiceBasedBridge::StartSyncableService() { DCHECK(store_); - - // If sync wasn't enabled according to the loaded metadata, let's wait until - // MergeSyncData() is called before starting the SyncableService. - if (!change_processor()->IsTrackingMetadata()) { - return base::nullopt; - } + DCHECK(!syncable_service_started_); + DCHECK(change_processor()->IsTrackingMetadata()); const base::TimeTicks start_time = base::TimeTicks::Now();
diff --git a/components/sync/model_impl/syncable_service_based_bridge.h b/components/sync/model_impl/syncable_service_based_bridge.h index 3a1a64a..514d92c 100644 --- a/components/sync/model_impl/syncable_service_based_bridge.h +++ b/components/sync/model_impl/syncable_service_based_bridge.h
@@ -47,7 +47,6 @@ ~SyncableServiceBasedBridge() override; // ModelTypeSyncBridge implementation. - void OnSyncStarting(const DataTypeActivationRequest& request) override; std::unique_ptr<MetadataChangeList> CreateMetadataChangeList() override; base::Optional<ModelError> MergeSyncData( std::unique_ptr<MetadataChangeList> metadata_change_list, @@ -76,14 +75,14 @@ ModelTypeChangeProcessor* other); private: - void OnSyncableServiceReady(); void OnStoreCreated(const base::Optional<ModelError>& error, std::unique_ptr<ModelTypeStore> store); void OnReadAllDataForInit(std::unique_ptr<InMemoryStore> in_memory_store, const base::Optional<ModelError>& error); void OnReadAllMetadataForInit(const base::Optional<ModelError>& error, std::unique_ptr<MetadataBatch> metadata_batch); - base::Optional<ModelError> MaybeStartSyncableService() WARN_UNUSED_RESULT; + void OnSyncableServiceReady(std::unique_ptr<MetadataBatch> metadata_batch); + base::Optional<ModelError> StartSyncableService() WARN_UNUSED_RESULT; SyncChangeList StoreAndConvertRemoteChanges( std::unique_ptr<MetadataChangeList> metadata_change_list, EntityChangeList input_entity_change_list); @@ -101,7 +100,6 @@ const ModelType type_; SyncableService* const syncable_service_; - OnceModelTypeStoreFactory store_factory_; std::unique_ptr<ModelTypeStore> store_; bool syncable_service_started_;
diff --git a/components/sync/model_impl/syncable_service_based_bridge_unittest.cc b/components/sync/model_impl/syncable_service_based_bridge_unittest.cc index 3fa2e26..155e582 100644 --- a/components/sync/model_impl/syncable_service_based_bridge_unittest.cc +++ b/components/sync/model_impl/syncable_service_based_bridge_unittest.cc
@@ -31,15 +31,12 @@ namespace { using testing::_; -using testing::DoAll; using testing::ElementsAre; using testing::Invoke; using testing::IsEmpty; -using testing::IsNull; using testing::NotNull; using testing::Pair; using testing::Return; -using testing::SaveArg; const ModelType kModelType = PREFERENCES; @@ -227,22 +224,21 @@ // Bridge initialization alone, without sync itself starting, should not // issue calls to the syncable service. InitializeBridge(); - EXPECT_FALSE(syncable_service_ready_cb); + + EXPECT_CALL(syncable_service_, WaitUntilReadyToSync(_)); + // Required to initialize the store. + base::RunLoop().RunUntilIdle(); + ASSERT_TRUE(syncable_service_ready_cb); // Sync itself starting should wait until the syncable service becomes ready, // before issuing any other call (e.g. MergeDataAndStartSyncing()). - EXPECT_CALL(syncable_service_, WaitUntilReadyToSync(_)); real_processor_->OnSyncStarting(GetTestActivationRequest(), base::DoNothing()); - ASSERT_TRUE(syncable_service_ready_cb); // When the SyncableService gets ready, the bridge should propagate this // information to the processor. EXPECT_CALL(mock_processor_, ModelReadyToSync(_)); std::move(syncable_service_ready_cb).Run(); - - // Required to initialize the store. - base::RunLoop().RunUntilIdle(); } TEST_F(SyncableServiceBasedBridgeTest, @@ -252,7 +248,7 @@ worker_->UpdateFromServer(); EXPECT_CALL(syncable_service_, StopSyncing(kModelType)); - real_processor_->OnSyncStopping(KEEP_METADATA); + real_processor_->OnSyncStopping(CLEAR_METADATA); EXPECT_CALL(syncable_service_, StopSyncing(_)).Times(0); ShutdownBridge(); @@ -304,18 +300,26 @@ } TEST_F(SyncableServiceBasedBridgeTest, - ShouldStartSyncingWithPreviousDirectoryDataWithoutRestart) { + ShouldKeepSyncingWhenSyncStoppedTemporarily) { InitializeBridge(); StartSyncing(); worker_->UpdateFromServer(kClientTagHash, GetTestSpecifics("name1")); + + // Stopping Sync temporarily (KEEP_METADATA) should *not* result in the + // SyncableService being stopped. + EXPECT_CALL(syncable_service_, StopSyncing(_)).Times(0); real_processor_->OnSyncStopping(KEEP_METADATA); EXPECT_THAT(GetAllData(), ElementsAre(Pair(kClientTagHash, _))); - EXPECT_CALL(syncable_service_, - MergeDataAndStartSyncing( - kModelType, ElementsAre(SyncDataRemoteMatches("name1")), - NotNull(), NotNull())); + // Since the SyncableService wasn't stopped, it shouldn't get restarted either + // when Sync starts up again. + EXPECT_CALL(syncable_service_, MergeDataAndStartSyncing(_, _, _, _)).Times(0); StartSyncing(); + + // Finally, shutting down the bridge (during browser shutdown) should also + // stop the SyncableService. + EXPECT_CALL(syncable_service_, StopSyncing(kModelType)); + ShutdownBridge(); } TEST_F(SyncableServiceBasedBridgeTest,
diff --git a/components/sync_preferences/pref_model_associator.cc b/components/sync_preferences/pref_model_associator.cc index d3e8110..66dec66 100644 --- a/components/sync_preferences/pref_model_associator.cc +++ b/components/sync_preferences/pref_model_associator.cc
@@ -171,7 +171,7 @@ void PrefModelAssociator::WaitUntilReadyToSync(base::OnceClosure done) { // Prefs are loaded very early during profile initialization. - DCHECK_NE(pref_service_->GetAllPrefStoresInitializationStatus(), + DCHECK_NE(pref_service_->GetInitializationStatus(), PrefService::INITIALIZATION_STATUS_WAITING); std::move(done).Run(); }
diff --git a/components/sync_sessions/favicon_cache.cc b/components/sync_sessions/favicon_cache.cc index 004e626d..4a36980 100644 --- a/components/sync_sessions/favicon_cache.cc +++ b/components/sync_sessions/favicon_cache.cc
@@ -238,7 +238,8 @@ FaviconCache::~FaviconCache() {} void FaviconCache::WaitUntilReadyToSync(base::OnceClosure done) { - if (history_service_->backend_loaded()) { + // |history_service_| can be null in tests. In that case, no point in waiting. + if (!history_service_ || history_service_->backend_loaded()) { std::move(done).Run(); } else { // Wait until HistoryService's backend loads, reported via
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.close_incognito_tabs_hover_incognito_browser_ui.Pixel_XL-25.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.close_incognito_tabs_hover_incognito_browser_ui.Pixel_XL-25.png.sha1 index 062442b..625cc1f 100644 --- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.close_incognito_tabs_hover_incognito_browser_ui.Pixel_XL-25.png.sha1 +++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.close_incognito_tabs_hover_incognito_browser_ui.Pixel_XL-25.png.sha1
@@ -1 +1 @@ -9dd756a65b2bb331409e1ab968b13641a6486bfa \ No newline at end of file +20ef25e0c4454df34f07331a5ef397bf987efd0f \ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.close_incognito_tabs_hover_incognito_browser_ui.Pixel_XL-26.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.close_incognito_tabs_hover_incognito_browser_ui.Pixel_XL-26.png.sha1 index 58de354b..90dbf3f 100644 --- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.close_incognito_tabs_hover_incognito_browser_ui.Pixel_XL-26.png.sha1 +++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.close_incognito_tabs_hover_incognito_browser_ui.Pixel_XL-26.png.sha1
@@ -1 +1 @@ -fa59896eefa99b5a3ffd60986c9f50e607d727f1 \ No newline at end of file +80e942fa06f0518c6ca00909cdb88093f87fbb1e \ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.forward_button_hover_browser_ui.Pixel_XL-25.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.forward_button_hover_browser_ui.Pixel_XL-25.png.sha1 index 63f38a0..ec8e36e 100644 --- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.forward_button_hover_browser_ui.Pixel_XL-25.png.sha1 +++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.forward_button_hover_browser_ui.Pixel_XL-25.png.sha1
@@ -1 +1 @@ -023f43d2fd3843654911a570a8493d10ced14118 \ No newline at end of file +136f44df7c66102775da397441f0fbe797336d4a \ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.forward_button_hover_browser_ui.Pixel_XL-26.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.forward_button_hover_browser_ui.Pixel_XL-26.png.sha1 index 17630ee2..ad2972a 100644 --- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.forward_button_hover_browser_ui.Pixel_XL-26.png.sha1 +++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.forward_button_hover_browser_ui.Pixel_XL-26.png.sha1
@@ -1 +1 @@ -f699f6cf9f3727a39598a3d2cb890110e30d4273 \ No newline at end of file +d05218e88bf24a6b4479563c0c4b22f26e8f94a5 \ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.forward_button_hover_incognito_browser_ui.Pixel_XL-25.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.forward_button_hover_incognito_browser_ui.Pixel_XL-25.png.sha1 index 75e2653..bc5f351a 100644 --- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.forward_button_hover_incognito_browser_ui.Pixel_XL-25.png.sha1 +++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.forward_button_hover_incognito_browser_ui.Pixel_XL-25.png.sha1
@@ -1 +1 @@ -fa9a5e738eeb4fa451153811027602fcefd64498 \ No newline at end of file +048310a22b411d78ed175077d6eda9b41d398e19 \ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.forward_button_hover_incognito_browser_ui.Pixel_XL-26.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.forward_button_hover_incognito_browser_ui.Pixel_XL-26.png.sha1 index 09c5cb9..d678c24 100644 --- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.forward_button_hover_incognito_browser_ui.Pixel_XL-26.png.sha1 +++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.forward_button_hover_incognito_browser_ui.Pixel_XL-26.png.sha1
@@ -1 +1 @@ -e6fbc61b2a194b313e285c3f28c5e2c5d7fba366 \ No newline at end of file +ed7b6698e44c9250b8e18d2ca6324e7ad3d1e609 \ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.new_incognito_tab_hover_browser_ui.Pixel_XL-25.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.new_incognito_tab_hover_browser_ui.Pixel_XL-25.png.sha1 index d0536e7..8c9085e 100644 --- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.new_incognito_tab_hover_browser_ui.Pixel_XL-25.png.sha1 +++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.new_incognito_tab_hover_browser_ui.Pixel_XL-25.png.sha1
@@ -1 +1 @@ -d06ba3194aae828b30f09436a8f1d099e4c03551 \ No newline at end of file +5e8f35695f82f98297cc4351eb43d68f9f92ff38 \ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.new_incognito_tab_hover_browser_ui.Pixel_XL-26.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.new_incognito_tab_hover_browser_ui.Pixel_XL-26.png.sha1 index ca29df6..3338514 100644 --- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.new_incognito_tab_hover_browser_ui.Pixel_XL-26.png.sha1 +++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.new_incognito_tab_hover_browser_ui.Pixel_XL-26.png.sha1
@@ -1 +1 @@ -d361f9d0784f3a77f7047ff9055bf5916f0174eb \ No newline at end of file +b93542ff3f1b6eb511eb53841c4196a0529b66ba \ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.overflow_menu_visible_browser_ui.Pixel_XL-25.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.overflow_menu_visible_browser_ui.Pixel_XL-25.png.sha1 index 9dc2b93..568346d 100644 --- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.overflow_menu_visible_browser_ui.Pixel_XL-25.png.sha1 +++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.overflow_menu_visible_browser_ui.Pixel_XL-25.png.sha1
@@ -1 +1 @@ -115da8f258062830b8b861cf0ffa8c8d101b71ba \ No newline at end of file +06260f4b7b4fe02102c9a687d90d08f25364e3a9 \ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.overflow_menu_visible_browser_ui.Pixel_XL-26.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.overflow_menu_visible_browser_ui.Pixel_XL-26.png.sha1 index 65ac77f..7fb7a23a 100644 --- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.overflow_menu_visible_browser_ui.Pixel_XL-26.png.sha1 +++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.overflow_menu_visible_browser_ui.Pixel_XL-26.png.sha1
@@ -1 +1 @@ -0dfae90e612afa2537605da7fb73e09fbea6149c \ No newline at end of file +b4aa286e7056050761ea964c7107e2607af8b50e \ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reload_button_hover_browser_ui.Pixel_XL-25.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reload_button_hover_browser_ui.Pixel_XL-25.png.sha1 index e6a9898..ad85b463b 100644 --- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reload_button_hover_browser_ui.Pixel_XL-25.png.sha1 +++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reload_button_hover_browser_ui.Pixel_XL-25.png.sha1
@@ -1 +1 @@ -5e5b493ef51a12b2a790a3d365ca0731b713aeff \ No newline at end of file +f189360f70397d81fd50b3f7bd6ef43316a42014 \ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reload_button_hover_browser_ui.Pixel_XL-26.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reload_button_hover_browser_ui.Pixel_XL-26.png.sha1 index c7ab849..1c1af10 100644 --- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reload_button_hover_browser_ui.Pixel_XL-26.png.sha1 +++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reload_button_hover_browser_ui.Pixel_XL-26.png.sha1
@@ -1 +1 @@ -752f6aac5ec25c566dfb4c7e0cbd70a6279c1a59 \ No newline at end of file +1745cab5afd4a1c2bdbeded28e229ce17bf480e3 \ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reload_button_hover_incognito_browser_ui.Pixel_XL-25.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reload_button_hover_incognito_browser_ui.Pixel_XL-25.png.sha1 index fa95eba..6a3ae04c 100644 --- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reload_button_hover_incognito_browser_ui.Pixel_XL-25.png.sha1 +++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reload_button_hover_incognito_browser_ui.Pixel_XL-25.png.sha1
@@ -1 +1 @@ -7da4a86a2148a744b2d2bec26a2dfa5aec490a5f \ No newline at end of file +02cd4997198ed6c3a6da558c89a9ddd8862010dc \ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reload_button_hover_incognito_browser_ui.Pixel_XL-26.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reload_button_hover_incognito_browser_ui.Pixel_XL-26.png.sha1 index f8ca74a..6ee7744 100644 --- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reload_button_hover_incognito_browser_ui.Pixel_XL-26.png.sha1 +++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reload_button_hover_incognito_browser_ui.Pixel_XL-26.png.sha1
@@ -1 +1 @@ -b94d691b62528b513f4d10256f0c1edaebc0be85 \ No newline at end of file +c45ec31b360af756412cfcd8880606bbb7ee469f \ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.repositioned_overflow_menu.Pixel_XL-25.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.repositioned_overflow_menu.Pixel_XL-25.png.sha1 index 6ed90228..daf7d5e7 100644 --- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.repositioned_overflow_menu.Pixel_XL-25.png.sha1 +++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.repositioned_overflow_menu.Pixel_XL-25.png.sha1
@@ -1 +1 @@ -69c9176c3446e13cbef1da62a0662d149c9b325a \ No newline at end of file +d1cbcc0fadbc33ee721228f28dff50ea1d4c3d05 \ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.repositioned_overflow_menu.Pixel_XL-26.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.repositioned_overflow_menu.Pixel_XL-26.png.sha1 index 52c2a865..9e02b0b 100644 --- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.repositioned_overflow_menu.Pixel_XL-26.png.sha1 +++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.repositioned_overflow_menu.Pixel_XL-26.png.sha1
@@ -1 +1 @@ -76a094c08e36daf87c632f1cef8ed6e66e63e07a \ No newline at end of file +89766057cc26687587d89e576cbd166384252d53 \ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNavigationTest.navigation_buttons_back_enabled.Pixel_XL-25.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNavigationTest.navigation_buttons_back_enabled.Pixel_XL-25.png.sha1 index ca20a2e..5da5f52 100644 --- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNavigationTest.navigation_buttons_back_enabled.Pixel_XL-25.png.sha1 +++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNavigationTest.navigation_buttons_back_enabled.Pixel_XL-25.png.sha1
@@ -1 +1 @@ -0f9b558ecaac382f144cae2647579a597152b8a3 \ No newline at end of file +9450f2e125b5e04ee4463bcbc2dff8b8a102d9e6 \ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNavigationTest.navigation_buttons_back_enabled.Pixel_XL-26.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNavigationTest.navigation_buttons_back_enabled.Pixel_XL-26.png.sha1 index fb7c2f1..db587a6 100644 --- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNavigationTest.navigation_buttons_back_enabled.Pixel_XL-26.png.sha1 +++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNavigationTest.navigation_buttons_back_enabled.Pixel_XL-26.png.sha1
@@ -1 +1 @@ -e5fa46dc5e243ac8f164a8b12a077c0109a25c3e \ No newline at end of file +6e6f14ad097fa9095ac194ac5be19097429ccf79 \ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNavigationTest.navigation_buttons_both_disabled.Pixel_XL-25.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNavigationTest.navigation_buttons_both_disabled.Pixel_XL-25.png.sha1 index 1c202ad..277ab0b 100644 --- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNavigationTest.navigation_buttons_both_disabled.Pixel_XL-25.png.sha1 +++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNavigationTest.navigation_buttons_both_disabled.Pixel_XL-25.png.sha1
@@ -1 +1 @@ -67d5565b078f625bfcc6fa4d951529bd638922b2 \ No newline at end of file +a771e024aec046967ea08ec97f1968b7ff5e5230 \ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNavigationTest.navigation_buttons_both_disabled.Pixel_XL-26.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNavigationTest.navigation_buttons_both_disabled.Pixel_XL-26.png.sha1 index 65ac77f..7fb7a23a 100644 --- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNavigationTest.navigation_buttons_both_disabled.Pixel_XL-26.png.sha1 +++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNavigationTest.navigation_buttons_both_disabled.Pixel_XL-26.png.sha1
@@ -1 +1 @@ -0dfae90e612afa2537605da7fb73e09fbea6149c \ No newline at end of file +b4aa286e7056050761ea964c7107e2607af8b50e \ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNavigationTest.navigation_buttons_forward_enabled.Pixel_XL-25.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNavigationTest.navigation_buttons_forward_enabled.Pixel_XL-25.png.sha1 index 59a7316..f149bf53 100644 --- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNavigationTest.navigation_buttons_forward_enabled.Pixel_XL-25.png.sha1 +++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNavigationTest.navigation_buttons_forward_enabled.Pixel_XL-25.png.sha1
@@ -1 +1 @@ -a22df8a3582ec5f241ab5b2864cfad7385f4c3f6 \ No newline at end of file +c69ce2e9225ac8e2bef4c4d97435f57a32712a29 \ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNavigationTest.navigation_buttons_forward_enabled.Pixel_XL-26.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNavigationTest.navigation_buttons_forward_enabled.Pixel_XL-26.png.sha1 index 0e284c0..b1f6897 100644 --- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNavigationTest.navigation_buttons_forward_enabled.Pixel_XL-26.png.sha1 +++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNavigationTest.navigation_buttons_forward_enabled.Pixel_XL-26.png.sha1
@@ -1 +1 @@ -ed308dcd89ed718b2f4c607f5c8776fa9e3b9c0c \ No newline at end of file +497547d4e9aabe2ee4c2c0d0eac3a46a23ce3ebe \ No newline at end of file
diff --git a/content/browser/android/java/gin_java_bridge_message_filter.cc b/content/browser/android/java/gin_java_bridge_message_filter.cc index f4ce393d..c3802dc 100644 --- a/content/browser/android/java/gin_java_bridge_message_filter.cc +++ b/content/browser/android/java/gin_java_bridge_message_filter.cc
@@ -59,7 +59,8 @@ return handled; } -base::TaskRunner* GinJavaBridgeMessageFilter::OverrideTaskRunnerForMessage( +scoped_refptr<base::SequencedTaskRunner> +GinJavaBridgeMessageFilter::OverrideTaskRunnerForMessage( const IPC::Message& message) { // As the filter is only invoked for the messages of the particular class, // we can return the task runner unconditionally.
diff --git a/content/browser/android/java/gin_java_bridge_message_filter.h b/content/browser/android/java/gin_java_bridge_message_filter.h index 1847f24..b4232aab 100644 --- a/content/browser/android/java/gin_java_bridge_message_filter.h +++ b/content/browser/android/java/gin_java_bridge_message_filter.h
@@ -37,7 +37,7 @@ // BrowserMessageFilter void OnDestruct() const override; bool OnMessageReceived(const IPC::Message& message) override; - base::TaskRunner* OverrideTaskRunnerForMessage( + scoped_refptr<base::SequencedTaskRunner> OverrideTaskRunnerForMessage( const IPC::Message& message) override; // RenderProcessHostObserver
diff --git a/content/browser/android/java/java_bridge_thread.cc b/content/browser/android/java/java_bridge_thread.cc index d0d0381..8919e96 100644 --- a/content/browser/android/java/java_bridge_thread.cc +++ b/content/browser/android/java/java_bridge_thread.cc
@@ -40,8 +40,8 @@ } // static -base::TaskRunner* JavaBridgeThread::GetTaskRunner() { - return g_background_thread.Get().message_loop()->task_runner().get(); +scoped_refptr<base::SingleThreadTaskRunner> JavaBridgeThread::GetTaskRunner() { + return g_background_thread.Get().message_loop()->task_runner(); } } // namespace content
diff --git a/content/browser/android/java/java_bridge_thread.h b/content/browser/android/java/java_bridge_thread.h index 662f031..05334270 100644 --- a/content/browser/android/java/java_bridge_thread.h +++ b/content/browser/android/java/java_bridge_thread.h
@@ -6,10 +6,7 @@ #define CONTENT_BROWSER_ANDROID_JAVA_GIN_JAVA_JAVA_BRIDGE_THREAD_H_ #include "base/android/java_handler_thread.h" - -namespace base { -class TaskRunner; -} +#include "base/single_thread_task_runner.h" namespace content { @@ -21,7 +18,9 @@ ~JavaBridgeThread() override; static bool CurrentlyOn(); - static base::TaskRunner* GetTaskRunner(); + // TODO(altimin): Make it const scoped_refptr& after we support this + // which is blocked by revoming MessageLoop::SetTaskRunner. + static scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(); }; } // namespace content
diff --git a/content/browser/blob_storage/chrome_blob_storage_context.cc b/content/browser/blob_storage/chrome_blob_storage_context.cc index 94588aa..859cf37 100644 --- a/content/browser/blob_storage/chrome_blob_storage_context.cc +++ b/content/browser/blob_storage/chrome_blob_storage_context.cc
@@ -155,6 +155,11 @@ context_->mutable_memory_controller()->GetWeakPtr())); } +storage::BlobStorageContext* ChromeBlobStorageContext::context() const { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + return context_.get(); +} + std::unique_ptr<BlobHandle> ChromeBlobStorageContext::CreateMemoryBackedBlob( const char* data, size_t length,
diff --git a/content/browser/blob_storage/chrome_blob_storage_context.h b/content/browser/blob_storage/chrome_blob_storage_context.h index afd21be63..8353f2a 100644 --- a/content/browser/blob_storage/chrome_blob_storage_context.h +++ b/content/browser/blob_storage/chrome_blob_storage_context.h
@@ -57,7 +57,7 @@ void InitializeOnIOThread(base::FilePath blob_storage_dir, scoped_refptr<base::TaskRunner> file_task_runner); - storage::BlobStorageContext* context() const { return context_.get(); } + storage::BlobStorageContext* context() const; // Returns a NULL scoped_ptr on failure. std::unique_ptr<BlobHandle> CreateMemoryBackedBlob(
diff --git a/content/browser/frame_host/navigation_handle_impl.cc b/content/browser/frame_host/navigation_handle_impl.cc index 6bdd0a2..b6a3781 100644 --- a/content/browser/frame_host/navigation_handle_impl.cc +++ b/content/browser/frame_host/navigation_handle_impl.cc
@@ -403,10 +403,6 @@ return navigation_request_->common_params().base_url_for_data_url; } -NavigationData* NavigationHandleImpl::GetNavigationData() { - return navigation_data_.get(); -} - void NavigationHandleImpl::RegisterSubresourceOverride( mojom::TransferrableURLLoaderPtr transferrable_loader) { if (!transferrable_loader)
diff --git a/content/browser/frame_host/navigation_handle_impl.h b/content/browser/frame_host/navigation_handle_impl.h index 01c0439..6337d2c 100644 --- a/content/browser/frame_host/navigation_handle_impl.h +++ b/content/browser/frame_host/navigation_handle_impl.h
@@ -26,7 +26,6 @@ #include "content/browser/frame_host/render_frame_host_impl.h" #include "content/common/content_export.h" #include "content/public/browser/global_request_id.h" -#include "content/public/browser/navigation_data.h" #include "content/public/browser/navigation_throttle.h" #include "content/public/browser/navigation_type.h" #include "content/public/browser/restore_type.h" @@ -122,7 +121,6 @@ // deferring NavigationThrottle do the resuming. void CallResumeForTesting(); - NavigationData* GetNavigationData() override; void RegisterSubresourceOverride( mojom::TransferrableURLLoaderPtr transferrable_loader) override; @@ -187,13 +185,6 @@ // |state_| and inform the delegate. void ReadyToCommitNavigation(bool is_error); - // Called during commit. Takes ownership of the embedder's NavigationData - // instance. This NavigationData may have been cloned prior to being added - // here. - void set_navigation_data(std::unique_ptr<NavigationData> navigation_data) { - navigation_data_ = std::move(navigation_data); - } - NavigationUIData* navigation_ui_data() const { return navigation_request_->navigation_ui_data(); } @@ -339,9 +330,6 @@ // to service the navigation request. std::unique_ptr<AppCacheNavigationHandle> appcache_handle_; - // Embedder data from the IO thread tied to this navigation. - std::unique_ptr<NavigationData> navigation_data_; - // The unique id to identify this to navigation with. int64_t navigation_id_;
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index cb48aa1..767a99e 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -54,7 +54,6 @@ #include "content/public/browser/content_browser_client.h" #include "content/public/browser/global_request_id.h" #include "content/public/browser/navigation_controller.h" -#include "content/public/browser/navigation_data.h" #include "content/public/browser/navigation_ui_data.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/site_isolation_policy.h" @@ -1214,7 +1213,6 @@ void NavigationRequest::OnResponseStarted( const scoped_refptr<network::ResourceResponse>& response, network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, - std::unique_ptr<NavigationData> navigation_data, const GlobalRequestID& request_id, bool is_download, NavigationDownloadPolicy download_policy, @@ -1336,9 +1334,6 @@ } } - if (navigation_data) - navigation_handle_->set_navigation_data(std::move(navigation_data)); - // This must be set before DetermineCommittedPreviews is called. navigation_handle_->set_proxy_server(response->head.proxy_server);
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h index 05bf0830..6137a0b 100644 --- a/content/browser/frame_host/navigation_request.h +++ b/content/browser/frame_host/navigation_request.h
@@ -46,7 +46,6 @@ class FrameTreeNode; class NavigationHandleImpl; class NavigationURLLoader; -class NavigationData; class NavigationUIData; class NavigatorDelegate; class PrefetchedSignedExchangeCache; @@ -452,7 +451,6 @@ void OnResponseStarted( const scoped_refptr<network::ResourceResponse>& response, network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, - std::unique_ptr<NavigationData> navigation_data, const GlobalRequestID& request_id, bool is_download, NavigationDownloadPolicy download_policy,
diff --git a/content/browser/frame_host/navigator_impl_unittest.cc b/content/browser/frame_host/navigator_impl_unittest.cc index bd18c53..25e97c4 100644 --- a/content/browser/frame_host/navigator_impl_unittest.cc +++ b/content/browser/frame_host/navigator_impl_unittest.cc
@@ -19,7 +19,6 @@ #include "content/common/frame.mojom.h" #include "content/common/frame_messages.h" #include "content/common/navigation_params.h" -#include "content/public/browser/navigation_data.h" #include "content/public/common/content_features.h" #include "content/public/common/url_constants.h" #include "content/public/common/url_utils.h" @@ -366,8 +365,7 @@ const char kNoContentHeaders[] = "HTTP/1.1 204 No Content\0\0"; response->head.headers = new net::HttpResponseHeaders( std::string(kNoContentHeaders, base::size(kNoContentHeaders))); - GetLoaderForNavigationRequest(main_request) - ->CallOnResponseStarted(response, nullptr); + GetLoaderForNavigationRequest(main_request)->CallOnResponseStarted(response); // There should be no pending nor speculative RenderFrameHost; the navigation // was aborted. @@ -392,8 +390,7 @@ const char kResetContentHeaders[] = "HTTP/1.1 205 Reset Content\0\0"; response->head.headers = new net::HttpResponseHeaders( std::string(kResetContentHeaders, base::size(kResetContentHeaders))); - GetLoaderForNavigationRequest(main_request) - ->CallOnResponseStarted(response, nullptr); + GetLoaderForNavigationRequest(main_request)->CallOnResponseStarted(response); // There should be no pending nor speculative RenderFrameHost; the navigation // was aborted.
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 387831a4..e027a78 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -466,6 +466,9 @@ int frame_id, StoragePartition* storage_partition, network::mojom::RestrictedCookieManagerRequest request) { + GetContentClient()->browser()->WillCreateRestrictedCookieManager( + frame_host->GetLastCommittedOrigin(), + /* is_service_worker = */ false, process_id, frame_id, &request); storage_partition->GetNetworkContext()->GetRestrictedCookieManager( std::move(request), frame_host->GetLastCommittedOrigin(), /* is_service_worker = */ false, process_id, frame_id);
diff --git a/content/browser/loader/mojo_async_resource_handler_unittest.cc b/content/browser/loader/mojo_async_resource_handler_unittest.cc index a6acea3..43a6de88 100644 --- a/content/browser/loader/mojo_async_resource_handler_unittest.cc +++ b/content/browser/loader/mojo_async_resource_handler_unittest.cc
@@ -25,7 +25,6 @@ #include "content/browser/loader/resource_dispatcher_host_impl.h" #include "content/browser/loader/resource_request_info_impl.h" #include "content/public/browser/appcache_service.h" -#include "content/public/browser/navigation_data.h" #include "content/public/browser/resource_context.h" #include "content/public/browser/resource_dispatcher_host_delegate.h" #include "content/public/browser/resource_throttle.h" @@ -143,11 +142,6 @@ ADD_FAILURE() << "RequestComplete should not be called."; } - NavigationData* GetNavigationData(net::URLRequest* request) const override { - ADD_FAILURE() << "GetNavigationData should not be called."; - return nullptr; - } - private: DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcherHostDelegate); };
diff --git a/content/browser/loader/navigation_url_loader_delegate.h b/content/browser/loader/navigation_url_loader_delegate.h index 270ab931..63634013 100644 --- a/content/browser/loader/navigation_url_loader_delegate.h +++ b/content/browser/loader/navigation_url_loader_delegate.h
@@ -25,7 +25,6 @@ namespace content { -class NavigationData; struct GlobalRequestID; struct SubresourceLoaderParams; @@ -54,7 +53,6 @@ virtual void OnResponseStarted( const scoped_refptr<network::ResourceResponse>& response, network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, - std::unique_ptr<NavigationData> navigation_data, const GlobalRequestID& request_id, bool is_download, NavigationDownloadPolicy download_policy,
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc index b938ff82..23b9bd71 100644 --- a/content/browser/loader/navigation_url_loader_impl.cc +++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -59,7 +59,6 @@ #include "content/public/browser/content_browser_client.h" #include "content/public/browser/download_utils.h" #include "content/public/browser/global_request_id.h" -#include "content/public/browser/navigation_data.h" #include "content/public/browser/navigation_ui_data.h" #include "content/public/browser/plugin_service.h" #include "content/public/browser/resource_dispatcher_host_delegate.h" @@ -1068,8 +1067,6 @@ bool is_download; - std::unique_ptr<NavigationData> cloned_navigation_data; - bool must_download = download_utils::MustDownload(url_, head.headers.get(), head.mime_type); bool known_mime_type = blink::IsSupportedMimeType(head.mime_type); @@ -1096,7 +1093,7 @@ if (base::FeatureList::IsEnabled(network::features::kNetworkService) || !default_loader_used_) { CallOnReceivedResponse(head, std::move(url_loader_client_endpoints), - std::move(cloned_navigation_data), is_download); + is_download); return; } @@ -1111,21 +1108,12 @@ ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(url_request); is_download = !head.intercepted_by_plugin && info->IsDownload(); - if (rdh->delegate()) { - NavigationData* navigation_data = - rdh->delegate()->GetNavigationData(url_request); - - // Clone the embedder's NavigationData before moving it to the UI - // thread. - if (navigation_data) - cloned_navigation_data = navigation_data->Clone(); - } } else { is_download = false; } CallOnReceivedResponse(head, std::move(url_loader_client_endpoints), - std::move(cloned_navigation_data), is_download); + is_download); } #if BUILDFLAG(ENABLE_PLUGINS) @@ -1159,14 +1147,13 @@ bool is_download = !has_plugin && is_download_if_not_handled_by_plugin; CallOnReceivedResponse(head, std::move(url_loader_client_endpoints), - nullptr, is_download); + is_download); } #endif void CallOnReceivedResponse( const network::ResourceResponseHead& head, network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, - std::unique_ptr<NavigationData> cloned_navigation_data, bool is_download) { scoped_refptr<network::ResourceResponse> response( new network::ResourceResponse()); @@ -1183,8 +1170,8 @@ base::BindOnce(&NavigationURLLoaderImpl::OnReceiveResponse, owner_, response->DeepCopy(), std::move(url_loader_client_endpoints), - std::move(cloned_navigation_data), global_request_id_, - is_download, ui_to_io_time_, base::Time::Now())); + global_request_id_, is_download, ui_to_io_time_, + base::Time::Now())); } void OnReceiveRedirect(const net::RedirectInfo& redirect_info, @@ -1679,7 +1666,6 @@ void NavigationURLLoaderImpl::OnReceiveResponse( scoped_refptr<network::ResourceResponse> response, network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, - std::unique_ptr<NavigationData> navigation_data, const GlobalRequestID& global_request_id, bool is_download, base::TimeDelta total_ui_to_io_time, @@ -1702,8 +1688,8 @@ // NavigationResourceHandler::OnResponseStarted() does. delegate_->OnResponseStarted( std::move(response), std::move(url_loader_client_endpoints), - std::move(navigation_data), global_request_id, is_download, - download_policy_, request_controller_->TakeSubresourceLoaderParams()); + global_request_id, is_download, download_policy_, + request_controller_->TakeSubresourceLoaderParams()); } void NavigationURLLoaderImpl::OnReceiveRedirect(
diff --git a/content/browser/loader/navigation_url_loader_impl.h b/content/browser/loader/navigation_url_loader_impl.h index 2d77856..63b715e 100644 --- a/content/browser/loader/navigation_url_loader_impl.h +++ b/content/browser/loader/navigation_url_loader_impl.h
@@ -23,7 +23,6 @@ namespace content { -class NavigationData; class NavigationLoaderInterceptor; class PrefetchedSignedExchangeCache; class ResourceContext; @@ -58,7 +57,6 @@ void OnReceiveResponse( scoped_refptr<network::ResourceResponse> response, network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, - std::unique_ptr<NavigationData> navigation_data, const GlobalRequestID& global_request_id, bool is_download, base::TimeDelta total_ui_to_io_time,
diff --git a/content/browser/scheduler/OWNERS b/content/browser/scheduler/OWNERS index 970514c..da9ba63 100644 --- a/content/browser/scheduler/OWNERS +++ b/content/browser/scheduler/OWNERS
@@ -1,4 +1,5 @@ altimin@chromium.org alexclarke@chromium.org +carlscab@chromium.org eseckler@chromium.org skyostil@chromium.org
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc index 419ca23c..1faf563 100644 --- a/content/browser/service_worker/service_worker_provider_host.cc +++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -105,6 +105,9 @@ if (interface_name == network::mojom::RestrictedCookieManager::Name_) { network::mojom::RestrictedCookieManagerRequest request( std::move(interface_pipe)); + GetContentClient()->browser()->WillCreateRestrictedCookieManager( + origin, true /* is_service_worker */, process_id, MSG_ROUTING_NONE, + &request); process->GetStoragePartition() ->GetNetworkContext() ->GetRestrictedCookieManager(std::move(request), origin,
diff --git a/content/browser/storage_partition_impl_map.cc b/content/browser/storage_partition_impl_map.cc index 830ef3b1..ba02d67b 100644 --- a/content/browser/storage_partition_impl_map.cc +++ b/content/browser/storage_partition_impl_map.cc
@@ -61,6 +61,33 @@ namespace { +// Wrapper to call ChromeBlobStorageContext::context() on the IO thread. +class BlobProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler { + public: + explicit BlobProtocolHandler(ChromeBlobStorageContext* blob_storage_context) + : blob_storage_context_(blob_storage_context) {} + + ~BlobProtocolHandler() override {} + + net::URLRequestJob* MaybeCreateJob( + net::URLRequest* request, + net::NetworkDelegate* network_delegate) const override { + if (!blob_protocol_handler_) { + // Construction is deferred because 'this' is constructed on + // the main thread but we want blob_protocol_handler_ constructed + // on the IO thread. + blob_protocol_handler_.reset( + new storage::BlobProtocolHandler(blob_storage_context_->context())); + } + return blob_protocol_handler_->MaybeCreateJob(request, network_delegate); + } + + private: + const scoped_refptr<ChromeBlobStorageContext> blob_storage_context_; + mutable std::unique_ptr<storage::BlobProtocolHandler> blob_protocol_handler_; + DISALLOW_COPY_AND_ASSIGN(BlobProtocolHandler); +}; + // These constants are used to create the directory structure under the profile // where renderers with a non-default storage partition keep their persistent // state. This will contain a set of directories that partially mirror the @@ -360,28 +387,27 @@ StoragePartitionImpl* partition = partition_ptr.get(); partitions_[partition_config] = std::move(partition_ptr); - ChromeBlobStorageContext* blob_storage_context = - ChromeBlobStorageContext::GetFor(browser_context_); - ProtocolHandlerMap protocol_handlers; - protocol_handlers[url::kBlobScheme] = - std::make_unique<storage::BlobProtocolHandler>( - blob_storage_context->context()); - protocol_handlers[url::kFileSystemScheme] = CreateFileSystemProtocolHandler( - partition_domain, partition->GetFileSystemContext()); - for (const auto& scheme : URLDataManagerBackend::GetWebUISchemes()) { - protocol_handlers[scheme] = URLDataManagerBackend::CreateProtocolHandler( - browser_context_->GetResourceContext(), blob_storage_context); - } - - URLRequestInterceptorScopedVector request_interceptors; - - auto devtools_interceptor = - DevToolsURLRequestInterceptor::MaybeCreate(browser_context_); - if (devtools_interceptor) - request_interceptors.push_back(std::move(devtools_interceptor)); - request_interceptors.push_back(std::make_unique<AppCacheInterceptor>()); - if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) { + ChromeBlobStorageContext* blob_storage_context = + ChromeBlobStorageContext::GetFor(browser_context_); + ProtocolHandlerMap protocol_handlers; + protocol_handlers[url::kBlobScheme] = + std::make_unique<BlobProtocolHandler>(blob_storage_context); + protocol_handlers[url::kFileSystemScheme] = CreateFileSystemProtocolHandler( + partition_domain, partition->GetFileSystemContext()); + for (const auto& scheme : URLDataManagerBackend::GetWebUISchemes()) { + protocol_handlers[scheme] = URLDataManagerBackend::CreateProtocolHandler( + browser_context_->GetResourceContext(), blob_storage_context); + } + + URLRequestInterceptorScopedVector request_interceptors; + + auto devtools_interceptor = + DevToolsURLRequestInterceptor::MaybeCreate(browser_context_); + if (devtools_interceptor) + request_interceptors.push_back(std::move(devtools_interceptor)); + request_interceptors.push_back(std::make_unique<AppCacheInterceptor>()); + // These calls must happen after StoragePartitionImpl::Create(). if (partition_domain.empty()) { partition->SetURLRequestContext(browser_context_->CreateRequestContext( @@ -392,22 +418,14 @@ partition->GetPath(), in_memory, &protocol_handlers, std::move(request_interceptors))); } - } - // A separate media cache isn't used with the network service. - if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) { + // A separate media cache isn't used with the network service. partition->SetMediaURLRequestContext( partition_domain.empty() ? browser_context_->CreateMediaRequestContext() : browser_context_->CreateMediaRequestContextForStoragePartition( partition->GetPath(), in_memory)); - } - // Arm the serviceworker cookie change observation API. - partition->GetCookieStoreContext()->ListenToCookieChanges( - partition->GetNetworkContext(), /*success_callback=*/base::DoNothing()); - - if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) { // This needs to happen after SetURLRequestContext() since we need this // code path only for non-NetworkService cases where NetworkContext needs to // be initialized using |url_request_context_|, which is initialized by @@ -417,6 +435,10 @@ partition->url_loader_factory_getter()->HandleFactoryRequests(); } + // Arm the serviceworker cookie change observation API. + partition->GetCookieStoreContext()->ListenToCookieChanges( + partition->GetNetworkContext(), /*success_callback=*/base::DoNothing()); + PostCreateInitialization(partition, in_memory); return partition;
diff --git a/content/common/render_widget_host_ns_view.mojom b/content/common/render_widget_host_ns_view.mojom index 5659d670..3b0787c 100644 --- a/content/common/render_widget_host_ns_view.mojom +++ b/content/common/render_widget_host_ns_view.mojom
@@ -13,7 +13,6 @@ import "ui/gfx/geometry/mojo/geometry.mojom"; import "ui/gfx/mojo/ca_layer_params.mojom"; import "ui/gfx/range/mojo/range.mojom"; -import "ui/platform_window/mojo/text_input_state.mojom"; // The interface through which code in the browser process, in // RenderWidgetHostViewMac, sends messages to the app shim process, targeting
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn index ffddd10a..86c4431 100644 --- a/content/public/browser/BUILD.gn +++ b/content/public/browser/BUILD.gn
@@ -196,7 +196,6 @@ "native_web_keyboard_event.h", "navigation_controller.cc", "navigation_controller.h", - "navigation_data.h", "navigation_details.cc", "navigation_details.h", "navigation_entry.h",
diff --git a/content/public/browser/browser_message_filter.cc b/content/public/browser/browser_message_filter.cc index b9906035..a52d3c1 100644 --- a/content/public/browser/browser_message_filter.cc +++ b/content/public/browser/browser_message_filter.cc
@@ -63,7 +63,7 @@ filter_->OverrideThreadForMessage(message, &thread); if (thread == BrowserThread::IO) { - scoped_refptr<base::TaskRunner> runner = + scoped_refptr<base::SequencedTaskRunner> runner = filter_->OverrideTaskRunnerForMessage(message); if (runner.get()) { runner->PostTask( @@ -160,7 +160,8 @@ return false; } -base::TaskRunner* BrowserMessageFilter::OverrideTaskRunnerForMessage( +scoped_refptr<base::SequencedTaskRunner> +BrowserMessageFilter::OverrideTaskRunnerForMessage( const IPC::Message& message) { return nullptr; }
diff --git a/content/public/browser/browser_message_filter.h b/content/public/browser/browser_message_filter.h index 505473cf..b4ee929 100644 --- a/content/public/browser/browser_message_filter.h +++ b/content/public/browser/browser_message_filter.h
@@ -11,6 +11,7 @@ #include "base/memory/ref_counted.h" #include "base/process/process.h" +#include "base/sequenced_task_runner.h" #include "build/build_config.h" #include "content/common/content_export.h" #include "content/public/browser/browser_thread.h" @@ -20,10 +21,6 @@ #include "base/synchronization/lock.h" #endif -namespace base { -class TaskRunner; -} - namespace IPC { class MessageFilter; } @@ -75,7 +72,7 @@ // return a non-null task runner which will target tasks accordingly. // Note: To target the UI thread, please use OverrideThreadForMessage // since that has extra checks to avoid deadlocks. - virtual base::TaskRunner* OverrideTaskRunnerForMessage( + virtual scoped_refptr<base::SequencedTaskRunner> OverrideTaskRunnerForMessage( const IPC::Message& message); // Override this to receive messages.
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index f4c61acb..53e6771 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -759,6 +759,13 @@ network::mojom::TrustedHeaderClientPtr* header_client, uint32_t* options) {} +void ContentBrowserClient::WillCreateRestrictedCookieManager( + const url::Origin& origin, + bool is_service_worker, + int process_id, + int frame_id, + network::mojom::RestrictedCookieManagerRequest* request) {} + std::vector<std::unique_ptr<URLLoaderRequestInterceptor>> ContentBrowserClient::WillCreateURLLoaderRequestInterceptors( content::NavigationUIData* navigation_ui_data,
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 6ab15079..2b4c2c1 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -1252,6 +1252,29 @@ network::mojom::TrustedHeaderClientPtr* header_client, uint32_t* options); + // Allows the embedder to intercept the mojo object vended to renderer + // processes for limited, origin-locked (to |origin|), access to + // script-accessible cookies. |*request| is always valid upon entry and MUST + // be valid upon return. The embedder may swap out the value of |*request| for + // its own. + // + // Currently this only affects the (hidden by default, experimental) + // CookieStore API, but may affect all JavaScript cookie operations in the + // future. + // + // If |is_service_worker| is false, then |process_id| and |routing_id| + // describe the frame the result is to be used from. If it's true, operations + // are not bound to a particular frame, but are in context of a service worker + // appropriate for |origin|. + // + // This is called on the UI thread. + virtual void WillCreateRestrictedCookieManager( + const url::Origin& origin, + bool is_service_worker, + int process_id, + int routing_id, + network::mojom::RestrictedCookieManagerRequest* request); + // Allows the embedder to returns a list of request interceptors that can // intercept a navigation request. //
diff --git a/content/public/browser/navigation_data.h b/content/public/browser/navigation_data.h deleted file mode 100644 index d753809..0000000 --- a/content/public/browser/navigation_data.h +++ /dev/null
@@ -1,25 +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 CONTENT_PUBLIC_BROWSER_NAVIGATION_DATA_H_ -#define CONTENT_PUBLIC_BROWSER_NAVIGATION_DATA_H_ - -#include <memory> - -namespace content { - -// Copyable interface for embedders to pass opaque data to content/. It is -// expected to be created on the IO thread, and content/ will transfer it to the -// UI thread as a clone. -class NavigationData { - public: - virtual ~NavigationData() {} - - // Creates a new NavigationData that is a deep copy of the original - virtual std::unique_ptr<NavigationData> Clone() = 0; -}; - -} // namespace content - -#endif // CONTENT_PUBLIC_BROWSER_NAVIGATION_DATA_H_
diff --git a/content/public/browser/navigation_handle.h b/content/public/browser/navigation_handle.h index af69b3d2..77af5b4 100644 --- a/content/public/browser/navigation_handle.h +++ b/content/public/browser/navigation_handle.h
@@ -29,7 +29,6 @@ namespace content { struct GlobalRequestID; -class NavigationData; class NavigationThrottle; class NavigationUIData; class RenderFrameHost; @@ -320,6 +319,9 @@ // navigation entry. virtual int GetNavigationEntryOffset() = 0; + virtual void RegisterSubresourceOverride( + mojom::TransferrableURLLoaderPtr transferrable_loader) = 0; + // Testing methods ---------------------------------------------------------- // // The following methods should be used exclusively for writing unit tests. @@ -336,14 +338,6 @@ // Returns whether this navigation is currently deferred. virtual bool IsDeferredForTesting() = 0; - - // The NavigationData that the embedder returned from - // ResourceDispatcherHostDelegate::GetNavigationData during commit. This will - // be a clone of the NavigationData. - virtual NavigationData* GetNavigationData() = 0; - - virtual void RegisterSubresourceOverride( - mojom::TransferrableURLLoaderPtr transferrable_loader) = 0; }; } // namespace content
diff --git a/content/public/browser/resource_dispatcher_host_delegate.cc b/content/public/browser/resource_dispatcher_host_delegate.cc index 95c5d64..7ef14a6 100644 --- a/content/public/browser/resource_dispatcher_host_delegate.cc +++ b/content/public/browser/resource_dispatcher_host_delegate.cc
@@ -4,7 +4,6 @@ #include "content/public/browser/resource_dispatcher_host_delegate.h" -#include "content/public/browser/navigation_data.h" #include "content/public/browser/resource_request_info.h" namespace content { @@ -45,9 +44,4 @@ void ResourceDispatcherHostDelegate::RequestComplete( net::URLRequest* url_request) {} -NavigationData* ResourceDispatcherHostDelegate::GetNavigationData( - net::URLRequest* request) const { - return nullptr; -} - } // namespace content
diff --git a/content/public/browser/resource_dispatcher_host_delegate.h b/content/public/browser/resource_dispatcher_host_delegate.h index aed1343..c414b4db 100644 --- a/content/public/browser/resource_dispatcher_host_delegate.h +++ b/content/public/browser/resource_dispatcher_host_delegate.h
@@ -25,7 +25,6 @@ namespace content { class AppCacheService; -class NavigationData; class ResourceContext; class ResourceThrottle; @@ -73,10 +72,6 @@ // Deprecated. // TODO(maksims): Remove this once all the callers are modified. virtual void RequestComplete(net::URLRequest* url_request); - - // Asks the embedder for NavigationData related to this request. It is only - // called for navigation requests. - virtual NavigationData* GetNavigationData(net::URLRequest* request) const; }; } // namespace content
diff --git a/content/public/test/mock_navigation_handle.h b/content/public/test/mock_navigation_handle.h index 569bb0b..e5809ef 100644 --- a/content/public/test/mock_navigation_handle.h +++ b/content/public/test/mock_navigation_handle.h
@@ -91,7 +91,6 @@ MOCK_METHOD1(RegisterThrottleForTesting, void(std::unique_ptr<NavigationThrottle>)); MOCK_METHOD0(IsDeferredForTesting, bool()); - NavigationData* GetNavigationData() override { return nullptr; } MOCK_METHOD1(RegisterSubresourceOverride, void(mojom::TransferrableURLLoaderPtr)); MOCK_METHOD0(IsSameProcess, bool());
diff --git a/content/public/test/web_contents_tester.h b/content/public/test/web_contents_tester.h index 292a667..411e9188 100644 --- a/content/public/test/web_contents_tester.h +++ b/content/public/test/web_contents_tester.h
@@ -29,7 +29,6 @@ namespace content { class BrowserContext; -class NavigationData; class NavigationHandle; class RenderFrameHost; @@ -112,11 +111,6 @@ const GURL& url, ui::PageTransition transition) = 0; - // Sets NavgationData on |navigation_handle|. - virtual void SetNavigationData( - NavigationHandle* navigation_handle, - std::unique_ptr<NavigationData> navigation_data) = 0; - // Sets HttpResponseData on |navigation_handle|. virtual void SetHttpResponseHeaders( NavigationHandle* navigation_handle,
diff --git a/content/shell/browser/web_test/web_test_message_filter.cc b/content/shell/browser/web_test/web_test_message_filter.cc index ff3f157..b2e1510 100644 --- a/content/shell/browser/web_test/web_test_message_filter.cc +++ b/content/shell/browser/web_test/web_test_message_filter.cc
@@ -59,7 +59,8 @@ BrowserThread::DeleteOnUIThread::Destruct(this); } -base::TaskRunner* WebTestMessageFilter::OverrideTaskRunnerForMessage( +scoped_refptr<base::SequencedTaskRunner> +WebTestMessageFilter::OverrideTaskRunnerForMessage( const IPC::Message& message) { switch (message.type()) { case WebTestHostMsg_ClearAllDatabases::ID: @@ -73,8 +74,7 @@ case WebTestHostMsg_InitiateCaptureDump::ID: case WebTestHostMsg_InspectSecondaryWindow::ID: case WebTestHostMsg_DeleteAllCookies::ID: - return base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}) - .get(); + return base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}); } return nullptr; }
diff --git a/content/shell/browser/web_test/web_test_message_filter.h b/content/shell/browser/web_test/web_test_message_filter.h index daa984c..a1f7f1b 100644 --- a/content/shell/browser/web_test/web_test_message_filter.h +++ b/content/shell/browser/web_test/web_test_message_filter.h
@@ -55,7 +55,7 @@ // BrowserMessageFilter implementation. void OnDestruct() const override; - base::TaskRunner* OverrideTaskRunnerForMessage( + scoped_refptr<base::SequencedTaskRunner> OverrideTaskRunnerForMessage( const IPC::Message& message) override; bool OnMessageReceived(const IPC::Message& message) override;
diff --git a/content/test/content_test_launcher.cc b/content/test/content_test_launcher.cc index e8a53f3e..37aec6f6 100644 --- a/content/test/content_test_launcher.cc +++ b/content/test/content_test_launcher.cc
@@ -24,6 +24,10 @@ #include "ui/base/buildflags.h" #include "ui/base/ui_base_switches.h" +#if defined(OS_WIN) +#include "base/win/win_util.h" +#endif // OS_WIN + namespace content { class ContentBrowserTestSuite : public ContentTestSuiteBase { @@ -86,6 +90,11 @@ if (parallel_jobs > 1U) { parallel_jobs /= 2U; } +#if defined(OS_WIN) + // Load and pin user32.dll to avoid having to load it once tests start while + // on the main thread loop where blocking calls are disallowed. + base::win::PinUser32(); +#endif // OS_WIN content::ContentTestLauncherDelegate launcher_delegate; return LaunchTests(&launcher_delegate, parallel_jobs, argc, argv); }
diff --git a/content/test/test_navigation_url_loader.cc b/content/test/test_navigation_url_loader.cc index 555f76a..6026fa4 100644 --- a/content/test/test_navigation_url_loader.cc +++ b/content/test/test_navigation_url_loader.cc
@@ -9,7 +9,6 @@ #include "content/browser/loader/navigation_url_loader_delegate.h" #include "content/browser/navigation_subresource_loader_params.h" #include "content/public/browser/global_request_id.h" -#include "content/public/browser/navigation_data.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/ssl_status.h" @@ -68,8 +67,7 @@ } void TestNavigationURLLoader::CallOnResponseStarted( - const scoped_refptr<network::ResourceResponse>& response, - std::unique_ptr<NavigationData> navigation_data) { + const scoped_refptr<network::ResourceResponse>& response) { // Start the request_ids at 1000 to avoid collisions with request ids from // network resources (it should be rare to compare these in unit tests). static int request_id = 1000; @@ -94,8 +92,8 @@ url_loader_ptr.PassInterface(), std::move(url_loader_client_request)); delegate_->OnResponseStarted(response, std::move(url_loader_client_endpoints), - std::move(navigation_data), global_id, false, - NavigationDownloadPolicy(), base::nullopt); + global_id, false, NavigationDownloadPolicy(), + base::nullopt); } TestNavigationURLLoader::~TestNavigationURLLoader() {}
diff --git a/content/test/test_navigation_url_loader.h b/content/test/test_navigation_url_loader.h index f7cd812..1d8ce23 100644 --- a/content/test/test_navigation_url_loader.h +++ b/content/test/test_navigation_url_loader.h
@@ -22,7 +22,6 @@ namespace content { -class NavigationData; class NavigationURLLoaderDelegate; // Test implementation of NavigationURLLoader to simulate the network stack @@ -52,8 +51,7 @@ const net::RedirectInfo& redirect_info, const scoped_refptr<network::ResourceResponse>& response); void CallOnResponseStarted( - const scoped_refptr<network::ResourceResponse>& response, - std::unique_ptr<NavigationData> navigation_data); + const scoped_refptr<network::ResourceResponse>& response); int redirect_count() { return redirect_count_; }
diff --git a/content/test/test_navigation_url_loader_delegate.cc b/content/test/test_navigation_url_loader_delegate.cc index 05a7a5d3..1cd221ecd 100644 --- a/content/test/test_navigation_url_loader_delegate.cc +++ b/content/test/test_navigation_url_loader_delegate.cc
@@ -8,7 +8,6 @@ #include "content/browser/navigation_subresource_loader_params.h" #include "content/common/navigation_params.h" #include "content/public/browser/global_request_id.h" -#include "content/public/browser/navigation_data.h" #include "services/network/public/cpp/resource_response.h" #include "testing/gtest/include/gtest/gtest.h" @@ -59,7 +58,6 @@ void TestNavigationURLLoaderDelegate::OnResponseStarted( const scoped_refptr<network::ResourceResponse>& response, network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, - std::unique_ptr<NavigationData> navigation_data, const GlobalRequestID& request_id, bool is_download, NavigationDownloadPolicy download_policy,
diff --git a/content/test/test_navigation_url_loader_delegate.h b/content/test/test_navigation_url_loader_delegate.h index 5abfe62b..f658b5e 100644 --- a/content/test/test_navigation_url_loader_delegate.h +++ b/content/test/test_navigation_url_loader_delegate.h
@@ -63,7 +63,6 @@ void OnResponseStarted( const scoped_refptr<network::ResourceResponse>& response, network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, - std::unique_ptr<NavigationData> navigation_data, const GlobalRequestID& request_id, bool is_download, NavigationDownloadPolicy download_policy,
diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc index dcd35c4..c72007e 100644 --- a/content/test/test_render_frame_host.cc +++ b/content/test/test_render_frame_host.cc
@@ -428,7 +428,7 @@ response->head.ssl_info = ssl_info; // TODO(carlosk): Ideally, it should be possible someday to // fully commit the navigation at this call to CallOnResponseStarted. - url_loader->CallOnResponseStarted(response, nullptr); + url_loader->CallOnResponseStarted(response); } void TestRenderFrameHost::SimulateCommitProcessed(
diff --git a/content/test/test_web_contents.cc b/content/test/test_web_contents.cc index 4d42b2a..020ea03e 100644 --- a/content/test/test_web_contents.cc +++ b/content/test/test_web_contents.cc
@@ -22,7 +22,6 @@ #include "content/common/frame_messages.h" #include "content/common/render_message_filter.mojom.h" #include "content/common/view_messages.h" -#include "content/public/browser/navigation_data.h" #include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_source.h" #include "content/public/browser/notification_types.h" @@ -371,13 +370,6 @@ history_length); } -void TestWebContents::SetNavigationData( - NavigationHandle* navigation_handle, - std::unique_ptr<NavigationData> navigation_data) { - static_cast<NavigationHandleImpl*>(navigation_handle) - ->set_navigation_data(std::move(navigation_data)); -} - void TestWebContents::SetHttpResponseHeaders( NavigationHandle* navigation_handle, scoped_refptr<net::HttpResponseHeaders> response_headers) {
diff --git a/content/test/test_web_contents.h b/content/test/test_web_contents.h index 1640763..dbc195a8 100644 --- a/content/test/test_web_contents.h +++ b/content/test/test_web_contents.h
@@ -36,7 +36,6 @@ namespace content { -class NavigationData; class NavigationHandle; class RenderViewHost; class TestRenderViewHost; @@ -92,9 +91,6 @@ bool was_within_same_document, int item_sequence_number, int document_sequence_number); - void SetNavigationData( - NavigationHandle* navigation_handle, - std::unique_ptr<NavigationData> navigation_data) override; void SetHttpResponseHeaders( NavigationHandle* navigation_handle, scoped_refptr<net::HttpResponseHeaders> response_headers) override;
diff --git a/extensions/renderer/api/automation/automation_internal_custom_bindings.cc b/extensions/renderer/api/automation/automation_internal_custom_bindings.cc index e05f19f..57d19cbd 100644 --- a/extensions/renderer/api/automation/automation_internal_custom_bindings.cc +++ b/extensions/renderer/api/automation/automation_internal_custom_bindings.cc
@@ -1994,6 +1994,29 @@ void AutomationInternalCustomBindings::MaybeSendFocusAndBlur( AutomationAXTreeWrapper* tree, const ExtensionMsg_AccessibilityEventBundleParams& event_bundle) { + // Only send focus or blur if we got one of these events from the originating + // renderer. While sending events purely based upon whether the targeted + // focus/blur node changed may work, we end up firing too many events since + // intermediate states trigger more events than likely necessary. Also, the + // |event_from| field is only properly associated with focus/blur when the + // event type is also focus/blur. + base::Optional<ax::mojom::EventFrom> event_from; + for (const auto& event : event_bundle.events) { + if (event.event_type == ax::mojom::Event::kBlur || + event.event_type == ax::mojom::Event::kFocus) + event_from = event.event_from; + } + + if (!event_from) { + // There was no explicit focus/blur; return early. + // Make an exception for the desktop tree, where we can reliably infer + // focus/blur even without an explicit event. + if (!tree->IsDesktopTree()) + return; + + event_from = ax::mojom::EventFrom::kNone; + } + // Get the root-most tree. AutomationAXTreeWrapper* root_tree = tree; while ( @@ -2014,18 +2037,11 @@ if (new_wrapper == old_wrapper && new_node == old_node) return; - ax::mojom::EventFrom event_from = ax::mojom::EventFrom::kNone; - for (const auto& event : event_bundle.events) { - if (event.event_type == ax::mojom::Event::kFocus || - event.event_type == ax::mojom::Event::kBlur) - event_from = event.event_from; - } - // Blur previous focus. if (old_node) { ui::AXEvent blur_event; blur_event.id = old_node->id(); - blur_event.event_from = event_from; + blur_event.event_from = *event_from; SendAutomationEvent(old_wrapper->tree_id(), event_bundle.mouse_location, blur_event, api::automation::EVENT_TYPE_BLUR); @@ -2037,7 +2053,7 @@ if (new_node) { ui::AXEvent focus_event; focus_event.id = new_node->id(); - focus_event.event_from = event_from; + focus_event.event_from = *event_from; SendAutomationEvent(new_wrapper->tree_id(), event_bundle.mouse_location, focus_event, api::automation::EVENT_TYPE_FOCUS); focus_id_ = new_node->id();
diff --git a/fuchsia/engine/BUILD.gn b/fuchsia/engine/BUILD.gn index 5dd737dcc..ff295ca 100644 --- a/fuchsia/engine/BUILD.gn +++ b/fuchsia/engine/BUILD.gn
@@ -115,6 +115,8 @@ "browser/web_engine_content_browser_client.h", "browser/web_engine_devtools_manager_delegate.cc", "browser/web_engine_devtools_manager_delegate.h", + "browser/web_engine_devtools_socket_factory.cc", + "browser/web_engine_devtools_socket_factory.h", "browser/web_engine_net_log.cc", "browser/web_engine_net_log.h", "browser/web_engine_screen.cc", @@ -231,6 +233,31 @@ ] } +test("web_engine_integration_tests") { + sandbox_policy = "integration_tests_sandbox_policy" + sources = [ + "test_debug_listener.cc", + "test_debug_listener.h", + "web_engine_debug_integration_test.cc", + ] + data = [ + "test/data", + ] + deps = [ + "//base", + "//base/test:run_all_unittests", + "//fuchsia/base", + "//fuchsia/base:test_support", + "//net", + "//net:test_support", + "//third_party/fuchsia-sdk/sdk:web", + ] + package_deps = [ [ + ":web_engine", + "chromium", + ] ] +} + if (is_official_build) { symbol_archive("symbol_archive") { deps = [
diff --git a/fuchsia/engine/browser/context_impl.cc b/fuchsia/engine/browser/context_impl.cc index 83be083f..2c0ae51 100644 --- a/fuchsia/engine/browser/context_impl.cc +++ b/fuchsia/engine/browser/context_impl.cc
@@ -9,14 +9,57 @@ #include <utility> #include "base/fuchsia/fuchsia_logging.h" +#include "base/strings/string_tokenizer.h" #include "content/public/browser/web_contents.h" #include "fuchsia/engine/browser/frame_impl.h" +#include "fuchsia/engine/browser/web_engine_browser_context.h" +#include "fuchsia/engine/common.h" ContextImpl::ContextImpl(content::BrowserContext* browser_context) - : browser_context_(browser_context) {} + : browser_context_(browser_context) { + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + kRemoteDebuggerHandles)) { + std::string handle_ids_str = + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + kRemoteDebuggerHandles); + + // Extract individual handle IDs from the comma-separated list. + base::StringTokenizer tokenizer(handle_ids_str, ","); + while (tokenizer.GetNext()) { + uint32_t handle_id = 0; + if (!base::StringToUint(tokenizer.token(), &handle_id)) + continue; + fidl::InterfacePtr<fuchsia::web::DevToolsPerContextListener> listener; + listener.Bind(zx::channel(zx_take_startup_handle(handle_id))); + devtools_listeners_.AddInterfacePtr(std::move(listener)); + } + } +} ContextImpl::~ContextImpl() = default; +void ContextImpl::DestroyFrame(FrameImpl* frame) { + DCHECK(frames_.find(frame) != frames_.end()); + frames_.erase(frames_.find(frame)); +} + +bool ContextImpl::IsJavaScriptInjectionAllowed() { + return allow_javascript_injection_; +} + +void ContextImpl::OnDevToolsPortReady() { + if (devtools_port_ == 0 || devtools_listeners_notified_) + return; + for (auto& listener : devtools_listeners_.ptrs()) { + listener->get()->OnHttpPortOpen(devtools_port_); + } + devtools_listeners_notified_ = true; +} + +void ContextImpl::OnDevToolsPortOpened(uint16_t port) { + devtools_port_ = port; +} + void ContextImpl::CreateFrame( fidl::InterfaceRequest<fuchsia::web::Frame> frame) { content::WebContents::CreateParams create_params(browser_context_, nullptr); @@ -27,15 +70,6 @@ std::move(frame))); } -void ContextImpl::DestroyFrame(FrameImpl* frame) { - DCHECK(frames_.find(frame) != frames_.end()); - frames_.erase(frames_.find(frame)); -} - -bool ContextImpl::IsJavaScriptInjectionAllowed() { - return allow_javascript_injection_; -} - FrameImpl* ContextImpl::GetFrameImplForTest(fuchsia::web::FramePtr* frame_ptr) { DCHECK(frame_ptr);
diff --git a/fuchsia/engine/browser/context_impl.h b/fuchsia/engine/browser/context_impl.h index 1475b60..96ef6a9 100644 --- a/fuchsia/engine/browser/context_impl.h +++ b/fuchsia/engine/browser/context_impl.h
@@ -6,6 +6,7 @@ #define FUCHSIA_ENGINE_BROWSER_CONTEXT_IMPL_H_ #include <fuchsia/web/cpp/fidl.h> +#include <lib/fidl/cpp/interface_ptr_set.h> #include <memory> #include <set> @@ -40,6 +41,14 @@ // Returns |true| if JS injection was enabled for this Context. bool IsJavaScriptInjectionAllowed(); + // Called by Frames to signal a document has been loaded and signal to the + // |devtools_listeners_| that they can now successfully connect ChromeDriver + // on |devtools_port_|. + void OnDevToolsPortReady(); + + // Signals the DevTools debugging port has been opened. + void OnDevToolsPortOpened(uint16_t port); + // fuchsia::web::Context implementation. void CreateFrame(fidl::InterfaceRequest<fuchsia::web::Frame> frame) override; @@ -48,7 +57,7 @@ FrameImpl* GetFrameImplForTest(fuchsia::web::FramePtr* frame_ptr); private: - content::BrowserContext* browser_context_; + content::BrowserContext* const browser_context_; // TODO(crbug.com/893236): Make this false by default, and allow it to be // initialized at Context creation time. @@ -58,6 +67,11 @@ // destruction when this ContextImpl is destroyed. std::set<std::unique_ptr<FrameImpl>, base::UniquePtrComparator> frames_; + fidl::InterfacePtrSet<fuchsia::web::DevToolsPerContextListener> + devtools_listeners_; + bool devtools_listeners_notified_ = false; + uint16_t devtools_port_ = 0; + DISALLOW_COPY_AND_ASSIGN(ContextImpl); };
diff --git a/fuchsia/engine/browser/frame_impl.cc b/fuchsia/engine/browser/frame_impl.cc index 10f2152..0ffbd22 100644 --- a/fuchsia/engine/browser/frame_impl.cc +++ b/fuchsia/engine/browser/frame_impl.cc
@@ -694,8 +694,9 @@ void FrameImpl::DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url) { - // The document and its statically-declared subresources are loaded. + context_->OnDevToolsPortReady(); + // The document and its statically-declared subresources are loaded. is_main_document_loaded_ = true; OnNavigationEntryChanged(); }
diff --git a/fuchsia/engine/browser/web_engine_browser_main_parts.cc b/fuchsia/engine/browser/web_engine_browser_main_parts.cc index 1539ab9f..e93f67b 100644 --- a/fuchsia/engine/browser/web_engine_browser_main_parts.cc +++ b/fuchsia/engine/browser/web_engine_browser_main_parts.cc
@@ -10,9 +10,11 @@ #include "base/files/file_util.h" #include "base/fuchsia/fuchsia_logging.h" #include "base/logging.h" +#include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/render_frame_host.h" #include "fuchsia/engine/browser/context_impl.h" #include "fuchsia/engine/browser/web_engine_browser_context.h" +#include "fuchsia/engine/browser/web_engine_devtools_socket_factory.h" #include "fuchsia/engine/browser/web_engine_screen.h" #include "fuchsia/engine/common.h" #include "ui/aura/screen_ozone.h" @@ -49,6 +51,16 @@ context_binding_ = std::make_unique<fidl::Binding<fuchsia::web::Context>>( context_service_.get(), std::move(request_)); + // Start the remote debugging server. + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + kRemoteDebuggerHandles)) { + content::DevToolsAgentHost::StartRemoteDebuggingServer( + std::make_unique<WebEngineDevToolsSocketFactory>( + base::BindRepeating(&ContextImpl::OnDevToolsPortOpened, + base::Unretained(context_service_.get()))), + browser_context_->GetPath(), base::FilePath()); + } + // Quit the browser main loop when the Context connection is dropped. context_binding_->set_error_handler([this](zx_status_t status) { ZX_LOG_IF(ERROR, status != ZX_ERR_PEER_CLOSED, status) @@ -74,6 +86,11 @@ DCHECK(!context_service_); DCHECK(!context_binding_->is_bound()); + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + kRemoteDebuggerHandles)) { + content::DevToolsAgentHost::StopRemoteDebuggingServer(); + } + // These resources must be freed while a MessageLoop is still available, so // that they may post cleanup tasks during teardown. // NOTE: Please destroy objects in the reverse order of their creation.
diff --git a/fuchsia/engine/browser/web_engine_devtools_socket_factory.cc b/fuchsia/engine/browser/web_engine_devtools_socket_factory.cc new file mode 100644 index 0000000..a80d661 --- /dev/null +++ b/fuchsia/engine/browser/web_engine_devtools_socket_factory.cc
@@ -0,0 +1,49 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "fuchsia/engine/browser/web_engine_devtools_socket_factory.h" +#include "fuchsia/engine/browser/web_engine_browser_context.h" +#include "net/base/net_errors.h" +#include "net/socket/tcp_server_socket.h" + +namespace { + +const int kTcpListenBackLog = 5; + +} // namespace + +WebEngineDevToolsSocketFactory::WebEngineDevToolsSocketFactory( + OnPortOpenedCallback callback) + : callback_(std::move(callback)) {} + +WebEngineDevToolsSocketFactory::~WebEngineDevToolsSocketFactory() = default; + +std::unique_ptr<net::ServerSocket> +WebEngineDevToolsSocketFactory::CreateForHttpServer() { + std::unique_ptr<net::ServerSocket> socket( + new net::TCPServerSocket(nullptr, net::NetLogSource())); + if (socket->Listen(net::IPEndPoint(net::IPAddress::IPv4Localhost(), 0), + kTcpListenBackLog) == net::OK) { + net::IPEndPoint end_point; + socket->GetLocalAddress(&end_point); + callback_.Run(end_point.port()); + return socket; + } + int error = socket->Listen( + net::IPEndPoint(net::IPAddress::IPv6Localhost(), 0), kTcpListenBackLog); + if (error == net::OK) { + net::IPEndPoint end_point; + socket->GetLocalAddress(&end_point); + callback_.Run(end_point.port()); + return socket; + } + LOG(WARNING) << "Failed to start the HTTP debugger service. " + << net::ErrorToString(error); + return nullptr; +} + +std::unique_ptr<net::ServerSocket> +WebEngineDevToolsSocketFactory::CreateForTethering(std::string* out_name) { + return nullptr; +}
diff --git a/fuchsia/engine/browser/web_engine_devtools_socket_factory.h b/fuchsia/engine/browser/web_engine_devtools_socket_factory.h new file mode 100644 index 0000000..e35d933 --- /dev/null +++ b/fuchsia/engine/browser/web_engine_devtools_socket_factory.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 FUCHSIA_ENGINE_BROWSER_WEB_ENGINE_DEVTOOLS_SOCKET_FACTORY_H_ +#define FUCHSIA_ENGINE_BROWSER_WEB_ENGINE_DEVTOOLS_SOCKET_FACTORY_H_ + +#include "base/callback.h" +#include "content/public/browser/devtools_socket_factory.h" + +class WebEngineDevToolsSocketFactory : public content::DevToolsSocketFactory { + public: + using OnPortOpenedCallback = base::RepeatingCallback<void(uint16_t)>; + + explicit WebEngineDevToolsSocketFactory(OnPortOpenedCallback callback); + ~WebEngineDevToolsSocketFactory() override; + + // content::DevToolsSocketFactory implementation. + std::unique_ptr<net::ServerSocket> CreateForHttpServer() override; + std::unique_ptr<net::ServerSocket> CreateForTethering( + std::string* out_name) override; + + private: + OnPortOpenedCallback callback_; + + DISALLOW_COPY_AND_ASSIGN(WebEngineDevToolsSocketFactory); +}; + +#endif // FUCHSIA_ENGINE_BROWSER_WEB_ENGINE_DEVTOOLS_SOCKET_FACTORY_H_
diff --git a/fuchsia/engine/common.cc b/fuchsia/engine/common.cc index 2c43db2b..61927a9 100644 --- a/fuchsia/engine/common.cc +++ b/fuchsia/engine/common.cc
@@ -5,3 +5,4 @@ #include "fuchsia/engine/common.h" constexpr char kIncognitoSwitch[] = "incognito"; +constexpr char kRemoteDebuggerHandles[] = "remote-debugger-handles";
diff --git a/fuchsia/engine/common.h b/fuchsia/engine/common.h index 350067c..b6f2672 100644 --- a/fuchsia/engine/common.h +++ b/fuchsia/engine/common.h
@@ -9,12 +9,16 @@ #include "fuchsia/engine/web_engine_export.h" -// Switch passed to content process when running in incognito mode, i.e. when +// This file contains constants and functions shared between Context and +// ContextProvider processes. + +// Switch passed to Context process when running in incognito mode, i.e. when // there is no kWebContextDataPath. WEB_ENGINE_EXPORT extern const char kIncognitoSwitch[]; -// This file contains constants and functions shared between Context and -// ContextProvider processes. +// Switch passed to Context process when enabling remote debugging. It takes +// a comma-separated list of remote debugger handle IDs as an argument. +WEB_ENGINE_EXPORT extern const char kRemoteDebuggerHandles[]; // Handle ID for the Context interface request passed from ContextProvider to // Context process.
diff --git a/fuchsia/engine/context_provider_impl.cc b/fuchsia/engine/context_provider_impl.cc index de2c27e..53e7fb2ff 100644 --- a/fuchsia/engine/context_provider_impl.cc +++ b/fuchsia/engine/context_provider_impl.cc
@@ -22,6 +22,8 @@ #include "base/logging.h" #include "base/path_service.h" #include "base/process/launch.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" #include "fuchsia/engine/common.h" #include "services/service_manager/sandbox/fuchsia/sandbox_policy_fuchsia.h" @@ -110,12 +112,27 @@ } launch_options.job_handle = job.get(); - const base::CommandLine* launch_command = - base::CommandLine::ForCurrentProcess(); + base::CommandLine launch_command(*base::CommandLine::ForCurrentProcess()); + if (devtools_listeners_.size() != 0) { + std::vector<std::string> handles_ids; + for (auto& devtools_listener : devtools_listeners_.ptrs()) { + fidl::InterfaceHandle<fuchsia::web::DevToolsPerContextListener> + client_listener; + devtools_listener.get()->get()->OnContextDevToolsAvailable( + client_listener.NewRequest()); + handles_ids.push_back( + base::NumberToString(base::LaunchOptions::AddHandleToTransfer( + &launch_options.handles_to_transfer, + client_listener.TakeChannel().release()))); + } + launch_command.AppendSwitchNative(kRemoteDebuggerHandles, + base::JoinString(handles_ids, ",")); + } + if (launch_for_test_) - launch_for_test_.Run(*launch_command, launch_options); + launch_for_test_.Run(launch_command, launch_options); else - base::LaunchProcess(*launch_command, launch_options); + base::LaunchProcess(launch_command, launch_options); // |context_handle| was transferred (not copied) to the Context process. ignore_result(context_handle.release()); @@ -125,3 +142,10 @@ LaunchCallbackForTest launch) { launch_for_test_ = std::move(launch); } + +void ContextProviderImpl::EnableDevTools( + fidl::InterfaceHandle<fuchsia::web::DevToolsListener> listener, + EnableDevToolsCallback callback) { + devtools_listeners_.AddInterfacePtr(listener.Bind()); + callback(); +}
diff --git a/fuchsia/engine/context_provider_impl.h b/fuchsia/engine/context_provider_impl.h index e25a982a..b08fdaa 100644 --- a/fuchsia/engine/context_provider_impl.h +++ b/fuchsia/engine/context_provider_impl.h
@@ -7,6 +7,7 @@ #include <fuchsia/web/cpp/fidl.h> #include <lib/fidl/cpp/binding_set.h> +#include <lib/fidl/cpp/interface_ptr_set.h> #include <memory> #include "base/callback.h" @@ -20,7 +21,8 @@ } // namespace base class WEB_ENGINE_EXPORT ContextProviderImpl - : public fuchsia::web::ContextProvider { + : public fuchsia::web::ContextProvider, + public fuchsia::web::Debug { public: using LaunchCallbackForTest = base::RepeatingCallback<base::Process( const base::CommandLine& command, @@ -39,10 +41,18 @@ void SetLaunchCallbackForTest(LaunchCallbackForTest launch); private: + // fuchsia::web::Debug implementation. + void EnableDevTools( + fidl::InterfaceHandle<fuchsia::web::DevToolsListener> listener, + EnableDevToolsCallback callback) override; + // Set by tests to use to launch Context child processes, e.g. to allow a // fake Context process to be launched. LaunchCallbackForTest launch_for_test_; + // The DevToolsListeners registered via the Debug interface. + fidl::InterfacePtrSet<fuchsia::web::DevToolsListener> devtools_listeners_; + DISALLOW_COPY_AND_ASSIGN(ContextProviderImpl); };
diff --git a/fuchsia/engine/context_provider_main.cc b/fuchsia/engine/context_provider_main.cc index 0d25951..d4b4675 100644 --- a/fuchsia/engine/context_provider_main.cc +++ b/fuchsia/engine/context_provider_main.cc
@@ -21,9 +21,8 @@ base::fuchsia::ScopedServiceBinding<fuchsia::web::ContextProvider> binding( directory, &context_provider); - fuchsia::web::ContextProviderPtr fuchsia_context_provider; - fidl::Binding<fuchsia::web::ContextProvider> fuchsia_binding( - &context_provider, fuchsia_context_provider.NewRequest()); + base::fuchsia::ScopedServiceBinding<fuchsia::web::Debug> debug_binding( + directory->debug(), &context_provider); base::RunLoop run_loop; cr_fuchsia::LifecycleImpl lifecycle(directory, run_loop.QuitClosure());
diff --git a/fuchsia/engine/integration_tests_sandbox_policy b/fuchsia/engine/integration_tests_sandbox_policy new file mode 100644 index 0000000..f987ae2 --- /dev/null +++ b/fuchsia/engine/integration_tests_sandbox_policy
@@ -0,0 +1,14 @@ +{ + "features": [ + "isolated-persistent-storage", + "shell", + "system-temp" ], + "services": [ + "fuchsia.logger.LogSink", + "fuchsia.net.SocketProvider", + "fuchsia.netstack.Netstack", + "fuchsia.process.Launcher", + "fuchsia.sysmem.Allocator", + "fuchsia.web.ContextProvider" + ] +}
diff --git a/fuchsia/engine/test_debug_listener.cc b/fuchsia/engine/test_debug_listener.cc new file mode 100644 index 0000000..9f3c67031 --- /dev/null +++ b/fuchsia/engine/test_debug_listener.cc
@@ -0,0 +1,61 @@ +// 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 "fuchsia/engine/test_debug_listener.h" + +#include "base/run_loop.h" +#include "testing/gtest/include/gtest/gtest.h" + +TestDebugListener::TestDebugListener() {} +TestDebugListener::~TestDebugListener() = default; + +void TestDebugListener::DestroyListener(TestPerContextListener* listener) { + EXPECT_EQ(per_context_listeners_.erase(listener), 1u); +} + +void TestDebugListener::AddPort(uint16_t port) { + EXPECT_EQ(debug_ports_.find(port), debug_ports_.end()); + debug_ports_.insert(port); + if (run_ack_) + std::move(run_ack_).Run(); +} + +void TestDebugListener::RemovePort(uint16_t port) { + EXPECT_EQ(debug_ports_.erase(port), 1u); + if (run_ack_) + std::move(run_ack_).Run(); +} + +void TestDebugListener::RunUntilNumberOfPortsIs(size_t size) { + while (debug_ports_.size() != size) { + base::RunLoop run_loop; + run_ack_ = run_loop.QuitClosure(); + run_loop.Run(); + } +} + +TestDebugListener::TestPerContextListener::TestPerContextListener( + TestDebugListener* test_debug_listener, + fidl::InterfaceRequest<fuchsia::web::DevToolsPerContextListener> listener) + : test_debug_listener_(test_debug_listener), + binding_(this, std::move(listener)) { + binding_.set_error_handler([this](zx_status_t) { + if (port_ != 0) + test_debug_listener_->RemovePort(port_); + test_debug_listener_->DestroyListener(this); + }); +} + +TestDebugListener::TestPerContextListener::~TestPerContextListener() = default; + +void TestDebugListener::TestPerContextListener::OnHttpPortOpen(uint16_t port) { + port_ = port; + test_debug_listener_->AddPort(port); +} + +void TestDebugListener::OnContextDevToolsAvailable( + fidl::InterfaceRequest<fuchsia::web::DevToolsPerContextListener> listener) { + per_context_listeners_.insert( + std::make_unique<TestPerContextListener>(this, std::move(listener))); +}
diff --git a/fuchsia/engine/test_debug_listener.h b/fuchsia/engine/test_debug_listener.h new file mode 100644 index 0000000..fba93a7 --- /dev/null +++ b/fuchsia/engine/test_debug_listener.h
@@ -0,0 +1,67 @@ +// 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_ENGINE_TEST_DEBUG_LISTENER_H_ +#define FUCHSIA_ENGINE_TEST_DEBUG_LISTENER_H_ + +#include <fuchsia/web/cpp/fidl.h> +#include <lib/fidl/cpp/binding.h> + +#include "base/callback.h" +#include "base/containers/flat_set.h" +#include "base/containers/unique_ptr_adapters.h" +#include "base/macros.h" + +// Listens to debug events and enables test code to block until a desired +// number of DevTools ports are open. +class TestDebugListener : public fuchsia::web::DevToolsListener { + public: + TestDebugListener(); + ~TestDebugListener() final; + + // Spins a RunLoop until there are exactly |size| DevTools ports open. + void RunUntilNumberOfPortsIs(size_t size); + + base::flat_set<uint16_t>& debug_ports() { return debug_ports_; } + + private: + class TestPerContextListener + : public fuchsia::web::DevToolsPerContextListener { + public: + TestPerContextListener( + TestDebugListener* test_debug_listener, + fidl::InterfaceRequest<fuchsia::web::DevToolsPerContextListener> + listener); + ~TestPerContextListener() final; + + private: + // fuchsia::web::DevToolsPerContextListener implementation. + void OnHttpPortOpen(uint16_t port) final; + + uint16_t port_ = 0; + TestDebugListener* test_debug_listener_; + fidl::Binding<fuchsia::web::DevToolsPerContextListener> binding_; + + DISALLOW_COPY_AND_ASSIGN(TestPerContextListener); + }; + + // fuchsia::web::DevToolsListener implementation. + void OnContextDevToolsAvailable( + fidl::InterfaceRequest<fuchsia::web::DevToolsPerContextListener> listener) + final; + + void DestroyListener(TestPerContextListener* listener); + void AddPort(uint16_t port); + void RemovePort(uint16_t port); + + base::flat_set<uint16_t> debug_ports_; + base::flat_set<std::unique_ptr<TestPerContextListener>, + base::UniquePtrComparator> + per_context_listeners_; + base::OnceClosure run_ack_; + + DISALLOW_COPY_AND_ASSIGN(TestDebugListener); +}; + +#endif // FUCHSIA_ENGINE_TEST_DEBUG_LISTENER_H_
diff --git a/fuchsia/engine/web_engine_debug_integration_test.cc b/fuchsia/engine/web_engine_debug_integration_test.cc new file mode 100644 index 0000000..e8d8766 --- /dev/null +++ b/fuchsia/engine/web_engine_debug_integration_test.cc
@@ -0,0 +1,283 @@ +// 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 <fuchsia/web/cpp/fidl.h> +#include <lib/fidl/cpp/binding.h> +#include <lib/fidl/cpp/binding_set.h> + +#include "base/files/file_enumerator.h" +#include "base/fuchsia/file_utils.h" +#include "base/fuchsia/service_directory_client.h" +#include "base/json/json_reader.h" +#include "base/macros.h" +#include "fuchsia/base/fit_adapter.h" +#include "fuchsia/base/frame_test_util.h" +#include "fuchsia/base/result_receiver.h" +#include "fuchsia/base/test_navigation_listener.h" +#include "fuchsia/engine/test_debug_listener.h" +#include "net/http/http_status_code.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" +#include "net/url_request/url_fetcher.h" +#include "net/url_request/url_fetcher_delegate.h" +#include "net/url_request/url_request_test_util.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +const char kTestServerRoot[] = FILE_PATH_LITERAL("fuchsia/engine/test/data"); + +} // namespace + +class WebEngineDebugIntegrationTest : public testing::Test, + public net::URLFetcherDelegate { + public: + WebEngineDebugIntegrationTest() + : dev_tools_listener_binding_(&dev_tools_listener_) {} + + ~WebEngineDebugIntegrationTest() override = default; + + void SetUp() override { + web_context_provider_ = + base::fuchsia::ServiceDirectoryClient::ForCurrentProcess() + ->ConnectToService<fuchsia::web::ContextProvider>(); + web_context_provider_.set_error_handler( + [](zx_status_t status) { ADD_FAILURE(); }); + + WaitForWebEngine(); + + // Connect to the Debug API. + base::FileEnumerator file_enum(base::FilePath("/hub/c/chromium.cmx"), false, + base::FileEnumerator::DIRECTORIES); + base::FilePath chromium_path = file_enum.Next(); + ASSERT_FALSE(chromium_path.empty()); + + // There should only be one instance of WebEngine in the realm. + ASSERT_TRUE(file_enum.Next().empty()); + + debug_dir_ = std::make_unique<base::fuchsia::ServiceDirectoryClient>( + base::fuchsia::OpenDirectory(chromium_path.Append("out/debug"))); + debug_ = debug_dir_->ConnectToServiceSync<fuchsia::web::Debug>(); + + // Attach the DevToolsListener. EnableDevTools has an acknowledgement + // callback so the listener will have been added after this call returns. + debug_->EnableDevTools(dev_tools_listener_binding_.NewBinding()); + + request_context_getter_ = + base::MakeRefCounted<net::TestURLRequestContextGetter>( + message_loop_.task_runner()); + + test_server_.ServeFilesFromSourceDirectory(kTestServerRoot); + ASSERT_TRUE(test_server_.Start()); + } + + protected: + void WaitForWebEngine() { + // Create a throwaway web context to ensure the WebEngine process is + // initialized and a Debug instance can be created. This is necessary + // because the Debug service is not available on the debug directory until + // after the WebEngine is fully initialized. + fuchsia::web::CreateContextParams create_params; + auto directory = base::fuchsia::OpenDirectory( + base::FilePath(base::fuchsia::kServiceDirectoryPath)); + ASSERT_TRUE(directory.is_valid()); + create_params.set_service_directory(std::move(directory)); + + fuchsia::web::ContextPtr web_context; + web_context_provider_->Create(std::move(create_params), + web_context.NewRequest()); + web_context.set_error_handler([](zx_status_t status) { ADD_FAILURE(); }); + + fuchsia::web::FramePtr web_frame; + web_context->CreateFrame(web_frame.NewRequest()); + web_frame.set_error_handler([](zx_status_t status) { ADD_FAILURE(); }); + + fuchsia::web::NavigationControllerPtr nav_controller; + web_frame->GetNavigationController(nav_controller.NewRequest()); + nav_controller.set_error_handler([](zx_status_t status) { ADD_FAILURE(); }); + + base::RunLoop run_loop; + cr_fuchsia::ResultReceiver<fuchsia::web::NavigationState> result( + run_loop.QuitClosure()); + nav_controller->GetVisibleEntry( + cr_fuchsia::CallbackToFitFunction(result.GetReceiveCallback())); + run_loop.Run(); + + // Sanity check, the NavigationState should be empty at this point. + ASSERT_TRUE(result->IsEmpty()); + } + + base::Value GetDevToolsListFromPort(uint16_t port) { + std::string url = base::StringPrintf("http://127.0.0.1:%d/json/list", port); + std::unique_ptr<net::URLFetcher> fetcher = net::URLFetcher::Create( + GURL(url), net::URLFetcher::GET, this, TRAFFIC_ANNOTATION_FOR_TESTS); + fetcher->SetRequestContext(request_context_getter_.get()); + fetcher->Start(); + + base::RunLoop run_loop; + on_url_fetch_complete_ack_ = run_loop.QuitClosure(); + run_loop.Run(); + + if (fetcher->GetStatus().status() != net::URLRequestStatus::SUCCESS) + return base::Value(); + + if (fetcher->GetResponseCode() != net::HTTP_OK) + return base::Value(); + + std::string result; + if (!fetcher->GetResponseAsString(&result)) + return base::Value(); + + return base::JSONReader::Read(result).value_or(base::Value()); + } + + // fuchsia::web::URLFetcherDelegate implementation. + void OnURLFetchComplete(const net::URLFetcher* source) override { + if (on_url_fetch_complete_ack_) + std::move(on_url_fetch_complete_ack_).Run(); + } + + base::MessageLoopForIO message_loop_; + + TestDebugListener dev_tools_listener_; + fidl::Binding<fuchsia::web::DevToolsListener> dev_tools_listener_binding_; + std::unique_ptr<base::fuchsia::ServiceDirectoryClient> debug_dir_; + fuchsia::web::ContextProviderPtr web_context_provider_; + fuchsia::web::DebugSyncPtr debug_; + + scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_; + base::OnceClosure on_url_fetch_complete_ack_; + + net::EmbeddedTestServer test_server_; + + DISALLOW_COPY_AND_ASSIGN(WebEngineDebugIntegrationTest); +}; + +// Helper struct to intiialize all data necessary for a Context to create a +// Frame and navigate it to a specific URL. +struct TestContextAndFrame { + explicit TestContextAndFrame(fuchsia::web::ContextProvider* context_provider, + std::string url) { + // Create a Context, a Frame and navigate it to |url|. + auto directory = base::fuchsia::OpenDirectory( + base::FilePath(base::fuchsia::kServiceDirectoryPath)); + if (!directory.is_valid()) + return; + + fuchsia::web::CreateContextParams create_params; + create_params.set_service_directory(std::move(directory)); + context_provider->Create(std::move(create_params), context.NewRequest()); + context->CreateFrame(frame.NewRequest()); + frame->GetNavigationController(controller.NewRequest()); + if (!cr_fuchsia::LoadUrlAndExpectResponse( + controller.get(), fuchsia::web::LoadUrlParams(), url)) { + ADD_FAILURE(); + context.Unbind(); + frame.Unbind(); + controller.Unbind(); + return; + } + } + ~TestContextAndFrame() = default; + + fuchsia::web::ContextPtr context; + fuchsia::web::FramePtr frame; + fuchsia::web::NavigationControllerPtr controller; + + DISALLOW_COPY_AND_ASSIGN(TestContextAndFrame); +}; + +// Test the Debug service is properly started and accessible. +TEST_F(WebEngineDebugIntegrationTest, DebugService) { + std::string url = test_server_.GetURL("/title1.html").spec(); + TestContextAndFrame frame_data(web_context_provider_.get(), url); + ASSERT_TRUE(frame_data.context); + + // Test the debug information is correct. + dev_tools_listener_.RunUntilNumberOfPortsIs(1u); + + base::Value devtools_list = + GetDevToolsListFromPort(*dev_tools_listener_.debug_ports().begin()); + ASSERT_TRUE(devtools_list.is_list()); + EXPECT_EQ(devtools_list.GetList().size(), 1u); + + base::Value* devtools_url = devtools_list.GetList()[0].FindPath("url"); + ASSERT_TRUE(devtools_url->is_string()); + EXPECT_EQ(devtools_url->GetString(), url); + + base::Value* devtools_title = devtools_list.GetList()[0].FindPath("title"); + ASSERT_TRUE(devtools_title->is_string()); + EXPECT_EQ(devtools_title->GetString(), "title 1"); + + // Unbind the context and wait for the listener to no longer have any active + // DevTools port. + frame_data.context.Unbind(); + dev_tools_listener_.RunUntilNumberOfPortsIs(0); +} + +TEST_F(WebEngineDebugIntegrationTest, MultipleDebugClients) { + std::string url1 = test_server_.GetURL("/title1.html").spec(); + TestContextAndFrame frame_data1(web_context_provider_.get(), url1); + ASSERT_TRUE(frame_data1.context); + + // Test the debug information is correct. + dev_tools_listener_.RunUntilNumberOfPortsIs(1u); + uint16_t port1 = *dev_tools_listener_.debug_ports().begin(); + + base::Value devtools_list1 = GetDevToolsListFromPort(port1); + ASSERT_TRUE(devtools_list1.is_list()); + EXPECT_EQ(devtools_list1.GetList().size(), 1u); + + base::Value* devtools_url1 = devtools_list1.GetList()[0].FindPath("url"); + ASSERT_TRUE(devtools_url1->is_string()); + EXPECT_EQ(devtools_url1->GetString(), url1); + + base::Value* devtools_title1 = devtools_list1.GetList()[0].FindPath("title"); + ASSERT_TRUE(devtools_title1->is_string()); + EXPECT_EQ(devtools_title1->GetString(), "title 1"); + + // Connect a second Debug interface. + fuchsia::web::DebugSyncPtr debug2; + debug2 = debug_dir_->ConnectToServiceSync<fuchsia::web::Debug>(); + TestDebugListener dev_tools_listener2; + fidl::Binding<fuchsia::web::DevToolsListener> dev_tools_listener_binding2( + &dev_tools_listener2); + debug2->EnableDevTools(dev_tools_listener_binding2.NewBinding()); + + // Create a second Context, a second Frame and navigate it to title2.html. + std::string url2 = test_server_.GetURL("/title2.html").spec(); + TestContextAndFrame frame_data2(web_context_provider_.get(), url2); + ASSERT_TRUE(frame_data2.context); + + // Ensure each DevTools listener has the right information. + dev_tools_listener_.RunUntilNumberOfPortsIs(2u); + dev_tools_listener2.RunUntilNumberOfPortsIs(1u); + + uint16_t port2 = *dev_tools_listener2.debug_ports().begin(); + ASSERT_NE(port1, port2); + ASSERT_NE(dev_tools_listener_.debug_ports().find(port2), + dev_tools_listener_.debug_ports().end()); + + base::Value devtools_list2 = GetDevToolsListFromPort(port2); + ASSERT_TRUE(devtools_list2.is_list()); + EXPECT_EQ(devtools_list2.GetList().size(), 1u); + + base::Value* devtools_url2 = devtools_list2.GetList()[0].FindPath("url"); + ASSERT_TRUE(devtools_url2->is_string()); + EXPECT_EQ(devtools_url2->GetString(), url2); + + base::Value* devtools_title2 = devtools_list2.GetList()[0].FindPath("title"); + ASSERT_TRUE(devtools_title2->is_string()); + EXPECT_EQ(devtools_title2->GetString(), "title 2"); + + // Unbind the first Context, each listener should still have one open port. + frame_data1.context.Unbind(); + dev_tools_listener_.RunUntilNumberOfPortsIs(1u); + dev_tools_listener2.RunUntilNumberOfPortsIs(1u); + + // Unbind the second Context, no listener should have any open port. + frame_data2.context.Unbind(); + dev_tools_listener_.RunUntilNumberOfPortsIs(0); + dev_tools_listener2.RunUntilNumberOfPortsIs(0); +} \ No newline at end of file
diff --git a/infra/config/cr-buildbucket.cfg b/infra/config/cr-buildbucket.cfg index 1a76fc8..59eac568 100644 --- a/infra/config/cr-buildbucket.cfg +++ b/infra/config/cr-buildbucket.cfg
@@ -1810,6 +1810,14 @@ mixins: "win-ci" } builders { + name: "win-pixel-builder-rel" + mixins: "win-ci" + } + builders { + name: "win-pixel-tester-rel" + mixins: "win-ci" + } + builders { name: "win32-arm64-rel" dimensions: "os:Windows-10" dimensions: "cpu:x86"
diff --git a/ios/chrome/app/application_delegate/user_activity_handler_unittest.mm b/ios/chrome/app/application_delegate/user_activity_handler_unittest.mm index d91cbe2..dbdbdf7 100644 --- a/ios/chrome/app/application_delegate/user_activity_handler_unittest.mm +++ b/ios/chrome/app/application_delegate/user_activity_handler_unittest.mm
@@ -27,7 +27,6 @@ #import "ios/chrome/browser/tabs/legacy_tab_helper.h" #import "ios/chrome/browser/tabs/tab.h" #import "ios/chrome/browser/tabs/tab_model.h" -#import "ios/chrome/browser/tabs/tab_model_observer.h" #import "ios/chrome/browser/u2f/u2f_tab_helper.h" #import "ios/chrome/browser/ui/main/test/stub_browser_interface_provider.h" #import "ios/chrome/browser/url_loading/url_loading_params.h"
diff --git a/ios/chrome/browser/crash_report/crash_report_helper.mm b/ios/chrome/browser/crash_report/crash_report_helper.mm index ff10d64..7688f518 100644 --- a/ios/chrome/browser/crash_report/crash_report_helper.mm +++ b/ios/chrome/browser/crash_report/crash_report_helper.mm
@@ -77,7 +77,7 @@ @end -// TabModelObserver that some tabs stats to be sent to the crash server. +// WebStateList Observer that some tabs stats to be sent to the crash server. @interface CrashReporterTabStateObserver : NSObject <CRWWebStateObserver, WebStateListObserving> { @private
diff --git a/ios/chrome/browser/signin/identity_manager_factory.cc b/ios/chrome/browser/signin/identity_manager_factory.cc index 0d7e6e2..475cd00 100644 --- a/ios/chrome/browser/signin/identity_manager_factory.cc +++ b/ios/chrome/browser/signin/identity_manager_factory.cc
@@ -12,6 +12,7 @@ #include "components/keyed_service/ios/browser_state_dependency_manager.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/signin/core/browser/account_consistency_method.h" +#include "components/signin/core/browser/gaia_cookie_manager_service.h" #include "components/signin/core/browser/identity_manager_wrapper.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_manager.h" @@ -62,11 +63,10 @@ std::unique_ptr<SigninManager> BuildSigninManager( ios::ChromeBrowserState* chrome_browser_state, AccountTrackerService* account_tracker_service, - ProfileOAuth2TokenService* token_service, - GaiaCookieManagerService* gaia_cookie_manager_service) { + ProfileOAuth2TokenService* token_service) { std::unique_ptr<SigninManager> service = std::make_unique<SigninManager>( SigninClientFactory::GetForBrowserState(chrome_browser_state), - token_service, account_tracker_service, gaia_cookie_manager_service, + token_service, account_tracker_service, signin::AccountConsistencyMethod::kMirror); service->Initialize(GetApplicationContext()->GetLocalState()); return service; @@ -140,8 +140,7 @@ SigninClientFactory::GetForBrowserState(browser_state)); std::unique_ptr<SigninManager> signin_manager = BuildSigninManager( - browser_state, account_tracker_service.get(), token_service.get(), - gaia_cookie_manager_service.get()); + browser_state, account_tracker_service.get(), token_service.get()); auto primary_account_mutator = std::make_unique<identity::PrimaryAccountMutatorImpl>(
diff --git a/ios/chrome/browser/tabs/BUILD.gn b/ios/chrome/browser/tabs/BUILD.gn index 2032415..872a462 100644 --- a/ios/chrome/browser/tabs/BUILD.gn +++ b/ios/chrome/browser/tabs/BUILD.gn
@@ -10,7 +10,6 @@ "tab_model.h", "tab_model_list.h", "tab_model_list_observer.h", - "tab_model_observer.h", "tab_model_synced_window_delegate.h", "tab_model_synced_window_delegate_getter.h", "tab_private.h", @@ -45,8 +44,6 @@ "tab_model_closing_web_state_observer.h", "tab_model_closing_web_state_observer.mm", "tab_model_list.mm", - "tab_model_observers.h", - "tab_model_observers.mm", "tab_model_selected_tab_observer.h", "tab_model_selected_tab_observer.mm", "tab_model_synced_window_delegate.mm",
diff --git a/ios/chrome/browser/tabs/tab_model.h b/ios/chrome/browser/tabs/tab_model.h index a82734e..f337aedd 100644 --- a/ios/chrome/browser/tabs/tab_model.h +++ b/ios/chrome/browser/tabs/tab_model.h
@@ -19,7 +19,6 @@ @class SessionServiceIOS; @class SessionWindowIOS; @class Tab; -@protocol TabModelObserver; class TabModelSyncedWindowDelegate; class TabUsageRecorder; class WebStateList; @@ -141,17 +140,6 @@ // when the app is shutting down. - (void)haltAllTabs; -// Notifies observers that the given |tab| was changed. -- (void)notifyTabChanged:(Tab*)tab; - -// Adds |observer| to the list of observers. |observer| is not retained. Does -// nothing if |observer| is already in the list. Any added observers must be -// explicitly removed before the TabModel is destroyed. -- (void)addObserver:(id<TabModelObserver>)observer; - -// Removes |observer| from the list of observers. -- (void)removeObserver:(id<TabModelObserver>)observer; - // Resets all session counters. - (void)resetSessionMetrics;
diff --git a/ios/chrome/browser/tabs/tab_model.mm b/ios/chrome/browser/tabs/tab_model.mm index 336f703..a813b48 100644 --- a/ios/chrome/browser/tabs/tab_model.mm +++ b/ios/chrome/browser/tabs/tab_model.mm
@@ -42,7 +42,6 @@ #import "ios/chrome/browser/tabs/tab.h" #import "ios/chrome/browser/tabs/tab_model_closing_web_state_observer.h" #import "ios/chrome/browser/tabs/tab_model_list.h" -#import "ios/chrome/browser/tabs/tab_model_observers.h" #import "ios/chrome/browser/tabs/tab_model_selected_tab_observer.h" #import "ios/chrome/browser/tabs/tab_model_synced_window_delegate.h" #import "ios/chrome/browser/tabs/tab_model_web_state_list_delegate.h" @@ -240,8 +239,6 @@ std::unique_ptr<TabUsageRecorder> _tabUsageRecorder; // Saves session's state. SessionServiceIOS* _sessionService; - // List of TabModelObservers. - TabModelObservers* _observers; // Used to ensure thread-safety of the certificate policy management code. base::CancelableTaskTracker _clearPoliciesTaskTracker; @@ -266,9 +263,6 @@ - (void)dealloc { // browserStateDestroyed should always have been called before destruction. DCHECK(!_browserState); - - // Make sure the observers do clean after themselves. - DCHECK([_observers empty]); } #pragma mark - Public methods @@ -312,8 +306,6 @@ - (instancetype)initWithSessionService:(SessionServiceIOS*)service browserState:(ios::ChromeBrowserState*)browserState { if ((self = [super init])) { - _observers = [TabModelObservers observers]; - _webStateListDelegate = std::make_unique<TabModelWebStateListDelegate>(); _webStateList = std::make_unique<WebStateList>(_webStateListDelegate.get()); @@ -508,18 +500,6 @@ } } -- (void)notifyTabChanged:(Tab*)tab { - [_observers tabModel:self didChangeTab:tab]; -} - -- (void)addObserver:(id<TabModelObserver>)observer { - [_observers addObserver:observer]; -} - -- (void)removeObserver:(id<TabModelObserver>)observer { - [_observers removeObserver:observer]; -} - - (void)resetSessionMetrics { if (_webStateListMetricsObserver) _webStateListMetricsObserver->ResetSessionMetrics(); @@ -613,9 +593,6 @@ // It is only ok to pass a nil |window| during the initial restore. DCHECK(window || initialRestore); - // The initial restore can only happen before observers are registered. - DCHECK(!initialRestore || [_observers empty]); - // Setting the sesion progress to |YES|, so BVC can check it to work around // crbug.com/763964. _restoringSession = YES; @@ -740,8 +717,6 @@ - (void)webState:(web::WebState*)webState didFinishNavigation:(web::NavigationContext*)navigation { - Tab* tab = LegacyTabHelper::GetTabForWebState(webState); - [self notifyTabChanged:tab]; if (!navigation->IsSameDocument() && navigation->HasCommitted() && !self.offTheRecord) { @@ -752,7 +727,6 @@ - (void)webState:(web::WebState*)webState didStartNavigation:(web::NavigationContext*)navigation { - Tab* tab = LegacyTabHelper::GetTabForWebState(webState); // In order to avoid false positive in the crash loop detection, disable the // counter as soon as an URL is loaded. This requires an user action and is a @@ -769,8 +743,6 @@ _tabUsageRecorder->RecordPageLoadStart(webState); } - [self notifyTabChanged:tab]; - DCHECK(webState->GetNavigationManager()); web::NavigationItem* navigationItem = webState->GetNavigationManager()->GetPendingItem(); @@ -800,9 +772,6 @@ } - (void)webState:(web::WebState*)webState didLoadPageWithSuccess:(BOOL)success { - Tab* tab = LegacyTabHelper::GetTabForWebState(webState); - [self notifyTabChanged:tab]; - RecordInterfaceOrientationMetric(); RecordMainFrameNavigationMetric(webState); @@ -811,25 +780,6 @@ loadSuccess:success]; } -- (void)webState:(web::WebState*)webState - didChangeLoadingProgress:(double)progress { - // TODO(crbug.com/546406): It is probably possible to do something smarter, - // but the fact that this is not always sent will have to be taken into - // account. - Tab* tab = LegacyTabHelper::GetTabForWebState(webState); - [self notifyTabChanged:tab]; -} - -- (void)webStateDidChangeTitle:(web::WebState*)webState { - Tab* tab = LegacyTabHelper::GetTabForWebState(webState); - [self notifyTabChanged:tab]; -} - -- (void)webStateDidChangeVisibleSecurityState:(web::WebState*)webState { - Tab* tab = LegacyTabHelper::GetTabForWebState(webState); - [self notifyTabChanged:tab]; -} - - (void)webStateDestroyed:(web::WebState*)webState { // The TabModel is removed from WebState's observer when the WebState is // detached from WebStateList which happens before WebState destructor, @@ -837,11 +787,6 @@ NOTREACHED(); } -- (void)webStateDidStopLoading:(web::WebState*)webState { - Tab* tab = LegacyTabHelper::GetTabForWebState(webState); - [self notifyTabChanged:tab]; -} - #pragma mark - WebStateListObserving - (void)webStateList:(WebStateList*)webStateList
diff --git a/ios/chrome/browser/tabs/tab_model_observer.h b/ios/chrome/browser/tabs/tab_model_observer.h deleted file mode 100644 index 9d99ceca..0000000 --- a/ios/chrome/browser/tabs/tab_model_observer.h +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 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. - -#ifndef IOS_CHROME_BROWSER_TABS_TAB_MODEL_OBSERVER_H_ -#define IOS_CHROME_BROWSER_TABS_TAB_MODEL_OBSERVER_H_ - -#import <Foundation/Foundation.h> - -@class Tab; -@class TabModel; - -// Observers implement these methods to be alerted to changes in the model. -// These methods are all optional. -@protocol TabModelObserver<NSObject> -@optional - -// Some properties about the given tab changed, such as the URL or title. -- (void)tabModel:(TabModel*)model didChangeTab:(Tab*)tab; - -@end - -#endif // IOS_CHROME_BROWSER_TABS_TAB_MODEL_OBSERVER_H_
diff --git a/ios/chrome/browser/tabs/tab_model_observers.h b/ios/chrome/browser/tabs/tab_model_observers.h deleted file mode 100644 index ab382a9c..0000000 --- a/ios/chrome/browser/tabs/tab_model_observers.h +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_TABS_TAB_MODEL_OBSERVERS_H_ -#define IOS_CHROME_BROWSER_TABS_TAB_MODEL_OBSERVERS_H_ - -#import "base/ios/crb_protocol_observers.h" -#import "ios/chrome/browser/tabs/tab_model_observer.h" - -@interface TabModelObservers : CRBProtocolObservers<TabModelObserver> - -+ (instancetype)observers; - -@end - -#endif // IOS_CHROME_BROWSER_TABS_TAB_MODEL_OBSERVERS_H_
diff --git a/ios/chrome/browser/tabs/tab_model_observers.mm b/ios/chrome/browser/tabs/tab_model_observers.mm deleted file mode 100644 index fd86c71..0000000 --- a/ios/chrome/browser/tabs/tab_model_observers.mm +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/tabs/tab_model_observers.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -@implementation TabModelObservers - -+ (instancetype)observers { - return [self observersWithProtocol:@protocol(TabModelObserver)]; -} - -@end
diff --git a/ios/chrome/browser/ui/activity_services/BUILD.gn b/ios/chrome/browser/ui/activity_services/BUILD.gn index 2e60c5b..cd31a20 100644 --- a/ios/chrome/browser/ui/activity_services/BUILD.gn +++ b/ios/chrome/browser/ui/activity_services/BUILD.gn
@@ -146,3 +146,28 @@ ] libs = [ "XCTest.framework" ] } + +source_set("eg2_tests") { + defines = [ "CHROME_EARL_GREY_2" ] + configs += [ + "//build/config/compiler:enable_arc", + "//build/config/ios:xctest_config", + ] + testonly = true + + sources = [ + "activity_service_controller_egtest.mm", + ] + + deps = [ + "//components/strings", + "//ios/chrome/app/strings:ios_strings_grit", + "//ios/chrome/test/earl_grey:eg_test_support+eg2", + "//ios/testing/earl_grey:eg_test_support+eg2", + "//ios/third_party/earl_grey2:test_lib", + "//ios/web/public/test/http_server", + "//ui/base", + ] + + libs = [ "UIKit.framework" ] +}
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm index 6130515..dbb026e7 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -77,7 +77,6 @@ #import "ios/chrome/browser/tabs/legacy_tab_helper.h" #import "ios/chrome/browser/tabs/tab.h" #import "ios/chrome/browser/tabs/tab_model.h" -#import "ios/chrome/browser/tabs/tab_model_observer.h" #import "ios/chrome/browser/tabs/tab_private.h" #import "ios/chrome/browser/translate/chrome_ios_translate_client.h" #import "ios/chrome/browser/ui/activity_services/activity_service_legacy_coordinator.h" @@ -393,7 +392,6 @@ SideSwipeControllerDelegate, SigninPresenter, SnapshotGeneratorDelegate, - TabModelObserver, TabStripPresentation, ToolbarHeightProviderForFullscreen, WebStateListObserving, @@ -1106,7 +1104,7 @@ } - (web::WebState*)currentWebState { - return self.tabModel.currentTab.webState; + return self.tabModel.webStateList->GetActiveWebState(); } - (BOOL)usesSafeInsetsForViewportAdjustments { @@ -1464,7 +1462,6 @@ // SideSwipeController is a tab model observer, so it needs to stop observing // before self.tabModel is released. _sideSwipeController = nil; - [self.tabModel removeObserver:self]; self.tabModel.webStateList->RemoveObserver(_webStateListObserver.get()); _webStateListObserver.reset(); _allWebStateObservationForwarder = nullptr; @@ -1933,7 +1930,6 @@ ->GetForBrowserState(_browserState) ->SetWebStateList(self.tabModel.webStateList); - [self.tabModel addObserver:self]; _webStateObserverBridge = std::make_unique<web::WebStateObserverBridge>(self); _allWebStateObservationForwarder = std::make_unique<AllWebStateObservationForwarder>( @@ -3519,6 +3515,12 @@ #pragma mark - CRWWebStateObserver methods. +- (void)webState:(web::WebState*)webState + didStartNavigation:(web::NavigationContext*)navigation { + if (webState == self.currentWebState) + [self updateToolbar]; +} + // TODO(crbug.com/918934): This call to closeFindInPage incorrectly triggers for // all navigations, not just navigations in the active WebState. - (void)webState:(web::WebState*)webState @@ -3664,8 +3666,7 @@ NOTREACHED(); } // If a native controller is vended before its tab is added to the tab model, - // use the temporary key and add it under the new tab's tabId in the - // TabModelObserver callback. This happens: + // use the temporary key. This happens: // - when there is no current tab (occurs when vending the NTP controller for // the first tab that is opened), // - when the current tab's url doesn't match |url| (occurs when a native @@ -4490,15 +4491,6 @@ willOpenInBackground:!activating]; } -#pragma mark - TabModelObserver methods - -- (void)tabModel:(TabModel*)model didChangeTab:(Tab*)tab { - DCHECK(tab && ([self.tabModel indexOfTab:tab] != NSNotFound)); - if (tab == self.tabModel.currentTab) { - [self updateToolbar]; - } -} - #pragma mark - WebStateListObserver helpers (new tab animations) - (void)initiateNewTabAnimationForWebState:(web::WebState*)webState
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm index 5b6ea9b..b4ea30e8 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm
@@ -31,7 +31,6 @@ #import "ios/chrome/browser/tabs/tab.h" #import "ios/chrome/browser/tabs/tab_helper_util.h" #import "ios/chrome/browser/tabs/tab_model.h" -#import "ios/chrome/browser/tabs/tab_model_observer.h" #import "ios/chrome/browser/ui/activity_services/share_protocol.h" #import "ios/chrome/browser/ui/activity_services/share_to_data.h" #import "ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h" @@ -88,8 +87,7 @@ @class ToolbarButtonUpdater; // Private methods in BrowserViewController to test. -@interface BrowserViewController (Testing) <CRWNativeContentProvider, - TabModelObserver> +@interface BrowserViewController (Testing) <CRWNativeContentProvider> - (void)pageLoadStarted:(NSNotification*)notification; - (void)pageLoadComplete:(NSNotification*)notification; - (void)webStateSelected:(web::WebState*)webState @@ -216,8 +214,6 @@ initWithRepresentedObject:[OCMockObject niceMockForClass:[Tab class]]]; [[[tabModel stub] andReturn:currentTab] currentTab]; [[[tabModel stub] andReturn:currentTab] tabAtIndex:0]; - [[tabModel stub] addObserver:[OCMArg any]]; - [[tabModel stub] removeObserver:[OCMArg any]]; [[tabModel stub] saveSessionImmediately:NO]; [[tabModel stub] setCurrentTab:[OCMArg any]]; [[tabModel stub] closeAllTabs]; @@ -230,6 +226,7 @@ [currentTab setWebState:webStateImpl_]; tabModel_.webStateList->InsertWebState(0, std::move(webState), 0, WebStateOpener()); + tabModel_.webStateList->ActivateWebStateAt(0); // Load TemplateURLService. TemplateURLService* template_url_service =
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_controller_unittest.mm b/ios/chrome/browser/ui/tabs/tab_strip_controller_unittest.mm index e09e5bf..ffa2987 100644 --- a/ios/chrome/browser/ui/tabs/tab_strip_controller_unittest.mm +++ b/ios/chrome/browser/ui/tabs/tab_strip_controller_unittest.mm
@@ -140,14 +140,6 @@ WebStateList::CLOSE_NO_FLAGS); } -- (void)addObserver:(id<TabModelObserver>)observer { - // Do nothing. -} - -- (void)removeObserver:(id<TabModelObserver>)observer { - // Do nothing. -} - - (WebStateList*)webStateList { return _webStateList.get(); }
diff --git a/ios/chrome/browser/web/forms_egtest.mm b/ios/chrome/browser/web/forms_egtest.mm index f34cb6a0..7b33e06 100644 --- a/ios/chrome/browser/web/forms_egtest.mm +++ b/ios/chrome/browser/web/forms_egtest.mm
@@ -242,6 +242,11 @@ // Tests that a POST followed by navigating to a new page and then tapping back // to the form result page resends data. - (void)testRepostFormAfterTappingBack { + // TODO(crbug.com/968296): Test is failing on iPad for slim nav. + if (IsIPadIdiom() && web::GetWebClient()->IsSlimNavigationManagerEnabled()) { + EARL_GREY_TEST_DISABLED(@"Test disabled on iPad."); + } + [self setUpFormTestSimpleHttpServer]; const GURL destinationURL = GetDestinationUrl();
diff --git a/ios/chrome/browser/web_state_list/web_state_list_favicon_driver_observer.h b/ios/chrome/browser/web_state_list/web_state_list_favicon_driver_observer.h index 255197f..b4031d0 100644 --- a/ios/chrome/browser/web_state_list/web_state_list_favicon_driver_observer.h +++ b/ios/chrome/browser/web_state_list/web_state_list_favicon_driver_observer.h
@@ -68,7 +68,7 @@ // Maps FaviconDriver to the WebState they are attached to. Used // to find the WebState that should be passed when forwarding the - // notification to TabModelObservers. + // notification to WebStateFaviconDriverObservers. std::map<favicon::FaviconDriver*, web::WebState*> driver_to_web_state_map_; ScopedObserver<WebStateList, WebStateListObserver> web_state_list_observer_;
diff --git a/ios/chrome/test/earl_grey2/BUILD.gn b/ios/chrome/test/earl_grey2/BUILD.gn index fa31f92..e249ed8 100644 --- a/ios/chrome/test/earl_grey2/BUILD.gn +++ b/ios/chrome/test/earl_grey2/BUILD.gn
@@ -39,6 +39,7 @@ xcode_test_application_name = "ios_chrome_eg2tests" deps = [ + "//ios/chrome/browser/ui/activity_services:eg2_tests", "//ios/chrome/browser/ui/download:eg2_tests", ] }
diff --git a/ios/web_view/internal/signin/web_view_identity_manager_factory.mm b/ios/web_view/internal/signin/web_view_identity_manager_factory.mm index b814bb9..5f3b7f2 100644 --- a/ios/web_view/internal/signin/web_view_identity_manager_factory.mm +++ b/ios/web_view/internal/signin/web_view_identity_manager_factory.mm
@@ -12,6 +12,7 @@ #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" #include "components/signin/core/browser/account_consistency_method.h" +#include "components/signin/core/browser/gaia_cookie_manager_service.h" #include "components/signin/core/browser/identity_manager_wrapper.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_manager.h" @@ -73,8 +74,7 @@ std::unique_ptr<SigninManager> BuildSigninManager( WebViewBrowserState* browser_state, AccountTrackerService* account_tracker_service, - ProfileOAuth2TokenService* token_service, - GaiaCookieManagerService* gaia_cookie_manager_service) { + ProfileOAuth2TokenService* token_service) { // Clearing the sign in state on start up greatly simplifies the management of // ChromeWebView's signin state. PrefService* pref_service = browser_state->GetPrefs(); @@ -84,7 +84,7 @@ std::unique_ptr<SigninManager> service = std::make_unique<SigninManager>( WebViewSigninClientFactory::GetForBrowserState(browser_state), - token_service, account_tracker_service, gaia_cookie_manager_service, + token_service, account_tracker_service, signin::AccountConsistencyMethod::kDisabled); service->Initialize(ApplicationContext::GetInstance()->GetLocalState()); return service; @@ -142,8 +142,7 @@ WebViewSigninClientFactory::GetForBrowserState(browser_state)); std::unique_ptr<SigninManager> signin_manager = BuildSigninManager( - browser_state, account_tracker_service.get(), token_service.get(), - gaia_cookie_manager_service.get()); + browser_state, account_tracker_service.get(), token_service.get()); auto primary_account_mutator = std::make_unique<identity::PrimaryAccountMutatorImpl>(
diff --git a/mojo/public/cpp/bindings/receiver_set.h b/mojo/public/cpp/bindings/receiver_set.h index 5019554..5244f6a 100644 --- a/mojo/public/cpp/bindings/receiver_set.h +++ b/mojo/public/cpp/bindings/receiver_set.h
@@ -338,14 +338,6 @@ template <typename Interface, typename ContextType = void> using ReceiverSet = ReceiverSetBase<Receiver<Interface>, ContextType>; -// Helper for a set of Receivers where each bound Receiver is tied to an owned -// implementation. The |Add()| method takes a std::unique_ptr<Interface> for -// each bound implementation. -template <typename Interface, typename ContextType = void> -using OwnedReceiverSet = - ReceiverSetBase<Receiver<Interface, UniquePtrImplRefTraits<Interface>>, - ContextType>; - } // namespace mojo #endif // MOJO_PUBLIC_CPP_BINDINGS_RECEIVER_SET_H_
diff --git a/mojo/public/cpp/bindings/tests/new_endpoint_types_unittest.cc b/mojo/public/cpp/bindings/tests/new_endpoint_types_unittest.cc index c254fd9..d421da9c 100644 --- a/mojo/public/cpp/bindings/tests/new_endpoint_types_unittest.cc +++ b/mojo/public/cpp/bindings/tests/new_endpoint_types_unittest.cc
@@ -18,8 +18,8 @@ #include "mojo/public/cpp/bindings/associated_receiver_set.h" #include "mojo/public/cpp/bindings/associated_remote.h" #include "mojo/public/cpp/bindings/receiver.h" -#include "mojo/public/cpp/bindings/receiver_set.h" #include "mojo/public/cpp/bindings/remote.h" +#include "mojo/public/cpp/bindings/unique_receiver_set.h" #include "mojo/public/interfaces/bindings/tests/new_endpoint_types.test-mojom.h" #include "testing/gtest/include/gtest/gtest.h" @@ -71,7 +71,7 @@ private: mojo::Receiver<mojom::WidgetFactory> receiver_; - mojo::OwnedReceiverSet<mojom::Widget> widgets_; + mojo::UniqueReceiverSet<mojom::Widget> widgets_; DISALLOW_COPY_AND_ASSIGN(FactoryImpl); };
diff --git a/mojo/public/cpp/system/README.md b/mojo/public/cpp/system/README.md index 60ef3f7a..07bc7d3 100644 --- a/mojo/public/cpp/system/README.md +++ b/mojo/public/cpp/system/README.md
@@ -145,10 +145,10 @@ ``` cpp mojo::ScopedSharedBufferMapping mapping = buffer->Map(64); -static_cast<int*>(mapping.get()) = 42; +static_cast<int*>(mapping.get())[0] = 42; mojo::ScopedSharedBufferMapping another_mapping = buffer->MapAtOffset(64, 4); -static_cast<int*>(mapping.get()) = 43; +static_cast<int*>(mapping.get())[0] = 43; ``` When `mapping` and `another_mapping` are destroyed, they automatically unmap
diff --git a/net/base/net_error_list.h b/net/base/net_error_list.h index 9614b3d8..38cdde8 100644 --- a/net/base/net_error_list.h +++ b/net/base/net_error_list.h
@@ -309,9 +309,7 @@ // Server request for client certificate did not contain any types we support. NET_ERROR(CLIENT_AUTH_CERT_TYPE_UNSUPPORTED, -151) -// Server requested one type of cert, then requested a different type while the -// first was still being generated. -NET_ERROR(ORIGIN_BOUND_CERT_GENERATION_TYPE_MISMATCH, -152) +// Error -152 was removed (ORIGIN_BOUND_CERT_GENERATION_TYPE_MISMATCH) // An SSL peer sent us a fatal decrypt_error alert. This typically occurs when // a peer could not correctly verify a signature (in CertificateVerify or
diff --git a/net/dns/host_resolver_manager.cc b/net/dns/host_resolver_manager.cc index 1b17b2c..52f18829 100644 --- a/net/dns/host_resolver_manager.cc +++ b/net/dns/host_resolver_manager.cc
@@ -2678,9 +2678,10 @@ // TODO(crbug.com/878582): Respect the type of cache lookup that should be // performed. - if (out_tasks->front() == TaskType::SECURE_CACHE_LOOKUP || - out_tasks->front() == TaskType::INSECURE_CACHE_LOOKUP || - out_tasks->front() == TaskType::CACHE_LOOKUP) { + if (!out_tasks->empty() && + (out_tasks->front() == TaskType::SECURE_CACHE_LOOKUP || + out_tasks->front() == TaskType::INSECURE_CACHE_LOOKUP || + out_tasks->front() == TaskType::CACHE_LOOKUP)) { out_tasks->pop_front(); if (cache_usage == ResolveHostParameters::CacheUsage::ALLOWED || cache_usage == ResolveHostParameters::CacheUsage::STALE_ALLOWED) {
diff --git a/net/docs/proxy.md b/net/docs/proxy.md index 9524db0d..8b99c8e2 100644 --- a/net/docs/proxy.md +++ b/net/docs/proxy.md
@@ -1,45 +1,47 @@ # Proxy support in Chrome -This document establishes basic proxy terminology, as well as describing -behaviors specific to Chrome. +This document establishes basic proxy terminology and describes Chrome-specific +proxy behaviors. -## Proxy Server +[TOC] -A proxy server is an intermediary used for network requests. It can be -identified by the 3-tuple (scheme, host, port) where: +## Proxy server identifiers -* scheme - protocol used to communicate with the proxy (ex: SOCKSv5, HTTPS). -* host - IP or hostname of the proxy server (ex: 192.168.0.1) -* port - TCP/UDP port number (ex: 443) +A proxy server is an intermediary used for network requests. A proxy server can +be described by its address, along with the proxy scheme that should be used to +communicate with it. -There are a variety of proxy server schemes supported by Chrome. When using an -explicit proxy in the browser, multiple layers of the network request are -impacted. +This can be written as a string using either the "PAC format" or the "URI +format". -Difference between proxy server schemes include: +The PAC format is how one names a proxy server in [Proxy +auto-config](https://en.wikipedia.org/wiki/Proxy_auto-config) scripts. For +example: +* `PROXY foo:2138` +* `SOCKS5 foo:1080` +* `DIRECT` -* Is communication to the proxy done over a secure channel? -* Is name resolution (ex: DNS) done client side, or proxy side? -* What authentication schemes to the proxy server are supported? -* What network traffic can be sent through the proxy? +The "URI format" instead encodes the information as a URL. For example: +* `foo:2138` +* `http://foo:2138` +* `socks5://foo:1080` +* `direct://` -Identifiers for proxy servers are often written as strings, using either the -PAC format (ex: `PROXY foo`) or Chrome's URI format (ex: `http://foo`). +The port number is optional in both formats. When omitted, a per-scheme default +is used. -When a proxy server's scheme is not stated, it's assumed to be HTTP in most -contexts. +See the [Proxy server schemes](#Proxy-server-schemes) section for details on +what schemes Chrome supports, and how to write them in the PAC and URI formats. -This can lead to some confusion, particularly when discussing system proxy -settings. Major platform UIs have converged on the term "Secure proxy" to mean -the host:port for an (insecure) HTTP proxy to use for proxying https:// URLs. +Most UI surfaces in Chrome (including command lines and policy) expect URI +formatted proxy server identifiers. However outside of Chrome, proxy servers +are generally identified less precisely by just an address -- the proxy +scheme is assumed based on context. -So when someone refers to their "HTTPS proxy" be aware of this ambiguity. The -intended meaning could be either "an HTTP proxy for https:// URLs", or "a proxy -using the HTTPS scheme". - -In this document when we say "an HTTPS proxy", we always mean "a proxy -that the browser speaks HTTPS to", and not "an (HTTP) proxy used to proxy -https:// URLs". +In Windows' proxy settings there are host and port fields for the +"HTTP", "Secure", "FTP", and "SOCKS" proxy. With the exception of "SOCKS", +those are all identifiers for insecure HTTP proxy servers (proxy scheme is +assumed as HTTP). ## Proxy resolution @@ -49,31 +51,42 @@ to send the request to. This can be either a proxy server, or the target host. This is called proxy resolution. The input to proxy resolution is a URL, and -the output is an ordered list of proxy server options. +the output is an ordered list of [proxy server +identifiers](#Proxy-server-identifiers). What proxies to use can be described using either: -* Manual proxy settings - proxy resolution is defined using a declarative set - of rules. These rules are expressed as a mapping from URL scheme to proxy - server(s), and a list of proxy bypass rules for when to go DIRECT instead of - using the mapped proxy. +* [Manual proxy settings](#Manual-proxy-settings) - proxy resolution is defined + using a declarative set of rules. These rules are expressed as a mapping from + URL scheme to proxy server identifier(s), and a list of proxy bypass rules for + when to go DIRECT instead of using the mapped proxy. * PAC script - proxy resolution is defined using a JavaScript program, that is - invoked whenever fetching a URL to get the list of proxy servers to use. + invoked whenever fetching a URL to get the list of proxy server identifiers + to use. * Auto-detect - the WPAD protocol is used to probe the network (using DHCP/DNS) and possibly discover the URL of a PAC script. ## Proxy server schemes -Chrome supports the following proxy server schemes: +When using an explicit proxy in the browser, multiple layers of the network +request are impacted, depending on the scheme that is used. Some implications +of the proxy scheme are: -* DIRECT -* HTTP -* HTTPS -* SOCKSv4 -* SOCKSv5 -* QUIC +* Is communication to the proxy done over a secure channel? +* Is name resolution (ex: DNS) done client side, or proxy side? +* What authentication schemes to the proxy server are supported? +* What network traffic can be sent through the proxy? + +Chrome supports these proxy server schemes: + +* [DIRECT](#DIRECT-proxy-scheme) +* [HTTP](#HTTP-proxy-scheme) +* [HTTPS](#HTTPS-proxy-scheme) +* [SOCKSv4](#SOCKSv4-proxy-scheme) +* [SOCKSv5](#SOCKSv5-proxy-scheme) +* [QUIC](#QUIC-proxy-scheme) ### DIRECT proxy scheme @@ -107,7 +120,7 @@ clear. HTTP proxies in Chrome support the same HTTP authentiation schemes as for -target servers: Basic, Digest, Negotiate/NTLM. +target servers: Basic, Digest, Negotiate, NTLM. ### HTTPS proxy scheme @@ -115,12 +128,21 @@ * Example identifier (PAC): `HTTPS proxy:8080` * Example identifier (URI): `https://proxy:8080` -This works exactly like an HTTP proxy, except the communication to the proxy -server is protected by TLS. Hence `http://` requests, and hostnames for -`https://` requests are not sent in the clear as with HTTP proxies. +This works like an [HTTP proxy](#HTTP-proxy-scheme), except the +communication to the proxy server is protected by TLS, and may negotiate +HTTP/2. -In addition to HTTP authentication methods, one can also use client -certificates to authenticate to HTTPS proxies. +Because the connection to the proxy server is secure, https:// requests +sent through the proxy are not sent in the clear as with an HTTP proxy. +Similarly, since CONNECT requests are sent over a protected channel, the +hostnames for proxied https:// URLs is also not revealed. + +In addition to the usual HTTP authentication methods, HTTPS proxies also +support client certificates. + +HTTPS proxies using HTTP/2 can offer better performance in Chrome than a +regular HTTP proxy due to higher connection limits (HTTP/1.1 proxies in Chrome +are limited to 32 simultaneous connections across all domains). ### SOCKSv4 proxy scheme @@ -183,18 +205,18 @@ The simplest way to configure proxy resolution is by providing a static list of rules comprised of: -1. A mapping of URL schemes to proxy servers -2. A list of proxy bypass rules +1. A mapping of URL schemes to [proxy server identifiers](#Proxy-server-identifiers). +2. A list of [proxy bypass rules](#Proxy-bypass-rules) We refer to this mode of configuration as "manual proxy settings". Manual proxy settings can succinctly describe setups like: -* Use HTTPS proxy `foo:8080` for all requests -* Use HTTP proxy `foo:8080` for all requests except those to a `google.com` +* Use proxy `http://foo:8080` for all requests +* Use proxy `http://foo:8080` for all requests except those to a `google.com` subdomain. -* Use HTTP proxy `foo:8080` for all `https://` requests, and the SOCKSv5 proxy - `mysocks:90` for everything else +* Use proxy `http://foo:8080` for all `https://` requests, and proxy + `socsk5://mysocks:90` for everything else Although manual proxy settings are a ubiquituous way to configure proxies across platforms, there is no standard representation or feature set. @@ -205,14 +227,14 @@ suffix matches. When defining manual proxy settings in Chrome, we specify three (possibly -empty) lists of proxy servers: +empty) lists of [proxy server identifiers](#Proxy-server-identifiers). - * proxies for HTTP - A list of proxy servers to use for `http://` requests, - if non-empty. - * proxies for HTTPS - A list of proxy servers to use for `https://` requests, - if non-empty. - * other proxies - A list of proxy servers to use for everything else - (whatever isn't matched by the other two lists) + * proxies for HTTP - A list of proxy server identifiers to use for `http://` + requests, if non-empty. + * proxies for HTTPS - A list of proxy server identifiers to use for + `https://` requests, if non-empty. + * other proxies - A list of proxy server identifiers to use for everything + else (whatever isn't matched by the other two lists) There are a lot of ways to end up with manual proxy settings in Chrome (discussed in other sections). @@ -220,8 +242,8 @@ The following examples will use the command line method. Launching Chrome with `--proxy-server=XXX` (and optionally `--proxy-bypass-list=YYY`) -Example: To use the HTTP proxy `foo:8080` for all requests we can launch -Chrome with `--proxy-server="http://foo:8080"`. This translates into: +Example: To use proxy `http://foo:8080` for all requests we can launch +Chrome with `--proxy-server="http://foo:8080"`. This translates to: * proxies for HTTP - *empty* * proxies for HTTPS - *empty* @@ -238,8 +260,8 @@ * other proxies - `http://foo:8080`, `direct://` If instead we wanted to proxy only `http://` URLs through the -HTTPS proxy `foo:443`, and have everything else use the SOCKSv5 proxy -`mysocks:1080` we could launch Chrome with +HTTPS proxy `https://foo:443`, and have everything else use the SOCKSv5 proxy +`socks5://mysocks:1080` we could launch Chrome with `--proxy-server="http=https://foo:443;socks=socks5://mysocks:1080"`. This now expands to: @@ -247,18 +269,20 @@ * proxies for HTTPS - *empty* * other proxies - `socks5://mysocks:1080` -The command line above uses WinInet's proxy map format, with two modifications: +The command line above uses WinInet's proxy map format, with some additional +features: -* Proxy servers can be optionally prefixed with a scheme (i.e. Chrome's "URI - format" for proxy server identifiers) -* The `socks=` mapping is understood as "other proxies". The subsequent proxy - list can include proxies of any scheme, however if the scheme is unspecified - it is understood to be `socks4://`. +* Instead of naming proxy servers by just a hostname:port, you can use Chrome's + URI format for proxy server identifiers. In other words, you can prefix the + proxy scheme so it doesn't default to HTTP. +* The `socks=` mapping is understood more broadly as "other proxies". The + subsequent proxy list can include proxies of any scheme, however if the + scheme is omitted it will be understood as SOCKSv4 rather than HTTP. -## Mapping WebSockets URLs to a proxy +### Mapping WebSockets URLs to a proxy -Manual proxy settings don't have mappings for `ws://` or `wss://` URLs - you -can't specify a separate proxy to use for those schemes. +[Manual proxy settings](#Manual-proxy-settings) don't have mappings for `ws://` +or `wss://` URLs. Selecting a proxy for these URL schemes is a bit different from other URL schemes. The algorithm that Chrome uses is: @@ -272,19 +296,22 @@ It is possible to route `ws://` and `wss://` separately using a PAC script. -## Proxy credentials in manual proxy settings +### Proxy credentials in manual proxy settings -Most platforms' manual proxy settings allow specifying a cleartext -username/password for proxy sign in. Chrome does not implement this, and will -not use any credentials embedded in the proxy settings. +Most platforms' [manual proxy settings](#Manual-proxy-settings) allow +specifying a cleartext username/password for proxy sign in. Chrome does not +implement this, and will not use any credentials embedded in the proxy +settings. Proxy authentication will instead go through the ordinary flow to find credentials. ## Proxy bypass rules -In addition to specifying three lists of proxy servers, Chrome's manual proxy -settings also lets you specify a list of "proxy bypass rules". +In addition to specifying three lists of [proxy server +identifiers](#proxy-server-identifiers), Chrome's [manual proxy +settings](#Manual-proxy-settings) lets you specify a list of "proxy bypass +rules". This ruleset determines whether a given URL should skip use of a proxy all together, even when a proxy is otherwise defined for it. @@ -369,8 +396,8 @@ Matches any URL whose hostname is an IPv4 literal, and falls between the given address range. -Only applies to URLs that are IP literals - see "Meaning of IP address range -bypass rules". +Note this [only applies to URLs that are IP +literals](#Meaning-of-IP-address-range-bypass-rules). Examples: @@ -385,8 +412,8 @@ Matches any URL that is an IPv6 literal that falls between the given range. Note that IPv6 literals must *not* be bracketed. -Only applies to URLs that are IP literals - see "Meaning of IP address range -bypass rules". +Note this [only applies to URLs that are IP +literals](#Meaning-of-IP-address-range-bypass-rules). Examples: @@ -408,8 +435,8 @@ The rule name comes from WinInet, and can easily be confused with the concept of localhost. However the two concepts are completely orthogonal. In practice -one wouldn't add rules to bypass localhost, as it is already done implicitly -(see "Implicit bypass rules"). +one wouldn't add rules to bypass localhost, as it is [already done +implicitly](#Implicit-bypass-rules). ### Bypass rule: Subtract implicit rules @@ -417,10 +444,9 @@ <-loopback> ``` -*Subtracts* the implicit proxy bypass rules (localhost and link local -addresses). See the "Implicit bypass rules" section for details on when/why to -use this, and the security caveats to doing so. Generally this is used for test -setups. +*Subtracts* the [implicit proxy bypass rules](#Implicit-bypass-rules) +(localhost and link local addresses). This is generally only needed for test +setupe. Beware of the security implications to proxying localhost. Whereas regular bypass rules instruct the browser about URLs that should *not* use the proxy, this rule has the opposite effect and tells the browser to @@ -432,8 +458,8 @@ ### Meaning of IP address range bypass rules -The IP address range bypass rules in manual proxy settings applies ONLY TO URL -LITERALS. This is not what one would intuitively expect! +The IP address range bypass rules in manual proxy settings applies only to URL +literals. This is not what one would intuitively expect. Example: @@ -497,7 +523,7 @@ * In M72 Chrome generalized the implicit proxy bypass rules to manually configured proxies -## Overriding the implicit bypass rules +### Overriding the implicit bypass rules If you want traffic to `localhost` to be sent through a proxy despite the security concerns, it can be done by adding the special proxy bypass rule @@ -516,8 +542,9 @@ ## Evaluating proxy lists (proxy fallback) -Proxy resolution results in a _list_ of proxy servers to use for a given -request, not just a single proxy server. +Proxy resolution results in a _list_ of [proxy server +identifiers](#Proxy-server-identifiers) to use for a +given request, not just a single proxy server identifier. For instance, consider this PAC script: @@ -532,12 +559,13 @@ ``` What proxy will Chrome use for connections to `www.example.com`, given that -we have a choice of 3 separate proxies, each of different type? +we have a choice of three separate proxy server identifiers to choose from +{`http://proxy1:80`, `https://proxy2:443`, `socks5://proxy3:1080`}? -Initially, Chrome will try the proxies in order. This means first attempting the -request through the HTTP WebProxy `proxy1`. If that "fails", the request is -next attempted through the HTTPS proxy `proxy2`. Lastly if that fails, the -request is attempted through the SOCKSv5 proxy `proxy3`. +Initially, Chrome will try the proxies in order. This means first attempting +the request through `http://proxy1:80`. If that "fails", the request is +next attempted through `https://proxy2:443`. Lastly if that fails, the +request is attempted through `socks5://proxy3:1080`. This process is referred to as _proxy fallback_. What constitutes a "failure" is described later. @@ -546,26 +574,24 @@ is influenced by the past responsiveness of proxy servers. Let's say we request `http://www.example.com/`. Per the PAC script this -resolves to: +resolves to a list of three proxy server identifiers: -``` -"PROXY proxy1; HTTPS proxy2; SOCKS5 proxy3" -``` +{`http://proxy1:80`, `https://proxy2:443`, `socks5://proxy3:1080`} Chrome will first attempt to issue the request through these proxies in the -left-to-right order (`proxy1`, `proxy2`, `proxy3`). +left-to-right order. -Let's say that the attempt through `proxy1` fails, but then the attempt through -`proxy2` succeeds. Chrome will mark `proxy1` as _bad_ for the next 5 minutes. -Being marked as _bad_ means that `proxy1` is de-prioritized with respect to -other proxies options (including DIRECT) that are not marked as bad. +Let's say that the attempt through `http://proxy1:80` fails, but then the +attempt through `https://proxy2:443` succeeds. Chrome will mark +`http://proxy1:80` as _bad_ for the next 5 minutes. Being marked as _bad_ +means that `http://proxy1:80` is de-prioritized with respect to +other proxy server identifiers (including `direct://`) that are not marked as +bad. That means the next time `http://www.example.com/` is requested, the effective order for proxies to attempt will be: -``` -HTTPS proxy2; SOCKS5 proxy3; "PROXY proxy1" -``` +{`https://proxy2:443`, `socks5://proxy3:1080`, `http://proxy1:80`} Conceptually, _bad_ proxies are moved to the end of the list, rather than being removed from consideration all together. @@ -615,7 +641,7 @@ will not give feedback that the bad proxies were cleared, however capturing a new NetLog dump can confirm it was cleared. -## Arguments passed to `FindProxyForURL(url, host)` in PAC scripts +## Arguments passed to FindProxyForURL() in PAC scripts PAC scripts in Chrome are expected to define a JavaScript function `FindProxyForURL`. @@ -668,7 +694,7 @@ capability](https://bugs.chromium.org/p/chromium/issues/detail?id=882536) in favor of a consistent policy. -## Resolving client's IP address within a PAC script using `myIpAddress()` +## Resolving client's IP address within a PAC script using myIpAddress() PAC scripts can invoke `myIpAddress()` to obtain the client's IP address. This function returns a single IP literal, or `"127.0.0.1"` on failure. @@ -705,10 +731,10 @@ *Historical note*: Prior to M72, Chrome's implementation of `myIpAddress()` was effectively just `getaddrinfo(gethostname)`. This is now step 2 of the heuristic. -### What about `var pacUseMultihomedDNS`? +### What about pacUseMultihomedDNS? -In Firefox, if you define a global named `pacUseMultihomedDNS` in your PAC -script, it causes `myIpAddress()` to report the IP address of the interface +In Firefox, if you define a global variable named `pacUseMultihomedDNS` in your +PAC script, it causes `myIpAddress()` to report the IP address of the interface that would (likely) have been used had we connected to it DIRECT. In particular, it will do a DNS resolution of the target host (the hostname of @@ -720,7 +746,7 @@ side-effects. Chrome has no APIs or settings to change `myIpAddress()`'s algorithm. -## Resolving client's IP address within a PAC script using `myIpAddressEx()` +## Resolving client's IP address within a PAC script using myIpAddressEx() Chrome supports the [Microsoft PAC extension](https://docs.microsoft.com/en-us/windows/desktop/winhttp/myipaddressex)
diff --git a/remoting/protocol/BUILD.gn b/remoting/protocol/BUILD.gn index f4348df..993159e 100644 --- a/remoting/protocol/BUILD.gn +++ b/remoting/protocol/BUILD.gn
@@ -266,12 +266,15 @@ deps += [ "//remoting/proto/remoting/v1:network_traversal_grpc_library", - "//third_party/webrtc/api:create_peerconnection_factory", + "//third_party/webrtc/api:callfactory_api", "//third_party/webrtc/api/audio_codecs:audio_codecs_api", "//third_party/webrtc/api/audio_codecs/opus:audio_decoder_opus", "//third_party/webrtc/api/audio_codecs/opus:audio_encoder_opus", + "//third_party/webrtc/api/rtc_event_log:rtc_event_log_factory", "//third_party/webrtc/api/video_codecs:builtin_video_decoder_factory", + "//third_party/webrtc/media:rtc_audio_video", "//third_party/webrtc_overrides:init_webrtc", + "//third_party/webrtc_overrides:task_queue_factory", ] }
diff --git a/remoting/protocol/DEPS b/remoting/protocol/DEPS index 1fa327ef..d05d3a9 100644 --- a/remoting/protocol/DEPS +++ b/remoting/protocol/DEPS
@@ -15,6 +15,7 @@ "+third_party/libjingle_xmpp/xmpp", "+third_party/protobuf/src", "+third_party/webrtc", + "+third_party/webrtc_overrides", "+ui/events/keycodes/dom", "+services/network/test", "+services/network/public/cpp",
diff --git a/remoting/protocol/webrtc_transport.cc b/remoting/protocol/webrtc_transport.cc index 16ad0bce..cbea8e8 100644 --- a/remoting/protocol/webrtc_transport.cc +++ b/remoting/protocol/webrtc_transport.cc
@@ -33,9 +33,14 @@ #include "third_party/webrtc/api/audio_codecs/audio_encoder_factory_template.h" #include "third_party/webrtc/api/audio_codecs/opus/audio_decoder_opus.h" #include "third_party/webrtc/api/audio_codecs/opus/audio_encoder_opus.h" -#include "third_party/webrtc/api/create_peerconnection_factory.h" +#include "third_party/webrtc/api/call/call_factory_interface.h" +#include "third_party/webrtc/api/peer_connection_interface.h" +#include "third_party/webrtc/api/rtc_event_log/rtc_event_log_factory.h" #include "third_party/webrtc/api/stats/rtcstats_objects.h" #include "third_party/webrtc/api/video_codecs/builtin_video_decoder_factory.h" +#include "third_party/webrtc/media/engine/webrtc_media_engine.h" +#include "third_party/webrtc/modules/audio_processing/include/audio_processing.h" +#include "third_party/webrtc_overrides/task_queue_factory.h" using jingle_xmpp::QName; using jingle_xmpp::XmlElement; @@ -246,16 +251,28 @@ : transport_(transport) { audio_module_ = new rtc::RefCountedObject<WebrtcAudioModule>(); - peer_connection_factory_ = webrtc::CreatePeerConnectionFactory( - worker_thread, // network_thread - worker_thread, - rtc::Thread::Current(), // signaling_thread - audio_module_, - webrtc::CreateAudioEncoderFactory<webrtc::AudioEncoderOpus>(), - webrtc::CreateAudioDecoderFactory<webrtc::AudioDecoderOpus>(), - std::move(encoder_factory), webrtc::CreateBuiltinVideoDecoderFactory(), - nullptr, // audio_mixer - nullptr); // audio_processing + webrtc::PeerConnectionFactoryDependencies pcf_deps; + pcf_deps.network_thread = worker_thread; + pcf_deps.worker_thread = worker_thread; + pcf_deps.signaling_thread = rtc::Thread::Current(); + pcf_deps.task_queue_factory = CreateWebRtcTaskQueueFactory(); + pcf_deps.call_factory = webrtc::CreateCallFactory(); + pcf_deps.event_log_factory = std::make_unique<webrtc::RtcEventLogFactory>( + pcf_deps.task_queue_factory.get()); + cricket::MediaEngineDependencies media_deps; + media_deps.task_queue_factory = pcf_deps.task_queue_factory.get(); + media_deps.adm = audio_module_; + media_deps.audio_encoder_factory = + webrtc::CreateAudioEncoderFactory<webrtc::AudioEncoderOpus>(); + media_deps.audio_decoder_factory = + webrtc::CreateAudioDecoderFactory<webrtc::AudioDecoderOpus>(); + media_deps.video_encoder_factory = std::move(encoder_factory); + media_deps.video_decoder_factory = + webrtc::CreateBuiltinVideoDecoderFactory(); + media_deps.audio_processing = webrtc::AudioProcessingBuilder().Create(); + pcf_deps.media_engine = cricket::CreateMediaEngine(std::move(media_deps)); + peer_connection_factory_ = + webrtc::CreateModularPeerConnectionFactory(std::move(pcf_deps)); webrtc::PeerConnectionInterface::RTCConfiguration rtc_config; rtc_config.enable_dtls_srtp = true;
diff --git a/services/identity/public/cpp/access_token_fetcher_unittest.cc b/services/identity/public/cpp/access_token_fetcher_unittest.cc index e5b287b..4fe4632 100644 --- a/services/identity/public/cpp/access_token_fetcher_unittest.cc +++ b/services/identity/public/cpp/access_token_fetcher_unittest.cc
@@ -8,9 +8,9 @@ #include <utility> #include "base/bind.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/test/mock_callback.h" +#include "base/test/scoped_task_environment.h" #include "components/prefs/testing_pref_service.h" #include "components/signin/core/browser/account_tracker_service.h" #include "components/signin/core/browser/fake_profile_oauth2_token_service.h" @@ -116,7 +116,7 @@ std::move(on_access_token_request_callback_).Run(); } - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment scoped_task_environment_; TestingPrefServiceSyncable pref_service_; TestSigninClient signin_client_; FakeProfileOAuth2TokenService token_service_;
diff --git a/services/identity/public/cpp/accounts_mutator_unittest.cc b/services/identity/public/cpp/accounts_mutator_unittest.cc index dc23d0b..9874096 100644 --- a/services/identity/public/cpp/accounts_mutator_unittest.cc +++ b/services/identity/public/cpp/accounts_mutator_unittest.cc
@@ -5,9 +5,9 @@ #include "services/identity/public/cpp/accounts_mutator_impl.h" #include "base/bind.h" -#include "base/message_loop/message_loop.h" #include "base/optional.h" #include "base/test/gtest_util.h" +#include "base/test/scoped_task_environment.h" #include "components/signin/core/browser/device_id_helper.h" #include "components/signin/core/browser/signin_metrics.h" #include "components/sync_preferences/testing_pref_service_syncable.h" @@ -111,7 +111,7 @@ } private: - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment scoped_task_environment_; sync_preferences::TestingPrefServiceSyncable prefs_; network::TestURLLoaderFactory test_url_loader_factory_; identity::IdentityTestEnvironment identity_test_env_;
diff --git a/services/identity/public/cpp/identity_manager.cc b/services/identity/public/cpp/identity_manager.cc index 7bdf6ab..12bd2ad 100644 --- a/services/identity/public/cpp/identity_manager.cc +++ b/services/identity/public/cpp/identity_manager.cc
@@ -8,6 +8,7 @@ #include "build/build_config.h" #include "components/signin/core/browser/account_fetcher_service.h" +#include "components/signin/core/browser/gaia_cookie_manager_service.h" #include "components/signin/core/browser/ubertoken_fetcher_impl.h" #include "google_apis/gaia/gaia_auth_util.h" #include "services/identity/public/cpp/accounts_cookie_mutator.h" @@ -65,7 +66,15 @@ token_service_->AddDiagnosticsObserver(this); token_service_->AddObserver(this); account_tracker_service_->AddObserver(this); - gaia_cookie_manager_service_->AddObserver(this); + + // IdentityManager owns gaia_cookie_manager_service_ and will outlive it, so + // base::Unretained is safe. + gaia_cookie_manager_service_->SetGaiaAccountsInCookieUpdatedCallback( + base::BindRepeating(&IdentityManager::OnGaiaAccountsInCookieUpdated, + base::Unretained(this))); + gaia_cookie_manager_service_->SetGaiaCookieDeletedByUserActionCallback( + base::BindRepeating(&IdentityManager::OnGaiaCookieDeletedByUserAction, + base::Unretained(this))); // Seed the primary account with any state that |signin_manager_| loaded from // prefs. @@ -86,7 +95,6 @@ token_service_->RemoveObserver(this); token_service_->RemoveDiagnosticsObserver(this); account_tracker_service_->RemoveObserver(this); - gaia_cookie_manager_service_->RemoveObserver(this); } // TODO(862619) change return type to base::Optional<CoreAccountInfo>
diff --git a/services/identity/public/cpp/identity_manager.h b/services/identity/public/cpp/identity_manager.h index 30d6ab7..a651290 100644 --- a/services/identity/public/cpp/identity_manager.h +++ b/services/identity/public/cpp/identity_manager.h
@@ -13,7 +13,6 @@ #include "components/signin/core/browser/account_fetcher_service.h" #include "components/signin/core/browser/account_info.h" #include "components/signin/core/browser/account_tracker_service.h" -#include "components/signin/core/browser/gaia_cookie_manager_service.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_manager_base.h" #include "components/signin/core/browser/signin_metrics.h" @@ -40,6 +39,8 @@ class PrefRegistrySimple; class SigninManagerAndroid; +class GaiaCookieManagerService; + namespace identity { class AccountsMutator; @@ -56,7 +57,6 @@ class IdentityManager : public SigninManagerBase::Observer, public OAuth2TokenService::DiagnosticsObserver, public OAuth2TokenService::Observer, - public GaiaCookieManagerService::Observer, public AccountTrackerService::Observer { public: class Observer { @@ -600,12 +600,12 @@ void OnAuthErrorChanged(const std::string& account_id, const GoogleServiceAuthError& auth_error) override; - // GaiaCookieManagerService::Observer: + // GaiaCookieManagerService callbacks: void OnGaiaAccountsInCookieUpdated( const std::vector<gaia::ListedAccount>& signed_in_accounts, const std::vector<gaia::ListedAccount>& signed_out_accounts, - const GoogleServiceAuthError& error) override; - void OnGaiaCookieDeletedByUserAction() override; + const GoogleServiceAuthError& error); + void OnGaiaCookieDeletedByUserAction(); // OAuth2TokenService::DiagnosticsObserver: void OnAccessTokenRequested(
diff --git a/services/identity/public/cpp/identity_manager_unittest.cc b/services/identity/public/cpp/identity_manager_unittest.cc index bd196ec7..5b20265d 100644 --- a/services/identity/public/cpp/identity_manager_unittest.cc +++ b/services/identity/public/cpp/identity_manager_unittest.cc
@@ -11,15 +11,16 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/containers/flat_set.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/stl_util.h" #include "base/test/bind_test_util.h" +#include "base/test/scoped_task_environment.h" #include "build/build_config.h" #include "components/image_fetcher/core/fake_image_decoder.h" #include "components/signin/core/browser/account_consistency_method.h" #include "components/signin/core/browser/account_tracker_service.h" #include "components/signin/core/browser/fake_profile_oauth2_token_service.h" +#include "components/signin/core/browser/gaia_cookie_manager_service.h" #include "components/signin/core/browser/list_accounts_test_utils.h" #include "components/signin/core/browser/set_accounts_in_cookie_result.h" #include "components/signin/core/browser/signin_manager.h" @@ -297,11 +298,11 @@ << "AccountConsistency is not used by SigninManagerBase"; auto signin_manager = std::make_unique<SigninManagerBase>( &signin_client_, token_service.get(), account_tracker_service.get(), - gaia_cookie_manager_service.get(), account_consistency); + account_consistency); #else auto signin_manager = std::make_unique<SigninManager>( &signin_client_, token_service.get(), account_tracker_service.get(), - gaia_cookie_manager_service.get(), account_consistency); + account_consistency); #endif // Passing this switch ensures that the new SigninManager starts with a @@ -368,7 +369,7 @@ } private: - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment scoped_task_environment_; sync_preferences::TestingPrefServiceSyncable pref_service_; network::TestURLLoaderFactory test_url_loader_factory_; TestSigninClient signin_client_;
diff --git a/services/identity/public/cpp/identity_test_environment.cc b/services/identity/public/cpp/identity_test_environment.cc index 104a313..8b2d0a6 100644 --- a/services/identity/public/cpp/identity_test_environment.cc +++ b/services/identity/public/cpp/identity_test_environment.cc
@@ -202,18 +202,18 @@ std::unique_ptr<SigninManagerBase> signin_manager = std::make_unique<SigninManagerBase>(signin_client, token_service.get(), account_tracker_service.get(), - nullptr, account_consistency); + account_consistency); #else std::unique_ptr<SigninManagerBase> signin_manager = std::make_unique<SigninManager>(signin_client, token_service.get(), - account_tracker_service.get(), nullptr, + account_tracker_service.get(), account_consistency); #endif signin_manager->Initialize(pref_service); - std::unique_ptr<GaiaCookieManagerService> gaia_cookie_manager_service; - gaia_cookie_manager_service = std::make_unique<GaiaCookieManagerService>( - token_service.get(), signin_client); + std::unique_ptr<GaiaCookieManagerService> gaia_cookie_manager_service = + std::make_unique<GaiaCookieManagerService>(token_service.get(), + signin_client); std::unique_ptr<PrimaryAccountMutator> primary_account_mutator; std::unique_ptr<AccountsMutator> accounts_mutator;
diff --git a/services/identity/public/cpp/identity_test_utils.cc b/services/identity/public/cpp/identity_test_utils.cc index 4d2215d..d380841b 100644 --- a/services/identity/public/cpp/identity_test_utils.cc +++ b/services/identity/public/cpp/identity_test_utils.cc
@@ -10,6 +10,7 @@ #include "base/run_loop.h" #include "base/strings/string_split.h" #include "components/signin/core/browser/account_tracker_service.h" +#include "components/signin/core/browser/gaia_cookie_manager_service.h" #include "components/signin/core/browser/list_accounts_test_utils.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "google_apis/gaia/gaia_auth_util.h"
diff --git a/services/identity/public/cpp/primary_account_access_token_fetcher_unittest.cc b/services/identity/public/cpp/primary_account_access_token_fetcher_unittest.cc index a79464d..ab3e9e5 100644 --- a/services/identity/public/cpp/primary_account_access_token_fetcher_unittest.cc +++ b/services/identity/public/cpp/primary_account_access_token_fetcher_unittest.cc
@@ -8,9 +8,9 @@ #include <utility> #include "base/bind.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/test/mock_callback.h" +#include "base/test/scoped_task_environment.h" #include "services/identity/public/cpp/identity_manager.h" #include "services/identity/public/cpp/identity_test_environment.h" #include "testing/gmock/include/gmock/gmock.h" @@ -79,7 +79,7 @@ } private: - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment scoped_task_environment_; IdentityTestEnvironment identity_test_env_; AccessTokenInfo access_token_info_; };
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_mac.cc b/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_mac.cc index d668ed60..a2041824 100644 --- a/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_mac.cc +++ b/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_mac.cc
@@ -22,6 +22,37 @@ namespace { +#if !defined(MAC_OS_X_VERSION_10_11) || \ + MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_11 +// The |phys_footprint| field was introduced in 10.11. +struct ChromeTaskVMInfo { + mach_vm_size_t virtual_size; + integer_t region_count; + integer_t page_size; + mach_vm_size_t resident_size; + mach_vm_size_t resident_size_peak; + mach_vm_size_t device; + mach_vm_size_t device_peak; + mach_vm_size_t internal; + mach_vm_size_t internal_peak; + mach_vm_size_t external; + mach_vm_size_t external_peak; + mach_vm_size_t reusable; + mach_vm_size_t reusable_peak; + mach_vm_size_t purgeable_volatile_pmap; + mach_vm_size_t purgeable_volatile_resident; + mach_vm_size_t purgeable_volatile_virtual; + mach_vm_size_t compressed; + mach_vm_size_t compressed_peak; + mach_vm_size_t compressed_lifetime; + mach_vm_size_t phys_footprint; +}; +#else +using ChromeTaskVMInfo = task_vm_info; +#endif // MAC_OS_X_VERSION_10_11 +mach_msg_type_number_t ChromeTaskVMInfoCount = + sizeof(ChromeTaskVMInfo) / sizeof(natural_t); + using VMRegion = mojom::VmRegion; bool IsAddressInSharedRegion(uint64_t address) { @@ -209,14 +240,22 @@ // static bool OSMetrics::FillOSMemoryDump(base::ProcessId pid, mojom::RawOSMemDump* dump) { - // Creating process metrics for child processes in mac or windows requires - // additional information like ProcessHandle or port provider. - DCHECK_EQ(base::kNullProcessId, pid); - auto process_metrics = base::ProcessMetrics::CreateCurrentProcessMetrics(); - base::ProcessMetrics::TaskVMInfo info = process_metrics->GetTaskVMInfo(); - dump->platform_private_footprint->phys_footprint_bytes = info.phys_footprint; - dump->platform_private_footprint->internal_bytes = info.internal; - dump->platform_private_footprint->compressed_bytes = info.compressed; + ChromeTaskVMInfo task_vm_info; + mach_msg_type_number_t count = ChromeTaskVMInfoCount; + kern_return_t result = + task_info(mach_task_self(), TASK_VM_INFO, + reinterpret_cast<task_info_t>(&task_vm_info), &count); + if (result != KERN_SUCCESS) + return false; + + dump->platform_private_footprint->internal_bytes = task_vm_info.internal; + dump->platform_private_footprint->compressed_bytes = task_vm_info.compressed; + + if (count == ChromeTaskVMInfoCount) { + dump->platform_private_footprint->phys_footprint_bytes = + task_vm_info.phys_footprint; + } + return true; }
diff --git a/services/ws/public/mojom/BUILD.gn b/services/ws/public/mojom/BUILD.gn index 8d53c49..f19658b 100644 --- a/services/ws/public/mojom/BUILD.gn +++ b/services/ws/public/mojom/BUILD.gn
@@ -22,7 +22,6 @@ "//mojo/public/mojom/base", "//ui/gfx/geometry/mojo", "//ui/gfx/mojo", - "//ui/platform_window/mojo:interfaces", ] if (is_chromeos) {
diff --git a/testing/buildbot/chromium.perf.json b/testing/buildbot/chromium.perf.json index 2a14f13..d2cffce 100644 --- a/testing/buildbot/chromium.perf.json +++ b/testing/buildbot/chromium.perf.json
@@ -1132,10 +1132,9 @@ { "args": [ "-v", - "--browser=exact", + "--browser=android-chrome", "--upload-results", - "--browser-executable=../../out/Release/bin/monochrome_64_32_bundle", - "--device=android", + "--run-ref-build", "--test-shard-map-filename=android-pixel2-perf_map.json" ], "isolate_name": "performance_test_suite",
diff --git a/testing/test.gni b/testing/test.gni index 563586d..9fb6865 100644 --- a/testing/test.gni +++ b/testing/test.gni
@@ -274,17 +274,18 @@ ] } + fuchsia_package(_pkg_target) { + testonly = true + forward_variables_from(invoker, [ "sandbox_policy" ]) + binary = ":$_exec_target" + package_name_override = _output_name + } + executable(_exec_target) { forward_variables_from(invoker, "*") testonly = true output_name = _exec_target } - - fuchsia_package(_pkg_target) { - testonly = true - binary = ":$_exec_target" - package_name_override = _output_name - } } else if (is_ios) { import("//build/config/ios/ios_sdk.gni") import("//build/config/ios/rules.gni")
diff --git a/third_party/blink/PRESUBMIT.py b/third_party/blink/PRESUBMIT.py index e6b80501..0095457d 100644 --- a/third_party/blink/PRESUBMIT.py +++ b/third_party/blink/PRESUBMIT.py
@@ -25,9 +25,10 @@ _EXCLUDED_PATHS = ( - # These directories are created and updated via a script. - r'^third_party[\\\/]blink[\\\/]tools[\\\/]blinkpy[\\\/]third_party[\\\/]wpt[\\\/]wpt[\\\/].*', - r'^third_party[\\\/]blink[\\\/]web_tests[\\\/]external[\\\/]wpt[\\\/]tools[\\\/].*', + # These are third-party dependencies that we don't directly control. + r'^third_party[\\/]blink[\\/]tools[\\/]blinkpy[\\/]third_party[\\/]wpt[\\/]wpt[\\/].*', + r'^third_party[\\/]blink[\\/]web_tests[\\/]external[\\/]wpt[\\/]tools[\\/].*', + r'^third_party[\\/]blink[\\/]web_tests[\\/]external[\\/]wpt[\\/]resources[\\/]webidl2[\\/].*', )
diff --git a/third_party/blink/public/platform/scheduler/OWNERS b/third_party/blink/public/platform/scheduler/OWNERS index 8423b49..00ad1396 100644 --- a/third_party/blink/public/platform/scheduler/OWNERS +++ b/third_party/blink/public/platform/scheduler/OWNERS
@@ -1,5 +1,6 @@ altimin@chromium.org alexclarke@chromium.org +carlscab@google.com rmcilroy@chromium.org skyostil@chromium.org
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn index 5595c3bb8..7a4a457 100644 --- a/third_party/blink/renderer/core/BUILD.gn +++ b/third_party/blink/renderer/core/BUILD.gn
@@ -1847,7 +1847,7 @@ "frame/performance_monitor_test.cc", "frame/root_frame_viewport_test.cc", "frame/rotation_viewport_anchor_test.cc", - "frame/use_counter_test.cc", + "frame/use_counter_helper_test.cc", "frame/visual_viewport_test.cc", "fullscreen/scoped_allow_fullscreen_test.cc", "geometry/dom_matrix_test.cc",
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/third_party/blink/renderer/core/css/resolver/style_resolver.cc index a56192af..525a24b 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -1132,9 +1132,10 @@ Element* element = state.GetElement(); DCHECK(element); - // The animating element may be this element, or its pseudo element. It is - // null when calculating the style for a potential pseudo element that has - // yet to be created. + // The animating element may be this element, the pseudo element we are + // resolving style for, or null if we are resolving style for a pseudo + // element which is not represented by a PseudoElement like scrollbar pseudo + // elements. DCHECK(animating_element == element || !animating_element || animating_element->ParentOrShadowHostElement() == element);
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_budget_test.cc b/third_party/blink/renderer/core/display_lock/display_lock_budget_test.cc index 7295877..b372b973 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_budget_test.cc +++ b/third_party/blink/renderer/core/display_lock/display_lock_budget_test.cc
@@ -18,22 +18,15 @@ namespace blink { -class DisplayLockBudgetTest : public RenderingTest { +class DisplayLockBudgetTest : public RenderingTest, + private ScopedDisplayLockingForTest { public: + DisplayLockBudgetTest() : ScopedDisplayLockingForTest(true) {} void SetUp() override { RenderingTest::SetUp(); - features_backup_.emplace(); - RuntimeEnabledFeatures::SetDisplayLockingEnabled(true); test_task_runner_ = base::MakeRefCounted<base::TestMockTimeTaskRunner>(); } - void TearDown() override { - if (features_backup_) { - features_backup_->Restore(); - features_backup_.reset(); - } - } - double GetBudgetMs(const YieldingDisplayLockBudget& budget) const { return budget.GetCurrentBudgetMs(); }
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc b/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc index 373a8b74..eb369f613 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc +++ b/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc
@@ -17,7 +17,7 @@ #include "third_party/blink/renderer/core/html/html_template_element.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h" -#include "third_party/blink/renderer/platform/runtime_enabled_features.h" +#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" namespace blink { @@ -84,19 +84,16 @@ }; } // namespace -class DisplayLockContextTest : public testing::Test { +class DisplayLockContextTest : public testing::Test, + private ScopedDisplayLockingForTest { public: + DisplayLockContextTest() : ScopedDisplayLockingForTest(true) {} + void SetUp() override { - features_backup_.emplace(); - RuntimeEnabledFeatures::SetDisplayLockingEnabled(true); web_view_helper_.Initialize(); } void TearDown() override { - if (features_backup_) { - features_backup_->Restore(); - features_backup_.reset(); - } web_view_helper_.Reset(); } @@ -163,7 +160,6 @@ const int FAKE_FIND_ID = 1; private: - base::Optional<RuntimeEnabledFeatures::Backup> features_backup_; frame_test_helpers::WebViewHelper web_view_helper_; };
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_utilities_test.cc b/third_party/blink/renderer/core/display_lock/display_lock_utilities_test.cc index 69e1164..e34792f 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_utilities_test.cc +++ b/third_party/blink/renderer/core/display_lock/display_lock_utilities_test.cc
@@ -10,23 +10,16 @@ #include "third_party/blink/renderer/core/dom/shadow_root.h" #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" +#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" namespace blink { -class DisplayLockUtilitiesTest : public RenderingTest { +class DisplayLockUtilitiesTest : public RenderingTest, + private ScopedDisplayLockingForTest { public: DisplayLockUtilitiesTest() - : RenderingTest(MakeGarbageCollected<SingleChildLocalFrameClient>()) {} - - void SetUp() override { - RenderingTest::SetUp(); - RuntimeEnabledFeatures::SetDisplayLockingEnabled(true); - } - - void TearDown() override { - RenderingTest::TearDown(); - RuntimeEnabledFeatures::SetDisplayLockingEnabled(false); - } + : RenderingTest(MakeGarbageCollected<SingleChildLocalFrameClient>()), + ScopedDisplayLockingForTest(true) {} }; TEST_F(DisplayLockUtilitiesTest, ActivatableLockedInclusiveAncestors) {
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h index 8208796..4d8b1abe 100644 --- a/third_party/blink/renderer/core/dom/document.h +++ b/third_party/blink/renderer/core/dom/document.h
@@ -66,7 +66,7 @@ #include "third_party/blink/renderer/core/execution_context/security_context.h" #include "third_party/blink/renderer/core/frame/dom_timer_coordinator.h" #include "third_party/blink/renderer/core/frame/hosts_using_features.h" -#include "third_party/blink/renderer/core/frame/use_counter.h" +#include "third_party/blink/renderer/core/frame/use_counter_helper.h" #include "third_party/blink/renderer/core/html/custom/v0_custom_element.h" #include "third_party/blink/renderer/core/html/parser/parser_synchronization_policy.h" #include "third_party/blink/renderer/core/scroll/scroll_types.h"
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index 65e52777a..e7a208e 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -267,8 +267,14 @@ return false; // The only block-container display types that potentially don't establish a // new formatting context, are 'block' and 'list-item'. - if (display != EDisplay::kBlock && display != EDisplay::kListItem) - return true; + if (display != EDisplay::kBlock && display != EDisplay::kListItem) { + // DETAILS and SUMMARY elements partially or completely ignore the display + // type, though, and may end up disregarding the display type and just + // create block containers. And those don't necessarily create a formatting + // context. + if (!IsHTMLDetailsElement(node) && !IsHTMLSummaryElement(node)) + return true; + } if (!style.IsOverflowVisible()) return node.GetDocument().ViewportDefiningElement() != &node; if (style.HasOutOfFlowPosition() || style.IsFloating() ||
diff --git a/third_party/blink/renderer/core/frame/BUILD.gn b/third_party/blink/renderer/core/frame/BUILD.gn index 03647d3..807a17d 100644 --- a/third_party/blink/renderer/core/frame/BUILD.gn +++ b/third_party/blink/renderer/core/frame/BUILD.gn
@@ -171,8 +171,9 @@ "smart_clip.cc", "smart_clip.h", "test_report_body.h", - "use_counter.cc", "use_counter.h", + "use_counter_helper.cc", + "use_counter_helper.h", "user_activation.cc", "user_activation.h", "viewport_data.cc",
diff --git a/third_party/blink/renderer/core/frame/ad_tracker_test.cc b/third_party/blink/renderer/core/frame/ad_tracker_test.cc index 5d16464..bc115e8 100644 --- a/third_party/blink/renderer/core/frame/ad_tracker_test.cc +++ b/third_party/blink/renderer/core/frame/ad_tracker_test.cc
@@ -12,6 +12,7 @@ #include "third_party/blink/renderer/core/testing/dummy_page_holder.h" #include "third_party/blink/renderer/core/testing/sim/sim_request.h" #include "third_party/blink/renderer/core/testing/sim/sim_test.h" +#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" namespace blink { @@ -494,11 +495,11 @@ EXPECT_TRUE(local_subframe->IsAdSubframe()); } -class AdTrackerDisabledSimTest : public SimTest { +class AdTrackerDisabledSimTest : public SimTest, + private ScopedAdTaggingForTest { protected: + AdTrackerDisabledSimTest() : ScopedAdTaggingForTest(false) {} void SetUp() override { - RuntimeEnabledFeatures::SetAdTaggingEnabled(false); - SimTest::SetUp(); main_resource_ = std::make_unique<SimRequest>( "https://example.com/test.html", "text/html");
diff --git a/third_party/blink/renderer/core/frame/frame_test.cc b/third_party/blink/renderer/core/frame/frame_test.cc index 58ebe05..0a126c3 100644 --- a/third_party/blink/renderer/core/frame/frame_test.cc +++ b/third_party/blink/renderer/core/frame/frame_test.cc
@@ -10,6 +10,7 @@ #include "third_party/blink/renderer/core/loader/document_loader.h" #include "third_party/blink/renderer/core/testing/document_interface_broker_test_helpers.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" +#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" namespace blink { @@ -163,7 +164,7 @@ } TEST_F(FrameTest, UserActivationInterfaceTest) { - RuntimeEnabledFeatures::SetUserActivationV2Enabled(true); + ScopedUserActivationV2ForTest scoped_feature(true); // Initially both sticky and transient bits are false. EXPECT_FALSE(GetDocument().GetFrame()->HasBeenActivated()); @@ -187,7 +188,7 @@ } TEST_F(FrameTest, UserActivationHistograms) { - RuntimeEnabledFeatures::SetUserActivationV2Enabled(true); + ScopedUserActivationV2ForTest scoped_feature(true); base::HistogramTester histograms; LocalFrame::HasTransientUserActivation(GetDocument().GetFrame());
diff --git a/third_party/blink/renderer/core/frame/use_counter.h b/third_party/blink/renderer/core/frame/use_counter.h index 4a948b3..9f1e86c52 100644 --- a/third_party/blink/renderer/core/frame/use_counter.h +++ b/third_party/blink/renderer/core/frame/use_counter.h
@@ -26,151 +26,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_USE_COUNTER_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_USE_COUNTER_H_ -#include <bitset> -#include "base/macros.h" -#include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/css/css_property_names.h" -#include "third_party/blink/renderer/core/css/parser/css_parser_mode.h" -#include "third_party/blink/renderer/core/frame/web_feature.h" -#include "third_party/blink/renderer/platform/heap/garbage_collected.h" -#include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" -#include "third_party/blink/renderer/platform/wtf/forward.h" - -namespace blink { - -class DocumentLoader; -class Element; -class EnumerationHistogram; -class LocalFrame; -class StyleSheetContents; - -// Utility class for muting UseCounter, for instance ignoring attributes -// constructed in user-agent shadow DOM. Once constructed, all UseCounting -// is muted, until the object is destroyed again. It is the callees -// responsibility to make sure this happens. -class UseCounterMuteScope { - STACK_ALLOCATED(); - - public: - UseCounterMuteScope(const Element& element); - ~UseCounterMuteScope(); - - private: - Member<DocumentLoader> loader_; -}; - -// This class provides an implementation of UseCounter - see the class comment -// of blink::UseCounter for the feature. -// Changes on UseCounterHelper are observable by UseCounterHelper::Observer. -class CORE_EXPORT UseCounterHelper final { - DISALLOW_NEW(); - - public: - // The context determines whether a feature is reported to UMA histograms. For - // example, when the context is set to kDisabledContext, no features will be - // reported to UMA, but features may still be marked as seen to avoid multiple - // console warnings for deprecation. - enum Context { - kDefaultContext, - // Counters for extensions. - kExtensionContext, - // Context for file:// URLs. - kFileContext, - // Context when counters should be disabled (eg, internal pages such as - // about, devtools, etc). - kDisabledContext - }; - - enum CommitState { kPreCommit, kCommited }; - - // CSS properties for animation are separately counted. This enum is used to - // distinguish them. - enum class CSSPropertyType { kDefault, kAnimation }; - - explicit UseCounterHelper(Context = kDefaultContext, - CommitState = kPreCommit); - - // An interface to observe UseCounterHelper changes. Note that this is never - // notified when the counter is disabled by |m_muteCount| or when |m_context| - // is kDisabledContext. - class Observer : public GarbageCollected<Observer> { - public: - // Notified when a feature is counted for the first time. This should return - // true if it no longer needs to observe changes so that the counter can - // remove a reference to the observer and stop notifications. - virtual bool OnCountFeature(WebFeature) = 0; - - virtual void Trace(blink::Visitor* visitor) {} - }; - - // Repeated calls are ignored. - void Count(CSSPropertyID, CSSPropertyType, const LocalFrame*); - // Repeated calls are ignored. - void Count(WebFeature, const LocalFrame*); - - bool IsCounted(CSSPropertyID unresolved_property, CSSPropertyType) const; - - // Retains a reference to the observer to notify of UseCounterHelper changes. - void AddObserver(Observer*); - - // Invoked when a new document is loaded into the main frame of the page. - void DidCommitLoad(const LocalFrame*); - - // When muted, all calls to "count" functions are ignoed. May be nested. - void MuteForInspector(); - void UnmuteForInspector(); - - void RecordMeasurement(WebFeature, const LocalFrame&); - void ReportAndTraceMeasurementByFeatureId(int, const LocalFrame&); - void ReportAndTraceMeasurementByCSSSampleId(int, - const LocalFrame*, - bool /*is_animated*/); - - // Return whether the feature has been seen since the last page load - // (except when muted). Does include features seen in documents which have - // reporting disabled. - bool HasRecordedMeasurement(WebFeature) const; - - void ClearMeasurementForTesting(WebFeature); - - void Trace(blink::Visitor*); - - private: - // Notifies that a feature is newly counted to |m_observers|. This shouldn't - // be called when the counter is disabled by |m_muteCount| or when |m_context| - // if kDisabledContext. - void NotifyFeatureCounted(WebFeature); - - EnumerationHistogram& FeaturesHistogram() const; - EnumerationHistogram& CssHistogram() const; - EnumerationHistogram& AnimatedCSSHistogram() const; - - static int MapCSSPropertyIdToCSSSampleIdForHistogram(CSSPropertyID); - - // If non-zero, ignore all 'count' calls completely. - unsigned mute_count_; - - // The scope represented by this UseCounterHelper instance, which must be - // fixed for the duration of a page but can change when a new page is loaded. - Context context_; - // CommitState tracks whether navigation has commited. Prior to commit, - // UseCounters are logged locally and delivered to the browser only once the - // document has been commited (eg. to ensure never logging a feature that has - // no corresponding PageVisits). - CommitState commit_state_; - - // Track what features/properties have been recorded. - std::bitset<static_cast<size_t>(WebFeature::kNumberOfFeatures)> - features_recorded_; - std::bitset<numCSSPropertyIDs> css_recorded_; - std::bitset<numCSSPropertyIDs> animated_css_recorded_; - - HeapHashSet<Member<Observer>> observers_; - - DISALLOW_COPY_AND_ASSIGN(UseCounterHelper); -}; - -} // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_USE_COUNTER_H_
diff --git a/third_party/blink/renderer/core/frame/use_counter.cc b/third_party/blink/renderer/core/frame/use_counter_helper.cc similarity index 99% rename from third_party/blink/renderer/core/frame/use_counter.cc rename to third_party/blink/renderer/core/frame/use_counter_helper.cc index 5b723084..ca80548 100644 --- a/third_party/blink/renderer/core/frame/use_counter.cc +++ b/third_party/blink/renderer/core/frame/use_counter_helper.cc
@@ -23,7 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "third_party/blink/renderer/core/frame/use_counter.h" +#include "third_party/blink/renderer/core/frame/use_counter_helper.h" #include "third_party/blink/public/mojom/use_counter/css_property_id.mojom-blink.h" #include "third_party/blink/renderer/core/css/css_style_sheet.h"
diff --git a/third_party/blink/renderer/core/frame/use_counter_helper.h b/third_party/blink/renderer/core/frame/use_counter_helper.h new file mode 100644 index 0000000..8b0145a --- /dev/null +++ b/third_party/blink/renderer/core/frame/use_counter_helper.h
@@ -0,0 +1,175 @@ +/* + * Copyright (C) 2012 Google, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_USE_COUNTER_HELPER_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_USE_COUNTER_HELPER_H_ + +#include <bitset> +#include "base/macros.h" +#include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/css/css_property_names.h" +#include "third_party/blink/renderer/core/css/parser/css_parser_mode.h" +#include "third_party/blink/renderer/core/frame/web_feature.h" +#include "third_party/blink/renderer/platform/heap/garbage_collected.h" +#include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" +#include "third_party/blink/renderer/platform/wtf/forward.h" + +namespace blink { + +class DocumentLoader; +class Element; +class EnumerationHistogram; +class LocalFrame; + +// Utility class for muting UseCounter, for instance ignoring attributes +// constructed in user-agent shadow DOM. Once constructed, all UseCounting +// is muted, until the object is destroyed again. It is the callees +// responsibility to make sure this happens. +class UseCounterMuteScope { + STACK_ALLOCATED(); + + public: + UseCounterMuteScope(const Element& element); + ~UseCounterMuteScope(); + + private: + Member<DocumentLoader> loader_; +}; + +// This class provides an implementation of UseCounter - see the class comment +// of blink::UseCounter for the feature. +// Changes on UseCounterHelper are observable by UseCounterHelper::Observer. +class CORE_EXPORT UseCounterHelper final { + DISALLOW_NEW(); + + public: + // The context determines whether a feature is reported to UMA histograms. For + // example, when the context is set to kDisabledContext, no features will be + // reported to UMA, but features may still be marked as seen to avoid multiple + // console warnings for deprecation. + enum Context { + kDefaultContext, + // Counters for extensions. + kExtensionContext, + // Context for file:// URLs. + kFileContext, + // Context when counters should be disabled (eg, internal pages such as + // about, devtools, etc). + kDisabledContext + }; + + enum CommitState { kPreCommit, kCommited }; + + // CSS properties for animation are separately counted. This enum is used to + // distinguish them. + enum class CSSPropertyType { kDefault, kAnimation }; + + explicit UseCounterHelper(Context = kDefaultContext, + CommitState = kPreCommit); + + // An interface to observe UseCounterHelper changes. Note that this is never + // notified when the counter is disabled by |m_muteCount| or when |m_context| + // is kDisabledContext. + class Observer : public GarbageCollected<Observer> { + public: + // Notified when a feature is counted for the first time. This should return + // true if it no longer needs to observe changes so that the counter can + // remove a reference to the observer and stop notifications. + virtual bool OnCountFeature(WebFeature) = 0; + + virtual void Trace(blink::Visitor* visitor) {} + }; + + // Repeated calls are ignored. + void Count(CSSPropertyID, CSSPropertyType, const LocalFrame*); + // Repeated calls are ignored. + void Count(WebFeature, const LocalFrame*); + + bool IsCounted(CSSPropertyID unresolved_property, CSSPropertyType) const; + + // Retains a reference to the observer to notify of UseCounterHelper changes. + void AddObserver(Observer*); + + // Invoked when a new document is loaded into the main frame of the page. + void DidCommitLoad(const LocalFrame*); + + // When muted, all calls to "count" functions are ignoed. May be nested. + void MuteForInspector(); + void UnmuteForInspector(); + + void RecordMeasurement(WebFeature, const LocalFrame&); + void ReportAndTraceMeasurementByFeatureId(int, const LocalFrame&); + void ReportAndTraceMeasurementByCSSSampleId(int, + const LocalFrame*, + bool /*is_animated*/); + + // Return whether the feature has been seen since the last page load + // (except when muted). Does include features seen in documents which have + // reporting disabled. + bool HasRecordedMeasurement(WebFeature) const; + + void ClearMeasurementForTesting(WebFeature); + + void Trace(blink::Visitor*); + + private: + // Notifies that a feature is newly counted to |m_observers|. This shouldn't + // be called when the counter is disabled by |m_muteCount| or when |m_context| + // if kDisabledContext. + void NotifyFeatureCounted(WebFeature); + + EnumerationHistogram& FeaturesHistogram() const; + EnumerationHistogram& CssHistogram() const; + EnumerationHistogram& AnimatedCSSHistogram() const; + + static int MapCSSPropertyIdToCSSSampleIdForHistogram(CSSPropertyID); + + // If non-zero, ignore all 'count' calls completely. + unsigned mute_count_; + + // The scope represented by this UseCounterHelper instance, which must be + // fixed for the duration of a page but can change when a new page is loaded. + Context context_; + // CommitState tracks whether navigation has commited. Prior to commit, + // UseCounters are logged locally and delivered to the browser only once the + // document has been commited (eg. to ensure never logging a feature that has + // no corresponding PageVisits). + CommitState commit_state_; + + // Track what features/properties have been recorded. + std::bitset<static_cast<size_t>(WebFeature::kNumberOfFeatures)> + features_recorded_; + std::bitset<numCSSPropertyIDs> css_recorded_; + std::bitset<numCSSPropertyIDs> animated_css_recorded_; + + HeapHashSet<Member<Observer>> observers_; + + DISALLOW_COPY_AND_ASSIGN(UseCounterHelper); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_USE_COUNTER_HELPER_H_
diff --git a/third_party/blink/renderer/core/frame/use_counter_test.cc b/third_party/blink/renderer/core/frame/use_counter_helper_test.cc similarity index 99% rename from third_party/blink/renderer/core/frame/use_counter_test.cc rename to third_party/blink/renderer/core/frame/use_counter_helper_test.cc index ca4a76a..6c51028a 100644 --- a/third_party/blink/renderer/core/frame/use_counter_test.cc +++ b/third_party/blink/renderer/core/frame/use_counter_helper_test.cc
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/renderer/core/frame/use_counter.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/mojom/use_counter/css_property_id.mojom-blink.h" #include "third_party/blink/renderer/core/dom/shadow_root.h" #include "third_party/blink/renderer/core/frame/deprecation.h" +#include "third_party/blink/renderer/core/frame/use_counter.h" #include "third_party/blink/renderer/core/html/html_html_element.h" #include "third_party/blink/renderer/core/loader/document_loader.h" #include "third_party/blink/renderer/core/page/page.h"
diff --git a/third_party/blink/renderer/core/input/event_handler.cc b/third_party/blink/renderer/core/input/event_handler.cc index ebde4d2..b490f79a 100644 --- a/third_party/blink/renderer/core/input/event_handler.cc +++ b/third_party/blink/renderer/core/input/event_handler.cc
@@ -2294,12 +2294,10 @@ if (capture_target) { LayoutObject* layout_object = capture_target->GetLayoutObject(); - // TODO(eirage): Is kIgnoreTransforms correct here? LayoutPoint local_point = layout_object ? layout_object ->AbsoluteToLocalPoint( - PhysicalOffsetToBeNoop(document_point), - kIgnoreTransforms) + PhysicalOffsetToBeNoop(document_point)) .ToLayoutPoint() : document_point;
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 9cb23518..2b94c53 100644 --- a/third_party/blink/renderer/core/input/event_handler_test.cc +++ b/third_party/blink/renderer/core/input/event_handler_test.cc
@@ -12,6 +12,7 @@ #include "third_party/blink/public/platform/web_keyboard_event.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/range.h" +#include "third_party/blink/renderer/core/editing/dom_selection.h" #include "third_party/blink/renderer/core/editing/editing_behavior.h" #include "third_party/blink/renderer/core/editing/editor.h" #include "third_party/blink/renderer/core/editing/ephemeral_range.h" @@ -2170,4 +2171,62 @@ ASSERT_EQ(visual_viewport.GetScrollOffset().Height(), 300); } +TEST_F(EventHandlerSimTest, SelecteTransformedTextWhenCapturing) { + WebView().MainFrameWidget()->Resize(WebSize(800, 600)); + SimRequest request("https://example.com/test.html", "text/html"); + LoadURL("https://example.com/test.html"); + request.Complete(R"HTML( + <!DOCTYPE html> + <div id='target' style = "width:250px; transform: rotate(180deg)"> + Some text to select + </div> + )HTML"); + Compositor().BeginFrame(); + + WebMouseEvent mouse_down_event(WebInputEvent::kMouseDown, + WebFloatPoint(100, 20), WebFloatPoint(0, 0), + WebPointerProperties::Button::kLeft, 1, + WebInputEvent::Modifiers::kLeftButtonDown, + WebInputEvent::GetStaticTimeStampForTests()); + mouse_down_event.SetFrameScale(1); + GetDocument().GetFrame()->GetEventHandler().HandleMousePressEvent( + mouse_down_event); + + ASSERT_TRUE(GetDocument() + .GetFrame() + ->GetEventHandler() + .GetSelectionController() + .MouseDownMayStartSelect()); + + Element* target = GetDocument().getElementById("target"); + GetDocument().GetFrame()->GetEventHandler().SetPointerCapture( + PointerEventFactory::kMouseId, target); + + WebMouseEvent mouse_move_event(WebInputEvent::kMouseMove, + WebFloatPoint(258, 20), WebFloatPoint(0, 0), + WebPointerProperties::Button::kLeft, 1, + WebInputEvent::Modifiers::kLeftButtonDown, + WebInputEvent::GetStaticTimeStampForTests()); + mouse_move_event.SetFrameScale(1); + GetDocument().GetFrame()->GetEventHandler().HandleMouseMoveEvent( + mouse_move_event, Vector<WebMouseEvent>(), Vector<WebMouseEvent>()); + + WebMouseEvent mouse_up_event( + WebMouseEvent::kMouseUp, WebFloatPoint(258, 20), WebFloatPoint(0, 0), + WebPointerProperties::Button::kLeft, 1, WebInputEvent::kNoModifiers, + WebInputEvent::GetStaticTimeStampForTests()); + mouse_up_event.SetFrameScale(1); + GetDocument().GetFrame()->GetEventHandler().HandleMouseReleaseEvent( + mouse_up_event); + + ASSERT_FALSE(GetDocument() + .GetFrame() + ->GetEventHandler() + .GetSelectionController() + .MouseDownMayStartSelect()); + + ASSERT_TRUE(GetDocument().GetSelection()); + EXPECT_EQ("Some text to select", GetDocument().GetSelection()->toString()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/jank_tracker_test.cc b/third_party/blink/renderer/core/layout/jank_tracker_test.cc index 2df6908..ed95372 100644 --- a/third_party/blink/renderer/core/layout/jank_tracker_test.cc +++ b/third_party/blink/renderer/core/layout/jank_tracker_test.cc
@@ -331,4 +331,55 @@ EXPECT_FLOAT_EQ(0.15, jank_tracker.WeightedScore()); } +TEST_F(JankTrackerTest, StableCompositingChanges) { + SetBodyInnerHTML(R"HTML( + <style> + body { margin: 0; } + #outer { + margin-left: 50px; + margin-top: 50px; + width: 200px; + height: 200px; + background: #dde; + } + .tr { + will-change: transform; + } + .pl { + position: relative; + z-index: 0; + left: 0; + top: 0; + } + #inner { + display: inline-block; + width: 100px; + height: 100px; + background: #666; + margin-left: 50px; + margin-top: 50px; + } + </style> + <div id=outer><div id=inner></div></div> + )HTML"); + + Element* element = GetDocument().getElementById("outer"); + size_t state = 0; + auto advance = [this, element, &state]() -> bool { + // + // Test each of the following transitions: + // - add/remove a PaintLayer + // - add/remove a cc::Layer when there is already a PaintLayer + // - add/remove a cc::Layer and a PaintLayer together + + static const char* states[] = {"", "pl", "pl tr", "pl", "", "tr", ""}; + element->setAttribute(html_names::kClassAttr, AtomicString(states[state])); + UpdateAllLifecyclePhases(); + return ++state < sizeof states / sizeof *states; + }; + while (advance()) { + } + EXPECT_FLOAT_EQ(0, GetJankTracker().Score()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_block.cc b/third_party/blink/renderer/core/layout/layout_block.cc index 54b0485..0839573 100644 --- a/third_party/blink/renderer/core/layout/layout_block.cc +++ b/third_party/blink/renderer/core/layout/layout_block.cc
@@ -1115,13 +1115,13 @@ void LayoutBlock::AddPercentHeightDescendant(LayoutBox* descendant) { // A replaced object is incapable of properly acting as a containing block for - // its children (this is an issue with VIDEO elements, for instance, which - // inserts some percentage height flexbox children). Assert that the - // descendant hasn't escaped from within a replaced object. Registering the - // percentage height descendant further up in the tree is only going to cause - // trouble, especially if the replaced object is out-of-flow positioned (and - // we failed to notice). - DCHECK(!descendant->Container()->IsLayoutReplaced()); + // its children. This is an issue with VIDEO elements, for instance, which + // insert some percentage height flexbox children. It is also very easily + // achievable with a foreignObject inside an SVG. Detect this situation and + // bail. The assumption is that there is no situation where we require quirky + // percentage height behavior inside replaced content. + if (UNLIKELY(descendant->Container()->IsLayoutReplaced())) + return; if (descendant->PercentHeightContainer()) { if (descendant->PercentHeightContainer() == this) {
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc index 9cbf663..5b1349b 100644 --- a/third_party/blink/renderer/core/layout/layout_box.cc +++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -3793,13 +3793,7 @@ &cb, &skipped_auto_height_containing_block); DCHECK(cb); - - // If the container of the descendant is a replaced element (a VIDEO, for - // instance), |cb| (which uses ContainingBlock()) may actually not be in the - // containing block chain for the descendant. - const LayoutObject* container = Container(); - if (!container->IsLayoutReplaced()) - cb->AddPercentHeightDescendant(const_cast<LayoutBox*>(this)); + cb->AddPercentHeightDescendant(const_cast<LayoutBox*>(this)); if (available_height == -1) return available_height;
diff --git a/third_party/blink/renderer/core/loader/base_fetch_context.h b/third_party/blink/renderer/core/loader/base_fetch_context.h index de03346..c8117e9 100644 --- a/third_party/blink/renderer/core/loader/base_fetch_context.h +++ b/third_party/blink/renderer/core/loader/base_fetch_context.h
@@ -51,6 +51,8 @@ return *fetcher_properties_; } + virtual void CountUsage(mojom::WebFeature) const = 0; + virtual void CountDeprecation(mojom::WebFeature) const = 0; virtual KURL GetSiteForCookies() const = 0; // Returns the origin of the top frame in the document.
diff --git a/third_party/blink/renderer/core/loader/document_loader.h b/third_party/blink/renderer/core/loader/document_loader.h index e375881..f1460c1 100644 --- a/third_party/blink/renderer/core/loader/document_loader.h +++ b/third_party/blink/renderer/core/loader/document_loader.h
@@ -48,6 +48,7 @@ #include "third_party/blink/renderer/core/frame/dactyloscoper.h" #include "third_party/blink/renderer/core/frame/frame_types.h" #include "third_party/blink/renderer/core/frame/use_counter.h" +#include "third_party/blink/renderer/core/frame/use_counter_helper.h" #include "third_party/blink/renderer/core/html/parser/parser_synchronization_policy.h" #include "third_party/blink/renderer/core/loader/document_load_timing.h" #include "third_party/blink/renderer/core/loader/frame_loader_types.h"
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context.cc b/third_party/blink/renderer/core/loader/frame_fetch_context.cc index 768b7ab..ea33c4f 100644 --- a/third_party/blink/renderer/core/loader/frame_fetch_context.cc +++ b/third_party/blink/renderer/core/loader/frame_fetch_context.cc
@@ -94,6 +94,7 @@ #include "third_party/blink/renderer/platform/histogram.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h" #include "third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.h" +#include "third_party/blink/renderer/platform/loader/fetch/detachable_use_counter.h" #include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h" #include "third_party/blink/renderer/platform/loader/fetch/resource.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_load_priority.h" @@ -240,9 +241,9 @@ properties), frame.GetTaskRunner(TaskType::kNetworking), MakeGarbageCollected<LoaderFactoryForFrame>(frame_or_imported_document)); - auto* console_logger = + init.use_counter = MakeGarbageCollected<DetachableUseCounter>(&document); + init.console_logger = MakeGarbageCollected<DetachableConsoleLogger>(&document); - init.console_logger = console_logger; // Frame loading should normally start with |kTight| throttling, as the // frame will be in layout-blocking state until the <body> tag is inserted init.initial_throttling_policy = @@ -276,9 +277,8 @@ properties), document->GetTaskRunner(blink::TaskType::kNetworking), MakeGarbageCollected<LoaderFactoryForFrame>(frame_or_imported_document)); - auto* console_logger = - MakeGarbageCollected<DetachableConsoleLogger>(document); - init.console_logger = console_logger; + init.use_counter = MakeGarbageCollected<DetachableUseCounter>(document); + init.console_logger = MakeGarbageCollected<DetachableConsoleLogger>(document); init.frame_scheduler = frame.GetFrameScheduler(); auto* fetcher = MakeGarbageCollected<ResourceFetcher>(init); fetcher->SetResourceLoadObserver(
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context.h b/third_party/blink/renderer/core/loader/frame_fetch_context.h index 756bbef..42d028b 100644 --- a/third_party/blink/renderer/core/loader/frame_fetch_context.h +++ b/third_party/blink/renderer/core/loader/frame_fetch_context.h
@@ -33,6 +33,7 @@ #include "base/optional.h" #include "base/single_thread_task_runner.h" +#include "third_party/blink/public/common/user_agent/user_agent_metadata.h" #include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom-blink.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/loader/base_fetch_context.h"
diff --git a/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc b/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc index 8412d3f..4f41fac 100644 --- a/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc +++ b/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc
@@ -381,8 +381,9 @@ #endif } -static void ForceRecomputeVisualRectsIncludingNonCompositingDescendants( - LayoutObject& layout_object) { +void PaintLayerCompositor:: + ForceRecomputeVisualRectsIncludingNonCompositingDescendants( + LayoutObject& layout_object) { // We clear the previous visual rect as it's wrong (paint invalidation // container changed, ...). Forcing a full invalidation will make us recompute // it. Also we are not changing the previous position from our paint
diff --git a/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h b/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h index 7264ea9..bbb7d42 100644 --- a/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h +++ b/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h
@@ -167,6 +167,9 @@ compositing_inputs_root_.Update(layer); } + void ForceRecomputeVisualRectsIncludingNonCompositingDescendants( + LayoutObject&); + private: #if DCHECK_IS_ON() void AssertNoUnresolvedDirtyBits();
diff --git a/third_party/blink/renderer/core/paint/paint_layer.cc b/third_party/blink/renderer/core/paint/paint_layer.cc index c08e7746..ae57e30e 100644 --- a/third_party/blink/renderer/core/paint/paint_layer.cc +++ b/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -214,8 +214,10 @@ // Child layers will be deleted by their corresponding layout objects, so // we don't need to delete them ourselves. - - ClearCompositedLayerMapping(true); + { + DisableCompositingQueryAsserts disabler; + ClearCompositedLayerMapping(true); + } if (scrollable_area_) scrollable_area_->Dispose(); @@ -2793,7 +2795,7 @@ } void PaintLayer::EnsureCompositedLayerMapping() { - if (rare_data_ && rare_data_->composited_layer_mapping) + if (HasCompositedLayerMapping()) return; EnsureRareData().composited_layer_mapping = @@ -2803,7 +2805,25 @@ } void PaintLayer::ClearCompositedLayerMapping(bool layer_being_destroyed) { - if (!layer_being_destroyed) { + if (!HasCompositedLayerMapping()) + return; + + if (layer_being_destroyed) { + if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { + // The visual rects will be in a different coordinate space after losing + // their compositing container. Clear them before prepaint to avoid + // spurious layout shift reports from JankTracker. + // If the PaintLayer were not being destroyed, this would happen during + // the compositing update (PaintLayerCompositor::UpdateIfNeeded). + // TODO: JankTracker's reliance on having visual rects cleared before + // prepaint in the case of compositing changes is not ideal, and will not + // work with CompositeAfterPaint. Some transform tree changes may still + // produce incorrect behavior from JankTracker (see discussion on review + // thread of http://crrev.com/c/1636403). + Compositor()->ForceRecomputeVisualRectsIncludingNonCompositingDescendants( + layout_object_); + } + } else { // We need to make sure our decendants get a geometry update. In principle, // we could call setNeedsGraphicsLayerUpdate on our children, but that would // require walking the z-order lists to find them. Instead, we @@ -2813,9 +2833,8 @@ compositing_parent->GetCompositedLayerMapping() ->SetNeedsGraphicsLayerUpdate(kGraphicsLayerUpdateSubtree); } - - if (rare_data_) - rare_data_->composited_layer_mapping.reset(); + DCHECK(rare_data_); + rare_data_->composited_layer_mapping.reset(); } void PaintLayer::SetGroupedMapping(CompositedLayerMapping* grouped_mapping,
diff --git a/third_party/blink/renderer/core/script/classic_pending_script.cc b/third_party/blink/renderer/core/script/classic_pending_script.cc index 3bd0f996..cbd7834 100644 --- a/third_party/blink/renderer/core/script/classic_pending_script.cc +++ b/third_party/blink/renderer/core/script/classic_pending_script.cc
@@ -22,6 +22,7 @@ #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/loader/allowed_by_nosniff.h" #include "third_party/blink/renderer/platform/loader/fetch/cached_metadata.h" +#include "third_party/blink/renderer/platform/loader/fetch/detachable_use_counter.h" #include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h" #include "third_party/blink/renderer/platform/loader/fetch/raw_resource.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_client.h" @@ -342,7 +343,7 @@ auto* fetcher = GetElement()->GetDocument().ContextDocument()->Fetcher(); // If the MIME check fails, which is considered as load failure. if (!AllowedByNosniff::MimeTypeAsScript( - fetcher->Context(), &fetcher->GetConsoleLogger(), + fetcher->GetUseCounter(), &fetcher->GetConsoleLogger(), resource->GetResponse(), AllowedByNosniff::MimeTypeCheck::kLax)) { return nullptr; }
diff --git a/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc b/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc index eeeaa47..c51ae114 100644 --- a/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc +++ b/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc
@@ -37,6 +37,7 @@ #include "third_party/blink/renderer/core/loader/resource/script_resource.h" #include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h" #include "third_party/blink/renderer/core/workers/worker_global_scope.h" +#include "third_party/blink/renderer/platform/loader/fetch/detachable_use_counter.h" #include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h" @@ -177,7 +178,7 @@ return; } if (!AllowedByNosniff::MimeTypeAsScript( - fetch_client_settings_object_fetcher_->Context(), + fetch_client_settings_object_fetcher_->GetUseCounter(), &fetch_client_settings_object_fetcher_->GetConsoleLogger(), response, fetch_client_settings_object_fetcher_->GetProperties() .GetFetchClientSettingsObject()
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 477614b..e27efa1 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
@@ -24,6 +24,7 @@ #include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h" #include "third_party/blink/renderer/core/workers/worker_thread.h" #include "third_party/blink/renderer/platform/cross_thread_functional.h" +#include "third_party/blink/renderer/platform/loader/fetch/detachable_use_counter.h" #include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h" #include "third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" @@ -306,8 +307,8 @@ GetTaskRunner(TaskType::kNetworking), MakeGarbageCollected<LoaderFactoryForWorker>( *this, web_worker_fetch_context_)); - auto* console_logger = MakeGarbageCollected<DetachableConsoleLogger>(this); - init.console_logger = console_logger; + init.use_counter = MakeGarbageCollected<DetachableUseCounter>(this); + init.console_logger = MakeGarbageCollected<DetachableConsoleLogger>(this); fetcher = MakeGarbageCollected<ResourceFetcher>(init); fetcher->SetResourceLoadObserver( MakeGarbageCollected<ResourceLoadObserverForWorker>(
diff --git a/third_party/blink/renderer/devtools/front_end/ui/ui_strings.grdp b/third_party/blink/renderer/devtools/front_end/ui/ui_strings.grdp index cd35e68..263028b 100644 --- a/third_party/blink/renderer/devtools/front_end/ui/ui_strings.grdp +++ b/third_party/blink/renderer/devtools/front_end/ui/ui_strings.grdp
@@ -45,6 +45,9 @@ <message name="IDS_DEVTOOLS_2c0924faed417c521b57d553c678ec21" desc=""> Step into </message> + <message name="IDS_DEVTOOLS_2ce2fc341b0bd9219a3634ff43a90bde" desc=""> + <ph name="ITEM_LABEL">$1s</ph>, <ph name="ITEM_SHORTCUT">$2s</ph> + </message> <message name="IDS_DEVTOOLS_2dfef1e9ae6e4da36eb0bbeea94742b9" desc=""> <ph name="MEGABYTES">$1.1f</ph> MB </message> @@ -219,6 +222,12 @@ <message name="IDS_DEVTOOLS_b228e7bd736e688236ab3aa37996bf8f" desc=""> Decrement by <ph name="__">$1f</ph> </message> + <message name="IDS_DEVTOOLS_b4b10705557aadcdad1f3182cadeaa76" desc=""> + <ph name="ITEM_LABEL">$1s</ph>, checked + </message> + <message name="IDS_DEVTOOLS_b508f4cb8252d1d90689d1a61344c8fc" desc=""> + <ph name="ITEM_LABEL">$1s</ph>, checked, <ph name="ITEM_SHORTCUT">$2s</ph> + </message> <message name="IDS_DEVTOOLS_b79165bf6163186253ed04568e1aee11" desc=""> Pause/ Continue </message>
diff --git a/third_party/blink/renderer/modules/webaudio/audio_context.cc b/third_party/blink/renderer/modules/webaudio/audio_context.cc index 89a0de1..f323213 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_context.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_context.cc
@@ -529,7 +529,7 @@ } bool AudioContext::HandlePreRenderTasks(const AudioIOPosition* output_position, - const AudioIOCallbackMetric* metric) { + const AudioCallbackMetric* metric) { DCHECK(IsAudioThread()); // At the beginning of every render quantum, try to update the internal @@ -677,7 +677,7 @@ double AudioContext::RenderCapacity() { DCHECK(IsMainThread()); GraphAutoLocker locker(this); - return callback_metric_.render_duration / callback_metric_.callback_interval; + return callback_metric_.render_capacity; } } // namespace blink
diff --git a/third_party/blink/renderer/modules/webaudio/audio_context.h b/third_party/blink/renderer/modules/webaudio/audio_context.h index e8cbb7a..1402683 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_context.h +++ b/third_party/blink/renderer/modules/webaudio/audio_context.h
@@ -73,7 +73,7 @@ void set_was_audible_for_testing(bool value) { was_audible_ = value; } bool HandlePreRenderTasks(const AudioIOPosition* output_position, - const AudioIOCallbackMetric* metric) final; + const AudioCallbackMetric* metric) final; // Called at the end of each render quantum. void HandlePostRenderTasks() final; @@ -152,7 +152,7 @@ Member<ScriptPromiseResolver> close_resolver_; AudioIOPosition output_position_; - AudioIOCallbackMetric callback_metric_; + AudioCallbackMetric callback_metric_; // Whether a user gesture is required to start this AudioContext. bool user_gesture_required_ = false;
diff --git a/third_party/blink/renderer/modules/webaudio/base_audio_context.h b/third_party/blink/renderer/modules/webaudio/base_audio_context.h index 8351bd86..d3ff40e 100644 --- a/third_party/blink/renderer/modules/webaudio/base_audio_context.h +++ b/third_party/blink/renderer/modules/webaudio/base_audio_context.h
@@ -43,6 +43,7 @@ #include "third_party/blink/renderer/modules/webaudio/deferred_task_handler.h" #include "third_party/blink/renderer/modules/webaudio/iir_filter_node.h" #include "third_party/blink/renderer/platform/audio/audio_bus.h" +#include "third_party/blink/renderer/platform/audio/audio_callback_metric_reporter.h" #include "third_party/blink/renderer/platform/audio/audio_io_callback.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/wtf/hash_set.h" @@ -249,7 +250,7 @@ // - The return value indicates whether the context needs to be suspended or // not after rendering. virtual bool HandlePreRenderTasks(const AudioIOPosition* output_position, - const AudioIOCallbackMetric* metric) = 0; + const AudioCallbackMetric* metric) = 0; // Called at the end of each render quantum. virtual void HandlePostRenderTasks() = 0;
diff --git a/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc b/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc index 4e74b80c..3830b5d 100644 --- a/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc +++ b/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc
@@ -389,11 +389,14 @@ bool OfflineAudioContext::HandlePreRenderTasks( const AudioIOPosition* output_position, - const AudioIOCallbackMetric* metric) { - DCHECK(IsAudioThread()); + const AudioCallbackMetric* metric) { + // TODO(hongchan, rtoy): passing |nullptr| as an argument is not a good + // pattern. Consider rewriting this method/interface. DCHECK_EQ(output_position, nullptr); DCHECK_EQ(metric, nullptr); + DCHECK(IsAudioThread()); + // OfflineGraphAutoLocker here locks the audio graph for this scope. Note // that this locker does not use tryLock() inside because the timing of // suspension MUST NOT be delayed.
diff --git a/third_party/blink/renderer/modules/webaudio/offline_audio_context.h b/third_party/blink/renderer/modules/webaudio/offline_audio_context.h index bc9462e..4c1cbd8 100644 --- a/third_party/blink/renderer/modules/webaudio/offline_audio_context.h +++ b/third_party/blink/renderer/modules/webaudio/offline_audio_context.h
@@ -76,7 +76,7 @@ void FireCompletionEvent(); bool HandlePreRenderTasks(const AudioIOPosition* output_position, - const AudioIOCallbackMetric* metric) final; + const AudioCallbackMetric* metric) final; void HandlePostRenderTasks() final; // Resolve a suspend scheduled at the specified frame. With this specified
diff --git a/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.cc b/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.cc index 376f84f..aac30e2 100644 --- a/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.cc +++ b/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.cc
@@ -165,7 +165,7 @@ AudioBus* destination_bus, uint32_t number_of_frames, const AudioIOPosition& output_position, - const AudioIOCallbackMetric& metric) { + const AudioCallbackMetric& metric) { TRACE_EVENT0("webaudio", "RealtimeAudioDestinationHandler::Render"); // Denormals can seriously hurt performance of audio processing. This will
diff --git a/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.h b/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.h index e495ec6d..05a865d1 100644 --- a/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.h +++ b/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.h
@@ -29,6 +29,7 @@ #include <memory> #include "third_party/blink/public/platform/web_audio_latency_hint.h" #include "third_party/blink/renderer/modules/webaudio/audio_destination_node.h" +#include "third_party/blink/renderer/platform/audio/audio_callback_metric_reporter.h" #include "third_party/blink/renderer/platform/audio/audio_destination.h" #include "third_party/blink/renderer/platform/audio/audio_io_callback.h" @@ -71,7 +72,7 @@ void Render(AudioBus* destination_bus, uint32_t number_of_frames, const AudioIOPosition& output_position, - const AudioIOCallbackMetric& metric) final; + const AudioCallbackMetric& metric) final; // Returns a hadrware callback buffer size from audio infra. uint32_t GetCallbackBufferSize() const;
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_vertex_input_descriptor.idl b/third_party/blink/renderer/modules/webgpu/gpu_vertex_input_descriptor.idl index ab127f7..0f9591f 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_vertex_input_descriptor.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_vertex_input_descriptor.idl
@@ -5,7 +5,7 @@ // https://github.com/gpuweb/gpuweb/blob/master/design/sketch.webidl dictionary GPUVertexInputDescriptor { - required GPUIndexFormat indexFormat; + GPUIndexFormat indexFormat = "uint32"; // TODO(crbug.com/951629): Make this a sequence of nullables. object vertexBuffers; // We validate this is an array of nullable GPUVertexBufferDescriptor };
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index 070fd58..64ae02a 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -291,6 +291,8 @@ "audio/audio_array.h", "audio/audio_bus.cc", "audio/audio_bus.h", + "audio/audio_callback_metric_reporter.cc", + "audio/audio_callback_metric_reporter.h", "audio/audio_channel.cc", "audio/audio_channel.h", "audio/audio_delay_dsp_kernel.cc",
diff --git a/third_party/blink/renderer/platform/audio/audio_callback_metric_reporter.cc b/third_party/blink/renderer/platform/audio/audio_callback_metric_reporter.cc new file mode 100644 index 0000000..708ee0a --- /dev/null +++ b/third_party/blink/renderer/platform/audio/audio_callback_metric_reporter.cc
@@ -0,0 +1,73 @@ +// 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/platform/audio/audio_callback_metric_reporter.h" + +#include "third_party/blink/renderer/platform/audio/audio_utilities.h" + +namespace blink { + +void AudioCallbackMetricReporter::Initialize( + int callback_buffer_size, float sample_rate) { + DCHECK_GT(callback_buffer_size, 0); + DCHECK_GT(sample_rate, 0); + + metric_.expected_callback_interval = + callback_buffer_size / static_cast<double>(sample_rate); + + // Prime the mean interval with the expected one. + metric_.mean_callback_interval = metric_.expected_callback_interval; + + // Calculates |alpha_| based on the specified time constant. Instead of + // the sample rate, we use "callbacks per second". + alpha_ = audio_utilities::DiscreteTimeConstantForSampleRate( + time_constant_, + 1.0 / metric_.expected_callback_interval); +} + +void AudioCallbackMetricReporter::BeginTrace() { + callback_start_time_ = base::TimeTicks::Now(); + + // If this is the first callback, the previous timestamps are not valid. + if (metric_.number_of_callbacks == 0) { + previous_callback_start_time_ = + callback_start_time_ - + base::TimeDelta::FromSecondsD(metric_.expected_callback_interval); + + // Let's assume that the previous render duration is zero. + previous_render_end_time_ = previous_callback_start_time_; + } + + UpdateMetric(); +} + +void AudioCallbackMetricReporter::EndTrace() { + previous_render_end_time_ = base::TimeTicks::Now(); + previous_callback_start_time_ = callback_start_time_; +} + +void AudioCallbackMetricReporter::UpdateMetric() { + metric_.number_of_callbacks++; + + // Calculate the callback interval between callback(n-1) and callback(n) and + // the render duration of previous render quantum. + callback_interval_ = + (callback_start_time_ - previous_callback_start_time_).InSecondsF(); + render_duration_ = + (previous_render_end_time_ - previous_callback_start_time_) + .InSecondsF(); + + // Calculates the instantaneous render capacity. + metric_.render_capacity = render_duration_ / callback_interval_; + + // The algorithm for exponentially-weighted mean and variance: + // http://people.ds.cam.ac.uk/fanf2/hermes/doc/antiforgery/stats.pdf (p. 8) + double diff = callback_interval_ - metric_.mean_callback_interval; + double increment = alpha_ * diff; + metric_.mean_callback_interval += increment; + metric_.variance_callback_interval = + (1 - alpha_) * (metric_.variance_callback_interval + diff * increment); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/platform/audio/audio_callback_metric_reporter.h b/third_party/blink/renderer/platform/audio/audio_callback_metric_reporter.h new file mode 100644 index 0000000..6c239c3 --- /dev/null +++ b/third_party/blink/renderer/platform/audio/audio_callback_metric_reporter.h
@@ -0,0 +1,85 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_AUDIO_AUDIO_CALLBACK_METRIC_REPORTER_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_AUDIO_AUDIO_CALLBACK_METRIC_REPORTER_H_ + +#include "base/time/time.h" + +namespace blink { + +// A data storage for callback/render related metric. WebAudio DevTool consumes +// this data eventually. +struct AudioCallbackMetric { + // The total number of callback so far. + int64_t number_of_callbacks = 0; + + // A value represents the current capacity of WebAudio renderer. + // = (time spent on actual graph rendering) / (platform callback interval)` + double render_capacity = 0.0; + + // Expected time (in sec) between callbacks, derived from the platform + // callback buffer size and the context sample rate. + double expected_callback_interval = 0.0; + + // A running mean of callback interval. This value should be close to + // |expected_callback_interval| on a system with accurate callback timer. + double mean_callback_interval = 0.0; + + // A running variance of callback interval. This value should be + // close to zero. + double variance_callback_interval = 0.0; +}; + +class AudioCallbackMetricReporter { + public: + AudioCallbackMetricReporter() {} + + // Must be called after WebAudioDevice is created, because we need the + // platform parameters like callback buffer size and hardware sample rate. + void Initialize(int callback_buffer_size, float sample_rate); + + // Gets called when the callback function starts. Calculates the metric for + // the previous callback right after obtaining the timestamp of current + // callback. + void BeginTrace(); + + // Gets called just before the callback function ends. Stores data for the + // current callback. + void EndTrace(); + + const AudioCallbackMetric& GetMetric() const { return metric_; } + + private: + void UpdateMetric(); + + // The start time of current callback function. + base::TimeTicks callback_start_time_; + + // The end time of previous callback function. The callback interval can be + // measured by |callback_start_time_| - |previous_callback_start_time_|. + base::TimeTicks previous_callback_start_time_; + + // The end time of previous render quantum. The previous render duration can + // be calculated by + // |previous_callback_start_time_| - |previous_render_end_time|. + base::TimeTicks previous_render_end_time_; + + double callback_interval_ = 0.0; + double render_duration_ = 0.0; + + // Time constant for smoothing the mean and variance metrics. Roughly, five + // times this value will be the memory of the metrics. + double time_constant_ = 1.0; + + // Filter coefficient for weighted mean and variance. Derived from + // |time_constant_|. + double alpha_ = 0.0; + + AudioCallbackMetric metric_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_AUDIO_AUDIO_CALLBACK_METRIC_REPORTER_H_
diff --git a/third_party/blink/renderer/platform/audio/audio_destination.cc b/third_party/blink/renderer/platform/audio/audio_destination.cc index 8fad2c4d..9b5cc1e 100644 --- a/third_party/blink/renderer/platform/audio/audio_destination.cc +++ b/third_party/blink/renderer/platform/audio/audio_destination.cc
@@ -87,6 +87,9 @@ callback_buffer_size_ = web_audio_device_->FramesPerBuffer(); + metric_reporter_.Initialize( + callback_buffer_size_, web_audio_device_->SampleRate()); + // Primes the FIFO for the given callback buffer size. This is to prevent // first FIFO pulls from causing "underflow" errors. const unsigned priming_render_quanta = @@ -213,16 +216,14 @@ "frames_to_render", frames_to_render, "timestamp (s)", delay_timestamp); + metric_reporter_.BeginTrace(); + frames_elapsed_ -= std::min(frames_elapsed_, prior_frames_skipped); output_position_.position = frames_elapsed_ / static_cast<double>(web_audio_device_->SampleRate()) - delay; output_position_.timestamp = delay_timestamp; - base::TimeTicks callback_request = base::TimeTicks::Now(); - metric_.callback_interval = - (callback_request - previous_callback_request_).InSecondsF(); - metric_.render_duration = previous_render_duration_.InSecondsF(); for (size_t pushed_frames = 0; pushed_frames < frames_to_render; pushed_frames += audio_utilities::kRenderQuantumFrames) { @@ -246,18 +247,15 @@ } else { // Process WebAudio graph and push the rendered output to FIFO. callback_.Render(render_bus_.get(), audio_utilities::kRenderQuantumFrames, - output_position_, metric_); + output_position_, metric_reporter_.GetMetric()); } fifo_->Push(render_bus_.get()); } - // Update the IO callback metric with information from the current iteration. - // They are will be picked up in the next render request. - previous_callback_request_ = callback_request; - previous_render_duration_ = base::TimeTicks::Now() - callback_request; - frames_elapsed_ += frames_requested; + + metric_reporter_.EndTrace(); } void AudioDestination::Start() { @@ -366,6 +364,6 @@ void AudioDestination::ProvideResamplerInput(int resampler_frame_delay, AudioBus* dest) { callback_.Render(dest, audio_utilities::kRenderQuantumFrames, - output_position_, metric_); + output_position_, metric_reporter_.GetMetric()); } } // namespace blink
diff --git a/third_party/blink/renderer/platform/audio/audio_destination.h b/third_party/blink/renderer/platform/audio/audio_destination.h index a19445e..f3045cc 100644 --- a/third_party/blink/renderer/platform/audio/audio_destination.h +++ b/third_party/blink/renderer/platform/audio/audio_destination.h
@@ -152,12 +152,6 @@ // engine. (i.e. DestinationNode) AudioIOCallback& callback_; - // When the last callback function from the device is called. - base::TimeTicks previous_callback_request_; - - // The time duration spent on rendering previous render quanta per callback. - base::TimeDelta previous_render_duration_; - // Accessed by rendering thread. size_t frames_elapsed_; @@ -171,7 +165,8 @@ // Required for RequestRender and also in the resampling callback (if used). AudioIOPosition output_position_; - AudioIOCallbackMetric metric_; + + AudioCallbackMetricReporter metric_reporter_; DISALLOW_COPY_AND_ASSIGN(AudioDestination); };
diff --git a/third_party/blink/renderer/platform/audio/audio_destination_test.cc b/third_party/blink/renderer/platform/audio/audio_destination_test.cc index ffab6ad..d1a43dc2 100644 --- a/third_party/blink/renderer/platform/audio/audio_destination_test.cc +++ b/third_party/blink/renderer/platform/audio/audio_destination_test.cc
@@ -9,6 +9,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/web_audio_device.h" #include "third_party/blink/public/platform/web_audio_latency_hint.h" +#include "third_party/blink/renderer/platform/audio/audio_callback_metric_reporter.h" #include "third_party/blink/renderer/platform/audio/audio_io_callback.h" #include "third_party/blink/renderer/platform/audio/audio_utilities.h" #include "third_party/blink/renderer/platform/testing/testing_platform_support.h" @@ -53,10 +54,10 @@ class AudioCallback : public blink::AudioIOCallback { public: - void Render(AudioBus* destination_bus, + void Render(AudioBus*, uint32_t frames_to_process, - const AudioIOPosition& output_position, - const AudioIOCallbackMetric& metric) override { + const AudioIOPosition&, + const AudioCallbackMetric&) override { frames_processed_ += frames_to_process; }
diff --git a/third_party/blink/renderer/platform/audio/audio_io_callback.h b/third_party/blink/renderer/platform/audio/audio_io_callback.h index cb9e87d..2f5f7238 100644 --- a/third_party/blink/renderer/platform/audio/audio_io_callback.h +++ b/third_party/blink/renderer/platform/audio/audio_io_callback.h
@@ -29,24 +29,12 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_AUDIO_AUDIO_IO_CALLBACK_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_AUDIO_AUDIO_IO_CALLBACK_H_ -#include "base/time/time.h" +#include "third_party/blink/renderer/platform/audio/audio_callback_metric_reporter.h" namespace blink { class AudioBus; -// For the calculation of "render capacity". The render capacity can be -// calculated by dividing |render_duration| by |callback_interval|. -struct AudioIOCallbackMetric { - // The time interval in seconds between the onset of previous callback - // function and the current one. - double callback_interval; - - // The time duration spent on rendering render quanta (i.e. batch pulling of - // audio graph) per a device callback request. - double render_duration; -}; - struct AudioIOPosition { // Audio stream position in seconds. double position; @@ -63,7 +51,7 @@ virtual void Render(AudioBus* destination_bus, uint32_t frames_to_process, const AudioIOPosition& output_position, - const AudioIOCallbackMetric& metric) = 0; + const AudioCallbackMetric& metric) = 0; virtual ~AudioIOCallback() = default; };
diff --git a/third_party/blink/renderer/platform/heap/heap_page.cc b/third_party/blink/renderer/platform/heap/heap_page.cc index 5734032..2ccddf6e 100644 --- a/third_party/blink/renderer/platform/heap/heap_page.cc +++ b/third_party/blink/renderer/platform/heap/heap_page.cc
@@ -273,15 +273,13 @@ return result; } -void BaseArena::SweepUnsweptPage() { - while (BasePage* page = unswept_pages_.Pop()) { - SetCurrentlyProccesedPage(page); - if (page->Sweep()) { - page->RemoveFromHeap(); - } else { - swept_pages_.Push(page); - page->MarkAsSwept(); - } +void BaseArena::SweepUnsweptPage(BasePage* page) { + SetCurrentlyProccesedPage(page); + if (page->Sweep()) { + page->RemoveFromHeap(); + } else { + swept_pages_.Push(page); + page->MarkAsSwept(); } SetCurrentlyProccesedPage(nullptr); } @@ -307,8 +305,8 @@ } } int page_count = 1; - while (!SweepingCompleted()) { - SweepUnsweptPage(); + while (BasePage* page = unswept_pages_.Pop()) { + SweepUnsweptPage(page); if (page_count % kDeadlineCheckInterval == 0) { if (deadline <= CurrentTimeTicks()) { // Deadline has come. @@ -332,8 +330,8 @@ // Some phases, e.g. verification, require iterability of a page. MakeIterable(); - while (!SweepingCompleted()) { - SweepUnsweptPage(); + while (BasePage* page = unswept_pages_.Pop()) { + SweepUnsweptPage(page); } }
diff --git a/third_party/blink/renderer/platform/heap/heap_page.h b/third_party/blink/renderer/platform/heap/heap_page.h index 59681b8..d78a7c3 100644 --- a/third_party/blink/renderer/platform/heap/heap_page.h +++ b/third_party/blink/renderer/platform/heap/heap_page.h
@@ -762,7 +762,7 @@ void PoisonArena(); #endif Address LazySweep(size_t, size_t gc_info_index); - void SweepUnsweptPage(); + void SweepUnsweptPage(BasePage*); // Returns true if we have swept all pages within the deadline. Returns false // otherwise. bool LazySweepWithDeadline(TimeTicks deadline);
diff --git a/third_party/blink/renderer/platform/loader/BUILD.gn b/third_party/blink/renderer/platform/loader/BUILD.gn index 29698d2..dedf6288 100644 --- a/third_party/blink/renderer/platform/loader/BUILD.gn +++ b/third_party/blink/renderer/platform/loader/BUILD.gn
@@ -34,6 +34,7 @@ "fetch/cross_origin_attribute_value.h", "fetch/data_pipe_bytes_consumer.cc", "fetch/data_pipe_bytes_consumer.h", + "fetch/detachable_use_counter.h", "fetch/fetch_client_settings_object.h", "fetch/fetch_client_settings_object_snapshot.cc", "fetch/fetch_client_settings_object_snapshot.h",
diff --git a/third_party/blink/renderer/platform/loader/allowed_by_nosniff.cc b/third_party/blink/renderer/platform/loader/allowed_by_nosniff.cc index 4a554a39..cb493b92 100644 --- a/third_party/blink/renderer/platform/loader/allowed_by_nosniff.cc +++ b/third_party/blink/renderer/platform/loader/allowed_by_nosniff.cc
@@ -4,8 +4,8 @@ #include "third_party/blink/renderer/platform/loader/allowed_by_nosniff.h" +#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/loader/fetch/console_logger.h" -#include "third_party/blink/renderer/platform/loader/fetch/fetch_context.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_response.h" #include "third_party/blink/renderer/platform/network/http_names.h" #include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h" @@ -124,7 +124,7 @@ } // namespace -bool AllowedByNosniff::MimeTypeAsScript(FetchContext& context, +bool AllowedByNosniff::MimeTypeAsScript(UseCounter& use_counter, ConsoleLogger* console_logger, const ResourceResponse& response, MimeTypeCheck mime_type_check_mode) { @@ -171,15 +171,15 @@ // These record usages for two MIME types (without subtypes), per same/cross // origin. if (mime_type.StartsWithIgnoringASCIICase("application/")) { - context.CountUsage(kApplicationFeatures[same_origin]); + use_counter.CountUse(kApplicationFeatures[same_origin]); } else if (mime_type.StartsWithIgnoringASCIICase("text/")) { - context.CountUsage(kTextFeatures[same_origin]); + use_counter.CountUse(kTextFeatures[same_origin]); } // The code above has made a decision and handed down the result in accept // and counter. if (counter != kWebFeatureNone) { - context.CountUsage(counter); + use_counter.CountUse(counter); } if (!allow) { console_logger->AddConsoleMessage(
diff --git a/third_party/blink/renderer/platform/loader/allowed_by_nosniff.h b/third_party/blink/renderer/platform/loader/allowed_by_nosniff.h index bf12ac4..34cffd5 100644 --- a/third_party/blink/renderer/platform/loader/allowed_by_nosniff.h +++ b/third_party/blink/renderer/platform/loader/allowed_by_nosniff.h
@@ -10,14 +10,14 @@ namespace blink { class ConsoleLogger; -class FetchContext; +class UseCounter; class ResourceResponse; class PLATFORM_EXPORT AllowedByNosniff final { public: enum class MimeTypeCheck { kStrict, kLax }; - static bool MimeTypeAsScript(FetchContext&, + static bool MimeTypeAsScript(UseCounter&, ConsoleLogger*, const ResourceResponse&, MimeTypeCheck mime_type_check_mode);
diff --git a/third_party/blink/renderer/platform/loader/allowed_by_nosniff_test.cc b/third_party/blink/renderer/platform/loader/allowed_by_nosniff_test.cc index a26edc1..809c1005f 100644 --- a/third_party/blink/renderer/platform/loader/allowed_by_nosniff_test.cc +++ b/third_party/blink/renderer/platform/loader/allowed_by_nosniff_test.cc
@@ -6,10 +6,10 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/loader/fetch/console_logger.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_response.h" -#include "third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h" #include "third_party/blink/renderer/platform/loader/testing/test_loader_factory.h" #include "third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.h" @@ -21,13 +21,17 @@ using WebFeature = mojom::WebFeature; using ::testing::_; -class CountUsageMockFetchContext : public MockFetchContext { +class MockUseCounter : public GarbageCollectedFinalized<MockUseCounter>, + public UseCounter { + USING_GARBAGE_COLLECTED_MIXIN(MockUseCounter); + public: - static CountUsageMockFetchContext* Create() { - return MakeGarbageCollected< - ::testing::StrictMock<CountUsageMockFetchContext>>(); + static MockUseCounter* Create() { + return MakeGarbageCollected<testing::StrictMock<MockUseCounter>>(); } - MOCK_CONST_METHOD1(CountUsage, void(mojom::WebFeature)); + + MOCK_METHOD1(CountUse, void(mojom::WebFeature)); + MOCK_METHOD1(CountDeprecation, void(mojom::WebFeature)); }; class MockConsoleLogger : public GarbageCollectedFinalized<MockConsoleLogger>, @@ -45,9 +49,6 @@ class AllowedByNosniffTest : public testing::Test { public: - static scoped_refptr<base::SingleThreadTaskRunner> CreateTaskRunner() { - return base::MakeRefCounted<scheduler::FakeTaskRunner>(); - } }; TEST_F(AllowedByNosniffTest, AllowedOrNot) { @@ -102,33 +103,27 @@ << (testcase.strict_allowed ? "true" : "false")); const KURL url("https://bla.com/"); - auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>( - SecurityOrigin::Create(url)); - auto* context = CountUsageMockFetchContext::Create(); - // Bind |properties| to |context| through a ResourceFetcher. - MakeGarbageCollected<ResourceFetcher>(ResourceFetcherInit( - properties->MakeDetachable(), context, CreateTaskRunner(), - MakeGarbageCollected<TestLoaderFactory>())); + Persistent<MockUseCounter> use_counter = MockUseCounter::Create(); Persistent<MockConsoleLogger> logger = MakeGarbageCollected<MockConsoleLogger>(); ResourceResponse response(url); response.SetHttpHeaderField("Content-Type", testcase.mimetype); - EXPECT_CALL(*context, CountUsage(_)).Times(::testing::AnyNumber()); + EXPECT_CALL(*use_counter, CountUse(_)).Times(::testing::AnyNumber()); if (!testcase.allowed) EXPECT_CALL(*logger, AddConsoleMessage(_, _, _)); EXPECT_EQ(testcase.allowed, - AllowedByNosniff::MimeTypeAsScript(*context, logger, response, + AllowedByNosniff::MimeTypeAsScript(*use_counter, logger, response, MimeTypeCheck::kLax)); - ::testing::Mock::VerifyAndClear(context); + ::testing::Mock::VerifyAndClear(use_counter); - EXPECT_CALL(*context, CountUsage(_)).Times(::testing::AnyNumber()); + EXPECT_CALL(*use_counter, CountUse(_)).Times(::testing::AnyNumber()); if (!testcase.strict_allowed) EXPECT_CALL(*logger, AddConsoleMessage(_, _, _)); EXPECT_EQ(testcase.strict_allowed, - AllowedByNosniff::MimeTypeAsScript(*context, logger, response, + AllowedByNosniff::MimeTypeAsScript(*use_counter, logger, response, MimeTypeCheck::kStrict)); - ::testing::Mock::VerifyAndClear(context); + ::testing::Mock::VerifyAndClear(use_counter); } } @@ -174,25 +169,19 @@ << testcase.origin << "\n mime type: " << testcase.mimetype << "\n response type: " << testcase.response_type << "\n webfeature: " << testcase.expected); - auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>( - SecurityOrigin::Create(KURL(testcase.origin))); - auto* context = CountUsageMockFetchContext::Create(); - // Bind |properties| to |context| through a ResourceFetcher. - MakeGarbageCollected<ResourceFetcher>(ResourceFetcherInit( - properties->MakeDetachable(), context, CreateTaskRunner(), - MakeGarbageCollected<TestLoaderFactory>())); + Persistent<MockUseCounter> use_counter = MockUseCounter::Create(); Persistent<MockConsoleLogger> logger = MakeGarbageCollected<MockConsoleLogger>(); ResourceResponse response(KURL(testcase.url)); response.SetType(testcase.response_type); response.SetHttpHeaderField("Content-Type", testcase.mimetype); - EXPECT_CALL(*context, CountUsage(testcase.expected)); - EXPECT_CALL(*context, CountUsage(::testing::Ne(testcase.expected))) + EXPECT_CALL(*use_counter, CountUse(testcase.expected)); + EXPECT_CALL(*use_counter, CountUse(::testing::Ne(testcase.expected))) .Times(::testing::AnyNumber()); - AllowedByNosniff::MimeTypeAsScript(*context, logger, response, + AllowedByNosniff::MimeTypeAsScript(*use_counter, logger, response, MimeTypeCheck::kLax); - ::testing::Mock::VerifyAndClear(context); + ::testing::Mock::VerifyAndClear(use_counter); } } @@ -222,12 +211,7 @@ }; for (auto& testcase : data) { - auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>(); - auto* context = CountUsageMockFetchContext::Create(); - // Bind |properties| to |context| through a ResourceFetcher. - MakeGarbageCollected<ResourceFetcher>(ResourceFetcherInit( - properties->MakeDetachable(), context, CreateTaskRunner(), - MakeGarbageCollected<TestLoaderFactory>())); + auto* use_counter = MockUseCounter::Create(); Persistent<MockConsoleLogger> logger = MakeGarbageCollected<MockConsoleLogger>(); EXPECT_CALL(*logger, AddConsoleMessage(_, _, _)) @@ -238,7 +222,7 @@ response.SetHttpHeaderField("Content-Type", "invalid"); response.SetHttpHeaderField("X-Content-Type-Options", "nosniff"); EXPECT_EQ(testcase.allowed, - AllowedByNosniff::MimeTypeAsScript(*context, logger, response, + AllowedByNosniff::MimeTypeAsScript(*use_counter, logger, response, MimeTypeCheck::kLax)); } }
diff --git a/third_party/blink/renderer/platform/loader/fetch/detachable_use_counter.h b/third_party/blink/renderer/platform/loader/fetch/detachable_use_counter.h new file mode 100644 index 0000000..353f792 --- /dev/null +++ b/third_party/blink/renderer/platform/loader/fetch/detachable_use_counter.h
@@ -0,0 +1,44 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_DETACHABLE_USE_COUNTER_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_DETACHABLE_USE_COUNTER_H_ + +#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" + +namespace blink { + +class DetachableUseCounter final + : public GarbageCollected<DetachableUseCounter>, + public UseCounter { + USING_GARBAGE_COLLECTED_MIXIN(DetachableUseCounter); + + public: + // |use_counter| can be null, and in that case |this| is already detached. + explicit DetachableUseCounter(UseCounter* use_counter) + : use_counter_(use_counter) {} + ~DetachableUseCounter() override = default; + + // UseCounter + void CountUse(mojom::WebFeature feature) override { + if (use_counter_) { + use_counter_->CountUse(feature); + } + } + void CountDeprecation(mojom::WebFeature feature) override { + if (use_counter_) { + use_counter_->CountDeprecation(feature); + } + } + void Trace(Visitor* visitor) override { visitor->Trace(use_counter_); } + + void Detach() { use_counter_ = nullptr; } + + private: + Member<UseCounter> use_counter_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_DETACHABLE_USE_COUNTER_H_
diff --git a/third_party/blink/renderer/platform/loader/fetch/fetch_context.cc b/third_party/blink/renderer/platform/loader/fetch/fetch_context.cc index 9bbb1a4..7324736 100644 --- a/third_party/blink/renderer/platform/loader/fetch/fetch_context.cc +++ b/third_party/blink/renderer/platform/loader/fetch/fetch_context.cc
@@ -34,22 +34,6 @@ namespace blink { -namespace { - -class NullFetchContext final : public FetchContext { - public: - NullFetchContext() = default; - - void CountUsage(mojom::WebFeature) const override {} - void CountDeprecation(mojom::WebFeature) const override {} -}; - -} // namespace - -FetchContext& FetchContext::NullInstance() { - return *MakeGarbageCollected<NullFetchContext>(); -} - void FetchContext::AddAdditionalRequestHeaders(ResourceRequest&) {} mojom::FetchCacheMode FetchContext::ResourceRequestCachePolicy(
diff --git a/third_party/blink/renderer/platform/loader/fetch/fetch_context.h b/third_party/blink/renderer/platform/loader/fetch/fetch_context.h index 01892c8..73248b2e 100644 --- a/third_party/blink/renderer/platform/loader/fetch/fetch_context.h +++ b/third_party/blink/renderer/platform/loader/fetch/fetch_context.h
@@ -38,16 +38,11 @@ #include "base/single_thread_task_runner.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-shared.h" #include "third_party/blink/public/mojom/loader/request_context_frame_type.mojom-shared.h" -#include "third_party/blink/public/mojom/web_feature/web_feature.mojom-blink.h" -#include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/resource_request_blocked_reason.h" -#include "third_party/blink/public/platform/web_url_loader.h" -#include "third_party/blink/public/platform/web_url_request.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_info.h" #include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_load_priority.h" -#include "third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_request.h" #include "third_party/blink/renderer/platform/network/content_security_policy_parsers.h" #include "third_party/blink/renderer/platform/platform_export.h" @@ -74,7 +69,9 @@ public: FetchContext() = default; - static FetchContext& NullInstance(); + static FetchContext& NullInstance() { + return *MakeGarbageCollected<FetchContext>(); + } virtual ~FetchContext() = default; @@ -128,9 +125,6 @@ return ResourceRequestBlockedReason::kOther; } - virtual void CountUsage(mojom::WebFeature) const = 0; - virtual void CountDeprecation(mojom::WebFeature) const = 0; - // Populates the ResourceRequest using the given values and information // stored in the FetchContext implementation. Used by ResourceFetcher to // prepare a ResourceRequest instance at the start of resource loading. @@ -144,8 +138,7 @@ // with "keepalive" specified). // Returns a "detached" fetch context which cannot be null. virtual FetchContext* Detach() { - auto* context = &NullInstance(); - return context; + return MakeGarbageCollected<FetchContext>(); } // Determine if the request is on behalf of an advertisement. If so, return
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc index dbb45cc..86261252 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -47,6 +47,7 @@ #include "third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h" #include "third_party/blink/renderer/platform/loader/cors/cors.h" #include "third_party/blink/renderer/platform/loader/fetch/console_logger.h" +#include "third_party/blink/renderer/platform/loader/fetch/detachable_use_counter.h" #include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h" #include "third_party/blink/renderer/platform/loader/fetch/fetch_context.h" #include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h" @@ -132,8 +133,8 @@ return ResourceLoadPriority::kHigh; case ResourceType::kManifest: case ResourceType::kMock: - // Also late-body scripts discovered by the preload scanner (set - // explicitly in loadPriority) + // Also late-body scripts and stylesheets discovered by the + // preload scanner (set explicitly in loadPriority) return ResourceLoadPriority::kMedium; case ResourceType::kImage: case ResourceType::kTextTrack: @@ -438,6 +439,18 @@ if (type == ResourceType::kImage && !is_link_preload) image_fetched_ = true; + // Check for late-in-document resources discovered by the preload scanner. + // kInDocument means it was found in the document by the preload scanner. + // image_fetched_ is used as the divider between "early" and "late" where + // anything after the first image is considered "late" in the document. + // This is used for lowering the priority of late-body scripts/stylesheets. + bool late_document_from_preload_scanner = false; + if (speculative_preload_type == + FetchParameters::SpeculativePreloadType::kInDocument && + image_fetched_) { + late_document_from_preload_scanner = true; + } + // A preloaded font should not take precedence over critical CSS or // parser-blocking scripts. if (type == ResourceType::kFont && is_link_preload) @@ -453,13 +466,17 @@ // Preload late in document: Medium if (FetchParameters::kLazyLoad == defer_option) { priority = ResourceLoadPriority::kLow; - } else if (speculative_preload_type == - FetchParameters::SpeculativePreloadType::kInDocument && - image_fetched_) { - // Speculative preload is used as a signal for scripts at the bottom of - // the document. + } else if (late_document_from_preload_scanner) { priority = ResourceLoadPriority::kMedium; } + } else if (type == ResourceType::kCSSStyleSheet && + late_document_from_preload_scanner) { + // Lower the priority of late-body stylesheets discovered by the preload + // scanner. They do not block render and this gives them the same behavior + // as late-body scripts. If the main parser reaches the stylesheet before + // it is loaded, a non-speculative fetch will be made and the priority will + // be boosted (just like with scripts). + priority = ResourceLoadPriority::kMedium; } else if (FetchParameters::kLazyLoad == defer_option) { priority = ResourceLoadPriority::kVeryLow; } else if (resource_request.GetRequestContext() == @@ -512,6 +529,9 @@ : properties_(*init.properties), context_(init.context), task_runner_(init.task_runner), + use_counter_(init.use_counter + ? init.use_counter.Get() + : MakeGarbageCollected<DetachableUseCounter>(nullptr)), console_logger_(init.console_logger ? init.console_logger.Get() : MakeGarbageCollected<DetachableConsoleLogger>()), @@ -1635,6 +1655,7 @@ } resource_load_observer_ = nullptr; + use_counter_->Detach(); console_logger_->Detach(); loader_factory_ = nullptr; @@ -1831,7 +1852,7 @@ RemovePreload(resource); if (network_utils::IsCertificateTransparencyRequiredError( error.ErrorCode())) { - Context().CountUsage( + use_counter_->CountUse( mojom::WebFeature::kCertificateTransparencyRequiredErrorOnResourceLoad); } resource->FinishAsError(error, task_runner_.get()); @@ -2095,6 +2116,7 @@ visitor->Trace(context_); visitor->Trace(properties_); visitor->Trace(resource_load_observer_); + visitor->Trace(use_counter_); visitor->Trace(console_logger_); visitor->Trace(loader_factory_); visitor->Trace(scheduler_);
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h index 42abc92..d8cec98 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
@@ -51,6 +51,7 @@ enum class ResourceType : uint8_t; class CodeCacheLoader; class DetachableConsoleLogger; +class DetachableUseCounter; class DetachableResourceFetcherProperties; class FetchContext; class FrameScheduler; @@ -170,6 +171,7 @@ FetchContext& Context() const; void ClearContext(); + DetachableUseCounter& GetUseCounter() { return *use_counter_; } DetachableConsoleLogger& GetConsoleLogger() { return *console_logger_; } int BlockingRequestCount() const; @@ -375,6 +377,7 @@ Member<ResourceLoadObserver> resource_load_observer_; Member<FetchContext> context_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + const Member<DetachableUseCounter> use_counter_; const Member<DetachableConsoleLogger> console_logger_; Member<LoaderFactory> loader_factory_; const Member<ResourceLoadScheduler> scheduler_; @@ -462,6 +465,7 @@ const Member<FetchContext> context; const scoped_refptr<base::SingleThreadTaskRunner> task_runner; const Member<ResourceFetcher::LoaderFactory> loader_factory; + Member<DetachableUseCounter> use_counter; Member<DetachableConsoleLogger> console_logger; ResourceLoadScheduler::ThrottlingPolicy initial_throttling_policy = ResourceLoadScheduler::ThrottlingPolicy::kNormal;
diff --git a/third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h b/third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h index bcef719..7f63406 100644 --- a/third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h +++ b/third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h
@@ -31,9 +31,6 @@ uint64_t GetTransferSize() const { return transfer_size_; } - void CountUsage(mojom::WebFeature) const override {} - void CountDeprecation(mojom::WebFeature) const override {} - bool AllowImage(bool images_enabled, const KURL&) const override { return true; }
diff --git a/third_party/blink/renderer/platform/scheduler/OWNERS b/third_party/blink/renderer/platform/scheduler/OWNERS index 8423b49..00ad1396 100644 --- a/third_party/blink/renderer/platform/scheduler/OWNERS +++ b/third_party/blink/renderer/platform/scheduler/OWNERS
@@ -1,5 +1,6 @@ altimin@chromium.org alexclarke@chromium.org +carlscab@google.com rmcilroy@chromium.org skyostil@chromium.org
diff --git a/third_party/blink/web_tests/ASANExpectations b/third_party/blink/web_tests/ASANExpectations index 7973887..9762aef 100644 --- a/third_party/blink/web_tests/ASANExpectations +++ b/third_party/blink/web_tests/ASANExpectations
@@ -67,16 +67,16 @@ crbug.com/803276 inspector-protocol/memory/sampling-native-snapshot.js [ Skip ] # CORS test crash on ASAN -crbug.com/838057 [ Linux ] virtual/blink-cors/external/wpt/fetch/api/cors/cors-cookies-redirect.any.html [ Crash ] -crbug.com/838057 [ Linux ] virtual/blink-cors/external/wpt/fetch/api/cors/cors-cookies-redirect.any.worker.html [ Crash ] -crbug.com/838057 [ Linux ] virtual/blink-cors/external/wpt/fetch/api/cors/cors-preflight-star.any.html [ Crash ] -crbug.com/838057 [ Linux ] virtual/blink-cors/external/wpt/fetch/api/cors/cors-preflight-star.any.worker.html [ Crash ] -crbug.com/838057 [ Linux ] virtual/blink-cors/external/wpt/fetch/api/cors/cors-preflight.any.html [ Crash ] -crbug.com/838057 [ Linux ] virtual/blink-cors/external/wpt/fetch/api/cors/cors-preflight.any.worker.html [ Crash ] -crbug.com/838057 [ Linux ] virtual/blink-cors/external/wpt/fetch/api/cors/cors-redirect-preflight.any.html [ Crash ] -crbug.com/838057 [ Linux ] virtual/blink-cors/external/wpt/fetch/api/cors/cors-redirect-preflight.any.worker.html [ Crash ] -crbug.com/838057 [ Linux ] virtual/blink-cors/external/wpt/service-workers/service-worker/fetch-canvas-tainting-video-cache.https.html [ Crash ] -crbug.com/838057 [ Linux ] virtual/blink-cors/external/wpt/service-workers/service-worker/fetch-canvas-tainting-video.https.html [ Crash ] +crbug.com/838057 [ Linux ] virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-cookies-redirect.any.html [ Crash ] +crbug.com/838057 [ Linux ] virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-cookies-redirect.any.worker.html [ Crash ] +crbug.com/838057 [ Linux ] virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-preflight-star.any.html [ Crash ] +crbug.com/838057 [ Linux ] virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-preflight-star.any.worker.html [ Crash ] +crbug.com/838057 [ Linux ] virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-preflight.any.html [ Crash ] +crbug.com/838057 [ Linux ] virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-preflight.any.worker.html [ Crash ] +crbug.com/838057 [ Linux ] virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-redirect-preflight.any.html [ Crash ] +crbug.com/838057 [ Linux ] virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-redirect-preflight.any.worker.html [ Crash ] +crbug.com/838057 [ Linux ] virtual/outofblink-cors/external/wpt/service-workers/service-worker/fetch-canvas-tainting-video-cache.https.html [ Crash ] +crbug.com/838057 [ Linux ] virtual/outofblink-cors/external/wpt/service-workers/service-worker/fetch-canvas-tainting-video.https.html [ Crash ] # Disabled by sheriff due to test crash crbug.com/896068 [ Linux ] webaudio/AudioBuffer/huge-buffer.html [ Crash ]
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-unsafe-webgpu b/third_party/blink/web_tests/FlagExpectations/enable-unsafe-webgpu index 55a55dd0..791bf45 100644 --- a/third_party/blink/web_tests/FlagExpectations/enable-unsafe-webgpu +++ b/third_party/blink/web_tests/FlagExpectations/enable-unsafe-webgpu
@@ -1,3 +1,4 @@ # WebGPU tests are only run with --enable-unsafe-webgpu Bug(none) webgpu/canvas_context.html [ Pass ] +Bug(none) webgpu/buffer_mapping.html [ Pass ] Bug(none) webgpu/fence.html [ Pass ]
diff --git a/third_party/blink/web_tests/MSANExpectations b/third_party/blink/web_tests/MSANExpectations index 36271445..8618df11 100644 --- a/third_party/blink/web_tests/MSANExpectations +++ b/third_party/blink/web_tests/MSANExpectations
@@ -158,25 +158,25 @@ crbug.com/856601 [ Linux ] external/wpt/webstorage/idlharness.window.html [ Pass Timeout ] crbug.com/856601 [ Linux ] virtual/feature-policy-permissions/external/wpt/mediacapture-streams/MediaDevices-IDL-enumerateDevices.html [ Pass Timeout ] crbug.com/856601 [ Linux ] virtual/feature-policy-permissions/external/wpt/mediacapture-streams/idlharness.https.window.html [ Pass Timeout ] -crbug.com/856601 [ Linux ] virtual/blink-cors/external/wpt/fetch/cors-rfc1918/idlharness.tentative.https.any.serviceworker.html [ Pass Timeout ] +crbug.com/856601 [ Linux ] virtual/outofblink-cors/external/wpt/fetch/cors-rfc1918/idlharness.tentative.https.any.serviceworker.html [ Pass Timeout ] crbug.com/856601 [ Linux ] virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/interfaces-sw.https.html [ Timeout Pass ] -crbug.com/856601 [ Linux ] virtual/blink-cors/external/wpt/service-workers/service-worker/interfaces-sw.https.html [ Timeout Pass ] +crbug.com/856601 [ Linux ] virtual/outofblink-cors/external/wpt/service-workers/service-worker/interfaces-sw.https.html [ Timeout Pass ] crbug.com/856601 [ Linux ] virtual/service-worker-servicification/external/wpt/service-workers/service-worker/interfaces-sw.https.html [ Timeout Pass ] crbug.com/856601 [ Linux ] external/wpt/fetch/api/idl.any.sharedworker.html [ Pass Timeout ] crbug.com/856601 [ Linux ] external/wpt/fetch/cors-rfc1918/idlharness.tentative.https.any.serviceworker.html [ Pass Timeout ] crbug.com/856601 [ Linux ] external/wpt/media-capabilities/idlharness.any.html [ Pass Timeout ] crbug.com/856601 [ Linux ] external/wpt/orientation-event/idlharness.window.html [ Pass Timeout ] crbug.com/856601 [ Linux ] external/wpt/pointerlock/interfaces.window.html [ Pass Timeout ] -crbug.com/856601 [ Linux ] virtual/blink-cors/external/wpt/xhr/idlharness.any.sharedworker.html [ Pass Timeout ] +crbug.com/856601 [ Linux ] virtual/outofblink-cors/external/wpt/xhr/idlharness.any.sharedworker.html [ Pass Timeout ] crbug.com/856601 [ Linux ] external/wpt/bluetooth/idl/idlharness.tentative.https.window.html [ Timeout Pass ] crbug.com/856601 [ Linux ] external/wpt/css/css-pseudo/idlharness.html [ Timeout Pass ] crbug.com/856601 [ Linux ] external/wpt/hr-time/idlharness.any.worker.html [ Timeout Pass ] crbug.com/856601 [ Linux ] external/wpt/media-source/idlharness.any.html [ Timeout Pass ] crbug.com/856601 [ Linux ] external/wpt/page-visibility/idlharness.window.html [ Timeout Pass ] crbug.com/856601 [ Linux ] virtual/new-remote-playback-pipeline/external/wpt/remote-playback/idlharness.window.html [ Timeout Pass ] -crbug.com/856601 [ Linux ] virtual/blink-cors/external/wpt/fetch/api/idl.any.html [ Timeout Pass ] -crbug.com/856601 [ Linux ] virtual/blink-cors/external/wpt/fetch/cors-rfc1918/idlharness.tentative.any.html [ Timeout Pass ] -crbug.com/856601 [ Linux ] virtual/blink-cors/external/wpt/xhr/idlharness.any.html [ Timeout Pass ] +crbug.com/856601 [ Linux ] virtual/outofblink-cors/external/wpt/fetch/api/idl.any.html [ Timeout Pass ] +crbug.com/856601 [ Linux ] virtual/outofblink-cors/external/wpt/fetch/cors-rfc1918/idlharness.tentative.any.html [ Timeout Pass ] +crbug.com/856601 [ Linux ] virtual/outofblink-cors/external/wpt/xhr/idlharness.any.html [ Timeout Pass ] crbug.com/856601 [ Linux ] virtual/service-worker-servicification/external/wpt/service-workers/service-worker/interfaces-window.https.html [ Timeout Pass ] crbug.com/856601 [ Linux ] virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/idlharness.https.window.html [ Timeout Pass ] crbug.com/856601 [ Linux ] external/wpt/css/filter-effects/interfaces.any.html [ Timeout Pass ] @@ -213,7 +213,7 @@ crbug.com/914900 [ Linux ] external/wpt/fetch/api/idl.any.worker.html [ Pass Timeout ] crbug.com/914900 [ Linux ] external/wpt/secure-contexts/idlharness.any.worker.html [ Pass Timeout ] crbug.com/914900 [ Linux ] http/tests/devtools/network/preview-searchable.js [ Pass Timeout ] -crbug.com/914900 [ Linux ] virtual/blink-cors/external/wpt/xhr/idlharness.any.worker.html [ Pass Timeout ] +crbug.com/914900 [ Linux ] virtual/outofblink-cors/external/wpt/xhr/idlharness.any.worker.html [ Pass Timeout ] # Sheriff 2019-01-28 crbug.com/925600 [ Linux ] external/wpt/webrtc-quic/RTCQuicStream.https.html [ Pass Timeout ] @@ -244,4 +244,4 @@ # Sheriff 2019-05-21 crbug.com/856601 [ Linux ] external/wpt/notifications/idlharness.https.window.html [ Pass Timeout ] crbug.com/856601 [ Linux ] external/wpt/fetch/cors-rfc1918/idlharness.tentative.any.serviceworker.html [ Pass Timeout ] -crbug.com/856601 [ Linux ] external/wpt/notifications/idlharness.https.any.sharedworker.html [ Pass Timeout ] +crbug.com/856601 [ Linux ] external/wpt/notifications/idlharness.https.any.sharedworker.html [ Pass Timeout ] \ No newline at end of file
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests index 10c83ef..a7cee3ca 100644 --- a/third_party/blink/web_tests/NeverFixTests +++ b/third_party/blink/web_tests/NeverFixTests
@@ -2162,11 +2162,6 @@ external/wpt/webstorage/storage_session-manual.html [ WontFix ] external/wpt/xhr/send-authentication-existing-session-manual.htm [ WontFix ] external/wpt/xhr/send-authentication-prompt-2-manual.htm [ WontFix ] -virtual/blink-cors/external/wpt/service-workers/service-worker/fetch-event-is-history-backward-navigation-manual.https.html [ WontFix ] -virtual/blink-cors/external/wpt/service-workers/service-worker/fetch-event-is-history-forward-navigation-manual.https.html [ WontFix ] -virtual/blink-cors/external/wpt/service-workers/service-worker/fetch-event-is-reload-navigation-manual.https.html [ WontFix ] -virtual/blink-cors/external/wpt/xhr/send-authentication-existing-session-manual.htm [ WontFix ] -virtual/blink-cors/external/wpt/xhr/send-authentication-prompt-2-manual.htm [ WontFix ] virtual/feature-policy-permissions/external/wpt/mediacapture-streams/MediaStream-MediaElement-preload-none-manual.https.html [ WontFix ] virtual/feature-policy-permissions/external/wpt/mediacapture-streams/MediaStreamTrack-end-manual.https.html [ WontFix ] virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/fetch-event-is-history-backward-navigation-manual.https.html [ WontFix ] @@ -2236,7 +2231,6 @@ # https://foo.example.com/path?token=secret needs to be replaced with just # https://foo.example.com). crbug.com/669083 http/tests/security/frameNavigation/xss-DENIED-top-navigation-without-user-gesture.html [ WontFix ] -crbug.com/669083 virtual/blink-cors/http/tests/security/frameNavigation/xss-DENIED-top-navigation-without-user-gesture.html [ WontFix ] # --------------------------- code cache isolation ----------------------- # Code cache isolation tests only make sense if either # 1) site isolation is disabled or
diff --git a/third_party/blink/web_tests/SlowTests b/third_party/blink/web_tests/SlowTests index b6f6746..47f8e8d 100644 --- a/third_party/blink/web_tests/SlowTests +++ b/third_party/blink/web_tests/SlowTests
@@ -151,7 +151,6 @@ crbug.com/522646 http/tests/media/encrypted-media/encrypted-media-encrypted-event-different-origin.html [ Slow ] crbug.com/411164 [ Win ] http/tests/security/powerfulFeatureRestrictions/serviceworker-on-insecure-origin.html [ Slow ] -crbug.com/411164 [ Win ] virtual/blink-cors/http/tests/security/powerfulFeatureRestrictions/serviceworker-on-insecure-origin.html [ Slow ] crbug.com/510337 http/tests/devtools/console/console-format.js [ Slow ] crbug.com/357427 http/tests/workers/terminate-during-sync-operation-file.html [ Slow ] crbug.com/357427 http/tests/workers/terminate-during-sync-operation-filesystem.html [ Slow ] @@ -173,7 +172,6 @@ crbug.com/372424 http/tests/serviceworker/registration-stress.html [ Slow ] crbug.com/448670 http/tests/serviceworker/register-different-script-many-times.html [ Slow ] crbug.com/516319 [ Win ] http/tests/fetch/ [ Slow ] -crbug.com/516319 [ Win ] virtual/blink-cors/http/tests/fetch/ [ Slow ] crbug.com/516319 [ Win ] virtual/streaming-preload/http/tests/fetch/ [ Slow ] # Most crypto/subtle tests are slow some or most of the time. @@ -258,8 +256,6 @@ # These tests take 90 seconds on MSAN due to a large amount of JS execution. crbug.com/853977 [ Linux ] http/tests/fetch/chromium/call-extra-crash-tee.html [ Slow ] crbug.com/853977 [ Linux ] http/tests/fetch/chromium/release-handle-crash.html [ Slow ] -crbug.com/853977 [ Linux ] virtual/blink-cors/http/tests/fetch/chromium/call-extra-crash-tee.html [ Slow ] -crbug.com/853977 [ Linux ] virtual/blink-cors/http/tests/fetch/chromium/release-handle-crash.html [ Slow ] crbug.com/853977 [ Linux ] virtual/streaming-preload/http/tests/fetch/chromium/call-extra-crash-tee.html [ Slow ] crbug.com/853977 [ Linux ] virtual/streaming-preload/http/tests/fetch/chromium/release-handle-crash.html [ Slow ] crbug.com/853977 [ Linux ] virtual/streams-native/http/tests/fetch/chromium/call-extra-crash-tee.html [ Slow ] @@ -634,34 +630,3 @@ crbug.com/962831 [ Release ] http/tests/devtools/network/preview-searchable.js [ Slow ] crbug.com/967526 http/tests/devtools/console/console-uncaught-promise.js [ Slow ] - -crbug.com/874695 virtual/blink-cors/http/tests/fetch/serviceworker/body-mixin-base-https-other-https.html [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/fetch/serviceworker/body-mixin.html [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/fetch/serviceworker/stream-reader-base-https-other-https.html [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/fetch/serviceworker/stream-reader.html [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/fetch/serviceworker/thorough/ [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/fetch/serviceworker-proxied/thorough/ [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/fetch/window/body-mixin-base-https-other-https.html [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/fetch/window/body-mixin.html [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/fetch/window/stream-reader-base-https-other-https.html [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/fetch/window/stream-reader.html [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/fetch/window/thorough/ [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/fetch/workers/body-mixin-base-https-other-https.html [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/fetch/workers/body-mixin.html [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/fetch/workers/stream-reader-base-https-other-https.html [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/fetch/workers/stream-reader.html [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/fetch/workers/thorough/ [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/navigation/navigation-interrupted-by-fragment.html [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/navigation/new-window-redirect-history.html [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/navigation/slowmetaredirect-basic.html [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/navigation/slowtimerredirect-basic.html [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/security/contentSecurityPolicy/redirect-with-delay.html [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/security/cross-frame-mouse-source-capabilities.html [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/security/frameNavigation/xss-ALLOWED-same-origin-top-navigation-without-user-gesture.html [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/security/video-poster-cross-origin-crash2.html [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/xmlhttprequest/timeout/xmlhttprequest-timeout-aborted.html [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/xmlhttprequest/timeout/xmlhttprequest-timeout-overridesexpires.html [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/xmlhttprequest/timeout/xmlhttprequest-timeout-simple.html [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/xmlhttprequest/timeout/xmlhttprequest-timeout-twice.html [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/xmlhttprequest/timeout/xmlhttprequest-timeout-worker-overridesexpires.html [ Slow ] -crbug.com/874695 virtual/blink-cors/http/tests/xmlhttprequest/timeout/xmlhttprequest-timeout-worker-twice.html [ Slow ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 3dd4c25..799a583 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -13,6 +13,7 @@ # WebGPU tests are only run with --enable-unsafe-webgpu Bug(none) webgpu/canvas_context.html [ Skip ] +Bug(none) webgpu/buffer_mapping.html [ Skip ] Bug(none) webgpu/fence.html [ Skip ] crbug.com/807686 crbug.com/24182 jquery/manipulation.html [ Timeout Pass ] @@ -63,7 +64,6 @@ crbug.com/645641 external/wpt/html/syntax/parsing/html5lib_tests19.html [ Crash Failure ] crbug.com/665058 http/tests/local/drag-over-remote-content.html [ Crash ] crbug.com/771003 http/tests/security/mixedContent/insecure-iframe-in-main-frame.html [ Failure ] -crbug.com/771003 virtual/blink-cors/http/tests/security/mixedContent/insecure-iframe-in-main-frame.html [ Failure ] # Tests temporarily disabled with Site Isolation - known differences in product # behavior (either accepted for the long-term, or for the short-term): @@ -1745,10 +1745,8 @@ crbug.com/410974 virtual/threaded/fast/scroll-behavior/scroll-customization/touch-scroll-customization.html [ Pass Failure ] crbug.com/390452 http/tests/security/isolatedWorld/media-query-wrapper-leaks.html [ Failure Pass Timeout ] -crbug.com/390452 virtual/blink-cors/http/tests/security/isolatedWorld/media-query-wrapper-leaks.html [ Failure Pass Timeout ] crbug.com/390452 virtual/isolated_world_csp/http/tests/security/isolatedWorld/media-query-wrapper-leaks.html [ Failure Pass Timeout ] crbug.com/518987 http/tests/xmlhttprequest/navigation-abort-detaches-frame.html [ Pass Timeout ] -crbug.com/518987 virtual/blink-cors/http/tests/xmlhttprequest/navigation-abort-detaches-frame.html [ Pass Timeout ] # These performance-sensitive user-timing tests are flaky in debug on all platforms, and flaky on all configurations of windows. # See: crbug.com/567965, crbug.com/518992, and crbug.com/518993 @@ -2173,10 +2171,6 @@ crbug.com/528062 [ Win ] http/tests/security/contentSecurityPolicy/cached-frame-csp.html [ Failure ] crbug.com/528062 [ Win ] http/tests/security/xssAuditor/cached-frame.html [ Failure ] crbug.com/528062 [ Win ] http/tests/security/xssAuditor/chunked-big-script.html [ Failure ] -crbug.com/528062 [ Win ] virtual/blink-cors/http/tests/security/XFrameOptions/x-frame-options-cached.html [ Failure ] -crbug.com/528062 [ Win ] virtual/blink-cors/http/tests/security/contentSecurityPolicy/cached-frame-csp.html [ Failure ] -crbug.com/528062 [ Win ] virtual/blink-cors/http/tests/security/xssAuditor/cached-frame.html [ Failure ] -crbug.com/528062 [ Win ] virtual/blink-cors/http/tests/security/xssAuditor/chunked-big-script.html [ Failure ] # When drawing subpixel smoothed glyphs, CoreGraphics will fake bold the glyphs. # In this configuration, the pixel smoothed glyphs will be created from subpixel smoothed glyphs. @@ -2443,7 +2437,6 @@ crbug.com/501659 fast/xsl/xslt-missing-namespace-in-xslt.xml [ Failure ] crbug.com/501659 http/tests/security/xss-DENIED-xml-external-entity.xhtml [ Failure ] -crbug.com/501659 virtual/blink-cors/http/tests/security/xss-DENIED-xml-external-entity.xhtml [ Failure ] crbug.com/501659 fast/css/stylesheet-candidate-nodes-crash.xhtml [ Failure ] crbug.com/591500 [ Win10 ] printing/webgl-repeated-printing.html [ Failure ] @@ -2552,7 +2545,6 @@ # Skip the non-virtualized CORS-RFC1918 tests: crbug.com/763830 http/tests/security/cors-rfc1918/ [ Skip ] -crbug.com/763830 virtual/blink-cors/http/tests/security/cors-rfc1918/ [ Skip ] crbug.com/831729 external/wpt/event-timing/crossiframe.html [ Timeout ] crbug.com/831729 external/wpt/event-timing/observer-manual.html [ Skip ] @@ -2594,7 +2586,6 @@ # Remove from virtual tests when FreezeUserAgent is turned on by default. crbug.com/955620 http/tests/navigation/frozen-useragent.html [ Skip ] -crbug.com/955620 virtual/blink-cors/http/tests/navigation/frozen-useragent.html [ Skip ] crbug.com/955620 virtual/stable/http/tests/navigation/frozen-useragent.html [ Skip ] crbug.com/863896 http/tests/permissions/test-query.html [ Timeout ] @@ -2668,7 +2659,6 @@ # Failure messages are unstable so we cannot create baselines. crbug.com/832071 external/wpt/service-workers/service-worker/worker-client-id.https.html [ Failure ] -crbug.com/832071 virtual/blink-cors/external/wpt/service-workers/service-worker/worker-client-id.https.html [ Failure ] crbug.com/832071 virtual/navigation-mojo-response/external/wpt/service-workers/service-worker/worker-client-id.https.html [ Failure ] crbug.com/832071 virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/worker-client-id.https.html [ Timeout ] @@ -2804,6 +2794,9 @@ crbug.com/965409 external/wpt/css/css-font-loading/fontface-descriptor-updates.html [ Failure ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 [ Linux ] external/wpt/infrastructure/testdriver/actions/actionsWithKeyPressed.html [ Timeout ] +crbug.com/626703 [ Mac ] external/wpt/infrastructure/testdriver/actions/actionsWithKeyPressed.html [ Timeout ] +crbug.com/626703 [ Win ] external/wpt/infrastructure/testdriver/actions/actionsWithKeyPressed.html [ Timeout ] crbug.com/626703 [ Linux ] external/wpt/css/css-backgrounds/border-radius-dynamic-from-no-radius.html [ Failure ] crbug.com/626703 [ Mac ] external/wpt/css/css-backgrounds/border-radius-dynamic-from-no-radius.html [ Failure ] crbug.com/626703 [ Win ] external/wpt/css/css-backgrounds/border-radius-dynamic-from-no-radius.html [ Failure ] @@ -2861,9 +2854,8 @@ crbug.com/626703 external/wpt/infrastructure/reftest/reftest_fuzzy_ini_ref_only.html [ Failure ] crbug.com/626703 [ Mac ] external/wpt/html/rendering/widgets/button-layout/propagate-text-decoration.html [ Failure ] crbug.com/626703 external/wpt/infrastructure/reftest/reftest_fuzzy_ini_short.html [ Failure ] -crbug.com/626703 external/wpt/xhr/abort-after-stop.any.worker.html [ Timeout ] -crbug.com/626703 virtual/blink-cors/external/wpt/xhr/abort-after-stop.any.worker.html [ Timeout ] crbug.com/626703 virtual/omt-worker-fetch/external/wpt/xhr/abort-after-stop.any.worker.html [ Timeout ] +crbug.com/626703 external/wpt/xhr/abort-after-stop.any.worker.html [ Timeout ] crbug.com/626703 external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/vertical_rl.html [ Failure ] crbug.com/626703 external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/vertical_ruby-position.html [ Failure ] crbug.com/626703 external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_vertical_text-combine-upright.html [ Failure ] @@ -2933,8 +2925,6 @@ crbug.com/626703 external/wpt/css/css-scroll-snap/scroll-target-margin-003.html [ Failure ] crbug.com/626703 external/wpt/css/css-sizing/image-min-max-content-intrinsic-size-change-001.html [ Failure ] crbug.com/626703 external/wpt/xhr/event-readystatechange-loaded.any.worker.html [ Timeout Failure ] -crbug.com/626703 virtual/blink-cors/external/wpt/xhr/event-readystatechange-loaded.any.worker.html [ Timeout Failure ] -crbug.com/626703 virtual/omt-worker-fetch/external/wpt/xhr/event-readystatechange-loaded.any.worker.html [ Timeout Failure ] crbug.com/626703 external/wpt/css/css-sizing/image-min-max-content-intrinsic-size-change-003.html [ Failure ] crbug.com/626703 external/wpt/css/css-text/line-breaking/line-breaking-017.html [ Failure ] crbug.com/626703 external/wpt/css/css-scroll-snap/scroll-target-padding-003.html [ Failure ] @@ -2943,6 +2933,7 @@ crbug.com/626703 external/wpt/css/css-lists/li-list-item-counter.html [ Failure ] crbug.com/626703 virtual/threaded/external/wpt/css/css-scroll-snap/scroll-target-snap-001.html [ Failure ] crbug.com/626703 external/wpt/css/css-sizing/image-min-max-content-intrinsic-size-change-006.html [ Failure ] +crbug.com/626703 virtual/omt-worker-fetch/external/wpt/xhr/event-readystatechange-loaded.any.html [ Timeout Failure ] crbug.com/626703 virtual/threaded/external/wpt/css/css-scroll-snap/scroll-target-margin-003.html [ Failure ] crbug.com/626703 external/wpt/css/css-scroll-snap/scroll-target-align-003.html [ Failure ] crbug.com/626703 virtual/threaded/external/wpt/css/css-scroll-snap/scroll-target-align-002.html [ Failure ] @@ -2956,8 +2947,6 @@ crbug.com/626703 external/wpt/css/css-text/text-transform/text-transform-multiple-001.html [ Failure ] crbug.com/626703 external/wpt/css/css-lists/li-value-counter-reset-001.html [ Failure ] crbug.com/626703 external/wpt/xhr/event-readystatechange-loaded.any.html [ Timeout Failure ] -crbug.com/626703 virtual/blink-cors/external/wpt/xhr/event-readystatechange-loaded.any.html [ Timeout Failure ] -crbug.com/626703 virtual/omt-worker-fetch/external/wpt/xhr/event-readystatechange-loaded.any.html [ Timeout Failure ] crbug.com/626703 virtual/threaded/external/wpt/css/css-scroll-snap/scroll-target-margin-002.html [ Failure ] crbug.com/626703 virtual/threaded/external/wpt/css/css-scroll-snap/scroll-target-padding-002.html [ Failure ] crbug.com/626703 virtual/threaded/external/wpt/css/css-scroll-snap/scroll-target-snap-003.html [ Failure ] @@ -2967,6 +2956,7 @@ crbug.com/626703 external/wpt/css/css-scroll-snap/scroll-target-padding-001.html [ Failure ] crbug.com/626703 virtual/threaded/external/wpt/css/css-scroll-snap/scroll-target-padding-001.html [ Failure ] crbug.com/626703 external/wpt/css/css-scroll-snap/scroll-target-snap-003.html [ Failure ] +crbug.com/626703 virtual/omt-worker-fetch/external/wpt/xhr/event-readystatechange-loaded.any.worker.html [ Timeout Failure ] crbug.com/626703 external/wpt/css/css-scroll-snap/scroll-target-snap-001.html [ Failure ] crbug.com/626703 external/wpt/css/css-scroll-snap/scroll-target-margin-002.html [ Failure ] crbug.com/626703 external/wpt/css/css-sizing/image-min-max-content-intrinsic-size-change-005.html [ Failure ] @@ -3108,12 +3098,11 @@ crbug.com/626703 external/wpt/svg/painting/marker-006.svg [ Failure ] crbug.com/626703 external/wpt/svg/painting/marker-005.svg [ Failure ] crbug.com/906369 external/wpt/css/css-text/text-transform/text-transform-capitalize-033.html [ Failure ] +crbug.com/626703 virtual/streams-native/external/wpt/fetch/content-type/response.window.html [ Timeout ] crbug.com/626703 [ Mac10.10 ] external/wpt/mimesniff/mime-types/parsing.any.worker.html [ Failure Timeout ] crbug.com/626703 [ Mac10.11 ] external/wpt/mimesniff/mime-types/parsing.any.worker.html [ Failure Timeout ] crbug.com/626703 [ Win ] external/wpt/html/semantics/embedded-content/media-elements/ready-states/autoplay-hidden.optional.html [ Failure Timeout ] crbug.com/626703 external/wpt/fetch/content-type/response.window.html [ Timeout ] -crbug.com/626703 virtual/blink-cors/external/wpt/fetch/content-type/response.window.html [ Timeout ] -crbug.com/626703 virtual/streams-native/external/wpt/fetch/content-type/response.window.html [ Timeout ] crbug.com/626703 virtual/streaming-preload/external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/no-active-script-manual-module.html [ Timeout ] crbug.com/626703 virtual/streaming-preload/external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/no-active-script-manual-classic.html [ Timeout ] crbug.com/626703 external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/no-active-script-manual-classic.html [ Timeout ] @@ -3190,11 +3179,6 @@ crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/internal-stylesheet.html [ Timeout Failure ] crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/presentation-attribute.html [ Timeout Failure ] crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/processing-instruction.html [ Timeout Failure ] -crbug.com/626703 virtual/blink-cors/external/wpt/referrer-policy/css-integration/svg/external-stylesheet.html [ Timeout Failure ] -crbug.com/626703 virtual/blink-cors/external/wpt/referrer-policy/css-integration/svg/inline-style.html [ Timeout Failure ] -crbug.com/626703 virtual/blink-cors/external/wpt/referrer-policy/css-integration/svg/internal-stylesheet.html [ Timeout Failure ] -crbug.com/626703 virtual/blink-cors/external/wpt/referrer-policy/css-integration/svg/presentation-attribute.html [ Timeout Failure ] -crbug.com/626703 virtual/blink-cors/external/wpt/referrer-policy/css-integration/svg/processing-instruction.html [ Timeout Failure ] crbug.com/626703 virtual/omt-worker-fetch/external/wpt/referrer-policy/css-integration/svg/external-stylesheet.html [ Timeout Failure ] crbug.com/626703 virtual/omt-worker-fetch/external/wpt/referrer-policy/css-integration/svg/inline-style.html [ Timeout Failure ] crbug.com/626703 virtual/omt-worker-fetch/external/wpt/referrer-policy/css-integration/svg/internal-stylesheet.html [ Timeout Failure ] @@ -3237,42 +3221,6 @@ crbug.com/906959 external/wpt/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/shared-worker/no-redirect/insecure-protocol.http.html [ Failure ] crbug.com/906959 external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/shared-worker/keep-origin-redirect/insecure-protocol.http.html [ Failure ] crbug.com/906959 external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/shared-worker/no-redirect/insecure-protocol.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/no-referrer/http-rp/same-origin/http-http/shared-worker/keep-origin-redirect/generic.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/no-referrer/http-rp/same-origin/http-http/shared-worker/no-redirect/generic.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/no-referrer/meta-referrer/same-origin/http-http/shared-worker/keep-origin-redirect/generic.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/no-referrer/meta-referrer/same-origin/http-http/shared-worker/no-redirect/generic.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/shared-worker/keep-origin-redirect/insecure-protocol.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/shared-worker/no-redirect/insecure-protocol.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/shared-worker/keep-origin-redirect/insecure-protocol.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/shared-worker/no-redirect/insecure-protocol.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/origin/http-rp/same-origin/http-http/shared-worker/keep-origin-redirect/generic.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/origin/http-rp/same-origin/http-http/shared-worker/no-redirect/generic.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/origin/meta-referrer/same-origin/http-http/shared-worker/keep-origin-redirect/generic.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/origin/meta-referrer/same-origin/http-http/shared-worker/no-redirect/generic.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/shared-worker/keep-origin-redirect/same-origin-insecure.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/shared-worker/no-redirect/same-origin-insecure.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/shared-worker/keep-origin-redirect/same-origin-insecure.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/shared-worker/no-redirect/same-origin-insecure.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/same-origin/http-rp/same-origin/http-http/shared-worker/keep-origin-redirect/same-origin-insecure.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/same-origin/http-rp/same-origin/http-http/shared-worker/no-redirect/same-origin-insecure.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/same-origin/meta-referrer/same-origin/http-http/shared-worker/keep-origin-redirect/same-origin-insecure.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/same-origin/meta-referrer/same-origin/http-http/shared-worker/no-redirect/same-origin-insecure.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/strict-origin/http-rp/same-origin/http-http/shared-worker/keep-origin-redirect/insecure-protocol.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/strict-origin/http-rp/same-origin/http-http/shared-worker/no-redirect/insecure-protocol.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/strict-origin/meta-referrer/same-origin/http-http/shared-worker/keep-origin-redirect/insecure-protocol.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/strict-origin/meta-referrer/same-origin/http-http/shared-worker/no-redirect/insecure-protocol.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/shared-worker/keep-origin-redirect/same-insecure.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/shared-worker/no-redirect/same-insecure.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-http/shared-worker/keep-origin-redirect/same-insecure.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-http/shared-worker/no-redirect/same-insecure.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/unsafe-url/http-rp/same-origin/http-http/shared-worker/keep-origin-redirect/generic.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/unsafe-url/http-rp/same-origin/http-http/shared-worker/no-redirect/generic.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/shared-worker/keep-origin-redirect/generic.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/shared-worker/no-redirect/generic.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/shared-worker/keep-origin-redirect/insecure-protocol.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/shared-worker/no-redirect/insecure-protocol.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/shared-worker/keep-origin-redirect/insecure-protocol.http.html [ Failure ] -crbug.com/906959 virtual/blink-cors/external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/shared-worker/no-redirect/insecure-protocol.http.html [ Failure ] crbug.com/906959 virtual/omt-worker-fetch/external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/shared-worker/keep-origin-redirect/insecure-protocol.http.html [ Failure ] crbug.com/906959 virtual/omt-worker-fetch/external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/shared-worker/no-redirect/insecure-protocol.http.html [ Failure ] crbug.com/906959 virtual/omt-worker-fetch/external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/shared-worker/keep-origin-redirect/insecure-protocol.http.html [ Failure ] @@ -3434,7 +3382,6 @@ crbug.com/626703 external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/navigation.sub.html?encoding=utf8 [ Timeout ] crbug.com/626703 external/wpt/css/css-transforms/transform-box/view-box-mutation.html [ Failure ] crbug.com/626703 external/wpt/fetch/security/redirect-to-url-with-credentials.https.html [ Timeout ] -crbug.com/626703 virtual/blink-cors/external/wpt/fetch/security/redirect-to-url-with-credentials.https.html [ Timeout ] crbug.com/626703 virtual/streams-native/external/wpt/fetch/security/redirect-to-url-with-credentials.https.html [ Timeout ] crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/shape-outside-polygon-024.html [ Failure ] crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/shape-outside-ellipse-048.html [ Failure ] @@ -3522,7 +3469,6 @@ crbug.com/626703 external/wpt/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-010.html [ Failure ] crbug.com/626703 external/wpt/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-009.html [ Failure ] crbug.com/626703 external/wpt/fetch/http-cache/basic-auth-cache-test.html [ Timeout ] -crbug.com/626703 virtual/blink-cors/external/wpt/fetch/http-cache/basic-auth-cache-test.html [ Timeout ] crbug.com/626703 virtual/streams-native/external/wpt/fetch/http-cache/basic-auth-cache-test.html [ Timeout ] crbug.com/626703 external/wpt/css/css-fonts/font-feature-settings-descriptor-01.html [ Failure ] crbug.com/626703 [ Win10 ] external/wpt/fetch/api/redirect/redirect-count.any.worker.html [ Timeout ] @@ -3776,8 +3722,7 @@ crbug.com/626703 external/wpt/requestidlecallback/callback-xhr-sync.html [ Timeout ] crbug.com/626703 external/wpt/screen-orientation/onchange-event-subframe.html [ Timeout ] crbug.com/648295 external/wpt/service-workers/service-worker/update-bytecheck.https.html [ Timeout ] -crbug.com/648295 virtual/blink-cors/external/wpt/service-workers/service-worker/update-bytecheck.https.html [ Timeout ] -crbug.com/648295 virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/update-bytecheck.https.html [ Timeout ] +crbug.com/626703 virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/update-bytecheck.https.html [ Timeout ] crbug.com/626703 external/wpt/svg/linking/reftests/href-filter-element.html [ Failure ] crbug.com/626703 external/wpt/webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_completely_move_up.html [ Failure ] crbug.com/626703 external/wpt/webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_partially_move_down.html [ Failure ] @@ -3991,10 +3936,8 @@ crbug.com/626703 external/wpt/webvtt/rendering/cues-with-video/processing-model/too_many_cues_wrapped.html [ Failure ] crbug.com/626703 virtual/omt-worker-fetch/external/wpt/xhr/event-readystatechange-loaded.htm [ Failure Timeout ] crbug.com/626703 external/wpt/xhr/preserve-ua-header-on-redirect.htm [ Failure ] -crbug.com/626703 virtual/blink-cors/external/wpt/xhr/preserve-ua-header-on-redirect.htm [ Failure ] crbug.com/626703 virtual/omt-worker-fetch/external/wpt/xhr/preserve-ua-header-on-redirect.htm [ Failure ] crbug.com/626703 external/wpt/xhr/setrequestheader-header-allowed.htm [ Failure ] -crbug.com/626703 virtual/blink-cors/external/wpt/xhr/setrequestheader-header-allowed.htm [ Failure ] crbug.com/626703 virtual/omt-worker-fetch/external/wpt/xhr/setrequestheader-header-allowed.htm [ Failure ] crbug.com/626703 [ Win10 ] external/wpt/preload/delaying-onload-link-preload-after-discovery.html [ Timeout ] crbug.com/626703 [ Win ] external/wpt/css/css-writing-modes/box-offsets-rel-pos-vlr-005.xht [ Failure ] @@ -4070,8 +4013,6 @@ # Can't add baselines because a generated unique ID is part of the failure message. crbug.com/888470 external/wpt/referrer-policy/css-integration/child-css/internal-import-stylesheet.html [ Failure ] crbug.com/888470 external/wpt/referrer-policy/css-integration/child-css/processing-instruction.html [ Failure ] -crbug.com/888470 virtual/blink-cors/external/wpt/referrer-policy/css-integration/child-css/internal-import-stylesheet.html [ Failure ] -crbug.com/888470 virtual/blink-cors/external/wpt/referrer-policy/css-integration/child-css/processing-instruction.html [ Failure ] crbug.com/888470 virtual/omt-worker-fetch/external/wpt/referrer-policy/css-integration/child-css/internal-import-stylesheet.html [ Failure ] crbug.com/888470 virtual/omt-worker-fetch/external/wpt/referrer-policy/css-integration/child-css/processing-instruction.html [ Failure ] @@ -4105,7 +4046,6 @@ # Unclear if XHR events should still be fired after its frame is discarded. crbug.com/881180 external/wpt/xhr/open-url-multi-window-4.htm [ Timeout ] -crbug.com/881180 virtual/blink-cors/external/wpt/xhr/open-url-multi-window-4.htm [ Timeout ] crbug.com/881180 virtual/omt-worker-fetch/external/wpt/xhr/open-url-multi-window-4.htm [ Timeout ] crbug.com/655458 external/wpt/workers/Worker_terminate_event_queue.htm [ Pass Timeout ] @@ -4201,12 +4141,11 @@ # This test requires a special browser flag and seems not suitable for a wpt test, see bug. crbug.com/691944 external/wpt/service-workers/service-worker/update-after-oneday.https.html [ Skip ] -crbug.com/691944 virtual/blink-cors/external/wpt/service-workers/service-worker/update-after-oneday.https.html [ Skip ] crbug.com/691944 virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/update-after-oneday.https.html [ Skip ] # These tests (erroneously) see a platform-specific User-Agent header crbug.com/595993 external/wpt/service-workers/service-worker/fetch-header-visibility.https.html [ Failure ] -crbug.com/595993 virtual/blink-cors/external/wpt/service-workers/service-worker/fetch-header-visibility.https.html [ Failure ] +crbug.com/595993 virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/request-end-to-end.https.html [ Failure ] crbug.com/595993 virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/fetch-header-visibility.https.html [ Failure ] crbug.com/619427 [ Mac ] fast/overflow/overflow-height-float-not-removed-crash3.html [ Pass Failure ] @@ -4233,7 +4172,6 @@ # Added 2016-12-12 crbug.com/610835 http/tests/security/XFrameOptions/x-frame-options-deny-multiple-clients.html [ Failure Pass ] -crbug.com/610835 virtual/blink-cors/http/tests/security/XFrameOptions/x-frame-options-deny-multiple-clients.html [ Failure Pass ] #crbug.com/765738 [ Linux Win Mac ] http/tests/wasm/wasm_remote_postMessage_test.https.html [ Pass Timeout ] crbug.com/892212 http/tests/wasm/wasm_remote_postMessage_test.https.html [ Pass Failure Timeout ] @@ -4392,8 +4330,6 @@ # Sheriff failures 2017-05-11 crbug.com/724027 http/tests/security/contentSecurityPolicy/directive-parsing-03.html [ Skip ] crbug.com/724027 http/tests/security/contentSecurityPolicy/source-list-parsing-04.html [ Skip ] -crbug.com/724027 virtual/blink-cors/http/tests/security/contentSecurityPolicy/directive-parsing-03.html [ Skip ] -crbug.com/724027 virtual/blink-cors/http/tests/security/contentSecurityPolicy/source-list-parsing-04.html [ Skip ] # Sheriff failures 2017-05-16 crbug.com/722212 fast/events/pointerevents/mouse-pointer-event-properties.html [ Failure Timeout Pass ] @@ -4475,7 +4411,6 @@ # Sheriff failures 2017-07-03 crbug.com/708994 http/tests/security/cross-frame-mouse-source-capabilities.html [ Timeout Pass ] -crbug.com/708994 virtual/blink-cors/http/tests/security/cross-frame-mouse-source-capabilities.html [ Timeout Pass ] crbug.com/745887 [ Mac ] fast/frames/sandboxed-iframe-plugins.html [ Failure Pass ] crbug.com/745887 [ Win ] fast/frames/sandboxed-iframe-plugins.html [ Failure Pass ] @@ -4637,7 +4572,6 @@ # Sheriff failures 2017-09-21 crbug.com/767469 http/tests/navigation/start-load-during-provisional-loader-detach.html [ Pass Failure ] -crbug.com/767469 virtual/blink-cors/http/tests/navigation/start-load-during-provisional-loader-detach.html [ Pass Failure ] crbug.com/767469 virtual/stable/http/tests/navigation/start-load-during-provisional-loader-detach.html [ Pass Failure ] # Sheriff failures 2017-10-02 @@ -5236,7 +5170,6 @@ crbug.com/881207 fast/js/regress/splice-to-remove.html [ Timeout Pass ] crbug.com/882689 http/tests/security/cookies/third-party-cookie-blocking-worker.html [ Pass Failure ] -crbug.com/882689 virtual/blink-cors/http/tests/security/cookies/third-party-cookie-blocking-worker.html [ Pass Failure ] # The following tests need LazyFrameLoading. crbug.com/869492 external/wpt/feature-policy/experimental-features/lazyload/lazyload-enabled-tentative.sub.html [ Failure ] @@ -5550,8 +5483,6 @@ # These started failing when network service was enabled by default. crbug.com/933880 external/wpt/service-workers/service-worker/request-end-to-end.https.html [ Failure ] -crbug.com/933880 virtual/blink-cors/external/wpt/service-workers/service-worker/request-end-to-end.https.html [ Failure ] -crbug.com/933880 virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/request-end-to-end.https.html [ Failure ] crbug.com/933880 http/tests/inspector-protocol/network/interception-take-stream.js [ Failure ] crbug.com/933880 http/tests/inspector-protocol/network/xhr-interception-auth-fail.js [ Failure ] # This passes in content_shell but not in chrome with network service disabled, @@ -5838,6 +5769,3 @@ crbug.com/966345 external/wpt/webvtt/rendering/cues-with-video/processing-model/3_tracks.html [ Failure ] crbug.com/966345 external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_normal_wrapped.html [ Failure ] crbug.com/966345 external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre-line_wrapped.html [ Failure ] - -crbug.com/905971 virtual/blink-cors/http/tests/security/img-redirect-to-crossorigin-credentials.html [ Failure ] -crbug.com/905971 virtual/blink-cors/http/tests/security/script-crossorigin-redirect-credentials.html [ Failure ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index a1e6ca1..3498184 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -988,50 +988,5 @@ "prefix": "cookies-without-samesite-must-be-secure", "base": "external/wpt/cookies/samesite-none-secure", "args": ["--enable-features=SameSiteByDefaultCookies,CookiesWithoutSameSiteMustBeSecure"] - }, - { - "prefix": "blink-cors", - "base": "external/wpt/fetch", - "args": ["--disable-features=OutOfBlinkCors"] - }, - { - "prefix": "blink-cors", - "base": "external/wpt/http", - "args": ["--disable-features=OutOfBlinkCors"] - }, - { - "prefix": "blink-cors", - "base": "external/wpt/referrer-policy", - "args": ["--disable-features=OutOfBlinkCors"] - }, - { - "prefix": "blink-cors", - "base": "external/wpt/service-workers", - "args": ["--disable-features=OutOfBlinkCors"] - }, - { - "prefix": "blink-cors", - "base": "external/wpt/xhr", - "args": ["--disable-features=OutOfBlinkCors"] - }, - { - "prefix": "blink-cors", - "base": "http/tests/fetch", - "args": ["--disable-features=OutOfBlinkCors"] - }, - { - "prefix": "blink-cors", - "base": "http/tests/navigation", - "args": ["--disable-features=OutOfBlinkCors"] - }, - { - "prefix": "blink-cors", - "base": "http/tests/security", - "args": ["--disable-features=OutOfBlinkCors"] - }, - { - "prefix": "blink-cors", - "base": "http/tests/xmlhttprequest", - "args": ["--disable-features=OutOfBlinkCors"] } ]
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 a1c6d3f..d83c35b6 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
@@ -6535,12 +6535,6 @@ {} ] ], - "pointerevents/pointerevent_touch-action-table-test_touch-manual.html": [ - [ - "pointerevents/pointerevent_touch-action-table-test_touch-manual.html", - {} - ] - ], "pointerevents/pointerlock/pointerevent_movementxy-manual.html": [ [ "pointerevents/pointerlock/pointerevent_movementxy-manual.html", @@ -70877,6 +70871,18 @@ {} ] ], + "css/css-text/white-space/trailing-space-align-start.tentative.html": [ + [ + "css/css-text/white-space/trailing-space-align-start.tentative.html", + [ + [ + "/css/css-text/white-space/reference/trailing-space-align-start-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-text/white-space/white-space-empty-text-sibling.html": [ [ "css/css-text/white-space/white-space-empty-text-sibling.html", @@ -153475,6 +153481,11 @@ {} ] ], + "css/css-text/white-space/reference/trailing-space-align-start-ref.html": [ + [ + {} + ] + ], "css/css-text/white-space/reference/white-space-break-spaces-005-ref.html": [ [ {} @@ -183425,6 +183436,11 @@ {} ] ], + "infrastructure/metadata/infrastructure/testdriver/actions/actionsWithKeyPressed.html.ini": [ + [ + {} + ] + ], "infrastructure/metadata/infrastructure/testdriver/actions/elementPosition.html.ini": [ [ {} @@ -193510,6 +193526,16 @@ {} ] ], + "service-workers/service-worker/registration-schedule-job.https-expected.txt": [ + [ + {} + ] + ], + "service-workers/service-worker/registration-updateviacache.https-expected.txt": [ + [ + {} + ] + ], "service-workers/service-worker/resources/404.py": [ [ {} @@ -240764,6 +240790,12 @@ {} ] ], + "css/css-text/text-align/text-align-last-empty-inline.html": [ + [ + "css/css-text/text-align/text-align-last-empty-inline.html", + {} + ] + ], "css/css-text/text-indent/percentage-value-intrinsic-size.html": [ [ "css/css-text/text-indent/percentage-value-intrinsic-size.html", @@ -273164,6 +273196,12 @@ {} ] ], + "html/semantics/interactive-elements/the-details-element/display-table-with-rt-crash.html": [ + [ + "html/semantics/interactive-elements/the-details-element/display-table-with-rt-crash.html", + {} + ] + ], "html/semantics/interactive-elements/the-details-element/toggleEvent.html": [ [ "html/semantics/interactive-elements/the-details-element/toggleEvent.html", @@ -273260,6 +273298,12 @@ {} ] ], + "html/semantics/interactive-elements/the-summary-element/display-table-with-rt-crash.html": [ + [ + "html/semantics/interactive-elements/the-summary-element/display-table-with-rt-crash.html", + {} + ] + ], "html/semantics/interfaces.html": [ [ "html/semantics/interfaces.html", @@ -279284,6 +279328,14 @@ {} ] ], + "infrastructure/testdriver/actions/actionsWithKeyPressed.html": [ + [ + "infrastructure/testdriver/actions/actionsWithKeyPressed.html", + { + "testdriver": true + } + ] + ], "infrastructure/testdriver/actions/elementPosition.html": [ [ "infrastructure/testdriver/actions/elementPosition.html", @@ -295945,6 +295997,15 @@ } ] ], + "pointerevents/pointerevent_touch-action-table-none-test_touch.html": [ + [ + "pointerevents/pointerevent_touch-action-table-none-test_touch.html", + { + "testdriver": true, + "timeout": "long" + } + ] + ], "pointerevents/pointerevent_touch-action-verification.html": [ [ "pointerevents/pointerevent_touch-action-verification.html", @@ -308948,6 +309009,12 @@ } ] ], + "service-workers/service-worker/registration-schedule-job.https.html": [ + [ + "service-workers/service-worker/registration-schedule-job.https.html", + {} + ] + ], "service-workers/service-worker/registration-scope.https.html": [ [ "service-workers/service-worker/registration-scope.https.html", @@ -376483,31 +376550,31 @@ "reftest" ], "css/css-color-adjust/inheritance-expected.txt": [ - "b0c6f2fbd74b6740458bd98ca4a6b5c2910a5544", + "9fdd1886b54c37355ae8ce4c4de083dedabe048a", "support" ], "css/css-color-adjust/inheritance.html": [ - "c48d2ade7bb0339377480cf506dad7312303deb1", + "f7f6529349bf1ba0436e2d1165a81552de95ffaa", "testharness" ], "css/css-color-adjust/parsing/color-scheme-computed.tentative-expected.txt": [ - "35ae840413c8030e4c79eefe68b68ef6fbeeb200", + "0aa58bb90e191bef42d9077a4bd8ea8949527c15", "support" ], "css/css-color-adjust/parsing/color-scheme-computed.tentative.html": [ - "74d1bb919dc299c20fa8d1a11fe116e28fa59bfd", + "80b9803981f7123d22c637ee9056c04ba3108818", "testharness" ], "css/css-color-adjust/parsing/color-scheme-invalid.html": [ - "0def5b3fc1090ab288c8ab9d601824e54e620f08", + "48fa4d1d1f3a1f6d172f650e2452bf29921314c7", "testharness" ], "css/css-color-adjust/parsing/color-scheme-valid-expected.txt": [ - "4839a167d34345d86ee0e1a0bedcec6b343dad2c", + "4fd64bb6a2ad2406946265291b397411e67698d9", "support" ], "css/css-color-adjust/parsing/color-scheme-valid.html": [ - "433610061f29411dcc9b7379ce4123fbb5110766", + "2ba01da394ebc63c9b6b87ea53714d1567032f9b", "testharness" ], "css/css-color/LICENSE": [ @@ -407718,6 +407785,10 @@ "0b10eb768825a44a2252c55a53326d6641d3fff9", "visual" ], + "css/css-text/text-align/text-align-last-empty-inline.html": [ + "07dcb3ba896c1f393896a397775cc3ff83fb5ef3", + "testharness" + ], "css/css-text/text-align/text-align-start-001.html": [ "40c6abaef4847027a628e53acfc88b707bad8c38", "reftest" @@ -409086,6 +409157,10 @@ "9f579f29e0c897c744e1b06d5d2d60e85612f823", "support" ], + "css/css-text/white-space/reference/trailing-space-align-start-ref.html": [ + "b65a8fe75479c0119a8ecc156b9a5d5f318d66d0", + "support" + ], "css/css-text/white-space/reference/white-space-break-spaces-005-ref.html": [ "dece5f7394470d5bbc393c4318fa412ea25f9b4e", "support" @@ -409314,6 +409389,10 @@ "af3187ae8d3d955dcb23a02de7ecc6b0b4db9479", "reftest" ], + "css/css-text/white-space/trailing-space-align-start.tentative.html": [ + "7908de12adff86e96df50a30a9ae57e2db9cd7f5", + "reftest" + ], "css/css-text/white-space/trailing-space-before-br-001.html": [ "2ecd4d3767acf5b2d54782eff26ae5bd3c97a87f", "testharness" @@ -462350,6 +462429,10 @@ "5ed14c53afc9371275917d460f5b9638ab9a091e", "testharness" ], + "html/semantics/interactive-elements/the-details-element/display-table-with-rt-crash.html": [ + "80812cccb548ef5bec9aa4c9d240faaab8de7747", + "testharness" + ], "html/semantics/interactive-elements/the-details-element/toggleEvent-expected.txt": [ "5c808aa0a050a4ad866e65445b3fbd7c6807903d", "support" @@ -462438,6 +462521,10 @@ "4a3693bd2dafe710b82054bfadd8bcaa97b16db5", "testharness" ], + "html/semantics/interactive-elements/the-summary-element/display-table-with-rt-crash.html": [ + "57cc45478e03ce1cdbb755281b2f434b38582563", + "testharness" + ], "html/semantics/interfaces-expected.txt": [ "886e7b2c154d563563708f78582f57808814c643", "support" @@ -468150,6 +468237,10 @@ "cbae6b15410e13433c4a9fadd8c2a8cc5fbc4fdc", "support" ], + "infrastructure/metadata/infrastructure/testdriver/actions/actionsWithKeyPressed.html.ini": [ + "38f84319c91d0b617ed0a72716bfa8756fc2c317", + "support" + ], "infrastructure/metadata/infrastructure/testdriver/actions/elementPosition.html.ini": [ "9ae71a6e73e22a855c69d3269936d71c17d6e9e5", "support" @@ -468350,6 +468441,10 @@ "ea7973a62e0ee9cdc874879fd844b2309e944e61", "testharness" ], + "infrastructure/testdriver/actions/actionsWithKeyPressed.html": [ + "74e939f5fde4773aade6ce4f7bbee573e39ae8ec", + "testharness" + ], "infrastructure/testdriver/actions/elementPosition.html": [ "145852e7b51bd0cdc9e7b4ef5ebddcbf1c0235c5", "testharness" @@ -482614,9 +482709,9 @@ "252ed2fed0cfec792dfc2fccacea27234216d8c4", "testharness" ], - "pointerevents/pointerevent_touch-action-table-test_touch-manual.html": [ - "07a78f572985658c04b6ce7709e01b936c73f0fd", - "manual" + "pointerevents/pointerevent_touch-action-table-none-test_touch.html": [ + "6f5e16a8c5315935d89f2d2240e52339e63d9715", + "testharness" ], "pointerevents/pointerevent_touch-action-verification.html": [ "f42d9f6bd6703b962058b79faae413fbed0757cc", @@ -495291,7 +495386,7 @@ "testharness" ], "service-workers/service-worker/fetch-event-async-respond-with.https.html": [ - "7842a829c9b82c0ebff94a3902284ad191b5be71", + "ae64fcb9a5445843afb75679d0dafa45a3366677", "testharness" ], "service-workers/service-worker/fetch-event-is-history-backward-navigation-manual.https.html": [ @@ -495830,6 +495925,14 @@ "aa9d38cedc989c61c7267acd4150b889744855e2", "testharness" ], + "service-workers/service-worker/registration-schedule-job.https-expected.txt": [ + "8deae645bc1036a908886e0eccf2c1b6175509e1", + "support" + ], + "service-workers/service-worker/registration-schedule-job.https.html": [ + "18589e0aa0b32e130934a65b1b065d5c7f79e36e", + "testharness" + ], "service-workers/service-worker/registration-scope.https.html": [ "f4a77d72b9120098bba40fbbc1a3174fe15b2f5e", "testharness" @@ -495850,8 +495953,12 @@ "f7b52d5ddced18613ca225386bb57f28b9bacd62", "testharness" ], + "service-workers/service-worker/registration-updateviacache.https-expected.txt": [ + "002474415b16b6a2fadc92c78ba872760e0e90ae", + "support" + ], "service-workers/service-worker/registration-updateviacache.https.html": [ - "dbcc6eab1f82a6b33ed7d889cba51be5b984b610", + "423908db0e428d65b48b8b8d16162a5ebcf87268", "testharness" ], "service-workers/service-worker/rejections.https.html": [ @@ -496187,7 +496294,7 @@ "support" ], "service-workers/service-worker/resources/fetch-event-async-respond-with-worker.js": [ - "3409d0a0397bdc552da166961b435fb2363e3468", + "dc3f1a1e98563ad1b5924c8315c0d64d17ffbbfd", "support" ], "service-workers/service-worker/resources/fetch-event-network-error-controllee-iframe.html": [ @@ -501615,7 +501722,7 @@ "support" ], "tools/manifest/update.py": [ - "65c428317654de386adbf18e33fa54d14afb1ddb", + "166a7c9caddbab5dfa40712be8840de7b3efb65f", "support" ], "tools/manifest/utils.py": [ @@ -501959,7 +502066,7 @@ "support" ], "tools/serve/serve.py": [ - "b86ad309142b5a7b617d046265019a2e7cae6439", + "575f8b7a3accfcc9789c27c9255e3b289cf1c984", "support" ], "tools/serve/test_functional.py": [ @@ -505811,7 +505918,7 @@ "support" ], "tools/wpt/testfiles.py": [ - "1707048754641137418ca7bf85d063a9ea52713c", + "b1c81877cd620f99c76e139329614e905c6271fe", "support" ], "tools/wpt/tox.ini": [ @@ -506339,7 +506446,7 @@ "support" ], "tools/wptserve/wptserve/server.py": [ - "d57a36b133844b1146c4ab44ae411ea94222cc6d", + "e58b4acd7195d798bd829ce0d10e8d4d1986e253", "support" ], "tools/wptserve/wptserve/sslutils/__init__.py": [ @@ -512235,7 +512342,7 @@ "testharness" ], "webrtc/RTCRtpReceiver-getSynchronizationSources.https-expected.txt": [ - "1a941ec8a33bdb772931c17cfa639f74cfcf7e0d", + "c07866218f3e7a3364cfb6eb43b40529561f8d6c", "support" ], "webrtc/RTCRtpReceiver-getSynchronizationSources.https.html": [
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-details-element/display-table-with-rt-crash.html b/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-details-element/display-table-with-rt-crash.html new file mode 100644 index 0000000..80812cc --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-details-element/display-table-with-rt-crash.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=969619"> +<details open="open" style="display:table;"><rt></rt></details> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + test(()=> { }, "No crash"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-summary-element/display-table-with-rt-crash.html b/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-summary-element/display-table-with-rt-crash.html new file mode 100644 index 0000000..57cc454 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-summary-element/display-table-with-rt-crash.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=969619"> +<summary style="display:table;"><rt></rt></summary> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + test(()=> { }, "No crash"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/actionsWithKeyPressed.html.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/actionsWithKeyPressed.html.ini new file mode 100644 index 0000000..38f8431 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/actionsWithKeyPressed.html.ini
@@ -0,0 +1,9 @@ +[actionsWithKeyPressed.html] + expected: + if product == "safari": ERROR + + + [TestDriver actions: actions with key pressed] + expected: + if product == "firefox": FAIL +
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/actions/actionsWithKeyPressed.html b/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/actions/actionsWithKeyPressed.html new file mode 100644 index 0000000..74e939f5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/infrastructure/testdriver/actions/actionsWithKeyPressed.html
@@ -0,0 +1,67 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>TestDriver actions: actions with key pressed</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="/resources/testdriver-vendor.js"></script> + +<style> +div#test1, div#test2 { + position: fixed; + top: 0; + left: 0; + width: 100px; + height: 100px; + background-color: blue; +} + +div#test2 { + position: fixed; + top: 100px; + left: 0; + width: 100px; + height: 100px; + background-color: green; +} +</style> + +<div id="test1"> +</div> + +<div id="test2"> +</div> + +<script> +let keys = []; + +async_test(t => { + let test1 = document.getElementById("test1"); + let test2 = document.getElementById("test2"); + document.getElementById("test1").addEventListener("click", + e => {keys.push(e.getModifierState("Control"))}); + document.getElementById("test2").addEventListener("click", + e => {keys.push(e.getModifierState("Control"))}); + + let actions = new test_driver.Actions() + .keyDown("\uE009") + .addTick() + .pointerMove(0, 0, {origin: test1}) + .pointerDown() + .pointerUp() + .pointerMove(0, 0, {origin: test2}) + .pointerDown() + .pointerUp() + .addTick() + .keyUp("\uE009") + .addTick() + .pointerMove(0, 0, {origin: test1}) + .pointerDown() + .pointerUp(); + + actions.send() + .then(t.step_func_done(() => assert_array_equals(keys, [true, true, false]))) + .catch(e => t.step_func(() => assert_unreached("Actions sequence failed " + e))); +}); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-table-test_touch-manual.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-table-none-test_touch.html similarity index 71% rename from third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-table-test_touch-manual.html rename to third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-table-none-test_touch.html index 07a78f5..6f5e16a8c 100644 --- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-table-test_touch-manual.html +++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-table-none-test_touch.html
@@ -8,6 +8,9 @@ <link rel="stylesheet" type="text/css" href="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 src="pointerevent_support.js"></script> <style> #target0 { @@ -38,7 +41,8 @@ </head> <body onload="run()"> <h2>Pointer Events touch-action attribute support</h2> - <h4 id="desc">Test Description: Try to scroll element DOWN starting your touch over the 1st Row. Wait for description update.</h4> + <h4 id="desc">Test Description: Try to scroll element DOWN then RIGHT starting your touch over the 1st Row. <br> + And try to scroll element DOWN then RIGHT starting your touch inside of the Cell 3, then tap complete button.</h4> <p>Note: this test is for touch only</p> <div id="target0"> <table id="testtable"> @@ -56,14 +60,13 @@ var xScrollIsReceived = false; var yScrollIsReceived = false; var xScr0, yScr0, xScr1, yScr1; - var scrollReturnInterval = 1000; var isFirstPart = true; - setup({ explicit_timeout: true }); add_completion_callback(showPointerTypes); function run() { var target0 = document.getElementById("target0"); var btnComplete = document.getElementById("btnComplete"); + var actions_promise; //TA 15.19 var test_touchaction_cell = async_test("touch-action attribute test on the cell"); @@ -74,11 +77,15 @@ on_event(btnComplete, 'click', function(event) { test_touchaction_cell.step(function() { - assert_equals(target0.scrollLeft, 0, "table scroll x offset should be 0 in the end of the test"); - assert_equals(target0.scrollTop, 0, "table scroll y offset should be 0 in the end of the test"); + assert_equals(target0.scrollLeft, xScr1, "table scroll x offset should be 0 in the end of the test"); + assert_equals(target0.scrollTop, yScr1, "table scroll y offset should be 0 in the end of the test"); assert_true(xScrollIsReceived && yScrollIsReceived, "target0 x and y scroll offsets should be greater than 0 after first two interactions (outside red border) respectively"); }); - test_touchaction_cell.done(); + + // Make sure the test finishes after all the input actions are completed. + actions_promise.then( () => { + test_touchaction_cell.done(); + }); updateDescriptionComplete(); }); @@ -99,43 +106,29 @@ test_touchaction_row.step(function () { yScrollIsReceived = true; }); - updateDescriptionSecondStepTable(target0, scrollReturnInterval); } if(xScrollIsReceived && yScrollIsReceived) { test_touchaction_row.done(); - updateDescriptionThirdStepTable(target0, scrollReturnInterval, function() { - setTimeout(function() { - isFirstPart = false; - }, scrollReturnInterval); // avoid immediate triggering while scroll is still being performed - }); } } else { test_touchaction_cell.step(failOnScroll, "scroll received while shouldn't"); } }); - } - function updateDescriptionSecondStepTable(target, scrollReturnInterval, element) { - window.setTimeout(function() { - objectScroller(target, 'up', 0); - } - , scrollReturnInterval); - document.getElementById('desc').innerHTML = "Test Description: Try to scroll element RIGHT staring your touch over the Row 1"; + // Inject touch inputs. + actions_promise = touchScrollInTarget(row1, 'down').then(function() { + return touchScrollInTarget(row1, 'right'); + }).then(function() { + isFirstPart = false; + return touchScrollInTarget(cell3, 'down'); + }).then(function() { + return touchScrollInTarget(cell3, 'right'); + }).then(function() { + return clickInTarget("touch", btnComplete); + }); } - - function updateDescriptionThirdStepTable(target, scrollReturnInterval, callback = null) { - window.setTimeout(function() { - objectScroller(target, 'left', 0); - if (callback) { - callback(); - } - } - , scrollReturnInterval); - document.getElementById('desc').innerHTML = "Test Description: Try to scroll element DOWN then RIGHT starting your touch inside of the Cell 3"; - } - </script> <h1>touch-action: none</h1> <div id="complete-notice">
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/registration-schedule-job.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/registration-schedule-job.https-expected.txt new file mode 100644 index 0000000..8deae64 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/registration-schedule-job.https-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +FAIL different scriptURL and updateViaCache assert_equals: expected "none" but got "imports" +FAIL different type assert_equals: expected (string) "classic" but got (undefined) undefined +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/registration-schedule-job.https.html b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/registration-schedule-job.https.html new file mode 100644 index 0000000..18589e0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/registration-schedule-job.https.html
@@ -0,0 +1,67 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Service Worker: Schedule Job algorithm</title> +<script src="/resources/testharness.js"></script> +<script src="resources/testharness-helpers.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +// Tests for https://w3c.github.io/ServiceWorker/#schedule-job-algorithm +// Non-equivalent register jobs should not be coalesced. +const scope = 'resources/'; +const script1 = 'resources/empty.js'; +const script2 = 'resources/empty.js?change'; + +async function cleanup() { + const registration = await navigator.serviceWorker.getRegistration(scope); + if (registration) + await registration.unregister(); +} + +function absolute_url(url) { + return new URL(url, self.location).toString(); +} + +// Test scriptURL and updateViaCache. +promise_test(async t => { + await cleanup(); + t.add_cleanup(cleanup); + + // Check defaults. + const registration = await + navigator.serviceWorker.register(script1, {scope}); + assert_equals(registration.updateViaCache, 'imports'); + + // Schedule several register jobs. + navigator.serviceWorker.register(script1, {scope}); + navigator.serviceWorker.register(script2, {scope}); + await navigator.serviceWorker.register(script2, + {scope, updateViaCache: 'none'}); + + // None of the changes should have been coalesced. + assert_equals(registration.installing.scriptURL, absolute_url(script2)); + assert_equals(registration.updateViaCache, 'none'); +}, 'different scriptURL and updateViaCache'); + +// Test |type| in another test case because most browsers don't support it. +promise_test(async t => { + const script1 = 'resources/empty.js'; + const script2 = 'resources/empty.js?change'; + + await cleanup(); + t.add_cleanup(cleanup); + + // Check defaults. + const registration = await + navigator.serviceWorker.register(script1, {scope}); + assert_equals(registration.installing.type, 'classic'); + + // Schedule several register jobs. + navigator.serviceWorker.register(script1, {scope}); + navigator.serviceWorker.register(script2, {scope}); + await navigator.serviceWorker.register(script2, {scope, type: 'module'}); + + // None of the changes should have been coalesced. + assert_equals(registration.installing.scriptURL, absolute_url(script2)); + assert_equals(registration.installing.type, 'module'); +}, 'different type'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/registration-updateviacache.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/registration-updateviacache.https-expected.txt new file mode 100644 index 0000000..0024744 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/registration-updateviacache.https-expected.txt
@@ -0,0 +1,28 @@ +This is a testharness.js-based test. +PASS register-with-updateViaCache-undefined +PASS register-with-updateViaCache-imports +PASS register-with-updateViaCache-all +PASS register-with-updateViaCache-none +PASS register-with-updateViaCache-undefined-then-undefined +PASS register-with-updateViaCache-undefined-then-imports +PASS register-with-updateViaCache-undefined-then-all +PASS register-with-updateViaCache-undefined-then-none +PASS register-with-updateViaCache-imports-then-undefined +PASS register-with-updateViaCache-imports-then-imports +PASS register-with-updateViaCache-imports-then-all +PASS register-with-updateViaCache-imports-then-none +PASS register-with-updateViaCache-all-then-undefined +PASS register-with-updateViaCache-all-then-imports +PASS register-with-updateViaCache-all-then-all +PASS register-with-updateViaCache-all-then-none +PASS register-with-updateViaCache-none-then-undefined +PASS register-with-updateViaCache-none-then-imports +PASS register-with-updateViaCache-none-then-all +PASS register-with-updateViaCache-none-then-none +PASS access-updateViaCache-after-unregister-undefined +PASS access-updateViaCache-after-unregister-imports +PASS access-updateViaCache-after-unregister-all +PASS access-updateViaCache-after-unregister-none +FAIL updateViaCache is not updated if register() rejects assert_equals: after update attempt expected "imports" but got "none" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/registration-updateviacache.https.html b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/registration-updateviacache.https.html index dbcc6eab..423908db 100644 --- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/registration-updateviacache.https.html +++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/registration-updateviacache.https.html
@@ -184,4 +184,21 @@ }, testName); } + promise_test(async t => { + await cleanup(); + t.add_cleanup(cleanup); + + const registration = await navigator.serviceWorker.register( + 'resources/empty.js', + {scope: SCOPE}); + assert_equals(registration.updateViaCache, 'imports', + 'before update attempt'); + + const fail = navigator.serviceWorker.register( + 'resources/malformed-worker.py?parse-error', + {scope: SCOPE, updateViaCache: 'none'}); + await promise_rejects(t, new TypeError(), fail); + assert_equals(registration.updateViaCache, 'imports', + 'after update attempt'); + }, 'updateViaCache is not updated if register() rejects'); </script>
diff --git a/third_party/blink/web_tests/external/wpt/tools/manifest/update.py b/third_party/blink/web_tests/external/wpt/tools/manifest/update.py index 65c42831..166a7c9 100755 --- a/third_party/blink/web_tests/external/wpt/tools/manifest/update.py +++ b/third_party/blink/web_tests/external/wpt/tools/manifest/update.py
@@ -23,7 +23,7 @@ def update(tests_root, # type: str manifest, # type: Manifest - manifest_path, # type: Optional[str] + manifest_path=None, # type: Optional[str] working_copy=True, # type: bool cache_root=None, # type: Optional[str] rebuild=False # type: bool
diff --git a/third_party/blink/web_tests/external/wpt/tools/serve/serve.py b/third_party/blink/web_tests/external/wpt/tools/serve/serve.py index b86ad30..575f8b7a 100644 --- a/third_party/blink/web_tests/external/wpt/tools/serve/serve.py +++ b/third_party/blink/web_tests/external/wpt/tools/serve/serve.py
@@ -32,6 +32,12 @@ from mod_pywebsocket import standalone as pywebsocket +EDIT_HOSTS_HELP = ("Please ensure all the necessary WPT subdomains " + "are mapped to a loopback device in /etc/hosts. " + "See https://github.com/web-platform-tests/wpt#running-the-tests " + "for instructions.") + + def replace_end(s, old, new): """ Given a string `s` that ends with `old`, replace that occurrence of `old` @@ -444,18 +450,19 @@ wrapper.start(start_http_server, host, port, paths, build_routes(aliases), bind_address, config) + url = "http://{}:{}/".format(host, port) connected = False for i in range(10): try: - urllib.request.urlopen("http://%s:%d/" % (host, port)) + urllib.request.urlopen(url) connected = True break except urllib.error.URLError: time.sleep(1) if not connected: - logger.critical("Failed to connect to test server on http://%s:%s. " - "You may need to edit /etc/hosts or similar, see README.md." % (host, port)) + logger.critical("Failed to connect to test server " + "on {}. {}".format(url, EDIT_HOSTS_HELP)) sys.exit(1) for domain in config.domains_set: @@ -465,8 +472,7 @@ try: urllib.request.urlopen("http://%s:%d/" % (domain, port)) except Exception: - logger.critical("Failed probing domain %s. " - "You may need to edit /etc/hosts or similar, see README.md." % domain) + logger.critical("Failed probing domain {}. {}".format(domain, EDIT_HOSTS_HELP)) sys.exit(1) wrapper.wait()
diff --git a/third_party/blink/web_tests/external/wpt/tools/wpt/testfiles.py b/third_party/blink/web_tests/external/wpt/tools/wpt/testfiles.py index 1707048..b1c81877 100644 --- a/third_party/blink/web_tests/external/wpt/tools/wpt/testfiles.py +++ b/third_party/blink/web_tests/external/wpt/tools/wpt/testfiles.py
@@ -5,6 +5,7 @@ import subprocess import sys +import six from collections import OrderedDict from six import iteritems @@ -375,11 +376,13 @@ def get_revish(**kwargs): - # type: (**Any) -> str - revish = kwargs["revish"] + # type: (**Any) -> bytes + revish = kwargs.get("revish") if revish is None: revish = "%s..HEAD" % branch_point() - assert isinstance(revish, str) + if isinstance(revish, six.text_type): + revish = revish.encode("utf8") + assert isinstance(revish, six.binary_type) return revish
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptserve/wptserve/server.py b/third_party/blink/web_tests/external/wpt/tools/wptserve/wptserve/server.py index d57a36b..e58b4ac 100644 --- a/third_party/blink/web_tests/external/wpt/tools/wptserve/wptserve/server.py +++ b/third_party/blink/web_tests/external/wpt/tools/wptserve/wptserve/server.py
@@ -29,7 +29,8 @@ from .utils import HTTPException from .constants import h2_headers -"""HTTP server designed for testing purposes. +""" +HTTP server designed for testing purposes. The server is designed to provide flexibility in the way that requests are handled, and to provide control both of exactly @@ -63,6 +64,12 @@ """ +EDIT_HOSTS_HELP = ("Please ensure all the necessary WPT subdomains " + "are mapped to a loopback device in /etc/hosts. " + "See https://github.com/web-platform-tests/wpt#running-the-tests " + "for instructions.") + + class RequestRewriter(object): def __init__(self, rules): """Object for rewriting the request path. @@ -669,8 +676,7 @@ _host, self.port = self.httpd.socket.getsockname() except Exception: - self.logger.error("Failed to start HTTP server. " - "You may need to edit /etc/hosts or similar, see README.md.") + self.logger.error("Failed to start HTTP server. {}".format(EDIT_HOSTS_HELP)) raise def start(self, block=False):
diff --git a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_touch-action-table-test_touch-manual-automation.js b/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_touch-action-table-test_touch-manual-automation.js deleted file mode 100644 index 2ae10e0..0000000 --- a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_touch-action-table-test_touch-manual-automation.js +++ /dev/null
@@ -1,15 +0,0 @@ -importAutomationScript('/pointerevents/pointerevent_common_input.js'); - -function inject_input() { - return touchScrollInTarget('#row1', 'down').then(function() { - return touchScrollInTarget('#row1', 'right'); - }).then(function() { - return delayPromise(4*scrollReturnInterval); - }).then(function() { - return touchScrollInTarget('#cell3', 'down'); - }).then(function() { - return touchScrollInTarget('#cell3', 'right'); - }).then(function() { - return touchTapInTarget('#btnComplete'); - }); -}
diff --git a/third_party/blink/web_tests/fast/replaced/percentage-height-foreign-object-crash.html b/third_party/blink/web_tests/fast/replaced/percentage-height-foreign-object-crash.html new file mode 100644 index 0000000..c9720d0 --- /dev/null +++ b/third_party/blink/web_tests/fast/replaced/percentage-height-foreign-object-crash.html
@@ -0,0 +1,11 @@ +<!DOCTYPE html> +<svg> + <foreignObject style="height:100%;"> + <object style="max-height:100%;"></object> + </foreignObject> +</svg> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script> + test(()=> { }, "did not crash"); +</script>
diff --git a/third_party/blink/web_tests/http/tests/devtools/network/resource-priority-expected.txt b/third_party/blink/web_tests/http/tests/devtools/network/resource-priority-expected.txt index 71ad775..043283f 100644 --- a/third_party/blink/web_tests/http/tests/devtools/network/resource-priority-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/network/resource-priority-expected.txt
@@ -12,6 +12,12 @@ Request: empty-script.js?precededByImage priority: Medium sendScriptRequestPrecededByPreloadedImage Request: abe.png?preloaded priority: Low +Request: style.css?precededByPreloadedImage priority: VeryHigh +sendStyleRequestPrecededByImage +Request: abe.png?precedingStyle priority: Low +Request: style.css?precededByImage priority: Medium +sendStyleRequestPrecededByPreloadedImage +Request: abe.png?preloaded priority: Low Request: empty-script.js?precededByPreloadedImage priority: High sendXHRSync Request: empty.html?xhr-sync priority: VeryHigh
diff --git a/third_party/blink/web_tests/http/tests/devtools/network/resource-priority.js b/third_party/blink/web_tests/http/tests/devtools/network/resource-priority.js index 8fa9b71..be47d6fa 100644 --- a/third_party/blink/web_tests/http/tests/devtools/network/resource-priority.js +++ b/third_party/blink/web_tests/http/tests/devtools/network/resource-priority.js
@@ -70,6 +70,24 @@ var iframe = document.createElement("iframe"); document.body.appendChild(iframe); iframe.srcdoc = '<html><body><link href="resources/abe.png?preloaded" rel=preload as=image>' + + '<link rel="stylesheet" type="text/css" href="http://localhost:8000/devtools/network/resources/style.css?precededByPreloadedImage">' + + '<img src="resources/abe.png?preloaded"></body></html>'; + } + + function sendStyleRequestPrecededByImage() + { + var iframe = document.createElement("iframe"); + document.body.appendChild(iframe); + iframe.srcdoc = '<html><body><img src="resources/abe.png?precedingStyle">' + + '<link rel="stylesheet" type="text/css" href="http://localhost:8000/devtools/network/resources/style.css?precededByImage">' + + '</body></html>'; + } + + function sendStyleRequestPrecededByPreloadedImage() + { + var iframe = document.createElement("iframe"); + document.body.appendChild(iframe); + iframe.srcdoc = '<html><body><link href="resources/abe.png?preloaded" rel=preload as=image>' + '<script src="http://localhost:8000/devtools/network/resources/empty-script.js?precededByPreloadedImage"></s' + 'cript><img src="resources/abe.png?preloaded"></body></html>'; } @@ -97,6 +115,8 @@ {'fn': 'sendModuleScriptRequest', 'requests': 2}, {'fn': 'sendScriptRequestPrecededByImage', 'requests': 2}, {'fn': 'sendScriptRequestPrecededByPreloadedImage', 'requests': 2}, + {'fn': 'sendStyleRequestPrecededByImage', 'requests': 2}, + {'fn': 'sendStyleRequestPrecededByPreloadedImage', 'requests': 2}, {'fn': 'sendXHRSync', 'requests': 1}, {'fn': 'sendXHRAsync', 'requests': 1}, {'fn': 'sendImageRequest', 'requests': 1},
diff --git a/third_party/blink/web_tests/platform/fuchsia/css3/selectors3/html/css3-modsel-18-expected.png b/third_party/blink/web_tests/platform/fuchsia/css3/selectors3/html/css3-modsel-18-expected.png deleted file mode 100644 index 0a689e2..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/css3/selectors3/html/css3-modsel-18-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/css3/selectors3/xhtml/css3-modsel-18-expected.png b/third_party/blink/web_tests/platform/fuchsia/css3/selectors3/xhtml/css3-modsel-18-expected.png deleted file mode 100644 index 0a689e2..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/css3/selectors3/xhtml/css3-modsel-18-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/css3/selectors3/xml/css3-modsel-18-expected.png b/third_party/blink/web_tests/platform/fuchsia/css3/selectors3/xml/css3-modsel-18-expected.png deleted file mode 100644 index a8a805f..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/css3/selectors3/xml/css3-modsel-18-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/editing/pasteboard/paste-line-endings-001-expected.png b/third_party/blink/web_tests/platform/fuchsia/editing/pasteboard/paste-line-endings-001-expected.png deleted file mode 100644 index cabbc51..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/editing/pasteboard/paste-line-endings-001-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/editing/pasteboard/paste-line-endings-002-expected.png b/third_party/blink/web_tests/platform/fuchsia/editing/pasteboard/paste-line-endings-002-expected.png deleted file mode 100644 index cabbc51..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/editing/pasteboard/paste-line-endings-002-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/editing/pasteboard/paste-line-endings-003-expected.png b/third_party/blink/web_tests/platform/fuchsia/editing/pasteboard/paste-line-endings-003-expected.png deleted file mode 100644 index cabbc51..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/editing/pasteboard/paste-line-endings-003-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/editing/pasteboard/paste-line-endings-004-expected.png b/third_party/blink/web_tests/platform/fuchsia/editing/pasteboard/paste-line-endings-004-expected.png deleted file mode 100644 index cabbc51..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/editing/pasteboard/paste-line-endings-004-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/editing/pasteboard/paste-line-endings-005-expected.png b/third_party/blink/web_tests/platform/fuchsia/editing/pasteboard/paste-line-endings-005-expected.png deleted file mode 100644 index cabbc51..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/editing/pasteboard/paste-line-endings-005-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/editing/selection/4402375-expected.png b/third_party/blink/web_tests/platform/fuchsia/editing/selection/4402375-expected.png deleted file mode 100644 index 05255e8..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/editing/selection/4402375-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/editing/style/block-styles-007-expected.png b/third_party/blink/web_tests/platform/fuchsia/editing/style/block-styles-007-expected.png deleted file mode 100644 index 5dc9b6a..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/editing/style/block-styles-007-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/fast/backgrounds/background-clip-text-expected.png b/third_party/blink/web_tests/platform/fuchsia/fast/backgrounds/background-clip-text-expected.png deleted file mode 100644 index 080a043..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/fast/backgrounds/background-clip-text-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/fast/block/float/centered-float-avoidance-complexity-expected.png b/third_party/blink/web_tests/platform/fuchsia/fast/block/float/centered-float-avoidance-complexity-expected.png deleted file mode 100644 index d464e27..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/fast/block/float/centered-float-avoidance-complexity-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/fast/block/float/float-in-float-hit-testing-expected.png b/third_party/blink/web_tests/platform/fuchsia/fast/block/float/float-in-float-hit-testing-expected.png deleted file mode 100644 index dc6a133e..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/fast/block/float/float-in-float-hit-testing-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/fast/block/float/float-in-float-painting-expected.png b/third_party/blink/web_tests/platform/fuchsia/fast/block/float/float-in-float-painting-expected.png deleted file mode 100644 index e47f0b83..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/fast/block/float/float-in-float-painting-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/fast/css/clip-zooming-expected.png b/third_party/blink/web_tests/platform/fuchsia/fast/css/clip-zooming-expected.png deleted file mode 100644 index 59ee8ff..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/fast/css/clip-zooming-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/fast/css/text-overflow-ellipsis-expected.png b/third_party/blink/web_tests/platform/fuchsia/fast/css/text-overflow-ellipsis-expected.png deleted file mode 100644 index a3d2066..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/fast/css/text-overflow-ellipsis-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/fast/css/text-overflow-ellipsis-strict-expected.png b/third_party/blink/web_tests/platform/fuchsia/fast/css/text-overflow-ellipsis-strict-expected.png deleted file mode 100644 index a3d2066..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/fast/css/text-overflow-ellipsis-strict-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/fast/inline-block/overflow-clip-expected.png b/third_party/blink/web_tests/platform/fuchsia/fast/inline-block/overflow-clip-expected.png deleted file mode 100644 index f1aa6dc9..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/fast/inline-block/overflow-clip-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/fast/inline/inline-box-background-expected.png b/third_party/blink/web_tests/platform/fuchsia/fast/inline/inline-box-background-expected.png deleted file mode 100644 index 96aeebc..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/fast/inline/inline-box-background-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/fast/inline/inline-box-background-repeat-x-expected.png b/third_party/blink/web_tests/platform/fuchsia/fast/inline/inline-box-background-repeat-x-expected.png deleted file mode 100644 index 166d29d..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/fast/inline/inline-box-background-repeat-x-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/fast/inline/inline-box-background-repeat-y-expected.png b/third_party/blink/web_tests/platform/fuchsia/fast/inline/inline-box-background-repeat-y-expected.png deleted file mode 100644 index aa020ce..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/fast/inline/inline-box-background-repeat-y-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/fast/lists/003-expected.png b/third_party/blink/web_tests/platform/fuchsia/fast/lists/003-expected.png deleted file mode 100644 index 409e070..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/fast/lists/003-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/fast/lists/scrolled-marker-paint-expected.png b/third_party/blink/web_tests/platform/fuchsia/fast/lists/scrolled-marker-paint-expected.png deleted file mode 100644 index b177f17..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/fast/lists/scrolled-marker-paint-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/fast/selectors/018-expected.png b/third_party/blink/web_tests/platform/fuchsia/fast/selectors/018-expected.png deleted file mode 100644 index 2c1c277..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/fast/selectors/018-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/fast/table/border-collapsing/004-expected.png b/third_party/blink/web_tests/platform/fuchsia/fast/table/border-collapsing/004-expected.png deleted file mode 100644 index 678d2c4..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/fast/table/border-collapsing/004-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/fast/text/international/001-expected.png b/third_party/blink/web_tests/platform/fuchsia/fast/text/international/001-expected.png deleted file mode 100644 index 07cc1d3..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/fast/text/international/001-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/fast/text/international/003-expected.png b/third_party/blink/web_tests/platform/fuchsia/fast/text/international/003-expected.png deleted file mode 100644 index a04ecdee..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/fast/text/international/003-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/fast/text/international/bidi-LDB-2-formatting-characters-expected.png b/third_party/blink/web_tests/platform/fuchsia/fast/text/international/bidi-LDB-2-formatting-characters-expected.png deleted file mode 100644 index 772c849..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/fast/text/international/bidi-LDB-2-formatting-characters-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/fast/text/stroking-decorations-expected.png b/third_party/blink/web_tests/platform/fuchsia/fast/text/stroking-decorations-expected.png deleted file mode 100644 index b265fcb3..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/fast/text/stroking-decorations-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/paint/invalidation/selection/selected-replaced-expected.png b/third_party/blink/web_tests/platform/fuchsia/paint/invalidation/selection/selected-replaced-expected.png deleted file mode 100644 index 11009a3..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/paint/invalidation/selection/selected-replaced-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/paint/invalidation/shadow-multiple-expected.png b/third_party/blink/web_tests/platform/fuchsia/paint/invalidation/shadow-multiple-expected.png deleted file mode 100644 index 127675da..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/paint/invalidation/shadow-multiple-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/tables/mozilla/bugs/bug2479-4-expected.png b/third_party/blink/web_tests/platform/fuchsia/tables/mozilla/bugs/bug2479-4-expected.png deleted file mode 100644 index 5c6ee300..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/tables/mozilla/bugs/bug2479-4-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/tables/mozilla/core/bloomberg-expected.png b/third_party/blink/web_tests/platform/fuchsia/tables/mozilla/core/bloomberg-expected.png deleted file mode 100644 index 953c918..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/tables/mozilla/core/bloomberg-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/tables/mozilla_expected_failures/bugs/bug1010-expected.png b/third_party/blink/web_tests/platform/fuchsia/tables/mozilla_expected_failures/bugs/bug1010-expected.png deleted file mode 100644 index 839c2a1..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/tables/mozilla_expected_failures/bugs/bug1010-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/tables/mozilla_expected_failures/bugs/bug1055-2-expected.png b/third_party/blink/web_tests/platform/fuchsia/tables/mozilla_expected_failures/bugs/bug1055-2-expected.png deleted file mode 100644 index 8ae4e04f..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/tables/mozilla_expected_failures/bugs/bug1055-2-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/tables/mozilla_expected_failures/bugs/bug2479-5-expected.png b/third_party/blink/web_tests/platform/fuchsia/tables/mozilla_expected_failures/bugs/bug2479-5-expected.png deleted file mode 100644 index 95eae29..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/tables/mozilla_expected_failures/bugs/bug2479-5-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/fuchsia/transforms/transformed-caret-expected.png b/third_party/blink/web_tests/platform/fuchsia/transforms/transformed-caret-expected.png deleted file mode 100644 index 6f79b58..0000000 --- a/third_party/blink/web_tests/platform/fuchsia/transforms/transformed-caret-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/resources/testdriver-vendor.js b/third_party/blink/web_tests/resources/testdriver-vendor.js index 95b584b..2dc45ac 100644 --- a/third_party/blink/web_tests/resources/testdriver-vendor.js +++ b/third_party/blink/web_tests/resources/testdriver-vendor.js
@@ -29,7 +29,6 @@ } var centerPoint = getInViewCenterPoint(rectangles[0]); - if ("elementsFromPoint" in document) { return document.elementsFromPoint(centerPoint[0], centerPoint[1]); } else if ("msElementsFromPoint" in document) { @@ -42,7 +41,7 @@ function inView(element) { var pointerInteractablePaintTree = getPointerInteractablePaintTree(element); - return pointerInteractablePaintTree.indexOf(element) !== -1; + return pointerInteractablePaintTree.indexOf(element) !== -1 || element.contains(pointerInteractablePaintTree[0]); } window.test_driver_internal.click = function(element, coords) {
diff --git a/third_party/blink/web_tests/virtual/blink-cors/external/wpt/fetch/README.txt b/third_party/blink/web_tests/virtual/blink-cors/external/wpt/fetch/README.txt deleted file mode 100644 index 19936c1..0000000 --- a/third_party/blink/web_tests/virtual/blink-cors/external/wpt/fetch/README.txt +++ /dev/null
@@ -1 +0,0 @@ -This directory is for testing Blink CORS implementation.
diff --git a/third_party/blink/web_tests/virtual/blink-cors/external/wpt/http/README.txt b/third_party/blink/web_tests/virtual/blink-cors/external/wpt/http/README.txt deleted file mode 100644 index 19936c1..0000000 --- a/third_party/blink/web_tests/virtual/blink-cors/external/wpt/http/README.txt +++ /dev/null
@@ -1 +0,0 @@ -This directory is for testing Blink CORS implementation.
diff --git a/third_party/blink/web_tests/virtual/blink-cors/external/wpt/referrer-policy/README.txt b/third_party/blink/web_tests/virtual/blink-cors/external/wpt/referrer-policy/README.txt deleted file mode 100644 index 19936c1..0000000 --- a/third_party/blink/web_tests/virtual/blink-cors/external/wpt/referrer-policy/README.txt +++ /dev/null
@@ -1 +0,0 @@ -This directory is for testing Blink CORS implementation.
diff --git a/third_party/blink/web_tests/virtual/blink-cors/external/wpt/service-workers/README.txt b/third_party/blink/web_tests/virtual/blink-cors/external/wpt/service-workers/README.txt deleted file mode 100644 index 19936c1..0000000 --- a/third_party/blink/web_tests/virtual/blink-cors/external/wpt/service-workers/README.txt +++ /dev/null
@@ -1 +0,0 @@ -This directory is for testing Blink CORS implementation.
diff --git a/third_party/blink/web_tests/virtual/blink-cors/external/wpt/service-workers/service-worker/fetch-request-xhr.https-expected.txt b/third_party/blink/web_tests/virtual/blink-cors/external/wpt/service-workers/service-worker/fetch-request-xhr.https-expected.txt deleted file mode 100644 index 44c6a05..0000000 --- a/third_party/blink/web_tests/virtual/blink-cors/external/wpt/service-workers/service-worker/fetch-request-xhr.https-expected.txt +++ /dev/null
@@ -1,16 +0,0 @@ -This is a testharness.js-based test. -PASS initialize global state -FAIL event.request has the expected headers for same-origin GET. promise_test: Unhandled rejection with value: object "Error: assert_array_equals: event.request has the expected headers for same-origin GET. lengths differ, expected 1 got 3" -FAIL event.request has the expected headers for same-origin POST. promise_test: Unhandled rejection with value: object "Error: assert_array_equals: event.request has the expected headers for same-origin POST. lengths differ, expected 2 got 5" -FAIL event.request has the expected headers for cross-origin GET. promise_test: Unhandled rejection with value: object "Error: assert_array_equals: event.request has the expected headers for cross-origin GET. lengths differ, expected 1 got 3" -FAIL event.request has the expected headers for cross-origin POST. promise_test: Unhandled rejection with value: object "Error: assert_array_equals: event.request has the expected headers for cross-origin POST. lengths differ, expected 2 got 5" -PASS FetchEvent#request.body contains XHR request data (string) -PASS FetchEvent#request.body contains XHR request data (blob) -PASS FetchEvent#request.method is set to XHR method -PASS XHR using OPTIONS method -PASS XHR with form data -PASS XHR with mode/credentials set -PASS XHR to data URL -PASS restore global state -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/virtual/blink-cors/external/wpt/xhr/README.txt b/third_party/blink/web_tests/virtual/blink-cors/external/wpt/xhr/README.txt deleted file mode 100644 index 19936c1..0000000 --- a/third_party/blink/web_tests/virtual/blink-cors/external/wpt/xhr/README.txt +++ /dev/null
@@ -1 +0,0 @@ -This directory is for testing Blink CORS implementation.
diff --git a/third_party/blink/web_tests/virtual/blink-cors/http/tests/fetch/README.txt b/third_party/blink/web_tests/virtual/blink-cors/http/tests/fetch/README.txt deleted file mode 100644 index 19936c1..0000000 --- a/third_party/blink/web_tests/virtual/blink-cors/http/tests/fetch/README.txt +++ /dev/null
@@ -1 +0,0 @@ -This directory is for testing Blink CORS implementation.
diff --git a/third_party/blink/web_tests/virtual/blink-cors/http/tests/navigation/README.txt b/third_party/blink/web_tests/virtual/blink-cors/http/tests/navigation/README.txt deleted file mode 100644 index 19936c1..0000000 --- a/third_party/blink/web_tests/virtual/blink-cors/http/tests/navigation/README.txt +++ /dev/null
@@ -1 +0,0 @@ -This directory is for testing Blink CORS implementation.
diff --git a/third_party/blink/web_tests/virtual/blink-cors/http/tests/security/README.txt b/third_party/blink/web_tests/virtual/blink-cors/http/tests/security/README.txt deleted file mode 100644 index 19936c1..0000000 --- a/third_party/blink/web_tests/virtual/blink-cors/http/tests/security/README.txt +++ /dev/null
@@ -1 +0,0 @@ -This directory is for testing Blink CORS implementation.
diff --git a/third_party/blink/web_tests/virtual/blink-cors/http/tests/security/frameNavigation/xss-DENIED-top-navigation-without-user-gesture-expected.txt b/third_party/blink/web_tests/virtual/blink-cors/http/tests/security/frameNavigation/xss-DENIED-top-navigation-without-user-gesture-expected.txt deleted file mode 100644 index 96c842b..0000000 --- a/third_party/blink/web_tests/virtual/blink-cors/http/tests/security/frameNavigation/xss-DENIED-top-navigation-without-user-gesture-expected.txt +++ /dev/null
@@ -1,8 +0,0 @@ -CONSOLE ERROR: line 8: Unsafe JavaScript attempt to initiate navigation for frame with origin 'http://127.0.0.1:8000' from frame with URL 'http://localhost:8000/security/frameNavigation/resources/iframe-that-performs-top-navigation-without-user-gesture.html'. The frame attempting navigation is targeting its top-level window, but is neither same-origin with its target nor has it received a user gesture. See https://www.chromestatus.com/features/5851021045661696. - - - --------- -Frame: '<!--framePath //<!--frame0-->-->' --------- -The navigation should fail. This text should be visible.
diff --git a/third_party/blink/web_tests/virtual/blink-cors/http/tests/xmlhttprequest/README.txt b/third_party/blink/web_tests/virtual/blink-cors/http/tests/xmlhttprequest/README.txt deleted file mode 100644 index 19936c1..0000000 --- a/third_party/blink/web_tests/virtual/blink-cors/http/tests/xmlhttprequest/README.txt +++ /dev/null
@@ -1 +0,0 @@ -This directory is for testing Blink CORS implementation.
diff --git a/third_party/blink/web_tests/virtual/blink-cors/http/tests/xmlhttprequest/cross-origin-unsupported-url-expected.txt b/third_party/blink/web_tests/virtual/blink-cors/http/tests/xmlhttprequest/cross-origin-unsupported-url-expected.txt deleted file mode 100644 index a18432e1..0000000 --- a/third_party/blink/web_tests/virtual/blink-cors/http/tests/xmlhttprequest/cross-origin-unsupported-url-expected.txt +++ /dev/null
@@ -1,28 +0,0 @@ -CONSOLE WARNING: line 8: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/. -CONSOLE ERROR: line 13: Access to XMLHttpRequest at 'mailto:foo@bar.com' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, https. -CONSOLE ERROR: line 13: Access to XMLHttpRequest at 'mailto:foo@bar.com' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, https. -CONSOLE ERROR: line 13: Access to XMLHttpRequest at 'localhost:8080/' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, https. -CONSOLE ERROR: line 13: Access to XMLHttpRequest at 'localhost:8080/' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, https. -CONSOLE ERROR: line 13: Access to XMLHttpRequest at 'tel:1234' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, https. -CONSOLE ERROR: line 13: Access to XMLHttpRequest at 'tel:1234' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, https. -CONSOLE ERROR: line 29: Access to XMLHttpRequest at 'mailto:foo@bar.com' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, https. -CONSOLE ERROR: line 29: Access to XMLHttpRequest at 'mailto:foo@bar.com' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, https. -CONSOLE ERROR: line 29: Access to XMLHttpRequest at 'localhost:8080/' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, https. -CONSOLE ERROR: line 29: Access to XMLHttpRequest at 'localhost:8080/' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, https. -CONSOLE ERROR: line 29: Access to XMLHttpRequest at 'tel:1234' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, https. -CONSOLE ERROR: line 29: Access to XMLHttpRequest at 'tel:1234' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, https. -This is a testharness.js-based test. -PASS sync test for url=mailto:foo@bar.com, contentType=undefined -PASS sync test for url=mailto:foo@bar.com, contentType=application/json -PASS async test for url=mailto:foo@bar.com, contentType=undefined -PASS async test for url=mailto:foo@bar.com, contentType=application/json -PASS sync test for url=localhost:8080/, contentType=undefined -PASS sync test for url=localhost:8080/, contentType=application/json -PASS async test for url=localhost:8080/, contentType=undefined -PASS async test for url=localhost:8080/, contentType=application/json -PASS sync test for url=tel:1234, contentType=undefined -PASS sync test for url=tel:1234, contentType=application/json -PASS async test for url=tel:1234, contentType=undefined -PASS async test for url=tel:1234, contentType=application/json -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/virtual/blink-cors/http/tests/xmlhttprequest/workers/cross-origin-unsupported-url-expected.txt b/third_party/blink/web_tests/virtual/blink-cors/http/tests/xmlhttprequest/workers/cross-origin-unsupported-url-expected.txt deleted file mode 100644 index 086a854..0000000 --- a/third_party/blink/web_tests/virtual/blink-cors/http/tests/xmlhttprequest/workers/cross-origin-unsupported-url-expected.txt +++ /dev/null
@@ -1,27 +0,0 @@ -CONSOLE ERROR: line 13: Access to XMLHttpRequest at 'mailto:foo@bar.com' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, https. -CONSOLE ERROR: line 13: Access to XMLHttpRequest at 'mailto:foo@bar.com' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, https. -CONSOLE ERROR: line 13: Access to XMLHttpRequest at 'localhost:8080/' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, https. -CONSOLE ERROR: line 13: Access to XMLHttpRequest at 'localhost:8080/' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, https. -CONSOLE ERROR: line 13: Access to XMLHttpRequest at 'tel:1234' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, https. -CONSOLE ERROR: line 13: Access to XMLHttpRequest at 'tel:1234' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, https. -CONSOLE ERROR: line 29: Access to XMLHttpRequest at 'mailto:foo@bar.com' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, https. -CONSOLE ERROR: line 29: Access to XMLHttpRequest at 'mailto:foo@bar.com' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, https. -CONSOLE ERROR: line 29: Access to XMLHttpRequest at 'localhost:8080/' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, https. -CONSOLE ERROR: line 29: Access to XMLHttpRequest at 'localhost:8080/' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, https. -CONSOLE ERROR: line 29: Access to XMLHttpRequest at 'tel:1234' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, https. -CONSOLE ERROR: line 29: Access to XMLHttpRequest at 'tel:1234' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, https. -This is a testharness.js-based test. -PASS sync test for url=mailto:foo@bar.com, contentType=undefined -PASS sync test for url=mailto:foo@bar.com, contentType=application/json -PASS async test for url=mailto:foo@bar.com, contentType=undefined -PASS async test for url=mailto:foo@bar.com, contentType=application/json -PASS sync test for url=localhost:8080/, contentType=undefined -PASS sync test for url=localhost:8080/, contentType=application/json -PASS async test for url=localhost:8080/, contentType=undefined -PASS async test for url=localhost:8080/, contentType=application/json -PASS sync test for url=tel:1234, contentType=undefined -PASS sync test for url=tel:1234, contentType=application/json -PASS async test for url=tel:1234, contentType=undefined -PASS async test for url=tel:1234, contentType=application/json -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/webgpu/buffer_mapping.html b/third_party/blink/web_tests/webgpu/buffer_mapping.html new file mode 100644 index 0000000..54b91745c --- /dev/null +++ b/third_party/blink/web_tests/webgpu/buffer_mapping.html
@@ -0,0 +1,131 @@ +<!DOCTYPE html> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script> +promise_test(async t => { + + const adapter = await navigator.gpu.requestAdapter(); + const device = await adapter.requestDevice(); + const queue = device.getQueue(); + + // Check expected length and zero-initialization. + function checkMapWriteResult(arrayBuffer, expectedSize) { + assert_equals(arrayBuffer.byteLength, expectedSize); + const view = new Uint8Array(arrayBuffer); + for (let i = 0; i < view.length; ++i) { + assert_equals(view[i], 0); + } + } + + // Copy and MapRead data to check buffer contents + async function expectContents(buffer, expected) { + const size = expected.byteLength; + + const readback = device.createBuffer({ + size, + usage: GPUBufferUsage.TRANSFER_DST | GPUBufferUsage.MAP_READ, + }); + + const commandEncoder = device.createCommandEncoder({}); + commandEncoder.copyBufferToBuffer(buffer, 0, readback, 0, size); + queue.submit([commandEncoder.finish()]); + + const actual = new Uint8Array(await readback.mapReadAsync()); + assert_equals(actual.byteLength, size); + + // Cast the expected contents as a byte array. + const expectedView = new Uint8Array(expected.buffer, expected.byteOffset, expected.byteLength); + + for (let i = 0; i < size; ++i) { + assert_equals(actual[i], expectedView[i]); + } + } + + { + // Test simple MapWrite. + const buffer = device.createBuffer({ + size: 12, + usage: GPUBufferUsage.TRANSFER_SRC | GPUBufferUsage.MAP_WRITE, + }); + + const arrayBuffer = await buffer.mapWriteAsync(); + checkMapWriteResult(arrayBuffer, 12); + + const view = new Uint32Array(arrayBuffer); + view[1] = 7; + buffer.unmap(); + + // Array buffer should be detached. + assert_equals(arrayBuffer.byteLength, 0); + assert_equals(view.byteLength, 0); + + await expectContents(buffer, new Uint32Array([0, 7, 0])); + } + + { + // Test large MapWrite + const size = 512 * 1024; + + const buffer = device.createBuffer({ + size, + usage: GPUBufferUsage.TRANSFER_SRC | GPUBufferUsage.MAP_WRITE, + }); + + const arrayBuffer = await buffer.mapWriteAsync(); + checkMapWriteResult(arrayBuffer, size); + + const view = new Uint32Array(arrayBuffer); + assert_equals(view.byteLength, size); + for (let i = 0; i < view.length; ++i) { + view[i] = i; + } + const expected = view.slice(); + buffer.unmap(); + + // Array buffer should be detached. + assert_equals(arrayBuffer.byteLength, 0); + assert_equals(view.byteLength, 0); + + await expectContents(buffer, expected); + } + + { + // Test simple MapRead + const buffer = device.createBuffer({ + size: 12, + usage: GPUBufferUsage.TRANSFER_DST | GPUBufferUsage.MAP_READ, + }); + + buffer.setSubData(8, new Uint32Array([3])); + + // TODO(enga): This should check the other values are zero, but we don't have + // lazy zero-initialization yet. + const actual = new Uint32Array(await buffer.mapReadAsync()); + assert_equals(actual[2], 3); + } + + { + // Test large MapRead + const size = 512 * 1024; + + const buffer = device.createBuffer({ + size, + usage: GPUBufferUsage.TRANSFER_DST | GPUBufferUsage.MAP_READ, + }); + + const data = new Uint32Array(new ArrayBuffer(size)); + for (let i = 0; i < data.length; ++i) { + data[i] = i; + } + buffer.setSubData(0, data); + + const actual = new Uint32Array(await buffer.mapReadAsync()); + assert_equals(data.length, actual.length); + for (let i = 0; i < data.length; ++i) { + assert_equals(data[i], actual[i]); + } + + } + +}, "Test WebGPU buffer mapping"); +</script>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 0ae1738..c34a9e0 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -128232,6 +128232,12 @@ </histogram> <histogram name="Sync.NonReflectionUpdateFreshnessPossiblySkewed" units="ms"> + <obsolete> + Deprecated as of 05/2019 because it recorded freshness only up to 1hr and + most samples were thus out of bounds. Replaced by + Sync.NonReflectionUpdateFreshnessPossiblySkewed2 which records freshness up + to 7 days. + </obsolete> <owner>mastiz@chromium.org</owner> <owner>melandory@chromium.org</owner> <summary> @@ -128243,6 +128249,18 @@ </summary> </histogram> +<histogram name="Sync.NonReflectionUpdateFreshnessPossiblySkewed2" units="ms"> + <owner>mastiz@chromium.org</owner> + <owner>melandory@chromium.org</owner> + <summary> + Freshness of the sync data per received sync entity update, excluding + reflections. The time represents the clock difference from the model being + modified (usually on another device) until the change is processing by this + instance of the browser. The time is capped at 1 week. Beware of potential + clock skew due to two clients being involved. + </summary> +</histogram> + <histogram name="Sync.PageRevisitBookmarksDuration" units="ms" expires_after="2018-02-21"> <obsolete>
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py index 5a7c3d1..9ca9b42 100755 --- a/tools/perf/core/perf_data_generator.py +++ b/tools/perf/core/perf_data_generator.py
@@ -413,17 +413,13 @@ { 'isolate': 'performance_test_suite', 'extra_args': [ - # TODO(crbug.com/612455): Enable ref builds once can pass both - # --browser=exact (used by this bot to have it run Monochrome6432) - # and --browser=reference together. - #'--run-ref-build', + '--run-ref-build', '--test-shard-map-filename=android-pixel2-perf_map.json', ], 'num_shards': 35 } ], 'platform': 'android-chrome', - 'browser': 'bin/monochrome_64_32_bundle', 'dimension': { 'pool': 'chrome.tests.perf', 'os': 'Android',
diff --git a/ui/aura/BUILD.gn b/ui/aura/BUILD.gn index f201984..e296dc2 100644 --- a/ui/aura/BUILD.gn +++ b/ui/aura/BUILD.gn
@@ -126,7 +126,6 @@ "//ui/gfx/geometry", "//ui/gl", "//ui/platform_window", - "//ui/platform_window/mojo", "//ui/platform_window/stub", ]
diff --git a/ui/base/ime/win/tsf_text_store.cc b/ui/base/ime/win/tsf_text_store.cc index faf3fb3..ba41c24c 100644 --- a/ui/base/ime/win/tsf_text_store.cc +++ b/ui/base/ime/win/tsf_text_store.cc
@@ -856,6 +856,7 @@ if (SUCCEEDED( context_composition->EnumCompositions(&enum_composition_view))) { Microsoft::WRL::ComPtr<ITfCompositionView> composition_view; + bool has_composition = false; if (enum_composition_view->Next(1, &composition_view, nullptr) == S_OK) { Microsoft::WRL::ComPtr<ITfRange> range; if (SUCCEEDED(composition_view->GetRange(&range))) { @@ -864,14 +865,21 @@ LONG start = 0; LONG length = 0; if (SUCCEEDED(range_acp->GetExtent(&start, &length))) { - composition_start_ = start; - has_composition_range_ = true; - composition_range_.set_start(start); - composition_range_.set_end(start + length); + // We should only consider it as a valid composition if the + // composition range is not collapsed (length > 0). + if (length > 0) { + has_composition = true; + composition_start_ = start; + has_composition_range_ = true; + composition_range_.set_start(start); + composition_range_.set_end(start + length); + } } } } - } else { + } + + if (!has_composition) { composition_start_ = selection_.start(); if (has_composition_range_) { has_composition_range_ = false;
diff --git a/ui/base/models/tree_node_model.h b/ui/base/models/tree_node_model.h index fac7dfbc..98e352c 100644 --- a/ui/base/models/tree_node_model.h +++ b/ui/base/models/tree_node_model.h
@@ -108,14 +108,6 @@ return ptr; } - // Removes the given node. Prefer to remove by index if you know it to avoid - // the search for the node to remove. - std::unique_ptr<NodeType> Remove(NodeType* node) { - int i = GetIndexOf(node); - DCHECK_NE(-1, i); - return Remove(i); - } - // Removes all the children from this node. void DeleteAll() { children_.clear(); }
diff --git a/ui/base/models/tree_node_model_unittest.cc b/ui/base/models/tree_node_model_unittest.cc index f5df948..cec60d4 100644 --- a/ui/base/models/tree_node_model_unittest.cc +++ b/ui/base/models/tree_node_model_unittest.cc
@@ -272,11 +272,11 @@ EXPECT_EQ(2, root.child_count()); EXPECT_EQ(child1->parent(), child2->parent()); - std::unique_ptr<TestNode> c2 = root.Remove(child2); + std::unique_ptr<TestNode> c2 = root.Remove(1); EXPECT_EQ(1, root.child_count()); EXPECT_EQ(NULL, child2->parent()); - std::unique_ptr<TestNode> c1 = root.Remove(child1); + std::unique_ptr<TestNode> c1 = root.Remove(0); EXPECT_EQ(0, root.child_count()); }
diff --git a/ui/ozone/demo/software_renderer.cc b/ui/ozone/demo/software_renderer.cc index 44e6330..92b799f7 100644 --- a/ui/ozone/demo/software_renderer.cc +++ b/ui/ozone/demo/software_renderer.cc
@@ -67,8 +67,8 @@ if (vsync_provider_) { vsync_provider_->GetVSyncParameters( - base::Bind(&SoftwareRenderer::UpdateVSyncParameters, - weak_ptr_factory_.GetWeakPtr())); + base::BindOnce(&SoftwareRenderer::UpdateVSyncParameters, + weak_ptr_factory_.GetWeakPtr())); } timer_.Start(FROM_HERE, vsync_period_, this, &SoftwareRenderer::RenderFrame);
diff --git a/ui/ozone/demo/surfaceless_gl_renderer.cc b/ui/ozone/demo/surfaceless_gl_renderer.cc index 342179a..b7b24c7d 100644 --- a/ui/ozone/demo/surfaceless_gl_renderer.cc +++ b/ui/ozone/demo/surfaceless_gl_renderer.cc
@@ -266,9 +266,9 @@ back_buffer_ ^= 1; gl_surface_->SwapBuffersAsync( - base::Bind(&SurfacelessGlRenderer::PostRenderFrameTask, - weak_ptr_factory_.GetWeakPtr()), - base::Bind([](const gfx::PresentationFeedback&) {})); + base::BindOnce(&SurfacelessGlRenderer::PostRenderFrameTask, + weak_ptr_factory_.GetWeakPtr()), + base::DoNothing()); } void SurfacelessGlRenderer::PostRenderFrameTask(
diff --git a/ui/ozone/platform/drm/gpu/proxy_helpers.h b/ui/ozone/platform/drm/gpu/proxy_helpers.h index d25933b..b037713 100644 --- a/ui/ozone/platform/drm/gpu/proxy_helpers.h +++ b/ui/ozone/platform/drm/gpu/proxy_helpers.h
@@ -19,14 +19,6 @@ template <typename... Args> void PostAsyncTask( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, - const base::Callback<void(Args...)>& callback, - Args... args) { - task_runner->PostTask(FROM_HERE, base::BindOnce(callback, args...)); -} - -template <typename... Args> -void PostAsyncTaskOnce( - const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, base::OnceCallback<void(Args...)> callback, Args... args) { auto closure = base::BindOnce(std::move(callback), std::move(args)...); @@ -59,7 +51,7 @@ template <typename... Args> base::OnceCallback<void(Args...)> CreateSafeOnceCallback( base::OnceCallback<void(Args...)> callback) { - return base::BindOnce(&internal::PostAsyncTaskOnce<Args...>, + return base::BindOnce(&internal::PostAsyncTask<Args...>, base::ThreadTaskRunnerHandle::Get(), std::move(callback)); }
diff --git a/ui/ozone/platform/drm/host/drm_device_connector.cc b/ui/ozone/platform/drm/host/drm_device_connector.cc index d207dbe1..3ab9667 100644 --- a/ui/ozone/platform/drm/host/drm_device_connector.cc +++ b/ui/ozone/platform/drm/host/drm_device_connector.cc
@@ -52,7 +52,7 @@ int host_id, scoped_refptr<base::SingleThreadTaskRunner> ui_runner, scoped_refptr<base::SingleThreadTaskRunner> send_runner, - const base::RepeatingCallback<void(IPC::Message*)>& send_callback) { + base::RepeatingCallback<void(IPC::Message*)> send_callback) { NOTREACHED(); }
diff --git a/ui/ozone/platform/drm/host/drm_device_connector.h b/ui/ozone/platform/drm/host/drm_device_connector.h index b915d3b..851208b4 100644 --- a/ui/ozone/platform/drm/host/drm_device_connector.h +++ b/ui/ozone/platform/drm/host/drm_device_connector.h
@@ -35,8 +35,7 @@ int host_id, scoped_refptr<base::SingleThreadTaskRunner> ui_runner, scoped_refptr<base::SingleThreadTaskRunner> send_runner, - const base::RepeatingCallback<void(IPC::Message*)>& send_callback) - override; + base::RepeatingCallback<void(IPC::Message*)> send_callback) override; void OnChannelDestroyed(int host_id) override; void OnMessageReceived(const IPC::Message& message) override; void OnGpuServiceLaunched(
diff --git a/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc b/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc index 4e353fb4..408a5cd 100644 --- a/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc +++ b/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc
@@ -31,7 +31,7 @@ class CursorIPC : public DrmCursorProxy { public: CursorIPC(scoped_refptr<base::SingleThreadTaskRunner> send_runner, - const base::Callback<void(IPC::Message*)>& send_callback); + base::RepeatingCallback<void(IPC::Message*)> send_callback); ~CursorIPC() override; // DrmCursorProxy implementation. @@ -47,14 +47,14 @@ void Send(IPC::Message* message); scoped_refptr<base::SingleThreadTaskRunner> send_runner_; - base::Callback<void(IPC::Message*)> send_callback_; + base::RepeatingCallback<void(IPC::Message*)> send_callback_; DISALLOW_COPY_AND_ASSIGN(CursorIPC); }; CursorIPC::CursorIPC(scoped_refptr<base::SingleThreadTaskRunner> send_runner, - const base::Callback<void(IPC::Message*)>& send_callback) - : send_runner_(send_runner), send_callback_(send_callback) {} + base::RepeatingCallback<void(IPC::Message*)> send_callback) + : send_runner_(send_runner), send_callback_(std::move(send_callback)) {} CursorIPC::~CursorIPC() {} @@ -132,7 +132,7 @@ int host_id, scoped_refptr<base::SingleThreadTaskRunner> ui_runner, scoped_refptr<base::SingleThreadTaskRunner> send_runner, - const base::Callback<void(IPC::Message*)>& send_callback) { + base::RepeatingCallback<void(IPC::Message*)> send_callback) { // If there was a task runner set during construction, prefer using that. if (!ui_runner_) { ui_runner_ = std::move(ui_runner); @@ -143,7 +143,7 @@ "host_id", host_id); host_id_ = host_id; send_runner_ = std::move(send_runner); - send_callback_ = send_callback; + send_callback_ = std::move(send_callback); for (GpuThreadObserver& observer : gpu_thread_observers_) observer.OnGpuProcessLaunched(); @@ -167,7 +167,6 @@ for (GpuThreadObserver& observer : gpu_thread_observers_) observer.OnGpuThreadRetired(); } - } void DrmGpuPlatformSupportHost::OnMessageReceived(const IPC::Message& message) {
diff --git a/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h b/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h index 6d9746e..caef027 100644 --- a/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h +++ b/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h
@@ -39,7 +39,7 @@ int host_id, scoped_refptr<base::SingleThreadTaskRunner> ui_runner, scoped_refptr<base::SingleThreadTaskRunner> send_runner, - const base::Callback<void(IPC::Message*)>& send_callback) override; + base::RepeatingCallback<void(IPC::Message*)> send_callback) override; void OnChannelDestroyed(int host_id) override; void OnGpuServiceLaunched( scoped_refptr<base::SingleThreadTaskRunner> ui_runner, @@ -124,7 +124,7 @@ scoped_refptr<base::SingleThreadTaskRunner> ui_runner_; scoped_refptr<base::SingleThreadTaskRunner> send_runner_; - base::Callback<void(IPC::Message*)> send_callback_; + base::RepeatingCallback<void(IPC::Message*)> send_callback_; DrmDisplayHostManager* display_manager_; // Not owned. DrmOverlayManagerHost* overlay_manager_; // Not owned. @@ -139,4 +139,4 @@ } // namespace ui -#endif // UI_OZONE_GPU_DRM_GPU_PLATFORM_SUPPORT_HOST_H_ +#endif // UI_OZONE_PLATFORM_DRM_HOST_DRM_GPU_PLATFORM_SUPPORT_HOST_H_
diff --git a/ui/ozone/platform/drm/ozone_platform_gbm.cc b/ui/ozone/platform/drm/ozone_platform_gbm.cc index 5431d13c..c35ea84 100644 --- a/ui/ozone/platform/drm/ozone_platform_gbm.cc +++ b/ui/ozone/platform/drm/ozone_platform_gbm.cc
@@ -112,13 +112,13 @@ return; registry->AddInterface<ozone::mojom::DeviceCursor>( - base::Bind(&OzonePlatformGbm::CreateDeviceCursorBinding, - weak_factory_.GetWeakPtr()), + base::BindRepeating(&OzonePlatformGbm::CreateDeviceCursorBinding, + weak_factory_.GetWeakPtr()), base::ThreadTaskRunnerHandle::Get()); registry->AddInterface<ozone::mojom::DrmDevice>( - base::Bind(&OzonePlatformGbm::CreateDrmDeviceBinding, - weak_factory_.GetWeakPtr()), + base::BindRepeating(&OzonePlatformGbm::CreateDrmDeviceBinding, + weak_factory_.GetWeakPtr()), base::ThreadTaskRunnerHandle::Get()); }
diff --git a/ui/ozone/platform/scenic/scenic_gpu_host.cc b/ui/ozone/platform/scenic/scenic_gpu_host.cc index 7863ef19..6f8ecf5 100644 --- a/ui/ozone/platform/scenic/scenic_gpu_host.cc +++ b/ui/ozone/platform/scenic/scenic_gpu_host.cc
@@ -72,7 +72,7 @@ int host_id, scoped_refptr<base::SingleThreadTaskRunner> ui_runner, scoped_refptr<base::SingleThreadTaskRunner> send_runner, - const base::RepeatingCallback<void(IPC::Message*)>& send_callback) { + base::RepeatingCallback<void(IPC::Message*)> send_callback) { NOTREACHED(); }
diff --git a/ui/ozone/platform/scenic/scenic_gpu_host.h b/ui/ozone/platform/scenic/scenic_gpu_host.h index 26bc402..8fb2bef63 100644 --- a/ui/ozone/platform/scenic/scenic_gpu_host.h +++ b/ui/ozone/platform/scenic/scenic_gpu_host.h
@@ -45,8 +45,7 @@ int host_id, scoped_refptr<base::SingleThreadTaskRunner> ui_runner, scoped_refptr<base::SingleThreadTaskRunner> send_runner, - const base::RepeatingCallback<void(IPC::Message*)>& send_callback) - override; + base::RepeatingCallback<void(IPC::Message*)> send_callback) override; void OnChannelDestroyed(int host_id) override; void OnMessageReceived(const IPC::Message& message) override; void OnGpuServiceLaunched(
diff --git a/ui/ozone/platform/wayland/host/wayland_buffer_manager_connector.cc b/ui/ozone/platform/wayland/host/wayland_buffer_manager_connector.cc index 8d8a8db..de99b68 100644 --- a/ui/ozone/platform/wayland/host/wayland_buffer_manager_connector.cc +++ b/ui/ozone/platform/wayland/host/wayland_buffer_manager_connector.cc
@@ -41,7 +41,7 @@ int host_id, scoped_refptr<base::SingleThreadTaskRunner> ui_runner, scoped_refptr<base::SingleThreadTaskRunner> send_runner, - const base::RepeatingCallback<void(IPC::Message*)>& send_callback) {} + base::RepeatingCallback<void(IPC::Message*)> send_callback) {} void WaylandBufferManagerConnector::OnChannelDestroyed(int host_id) { buffer_manager_->OnChannelDestroyed();
diff --git a/ui/ozone/platform/wayland/host/wayland_buffer_manager_connector.h b/ui/ozone/platform/wayland/host/wayland_buffer_manager_connector.h index 29c91d7..e4fc4fc 100644 --- a/ui/ozone/platform/wayland/host/wayland_buffer_manager_connector.h +++ b/ui/ozone/platform/wayland/host/wayland_buffer_manager_connector.h
@@ -27,8 +27,7 @@ int host_id, scoped_refptr<base::SingleThreadTaskRunner> ui_runner, scoped_refptr<base::SingleThreadTaskRunner> send_runner, - const base::RepeatingCallback<void(IPC::Message*)>& send_callback) - override; + base::RepeatingCallback<void(IPC::Message*)> send_callback) override; void OnChannelDestroyed(int host_id) override; void OnMessageReceived(const IPC::Message& message) override; void OnGpuServiceLaunched(
diff --git a/ui/ozone/public/gpu_platform_support_host.cc b/ui/ozone/public/gpu_platform_support_host.cc index 0881946..e52608e 100644 --- a/ui/ozone/public/gpu_platform_support_host.cc +++ b/ui/ozone/public/gpu_platform_support_host.cc
@@ -19,7 +19,7 @@ int host_id, scoped_refptr<base::SingleThreadTaskRunner> ui_runner, scoped_refptr<base::SingleThreadTaskRunner> send_runner, - const base::Callback<void(IPC::Message*)>& send_callback) override {} + base::RepeatingCallback<void(IPC::Message*)> send_callback) override {} void OnChannelDestroyed(int host_id) override {} void OnMessageReceived(const IPC::Message&) override {}
diff --git a/ui/ozone/public/gpu_platform_support_host.h b/ui/ozone/public/gpu_platform_support_host.h index 2f81d97..9694d730 100644 --- a/ui/ozone/public/gpu_platform_support_host.h +++ b/ui/ozone/public/gpu_platform_support_host.h
@@ -42,7 +42,7 @@ int host_id, scoped_refptr<base::SingleThreadTaskRunner> ui_runner, scoped_refptr<base::SingleThreadTaskRunner> send_runner, - const base::Callback<void(IPC::Message*)>& sender) = 0; + base::RepeatingCallback<void(IPC::Message*)> sender) = 0; // Called when the GPU process is destroyed. // This is called from browser UI thread.
diff --git a/ui/ozone/public/ozone_gpu_test_helper.cc b/ui/ozone/public/ozone_gpu_test_helper.cc index ca78153..575f17d 100644 --- a/ui/ozone/public/ozone_gpu_test_helper.cc +++ b/ui/ozone/public/ozone_gpu_test_helper.cc
@@ -88,7 +88,7 @@ ui::OzonePlatform::GetInstance() ->GetGpuPlatformSupportHost() ->OnGpuProcessLaunched(kGpuProcessHostId, ui_task_runner_, - gpu_io_task_runner_, sender); + gpu_io_task_runner_, std::move(sender)); } private:
diff --git a/ui/ozone/public/surface_factory_ozone.h b/ui/ozone/public/surface_factory_ozone.h index ba04a36..7512ad7 100644 --- a/ui/ozone/public/surface_factory_ozone.h +++ b/ui/ozone/public/surface_factory_ozone.h
@@ -149,7 +149,7 @@ // be used instead of the NativePixmap that would have been produced by the // standard, implementation-specific NativePixmapHandle import mechanism. using GetProtectedNativePixmapCallback = - base::Callback<scoped_refptr<gfx::NativePixmap>( + base::RepeatingCallback<scoped_refptr<gfx::NativePixmap>( const gfx::NativePixmapHandle& handle)>; // Called by an external service to set the GetProtectedNativePixmapCallback, // to be used by the implementation when importing NativePixmapHandles.
diff --git a/ui/platform_window/mojo/BUILD.gn b/ui/platform_window/mojo/BUILD.gn deleted file mode 100644 index b42cf4f..0000000 --- a/ui/platform_window/mojo/BUILD.gn +++ /dev/null
@@ -1,39 +0,0 @@ -# Copyright 2015 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//build/config/jumbo.gni") -import("//mojo/public/tools/bindings/mojom.gni") - -# This target does NOT depend on skia. One can depend on this target to avoid -# picking up a dependency on skia. -jumbo_component("mojo") { - output_name = "mojo_ime_lib" - - public_deps = [ - "//ui/base/ime", - ] - deps = [ - ":interfaces", - "//base", - "//ui/platform_window", - ] - - defines = [ "MOJO_IME_IMPLEMENTATION" ] - - sources = [ - "ime_type_converters.cc", - "ime_type_converters.h", - "mojo_ime_export.h", - ] -} - -mojom("interfaces") { - sources = [ - "text_input_state.mojom", - ] - - public_deps = [ - "//ui/base/ime/mojo", - ] -}
diff --git a/ui/platform_window/mojo/DEPS b/ui/platform_window/mojo/DEPS deleted file mode 100644 index 1d56d19d..0000000 --- a/ui/platform_window/mojo/DEPS +++ /dev/null
@@ -1,5 +0,0 @@ -include_rules = [ - "+ui/base/ime/text_input_flags.h", - "+ui/base/ime/text_input_type.h", - "+ui/platform_window/text_input_state.h", -]
diff --git a/ui/platform_window/mojo/OWNERS b/ui/platform_window/mojo/OWNERS deleted file mode 100644 index 5d54957..0000000 --- a/ui/platform_window/mojo/OWNERS +++ /dev/null
@@ -1,5 +0,0 @@ -per-file *_type_converter*.*=set noparent -per-file *_type_converter*.*=file://ipc/SECURITY_OWNERS - -per-file *.mojom=set noparent -per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/ui/platform_window/mojo/ime_type_converters.cc b/ui/platform_window/mojo/ime_type_converters.cc deleted file mode 100644 index 9435045..0000000 --- a/ui/platform_window/mojo/ime_type_converters.cc +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/platform_window/mojo/ime_type_converters.h" - -#include <stdint.h> - -#include "base/macros.h" - -namespace mojo { - -#define TEXT_INPUT_TYPE_ASSERT(NAME) \ - static_assert(static_cast<int32_t>(ui::mojom::TextInputType::NAME) == \ - static_cast<int32_t>(ui::TEXT_INPUT_TYPE_##NAME), \ - "TEXT_INPUT_TYPE must match") -TEXT_INPUT_TYPE_ASSERT(NONE); -TEXT_INPUT_TYPE_ASSERT(TEXT); -TEXT_INPUT_TYPE_ASSERT(PASSWORD); -TEXT_INPUT_TYPE_ASSERT(SEARCH); -TEXT_INPUT_TYPE_ASSERT(EMAIL); -TEXT_INPUT_TYPE_ASSERT(NUMBER); -TEXT_INPUT_TYPE_ASSERT(TELEPHONE); -TEXT_INPUT_TYPE_ASSERT(URL); -TEXT_INPUT_TYPE_ASSERT(DATE); -TEXT_INPUT_TYPE_ASSERT(DATE_TIME); -TEXT_INPUT_TYPE_ASSERT(DATE_TIME_LOCAL); -TEXT_INPUT_TYPE_ASSERT(MONTH); -TEXT_INPUT_TYPE_ASSERT(TIME); -TEXT_INPUT_TYPE_ASSERT(WEEK); -TEXT_INPUT_TYPE_ASSERT(TEXT_AREA); -TEXT_INPUT_TYPE_ASSERT(CONTENT_EDITABLE); -TEXT_INPUT_TYPE_ASSERT(DATE_TIME_FIELD); -TEXT_INPUT_TYPE_ASSERT(MAX); - -#define TEXT_INPUT_FLAG_ASSERT(NAME) \ - static_assert(static_cast<int32_t>(ui::mojom::TextInputFlag::NAME) == \ - static_cast<int32_t>(ui::TEXT_INPUT_FLAG_##NAME), \ - "TEXT_INPUT_FLAG must match") -TEXT_INPUT_FLAG_ASSERT(NONE); -TEXT_INPUT_FLAG_ASSERT(AUTOCOMPLETE_ON); -TEXT_INPUT_FLAG_ASSERT(AUTOCOMPLETE_OFF); -TEXT_INPUT_FLAG_ASSERT(AUTOCORRECT_ON); -TEXT_INPUT_FLAG_ASSERT(AUTOCORRECT_OFF); -TEXT_INPUT_FLAG_ASSERT(SPELLCHECK_ON); -TEXT_INPUT_FLAG_ASSERT(SPELLCHECK_OFF); -TEXT_INPUT_FLAG_ASSERT(AUTOCAPITALIZE_NONE); -TEXT_INPUT_FLAG_ASSERT(AUTOCAPITALIZE_CHARACTERS); -TEXT_INPUT_FLAG_ASSERT(AUTOCAPITALIZE_WORDS); -TEXT_INPUT_FLAG_ASSERT(AUTOCAPITALIZE_SENTENCES); - -// static -ui::TextInputState -TypeConverter<ui::TextInputState, ui::mojom::TextInputStatePtr>::Convert( - const ui::mojom::TextInputStatePtr& input) { - return ui::TextInputState( - ConvertTo<ui::TextInputType>(input->type), input->flags, - input->text.has_value() ? input->text.value() : std::string(), - input->selection_start, input->selection_end, input->composition_start, - input->composition_end, input->can_compose_inline); -} - -} // namespace mojo
diff --git a/ui/platform_window/mojo/ime_type_converters.h b/ui/platform_window/mojo/ime_type_converters.h deleted file mode 100644 index a55125d..0000000 --- a/ui/platform_window/mojo/ime_type_converters.h +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_PLATFORM_WINDOW_MOJO_IME_TYPE_CONVERTERS_H_ -#define UI_PLATFORM_WINDOW_MOJO_IME_TYPE_CONVERTERS_H_ - -#include "ui/base/ime/ime_text_span.h" -#include "ui/platform_window/mojo/mojo_ime_export.h" -#include "ui/platform_window/mojo/text_input_state.mojom.h" -#include "ui/platform_window/text_input_state.h" - -namespace mojo { - -template <> -struct MOJO_IME_EXPORT - TypeConverter<ui::TextInputState, ui::mojom::TextInputStatePtr> { - static ui::TextInputState Convert(const ui::mojom::TextInputStatePtr& input); -}; - -} // namespace mojo - -#endif // UI_PLATFORM_WINDOW_MOJO_IME_TYPE_CONVERTERS_H_
diff --git a/ui/platform_window/mojo/mojo_ime_export.h b/ui/platform_window/mojo/mojo_ime_export.h deleted file mode 100644 index e616f25..0000000 --- a/ui/platform_window/mojo/mojo_ime_export.h +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_PLATFORM_WINDOW_MOJO_MOJO_IME_EXPORT_H_ -#define UI_PLATFORM_WINDOW_MOJO_MOJO_IME_EXPORT_H_ - -#if defined(COMPONENT_BUILD) - -#if defined(WIN32) - -#if defined(MOJO_IME_IMPLEMENTATION) -#define MOJO_IME_EXPORT __declspec(dllexport) -#else -#define MOJO_IME_EXPORT __declspec(dllimport) -#endif - -#else // !defined(WIN32) - -#if defined(MOJO_IME_IMPLEMENTATION) -#define MOJO_IME_EXPORT __attribute__((visibility("default"))) -#else -#define MOJO_IME_EXPORT -#endif - -#endif // defined(WIN32) - -#else // !defined(COMPONENT_BUILD) -#define MOJO_IME_EXPORT -#endif - -#endif // UI_PLATFORM_WINDOW_MOJO_MOJO_IME_EXPORT_H_
diff --git a/ui/platform_window/mojo/text_input_state.mojom b/ui/platform_window/mojo/text_input_state.mojom deleted file mode 100644 index 21767a5..0000000 --- a/ui/platform_window/mojo/text_input_state.mojom +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -module ui.mojom; - -import "ui/base/ime/mojo/ime_types.mojom"; - -// Text input info which is based on blink::WebTextInputInfo. -struct TextInputState { - // The type of input field. - TextInputType type; - - // The flags of the input field (autocorrect, autocomplete, etc.). - int32 flags; - - // The value of the input field. - string? text; - - // The cursor position of the current selection start, or the caret position - // if nothing is selected. - int32 selection_start; - - // The cursor position of the current selection end, or the caret position - // if nothing is selected. - int32 selection_end; - - // The start position of the current composition, or -1 if there is none. - int32 composition_start; - - // The end position of the current composition, or -1 if there is none. - int32 composition_end; - - // Whether or not inline composition can be performed for the current input. - bool can_compose_inline; -};
diff --git a/ui/surface/transport_dib.h b/ui/surface/transport_dib.h index 759c23b..ff29b86 100644 --- a/ui/surface/transport_dib.h +++ b/ui/surface/transport_dib.h
@@ -14,10 +14,6 @@ #include "build/build_config.h" #include "ui/surface/surface_export.h" -#if defined(OS_WIN) -#include <windows.h> -#endif - class SkCanvas; // -----------------------------------------------------------------------------