diff --git a/DEPS b/DEPS index d6db4f49..324ead4 100644 --- a/DEPS +++ b/DEPS
@@ -40,11 +40,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': '222958d5cbd46af9e643eb77186efceb176dd95d', + 'skia_revision': 'eb64b9b201d04f9f72b37a05e86d459e6a91d974', # 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': '8e20b3fc2b78eb04d9315af65547bb2f0bcf18fc', + 'v8_revision': '46fa3ae618ba90f52b9a3a1312b10d4b47cf01b1', # 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. @@ -52,7 +52,7 @@ # 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': '12b0b399aaa22d0f5df0784997753f74ecdb8e36', + 'angle_revision': '579d8c7dfcfaeb44fc7a650cd151539d87eedcd2', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. @@ -64,7 +64,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': 'e17011dc1f5d046dc60c3347b89c0aad7d674dff', + 'pdfium_revision': '9a25eded6f4afe3f4815a00b34b31d3a0fbadb69', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -96,7 +96,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': '76def89024c63d7d3fd777cd82b92ae7dc8bc781', + 'catapult_revision': 'a857866b281fbbf9ecab0b0fd7f4393f4be91587', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other.
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 6d09321..895e6932 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -215,6 +215,8 @@ r"^base[\\\/]process[\\\/]process_linux\.cc$", r"^base[\\\/]process[\\\/]process_metrics_linux\.cc$", r"^chrome[\\\/]browser[\\\/]chromeos[\\\/]boot_times_recorder\.cc$", + r"^chrome[\\\/]browser[\\\/]extensions[\\\/]" + + r"chrome_test_extension_loader.cc$", r"^chrome[\\\/]browser[\\\/]lifetime[\\\/]application_lifetime\.cc$", r"^components[\\\/]crash[\\\/]app[\\\/]breakpad_mac\.mm$", r"^content[\\\/]shell[\\\/]browser[\\\/]layout_test[\\\/]" +
diff --git a/android_webview/browser/net/aw_cookie_store_wrapper.cc b/android_webview/browser/net/aw_cookie_store_wrapper.cc index 17423fd..5a92c05b 100644 --- a/android_webview/browser/net/aw_cookie_store_wrapper.cc +++ b/android_webview/browser/net/aw_cookie_store_wrapper.cc
@@ -104,9 +104,9 @@ const GURL& url, const std::string& cookie_line, const net::CookieOptions& options, - const net::CookieStore::SetCookiesCallback& callback) { + net::CookieStore::SetCookiesCallback callback) { GetCookieStore()->SetCookieWithOptionsAsync(url, cookie_line, options, - callback); + std::move(callback)); } void SetCookieWithDetailsAsyncOnCookieThread( @@ -122,76 +122,79 @@ bool http_only, net::CookieSameSite same_site, net::CookiePriority priority, - const net::CookieStore::SetCookiesCallback& callback) { + net::CookieStore::SetCookiesCallback callback) { GetCookieStore()->SetCookieWithDetailsAsync( url, name, value, domain, path, creation_time, expiration_time, - last_access_time, secure, http_only, same_site, priority, callback); + last_access_time, secure, http_only, same_site, priority, + std::move(callback)); } void SetCanonicalCookieAsyncOnCookieThread( std::unique_ptr<net::CanonicalCookie> cookie, bool secure_source, bool modify_http_only, - const net::CookieStore::SetCookiesCallback& callback) { - GetCookieStore()->SetCanonicalCookieAsync(std::move(cookie), secure_source, - modify_http_only, callback); + net::CookieStore::SetCookiesCallback callback) { + GetCookieStore()->SetCanonicalCookieAsync( + std::move(cookie), secure_source, modify_http_only, std::move(callback)); } void GetCookiesWithOptionsAsyncOnCookieThread( const GURL& url, const net::CookieOptions& options, - const net::CookieStore::GetCookiesCallback& callback) { - GetCookieStore()->GetCookiesWithOptionsAsync(url, options, callback); + net::CookieStore::GetCookiesCallback callback) { + GetCookieStore()->GetCookiesWithOptionsAsync(url, options, + std::move(callback)); } void GetCookieListWithOptionsAsyncOnCookieThread( const GURL& url, const net::CookieOptions& options, - const net::CookieStore::GetCookieListCallback& callback) { - GetCookieStore()->GetCookieListWithOptionsAsync(url, options, callback); + net::CookieStore::GetCookieListCallback callback) { + GetCookieStore()->GetCookieListWithOptionsAsync(url, options, + std::move(callback)); } void GetAllCookiesAsyncOnCookieThread( - const net::CookieStore::GetCookieListCallback& callback) { - GetCookieStore()->GetAllCookiesAsync(callback); + net::CookieStore::GetCookieListCallback callback) { + GetCookieStore()->GetAllCookiesAsync(std::move(callback)); } void DeleteCookieAsyncOnCookieThread(const GURL& url, const std::string& cookie_name, - const base::Closure& callback) { - GetCookieStore()->DeleteCookieAsync(url, cookie_name, callback); + base::OnceClosure callback) { + GetCookieStore()->DeleteCookieAsync(url, cookie_name, std::move(callback)); } void DeleteCanonicalCookieAsyncOnCookieThread( const net::CanonicalCookie& cookie, - const net::CookieStore::DeleteCallback& callback) { - GetCookieStore()->DeleteCanonicalCookieAsync(cookie, callback); + net::CookieStore::DeleteCallback callback) { + GetCookieStore()->DeleteCanonicalCookieAsync(cookie, std::move(callback)); } void DeleteAllCreatedBetweenAsyncOnCookieThread( const base::Time& delete_begin, const base::Time& delete_end, - const net::CookieStore::DeleteCallback& callback) { + net::CookieStore::DeleteCallback callback) { GetCookieStore()->DeleteAllCreatedBetweenAsync(delete_begin, delete_end, - callback); + std::move(callback)); } void DeleteAllCreatedBetweenWithPredicateAsyncOnCookieThread( const base::Time& delete_begin, const base::Time& delete_end, const net::CookieStore::CookiePredicate& predicate, - const net::CookieStore::DeleteCallback& callback) { + net::CookieStore::DeleteCallback callback) { GetCookieStore()->DeleteAllCreatedBetweenWithPredicateAsync( - delete_begin, delete_end, predicate, callback); + delete_begin, delete_end, predicate, std::move(callback)); } void DeleteSessionCookiesAsyncOnCookieThread( - const net::CookieStore::DeleteCallback& callback) { - GetCookieStore()->DeleteSessionCookiesAsync(callback); + net::CookieStore::DeleteCallback callback) { + GetCookieStore()->DeleteSessionCookiesAsync(std::move(callback)); } -void FlushStoreOnCookieThread(const base::Closure& callback) { - GetCookieStore()->FlushStore(callback); +void FlushStoreOnCookieThread(base::OnceClosure callback) { + GetCookieStore()->FlushStore(std::move(callback)); } void SetForceKeepSessionStateOnCookieThread() { @@ -210,11 +213,11 @@ const GURL& url, const std::string& cookie_line, const net::CookieOptions& options, - const net::CookieStore::SetCookiesCallback& callback) { + net::CookieStore::SetCookiesCallback callback) { DCHECK(client_task_runner_->RunsTasksInCurrentSequence()); - PostTaskToCookieStoreTaskRunner( - base::Bind(&SetCookieWithOptionsAsyncOnCookieThread, url, cookie_line, - options, CreateWrappedCallback<bool>(callback))); + PostTaskToCookieStoreTaskRunner(base::BindOnce( + &SetCookieWithOptionsAsyncOnCookieThread, url, cookie_line, options, + CreateWrappedCallback<bool>(std::move(callback)))); } void AwCookieStoreWrapper::SetCookieWithDetailsAsync( @@ -230,105 +233,103 @@ bool http_only, net::CookieSameSite same_site, net::CookiePriority priority, - const SetCookiesCallback& callback) { + SetCookiesCallback callback) { DCHECK(client_task_runner_->RunsTasksInCurrentSequence()); - PostTaskToCookieStoreTaskRunner( - base::Bind(&SetCookieWithDetailsAsyncOnCookieThread, url, name, value, - domain, path, creation_time, expiration_time, last_access_time, - secure, http_only, same_site, priority, - CreateWrappedCallback<bool>(callback))); + PostTaskToCookieStoreTaskRunner(base::BindOnce( + &SetCookieWithDetailsAsyncOnCookieThread, url, name, value, domain, path, + creation_time, expiration_time, last_access_time, secure, http_only, + same_site, priority, CreateWrappedCallback<bool>(std::move(callback)))); } void AwCookieStoreWrapper::SetCanonicalCookieAsync( std::unique_ptr<net::CanonicalCookie> cookie, bool secure_source, bool modify_http_only, - const SetCookiesCallback& callback) { + SetCookiesCallback callback) { DCHECK(client_task_runner_->RunsTasksOnCurrentThread()); PostTaskToCookieStoreTaskRunner(base::BindOnce( &SetCanonicalCookieAsyncOnCookieThread, std::move(cookie), secure_source, - modify_http_only, CreateWrappedCallback<bool>(callback))); + modify_http_only, CreateWrappedCallback<bool>(std::move(callback)))); } void AwCookieStoreWrapper::GetCookiesWithOptionsAsync( const GURL& url, const net::CookieOptions& options, - const GetCookiesCallback& callback) { + GetCookiesCallback callback) { DCHECK(client_task_runner_->RunsTasksInCurrentSequence()); - PostTaskToCookieStoreTaskRunner( - base::Bind(&GetCookiesWithOptionsAsyncOnCookieThread, url, options, - CreateWrappedCallback<const std::string&>(callback))); + PostTaskToCookieStoreTaskRunner(base::BindOnce( + &GetCookiesWithOptionsAsyncOnCookieThread, url, options, + CreateWrappedCallback<const std::string&>(std::move(callback)))); } void AwCookieStoreWrapper::GetCookieListWithOptionsAsync( const GURL& url, const net::CookieOptions& options, - const GetCookieListCallback& callback) { + GetCookieListCallback callback) { DCHECK(client_task_runner_->RunsTasksInCurrentSequence()); - PostTaskToCookieStoreTaskRunner( - base::Bind(&GetCookieListWithOptionsAsyncOnCookieThread, url, options, - CreateWrappedCallback<const net::CookieList&>(callback))); + PostTaskToCookieStoreTaskRunner(base::BindOnce( + &GetCookieListWithOptionsAsyncOnCookieThread, url, options, + CreateWrappedCallback<const net::CookieList&>(std::move(callback)))); } -void AwCookieStoreWrapper::GetAllCookiesAsync( - const GetCookieListCallback& callback) { +void AwCookieStoreWrapper::GetAllCookiesAsync(GetCookieListCallback callback) { DCHECK(client_task_runner_->RunsTasksInCurrentSequence()); - PostTaskToCookieStoreTaskRunner( - base::Bind(&GetAllCookiesAsyncOnCookieThread, - CreateWrappedCallback<const net::CookieList&>(callback))); + PostTaskToCookieStoreTaskRunner(base::BindOnce( + &GetAllCookiesAsyncOnCookieThread, + CreateWrappedCallback<const net::CookieList&>(std::move(callback)))); } void AwCookieStoreWrapper::DeleteCookieAsync(const GURL& url, const std::string& cookie_name, - const base::Closure& callback) { + base::OnceClosure callback) { DCHECK(client_task_runner_->RunsTasksInCurrentSequence()); PostTaskToCookieStoreTaskRunner( - base::Bind(&DeleteCookieAsyncOnCookieThread, url, cookie_name, - CreateWrappedClosureCallback(callback))); + base::BindOnce(&DeleteCookieAsyncOnCookieThread, url, cookie_name, + CreateWrappedClosureCallback(std::move(callback)))); } void AwCookieStoreWrapper::DeleteCanonicalCookieAsync( const net::CanonicalCookie& cookie, - const DeleteCallback& callback) { + DeleteCallback callback) { DCHECK(client_task_runner_->RunsTasksInCurrentSequence()); PostTaskToCookieStoreTaskRunner( - base::Bind(&DeleteCanonicalCookieAsyncOnCookieThread, cookie, - CreateWrappedCallback<int>(callback))); + base::BindOnce(&DeleteCanonicalCookieAsyncOnCookieThread, cookie, + CreateWrappedCallback<int>(std::move(callback)))); } void AwCookieStoreWrapper::DeleteAllCreatedBetweenAsync( const base::Time& delete_begin, const base::Time& delete_end, - const DeleteCallback& callback) { + DeleteCallback callback) { DCHECK(client_task_runner_->RunsTasksInCurrentSequence()); - PostTaskToCookieStoreTaskRunner( - base::Bind(&DeleteAllCreatedBetweenAsyncOnCookieThread, delete_begin, - delete_end, CreateWrappedCallback<int>(callback))); + PostTaskToCookieStoreTaskRunner(base::BindOnce( + &DeleteAllCreatedBetweenAsyncOnCookieThread, delete_begin, delete_end, + CreateWrappedCallback<int>(std::move(callback)))); } void AwCookieStoreWrapper::DeleteAllCreatedBetweenWithPredicateAsync( const base::Time& delete_begin, const base::Time& delete_end, const CookiePredicate& predicate, - const DeleteCallback& callback) { + DeleteCallback callback) { DCHECK(client_task_runner_->RunsTasksInCurrentSequence()); - PostTaskToCookieStoreTaskRunner(base::Bind( + PostTaskToCookieStoreTaskRunner(base::BindOnce( &DeleteAllCreatedBetweenWithPredicateAsyncOnCookieThread, delete_begin, - delete_end, predicate, CreateWrappedCallback<int>(callback))); + delete_end, predicate, CreateWrappedCallback<int>(std::move(callback)))); } -void AwCookieStoreWrapper::DeleteSessionCookiesAsync( - const DeleteCallback& callback) { +void AwCookieStoreWrapper::DeleteSessionCookiesAsync(DeleteCallback callback) { DCHECK(client_task_runner_->RunsTasksInCurrentSequence()); PostTaskToCookieStoreTaskRunner( - base::Bind(&DeleteSessionCookiesAsyncOnCookieThread, - CreateWrappedCallback<int>(callback))); + base::BindOnce(&DeleteSessionCookiesAsyncOnCookieThread, + CreateWrappedCallback<int>(std::move(callback)))); } -void AwCookieStoreWrapper::FlushStore(const base::Closure& callback) { +void AwCookieStoreWrapper::FlushStore(base::OnceClosure callback) { DCHECK(client_task_runner_->RunsTasksInCurrentSequence()); - PostTaskToCookieStoreTaskRunner(base::Bind( - &FlushStoreOnCookieThread, CreateWrappedClosureCallback(callback))); + PostTaskToCookieStoreTaskRunner( + base::BindOnce(&FlushStoreOnCookieThread, + CreateWrappedClosureCallback(std::move(callback)))); } void AwCookieStoreWrapper::SetForceKeepSessionState() { @@ -358,19 +359,20 @@ return GetCookieStore()->IsEphemeral(); } -base::Closure AwCookieStoreWrapper::CreateWrappedClosureCallback( - const base::Closure& callback) { +base::OnceClosure AwCookieStoreWrapper::CreateWrappedClosureCallback( + base::OnceClosure callback) { if (callback.is_null()) return callback; - return base::Bind(base::IgnoreResult(&base::TaskRunner::PostTask), - client_task_runner_, FROM_HERE, - base::Bind(&AwCookieStoreWrapper::RunClosureCallback, - weak_factory_.GetWeakPtr(), callback)); + return base::BindOnce( + base::IgnoreResult(&base::TaskRunner::PostTask), client_task_runner_, + FROM_HERE, + base::BindOnce(&AwCookieStoreWrapper::RunClosureCallback, + weak_factory_.GetWeakPtr(), std::move(callback))); } -void AwCookieStoreWrapper::RunClosureCallback(const base::Closure& callback) { +void AwCookieStoreWrapper::RunClosureCallback(base::OnceClosure callback) { DCHECK(client_task_runner_->RunsTasksInCurrentSequence()); - callback.Run(); + std::move(callback).Run(); } } // namespace android_webview
diff --git a/android_webview/browser/net/aw_cookie_store_wrapper.h b/android_webview/browser/net/aw_cookie_store_wrapper.h index 860f81a4a..6094b1c 100644 --- a/android_webview/browser/net/aw_cookie_store_wrapper.h +++ b/android_webview/browser/net/aw_cookie_store_wrapper.h
@@ -44,7 +44,7 @@ void SetCookieWithOptionsAsync(const GURL& url, const std::string& cookie_line, const net::CookieOptions& options, - const SetCookiesCallback& callback) override; + SetCookiesCallback callback) override; void SetCookieWithDetailsAsync(const GURL& url, const std::string& name, const std::string& value, @@ -57,34 +57,33 @@ bool http_only, net::CookieSameSite same_site, net::CookiePriority priority, - const SetCookiesCallback& callback) override; + SetCookiesCallback callback) override; void SetCanonicalCookieAsync(std::unique_ptr<net::CanonicalCookie> cookie, bool secure_source, bool modify_http_only, - const SetCookiesCallback& callback) override; + SetCookiesCallback callback) override; void GetCookiesWithOptionsAsync(const GURL& url, const net::CookieOptions& options, - const GetCookiesCallback& callback) override; - void GetCookieListWithOptionsAsync( - const GURL& url, - const net::CookieOptions& options, - const GetCookieListCallback& callback) override; - void GetAllCookiesAsync(const GetCookieListCallback& callback) override; + GetCookiesCallback callback) override; + void GetCookieListWithOptionsAsync(const GURL& url, + const net::CookieOptions& options, + GetCookieListCallback callback) override; + void GetAllCookiesAsync(GetCookieListCallback callback) override; void DeleteCookieAsync(const GURL& url, const std::string& cookie_name, - const base::Closure& callback) override; + base::OnceClosure callback) override; void DeleteCanonicalCookieAsync(const net::CanonicalCookie& cookie, - const DeleteCallback& callback) override; + DeleteCallback callback) override; void DeleteAllCreatedBetweenAsync(const base::Time& delete_begin, const base::Time& delete_end, - const DeleteCallback& callback) override; + DeleteCallback callback) override; void DeleteAllCreatedBetweenWithPredicateAsync( const base::Time& delete_begin, const base::Time& delete_end, const CookiePredicate& predicate, - const DeleteCallback& callback) override; - void DeleteSessionCookiesAsync(const DeleteCallback& callback) override; - void FlushStore(const base::Closure& callback) override; + DeleteCallback callback) override; + void DeleteSessionCookiesAsync(DeleteCallback callback) override; + void FlushStore(base::OnceClosure callback) override; void SetForceKeepSessionState() override; std::unique_ptr<CookieChangedSubscription> AddCallbackForCookie( const GURL& url, @@ -93,7 +92,7 @@ bool IsEphemeral() override; private: - // Used by CreateWrappedCallback below. Takes an arugment of Type and posts + // Used by CreateWrappedCallback below. Takes an argument of Type and posts // a task to |task_runner| to invoke |callback| with that argument. If // |weak_cookie_store| is deleted before the task is run, the task will not // be run. @@ -101,33 +100,35 @@ static void RunCallbackOnClientThread( base::TaskRunner* task_runner, base::WeakPtr<AwCookieStoreWrapper> weak_cookie_store, - base::Callback<void(Type)> callback, + base::OnceCallback<void(Type)> callback, Type argument) { task_runner->PostTask( FROM_HERE, - base::Bind(&AwCookieStoreWrapper::RunClosureCallback, weak_cookie_store, - base::Bind(callback, argument))); + base::BindOnce(&AwCookieStoreWrapper::RunClosureCallback, + weak_cookie_store, + base::BindOnce(std::move(callback), argument))); } // Returns a base::Callback that takes an argument of Type and posts a task to // the |client_task_runner_| to invoke |callback| with that argument. template <class Type> - base::Callback<void(Type)> CreateWrappedCallback( - base::Callback<void(Type)> callback) { + base::OnceCallback<void(Type)> CreateWrappedCallback( + base::OnceCallback<void(Type)> callback) { if (callback.is_null()) - return callback; - return base::Bind(&AwCookieStoreWrapper::RunCallbackOnClientThread<Type>, - base::RetainedRef(client_task_runner_), - weak_factory_.GetWeakPtr(), callback); + return std::move(callback); + return base::BindOnce( + &AwCookieStoreWrapper::RunCallbackOnClientThread<Type>, + base::RetainedRef(client_task_runner_), weak_factory_.GetWeakPtr(), + std::move(callback)); } - // Returns a base::Closure that posts a task to the |client_task_runner_| to - // invoke |callback|. - base::Closure CreateWrappedClosureCallback(const base::Closure& callback); + // Returns a base::OnceClosure that posts a task to the |client_task_runner_| + // to invoke |callback|. + base::OnceClosure CreateWrappedClosureCallback(base::OnceClosure callback); // Runs |callback|. Used to prevent callbacks from being invoked after the // AwCookieStoreWrapper has been destroyed. - void RunClosureCallback(const base::Closure& callback); + void RunClosureCallback(base::OnceClosure callback); scoped_refptr<base::SingleThreadTaskRunner> client_task_runner_;
diff --git a/ash/resources/vector_icons/BUILD.gn b/ash/resources/vector_icons/BUILD.gn index 262e896..e790938 100644 --- a/ash/resources/vector_icons/BUILD.gn +++ b/ash/resources/vector_icons/BUILD.gn
@@ -70,6 +70,8 @@ "palette_mode_laser_pointer.icon", "palette_mode_magnify.1x.icon", "palette_mode_magnify.icon", + "palette_mode_metalayer.1x.icon", + "palette_mode_metalayer.icon", "palette_tray_icon_capture_region.1x.icon", "palette_tray_icon_capture_region.icon", "palette_tray_icon_default.1x.icon", @@ -78,6 +80,8 @@ "palette_tray_icon_laser_pointer.icon", "palette_tray_icon_magnify.1x.icon", "palette_tray_icon_magnify.icon", + "palette_tray_icon_metalayer.1x.icon", + "palette_tray_icon_metalayer.icon", "shelf_keyboard.1x.icon", "shelf_keyboard.icon", "shelf_logout.1x.icon",
diff --git a/ash/resources/vector_icons/palette_mode_metalayer.1x.icon b/ash/resources/vector_icons/palette_mode_metalayer.1x.icon new file mode 100644 index 0000000..787ebf33 --- /dev/null +++ b/ash/resources/vector_icons/palette_mode_metalayer.1x.icon
@@ -0,0 +1,27 @@ +// 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. + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 16.79f, 7.9f, +CUBIC_TO, 17.38f, 7.9f, 17.86f, 7.42f, 17.86f, 6.83f, +CUBIC_TO, 17.86f, 6.24f, 17.38f, 5.77f, 16.79f, 5.77f, +CUBIC_TO, 16.2f, 5.77f, 15.72f, 6.24f, 15.72f, 6.83f, +CUBIC_TO, 15.72f, 7.42f, 16.2f, 7.9f, 16.79f, 7.9f, +MOVE_TO, 13.59f, 11.46f, +CUBIC_TO, 14.77f, 11.46f, 15.72f, 10.5f, 15.72f, 9.32f, +CUBIC_TO, 15.72f, 8.14f, 14.77f, 7.19f, 13.59f, 7.19f, +CUBIC_TO, 12.41f, 7.19f, 11.46f, 8.14f, 11.46f, 9.32f, +CUBIC_TO, 11.46f, 10.5f, 12.41f, 11.46f, 13.59f, 11.46f, +MOVE_TO, 13.59f, 17.14f, +CUBIC_TO, 14.96f, 17.14f, 16.08f, 16.03f, 16.08f, 14.66f, +CUBIC_TO, 16.08f, 13.28f, 14.96f, 12.17f, 13.59f, 12.17f, +CUBIC_TO, 12.21f, 12.17f, 11.1f, 13.28f, 11.1f, 14.66f, +CUBIC_TO, 11.1f, 16.03f, 12.21f, 17.14f, 13.59f, 17.14f, +MOVE_TO, 10.74f, 7.19f, +CUBIC_TO, 10.74f, 4.83f, 8.83f, 2.92f, 6.48f, 2.92f, +CUBIC_TO, 4.12f, 2.92f, 2.21f, 4.83f, 2.21f, 7.19f, +CUBIC_TO, 2.21f, 9.55f, 4.12f, 11.46f, 6.48f, 11.46f, +CUBIC_TO, 8.83f, 11.46f, 10.74f, 9.55f, 10.74f, 7.19f, +CLOSE, +END
diff --git a/ash/resources/vector_icons/palette_mode_metalayer.icon b/ash/resources/vector_icons/palette_mode_metalayer.icon new file mode 100644 index 0000000..3f9b3c8 --- /dev/null +++ b/ash/resources/vector_icons/palette_mode_metalayer.icon
@@ -0,0 +1,27 @@ +// 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. + +CANVAS_DIMENSIONS, 40, +MOVE_TO, 33.58f, 15.8f, +CUBIC_TO, 34.76f, 15.8f, 35.71f, 14.84f, 35.71f, 13.67f, +CUBIC_TO, 35.71f, 12.49f, 34.76f, 11.53f, 33.58f, 11.53f, +CUBIC_TO, 32.4f, 11.53f, 31.44f, 12.49f, 31.44f, 13.67f, +CUBIC_TO, 31.44f, 14.84f, 32.4f, 15.8f, 33.58f, 15.8f, +MOVE_TO, 27.18f, 22.91f, +CUBIC_TO, 29.53f, 22.91f, 31.44f, 21, 31.44f, 18.64f, +CUBIC_TO, 31.44f, 16.29f, 29.53f, 14.38f, 27.18f, 14.38f, +CUBIC_TO, 24.82f, 14.38f, 22.91f, 16.29f, 22.91f, 18.64f, +CUBIC_TO, 22.91f, 21, 24.82f, 22.91f, 27.18f, 22.91f, +MOVE_TO, 27.18f, 34.29f, +CUBIC_TO, 29.93f, 34.29f, 32.16f, 32.06f, 32.16f, 29.31f, +CUBIC_TO, 32.16f, 26.56f, 29.93f, 24.33f, 27.18f, 24.33f, +CUBIC_TO, 24.43f, 24.33f, 22.2f, 26.56f, 22.2f, 29.31f, +CUBIC_TO, 22.2f, 32.06f, 24.43f, 34.29f, 27.18f, 34.29f, +MOVE_TO, 21.49f, 14.38f, +CUBIC_TO, 21.49f, 9.66f, 17.67f, 5.84f, 12.96f, 5.84f, +CUBIC_TO, 8.24f, 5.84f, 4.42f, 9.66f, 4.42f, 14.38f, +CUBIC_TO, 4.42f, 19.09f, 8.24f, 22.91f, 12.96f, 22.91f, +CUBIC_TO, 17.67f, 22.91f, 21.49f, 19.09f, 21.49f, 14.38f, +CLOSE, +END \ No newline at end of file
diff --git a/ash/resources/vector_icons/palette_tray_icon_metalayer.1x.icon b/ash/resources/vector_icons/palette_tray_icon_metalayer.1x.icon new file mode 100644 index 0000000..2116990 --- /dev/null +++ b/ash/resources/vector_icons/palette_tray_icon_metalayer.1x.icon
@@ -0,0 +1,27 @@ +// 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. + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 13.43f, 6.32f, +CUBIC_TO, 13.9f, 6.32f, 14.28f, 5.94f, 14.28f, 5.47f, +CUBIC_TO, 14.28f, 5, 13.9f, 4.61f, 13.43f, 4.61f, +CUBIC_TO, 12.96f, 4.61f, 12.58f, 5, 12.58f, 5.47f, +CUBIC_TO, 12.58f, 5.94f, 12.96f, 6.32f, 13.43f, 6.32f, +MOVE_TO, 10.87f, 9.16f, +CUBIC_TO, 11.81f, 9.16f, 12.58f, 8.4f, 12.58f, 7.46f, +CUBIC_TO, 12.58f, 6.52f, 11.81f, 5.75f, 10.87f, 5.75f, +CUBIC_TO, 9.93f, 5.75f, 9.16f, 6.52f, 9.16f, 7.46f, +CUBIC_TO, 9.16f, 8.4f, 9.93f, 9.16f, 10.87f, 9.16f, +MOVE_TO, 10.87f, 13.72f, +CUBIC_TO, 11.97f, 13.72f, 12.86f, 12.82f, 12.86f, 11.72f, +CUBIC_TO, 12.86f, 10.62f, 11.97f, 9.73f, 10.87f, 9.73f, +CUBIC_TO, 9.77f, 9.73f, 8.88f, 10.62f, 8.88f, 11.72f, +CUBIC_TO, 8.88f, 12.82f, 9.77f, 13.72f, 10.87f, 13.72f, +MOVE_TO, 8.6f, 5.75f, +CUBIC_TO, 8.6f, 3.87f, 7.07f, 2.34f, 5.18f, 2.34f, +CUBIC_TO, 3.3f, 2.34f, 1.77f, 3.87f, 1.77f, 5.75f, +CUBIC_TO, 1.77f, 7.64f, 3.3f, 9.16f, 5.18f, 9.16f, +CUBIC_TO, 7.07f, 9.16f, 8.6f, 7.64f, 8.6f, 5.75f, +CLOSE, +END
diff --git a/ash/resources/vector_icons/palette_tray_icon_metalayer.icon b/ash/resources/vector_icons/palette_tray_icon_metalayer.icon new file mode 100644 index 0000000..326b4430 --- /dev/null +++ b/ash/resources/vector_icons/palette_tray_icon_metalayer.icon
@@ -0,0 +1,27 @@ +// 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. + +CANVAS_DIMENSIONS, 32, +MOVE_TO, 26.86f, 12.64f, +CUBIC_TO, 27.8f, 12.64f, 28.57f, 11.88f, 28.57f, 10.93f, +CUBIC_TO, 28.57f, 9.99f, 27.8f, 9.23f, 26.86f, 9.23f, +CUBIC_TO, 25.92f, 9.23f, 25.16f, 9.99f, 25.16f, 10.93f, +CUBIC_TO, 25.16f, 11.88f, 25.92f, 12.64f, 26.86f, 12.64f, +MOVE_TO, 21.74f, 18.33f, +CUBIC_TO, 23.63f, 18.33f, 25.16f, 16.8f, 25.16f, 14.92f, +CUBIC_TO, 25.16f, 13.03f, 23.63f, 11.5f, 21.74f, 11.5f, +CUBIC_TO, 19.86f, 11.5f, 18.33f, 13.03f, 18.33f, 14.92f, +CUBIC_TO, 18.33f, 16.8f, 19.86f, 18.33f, 21.74f, 18.33f, +MOVE_TO, 21.74f, 27.43f, +CUBIC_TO, 23.94f, 27.43f, 25.72f, 25.65f, 25.72f, 23.45f, +CUBIC_TO, 25.72f, 21.25f, 23.94f, 19.47f, 21.74f, 19.47f, +CUBIC_TO, 19.54f, 19.47f, 17.76f, 21.25f, 17.76f, 23.45f, +CUBIC_TO, 17.76f, 25.65f, 19.54f, 27.43f, 21.74f, 27.43f, +MOVE_TO, 17.19f, 11.5f, +CUBIC_TO, 17.19f, 7.73f, 14.13f, 4.68f, 10.36f, 4.68f, +CUBIC_TO, 6.59f, 4.68f, 3.54f, 7.73f, 3.54f, 11.5f, +CUBIC_TO, 3.54f, 15.27f, 6.59f, 18.33f, 10.36f, 18.33f, +CUBIC_TO, 14.13f, 18.33f, 17.19f, 15.27f, 17.19f, 11.5f, +CLOSE, +END
diff --git a/ash/shelf/voice_interaction_overlay.cc b/ash/shelf/voice_interaction_overlay.cc index 2160238..ad9447d 100644 --- a/ash/shelf/voice_interaction_overlay.cc +++ b/ash/shelf/voice_interaction_overlay.cc
@@ -381,7 +381,7 @@ IMMEDIATELY_ANIMATE_TO_NEW_TARGET); settings.SetTransitionDuration( base::TimeDelta::FromMilliseconds(kFullRetractDurationMs)); - settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN); + settings.SetTweenType(gfx::Tween::SLOW_OUT_LINEAR_IN); ripple_layer_->SetTransform(transform); @@ -405,7 +405,7 @@ IMMEDIATELY_ANIMATE_TO_NEW_TARGET); settings.SetTransitionDuration( base::TimeDelta::FromMilliseconds(kFullRetractDurationMs)); - settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN); + settings.SetTweenType(gfx::Tween::SLOW_OUT_LINEAR_IN); icon_layer_->SetTransform(transform); icon_layer_->SetOpacity(0); @@ -426,7 +426,7 @@ IMMEDIATELY_ANIMATE_TO_NEW_TARGET); settings.SetTransitionDuration( base::TimeDelta::FromMilliseconds(kFullRetractDurationMs)); - settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN); + settings.SetTweenType(gfx::Tween::SLOW_OUT_LINEAR_IN); background_layer_->SetTransform(transform); background_layer_->SetOpacity(0);
diff --git a/ash/system/palette/tools/metalayer_mode.cc b/ash/system/palette/tools/metalayer_mode.cc index ff3a8a7..3991aff9 100644 --- a/ash/system/palette/tools/metalayer_mode.cc +++ b/ash/system/palette/tools/metalayer_mode.cc
@@ -41,13 +41,11 @@ } const gfx::VectorIcon& MetalayerMode::GetActiveTrayIcon() const { - // TODO(kaznacheev) replace with the correct icon when it is available - return kPaletteTrayIconCaptureRegionIcon; + return kPaletteTrayIconMetalayerIcon; } const gfx::VectorIcon& MetalayerMode::GetPaletteIcon() const { - // TODO(kaznacheev) replace with the correct icon when it is available - return kPaletteActionCaptureRegionIcon; + return kPaletteModeMetalayerIcon; } views::View* MetalayerMode::CreateView() {
diff --git a/ash/test/ash_test_base.cc b/ash/test/ash_test_base.cc index 8237e27..468b17aa 100644 --- a/ash/test/ash_test_base.cc +++ b/ash/test/ash_test_base.cc
@@ -75,10 +75,11 @@ return aura::client::GetScreenPositionClient(window->GetRootWindow()); } - void DispatchKeyEventToIME(ui::EventTarget* target, - ui::KeyEvent* event) override { + ui::EventDispatchDetails DispatchKeyEventToIME(ui::EventTarget* target, + ui::KeyEvent* event) override { // In Ash environment, the key event will be processed by event rewriters // first. + return ui::EventDispatchDetails(); } private:
diff --git a/base/debug/stack_trace_fuchsia.cc b/base/debug/stack_trace_fuchsia.cc index 7b71488e..8a4b1fec 100644 --- a/base/debug/stack_trace_fuchsia.cc +++ b/base/debug/stack_trace_fuchsia.cc
@@ -38,71 +38,16 @@ return _URC_NO_REASON; } -constexpr uint64_t kExceptionKey = 0x424144u; // "BAD". -bool g_in_process_exception_handler_enabled; - -int SelfDumpFunc(void* arg) { - mx_handle_t exception_port = - static_cast<mx_handle_t>(reinterpret_cast<uintptr_t>(arg)); - - mx_exception_packet_t packet; - mx_status_t status = - mx_port_wait(exception_port, MX_TIME_INFINITE, &packet, sizeof(packet)); - if (status < 0) { - DLOG(ERROR) << "mx_port_wait failed: " << status; - return 1; - } - if (packet.hdr.key != kExceptionKey) { - DLOG(ERROR) << "unexpected crash key"; - return 1; - } - - LOG(ERROR) << "Process crashed."; - - // TODO(fuchsia): Log a stack. See https://crbug.com/706592. - - _exit(1); -} - -bool SetInProcessExceptionHandler() { - if (g_in_process_exception_handler_enabled) - return true; - - mx_status_t status; - mx_handle_t self_dump_port; - status = mx_port_create(0u, &self_dump_port); - if (status < 0) { - DLOG(ERROR) << "mx_port_create failed: " << status; - return false; - } - - // A thread to wait for and process internal exceptions. - thrd_t self_dump_thread; - void* self_dump_arg = - reinterpret_cast<void*>(static_cast<uintptr_t>(self_dump_port)); - int ret = thrd_create(&self_dump_thread, SelfDumpFunc, self_dump_arg); - if (ret != thrd_success) { - DLOG(ERROR) << "thrd_create failed: " << ret; - return false; - } - - status = mx_task_bind_exception_port(mx_process_self(), self_dump_port, - kExceptionKey, 0); - - if (status < 0) { - DLOG(ERROR) << "mx_task_bind_exception_port failed: " << status; - return false; - } - - g_in_process_exception_handler_enabled = true; - return true; -} - } // namespace // static bool EnableInProcessStackDumping() { - return SetInProcessExceptionHandler(); + // StackTrace works to capture the current stack (e.g. for diagnostics added + // to code), but for local capture and print of backtraces, we just let the + // system crashlogger take over. It handles printing out a nicely formatted + // backtrace with dso information, relative offsets, etc. that we can then + // filter with addr2line in the run script to get file/line info. + return true; } StackTrace::StackTrace(size_t count) : count_(0) {
diff --git a/base/test/android/javatests/src/org/chromium/base/test/util/CommandLineFlags.java b/base/test/android/javatests/src/org/chromium/base/test/util/CommandLineFlags.java index d5579e3..a140ff1 100644 --- a/base/test/android/javatests/src/org/chromium/base/test/util/CommandLineFlags.java +++ b/base/test/android/javatests/src/org/chromium/base/test/util/CommandLineFlags.java
@@ -7,6 +7,7 @@ import android.content.Context; import org.junit.Assert; +import org.junit.Rule; import org.chromium.base.BaseChromiumApplication; import org.chromium.base.CommandLine; @@ -19,6 +20,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Arrays; import java.util.HashSet; @@ -32,7 +34,24 @@ * so a derived class can add a command-line flag that a base class has removed (or vice versa). * Similarly, uses of these annotations on a test method will take precedence over uses on the * containing class. + * <p> + * These annonations may also be used on Junit4 Rule classes and on their base classes. Note, + * however that the annotation processor only looks at the declared type of the Rule, not its actual + * type, so in, for example: * + * <pre> + * @Rule + * TestRule mRule = new ChromeActivityTestRule(); + * </pre> + * + * will only look for CommandLineFlags annotations on TestRule, not for CommandLineFlags annotations + * on ChromeActivityTestRule. + * <p> + * In addition a rule may not remove flags added by an independently invoked rule, although it may + * remove flags added by its base classes. + * <p> + * Uses of these annotations on the test class or methods take precedence over uses on Rule classes. + * <p> * Note that this class should never be instantiated. */ public final class CommandLineFlags { @@ -81,12 +100,42 @@ } } - private static Set<String> getFlags(AnnotatedElement element) { + private static Set<String> getFlags(AnnotatedElement type) { + Set<String> rule_flags = new HashSet<>(); + updateFlagsForElement(type, rule_flags); + return rule_flags; + } + + private static void updateFlagsForElement(AnnotatedElement element, Set<String> flags) { + if (element instanceof Class<?>) { + // Get flags from rules within the class. + for (Field field : ((Class<?>) element).getFields()) { + if (field.isAnnotationPresent(Rule.class)) { + // The order in which fields are returned is undefined, so, for consistency, + // a rule must not remove a flag added by a different rule. Ensure this by + // initially getting the flags into a new set. + Set<String> rule_flags = getFlags(field.getType()); + flags.addAll(rule_flags); + } + } + for (Method method : ((Class<?>) element).getMethods()) { + if (method.isAnnotationPresent(Rule.class)) { + // The order in which methods are returned is undefined, so, for consistency, + // a rule must not remove a flag added by a different rule. Ensure this by + // initially getting the flags into a new set. + Set<String> rule_flags = getFlags(method.getReturnType()); + flags.addAll(rule_flags); + } + } + } + + // Add the flags from the parent. Override any flags defined by the rules. AnnotatedElement parent = (element instanceof Method) ? ((Method) element).getDeclaringClass() - : ((Class) element).getSuperclass(); - Set<String> flags = (parent == null) ? new HashSet<String>() : getFlags(parent); + : ((Class<?>) element).getSuperclass(); + if (parent != null) updateFlagsForElement(parent, flags); + // Flags on the element itself override all other flag sources. if (element.isAnnotationPresent(CommandLineFlags.Add.class)) { flags.addAll( Arrays.asList(element.getAnnotation(CommandLineFlags.Add.class).value())); @@ -104,8 +153,6 @@ } flags.removeAll(flagsToRemove); } - - return flags; } private CommandLineFlags() { @@ -129,18 +176,16 @@ * instructs to run the test with default command-line flags. * * Example: + * * @ParameterizedTest.Set(tests = { - * @ParameterizedTest(parameters = { - * @Parameter( - * tag = CommandLineFlags.Parameter.PARAMETER_TAG)}), - * @ParameterizedTest(parameters = { - * @Parameter( - * tag = CommandLineFlags.Parameter.PARAMETER_TAG, - * arguments = { - * @Parameter.Argument( - * name = CommandLineFlags.Parameter.ADD_ARG, - * stringArray = {'arg1', 'arg2'}) - * })})}) + * @ParameterizedTest(parameters = { + * @Parameter( tag = CommandLineFlags.Parameter.PARAMETER_TAG)}), + * @ParameterizedTest(parameters = { + * @Parameter( tag = CommandLineFlags.Parameter.PARAMETER_TAG, + * arguments = { + * @Parameter.Argument( name = CommandLineFlags.Parameter.ADD_ARG, + * stringArray = {'arg1', 'arg2'}) + * })})}) * * Note that because the entire instrumentation test process needs to be restarted to apply * modified command-line arguments, this annotation is handled by test_runner.py, not by
diff --git a/base/test/scoped_async_task_scheduler.h b/base/test/scoped_async_task_scheduler.h index c849f70..29a543f 100644 --- a/base/test/scoped_async_task_scheduler.h +++ b/base/test/scoped_async_task_scheduler.h
@@ -6,6 +6,7 @@ #define BASE_TEST_SCOPED_ASYNC_TASK_SCHEDULER_H_ #include "base/macros.h" +#include "base/task_scheduler/lazy_task_runner.h" namespace base { @@ -35,6 +36,10 @@ private: const TaskScheduler* task_scheduler_ = nullptr; + // Ensures destruction of lazy TaskRunners when this is destroyed. + internal::ScopedLazyTaskRunnerListForTesting + scoped_lazy_task_runner_list_for_testing_; + DISALLOW_COPY_AND_ASSIGN(ScopedAsyncTaskScheduler); };
diff --git a/build/fuchsia/test_runner.py b/build/fuchsia/test_runner.py index 168f513..63a3c581 100755 --- a/build/fuchsia/test_runner.py +++ b/build/fuchsia/test_runner.py
@@ -6,11 +6,11 @@ """Packages a user.bootfs for a Fuchsia QEMU image, pulling in the runtime dependencies of a test binary, and then uses QEMU from the Fuchsia SDK to run -it. Does not yet implement running on real hardware, or symbolization of -crashes.""" +it. Does not yet implement running on real hardware.""" import argparse import os +import re import subprocess import sys import tempfile @@ -198,7 +198,7 @@ def main(): parser = argparse.ArgumentParser() parser.add_argument('--dry-run', '-n', action='store_true', default=False, - help="Just print commands, don't execute them.") + help='Just print commands, don\'t execute them.') parser.add_argument('--output-directory', type=os.path.realpath, help=('Path to the directory in which build files are' @@ -240,17 +240,38 @@ if args.dry_run: print 'Run:', qemu_command else: + prefix = r'^.*> ' + bt_with_offset_re = re.compile(prefix + + 'bt#(\d+): pc 0x[0-9a-f]+ sp (0x[0-9a-f]+) \((\S+),(0x[0-9a-f]+)\)$') + bt_end_re = re.compile(prefix + 'bt#(\d+): end') qemu_popen = subprocess.Popen(qemu_command, stdout=subprocess.PIPE) + processed_lines = [] success = False - # TODO(scottmg): Pipe through magenta/scripts/symbolize too, once that's - # available in the SDK. while True: line = qemu_popen.stdout.readline() if not line: break + print line, if 'SUCCESS: all tests passed.' in line: success = True - print line, + if bt_end_re.match(line.strip()): + if processed_lines: + print '----- start symbolized stack' + for processed in processed_lines: + print processed + print '----- end symbolized stack' + processed_lines = [] + else: + m = bt_with_offset_re.match(line.strip()) + if m: + addr2line_output = subprocess.check_output( + ['addr2line', '-Cipf', '--exe=' + args.test_name, m.group(4)]) + prefix = '#%s: ' % m.group(1) + # addr2line outputs a second line for inlining information, offset + # that to align it properly after the frame index. + addr2line_filtered = addr2line_output.strip().replace( + '(inlined', ' ' * len(prefix) + '(inlined') + processed_lines.append('%s%s' % (prefix, addr2line_filtered)) qemu_popen.wait() return 0 if success else 1
diff --git a/build/vs_toolchain.py b/build/vs_toolchain.py index 0e191073..2f1ef173 100755 --- a/build/vs_toolchain.py +++ b/build/vs_toolchain.py
@@ -339,8 +339,8 @@ to build with.""" env_version = GetVisualStudioVersion() if env_version == '2015': - # Update 3 final with fixed 10.0.15063.0 SDK and patched event.h. - return ['a11b39300bafe01d9d46bbc16483e373503acc29'] + # Update 3 final with 10.0.15063.468 SDK and no vctip.exe. + return ['f53e4598951162bad6330f7a167486c7ae5db1e5'] if env_version == '2017': # VS 2017 Update 3 Preview 2 with 10.0.15063.0 SDK and patched event.h. return ['425bd64734a387734dfcf445b285a7c5073e4262']
diff --git a/build_overrides/pdfium.gni b/build_overrides/pdfium.gni index fb376460..377cdbeb 100644 --- a/build_overrides/pdfium.gni +++ b/build_overrides/pdfium.gni
@@ -15,8 +15,8 @@ # Disable use of Skia backend. pdf_use_skia_override = false -# Disable use of Skia backend, paths only (experimental) -pdf_use_skia_paths_override = false +# Enable use of Skia backend, paths only. +pdf_use_skia_paths_override = true # Enable experimental win32 GDI APIs. pdf_use_win32_gdi_override = true
diff --git a/cc/layers/render_surface_impl.cc b/cc/layers/render_surface_impl.cc index f124602..1f03887 100644 --- a/cc/layers/render_surface_impl.cc +++ b/cc/layers/render_surface_impl.cc
@@ -403,6 +403,9 @@ // mask layers. DCHECK(BlendMode() != SkBlendMode::kDstIn) << "kDstIn blend mode with mask layer is unsupported."; + TRACE_EVENT1("cc", "RenderSurfaceImpl::AppendQuads", + "mask_layer_gpu_memory_usage", + mask_layer->GPUMemoryUsageInBytes()); if (mask_layer->mask_type() == Layer::LayerMaskType::MULTI_TEXTURE_MASK) { TileMaskLayer(render_pass, shared_quad_state, visible_layer_rect); return;
diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc index 7578582..a21bbcc 100644 --- a/cc/trees/draw_property_utils.cc +++ b/cc/trees/draw_property_utils.cc
@@ -1026,6 +1026,7 @@ property_trees->transform_tree); mask_layer->draw_properties().visible_layer_rect = gfx::Rect(mask_layer->bounds()); + mask_layer->draw_properties().opacity = 1; } void ComputeSurfaceDrawProperties(PropertyTrees* property_trees,
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index cd297d7f..2d21951f 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -7322,6 +7322,93 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskWithNonExactTextureSize); +class LayerTreeTestSolidColorMaskLayer : public LayerTreeTest { + protected: + void SetupTree() override { + // Root + // | + // +-- Content Layer + // +--Mask + scoped_refptr<Layer> root = Layer::Create(); + scoped_refptr<FakePictureLayer> content_layer = + FakePictureLayer::Create(&client_); + root->AddChild(content_layer); + gfx::Size content_size(100, 100); + std::unique_ptr<RecordingSource> recording_source = + FakeRecordingSource::CreateFilledRecordingSource(content_size); + PaintFlags paint; + static_cast<FakeRecordingSource*>(recording_source.get()) + ->add_draw_rect_with_flags(gfx::Rect(content_size), paint); + + client_.set_fill_with_nonsolid_color(true); + static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord(); + scoped_refptr<FakePictureLayer> mask_layer = + FakePictureLayer::CreateWithRecordingSource( + &client_, std::move(recording_source)); + content_layer->SetMaskLayer(mask_layer.get()); + gfx::Size root_size(100, 100); + root->SetBounds(root_size); + content_layer->SetBounds(content_size); + + mask_layer->SetBounds(content_size); + mask_layer->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK); + + layer_tree_host()->SetRootLayer(root); + LayerTreeTest::SetupTree(); + client_.set_bounds(root->bounds()); + } + + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, + LayerTreeHostImpl::FrameData* frame_data, + DrawResult draw_result) override { + EXPECT_EQ(2u, frame_data->render_passes.size()); + RenderPass* root_pass = frame_data->render_passes.back().get(); + EXPECT_EQ(2u, root_pass->quad_list.size()); + + // There's a solid color quad under everything. + EXPECT_EQ(DrawQuad::SOLID_COLOR, root_pass->quad_list.back()->material); + + // Mask layer tiles should not be skipped even if the mask layer is solid + // color. + EXPECT_EQ(DrawQuad::RENDER_PASS, root_pass->quad_list.front()->material); + const RenderPassDrawQuad* render_pass_quad = + RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front()); + EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), + render_pass_quad->rect.ToString()); + EXPECT_EQ(gfx::RectF().ToString(), + + render_pass_quad->mask_uv_rect.ToString()); + EndTest(); + return draw_result; + } + + void AfterTest() override {} + + FakeContentLayerClient client_; +}; + +class LayerTreeTestSingleTextureSolidColorMaskLayer + : public LayerTreeTestSolidColorMaskLayer { + public: + void InitializeSettings(LayerTreeSettings* settings) override { + settings->enable_mask_tiling = false; + } +}; + +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestSingleTextureSolidColorMaskLayer); + +class LayerTreeTestMultiTextureSolidColorMaskLayer + : public LayerTreeTestSolidColorMaskLayer { + public: + void InitializeSettings(LayerTreeSettings* settings) override { + settings->enable_mask_tiling = true; + } +}; + +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMultiTextureSolidColorMaskLayer); + class LayerTreeTestPageScaleFlags : public LayerTreeTest { protected: void SetupTree() override {
diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h index 902d64b..c7b96b1 100644 --- a/cc/trees/layer_tree_settings.h +++ b/cc/trees/layer_tree_settings.h
@@ -93,7 +93,7 @@ // TODO(sunxd): remove this flag when filter demoting and aa of mask layers // are implemented. - bool enable_mask_tiling = false; + bool enable_mask_tiling = true; // If set to true, the compositor may selectively defer image decodes to the // Image Decode Service and raster tiles without images until the decode is
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ProfileDataCache.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ProfileDataCache.java index 2e68ef5..b1bc86f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ProfileDataCache.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ProfileDataCache.java
@@ -142,7 +142,7 @@ @Override public void onProfileDownloaded(String accountId, String fullName, String givenName, Bitmap bitmap) { - Drawable drawable = getCroppedAvatar(bitmap); + Drawable drawable = bitmap != null ? getCroppedAvatar(bitmap) : mPlaceholderImage; mCacheEntries.put(accountId, new CacheEntry(drawable, fullName, givenName)); for (Observer observer : mObservers) { observer.onProfileDataUpdated(accountId);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/ChromeHomeNewTabPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/ChromeHomeNewTabPage.java index 9e722b2..d31f9617 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/ChromeHomeNewTabPage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/ChromeHomeNewTabPage.java
@@ -25,7 +25,7 @@ */ public class ChromeHomeNewTabPage extends ChromeHomeNewTabPageBase implements TemplateUrlServiceObserver { - private final LogoView.Delegate mLogoDelegate; + private final LogoDelegateImpl mLogoDelegate; private final View mView; private final LogoView mLogoView; @@ -89,14 +89,14 @@ } private void updateSearchProviderLogoVisibility() { - boolean hasLogo = TemplateUrlService.getInstance().isDefaultSearchEngineGoogle(); + boolean hasLogo = TemplateUrlService.getInstance().doesDefaultSearchEngineHaveLogo(); mLogoView.setVisibility(hasLogo ? View.VISIBLE : View.GONE); } - private LogoView.Delegate initializeLogoView() { + private LogoDelegateImpl initializeLogoView() { TemplateUrlService.getInstance().addObserver(this); - final LogoView.Delegate logoDelegate = new LogoDelegateImpl(mTab, mLogoView); + final LogoDelegateImpl logoDelegate = new LogoDelegateImpl(mTab, mLogoView); logoDelegate.getSearchProviderLogo(new LogoObserver() { @Override public void onLogoAvailable(Logo logo, boolean fromCache) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/LogoDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/LogoDelegateImpl.java index c5d225c0..7a220a0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/LogoDelegateImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/LogoDelegateImpl.java
@@ -53,7 +53,6 @@ mLogoBridge = new LogoBridge(tab.getProfile()); } - @Override public void destroy() { mIsDestroyed = true; } @@ -79,9 +78,8 @@ } } - @Override public void getSearchProviderLogo(final LogoObserver logoObserver) { - if (mIsDestroyed) return; + assert !mIsDestroyed; final long loadTimeStart = System.currentTimeMillis();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/LogoView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/LogoView.java index 38c4db9..73e04fc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/LogoView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/LogoView.java
@@ -24,7 +24,7 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.ntp.LogoBridge.Logo; -import org.chromium.chrome.browser.ntp.LogoBridge.LogoObserver; +import org.chromium.chrome.browser.search_engines.TemplateUrlService; import org.chromium.chrome.browser.widget.LoadingView; import java.lang.ref.WeakReference; @@ -96,17 +96,6 @@ * @param isAnimatedLogoShowing Whether the animated GIF logo is playing. */ void onLogoClicked(boolean isAnimatedLogoShowing); - - /** - * Gets the default search provider's logo and calls logoObserver with the result. - * @param logoObserver The callback to notify when the logo is available. - */ - void getSearchProviderLogo(LogoObserver logoObserver); - - /** - * Should be called when the owning class is destroyed. - */ - void destroy(); } /** @@ -115,7 +104,6 @@ public LogoView(Context context, AttributeSet attrs) { super(context, attrs); - mLogo = getDefaultLogo(); mLogoMatrix = new Matrix(); mLogoIsDefault = true; @@ -175,30 +163,53 @@ } /** - * Lets logo view show a spinning progressbar. + * Show a spinning progressbar. */ public void showLoadingView() { + mLogo = null; mLoadingView.showLoadingUI(); } /** + * Show a loading indicator or a baked-in default search provider logo, based on what is + * available. + */ + public void showSearchProviderInitialView() { + if (maybeShowDefaultLogo()) return; + + showLoadingView(); + } + + /** * Fades in a new logo over the current logo. * - * @param logo The new logo to fade in. May be null to reset to the default logo. + * @param logo The new logo to fade in. */ public void updateLogo(Logo logo) { if (logo == null) { - updateLogo(getDefaultLogo(), null, true); - } else { - String contentDescription = TextUtils.isEmpty(logo.altText) ? null - : getResources().getString(R.string.accessibility_google_doodle, logo.altText); - updateLogo(logo.image, contentDescription, false); + if (maybeShowDefaultLogo()) return; + + mLogo = null; + invalidate(); + return; } + + String contentDescription = TextUtils.isEmpty(logo.altText) + ? null + : getResources().getString(R.string.accessibility_google_doodle, logo.altText); + updateLogo(logo.image, contentDescription, false); } private void updateLogo(Bitmap logo, final String contentDescription, boolean isDefaultLogo) { + assert logo != null; + if (mFadeAnimation != null) mFadeAnimation.end(); + mLoadingView.hideLoadingUI(); + + // Don't crossfade if the new logo is the same as the old one. + if (mLogo != null && mLogo.sameAs(logo)) return; + mNewLogo = logo; mNewLogoMatrix = new Matrix(); mNewLogoIsDefault = isDefaultLogo; @@ -238,6 +249,19 @@ } /** + * Shows the default search engine logo if available. + * @return Whether the default search engine logo is available. + */ + private boolean maybeShowDefaultLogo() { + Bitmap defaultLogo = getDefaultLogo(); + if (defaultLogo != null) { + updateLogo(defaultLogo, null, true); + return true; + } + return false; + } + + /** * @return Whether a new logo is currently fading in over the old logo. */ private boolean isTransitioning() { @@ -270,6 +294,8 @@ * @return The default logo. */ private Bitmap getDefaultLogo() { + if (!TemplateUrlService.getInstance().isDefaultSearchEngineGoogle()) return null; + Bitmap defaultLogo = sDefaultLogo == null ? null : sDefaultLogo.get(); if (defaultLogo == null) { defaultLogo = BitmapFactory.decodeResource(getResources(), R.drawable.google_logo);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java index 44556c8..4838a28 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java
@@ -5,7 +5,6 @@ package org.chromium.chrome.browser.ntp; import android.annotation.TargetApi; -import android.content.Context; import android.graphics.Canvas; import android.graphics.Point; import android.graphics.Rect; @@ -91,6 +90,7 @@ private TabObserver mTabObserver; private boolean mSearchProviderHasLogo; + private FakeboxDelegate mFakeboxDelegate; private SnippetsBridge mSnippetsBridge; @@ -188,9 +188,7 @@ @Override public boolean isLocationBarShownInNTP() { if (mIsDestroyed) return false; - Context context = mNewTabPageView.getContext(); - return isInSingleUrlBarMode(context) - && !mNewTabPageView.urlFocusAnimationsDisabled(); + return isInSingleUrlBarMode() && !mNewTabPageView.urlFocusAnimationsDisabled(); } @Override @@ -407,20 +405,20 @@ mNewTabPageView.setUrlFocusAnimationsDisabled(disable); } - private boolean isInSingleUrlBarMode(Context context) { + private boolean isInSingleUrlBarMode() { if (DeviceFormFactor.isTablet()) return false; if (FeatureUtilities.isChromeHomeEnabled()) return false; return mSearchProviderHasLogo; } private void updateSearchProviderHasLogo() { - mSearchProviderHasLogo = TemplateUrlService.getInstance().isDefaultSearchEngineGoogle(); + mSearchProviderHasLogo = TemplateUrlService.getInstance().doesDefaultSearchEngineHaveLogo(); } private void onSearchEngineUpdated() { - // TODO(newt): update this if other search providers provide logos. updateSearchProviderHasLogo(); mNewTabPageView.setSearchProviderHasLogo(mSearchProviderHasLogo); + mNewTabPageView.loadSearchProviderLogo(); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java index 7281c047..2cc2d10 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java
@@ -107,7 +107,7 @@ private ChromeActivity mActivity; private NewTabPageManager mManager; - private LogoView.Delegate mLogoDelegate; + private LogoDelegateImpl mLogoDelegate; private TileGroup.Delegate mTileGroupDelegate; private TileGroup mTileGroup; private UiConfig mUiConfig; @@ -276,6 +276,7 @@ initializeVoiceSearchButton(); initializeLayoutChangeListeners(); setSearchProviderHasLogo(searchProviderHasLogo); + mSearchProviderLogoView.showSearchProviderInitialView(); mTileGroup.startObserving(getMaxTileRows(searchProviderHasLogo) * getMaxTileColumns()); @@ -560,11 +561,16 @@ /** * Loads the search provider logo (e.g. Google doodle), if any. */ - private void loadSearchProviderLogo() { + public void loadSearchProviderLogo() { + if (!mSearchProviderHasLogo) return; + + mSearchProviderLogoView.showSearchProviderInitialView(); + mLogoDelegate.getSearchProviderLogo(new LogoObserver() { @Override public void onLogoAvailable(Logo logo, boolean fromCache) { if (logo == null && fromCache) return; + mSearchProviderLogoView.setDelegate(mLogoDelegate); mSearchProviderLogoView.updateLogo(logo); mSnapshotTileGridChanged = true;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteEditText.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteEditText.java index 4642fac..ce6e3eea5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteEditText.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteEditText.java
@@ -260,7 +260,7 @@ } @Override - public void onAutocompleteTextStateChanged(boolean textDeleted, boolean updateDisplay) { + public void onAutocompleteTextStateChanged(boolean updateDisplay) { assert false; // make sure that this method is properly overridden. }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextModel.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextModel.java index 2bbcc5f..23b5fb8c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextModel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextModel.java
@@ -422,7 +422,13 @@ } if (mIgnoreTextChangeFromAutocomplete) return; mLastEditWasDelete = textDeleted; - mDelegate.onAutocompleteTextStateChanged(textDeleted, updateDisplay); + mDelegate.onAutocompleteTextStateChanged(updateDisplay); + // Occasionally, was seeing the selection in the URL not being cleared during + // very rapid editing. This is here to hopefully force a selection reset during + // deletes. + if (textDeleted) { + mDelegate.setSelection(mDelegate.getSelectionStart(), mDelegate.getSelectionStart()); + } } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextModelBase.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextModelBase.java index acc4024e..674300d5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextModelBase.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextModelBase.java
@@ -48,10 +48,9 @@ /** * This is called when autocomplete text state changes. - * @param textDeleted True if text is just deleted. * @param updateDisplay True if string is changed. */ - void onAutocompleteTextStateChanged(boolean textDeleted, boolean updateDisplay); + void onAutocompleteTextStateChanged(boolean updateDisplay); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java index 20577fd..20f0722 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java
@@ -1126,7 +1126,7 @@ } @Override - public void onTextChangedForAutocomplete(final boolean textDeleted) { + public void onTextChangedForAutocomplete() { cancelPendingAutocompleteStart(); updateButtonVisibility(); @@ -1152,8 +1152,7 @@ @Override public void run() { String textWithoutAutocomplete = mUrlBar.getTextWithoutAutocomplete(); - - boolean preventAutocomplete = textDeleted || !mUrlBar.shouldAutocomplete(); + boolean preventAutocomplete = !mUrlBar.shouldAutocomplete(); mRequestSuggestions = null; if (getCurrentTab() == null @@ -1174,11 +1173,6 @@ mDeferredNativeRunnables.add(mRequestSuggestions); } } - - // Occasionally, was seeing the selection in the URL not being cleared during - // very rapid editing. This is here to hopefully force a selection reset during - // deletes. - if (textDeleted) mUrlBar.setSelection(mUrlBar.getSelectionStart()); } @Override @@ -2373,7 +2367,7 @@ if (!hasWindowFocus && !mSuggestionModalShown) { hideSuggestions(); } else if (hasWindowFocus && mUrlHasFocus && mNativeInitialized) { - onTextChangedForAutocomplete(false); + onTextChangedForAutocomplete(); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java index 04daa63..6bafb2d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java
@@ -155,10 +155,8 @@ /** * Called when the text state has changed and the autocomplete suggestions should be * refreshed. - * - * @param textDeleted Whether this change was as a result of text being deleted. */ - void onTextChangedForAutocomplete(boolean textDeleted); + void onTextChangedForAutocomplete(); /** * @return Whether the light security theme should be used. @@ -784,15 +782,14 @@ } @Override - public void onAutocompleteTextStateChanged(boolean textDeleted, boolean updateDisplay) { + public void onAutocompleteTextStateChanged(boolean updateDisplay) { if (DEBUG) { - Log.i(TAG, "onAutocompleteTextStateChanged: DEL[%b], DIS[%b]", textDeleted, - updateDisplay); + Log.i(TAG, "onAutocompleteTextStateChanged: DIS[%b]", updateDisplay); } if (mUrlBarDelegate == null) return; if (updateDisplay) limitDisplayableLength(); - mUrlBarDelegate.onTextChangedForAutocomplete(textDeleted); + mUrlBarDelegate.onTextChangedForAutocomplete(); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/search_engines/TemplateUrlService.java b/chrome/android/java/src/org/chromium/chrome/browser/search_engines/TemplateUrlService.java index a3e338a7..1e61c1fb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/search_engines/TemplateUrlService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/search_engines/TemplateUrlService.java
@@ -297,6 +297,10 @@ return nativeIsDefaultSearchEngineGoogle(mNativeTemplateUrlServiceAndroid); } + public boolean doesDefaultSearchEngineHaveLogo() { + return nativeDoesDefaultSearchEngineHaveLogo(mNativeTemplateUrlServiceAndroid); + } + /** * Checks whether a search result page is from a default search provider. * @param url The url for the search result page. @@ -443,6 +447,8 @@ long nativeTemplateUrlServiceAndroid, String url); private native boolean nativeIsSearchByImageAvailable(long nativeTemplateUrlServiceAndroid); private native boolean nativeIsDefaultSearchEngineGoogle(long nativeTemplateUrlServiceAndroid); + private native boolean nativeDoesDefaultSearchEngineHaveLogo( + long nativeTemplateUrlServiceAndroid); private native String nativeGetUrlForSearchQuery(long nativeTemplateUrlServiceAndroid, String query); private native String nativeGetUrlForVoiceSearchQuery(long nativeTemplateUrlServiceAndroid,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivityLocationBarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivityLocationBarLayout.java index 56bbc630..d16e3d00 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivityLocationBarLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivityLocationBarLayout.java
@@ -71,7 +71,7 @@ void onDeferredStartup(boolean isVoiceSearchIntent) { SearchWidgetProvider.updateCachedVoiceSearchAvailability(isVoiceSearchEnabled()); if (isVoiceSearchIntent && mUrlBar.isFocused()) onUrlFocusChange(true); - if (!TextUtils.isEmpty(mUrlBar.getText())) onTextChangedForAutocomplete(false); + if (!TextUtils.isEmpty(mUrlBar.getText())) onTextChangedForAutocomplete(); } /** Begins a new query. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java index f717e92..3a9c31b2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java
@@ -633,7 +633,9 @@ Context context, String accountId, String fullName, Bitmap bitmap) { sChildAccountId = null; sCachedBadgedPicture = null; - sToNamePicture.put(accountId, new Pair<>(fullName, makeRoundUserPicture(context, bitmap))); + Drawable userPicture = bitmap != null ? makeRoundUserPicture(context, bitmap) + : getAvatarPlaceholder(context); + sToNamePicture.put(accountId, new Pair<>(fullName, userPicture)); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileGrid.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileGrid.java index b4cb9396..0ba23035 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileGrid.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileGrid.java
@@ -96,7 +96,7 @@ } private static int getMaxTileRows() { - int defaultValue = 1; + int defaultValue = 2; return ChromeFeatureList.getFieldTrialParamByFeatureAsInt( ChromeFeatureList.CHROME_HOME, PARAM_CHROME_HOME_MAX_TILE_ROWS, defaultValue); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/CustomTabToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/CustomTabToolbar.java index bbd8aee..35aaa5d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/CustomTabToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/CustomTabToolbar.java
@@ -696,7 +696,7 @@ // Toolbar and LocationBar calls that are not relevant here. @Override - public void onTextChangedForAutocomplete(boolean canInlineAutocomplete) {} + public void onTextChangedForAutocomplete() {} @Override public void backKeyPressed() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/ChromeHomeAppMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/ChromeHomeAppMenuTest.java index 013212e..ae62965 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/ChromeHomeAppMenuTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/ChromeHomeAppMenuTest.java
@@ -18,10 +18,8 @@ import org.junit.runner.RunWith; import org.chromium.base.ThreadUtils; -import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Restriction; import org.chromium.base.test.util.UrlUtils; -import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.test.BottomSheetTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.content.browser.test.util.Criteria; @@ -31,9 +29,6 @@ * Tests for the app menu when Chrome Home is enabled. */ @RunWith(ChromeJUnit4ClassRunner.class) -@CommandLineFlags.Add({BottomSheetTestRule.ENABLE_CHROME_HOME, - ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, - BottomSheetTestRule.DISABLE_NETWORK_PREDICTION_FLAG}) @Restriction(RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones public class ChromeHomeAppMenuTest { private static final String TEST_URL = UrlUtils.encodeHtmlDataUri("<html>foo</html>");
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetTest.java index bafafb69..3615fcc 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetTest.java
@@ -22,11 +22,9 @@ import org.junit.runner.RunWith; import org.chromium.base.ThreadUtils; -import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Restriction; import org.chromium.base.test.util.RetryOnFailure; import org.chromium.chrome.R; -import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.ntp.cards.ItemViewType; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.SuggestionsBottomSheetTestRule; @@ -37,9 +35,6 @@ * Instrumentation tests for {@link SuggestionsBottomSheetContent}. */ @RunWith(ChromeJUnit4ClassRunner.class) -@CommandLineFlags.Add({SuggestionsBottomSheetTestRule.ENABLE_CHROME_HOME, - ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, - SuggestionsBottomSheetTestRule.DISABLE_NETWORK_PREDICTION_FLAG}) @Restriction(RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones public class SuggestionsBottomSheetTest { @Rule
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetUiCaptureTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetUiCaptureTest.java index e42d34f..b29fb71 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetUiCaptureTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetUiCaptureTest.java
@@ -19,12 +19,10 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Restriction; import org.chromium.base.test.util.ScreenShooter; import org.chromium.chrome.R; -import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.SuggestionsBottomSheetTestRule; @@ -33,9 +31,6 @@ * Tests for the appearance of Article Snippets. */ @RunWith(ChromeJUnit4ClassRunner.class) -@CommandLineFlags.Add({SuggestionsBottomSheetTestRule.ENABLE_CHROME_HOME, - ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, - SuggestionsBottomSheetTestRule.DISABLE_NETWORK_PREDICTION_FLAG}) @Restriction(RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones public class SuggestionsBottomSheetUiCaptureTest { @Rule
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetContentControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetContentControllerTest.java index c55fd01..2522e81 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetContentControllerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetContentControllerTest.java
@@ -17,10 +17,8 @@ import org.junit.runner.RunWith; import org.chromium.base.ThreadUtils; -import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Restriction; import org.chromium.chrome.R; -import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.bookmarks.BookmarkSheetContent; import org.chromium.chrome.browser.bookmarks.BookmarkUtils; @@ -36,9 +34,6 @@ /** This class tests the functionality of the {@link BottomSheetContentController}. */ @RunWith(ChromeJUnit4ClassRunner.class) -@CommandLineFlags.Add({"enable-features=ChromeHome", - ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, - BottomSheetTestRule.DISABLE_NETWORK_PREDICTION_FLAG}) @Restriction(RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones public class BottomSheetContentControllerTest { private BottomSheetTestRule.Observer mObserver;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetObserverTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetObserverTest.java index 2796178..7ce167a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetObserverTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetObserverTest.java
@@ -17,10 +17,8 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CallbackHelper; -import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Restriction; import org.chromium.chrome.R; -import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.bookmarks.BookmarkSheetContent; import org.chromium.chrome.browser.download.DownloadSheetContent; import org.chromium.chrome.browser.history.HistorySheetContent; @@ -33,9 +31,6 @@ /** This class tests the functionality of the {@link BottomSheetObserver}. */ @RunWith(ChromeJUnit4ClassRunner.class) -@CommandLineFlags.Add({BottomSheetTestRule.ENABLE_CHROME_HOME, - ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, - BottomSheetTestRule.DISABLE_NETWORK_PREDICTION_FLAG}) @Restriction(RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones public class BottomSheetObserverTest { @Rule
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextTest.java index 27284cc..a1ebffd4 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextTest.java
@@ -46,7 +46,7 @@ // This is needed to limit the target of inOrder#verify. private static class AutocompleteEmbedder { - public void onAutocompleteTextStateChanged(boolean textDeleted, boolean updateDisplay) { + public void onAutocompleteTextStateChanged(boolean updateDisplay) { if (DEBUG) Log.i(TAG, "onAutocompleteTextStateChanged"); } } @@ -61,10 +61,10 @@ } @Override - public void onAutocompleteTextStateChanged(boolean textDeleted, boolean updateDisplay) { + public void onAutocompleteTextStateChanged(boolean updateDisplay) { // This function is called in super(), so mEmbedder may be null. if (mEmbedder != null) { - mEmbedder.onAutocompleteTextStateChanged(textDeleted, updateDisplay); + mEmbedder.onAutocompleteTextStateChanged(updateDisplay); } } @@ -84,7 +84,7 @@ mAutocomplete = spy(new TestAutocompleteEditText(mEmbedder, mContext, null)); assertNotNull(mAutocomplete); // Note: this cannot catch the first {@link - // AutocompleteEditText#onAutocompleteTextStateChanged(boolean, boolean)}, which is caused + // AutocompleteEditText#onAutocompleteTextStateChanged(boolean)}, which is caused // by View constructor's call to setText(). mInOrder = inOrder(mEmbedder); mAutocomplete.onCreateInputConnection(new EditorInfo()); @@ -107,10 +107,10 @@ mAutocomplete.setIgnoreTextChangesForAutocomplete(false); // User types "h". assertTrue(mInputConnection.commitText("h", 1)); - mInOrder.verify(mEmbedder).onAutocompleteTextStateChanged(false, true); + mInOrder.verify(mEmbedder).onAutocompleteTextStateChanged(true); // User types "hello". assertTrue(mInputConnection.commitText("ello", 1)); - mInOrder.verify(mEmbedder).onAutocompleteTextStateChanged(false, true); + mInOrder.verify(mEmbedder).onAutocompleteTextStateChanged(true); mInOrder.verifyNoMoreInteractions(); // The controller kicks in. mAutocomplete.setAutocompleteText("hello", " world"); @@ -120,7 +120,7 @@ assertTexts("hello ", "world"); mInOrder.verifyNoMoreInteractions(); assertTrue(mInputConnection.endBatchEdit()); - mInOrder.verify(mEmbedder).onAutocompleteTextStateChanged(false, true); + mInOrder.verify(mEmbedder).onAutocompleteTextStateChanged(true); mAutocomplete.setAutocompleteText("hello ", "world"); assertTexts("hello ", "world"); mInOrder.verifyNoMoreInteractions();
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc index b8c9859..80e8c1e 100644 --- a/chrome/browser/android/chrome_feature_list.cc +++ b/chrome/browser/android/chrome_feature_list.cc
@@ -252,7 +252,7 @@ "WebPaymentsSingleAppUiSkip", base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kWebVrAutopresent{"WebVrAutopresent", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kWebVRCardboardSupport{"WebVRCardboardSupport", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chrome/browser/android/logo_service.cc b/chrome/browser/android/logo_service.cc index eea93ac2..5ef34a3 100644 --- a/chrome/browser/android/logo_service.cc +++ b/chrome/browser/android/logo_service.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/search_engines/ui_thread_search_terms_data.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/search_engines/template_url_service.h" +#include "components/search_provider_logos/fixed_logo_api.h" #include "components/search_provider_logos/google_logo_api.h" #include "content/public/browser/browser_thread.h" #include "net/url_request/url_request_context_getter.h" @@ -111,27 +112,42 @@ const TemplateURL* template_url = template_url_service->GetDefaultSearchProvider(); - if (!template_url || !template_url->url_ref().HasGoogleBaseURLs( - template_url_service->search_terms_data())) + if (!template_url) return; + const bool use_fixed_logo = !template_url->logo_url().is_empty(); + + if (!template_url->url_ref().HasGoogleBaseURLs( + template_url_service->search_terms_data()) && + !use_fixed_logo) { + return; + } + if (!logo_tracker_) { - logo_tracker_.reset(new LogoTracker( + logo_tracker_ = base::MakeUnique<LogoTracker>( profile_->GetPath().Append(kCachedLogoDirectory), BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE), BrowserThread::GetBlockingPool(), profile_->GetRequestContext(), - std::unique_ptr<search_provider_logos::LogoDelegate>( - new ChromeLogoDelegate()))); + base::MakeUnique<ChromeLogoDelegate>()); } + GURL url = + use_fixed_logo ? template_url->logo_url() : GetGoogleDoodleURL(profile_); + auto parse_logo_response_callback = + use_fixed_logo + ? base::Bind(&search_provider_logos::ParseFixedLogoResponse) + : base::Bind(&search_provider_logos::GoogleParseLogoResponse); + bool use_gray_background = !base::FeatureList::IsEnabled(chrome::android::kChromeHomeFeature); - logo_tracker_->SetServerAPI( - GetGoogleDoodleURL(profile_), - base::Bind(&search_provider_logos::GoogleParseLogoResponse), - base::Bind(&search_provider_logos::GoogleAppendQueryparamsToLogoURL), - true, /* wants_cta */ - use_gray_background); + auto append_query_params_callback = + use_fixed_logo + ? base::Bind(&search_provider_logos::UseFixedLogoUrl) + : base::Bind(&search_provider_logos::GoogleAppendQueryparamsToLogoURL, + use_gray_background); + + logo_tracker_->SetServerAPI(url, parse_logo_response_callback, + append_query_params_callback); logo_tracker_->GetLogo(observer); }
diff --git a/chrome/browser/browsing_data/browsing_data_cookie_helper.cc b/chrome/browser/browsing_data/browsing_data_cookie_helper.cc index 0ae5e6aa..40d9dc85 100644 --- a/chrome/browser/browsing_data/browsing_data_cookie_helper.cc +++ b/chrome/browser/browsing_data/browsing_data_cookie_helper.cc
@@ -128,9 +128,8 @@ return count; } - void CannedBrowsingDataCookieHelper::StartFetching( - const net::CookieStore::GetCookieListCallback& callback) { + const FetchCallback& callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); net::CookieList cookie_list; for (const auto& pair : origin_cookie_set_map_) {
diff --git a/chrome/browser/browsing_data/browsing_data_cookie_helper.h b/chrome/browser/browsing_data/browsing_data_cookie_helper.h index ba30e26..eb2fe20 100644 --- a/chrome/browser/browsing_data/browsing_data_cookie_helper.h +++ b/chrome/browser/browsing_data/browsing_data_cookie_helper.h
@@ -114,8 +114,7 @@ bool empty() const; // BrowsingDataCookieHelper methods. - void StartFetching( - const net::CookieMonster::GetCookieListCallback& callback) override; + void StartFetching(const FetchCallback& callback) override; void DeleteCookie(const net::CanonicalCookie& cookie) override; // Returns the number of stored cookies.
diff --git a/chrome/browser/browsing_data/mock_browsing_data_cookie_helper.cc b/chrome/browser/browsing_data/mock_browsing_data_cookie_helper.cc index d98feee..2ea653b 100644 --- a/chrome/browser/browsing_data/mock_browsing_data_cookie_helper.cc +++ b/chrome/browser/browsing_data/mock_browsing_data_cookie_helper.cc
@@ -21,7 +21,7 @@ } void MockBrowsingDataCookieHelper::StartFetching( - const net::CookieStore::GetCookieListCallback &callback) { + const FetchCallback& callback) { ASSERT_FALSE(callback.is_null()); ASSERT_TRUE(callback_.is_null()); callback_ = callback;
diff --git a/chrome/browser/browsing_data/mock_browsing_data_cookie_helper.h b/chrome/browser/browsing_data/mock_browsing_data_cookie_helper.h index 7b9daf9e..f6487a617 100644 --- a/chrome/browser/browsing_data/mock_browsing_data_cookie_helper.h +++ b/chrome/browser/browsing_data/mock_browsing_data_cookie_helper.h
@@ -20,8 +20,7 @@ net::URLRequestContextGetter* request_context_getter); // BrowsingDataCookieHelper methods. - void StartFetching( - const net::CookieStore::GetCookieListCallback& callback) override; + void StartFetching(const FetchCallback& callback) override; void DeleteCookie(const net::CanonicalCookie& cookie) override; // Adds some cookie samples. @@ -40,7 +39,7 @@ private: ~MockBrowsingDataCookieHelper() override; - net::CookieStore::GetCookieListCallback callback_; + FetchCallback callback_; net::CookieList cookie_list_;
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index f052a50..c4c84a32 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -1308,6 +1308,8 @@ "power/renderer_freezer.h", "preferences.cc", "preferences.h", + "printing/combining_printer_detector.cc", + "printing/combining_printer_detector.h", "printing/cups_print_job.cc", "printing/cups_print_job.h", "printing/cups_print_job_manager.cc", @@ -1322,8 +1324,7 @@ "printing/ppd_provider_factory.h", "printing/printer_configurer.cc", "printing/printer_configurer.h", - "printing/printer_discoverer.cc", - "printing/printer_discoverer.h", + "printing/printer_detector.h", "printing/printer_info.h", "printing/printers_manager.cc", "printing/printers_manager.h", @@ -1842,6 +1843,7 @@ "power/power_prefs_unittest.cc", "power/renderer_freezer_unittest.cc", "preferences_unittest.cc", + "printing/combining_printer_detector_unittest.cc", "printing/printers_manager_unittest.cc", "printing/specifics_translation_unittest.cc", "profiles/profile_list_chromeos_unittest.cc",
diff --git a/chrome/browser/chromeos/arc/arc_play_store_enabled_preference_handler_unittest.cc b/chrome/browser/chromeos/arc/arc_play_store_enabled_preference_handler_unittest.cc index 356a73e..e5ba0a891 100644 --- a/chrome/browser/chromeos/arc/arc_play_store_enabled_preference_handler_unittest.cc +++ b/chrome/browser/chromeos/arc/arc_play_store_enabled_preference_handler_unittest.cc
@@ -25,7 +25,6 @@ #include "components/arc/arc_util.h" #include "components/arc/test/fake_arc_session.h" #include "components/sync_preferences/testing_pref_service_syncable.h" -#include "content/public/browser/browser_thread.h" #include "content/public/test/test_browser_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h" @@ -125,13 +124,6 @@ // Setting profile initiates a code fetching process. ASSERT_EQ(ArcSessionManager::State::NEGOTIATING_TERMS_OF_SERVICE, arc_session_manager()->state()); - - content::BrowserThread::GetBlockingPool()->FlushForTesting(); - base::RunLoop().RunUntilIdle(); - - // UI is disabled in unit tests and this code is unchanged. - ASSERT_EQ(ArcSessionManager::State::NEGOTIATING_TERMS_OF_SERVICE, - arc_session_manager()->state()); } TEST_F(ArcPlayStoreEnabledPreferenceHandlerTest, RemoveDataDir_Managed) {
diff --git a/chrome/browser/chromeos/login/screens/update_screen.cc b/chrome/browser/chromeos/login/screens/update_screen.cc index f054b10..d26f50f7 100644 --- a/chrome/browser/chromeos/login/screens/update_screen.cc +++ b/chrome/browser/chromeos/login/screens/update_screen.cc
@@ -242,7 +242,6 @@ HostPairingController::UPDATE_STATUS_UPDATING); break; case UpdateEngineClient::UPDATE_STATUS_UPDATE_AVAILABLE: - ClearUpdateCheckNoUpdateTime(); MakeSureScreenIsShown(); GetContextEditor() .SetInteger(kContextKeyProgress, kBeforeDownloadProgress) @@ -556,18 +555,11 @@ if (state_ == State::STATE_ERROR) HideErrorMessage(); - if (ShouldCheckForUpdate()) { - state_ = State::STATE_UPDATE; - DBusThreadManager::Get()->GetUpdateEngineClient()->AddObserver(this); - VLOG(1) << "Initiate update check"; - RecordUpdateCheckWithNoUpdateYet(); - DBusThreadManager::Get()->GetUpdateEngineClient()->RequestUpdateCheck( - base::Bind(StartUpdateCallback, this)); - } else { - LOG(WARNING) << "Skipping update check since one was done recently " - "which did not result in an update."; - CancelUpdate(); - } + state_ = State::STATE_UPDATE; + DBusThreadManager::Get()->GetUpdateEngineClient()->AddObserver(this); + VLOG(1) << "Initiate update check"; + DBusThreadManager::Get()->GetUpdateEngineClient()->RequestUpdateCheck( + base::Bind(StartUpdateCallback, this)); } void UpdateScreen::ShowErrorMessage() { @@ -638,34 +630,4 @@ } } -void UpdateScreen::RecordUpdateCheckWithNoUpdateYet() { - StartupUtils::SaveTimeOfLastUpdateCheckWithoutUpdate(base::Time::Now()); -} - -void UpdateScreen::ClearUpdateCheckNoUpdateTime() { - StartupUtils::ClearTimeOfLastUpdateCheckWithoutUpdate(); -} - -bool UpdateScreen::ShouldCheckForUpdate() { - // Always run update check for non hands-off enrollment. - if (!WizardController::UsingHandsOffEnrollment()) - return true; - - // If we check for an update and there is no need to perform an update, - // this is the time in hours we should wait before checking again. - const base::TimeDelta kUpdateCheckRecencyThreshold = - base::TimeDelta::FromHours(1); - - base::Time now = base::Time::Now(); - base::Time last = StartupUtils::GetTimeOfLastUpdateCheckWithoutUpdate(); - - // Return false if enough time has not passed since the last update check. - // Otherwise, return true. - if (now > last) { - return (now - last) > kUpdateCheckRecencyThreshold; - } - - return true; -} - } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/screens/update_screen.h b/chrome/browser/chromeos/login/screens/update_screen.h index a03787d..15e3dd2 100644 --- a/chrome/browser/chromeos/login/screens/update_screen.h +++ b/chrome/browser/chromeos/login/screens/update_screen.h
@@ -126,18 +126,6 @@ // The user requested an attempt to connect to the network should be made. void OnConnectRequested(); - // Records the fact that we performed an update check but do not yet - // know if this update check is going to result in an update. - void RecordUpdateCheckWithNoUpdateYet(); - - // When an update is found, this is called to clear the time of update check - // which had saved when we did not yet know whether it would result in an - // update. - void ClearUpdateCheckNoUpdateTime(); - - // Returns true if we should check for an update. - bool ShouldCheckForUpdate(); - // Timer for the interval to wait for the reboot. // If reboot didn't happen - ask user to reboot manually. base::OneShotTimer reboot_timer_;
diff --git a/chrome/browser/chromeos/login/screens/update_screen_unittest.cc b/chrome/browser/chromeos/login/screens/update_screen_unittest.cc index 836154d..ef77bca 100644 --- a/chrome/browser/chromeos/login/screens/update_screen_unittest.cc +++ b/chrome/browser/chromeos/login/screens/update_screen_unittest.cc
@@ -37,14 +37,6 @@ : fake_controller_(""), local_state_(TestingBrowserProcess::GetGlobal()) {} - // Fast-forwards time by the specified amount. - void FastForwardTime(base::TimeDelta time) { - base::Time last = StartupUtils::GetTimeOfLastUpdateCheckWithoutUpdate(); - ASSERT_FALSE(last.is_null()); - base::Time modified_last = last - time; - StartupUtils::SaveTimeOfLastUpdateCheckWithoutUpdate(modified_last); - } - // Simulates an update being available (or not). // The parameter "update_screen" points to the currently active UpdateScreen. // The parameter "available" indicates whether an update is available. @@ -75,7 +67,7 @@ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( switches::kEnterpriseEnableZeroTouchEnrollment, "hands-off"); - // Initialize objects needed by UpdateScreen + // Initialize objects needed by UpdateScreen. fake_update_engine_client_ = new FakeUpdateEngineClient(); DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient( std::unique_ptr<UpdateEngineClient>(fake_update_engine_client_)); @@ -93,17 +85,11 @@ EXPECT_CALL(mock_base_screen_delegate_, GetErrorScreen()) .Times(AnyNumber()) .WillRepeatedly(Return(mock_error_screen_.get())); - - // Later verifies that UpdateScreen successfully exits both times. - EXPECT_CALL(mock_base_screen_delegate_, - OnExit(_, ScreenExitCode::UPDATE_NOUPDATE, _)) - .Times(2); } void TearDown() override { TestingBrowserProcess::GetGlobal()->SetShuttingDown(true); - first_update_screen_.reset(); - second_update_screen_.reset(); + update_screen_.reset(); mock_error_screen_.reset(); network_portal_detector::Shutdown(); NetworkHandler::Shutdown(); @@ -111,13 +97,8 @@ } protected: - // A pointer to the UpdateScreen that shows up during the first OOBE. - std::unique_ptr<UpdateScreen> first_update_screen_; - - // A pointer to the UpdateScreen which shows up during the second OOBE. - // This test verifies proper behavior if the device is restarted before - // OOBE is complete, which is why there is a second OOBE. - std::unique_ptr<UpdateScreen> second_update_screen_; + // A pointer to the UpdateScreen used in this test. + std::unique_ptr<UpdateScreen> update_screen_; // Accessory objects needed by UpdateScreen. MockBaseScreenDelegate mock_base_screen_delegate_; @@ -137,167 +118,64 @@ DISALLOW_COPY_AND_ASSIGN(UpdateScreenUnitTest); }; -// Test Scenario Description: -// In this description, "will" refers to an external event, and "should" refers -// to the expected behavior of the DUT in response to external events. -// -// The DUT boots up and starts OOBE. Since it is a Hands-Off device, it -// proceeds through OOBE automatically. When it hits the UpdateScreen, -// it checks for updates. It will find that there is indeed an update -// available, will then install it. After installing the update, it should -// continue with Hands-Off OOBE. Then, before OOBE is complete, something -// (could be user, environment, anything) will cause the DUT to reboot. -// Since OOBE is not complete, the DUT goes through OOBE again. -// When the DUT hits the UpdateScreen during this second OOBE run-through, -// it should check for updates again. -TEST_F(UpdateScreenUnitTest, ChecksForUpdateBothTimesIfFirstIsInstalled) { - // DUT reaches UpdateScreen for the first time. - first_update_screen_.reset(new UpdateScreen(&mock_base_screen_delegate_, - &mock_view_, &fake_controller_)); - first_update_screen_->StartNetworkCheck(); +TEST_F(UpdateScreenUnitTest, HandlesNoUpdate) { + // Set expectation that UpdateScreen will exit successfully + // with code UPDATE_NOUPDATE. + EXPECT_CALL(mock_base_screen_delegate_, + OnExit(_, ScreenExitCode::UPDATE_NOUPDATE, _)) + .Times(1); + + // DUT reaches UpdateScreen. + update_screen_.reset(new UpdateScreen(&mock_base_screen_delegate_, + &mock_view_, &fake_controller_)); + update_screen_->StartNetworkCheck(); // Verify that the DUT checks for an update. EXPECT_EQ(fake_update_engine_client_->request_update_check_call_count(), 1); - // An update is available. - SimulateUpdateAvailable(first_update_screen_, true /* available */, - false /* critical */); - - // DUT reboots... - // After rebooting, the DUT reaches UpdateScreen for the second time. - second_update_screen_.reset(new UpdateScreen(&mock_base_screen_delegate_, - &mock_view_, &fake_controller_)); - second_update_screen_->StartNetworkCheck(); - - // Verify that the DUT checks for updates again. - EXPECT_EQ(fake_update_engine_client_->request_update_check_call_count(), 2); - - // No updates available this time. - SimulateUpdateAvailable(second_update_screen_, false /* available */, - false /* critical */); -} - -// Test Scenario Description: -// In this description, "will" refers to an external event, and "should" refers -// to the expected behavior of the DUT in response to external events. -// -// The DUT boots up and starts OOBE. Since it is a Hands-Off device, it -// proceeds through OOBE automatically. When it hits the UpdateScreen, -// it checks for updates. It will find that there are no updates -// available, and it should leave the UpdateScreen without installing any -// updates. It continues with OOBE. Then, before OOBE is complete, something -// (could be user, environment, anything) will cause the DUT to reboot. -// Since OOBE is not complete, the DUT goes through OOBE again. -// When the DUT hits the UpdateScreen during this second OOBE run-through, -// more than one hour will have passed since the previous update check. -// Therefore, the DUT should check for updates again. -TEST_F(UpdateScreenUnitTest, ChecksForUpdateBothTimesIfEnoughTimePasses) { - // DUT reaches UpdateScreen for the first time. - first_update_screen_.reset(new UpdateScreen(&mock_base_screen_delegate_, - &mock_view_, &fake_controller_)); - first_update_screen_->StartNetworkCheck(); - - // Verify that the DUT checks for updates. - EXPECT_EQ(fake_update_engine_client_->request_update_check_call_count(), 1); - // No updates are available. - SimulateUpdateAvailable(first_update_screen_, false /* available */, - false /* critical */); - - // Fast-forward time by one hour. - FastForwardTime(base::TimeDelta::FromHours(1)); - - // DUT reboots... - // After rebooting, the DUT reaches UpdateScreen for the second time. - second_update_screen_.reset(new UpdateScreen(&mock_base_screen_delegate_, - &mock_view_, &fake_controller_)); - second_update_screen_->StartNetworkCheck(); - - // Verify that the DUT checks for updates again. - EXPECT_EQ(fake_update_engine_client_->request_update_check_call_count(), 2); - - // No updates available this time either. - SimulateUpdateAvailable(second_update_screen_, false /* available */, + SimulateUpdateAvailable(update_screen_, false /* available */, false /* critical */); } -// Test Scenario Description: -// In this description, "will" refers to an external event, and "should" refers -// to the expected behavior of the DUT in response to external events. -// -// The DUT boots up and starts OOBE. Since it is a Hands-Off device, it -// proceeds through OOBE automatically. When it hits the UpdateScreen, -// it checks for updates. It will find that there are no updates -// available, and it should leave the UpdateScreen without installing any -// updates. It continues with OOBE. Then, before OOBE is complete, something -// (could be user, environment, anything) will cause the DUT to reboot. -// Since OOBE is not complete, the DUT goes through OOBE again. -// When the DUT hits the UpdateScreen during this second OOBE run-through, -// less than one hour will have passed since the previous update check. -// Therefore, the DUT should not check for updates again. -TEST_F(UpdateScreenUnitTest, ChecksForUpdateOnceButNotAgainIfTooSoon) { - // DUT reaches UpdateScreen for the first time. - first_update_screen_.reset(new UpdateScreen(&mock_base_screen_delegate_, - &mock_view_, &fake_controller_)); - first_update_screen_->StartNetworkCheck(); +TEST_F(UpdateScreenUnitTest, HandlesNonCriticalUpdate) { + // Set expectation that UpdateScreen will exit successfully + // with code UPDATE_NOUPDATE. No, this is not a typo. + // UPDATE_NOUPDATE means that either there was no update + // or there was a non-critical update. + EXPECT_CALL(mock_base_screen_delegate_, + OnExit(_, ScreenExitCode::UPDATE_NOUPDATE, _)) + .Times(1); - // Verify that the DUT checks for updates. + // DUT reaches UpdateScreen. + update_screen_.reset(new UpdateScreen(&mock_base_screen_delegate_, + &mock_view_, &fake_controller_)); + update_screen_->StartNetworkCheck(); + + // Verify that the DUT checks for an update. EXPECT_EQ(fake_update_engine_client_->request_update_check_call_count(), 1); - // No update available. - SimulateUpdateAvailable(first_update_screen_, false /* available */, - false /* critical */); - - // DUT reboots... - // After rebooting, the DUT reaches UpdateScreen for the second time. - second_update_screen_.reset(new UpdateScreen(&mock_base_screen_delegate_, - &mock_view_, &fake_controller_)); - second_update_screen_->StartNetworkCheck(); - - // Verify that the DUT did not check for updates again. - EXPECT_EQ(fake_update_engine_client_->request_update_check_call_count(), 1); - - // No update available this time either. - SimulateUpdateAvailable(second_update_screen_, false /* available */, + // A non-critical update is available. + SimulateUpdateAvailable(update_screen_, true /* available */, false /* critical */); } -// Test Scenario Description: -// In this description, "will" refers to an external event, and "should" refers -// to the expected behavior of the DUT in response to external events. -// -// The DUT boots up and starts OOBE. Since it is a Hands-Off device, it -// proceeds through OOBE automatically. When it hits the UpdateScreen, -// it checks for updates. It will find that a critical update is available. -// The DUT installs the update, and because the update is critical, it reboots. -// Since OOBE is not complete, the DUT goes through OOBE again after reboot. -// When the DUT hits the UpdateScreen during this second OOBE run-through, -// it should check for updates again. -TEST_F(UpdateScreenUnitTest, ChecksForUpdateBothTimesIfCriticalUpdate) { - // DUT reaches UpdateScreen for the first time. - first_update_screen_.reset(new UpdateScreen(&mock_base_screen_delegate_, - &mock_view_, &fake_controller_)); - first_update_screen_->StartNetworkCheck(); +TEST_F(UpdateScreenUnitTest, HandlesCriticalUpdate) { + // Set expectation that UpdateScreen does not exit. + // This is the case because a critical update mandates reboot. + EXPECT_CALL(mock_base_screen_delegate_, OnExit(_, _, _)).Times(0); - // Verify that the DUT checks for updates. + // DUT reaches UpdateScreen. + update_screen_.reset(new UpdateScreen(&mock_base_screen_delegate_, + &mock_view_, &fake_controller_)); + update_screen_->StartNetworkCheck(); + + // Verify that the DUT checks for an update. EXPECT_EQ(fake_update_engine_client_->request_update_check_call_count(), 1); // An update is available, and it's critical! - SimulateUpdateAvailable(first_update_screen_, true /* available */, + SimulateUpdateAvailable(update_screen_, true /* available */, true /* critical */); - - // DUT reboots... - // After rebooting, the DUT reaches UpdateScreen for the second time. - second_update_screen_.reset(new UpdateScreen(&mock_base_screen_delegate_, - &mock_view_, &fake_controller_)); - second_update_screen_->StartNetworkCheck(); - - // Verify that the DUT checks for updates again. - EXPECT_EQ(fake_update_engine_client_->request_update_check_call_count(), 2); - - // No update available this time. - SimulateUpdateAvailable(second_update_screen_, false /* available */, - false /* critical */); } } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/startup_utils.cc b/chrome/browser/chromeos/login/startup_utils.cc index e942437e..46bbf1c8 100644 --- a/chrome/browser/chromeos/login/startup_utils.cc +++ b/chrome/browser/chromeos/login/startup_utils.cc
@@ -41,14 +41,6 @@ prefs->CommitPendingWrite(); } -// Saves 64 bit signed integer "Local State" preference and forces its -// persistence to disk. -void SaveInt64PreferenceForced(const char* pref_name, int64_t value) { - PrefService* prefs = g_browser_process->local_state(); - prefs->SetInt64(pref_name, value); - prefs->CommitPendingWrite(); -} - // Saves string "Local State" preference and forces its persistence to disk. void SaveStringPreferenceForced(const char* pref_name, const std::string& value) { @@ -100,8 +92,6 @@ registry->RegisterStringPref(prefs::kInitialLocale, "en-US"); registry->RegisterBooleanPref(prefs::kIsBootstrappingSlave, false); registry->RegisterBooleanPref(prefs::kOobeControllerDetected, false); - registry->RegisterInt64Pref(prefs::kOobeTimeOfLastUpdateCheckWithoutUpdate, - 0); } // static @@ -206,24 +196,4 @@ NOTREACHED(); } -// static -void StartupUtils::SaveTimeOfLastUpdateCheckWithoutUpdate(base::Time time) { - SaveInt64PreferenceForced(prefs::kOobeTimeOfLastUpdateCheckWithoutUpdate, - time.ToInternalValue()); -} - -// static -void StartupUtils::ClearTimeOfLastUpdateCheckWithoutUpdate() { - PrefService* prefs = g_browser_process->local_state(); - prefs->ClearPref(prefs::kOobeTimeOfLastUpdateCheckWithoutUpdate); - prefs->CommitPendingWrite(); -} - -// static -base::Time StartupUtils::GetTimeOfLastUpdateCheckWithoutUpdate() { - return base::Time::FromInternalValue( - g_browser_process->local_state()->GetInt64( - prefs::kOobeTimeOfLastUpdateCheckWithoutUpdate)); -} - } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/startup_utils.h b/chrome/browser/chromeos/login/startup_utils.h index 426eb4a..1f9778d 100644 --- a/chrome/browser/chromeos/login/startup_utils.h +++ b/chrome/browser/chromeos/login/startup_utils.h
@@ -12,7 +12,6 @@ class PrefRegistrySimple; namespace base { -class Time; class TimeDelta; } @@ -60,15 +59,6 @@ // Sets initial locale in local settings. static void SetInitialLocale(const std::string& locale); - // Saves the time of the last update check which did not result in any update. - static void SaveTimeOfLastUpdateCheckWithoutUpdate(base::Time time); - - // Clears the update check time which was previously saved. - static void ClearTimeOfLastUpdateCheckWithoutUpdate(); - - // Returns the time of the last update check which did not lead to an update. - static base::Time GetTimeOfLastUpdateCheckWithoutUpdate(); - // Registers OOBE preferences. static void RegisterPrefs(PrefRegistrySimple* registry); };
diff --git a/chrome/browser/chromeos/mobile/mobile_activator.cc b/chrome/browser/chromeos/mobile/mobile_activator.cc index a53ed1e..8016909 100644 --- a/chrome/browser/chromeos/mobile/mobile_activator.cc +++ b/chrome/browser/chromeos/mobile/mobile_activator.cc
@@ -21,6 +21,8 @@ #include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "base/task_scheduler/post_task.h" +#include "base/threading/thread_restrictions.h" #include "base/timer/timer.h" #include "base/values.h" #include "chrome/browser/browser_process.h" @@ -102,7 +104,8 @@ } void CellularConfigDocument::LoadCellularConfigFile() { - DCHECK_CURRENTLY_ON(BrowserThread::FILE); + base::ThreadRestrictions::AssertIOAllowed(); + // Load partner customization startup manifest if it is available. base::FilePath config_path(kCellularConfigPath); if (!base::PathExists(config_path)) @@ -271,10 +274,11 @@ ChangeState(network, PLAN_ACTIVATION_PAGE_LOADING, ""); - BrowserThread::PostTaskAndReply(BrowserThread::FILE, FROM_HERE, - base::Bind(&CellularConfigDocument::LoadCellularConfigFile, - cellular_config_.get()), - base::Bind(&MobileActivator::ContinueActivation, AsWeakPtr())); + base::PostTaskWithTraitsAndReply( + FROM_HERE, {base::TaskPriority::BACKGROUND, base::MayBlock()}, + base::BindOnce(&CellularConfigDocument::LoadCellularConfigFile, + cellular_config_.get()), + base::BindOnce(&MobileActivator::ContinueActivation, AsWeakPtr())); } void MobileActivator::ContinueActivation() {
diff --git a/chrome/browser/chromeos/mobile_config.cc b/chrome/browser/chromeos/mobile_config.cc index f523ad4..a347a69 100644 --- a/chrome/browser/chromeos/mobile_config.cc +++ b/chrome/browser/chromeos/mobile_config.cc
@@ -15,12 +15,11 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/stl_util.h" +#include "base/task_scheduler/post_task.h" +#include "base/threading/thread_restrictions.h" #include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/login/startup_utils.h" -#include "content/public/browser/browser_thread.h" - -using content::BrowserThread; namespace { @@ -60,6 +59,24 @@ const char kLocalCarrierConfigPath[] = "/opt/oem/etc/carrier_config.json"; +// Executes on background thread and reads config files to string. +chromeos::MobileConfig::Config ReadConfigInBackground( + const base::FilePath& global_config_file, + const base::FilePath& local_config_file) { + base::ThreadRestrictions::AssertIOAllowed(); + + chromeos::MobileConfig::Config config; + if (!base::ReadFileToString(global_config_file, &config.global_config)) { + VLOG(1) << "Failed to load global mobile config from: " + << global_config_file.value(); + } + if (!base::ReadFileToString(local_config_file, &config.local_config)) { + VLOG(1) << "Failed to load local mobile config from: " + << local_config_file.value(); + } + return config; +} + } // anonymous namespace namespace chromeos { @@ -316,28 +333,29 @@ } void MobileConfig::LoadConfig() { - BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, - base::Bind(&MobileConfig::ReadConfigInBackground, - base::Unretained(this), // this class is a singleton. - base::FilePath(kGlobalCarrierConfigPath), - base::FilePath(kLocalCarrierConfigPath))); + base::PostTaskWithTraitsAndReplyWithResult( + FROM_HERE, {base::TaskPriority::BACKGROUND, base::MayBlock()}, + base::BindOnce(&ReadConfigInBackground, + base::FilePath(kGlobalCarrierConfigPath), + base::FilePath(kLocalCarrierConfigPath)), + base::BindOnce(&MobileConfig::ProcessConfig, + base::Unretained(this))); // singleton. } -void MobileConfig::ProcessConfig(const std::string& global_config, - const std::string& local_config) { +void MobileConfig::ProcessConfig(const Config& config) { // Global config is mandatory, local config is optional. bool global_initialized = false; bool local_initialized = true; std::unique_ptr<base::DictionaryValue> global_config_root; - if (!global_config.empty()) { - global_initialized = LoadManifestFromString(global_config); + if (!config.global_config.empty()) { + global_initialized = LoadManifestFromString(config.global_config); // Backup global config root as it might be // owerwritten while loading local config. global_config_root = std::move(root_); } - if (!local_config.empty()) - local_initialized = LoadManifestFromString(local_config); + if (!config.local_config.empty()) + local_initialized = LoadManifestFromString(config.local_config); // Treat any parser errors as fatal. if (!global_initialized || !local_initialized) { @@ -349,25 +367,4 @@ } } -void MobileConfig::ReadConfigInBackground( - const base::FilePath& global_config_file, - const base::FilePath& local_config_file) { - DCHECK_CURRENTLY_ON(BrowserThread::FILE); - std::string global_config; - std::string local_config; - if (!base::ReadFileToString(global_config_file, &global_config)) { - VLOG(1) << "Failed to load global mobile config from: " - << global_config_file.value(); - } - if (!base::ReadFileToString(local_config_file, &local_config)) { - VLOG(1) << "Failed to load local mobile config from: " - << local_config_file.value(); - } - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(&MobileConfig::ProcessConfig, - base::Unretained(this), // singleton. - global_config, - local_config)); -} - } // namespace chromeos
diff --git a/chrome/browser/chromeos/mobile_config.h b/chrome/browser/chromeos/mobile_config.h index 628b448..5d9871142 100644 --- a/chrome/browser/chromeos/mobile_config.h +++ b/chrome/browser/chromeos/mobile_config.h
@@ -18,7 +18,6 @@ namespace base { class DictionaryValue; -class FilePath; } namespace chromeos { @@ -134,6 +133,12 @@ DISALLOW_COPY_AND_ASSIGN(LocaleConfig); }; + // A struct to hold global and local config content read from config files. + struct Config { + std::string global_config; + std::string local_config; + }; + // External carrier ID (ex. "Verizon (us)") mapping to internal carrier ID. using CarrierIdMap = std::map<std::string, std::string>; @@ -174,12 +179,7 @@ void LoadConfig(); // Processes global/local config. - void ProcessConfig(const std::string& global_config, - const std::string& local_config); - - // Executes on FILE thread and reads config files to string. - void ReadConfigInBackground(const base::FilePath& global_config_file, - const base::FilePath& local_config_file); + void ProcessConfig(const Config& config); // Maps external carrier ID to internal carrier ID. CarrierIdMap carrier_id_map_;
diff --git a/chrome/browser/chromeos/printing/combining_printer_detector.cc b/chrome/browser/chromeos/printing/combining_printer_detector.cc new file mode 100644 index 0000000..920d429 --- /dev/null +++ b/chrome/browser/chromeos/printing/combining_printer_detector.cc
@@ -0,0 +1,153 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/printing/combining_printer_detector.h" + +#include <map> +#include <utility> +#include <vector> + +#include "base/memory/ptr_util.h" +#include "base/observer_list.h" +#include "base/scoped_observer.h" +#include "chrome/browser/chromeos/printing/printer_detector.h" +#include "chromeos/printing/printer_configuration.h" + +namespace chromeos { +namespace { + +class CombiningPrinterDetectorImpl; + +// We can't just implement PrinterDetector::Observer in +// CombiningPrinterDetectorImpl because we need to be able to determing *which* +// underlying detector is giving us new information. Thus we use delegate +// instantions to allow for a disambiguation about the source of a +// PrinterDetector callback from one of the detectors being combined. +class ObserverDelegate : public PrinterDetector::Observer { + public: + ObserverDelegate(CombiningPrinterDetectorImpl* parent, + PrinterDetector* detector) + : parent_(parent), observer_(this) { + observer_.Add(detector); + } + void OnPrintersFound(const std::vector<Printer>& printers) override; + void OnPrinterScanComplete() override; + + private: + CombiningPrinterDetectorImpl* parent_; + ScopedObserver<PrinterDetector, PrinterDetector::Observer> observer_; +}; + +class CombiningPrinterDetectorImpl : public CombiningPrinterDetector { + public: + ~CombiningPrinterDetectorImpl() override = default; + + void AddDetector(PrinterDetector* detector) override { + detectors_.push_back(detector); + delegates_.push_back(base::MakeUnique<ObserverDelegate>(this, detector)); + printers_.insert({delegates_.back().get(), detector->GetPrinters()}); + scan_done_[delegates_.back().get()] = false; + } + + void AddOwnedDetector(std::unique_ptr<PrinterDetector> detector) override { + AddDetector(detector.get()); + owned_detectors_.emplace_back(std::move(detector)); + } + + // PrinterDetector implementations. + void AddObserver(PrinterDetector::Observer* observer) override { + observer_list_.AddObserver(observer); + } + + void RemoveObserver(PrinterDetector::Observer* observer) override { + observer_list_.RemoveObserver(observer); + } + + // Note this is *not* the PrinterDetectorObserver interface directly, + // it's the entry point for ObserverDelegates to pass along those messages + // into this class. + void OnPrintersFound(const ObserverDelegate* source, + const std::vector<Printer>& printers) { + // If this object doesn't know about the delegate trying to update its + // printers, we missed delegate registration somehow, which shouldn't + // happen. + DCHECK(base::ContainsKey(printers_, source)); + printers_[source] = printers; + std::vector<Printer> all_printers = GetPrinters(); + for (PrinterDetector::Observer& observer : observer_list_) { + observer.OnPrintersFound(all_printers); + } + } + + void OnPrinterScanComplete(const ObserverDelegate* source) { + DCHECK(base::ContainsKey(printers_, source)); + bool& scan_done = scan_done_[source]; + if (!scan_done) { + scan_done = true; + for (const auto& entry : scan_done_) { + if (!entry.second) { + // Not all done yet. + return; + } + } + // Final outstanding scan just finished, notify observers. + for (PrinterDetector::Observer& observer : observer_list_) { + observer.OnPrinterScanComplete(); + } + } + } + + // Aggregate the printers from all underlying sources and return them. + std::vector<Printer> GetPrinters() override { + std::vector<Printer> ret; + for (const auto& entry : printers_) { + ret.insert(ret.end(), entry.second.begin(), entry.second.end()); + } + return ret; + } + + void Start() override { + for (PrinterDetector* detector : detectors_) { + detector->Start(); + } + } + + private: + // Map from observer delegate to the most recent list of printers from that + // observer. + std::map<const ObserverDelegate*, std::vector<Printer>> printers_; + + // Map from observer delegate to whether or not that observer has completed + // its scan. + std::map<const ObserverDelegate*, bool> scan_done_; + + // Observers of this object. + base::ObserverList<PrinterDetector::Observer> observer_list_; + + std::vector<std::unique_ptr<PrinterDetector>> owned_detectors_; + + // Memory management -- this just exists to ensure that the held + // elements get cleaned up. + std::vector<std::unique_ptr<ObserverDelegate>> delegates_; + + // All detectors used by the combining detector, owned or unowned. + std::vector<PrinterDetector*> detectors_; +}; + +void ObserverDelegate::OnPrintersFound(const std::vector<Printer>& printers) { + parent_->OnPrintersFound(this, printers); +} + +void ObserverDelegate::OnPrinterScanComplete() { + parent_->OnPrinterScanComplete(this); +} + +} // namespace + +// static +std::unique_ptr<CombiningPrinterDetector> CombiningPrinterDetector::Create() { + return base::MakeUnique<CombiningPrinterDetectorImpl>(); +} + +} // namespace chromeos
diff --git a/chrome/browser/chromeos/printing/combining_printer_detector.h b/chrome/browser/chromeos/printing/combining_printer_detector.h new file mode 100644 index 0000000..fcba36f --- /dev/null +++ b/chrome/browser/chromeos/printing/combining_printer_detector.h
@@ -0,0 +1,34 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_PRINTING_COMBINING_PRINTER_DETECTOR_H_ +#define CHROME_BROWSER_CHROMEOS_PRINTING_COMBINING_PRINTER_DETECTOR_H_ + +#include <memory> + +#include "chrome/browser/chromeos/printing/printer_detector.h" + +namespace chromeos { + +// CombiningPrinterDetector implements PrinterDetector and exports the combined +// results of one or more underlying PrinterDetectors. +class CHROMEOS_EXPORT CombiningPrinterDetector : public PrinterDetector { + public: + // Static factory + static std::unique_ptr<CombiningPrinterDetector> Create(); + + ~CombiningPrinterDetector() override = default; + + // Add an underlying detector to be used. Ownership is not taken. All + // detectors should be added on the same sequence. Calling AddDetector after + // observers have been added is disallowed. + virtual void AddDetector(PrinterDetector* detector) = 0; + + // Same as AddDetector, but ownership of the detector is taken. + virtual void AddOwnedDetector(std::unique_ptr<PrinterDetector> detector) = 0; +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_PRINTING_COMBINING_PRINTER_DETECTOR_H_
diff --git a/chrome/browser/chromeos/printing/combining_printer_detector_unittest.cc b/chrome/browser/chromeos/printing/combining_printer_detector_unittest.cc new file mode 100644 index 0000000..478b923 --- /dev/null +++ b/chrome/browser/chromeos/printing/combining_printer_detector_unittest.cc
@@ -0,0 +1,220 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/printing/combining_printer_detector.h" + +#include <algorithm> +#include <memory> +#include <set> +#include <string> +#include <utility> +#include <vector> + +#include "base/memory/ptr_util.h" +#include "base/observer_list.h" +#include "base/strings/string_util.h" +#include "chromeos/printing/printer_configuration.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromeos { + +namespace { +// Fake printer detectors used as the source of detections to be combined. +class FakePrinterDetector : public PrinterDetector { + public: + explicit FakePrinterDetector( + const std::vector<std::string>& starting_printers) + : printer_ids_(starting_printers.begin(), starting_printers.end()) {} + + ~FakePrinterDetector() override = default; + + void Start() override {} + + // Add these printers to the list of detected printers, and notify + // downstream observers. + void AddPrinters(const std::vector<std::string>& ids) { + for (const std::string& id : ids) { + CHECK(printer_ids_.insert(id).second) + << "Cowardly refusing to add printer with duplicate id " << id; + } + Notify(); + } + + // Remove these printers from the list of detected printers, and notify + // downstream observers. + void RemovePrinters(const std::vector<std::string>& ids) { + for (const std::string id : ids) { + CHECK_EQ(printer_ids_.erase(id), static_cast<size_t>(1)) + << "Can't remove printer with nonexistant id " << id; + } + Notify(); + } + + // Tell downstream observers that we're done finding printers. + void PrinterScanComplete() { + for (PrinterDetector::Observer& observer : observer_list_) { + observer.OnPrinterScanComplete(); + } + } + + // PrinterDetector implementations. + void AddObserver(PrinterDetector::Observer* observer) override { + observer_list_.AddObserver(observer); + } + + void RemoveObserver(PrinterDetector::Observer* observer) override { + observer_list_.RemoveObserver(observer); + } + + std::vector<Printer> GetPrinters() override { + std::vector<Printer> printers; + for (const std::string& id : printer_ids_) { + printers.push_back(Printer(id)); + } + return printers; + } + + private: + void Notify() { + std::vector<Printer> printers = GetPrinters(); + for (PrinterDetector::Observer& observer : observer_list_) { + observer.OnPrintersFound(printers); + } + } + + base::ObserverList<PrinterDetector::Observer> observer_list_; + + // In the fake, we only use printer ids to figure out if the right printers + // are being propagated. So internally we just track ids and construct + // printers on the fly when asked for them. + std::set<std::string> printer_ids_; +}; + +class PrintingCombiningPrinterDetectorTest : public testing::Test, + public PrinterDetector::Observer { + public: + void Init(const std::vector<std::vector<std::string>>& id_lists) { + combining_detector_ = CombiningPrinterDetector::Create(); + + bool test_owned = false; + for (const std::vector<std::string>& id_list : id_lists) { + // Divide up fake detectors between owned and unowned to exercise both + // paths. It shouldn't really matter in the test below where ownership of + // a specific fake detector lies. + auto fake_detector = base::MakeUnique<FakePrinterDetector>(id_list); + fake_detectors_.push_back(fake_detector.get()); + if (test_owned) { + combining_detector_->AddDetector(fake_detector.get()); + owned_fake_detectors_.emplace_back(std::move(fake_detector)); + } else { + combining_detector_->AddOwnedDetector(std::move(fake_detector)); + } + test_owned = !test_owned; + } + combining_detector_->AddObserver(this); + combining_detector_->Start(); + printers_ = combining_detector_->GetPrinters(); + } + + void OnPrintersFound(const std::vector<Printer>& printers) override { + printers_ = printers; + } + + void OnPrinterScanComplete() override { scan_complete_ = true; } + + protected: + // Testing utility function -- return true if the printers we got in the most + // recent OnPrintersFound call are the same as printers (without considering + // order). + void ExpectFoundPrintersAre(const std::vector<std::string>& expected_ids) { + std::vector<std::string> sorted_expected(expected_ids.begin(), + expected_ids.end()); + std::vector<std::string> sorted_actual; + for (const Printer& printer : printers_) { + sorted_actual.push_back(printer.id()); + } + std::sort(sorted_expected.begin(), sorted_expected.end()); + std::sort(sorted_actual.begin(), sorted_actual.end()); + if (sorted_expected != sorted_actual) { + ADD_FAILURE() << "Printer ids mismatch. Expected: {" + << base::JoinString(sorted_expected, ", ") << "}; Found: {" + << base::JoinString(sorted_actual, ", ") << "}"; + } + } + + // Have we been notified that the scan is complete? + bool scan_complete_ = false; + + // The printers in the most recent OnPrintersFound call. + std::vector<Printer> printers_; + + // The fake detectors plugged into the combining detector. + std::vector<FakePrinterDetector*> fake_detectors_; + + // Cleanup pointers for fake detectors owned by the test. (The + // other fake detectors are owned by the combining_detector. + std::vector<std::unique_ptr<FakePrinterDetector>> owned_fake_detectors_; + + std::unique_ptr<CombiningPrinterDetector> combining_detector_; +}; + +TEST_F(PrintingCombiningPrinterDetectorTest, BasicUsage) { + Init({{"1a"}, std::vector<std::string>(), {"3a"}}); + ExpectFoundPrintersAre({"1a", "3a"}); + EXPECT_FALSE(scan_complete_); + + // Find some printers in the second detector. + fake_detectors_[1]->AddPrinters({"2a", "2b", "2c"}); + ExpectFoundPrintersAre({"1a", "2a", "2b", "2c", "3a"}); + EXPECT_FALSE(scan_complete_); + + // Find some printers on the first detector. + fake_detectors_[0]->AddPrinters({"1b"}); + ExpectFoundPrintersAre({"1a", "1b", "2a", "2b", "2c", "3a"}); + EXPECT_FALSE(scan_complete_); + + // Have the first detector signal completion, the combined detector should + // not be complete until all 3 fake detectors have completed. + fake_detectors_[0]->PrinterScanComplete(); + EXPECT_FALSE(scan_complete_); + ExpectFoundPrintersAre({"1a", "1b", "2a", "2b", "2c", "3a"}); + + // Exercise removal of a printer. + fake_detectors_[2]->RemovePrinters({"3a"}); + EXPECT_FALSE(scan_complete_); + ExpectFoundPrintersAre({"1a", "1b", "2a", "2b", "2c"}); + + // Mark the 3rd detector as complete. The 2nd detector has still not declared + // itself complete. + fake_detectors_[2]->PrinterScanComplete(); + EXPECT_FALSE(scan_complete_); + ExpectFoundPrintersAre({"1a", "1b", "2a", "2b", "2c"}); + + // Multiple scan complete calls from the same detector shouldn't happen, but + // if they do happen, it should be a nop. + fake_detectors_[2]->PrinterScanComplete(); + EXPECT_FALSE(scan_complete_); + ExpectFoundPrintersAre({"1a", "1b", "2a", "2b", "2c"}); + + // We can still add printers from a detector that has declared itself + // complete. + fake_detectors_[0]->AddPrinters({"1c"}); + ExpectFoundPrintersAre({"1a", "1b", "1c", "2a", "2b", "2c"}); + EXPECT_FALSE(scan_complete_); + + // Finally the 2nd detector declares itself complete, which should mean the + // combined detector is now complete. + fake_detectors_[1]->PrinterScanComplete(); + EXPECT_TRUE(scan_complete_); + ExpectFoundPrintersAre({"1a", "1b", "1c", "2a", "2b", "2c"}); + + // Should still be able to add printers even after completion. + fake_detectors_[2]->AddPrinters({"3g", "3h", "3i"}); + EXPECT_TRUE(scan_complete_); + ExpectFoundPrintersAre( + {"1a", "1b", "1c", "2a", "2b", "2c", "3g", "3h", "3i"}); +} + +} // namespace +} // namespace chromeos
diff --git a/chrome/browser/chromeos/printing/printer_detector.h b/chrome/browser/chromeos/printing/printer_detector.h new file mode 100644 index 0000000..eba88bdd --- /dev/null +++ b/chrome/browser/chromeos/printing/printer_detector.h
@@ -0,0 +1,63 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_PRINTING_PRINTER_DETECTOR_H_ +#define CHROME_BROWSER_CHROMEOS_PRINTING_PRINTER_DETECTOR_H_ + +#include <vector> + +#include "chromeos/printing/printer_configuration.h" + +namespace chromeos { + +// Interface for automatic printer detection. This API allows for +// incremental discovery of printers and notification when discovery +// is complete. +// +// All of the interface calls in this class must be called from the +// same sequence, but do not have to be on any specific thread. +// +// The usual usage of this interface by a class that wants to maintain +// an up-to-date list of the printers detected is this: +// +// auto detector_ = PrinterDetectorImplementation::Create(); +// detector_->AddObserver(this); +// printers_ = detector_->GetPrinters(); +// +class CHROMEOS_EXPORT PrinterDetector { + public: + class Observer { + public: + virtual ~Observer() = default; + + // Called with a collection of printers as they are discovered. On each + // call |printers| is the full set of known printers; it is not + // incremental; printers may be added or removed. + virtual void OnPrintersFound(const std::vector<Printer>& printers) = 0; + + // Called when we are done with the initial scan for printers. We may + // still call OnPrintersFound if the set of available printers + // changes, but the user can conclude that if a printer is currently + // available and not in the list, we're not still looking for it. + virtual void OnPrinterScanComplete() = 0; + }; + + virtual ~PrinterDetector() = default; + + // Start scanning for printers. No observer callbacks will be performed + // until this is called. + virtual void Start() = 0; + + // Observer management. Observer callbacks will be performed on the + // calling sequence. + virtual void AddObserver(Observer* observer) = 0; + virtual void RemoveObserver(Observer* observer) = 0; + + // Get the current list of known printers. + virtual std::vector<Printer> GetPrinters() = 0; +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_PRINTING_PRINTER_DETECTOR_H_
diff --git a/chrome/browser/chromeos/printing/usb_printer_detector.cc b/chrome/browser/chromeos/printing/usb_printer_detector.cc index 5ce8fb6..3be8d30 100644 --- a/chrome/browser/chromeos/printing/usb_printer_detector.cc +++ b/chrome/browser/chromeos/printing/usb_printer_detector.cc
@@ -107,6 +107,15 @@ return GetPrintersLocked(); } + void Start() override { + started_ = true; + observer_list_->Notify(FROM_HERE, + &PrinterDetector::Observer::OnPrintersFound, + GetPrintersLocked()); + observer_list_->Notify(FROM_HERE, + &PrinterDetector::Observer::OnPrinterScanComplete); + } + private: std::vector<Printer> GetPrintersLocked() { pp_lock_.AssertAcquired(); @@ -143,13 +152,14 @@ base::AutoLock auto_lock(pp_lock_); if (base::ContainsKey(present_printers_, device->guid())) { present_printers_.erase(device->guid()); - auto printers = GetPrintersLocked(); - // We already have pp_lock_, so need to call the pre-locked version of - // GetPrinters to prevent deadlock. - observer_list_->Notify( - FROM_HERE, - &UsbPrinterDetector::Observer::OnAvailableUsbPrintersChanged, - GetPrintersLocked()); + if (started_) { + auto printers = GetPrintersLocked(); + // We already have pp_lock_, so need to call the pre-locked version of + // GetPrinters to prevent deadlock. + observer_list_->Notify(FROM_HERE, + &PrinterDetector::Observer::OnPrintersFound, + GetPrintersLocked()); + } } else { // If the device has been removed but it's not in present_printers_, it // must still be in the setup flow. @@ -274,12 +284,15 @@ } else { base::AutoLock auto_lock(pp_lock_); present_printers_.emplace(data->device->guid(), std::move(data->printer)); - observer_list_->Notify( - FROM_HERE, - &UsbPrinterDetector::Observer::OnAvailableUsbPrintersChanged, - GetPrintersLocked()); + if (started_) { + observer_list_->Notify(FROM_HERE, + &PrinterDetector::Observer::OnPrintersFound, + GetPrintersLocked()); + } } } + // Has Start() been called yet? + bool started_ = false; // Map from USB GUID to Printer that we have detected as being currently // plugged in and have finished processing. Note present_printers_ may be
diff --git a/chrome/browser/chromeos/printing/usb_printer_detector.h b/chrome/browser/chromeos/printing/usb_printer_detector.h index 1e5c9d9f..3482ab97 100644 --- a/chrome/browser/chromeos/printing/usb_printer_detector.h +++ b/chrome/browser/chromeos/printing/usb_printer_detector.h
@@ -10,6 +10,7 @@ #include <vector> #include "base/macros.h" +#include "chrome/browser/chromeos/printing/printer_detector.h" #include "chromeos/printing/printer_configuration.h" #include "components/keyed_service/core/keyed_service.h" @@ -17,30 +18,17 @@ namespace chromeos { -// Observes device::UsbService for addition of USB printers (devices with -// interface class 7). When a device is detected, it is forwarded to the -// printing subsystem for either autoconfiguration or user guidance. -class UsbPrinterDetector : public KeyedService { +// Observes device::UsbService for addition of USB printers. When a new USB +// printer that is not already configured for this user is found, if it can be +// automatically configured for printing, that is done. USB printers that +// cannot be automatically configured are exposed via the PrinterDetector +// interface so that higher level processing can handle them. +class UsbPrinterDetector : public PrinterDetector, public KeyedService { public: - class Observer { - public: - virtual ~Observer() = default; - - // The set of available printers has changed. - virtual void OnAvailableUsbPrintersChanged( - const std::vector<Printer>& printers) = 0; - }; - // Factory function for the CUPS implementation. static std::unique_ptr<UsbPrinterDetector> Create(Profile* profile); ~UsbPrinterDetector() override = default; - virtual void AddObserver(Observer* observer) = 0; - virtual void RemoveObserver(Observer* observer) = 0; - - // Get the current set of detected printers. - virtual std::vector<Printer> GetPrinters() = 0; - protected: UsbPrinterDetector() = default;
diff --git a/chrome/browser/component_updater/pepper_flash_component_installer.cc b/chrome/browser/component_updater/pepper_flash_component_installer.cc index f15ed8dc..5e2b492d 100644 --- a/chrome/browser/component_updater/pepper_flash_component_installer.cc +++ b/chrome/browser/component_updater/pepper_flash_component_installer.cc
@@ -24,7 +24,7 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" -#include "base/threading/sequenced_worker_pool.h" +#include "base/task_scheduler/post_task.h" #include "base/version.h" #include "build/build_config.h" #include "chrome/browser/component_updater/component_installer_errors.h" @@ -286,9 +286,9 @@ } #if defined(OS_CHROMEOS) - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&ImageLoaderRegistration, version, install_dir)); + content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::UI) + ->PostTask(FROM_HERE, base::BindOnce(&ImageLoaderRegistration, version, + install_dir)); #elif defined(OS_LINUX) const base::FilePath flash_path = install_dir.Append(chrome::kPepperFlashPluginFilename); @@ -312,8 +312,9 @@ // Flash version, so we do not do this. RegisterPepperFlashWithChrome(path.Append(chrome::kPepperFlashPluginFilename), version); - BrowserThread::GetBlockingPool()->PostTask( - FROM_HERE, base::Bind(&UpdatePathService, path)); + base::PostTaskWithTraits(FROM_HERE, + {base::TaskPriority::BACKGROUND, base::MayBlock()}, + base::BindOnce(&UpdatePathService, path)); #endif // !defined(OS_LINUX) }
diff --git a/chrome/browser/component_updater/pnacl_component_installer.cc b/chrome/browser/component_updater/pnacl_component_installer.cc index bd0206ad..c4857dd8 100644 --- a/chrome/browser/component_updater/pnacl_component_installer.cc +++ b/chrome/browser/component_updater/pnacl_component_installer.cc
@@ -21,6 +21,9 @@ #include "base/macros.h" #include "base/path_service.h" #include "base/strings/string_util.h" +#include "base/task_scheduler/post_task.h" +#include "base/threading/thread_restrictions.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/values.h" #include "base/version.h" #include "build/build_config.h" @@ -331,7 +334,7 @@ // a hosted version is actually newer. void StartPnaclUpdateRegistration( const scoped_refptr<PnaclComponentInstaller>& pci) { - DCHECK_CURRENTLY_ON(BrowserThread::FILE); + base::ThreadRestrictions::AssertIOAllowed(); base::FilePath path = pci->GetPnaclBaseDirectory(); if (!base::PathExists(path)) { if (!base::CreateDirectory(path)) { @@ -365,12 +368,10 @@ } } - BrowserThread::PostTask(BrowserThread::UI, - FROM_HERE, - base::Bind(&FinishPnaclUpdateRegistration, - current_version, - current_fingerprint, - pci)); + BrowserThread::GetTaskRunnerForThread(BrowserThread::UI) + ->PostTask(FROM_HERE, + base::BindOnce(&FinishPnaclUpdateRegistration, current_version, + current_fingerprint, pci)); // Remove older versions of PNaCl. for (std::vector<base::FilePath>::iterator iter = older_dirs.begin(); @@ -385,9 +386,9 @@ void PnaclComponentInstaller::RegisterPnaclComponent( ComponentUpdateService* cus) { cus_ = cus; - BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, - base::Bind(&StartPnaclUpdateRegistration, make_scoped_refptr(this))); + base::PostTaskWithTraits( + FROM_HERE, {base::TaskPriority::BACKGROUND, base::MayBlock()}, + base::BindOnce(&StartPnaclUpdateRegistration, make_scoped_refptr(this))); } } // namespace component_updater
diff --git a/chrome/browser/component_updater/sth_set_component_installer.cc b/chrome/browser/component_updater/sth_set_component_installer.cc index 9b009cf74..0f678dd 100644 --- a/chrome/browser/component_updater/sth_set_component_installer.cc +++ b/chrome/browser/component_updater/sth_set_component_installer.cc
@@ -14,7 +14,7 @@ #include "base/logging.h" #include "base/path_service.h" #include "base/strings/string_number_conversions.h" -#include "base/threading/sequenced_worker_pool.h" +#include "base/task_scheduler/post_task.h" #include "base/values.h" #include "base/version.h" #include "chrome/browser/net/sth_distributor_provider.h" @@ -77,12 +77,11 @@ const base::Version& version, const base::FilePath& install_dir, std::unique_ptr<base::DictionaryValue> manifest) { - const base::Closure load_sths_closure = base::Bind( - &STHSetComponentInstallerTraits::LoadSTHsFromDisk, - weak_ptr_factory_.GetWeakPtr(), GetInstalledPath(install_dir), version); - - content::BrowserThread::PostAfterStartupTask( - FROM_HERE, content::BrowserThread::GetBlockingPool(), load_sths_closure); + base::PostTaskWithTraits( + FROM_HERE, {base::TaskPriority::BACKGROUND, base::MayBlock()}, + base::BindOnce(&STHSetComponentInstallerTraits::LoadSTHsFromDisk, + weak_ptr_factory_.GetWeakPtr(), + GetInstalledPath(install_dir), version)); } // Called during startup and installation before ComponentReady(). @@ -179,10 +178,11 @@ // The log id is not a part of the response, fill in manually. signed_tree_head.log_id = log_id; - content::BrowserThread::PostTask( - content::BrowserThread::IO, FROM_HERE, - base::Bind(&net::ct::STHObserver::NewSTHObserved, - base::Unretained(sth_observer_), signed_tree_head)); + content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::IO) + ->PostTask( + FROM_HERE, + base::BindOnce(&net::ct::STHObserver::NewSTHObserved, + base::Unretained(sth_observer_), signed_tree_head)); } void STHSetComponentInstallerTraits::OnJsonParseError(
diff --git a/chrome/browser/download/download_commands.cc b/chrome/browser/download/download_commands.cc index 23fc2938..a4a6040e 100644 --- a/chrome/browser/download/download_commands.cc +++ b/chrome/browser/download/download_commands.cc
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" +#include "base/task_scheduler/post_task.h" #include "base/threading/sequenced_worker_pool.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" @@ -49,24 +50,25 @@ class ImageClipboardCopyManager : public ImageDecoder::ImageRequest { public: - static void Start(const base::FilePath& file_path) { - new ImageClipboardCopyManager(file_path); + static void Start(const base::FilePath& file_path, + base::SequencedTaskRunner* task_runner) { + new ImageClipboardCopyManager(file_path, task_runner); } private: - explicit ImageClipboardCopyManager(const base::FilePath& file_path) + ImageClipboardCopyManager(const base::FilePath& file_path, + base::SequencedTaskRunner* task_runner) : file_path_(file_path) { // Constructor must be called in the UI thread. DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - content::BrowserThread::GetBlockingPool()->PostTask( + task_runner->PostTask( FROM_HERE, base::BindOnce(&ImageClipboardCopyManager::StartDecoding, base::Unretained(this))); } void StartDecoding() { - DCHECK(content::BrowserThread::GetBlockingPool()-> - RunsTasksInCurrentSequence()); + base::ThreadRestrictions::AssertIOAllowed(); // Re-check the filesize since the file may be modified after downloaded. int64_t filesize; @@ -126,6 +128,8 @@ DCHECK(download_item); } +DownloadCommands::~DownloadCommands() = default; + int DownloadCommands::GetCommandIconId(Command command) const { switch (command) { case PAUSE: @@ -397,7 +401,7 @@ #endif } -void DownloadCommands::CopyFileAsImageToClipboard() const { +void DownloadCommands::CopyFileAsImageToClipboard() { if (download_item_->GetState() != content::DownloadItem::COMPLETE || download_item_->GetReceivedBytes() > kMaxImageClipboardSize) { return; @@ -407,5 +411,11 @@ return; base::FilePath file_path = download_item_->GetFullPath(); - ImageClipboardCopyManager::Start(file_path); + + if (!task_runner_) { + task_runner_ = base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::BACKGROUND, + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}); + } + ImageClipboardCopyManager::Start(file_path, task_runner_.get()); }
diff --git a/chrome/browser/download/download_commands.h b/chrome/browser/download/download_commands.h index e107574..d998ef5 100644 --- a/chrome/browser/download/download_commands.h +++ b/chrome/browser/download/download_commands.h
@@ -33,7 +33,7 @@ // |download_item| must outlive DownloadCommands. explicit DownloadCommands(content::DownloadItem* download_item); - virtual ~DownloadCommands() {} + virtual ~DownloadCommands(); gfx::Image GetCommandIcon(Command command); @@ -55,9 +55,11 @@ Browser* GetBrowser() const; int GetCommandIconId(Command command) const; GURL GetLearnMoreURLForInterruptedDownload() const; - void CopyFileAsImageToClipboard() const; + void CopyFileAsImageToClipboard(); content::DownloadItem* const download_item_; + + scoped_refptr<base::SequencedTaskRunner> task_runner_; }; #endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_COMMANDS_H_
diff --git a/chrome/browser/extensions/api/cookies/cookies_helpers.cc b/chrome/browser/extensions/api/cookies/cookies_helpers.cc index bcb3066..42ca67b 100644 --- a/chrome/browser/extensions/api/cookies/cookies_helpers.cc +++ b/chrome/browser/extensions/api/cookies/cookies_helpers.cc
@@ -121,13 +121,13 @@ void GetCookieListFromStore( net::CookieStore* cookie_store, const GURL& url, - const net::CookieMonster::GetCookieListCallback& callback) { + net::CookieMonster::GetCookieListCallback callback) { DCHECK(cookie_store); if (!url.is_empty()) { DCHECK(url.is_valid()); - cookie_store->GetAllCookiesForURLAsync(url, callback); + cookie_store->GetAllCookiesForURLAsync(url, std::move(callback)); } else { - cookie_store->GetAllCookiesAsync(callback); + cookie_store->GetAllCookiesAsync(std::move(callback)); } }
diff --git a/chrome/browser/extensions/api/cookies/cookies_helpers.h b/chrome/browser/extensions/api/cookies/cookies_helpers.h index 28a1941..0fa58c69 100644 --- a/chrome/browser/extensions/api/cookies/cookies_helpers.h +++ b/chrome/browser/extensions/api/cookies/cookies_helpers.h
@@ -58,10 +58,9 @@ // Retrieves all cookies from the given cookie store corresponding to the given // URL. If the URL is empty, all cookies in the cookie store are retrieved. // This can only be called on the IO thread. -void GetCookieListFromStore( - net::CookieStore* cookie_store, - const GURL& url, - const net::CookieMonster::GetCookieListCallback& callback); +void GetCookieListFromStore(net::CookieStore* cookie_store, + const GURL& url, + net::CookieMonster::GetCookieListCallback callback); // Constructs a URL from a cookie's information for use in checking // a cookie against the extension's host permissions. The Secure
diff --git a/chrome/browser/extensions/api/desktop_capture/desktop_capture_apitest.cc b/chrome/browser/extensions/api/desktop_capture/desktop_capture_apitest.cc index da76a6d0..796f1f37 100644 --- a/chrome/browser/extensions/api/desktop_capture/desktop_capture_apitest.cc +++ b/chrome/browser/extensions/api/desktop_capture/desktop_capture_apitest.cc
@@ -23,6 +23,8 @@ #include "net/test/embedded_test_server/embedded_test_server.h" #include "third_party/webrtc/modules/desktop_capture/desktop_capture_types.h" +using content::DesktopMediaID; + namespace extensions { namespace { @@ -56,9 +58,7 @@ gfx::NativeWindow parent, const base::string16& app_name, const base::string16& target_name, - std::unique_ptr<DesktopMediaList> screen_list, - std::unique_ptr<DesktopMediaList> window_list, - std::unique_ptr<DesktopMediaList> tab_list, + std::vector<std::unique_ptr<DesktopMediaList>> source_lists, bool request_audio, const DoneCallback& done_callback) override { if (!expectation_->cancelled) { @@ -115,11 +115,14 @@ EXPECT_EQ(test_flags_[current_test_].expect_audio, show_audio); media_lists[0] = std::unique_ptr<DesktopMediaList>( - show_screens ? new FakeDesktopMediaList() : nullptr); + show_screens ? new FakeDesktopMediaList(DesktopMediaID::TYPE_SCREEN) + : nullptr); media_lists[1] = std::unique_ptr<DesktopMediaList>( - show_windows ? new FakeDesktopMediaList() : nullptr); + show_windows ? new FakeDesktopMediaList(DesktopMediaID::TYPE_WINDOW) + : nullptr); media_lists[2] = std::unique_ptr<DesktopMediaList>( - show_tabs ? new FakeDesktopMediaList() : nullptr); + show_tabs ? new FakeDesktopMediaList(DesktopMediaID::TYPE_WEB_CONTENTS) + : nullptr); return media_lists; }
diff --git a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc index e9ee3550..29763ff 100644 --- a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc +++ b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc
@@ -29,6 +29,8 @@ #include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h" #include "ui/base/l10n/l10n_util.h" +using content::DesktopMediaID; + namespace extensions { namespace { @@ -85,23 +87,34 @@ bool show_tabs = false; bool request_audio = false; + std::vector<DesktopMediaID::Type> source_types; + for (auto source_type : sources) { + // Avoid duplicates in the input |sources|. + if (std::find(source_types.begin(), source_types.end(), source_type) != + source_types.end()) { + continue; + } + switch (source_type) { case api::desktop_capture::DESKTOP_CAPTURE_SOURCE_TYPE_NONE: error_ = kInvalidSourceNameError; return false; case api::desktop_capture::DESKTOP_CAPTURE_SOURCE_TYPE_SCREEN: + source_types.push_back(DesktopMediaID::TYPE_SCREEN); show_screens = true; break; case api::desktop_capture::DESKTOP_CAPTURE_SOURCE_TYPE_WINDOW: + source_types.push_back(DesktopMediaID::TYPE_WINDOW); show_windows = true; break; case api::desktop_capture::DESKTOP_CAPTURE_SOURCE_TYPE_TAB: if (!base::CommandLine::ForCurrentProcess()->HasSwitch( extensions::switches::kDisableTabForDesktopShare)) { + source_types.push_back(DesktopMediaID::TYPE_WEB_CONTENTS); show_tabs = true; } break; @@ -145,14 +158,14 @@ // Create a screens list. if (show_screens) { #if defined(USE_ASH) - screen_list = base::MakeUnique<DesktopMediaListAsh>( - content::DesktopMediaID::TYPE_SCREEN); + screen_list = + base::MakeUnique<DesktopMediaListAsh>(DesktopMediaID::TYPE_SCREEN); #else // !defined(USE_ASH) webrtc::DesktopCaptureOptions capture_options = webrtc::DesktopCaptureOptions::CreateDefault(); capture_options.set_disable_effects(false); screen_list = base::MakeUnique<NativeDesktopMediaList>( - content::DesktopMediaID::TYPE_SCREEN, + DesktopMediaID::TYPE_SCREEN, webrtc::DesktopCapturer::CreateScreenCapturer(capture_options)); #endif // !defined(USE_ASH) } @@ -160,8 +173,8 @@ // Create a windows list. if (show_windows) { #if defined(USE_ASH) - window_list = base::MakeUnique<DesktopMediaListAsh>( - content::DesktopMediaID::TYPE_WINDOW); + window_list = + base::MakeUnique<DesktopMediaListAsh>(DesktopMediaID::TYPE_WINDOW); #else // !defined(USE_ASH) // NativeDesktopMediaList calls the capturers on a background // thread. This means that the two DesktopCapturer instances (for screens @@ -172,7 +185,7 @@ webrtc::DesktopCaptureOptions::CreateDefault(); capture_options.set_disable_effects(false); window_list = base::MakeUnique<NativeDesktopMediaList>( - content::DesktopMediaID::TYPE_WINDOW, + DesktopMediaID::TYPE_WINDOW, webrtc::DesktopCapturer::CreateWindowCapturer(capture_options)); #endif // !defined(USE_ASH) } @@ -181,6 +194,7 @@ tab_list = base::MakeUnique<TabDesktopMediaList>(); DCHECK(screen_list || window_list || tab_list); + DCHECK(!source_types.empty()); // DesktopMediaPicker is implemented only for Windows, OSX and // Aura Linux builds. @@ -192,14 +206,35 @@ #endif } + // Keep same order as the input |sources|. + std::vector<std::unique_ptr<DesktopMediaList>> source_lists; + for (auto source_type : source_types) { + switch (source_type) { + case DesktopMediaID::TYPE_NONE: + NOTREACHED(); + break; + case DesktopMediaID::TYPE_SCREEN: + if (screen_list) + source_lists.push_back(std::move(screen_list)); + break; + case DesktopMediaID::TYPE_WINDOW: + if (window_list) + source_lists.push_back(std::move(window_list)); + break; + case DesktopMediaID::TYPE_WEB_CONTENTS: + if (tab_list) + source_lists.push_back(std::move(tab_list)); + break; + } + } + DesktopMediaPicker::DoneCallback callback = base::Bind( &DesktopCaptureChooseDesktopMediaFunctionBase::OnPickerDialogResults, this); picker_->Show(web_contents, parent_window, parent_window, base::UTF8ToUTF16(GetCallerDisplayName()), target_name, - std::move(screen_list), std::move(window_list), - std::move(tab_list), request_audio, callback); + std::move(source_lists), request_audio, callback); origin_ = origin; return true; } @@ -219,10 +254,9 @@ } void DesktopCaptureChooseDesktopMediaFunctionBase::OnPickerDialogResults( - content::DesktopMediaID source) { + DesktopMediaID source) { std::string result; - if (source.type != content::DesktopMediaID::TYPE_NONE && - web_contents()) { + if (source.type != DesktopMediaID::TYPE_NONE && web_contents()) { DesktopStreamsRegistry* registry = MediaCaptureDevicesDispatcher::GetInstance()-> GetDesktopStreamsRegistry();
diff --git a/chrome/browser/extensions/chrome_extensions_browser_client.cc b/chrome/browser/extensions/chrome_extensions_browser_client.cc index 0e03d73..c7aee0a 100644 --- a/chrome/browser/extensions/chrome_extensions_browser_client.cc +++ b/chrome/browser/extensions/chrome_extensions_browser_client.cc
@@ -72,6 +72,14 @@ namespace extensions { +namespace { + +// If true, the extensions client will behave as though there is always a +// new chrome update. +bool g_did_chrome_update_for_testing = false; + +} // namespace + ChromeExtensionsBrowserClient::ChromeExtensionsBrowserClient() { process_manager_delegate_.reset(new ChromeProcessManagerDelegate); api_client_.reset(new ChromeExtensionsAPIClient); @@ -209,6 +217,9 @@ if (!extension_prefs) return false; + if (g_did_chrome_update_for_testing) + return true; + // If we're inside a browser test, then assume prefs are all up to date. if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kTestType)) return false; @@ -450,4 +461,11 @@ return false; #endif } + +// static +void ChromeExtensionsBrowserClient::set_did_chrome_update_for_testing( + bool did_update) { + g_did_chrome_update_for_testing = did_update; +} + } // namespace extensions
diff --git a/chrome/browser/extensions/chrome_extensions_browser_client.h b/chrome/browser/extensions/chrome_extensions_browser_client.h index 8f8e6e0b..1905cd3a 100644 --- a/chrome/browser/extensions/chrome_extensions_browser_client.h +++ b/chrome/browser/extensions/chrome_extensions_browser_client.h
@@ -126,6 +126,8 @@ KioskDelegate* GetKioskDelegate() override; bool IsLockScreenContext(content::BrowserContext* context) override; + static void set_did_chrome_update_for_testing(bool did_update); + private: friend struct base::LazyInstanceTraitsBase<ChromeExtensionsBrowserClient>;
diff --git a/chrome/browser/extensions/chrome_test_extension_loader.cc b/chrome/browser/extensions/chrome_test_extension_loader.cc index aef672f..ed1485a3 100644 --- a/chrome/browser/extensions/chrome_test_extension_loader.cc +++ b/chrome/browser/extensions/chrome_test_extension_loader.cc
@@ -8,6 +8,7 @@ #include "base/files/file_util.h" #include "base/run_loop.h" +#include "base/threading/thread_restrictions.h" #include "chrome/browser/extensions/chrome_extension_test_notification_observer.h" #include "chrome/browser/extensions/crx_installer.h" #include "chrome/browser/extensions/extension_creator.h" @@ -33,7 +34,13 @@ extension_service_(extension_system_->extension_service()), extension_registry_(ExtensionRegistry::Get(browser_context)) {} -ChromeTestExtensionLoader::~ChromeTestExtensionLoader() {} +ChromeTestExtensionLoader::~ChromeTestExtensionLoader() { + // If there was a temporary directory created for a CRX, we need to clean it + // up before the member is destroyed so we can explicitly allow IO. + base::ThreadRestrictions::ScopedAllowIO allow_io; + if (temp_dir_.IsValid()) + EXPECT_TRUE(temp_dir_.Delete()); +} scoped_refptr<const Extension> ChromeTestExtensionLoader::LoadExtension( const base::FilePath& path) { @@ -99,6 +106,7 @@ base::FilePath ChromeTestExtensionLoader::PackExtension( const base::FilePath& unpacked_path) { + base::ThreadRestrictions::ScopedAllowIO allow_io; if (!base::PathExists(unpacked_path)) { ADD_FAILURE() << "Unpacked path does not exist: " << unpacked_path.value(); return base::FilePath();
diff --git a/chrome/browser/extensions/events_apitest.cc b/chrome/browser/extensions/events_apitest.cc index 143a82d..da6bf40 100644 --- a/chrome/browser/extensions/events_apitest.cc +++ b/chrome/browser/extensions/events_apitest.cc
@@ -4,12 +4,18 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" +#include "chrome/browser/extensions/chrome_extension_test_notification_observer.h" +#include "chrome/browser/extensions/chrome_extensions_browser_client.h" +#include "chrome/browser/extensions/chrome_test_extension_loader.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/test/base/ui_test_utils.h" #include "extensions/browser/event_router.h" #include "extensions/browser/extension_registry.h" +#include "extensions/browser/process_manager.h" +#include "extensions/browser/process_manager_observer.h" #include "extensions/browser/scoped_ignore_content_verifier_for_test.h" +#include "extensions/test/extension_test_message_listener.h" #include "extensions/test/result_catcher.h" namespace extensions { @@ -211,4 +217,99 @@ } } +class ChromeUpdatesEventsApiTest : public EventsApiTest, + public ProcessManagerObserver { + public: + ChromeUpdatesEventsApiTest() { + // We set this in the constructor (rather than in a SetUp() method) because + // it needs to be done before any of the extensions system is created. + ChromeExtensionsBrowserClient::set_did_chrome_update_for_testing(true); + } + + void SetUpOnMainThread() override { + EventsApiTest::SetUpOnMainThread(); + ProcessManager* process_manager = ProcessManager::Get(profile()); + ProcessManager::Get(profile())->AddObserver(this); + const ProcessManager::FrameSet& frames = process_manager->GetAllFrames(); + for (auto* frame : frames) { + const Extension* extension = + process_manager->GetExtensionForRenderFrameHost(frame); + if (extension) + observed_extension_names_.insert(extension->name()); + } + + updates_listener_ = + base::MakeUnique<ExtensionTestMessageListener>("update event", false); + failure_listener_ = + base::MakeUnique<ExtensionTestMessageListener>("not listening", false); + } + + void TearDownOnMainThread() override { + ProcessManager::Get(profile())->RemoveObserver(this); + ChromeExtensionsBrowserClient::set_did_chrome_update_for_testing(false); + EventsApiTest::TearDownOnMainThread(); + } + + void OnBackgroundHostCreated(ExtensionHost* host) override { + // Use name since it's more deterministic than ID. + observed_extension_names_.insert(host->extension()->name()); + } + + ExtensionTestMessageListener* updates_listener() { + return updates_listener_.get(); + } + ExtensionTestMessageListener* failure_listener() { + return failure_listener_.get(); + } + const std::set<std::string> observed_extension_names() const { + return observed_extension_names_; + } + + private: + std::unique_ptr<ExtensionTestMessageListener> updates_listener_; + std::unique_ptr<ExtensionTestMessageListener> failure_listener_; + + std::set<std::string> observed_extension_names_; + + DISALLOW_COPY_AND_ASSIGN(ChromeUpdatesEventsApiTest); +}; + +IN_PROC_BROWSER_TEST_F(ChromeUpdatesEventsApiTest, PRE_ChromeUpdates) { + { + ChromeTestExtensionLoader loader(profile()); + loader.set_pack_extension(true); + ResultCatcher catcher; + ASSERT_TRUE(loader.LoadExtension( + test_data_dir_.AppendASCII("lazy_events/chrome_updates/listener"))); + EXPECT_TRUE(catcher.GetNextResult()); + } + { + ChromeTestExtensionLoader loader(profile()); + loader.set_pack_extension(true); + ResultCatcher catcher; + ASSERT_TRUE(loader.LoadExtension( + test_data_dir_.AppendASCII("lazy_events/chrome_updates/non_listener"))); + EXPECT_TRUE(catcher.GetNextResult()); + } +} + +// Test that we only dispatch the onInstalled event triggered by a chrome update +// to extensions that have a registered onInstalled listener. +IN_PROC_BROWSER_TEST_F(ChromeUpdatesEventsApiTest, ChromeUpdates) { + ChromeExtensionTestNotificationObserver(browser()) + .WaitForExtensionViewsToLoad(); + + // "chrome updates listener" registerd a listener for the onInstalled event, + // whereas "chrome updates non listener" did not. Only the + // "chrome updates listener" extension should have been woken up for the + // chrome update event. + EXPECT_TRUE(observed_extension_names().count("chrome updates listener")); + EXPECT_FALSE(observed_extension_names().count("chrome updates non listener")); + + EXPECT_TRUE(updates_listener()->WaitUntilSatisfied()); + content::RunAllPendingInMessageLoop(); + content::RunAllBlockingPoolTasksUntilIdle(); + EXPECT_FALSE(failure_listener()->was_satisfied()); +} + } // namespace extensions
diff --git a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc index 9412c6e4..36e5dc1 100644 --- a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc +++ b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
@@ -50,6 +50,7 @@ #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_util.h" #include "components/google/core/browser/google_util.h" +#include "components/offline_pages/features/features.h" #include "components/policy/core/common/cloud/policy_header_io_helper.h" #include "components/previews/core/previews_experiments.h" #include "components/previews/core/previews_io_data.h" @@ -102,11 +103,15 @@ #include "extensions/common/user_script.h" #endif +#if BUILDFLAG(ENABLE_OFFLINE_PAGES) +#include "chrome/browser/offline_pages/offliner_user_data.h" +#include "chrome/browser/offline_pages/resource_loading_observer.h" +#endif + #if defined(OS_ANDROID) #include "chrome/browser/android/download/intercept_download_resource_throttle.h" #include "chrome/browser/android/offline_pages/downloads/resource_throttle.h" #include "chrome/browser/loader/data_reduction_proxy_resource_throttle_android.h" -#include "chrome/browser/offline_pages/background_loader_offliner.h" #include "components/navigation_interception/intercept_navigation_delegate.h" #endif @@ -349,6 +354,40 @@ } } +#if BUILDFLAG(ENABLE_OFFLINE_PAGES) +// Translate content::ResourceType to a type to use for Offliners. +offline_pages::ResourceLoadingObserver::ResourceDataType +ConvertResourceTypeToResourceDataType(content::ResourceType type) { + switch (type) { + case content::RESOURCE_TYPE_STYLESHEET: + return offline_pages::ResourceLoadingObserver::ResourceDataType::TEXT_CSS; + case content::RESOURCE_TYPE_IMAGE: + return offline_pages::ResourceLoadingObserver::ResourceDataType::IMAGE; + default: + return offline_pages::ResourceLoadingObserver::ResourceDataType::OTHER; + } +} + +void NotifyUIThreadOfRequestStarted( + const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter, + ResourceType resource_type) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + content::WebContents* web_contents = web_contents_getter.Run(); + if (!web_contents) + return; + + // If we are producing an offline version of the page, track resource loading. + offline_pages::ResourceLoadingObserver* resource_tracker = + offline_pages::OfflinerUserData::ResourceLoadingObserverFromWebContents( + web_contents); + if (resource_tracker) { + offline_pages::ResourceLoadingObserver::ResourceDataType data_type = + ConvertResourceTypeToResourceDataType(resource_type); + resource_tracker->ObserveResourceLoading(data_type, true /* STARTED */); + } +} +#endif + void NotifyUIThreadOfRequestComplete( const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter, const content::ResourceRequestInfo::FrameTreeNodeIdGetter& @@ -371,20 +410,30 @@ content::WebContents* web_contents = web_contents_getter.Run(); if (!web_contents) return; + if (resource_type == content::RESOURCE_TYPE_MAIN_FRAME) { LogMainFrameMetricsOnUIThread(url, net_error, request_loading_time, web_contents); } + if (!was_cached) { UpdatePrerenderNetworkBytesCallback(web_contents, total_received_bytes); -#if defined(OS_ANDROID) - offline_pages::BackgroundLoaderOffliner* background_loader = - offline_pages::BackgroundLoaderOffliner::FromWebContents(web_contents); - - if (background_loader) - background_loader->OnNetworkBytesChanged(total_received_bytes); -#endif // OS_ANDROID } + +#if BUILDFLAG(ENABLE_OFFLINE_PAGES) + // If we are producing an offline version of the page, track resource loading. + offline_pages::ResourceLoadingObserver* resource_tracker = + offline_pages::OfflinerUserData::ResourceLoadingObserverFromWebContents( + web_contents); + if (resource_tracker) { + offline_pages::ResourceLoadingObserver::ResourceDataType data_type = + ConvertResourceTypeToResourceDataType(resource_type); + resource_tracker->ObserveResourceLoading(data_type, false /* COMPLETED */); + if (!was_cached) + resource_tracker->OnNetworkBytesChanged(total_received_bytes); + } +#endif // BUILDFLAG(ENABLE_OFFLINE_PAGES) + if (!is_download) { page_load_metrics::MetricsWebContentsObserver* metrics_observer = page_load_metrics::MetricsWebContentsObserver::FromWebContents( @@ -458,6 +507,16 @@ const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); +#if BUILDFLAG(ENABLE_OFFLINE_PAGES) + // TODO(petewil): Unify the safe browsing request and the metrics observer + // request if possible so we only have to cross to the main thread once. + // http://crbug.com/712312. + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::Bind(&NotifyUIThreadOfRequestStarted, + info->GetWebContentsGetterForRequest(), + info->GetResourceType())); +#endif // BUILDFLAG(ENABLE_OFFLINE_PAGES) + ProfileIOData* io_data = ProfileIOData::FromResourceContext( resource_context);
diff --git a/chrome/browser/media/webrtc/desktop_media_picker.h b/chrome/browser/media/webrtc/desktop_media_picker.h index d9c75423..6cb1b8e 100644 --- a/chrome/browser/media/webrtc/desktop_media_picker.h +++ b/chrome/browser/media/webrtc/desktop_media_picker.h
@@ -41,9 +41,7 @@ gfx::NativeWindow parent, const base::string16& app_name, const base::string16& target_name, - std::unique_ptr<DesktopMediaList> screen_list, - std::unique_ptr<DesktopMediaList> window_list, - std::unique_ptr<DesktopMediaList> tab_list, + std::vector<std::unique_ptr<DesktopMediaList>> source_lists, bool request_audio, const DoneCallback& done_callback) = 0;
diff --git a/chrome/browser/media/webrtc/fake_desktop_media_list.cc b/chrome/browser/media/webrtc/fake_desktop_media_list.cc index b70fac2..24c2b42 100644 --- a/chrome/browser/media/webrtc/fake_desktop_media_list.cc +++ b/chrome/browser/media/webrtc/fake_desktop_media_list.cc
@@ -10,7 +10,8 @@ using content::DesktopMediaID; -FakeDesktopMediaList::FakeDesktopMediaList() : observer_(NULL) {} +FakeDesktopMediaList::FakeDesktopMediaList(DesktopMediaID::Type type) + : observer_(NULL), type_(type) {} FakeDesktopMediaList::~FakeDesktopMediaList() {} void FakeDesktopMediaList::AddSource(int id) { @@ -74,5 +75,5 @@ } DesktopMediaID::Type FakeDesktopMediaList::GetMediaListType() const { - return DesktopMediaID::TYPE_NONE; + return type_; }
diff --git a/chrome/browser/media/webrtc/fake_desktop_media_list.h b/chrome/browser/media/webrtc/fake_desktop_media_list.h index 09253979..1d36650 100644 --- a/chrome/browser/media/webrtc/fake_desktop_media_list.h +++ b/chrome/browser/media/webrtc/fake_desktop_media_list.h
@@ -11,7 +11,7 @@ class FakeDesktopMediaList : public DesktopMediaList { public: - FakeDesktopMediaList(); + explicit FakeDesktopMediaList(content::DesktopMediaID::Type type); ~FakeDesktopMediaList() override; void AddSource(int id); @@ -34,6 +34,9 @@ std::vector<Source> sources_; DesktopMediaListObserver* observer_; gfx::ImageSkia thumbnail_; + const content::DesktopMediaID::Type type_; + + DISALLOW_COPY_AND_ASSIGN(FakeDesktopMediaList); }; #endif // CHROME_BROWSER_MEDIA_WEBRTC_FAKE_DESKTOP_MEDIA_LIST_H_
diff --git a/chrome/browser/net/crl_set_fetcher.cc b/chrome/browser/net/crl_set_fetcher.cc index 1fba045..a92bbe40 100644 --- a/chrome/browser/net/crl_set_fetcher.cc +++ b/chrome/browser/net/crl_set_fetcher.cc
@@ -10,6 +10,8 @@ #include "base/numerics/safe_conversions.h" #include "base/rand_util.h" #include "base/strings/string_number_conversions.h" +#include "base/task_scheduler/post_task.h" +#include "base/threading/thread_restrictions.h" #include "base/time/time.h" #include "base/trace_event/trace_event.h" #include "chrome/browser/profiles/profile.h" @@ -44,11 +46,9 @@ SetCRLSetFilePath(path); cus_ = cus; - if (!BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, - base::BindOnce(&CRLSetFetcher::DoInitialLoadFromDisk, this))) { - NOTREACHED(); - } + base::PostTaskWithTraits( + FROM_HERE, {base::TaskPriority::BACKGROUND, base::MayBlock()}, + base::BindOnce(&CRLSetFetcher::DoInitialLoadFromDisk, this)); } void CRLSetFetcher::DeleteFromDisk(const base::FilePath& path) { @@ -57,16 +57,14 @@ if (path.empty()) return; SetCRLSetFilePath(path); - if (!BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, - base::BindOnce(&CRLSetFetcher::DoDeleteFromDisk, this))) { - NOTREACHED(); - } + base::PostTaskWithTraits( + FROM_HERE, {base::TaskPriority::BACKGROUND, base::MayBlock()}, + base::BindOnce(&CRLSetFetcher::DoDeleteFromDisk, this)); } void CRLSetFetcher::DoInitialLoadFromDisk() { TRACE_EVENT0("net", "CRLSetFetcher::DoInitialLoadFromDisk"); - DCHECK_CURRENTLY_ON(BrowserThread::FILE); + base::ThreadRestrictions::AssertIOAllowed(); LoadFromDisk(GetCRLSetFilePath(), &crl_set_); @@ -76,9 +74,10 @@ // Get updates, advertising the sequence number of the CRL set that we just // loaded, if any. - if (!BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::BindOnce(&CRLSetFetcher::RegisterComponent, - this, sequence_of_loaded_crl))) { + if (!BrowserThread::GetTaskRunnerForThread(BrowserThread::UI) + ->PostTask(FROM_HERE, + base::BindOnce(&CRLSetFetcher::RegisterComponent, this, + sequence_of_loaded_crl))) { NOTREACHED(); } } @@ -87,7 +86,7 @@ scoped_refptr<net::CRLSet>* out_crl_set) { TRACE_EVENT0("net", "CRLSetFetcher::LoadFromDisk"); - DCHECK_CURRENTLY_ON(BrowserThread::FILE); + base::ThreadRestrictions::AssertIOAllowed(); std::string crl_set_bytes; { @@ -103,9 +102,10 @@ VLOG(1) << "Loaded " << crl_set_bytes.size() << " bytes of CRL set from disk"; - if (!BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::BindOnce(&CRLSetFetcher::SetCRLSetIfNewer, - this, *out_crl_set))) { + if (!BrowserThread::GetTaskRunnerForThread(BrowserThread::IO) + ->PostTask(FROM_HERE, + base::BindOnce(&CRLSetFetcher::SetCRLSetIfNewer, this, + *out_crl_set))) { NOTREACHED(); } } @@ -155,7 +155,7 @@ } void CRLSetFetcher::DoDeleteFromDisk() { - DCHECK_CURRENTLY_ON(BrowserThread::FILE); + base::ThreadRestrictions::AssertIOAllowed(); DeleteFile(GetCRLSetFilePath(), false /* not recursive */); } @@ -233,9 +233,10 @@ crl_set_ = new_crl_set; } - if (!BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - base::BindOnce(&CRLSetFetcher::SetCRLSetIfNewer, this, crl_set_))) { + if (!BrowserThread::GetTaskRunnerForThread(BrowserThread::IO) + ->PostTask(FROM_HERE, + base::BindOnce(&CRLSetFetcher::SetCRLSetIfNewer, this, + crl_set_))) { NOTREACHED(); }
diff --git a/chrome/browser/notifications/notification_channels_provider_android.cc b/chrome/browser/notifications/notification_channels_provider_android.cc index e367a84b..ccbd084 100644 --- a/chrome/browser/notifications/notification_channels_provider_android.cc +++ b/chrome/browser/notifications/notification_channels_provider_android.cc
@@ -102,13 +102,12 @@ content_settings::Rule Next() override { DCHECK(HasNext()); - DCHECK_NE(channels_[index_].status_, - NotificationChannelStatus::UNAVAILABLE); + DCHECK_NE(channels_[index_].status, NotificationChannelStatus::UNAVAILABLE); content_settings::Rule rule = content_settings::Rule( - ContentSettingsPattern::FromString(channels_[index_].origin_), + ContentSettingsPattern::FromString(channels_[index_].origin), ContentSettingsPattern::Wildcard(), new base::Value( - ChannelStatusToContentSetting(channels_[index_].status_))); + ChannelStatusToContentSetting(channels_[index_].status))); index_++; return rule; } @@ -210,8 +209,18 @@ void NotificationChannelsProviderAndroid::ClearAllContentSettingsRules( ContentSettingsType content_type) { - // TODO(crbug.com/700377): If |content_type| == NOTIFICATIONS, delete - // all channels. + if (content_type != CONTENT_SETTINGS_TYPE_NOTIFICATIONS || + !should_use_channels_) { + return; + } + std::vector<NotificationChannel> channels = bridge_->GetChannels(); + for (auto channel : channels) + bridge_->DeleteChannel(channel.origin); + + if (channels.size() > 0) { + NotifyObservers(ContentSettingsPattern(), ContentSettingsPattern(), + content_type, std::string()); + } } void NotificationChannelsProviderAndroid::ShutdownOnUIThread() {
diff --git a/chrome/browser/notifications/notification_channels_provider_android.h b/chrome/browser/notifications/notification_channels_provider_android.h index d8034ba2..6e6dfb265 100644 --- a/chrome/browser/notifications/notification_channels_provider_android.h +++ b/chrome/browser/notifications/notification_channels_provider_android.h
@@ -24,15 +24,15 @@ struct NotificationChannel { NotificationChannel(std::string origin, NotificationChannelStatus status) - : origin_(origin), status_(status) {} + : origin(origin), status(status) {} bool operator==(const NotificationChannel& other) const { - return origin_ == other.origin_ && status_ == other.status_; + return origin == other.origin && status == other.status; } bool operator<(const NotificationChannel& other) const { - return std::tie(origin_, status_) < std::tie(other.origin_, other.status_); + return std::tie(origin, status) < std::tie(other.origin, other.status); } - std::string origin_; - NotificationChannelStatus status_ = NotificationChannelStatus::UNAVAILABLE; + std::string origin; + NotificationChannelStatus status = NotificationChannelStatus::UNAVAILABLE; }; // This class provides notification content settings from system notification
diff --git a/chrome/browser/notifications/notification_channels_provider_android_unittest.cc b/chrome/browser/notifications/notification_channels_provider_android_unittest.cc index 32474ae..d61b8bc5 100644 --- a/chrome/browser/notifications/notification_channels_provider_android_unittest.cc +++ b/chrome/browser/notifications/notification_channels_provider_android_unittest.cc
@@ -265,7 +265,7 @@ EXPECT_CALL(check, Call("2: GetRuleIterator()")); // Now report channel as blocked. - channels[0].status_ = NotificationChannelStatus::BLOCKED; + channels[0].status = NotificationChannelStatus::BLOCKED; EXPECT_CALL(*mock_bridge_, GetChannels()).WillOnce(Return(channels)); // GetRuleIterator should now notify observer. @@ -305,3 +305,50 @@ CONTENT_SETTINGS_TYPE_NOTIFICATIONS, std::string(), new base::Value(CONTENT_SETTING_ALLOW)); } + +TEST_F(NotificationChannelsProviderAndroidTest, + ClearAllContentSettingsRulesDeletesChannelsAndNotifiesObservers) { + InitChannelsProvider(true /* should_use_channels */); + content_settings::MockObserver mock_observer; + channels_provider_->AddObserver(&mock_observer); + + std::vector<NotificationChannel> channels; + channels.emplace_back("https://abc.com", NotificationChannelStatus::ENABLED); + channels.emplace_back("https://xyz.com", NotificationChannelStatus::BLOCKED); + ON_CALL(*mock_bridge_, GetChannels()).WillByDefault(Return(channels)); + + EXPECT_CALL(*mock_bridge_, DeleteChannel("https://abc.com")); + EXPECT_CALL(*mock_bridge_, DeleteChannel("https://xyz.com")); + EXPECT_CALL(mock_observer, + OnContentSettingChanged( + ContentSettingsPattern(), ContentSettingsPattern(), + CONTENT_SETTINGS_TYPE_NOTIFICATIONS, std::string())); + channels_provider_->ClearAllContentSettingsRules( + CONTENT_SETTINGS_TYPE_NOTIFICATIONS); +} + +TEST_F(NotificationChannelsProviderAndroidTest, + ClearAllContentSettingsRulesNoopsForUnrelatedContentSettings) { + InitChannelsProvider(true /* should_use_channels */); + + EXPECT_CALL(*mock_bridge_, GetChannels()).Times(0); + EXPECT_CALL(*mock_bridge_, DeleteChannel(_)).Times(0); + + channels_provider_->ClearAllContentSettingsRules( + CONTENT_SETTINGS_TYPE_COOKIES); + channels_provider_->ClearAllContentSettingsRules( + CONTENT_SETTINGS_TYPE_JAVASCRIPT); + channels_provider_->ClearAllContentSettingsRules( + CONTENT_SETTINGS_TYPE_GEOLOCATION); +} + +TEST_F(NotificationChannelsProviderAndroidTest, + ClearAllContentSettingsRulesNoopsIfNotUsingChannels) { + InitChannelsProvider(false /* should_use_channels */); + + EXPECT_CALL(*mock_bridge_, GetChannels()).Times(0); + EXPECT_CALL(*mock_bridge_, DeleteChannel(_)).Times(0); + + channels_provider_->ClearAllContentSettingsRules( + CONTENT_SETTINGS_TYPE_NOTIFICATIONS); +}
diff --git a/chrome/browser/offline_pages/background_loader_offliner.cc b/chrome/browser/offline_pages/background_loader_offliner.cc index 25b437f..a9f60b9 100644 --- a/chrome/browser/offline_pages/background_loader_offliner.cc +++ b/chrome/browser/offline_pages/background_loader_offliner.cc
@@ -106,6 +106,8 @@ network_bytes_(0LL), is_low_bar_met_(false), did_snapshot_on_last_retry_(false), + started_count_(0LL), + completed_count_(0LL), weak_ptr_factory_(this) { DCHECK(offline_page_model_); DCHECK(browser_context_); @@ -355,8 +357,18 @@ void BackgroundLoaderOffliner::ObserveResourceLoading( ResourceLoadingObserver::ResourceDataType type, bool started) { - // TODO(petewil) Not implemented yet. - return; + // TODO(petewil): Use actual signal type instead of hardcoding name to + // image. + // Add the signal to extra data, and use for tracking. + if (type == ResourceDataType::IMAGE) { + if (started) { + started_count_++; + signal_data_.SetDouble("StartedImages", started_count_); + } else { + completed_count_++; + signal_data_.SetDouble("CompletedImages", completed_count_); + } + } } void BackgroundLoaderOffliner::OnNetworkBytesChanged(int64_t bytes) {
diff --git a/chrome/browser/offline_pages/background_loader_offliner.h b/chrome/browser/offline_pages/background_loader_offliner.h index 560e830..3af9ef8 100644 --- a/chrome/browser/offline_pages/background_loader_offliner.h +++ b/chrome/browser/offline_pages/background_loader_offliner.h
@@ -141,6 +141,10 @@ // Callback for cancel. CancelCallback cancel_callback_; + // TODO(petewil): Replace with a map of all types + int64_t started_count_; + int64_t completed_count_; + base::WeakPtrFactory<BackgroundLoaderOffliner> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(BackgroundLoaderOffliner); };
diff --git a/chrome/browser/offline_pages/offliner_user_data.cc b/chrome/browser/offline_pages/offliner_user_data.cc index 0dc7273a..0a44a2ac 100644 --- a/chrome/browser/offline_pages/offliner_user_data.cc +++ b/chrome/browser/offline_pages/offliner_user_data.cc
@@ -4,8 +4,6 @@ #include "chrome/browser/offline_pages/offliner_user_data.h" -class ResourceTrackerObserver; - namespace offline_pages { void OfflinerUserData::AddToWebContents(content::WebContents* webcontents,
diff --git a/chrome/browser/offline_pages/offliner_user_data.h b/chrome/browser/offline_pages/offliner_user_data.h index 9ed7c6a..b2ca72d 100644 --- a/chrome/browser/offline_pages/offliner_user_data.h +++ b/chrome/browser/offline_pages/offliner_user_data.h
@@ -7,7 +7,6 @@ #include "chrome/browser/offline_pages/background_loader_offliner.h" #include "chrome/browser/offline_pages/resource_loading_observer.h" -#include "components/offline_pages/features/features.h" #include "content/public/browser/web_contents_user_data.h" namespace offline_pages {
diff --git a/chrome/browser/profiles/profile_downloader.cc b/chrome/browser/profiles/profile_downloader.cc index 65f15c7..c1b95c1 100644 --- a/chrome/browser/profiles/profile_downloader.cc +++ b/chrome/browser/profiles/profile_downloader.cc
@@ -34,6 +34,7 @@ #include "content/public/browser/browser_thread.h" #include "google_apis/gaia/gaia_constants.h" #include "net/base/load_flags.h" +#include "net/http/http_status_code.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request_status.h" @@ -48,50 +49,8 @@ const char kAuthorizationHeader[] = "Authorization: Bearer %s"; -// Separator of URL path components. -const char kURLPathSeparator = '/'; - -// Photo ID of the Picasa Web Albums profile picture (base64 of 0). -const char kPicasaPhotoId[] = "AAAAAAAAAAA"; - -// Photo version of the default PWA profile picture (base64 of 1). -const char kDefaultPicasaPhotoVersion[] = "AAAAAAAAAAE"; - -// The minimum number of path components in profile picture URL. -const size_t kProfileImageURLPathComponentsCount = 6; - -// Index of path component with photo ID. -const int kPhotoIdPathComponentIndex = 2; - -// Index of path component with photo version. -const int kPhotoVersionPathComponentIndex = 3; - } // namespace -// static -bool ProfileDownloader::IsDefaultProfileImageURL(const std::string& url) { - if (url.empty()) - return true; - - GURL image_url_object(url); - DCHECK(image_url_object.is_valid()); - VLOG(1) << "URL to check for default image: " << image_url_object.spec(); - std::vector<std::string> path_components = base::SplitString( - image_url_object.path(), std::string(1, kURLPathSeparator), - base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); - - if (path_components.size() < kProfileImageURLPathComponentsCount) - return false; - - const std::string& photo_id = path_components[kPhotoIdPathComponentIndex]; - const std::string& photo_version = - path_components[kPhotoVersionPathComponentIndex]; - - // Check that the ID and version match the default Picasa profile photo. - return photo_id == kPicasaPhotoId && - photo_version == kDefaultPicasaPhotoVersion; -} - ProfileDownloader::ProfileDownloader(ProfileDownloaderDelegate* delegate) : OAuth2TokenService::Consumer("profile_downloader"), delegate_(delegate), @@ -165,7 +124,7 @@ return std::string(); return profiles::GetImageURLWithOptions( GURL(account_info_.picture_url), - delegate_->GetDesiredImageSideLength(), false /* no_silhouette */) + delegate_->GetDesiredImageSideLength(), true /* no_silhouette */) .spec(); } @@ -214,19 +173,14 @@ void ProfileDownloader::FetchImageData() { DCHECK(account_info_.IsValid()); - std::string image_url_with_size = GetProfilePictureURL(); if (!delegate_->NeedsProfilePicture()) { VLOG(1) << "Skipping profile picture download"; delegate_->OnProfileDownloadSuccess(this); return; } - if (IsDefaultProfileImageURL(image_url_with_size)) { - VLOG(1) << "User has default profile picture"; - picture_status_ = PICTURE_DEFAULT; - delegate_->OnProfileDownloadSuccess(this); - return; - } + + std::string image_url_with_size = GetProfilePictureURL(); if (!image_url_with_size.empty() && image_url_with_size == delegate_->GetCachedPictureURL()) { VLOG(1) << "Picture URL matches cached picture URL"; @@ -280,25 +234,28 @@ void ProfileDownloader::OnURLFetchComplete(const net::URLFetcher* source) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - std::string data; - source->GetResponseAsString(&data); - bool network_error = - source->GetStatus().status() != net::URLRequestStatus::SUCCESS; - if (network_error || source->GetResponseCode() != 200) { + if (source->GetResponseCode() == net::HTTP_OK) { + std::string data; + source->GetResponseAsString(&data); + DVLOG(1) << "Decoding the image..."; + ImageDecoder::Start(this, data); + } else if (source->GetResponseCode() == net::HTTP_NOT_FOUND) { + VLOG(1) << "Got 404, using default picture..."; + picture_status_ = PICTURE_DEFAULT; + delegate_->OnProfileDownloadSuccess(this); + } else { LOG(WARNING) << "Fetching profile data failed"; DVLOG(1) << " Status: " << source->GetStatus().status(); DVLOG(1) << " Error: " << source->GetStatus().error(); DVLOG(1) << " Response code: " << source->GetResponseCode(); DVLOG(1) << " Url: " << source->GetURL().spec(); - profile_image_fetcher_.reset(); + bool network_error = + source->GetStatus().status() != net::URLRequestStatus::SUCCESS; delegate_->OnProfileDownloadFailure(this, network_error ? ProfileDownloaderDelegate::NETWORK_ERROR : ProfileDownloaderDelegate::SERVICE_ERROR); - } else { - profile_image_fetcher_.reset(); - VLOG(1) << "Decoding the image..."; - ImageDecoder::Start(this, data); } + profile_image_fetcher_.reset(); } void ProfileDownloader::OnImageDecoded(const SkBitmap& decoded_image) {
diff --git a/chrome/browser/profiles/profile_downloader.h b/chrome/browser/profiles/profile_downloader.h index 0bf2a80..0969406 100644 --- a/chrome/browser/profiles/profile_downloader.h +++ b/chrome/browser/profiles/profile_downloader.h
@@ -109,9 +109,6 @@ // Implementation of AccountTrackerService::Observer. void OnAccountUpdated(const AccountInfo& info) override; - // Returns true if the image url is url of the default profile picture. - static bool IsDefaultProfileImageURL(const std::string& url); - // Issues the first request to get user profile image. void StartFetchingImage();
diff --git a/chrome/browser/profiles/profile_downloader_unittest.cc b/chrome/browser/profiles/profile_downloader_unittest.cc index 16f0b5c..1b340c1 100644 --- a/chrome/browser/profiles/profile_downloader_unittest.cc +++ b/chrome/browser/profiles/profile_downloader_unittest.cc
@@ -116,20 +116,3 @@ SimulateUserInfoSuccess(); ASSERT_EQ(kTestPictureURL, profile_downloader_->GetProfilePictureURL()); } - -TEST_F(ProfileDownloaderTest, DefaultURL) { - // Empty URL should be default photo - EXPECT_TRUE(ProfileDownloader::IsDefaultProfileImageURL(std::string())); - // Picasa default photo - EXPECT_TRUE(ProfileDownloader::IsDefaultProfileImageURL( - "https://example.com/-4/AAAAAAAAAAA/AAAAAAAAAAE/G/s64-c/photo.jpg")); - // Not default G+ photo - EXPECT_FALSE(ProfileDownloader::IsDefaultProfileImageURL( - "https://example.com/-4/AAAAAAAAAAI/AAAAAAAAAAA/G/photo.jpg")); - // Not default with 6 components - EXPECT_FALSE(ProfileDownloader::IsDefaultProfileImageURL( - "https://example.com/-4/AAAAAAAAAAI/AAAAAAAAACQ/Efg/photo.jpg")); - // Not default with 7 components - EXPECT_FALSE(ProfileDownloader::IsDefaultProfileImageURL( - "https://example.com/-4/AAAAAAAAAAI/AAAAAAAAACQ/Efg/s32-c/photo.jpg")); -}
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/settings_resetter_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/settings_resetter_win.cc index 3a8bb83f..3c63d8b 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/settings_resetter_win.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/settings_resetter_win.cc
@@ -15,6 +15,7 @@ #include "base/callback_helpers.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/sequence_checker.h" #include "base/synchronization/lock.h" #include "base/win/registry.h" #include "chrome/browser/browser_process.h" @@ -96,6 +97,14 @@ // The profiles to be reset. std::vector<Profile*> profiles_to_reset_; + // The ProfileResetter objects that are used to reset each profile. We need to + // hold on to these until each reset operation has been completed. + std::vector<std::unique_ptr<ProfileResetter>> profile_resetters_; + + // Used to check that modifications to |profile_resetters_| are sequenced + // correctly. + SEQUENCE_CHECKER(sequence_checker_); + // The number of profiles that need to be reset. int num_pending_resets_; @@ -118,6 +127,8 @@ DCHECK_LT(0, num_pending_resets_); DCHECK(done_callback_); DCHECK(delegate_); + + DETACH_FROM_SEQUENCE(sequence_checker_); } SettingsResetter::~SettingsResetter() { @@ -135,12 +146,15 @@ void SettingsResetter::OnFetchCompleted( Profile* profile, std::unique_ptr<BrandcodedDefaultSettings> master_settings) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + static const ProfileResetter::ResettableFlags kSettingsToReset = ProfileResetter::DEFAULT_SEARCH_ENGINE | ProfileResetter::HOMEPAGE | ProfileResetter::EXTENSIONS | ProfileResetter::STARTUP_PAGES | ProfileResetter::SHORTCUTS; - delegate_->GetProfileResetter(profile)->Reset( + profile_resetters_.push_back(delegate_->GetProfileResetter(profile)); + profile_resetters_.back()->Reset( kSettingsToReset, std::move(master_settings), base::Bind(&SettingsResetter::OnResetCompleted, this, profile)); }
diff --git a/chrome/browser/search_engines/template_url_service_android.cc b/chrome/browser/search_engines/template_url_service_android.cc index 8e8f5e1..5005697 100644 --- a/chrome/browser/search_engines/template_url_service_android.cc +++ b/chrome/browser/search_engines/template_url_service_android.cc
@@ -118,6 +118,18 @@ template_url_service_->search_terms_data()); } +jboolean TemplateUrlServiceAndroid::DoesDefaultSearchEngineHaveLogo( + JNIEnv* env, + const JavaParamRef<jobject>& obj) { + if (IsDefaultSearchEngineGoogle(env, obj)) + return true; + + const TemplateURL* default_search_provider = + template_url_service_->GetDefaultSearchProvider(); + return default_search_provider && + !default_search_provider->logo_url().is_empty(); +} + jboolean TemplateUrlServiceAndroid::IsSearchResultsPageFromDefaultSearchProvider( JNIEnv* env,
diff --git a/chrome/browser/search_engines/template_url_service_android.h b/chrome/browser/search_engines/template_url_service_android.h index af6c8b05..14a353b 100644 --- a/chrome/browser/search_engines/template_url_service_android.h +++ b/chrome/browser/search_engines/template_url_service_android.h
@@ -52,6 +52,9 @@ jboolean IsDefaultSearchEngineGoogle( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); + jboolean DoesDefaultSearchEngineHaveLogo( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj); jboolean IsSearchResultsPageFromDefaultSearchProvider( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj,
diff --git a/chrome/browser/subresource_filter/subresource_filter_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_browsertest.cc index 4f3d6ce..59b45a3 100644 --- a/chrome/browser/subresource_filter/subresource_filter_browsertest.cc +++ b/chrome/browser/subresource_filter/subresource_filter_browsertest.cc
@@ -1129,10 +1129,8 @@ tester.ExpectBucketCount(kSubresourceFilterActionsHistogram, kActionUIShown, 0); - // TODO(csharrison): Make this EXPECT_TRUE (e.g. turn the feature on for - // spoofed clicked). See crbug.com/733330 for more details. - EXPECT_FALSE(TabSpecificContentSettings::FromWebContents(web_contents) - ->IsContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS)); + EXPECT_TRUE(TabSpecificContentSettings::FromWebContents(web_contents) + ->IsContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS)); // Navigate to |b_url|, which should successfully open the popup. @@ -1160,7 +1158,8 @@ // Only necessary so we have a valid ruleset. ASSERT_NO_FATAL_FAILURE(SetRulesetWithRules(std::vector<proto::UrlRule>())); - // Navigate to a_url, should trigger the popup blocker. + // Should not trigger the popup blocker because internally opens the tab with + // a user gesture. ui_test_utils::NavigateToURLWithDisposition( browser(), url, WindowOpenDisposition::NEW_FOREGROUND_TAB, ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
diff --git a/chrome/browser/subresource_filter/subresource_filter_content_settings_manager.cc b/chrome/browser/subresource_filter/subresource_filter_content_settings_manager.cc index a22b65a..afb8028 100644 --- a/chrome/browser/subresource_filter/subresource_filter_content_settings_manager.cc +++ b/chrome/browser/subresource_filter/subresource_filter_content_settings_manager.cc
@@ -194,9 +194,14 @@ ChromeSubresourceFilterClient::LogAction( kActionContentSettingsAllowedWhileUISuppressed); } - // Note: could potentially reset the smart UI here to enable the user to - // easily change their decision. If that code is added we should make sure not - // to delete the metadata, but merely remove / reset the timestamp. + // Reset the smart UI here. Be careful not to delete the metadata (as + // ClearSiteMetadata would do), just remove the timestamp. + // + // This is to allow the UI appear again after a user has made a manual setting + // change in the settings UI. Deleting the metadata would affect how the + // permission behaves in Site Details / Page Info. + SetSiteMetadata(url, base::MakeUnique<base::DictionaryValue>()); + DCHECK(ShouldShowUIForSite(url)); } // When history URLs are deleted, clear the metadata for the smart UI.
diff --git a/chrome/browser/subresource_filter/subresource_filter_content_settings_manager.h b/chrome/browser/subresource_filter/subresource_filter_content_settings_manager.h index 3981f2c..fcaf3ac 100644 --- a/chrome/browser/subresource_filter/subresource_filter_content_settings_manager.h +++ b/chrome/browser/subresource_filter/subresource_filter_content_settings_manager.h
@@ -55,6 +55,9 @@ void OnDidShowUI(const GURL& url); bool ShouldShowUIForSite(const GURL& url) const; bool should_use_smart_ui() const { return should_use_smart_ui_; } + void set_should_use_smart_ui_for_testing(bool should_use_smart_ui) { + should_use_smart_ui_ = should_use_smart_ui; + } void ClearSiteMetadata(const GURL& url); @@ -65,7 +68,7 @@ // Time before showing the UI again on a domain. // TODO(csharrison): Consider setting this via a finch param. static constexpr base::TimeDelta kDelayBeforeShowingInfobarAgain = - base::TimeDelta::FromMinutes(30); + base::TimeDelta::FromHours(24); private: // content_settings::Observer: @@ -101,7 +104,7 @@ // user initiated through the settings UI. bool ignore_settings_changes_ = false; - const bool should_use_smart_ui_ = false; + bool should_use_smart_ui_ = false; DISALLOW_COPY_AND_ASSIGN(SubresourceFilterContentSettingsManager); };
diff --git a/chrome/browser/subresource_filter/subresource_filter_content_settings_manager_unittest.cc b/chrome/browser/subresource_filter/subresource_filter_content_settings_manager_unittest.cc index f4f6b68..c7ee05f 100644 --- a/chrome/browser/subresource_filter/subresource_filter_content_settings_manager_unittest.cc +++ b/chrome/browser/subresource_filter/subresource_filter_content_settings_manager_unittest.cc
@@ -46,6 +46,7 @@ settings_manager_ = SubresourceFilterProfileContextFactory::GetForProfile(&testing_profile_) ->settings_manager(); + settings_manager_->set_should_use_smart_ui_for_testing(true); auto test_clock = base::MakeUnique<base::SimpleTestClock>(); test_clock_ = test_clock.get(); settings_manager_->set_clock_for_testing(std::move(test_clock)); @@ -181,9 +182,6 @@ } TEST_F(SubresourceFilterContentSettingsManagerTest, SmartUI) { - if (!settings_manager()->should_use_smart_ui()) - return; - GURL url("https://example.test/"); GURL url2("https://example.test/path"); EXPECT_TRUE(settings_manager()->ShouldShowUIForSite(url)); @@ -208,13 +206,23 @@ EXPECT_TRUE(settings_manager()->ShouldShowUIForSite(url2)); } +TEST_F(SubresourceFilterContentSettingsManagerTest, NoSmartUI) { + settings_manager()->set_should_use_smart_ui_for_testing(false); + + GURL url("https://example.test/"); + EXPECT_TRUE(settings_manager()->ShouldShowUIForSite(url)); + + EXPECT_EQ(CONTENT_SETTING_DEFAULT, + GetContentSettingMatchingUrlWithEmptyPath(url)); + settings_manager()->OnDidShowUI(url); + + EXPECT_TRUE(settings_manager()->ShouldShowUIForSite(url)); +} + // If the user manually sets a content setting to block the feature, the smart // UI should be reset. TEST_F(SubresourceFilterContentSettingsManagerTest, SmartUIWithOverride_Resets) { - if (!settings_manager()->should_use_smart_ui()) - return; - GURL url("https://example.test/"); EXPECT_TRUE(settings_manager()->ShouldShowUIForSite(url)); @@ -287,7 +295,7 @@ NoExperimentalUI_NoWebsiteSetting) { GURL url("https://example.test/"); - // Do no explicitly allow the experimental UI. + // Do not explicitly allow the experimental UI. scoped_feature_toggle().ResetSubresourceFilterState( base::FeatureList::OVERRIDE_ENABLE_FEATURE); settings_manager()->OnDidShowUI(url); @@ -300,11 +308,27 @@ EXPECT_TRUE(settings_manager()->GetSiteMetadata(url)); } +TEST_F(SubresourceFilterContentSettingsManagerTest, + ManualSettingsChange_ResetsSmartUI) { + GURL url("https://example.test/"); + EXPECT_TRUE(settings_manager()->ShouldShowUIForSite(url)); + settings_manager()->OnDidShowUI(url); + + EXPECT_FALSE(settings_manager()->ShouldShowUIForSite(url)); + + // Manual settings change should reset the smart UI. + GetSettingsMap()->SetContentSettingDefaultScope( + url, GURL(), CONTENT_SETTINGS_TYPE_ADS, std::string(), + CONTENT_SETTING_BLOCK); + EXPECT_TRUE(settings_manager()->ShouldShowUIForSite(url)); + + // Metadata should not be completely cleared, as we still want to maintain the + // invariant that the existence of the metadata implies that the UI was shown. + EXPECT_TRUE(settings_manager()->GetSiteMetadata(url)); +} + TEST_F(SubresourceFilterContentSettingsManagerHistoryTest, HistoryUrlDeleted_ClearsWebsiteSetting) { - if (!settings_manager()->should_use_smart_ui()) - return; - // Simulate a history already populated with a URL. auto* history_service = HistoryServiceFactory::GetForProfile( profile(), ServiceAccessType::EXPLICIT_ACCESS); @@ -333,9 +357,6 @@ TEST_F(SubresourceFilterContentSettingsManagerHistoryTest, AllHistoryUrlDeleted_ClearsWebsiteSetting) { - if (!settings_manager()->should_use_smart_ui()) - return; - auto* history_service = HistoryServiceFactory::GetForProfile( profile(), ServiceAccessType::EXPLICIT_ACCESS); ASSERT_TRUE(history_service);
diff --git a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_cell_unittest.mm b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_cell_unittest.mm index b913e67..d672438 100644 --- a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_cell_unittest.mm +++ b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_cell_unittest.mm
@@ -81,8 +81,7 @@ TEST_VIEW(AutocompleteTextFieldCellTest, view_); // Test drawing, mostly to ensure nothing leaks or crashes. -// Flaky, disabled. Bug http://crbug.com/49522 -TEST_F(AutocompleteTextFieldCellTest, DISABLED_FocusedDisplay) { +TEST_F(AutocompleteTextFieldCellTest, FocusedDisplay) { [view_ display]; // Test focused drawing.
diff --git a/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_cocoa.h b/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_cocoa.h index 05ed3f0..d68638ee 100644 --- a/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_cocoa.h +++ b/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_cocoa.h
@@ -24,9 +24,7 @@ gfx::NativeWindow parent, const base::string16& app_name, const base::string16& target_name, - std::unique_ptr<DesktopMediaList> screen_list, - std::unique_ptr<DesktopMediaList> window_list, - std::unique_ptr<DesktopMediaList> tab_list, + std::vector<std::unique_ptr<DesktopMediaList>> source_lists, bool request_audio, const DoneCallback& done_callback) override;
diff --git a/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_cocoa.mm b/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_cocoa.mm index d777da4..bce6a90 100644 --- a/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_cocoa.mm +++ b/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_cocoa.mm
@@ -20,20 +20,16 @@ gfx::NativeWindow parent, const base::string16& app_name, const base::string16& target_name, - std::unique_ptr<DesktopMediaList> screen_list, - std::unique_ptr<DesktopMediaList> window_list, - std::unique_ptr<DesktopMediaList> tab_list, + std::vector<std::unique_ptr<DesktopMediaList>> source_lists, bool request_audio, const DoneCallback& done_callback) { controller_.reset([[DesktopMediaPickerController alloc] - initWithScreenList:std::move(screen_list) - windowList:std::move(window_list) - tabList:std::move(tab_list) - parent:parent - callback:done_callback - appName:app_name - targetName:target_name - requestAudio:request_audio]); + initWithSourceLists:std::move(source_lists) + parent:parent + callback:done_callback + appName:app_name + targetName:target_name + requestAudio:request_audio]); [controller_ showWindow:nil]; }
diff --git a/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_controller.h b/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_controller.h index 84bb284..9e52ee7 100644 --- a/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_controller.h +++ b/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_controller.h
@@ -47,9 +47,7 @@ // Provides source information (including thumbnails) to fill up the array of // |screenItems_|, |windowItems_| and |tabItems_|, and to render in // |screenBrowser_|, |windowBrowser_| and |tabBrowser_|. - std::unique_ptr<DesktopMediaList> screenList_; - std::unique_ptr<DesktopMediaList> windowList_; - std::unique_ptr<DesktopMediaList> tabList_; + std::vector<std::unique_ptr<DesktopMediaList>> sourceLists_; // To be called with the user selection. DesktopMediaPicker::DoneCallback doneCallback_; @@ -75,14 +73,13 @@ // appears as the initiator of the request. // |targetName| will be used to format the dialog's label and appear as the // consumer of the requested stream. -- (id)initWithScreenList:(std::unique_ptr<DesktopMediaList>)screenList - windowList:(std::unique_ptr<DesktopMediaList>)windowList - tabList:(std::unique_ptr<DesktopMediaList>)tabList - parent:(NSWindow*)parent - callback:(const DesktopMediaPicker::DoneCallback&)callback - appName:(const base::string16&)appName - targetName:(const base::string16&)targetName - requestAudio:(bool)requestAudio; +- (id)initWithSourceLists: + (std::vector<std::unique_ptr<DesktopMediaList>>)sourceLists + parent:(NSWindow*)parent + callback:(const DesktopMediaPicker::DoneCallback&)callback + appName:(const base::string16&)appName + targetName:(const base::string16&)targetName + requestAudio:(bool)requestAudio; @end
diff --git a/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_controller.mm b/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_controller.mm index 9fabd474e..8a7bbc8 100644 --- a/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_controller.mm +++ b/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_controller.mm
@@ -97,7 +97,6 @@ // Helper functions to get source type, or get data entities based on source // type. - (DesktopMediaID::Type)selectedSourceType; -- (DesktopMediaID::Type)sourceTypeForList:(DesktopMediaList*)list; - (DesktopMediaID::Type)sourceTypeForBrowser:(id)browser; - (id)browserViewForType:(DesktopMediaID::Type)sourceType; - (NSMutableArray*)itemSetForType:(DesktopMediaID::Type)sourceType; @@ -108,14 +107,13 @@ @implementation DesktopMediaPickerController -- (id)initWithScreenList:(std::unique_ptr<DesktopMediaList>)screenList - windowList:(std::unique_ptr<DesktopMediaList>)windowList - tabList:(std::unique_ptr<DesktopMediaList>)tabList - parent:(NSWindow*)parent - callback:(const DesktopMediaPicker::DoneCallback&)callback - appName:(const base::string16&)appName - targetName:(const base::string16&)targetName - requestAudio:(bool)requestAudio { +- (id)initWithSourceLists: + (std::vector<std::unique_ptr<DesktopMediaList>>)sourceLists + parent:(NSWindow*)parent + callback:(const DesktopMediaPicker::DoneCallback&)callback + appName:(const base::string16&)appName + targetName:(const base::string16&)targetName + requestAudio:(bool)requestAudio { const NSUInteger kStyleMask = NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask; base::scoped_nsobject<NSWindow> window( @@ -127,21 +125,25 @@ if ((self = [super initWithWindow:window])) { [parent addChildWindow:window ordered:NSWindowAbove]; [window setDelegate:self]; - if (screenList) { - screenList_ = std::move(screenList); - screenItems_.reset([[NSMutableArray alloc] init]); - } - if (windowList) { - windowList_ = std::move(windowList); - windowList_->SetViewDialogWindowId( - DesktopMediaID(DesktopMediaID::TYPE_WINDOW, [window windowNumber])); - windowItems_.reset([[NSMutableArray alloc] init]); - } - - if (tabList) { - tabList_ = std::move(tabList); - tabItems_.reset([[NSMutableArray alloc] init]); + sourceLists_ = std::move(sourceLists); + for (auto& sourceList : sourceLists_) { + switch (sourceList->GetMediaListType()) { + case DesktopMediaID::TYPE_NONE: + NOTREACHED(); + break; + case DesktopMediaID::TYPE_SCREEN: + screenItems_.reset([[NSMutableArray alloc] init]); + break; + case DesktopMediaID::TYPE_WINDOW: + sourceList->SetViewDialogWindowId(DesktopMediaID( + DesktopMediaID::TYPE_WINDOW, [window windowNumber])); + windowItems_.reset([[NSMutableArray alloc] init]); + break; + case DesktopMediaID::TYPE_WEB_CONTENTS: + tabItems_.reset([[NSMutableArray alloc] init]); + break; + } } [self initializeContentsWithAppName:appName @@ -229,39 +231,44 @@ sourceTypeControl_.reset( [[NSSegmentedControl alloc] initWithFrame:NSZeroRect]); - NSInteger segmentCount = - (screenList_ ? 1 : 0) + (windowList_ ? 1 : 0) + (tabList_ ? 1 : 0); + NSInteger segmentCount = sourceLists_.size(); [sourceTypeControl_ setSegmentCount:segmentCount]; NSInteger segmentIndex = 0; - if (screenList_) { - [sourceTypeControl_ - setLabel:l10n_util::GetNSString( - IDS_DESKTOP_MEDIA_PICKER_SOURCE_TYPE_SCREEN) - forSegment:segmentIndex]; + for (auto& sourceList : sourceLists_) { + switch (sourceList->GetMediaListType()) { + case DesktopMediaID::TYPE_NONE: + NOTREACHED(); + break; + case DesktopMediaID::TYPE_SCREEN: + [sourceTypeControl_ + setLabel:l10n_util::GetNSString( + IDS_DESKTOP_MEDIA_PICKER_SOURCE_TYPE_SCREEN) + forSegment:segmentIndex]; - [[sourceTypeControl_ cell] setTag:DesktopMediaID::TYPE_SCREEN - forSegment:segmentIndex]; + [[sourceTypeControl_ cell] setTag:DesktopMediaID::TYPE_SCREEN + forSegment:segmentIndex]; + break; + case DesktopMediaID::TYPE_WINDOW: + [sourceTypeControl_ + setLabel:l10n_util::GetNSString( + IDS_DESKTOP_MEDIA_PICKER_SOURCE_TYPE_WINDOW) + forSegment:segmentIndex]; + [[sourceTypeControl_ cell] setTag:DesktopMediaID::TYPE_WINDOW + forSegment:segmentIndex]; + break; + case DesktopMediaID::TYPE_WEB_CONTENTS: + [sourceTypeControl_ + setLabel:l10n_util::GetNSString( + IDS_DESKTOP_MEDIA_PICKER_SOURCE_TYPE_TAB) + forSegment:segmentIndex]; + [[sourceTypeControl_ cell] setTag:DesktopMediaID::TYPE_WEB_CONTENTS + forSegment:segmentIndex]; + break; + } ++segmentIndex; } - if (windowList_) { - [sourceTypeControl_ - setLabel:l10n_util::GetNSString( - IDS_DESKTOP_MEDIA_PICKER_SOURCE_TYPE_WINDOW) - forSegment:segmentIndex]; - [[sourceTypeControl_ cell] setTag:DesktopMediaID::TYPE_WINDOW - forSegment:segmentIndex]; - ++segmentIndex; - } - - if (tabList_) { - [sourceTypeControl_ setLabel:l10n_util::GetNSString( - IDS_DESKTOP_MEDIA_PICKER_SOURCE_TYPE_TAB) - forSegment:segmentIndex]; - [[sourceTypeControl_ cell] setTag:DesktopMediaID::TYPE_WEB_CONTENTS - forSegment:segmentIndex]; - } [sourceTypeControl_ setTarget:self]; [sourceTypeControl_ setAction:@selector(typeButtonPressed:)]; @@ -280,41 +287,51 @@ } - (void)createSourceViewsAtOrigin:(NSPoint)origin { - if (screenList_) { - const bool is_single = screenList_->GetSourceCount() <= 1; - const CGFloat width = is_single ? kSingleScreenWidth : kMultipleScreenWidth; - const CGFloat height = - is_single ? kSingleScreenHeight : kMultipleScreenHeight; - screenBrowser_.reset( - [[self createImageBrowserWithSize:NSMakeSize(width, height)] retain]); - } + for (auto& sourceList : sourceLists_) { + switch (sourceList->GetMediaListType()) { + case DesktopMediaID::TYPE_NONE: { + NOTREACHED(); + break; + } + case DesktopMediaID::TYPE_SCREEN: { + const bool is_single = sourceList->GetSourceCount() <= 1; + const CGFloat width = + is_single ? kSingleScreenWidth : kMultipleScreenWidth; + const CGFloat height = + is_single ? kSingleScreenHeight : kMultipleScreenHeight; + screenBrowser_.reset([[self + createImageBrowserWithSize:NSMakeSize(width, height)] retain]); + break; + } - if (windowList_) { - windowBrowser_.reset([ - [self createImageBrowserWithSize:NSMakeSize(kThumbnailWidth, - kThumbnailHeight)] retain]); + case DesktopMediaID::TYPE_WINDOW: { + windowBrowser_.reset([[self + createImageBrowserWithSize:NSMakeSize(kThumbnailWidth, + kThumbnailHeight)] retain]); + break; + } + case DesktopMediaID::TYPE_WEB_CONTENTS: { + tabBrowser_.reset([[NSTableView alloc] initWithFrame:NSZeroRect]); + [tabBrowser_ setDelegate:self]; + [tabBrowser_ setDataSource:self]; + [tabBrowser_ setAllowsMultipleSelection:NO]; + [tabBrowser_ setRowHeight:kRowHeight]; + [tabBrowser_ setDoubleAction:@selector(sharePressed:)]; + base::scoped_nsobject<NSTableColumn> iconColumn( + [[NSTableColumn alloc] initWithIdentifier:kIconId]); + [iconColumn setEditable:NO]; + [iconColumn setWidth:kIconWidth]; + [tabBrowser_ addTableColumn:iconColumn]; + base::scoped_nsobject<NSTableColumn> titleColumn( + [[NSTableColumn alloc] initWithIdentifier:kTitleId]); + [titleColumn setEditable:NO]; + [titleColumn setWidth:kRowWidth]; + [tabBrowser_ addTableColumn:titleColumn]; + [tabBrowser_ setHeaderView:nil]; + break; + } + } } - - if (tabList_) { - tabBrowser_.reset([[NSTableView alloc] initWithFrame:NSZeroRect]); - [tabBrowser_ setDelegate:self]; - [tabBrowser_ setDataSource:self]; - [tabBrowser_ setAllowsMultipleSelection:NO]; - [tabBrowser_ setRowHeight:kRowHeight]; - [tabBrowser_ setDoubleAction:@selector(sharePressed:)]; - base::scoped_nsobject<NSTableColumn> iconColumn( - [[NSTableColumn alloc] initWithIdentifier:kIconId]); - [iconColumn setEditable:NO]; - [iconColumn setWidth:kIconWidth]; - [tabBrowser_ addTableColumn:iconColumn]; - base::scoped_nsobject<NSTableColumn> titleColumn( - [[NSTableColumn alloc] initWithIdentifier:kTitleId]); - [titleColumn setEditable:NO]; - [titleColumn setWidth:kRowWidth]; - [tabBrowser_ addTableColumn:titleColumn]; - [tabBrowser_ setHeaderView:nil]; - } - // Create a scroll view to host the image browsers. NSRect imageBrowserScrollFrame = NSMakeRect(origin.x, origin.y, kPaddedWidth, 350); @@ -412,20 +429,30 @@ - (void)showWindow:(id)sender { // Signal the source lists to start sending thumbnails. |bridge_| is used as // the observer, and will forward notifications to this object. - if (screenList_) { - screenList_->SetThumbnailSize( - gfx::Size(kSingleScreenWidth, kSingleScreenHeight)); - screenList_->StartUpdating(bridge_.get()); - } - - if (windowList_) { - windowList_->SetThumbnailSize(gfx::Size(kThumbnailWidth, kThumbnailHeight)); - windowList_->StartUpdating(bridge_.get()); - } - - if (tabList_) { - tabList_->SetThumbnailSize(gfx::Size(kIconWidth, kRowHeight)); - tabList_->StartUpdating(bridge_.get()); + for (auto& sourceList : sourceLists_) { + switch (sourceList->GetMediaListType()) { + case DesktopMediaID::TYPE_NONE: { + NOTREACHED(); + break; + } + case DesktopMediaID::TYPE_SCREEN: { + sourceList->SetThumbnailSize( + gfx::Size(kSingleScreenWidth, kSingleScreenHeight)); + sourceList->StartUpdating(bridge_.get()); + break; + } + case DesktopMediaID::TYPE_WINDOW: { + sourceList->SetThumbnailSize( + gfx::Size(kThumbnailWidth, kThumbnailHeight)); + sourceList->StartUpdating(bridge_.get()); + break; + } + case DesktopMediaID::TYPE_WEB_CONTENTS: { + sourceList->SetThumbnailSize(gfx::Size(kIconWidth, kRowHeight)); + sourceList->StartUpdating(bridge_.get()); + break; + } + } } [self.window center]; @@ -502,14 +529,6 @@ [[sourceTypeControl_ cell] tagForSegment:segment]); } -- (DesktopMediaID::Type)sourceTypeForList:(DesktopMediaList*)list { - if (list == screenList_.get()) - return DesktopMediaID::TYPE_SCREEN; - if (list == windowList_.get()) - return DesktopMediaID::TYPE_WINDOW; - return DesktopMediaID::TYPE_WEB_CONTENTS; -} - - (DesktopMediaID::Type)sourceTypeForBrowser:(id)browser { if (browser == screenBrowser_.get()) return DesktopMediaID::TYPE_SCREEN; @@ -678,7 +697,7 @@ #pragma mark DesktopMediaPickerObserver - (void)sourceAddedForList:(DesktopMediaList*)list atIndex:(int)index { - DesktopMediaID::Type sourceType = [self sourceTypeForList:list]; + DesktopMediaID::Type sourceType = list->GetMediaListType(); NSMutableArray* items = [self itemSetForType:sourceType]; id browser = [self browserViewForType:sourceType]; NSInteger selectedIndex = [self selectedIndexForType:sourceType]; @@ -720,7 +739,7 @@ } - (void)sourceRemovedForList:(DesktopMediaList*)list atIndex:(int)index { - DesktopMediaID::Type sourceType = [self sourceTypeForList:list]; + DesktopMediaID::Type sourceType = list->GetMediaListType(); NSMutableArray* items = [self itemSetForType:sourceType]; id browser = [self browserViewForType:sourceType]; @@ -749,7 +768,7 @@ - (void)sourceMovedForList:(DesktopMediaList*)list from:(int)oldIndex to:(int)newIndex { - DesktopMediaID::Type sourceType = [self sourceTypeForList:list]; + DesktopMediaID::Type sourceType = list->GetMediaListType(); NSMutableArray* items = [self itemSetForType:sourceType]; id browser = [self browserViewForType:sourceType]; NSInteger selectedIndex = [self selectedIndexForType:sourceType]; @@ -771,7 +790,7 @@ } - (void)sourceNameChangedForList:(DesktopMediaList*)list atIndex:(int)index { - DesktopMediaID::Type sourceType = [self sourceTypeForList:list]; + DesktopMediaID::Type sourceType = list->GetMediaListType(); NSMutableArray* items = [self itemSetForType:sourceType]; id browser = [self browserViewForType:sourceType]; NSInteger selectedIndex = [self selectedIndexForType:sourceType]; @@ -786,7 +805,7 @@ - (void)sourceThumbnailChangedForList:(DesktopMediaList*)list atIndex:(int)index { - DesktopMediaID::Type sourceType = [self sourceTypeForList:list]; + DesktopMediaID::Type sourceType = list->GetMediaListType(); NSMutableArray* items = [self itemSetForType:sourceType]; id browser = [self browserViewForType:sourceType]; NSInteger selectedIndex = [self selectedIndexForType:sourceType];
diff --git a/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_controller_unittest.mm b/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_controller_unittest.mm index 04a1fb1..60d84b8 100644 --- a/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_controller_unittest.mm
@@ -78,23 +78,30 @@ void SetUp() override { CocoaTest::SetUp(); - screen_list_ = new FakeDesktopMediaList(); - window_list_ = new FakeDesktopMediaList(); - tab_list_ = new FakeDesktopMediaList(); + std::vector<DesktopMediaID::Type> source_types = { + DesktopMediaID::TYPE_SCREEN, DesktopMediaID::TYPE_WINDOW, + DesktopMediaID::TYPE_WEB_CONTENTS}; + + screen_list_ = new FakeDesktopMediaList(DesktopMediaID::TYPE_SCREEN); + window_list_ = new FakeDesktopMediaList(DesktopMediaID::TYPE_WINDOW); + tab_list_ = new FakeDesktopMediaList(DesktopMediaID::TYPE_WEB_CONTENTS); + + std::vector<std::unique_ptr<DesktopMediaList>> source_lists; + source_lists.push_back(std::unique_ptr<DesktopMediaList>(screen_list_)); + source_lists.push_back(std::unique_ptr<DesktopMediaList>(window_list_)); + source_lists.push_back(std::unique_ptr<DesktopMediaList>(tab_list_)); DesktopMediaPicker::DoneCallback callback = base::Bind(&DesktopMediaPickerControllerTest::OnResult, base::Unretained(this)); controller_.reset([[DesktopMediaPickerController alloc] - initWithScreenList:std::unique_ptr<DesktopMediaList>(screen_list_) - windowList:std::unique_ptr<DesktopMediaList>(window_list_) - tabList:std::unique_ptr<DesktopMediaList>(tab_list_) - parent:nil - callback:callback - appName:base::ASCIIToUTF16("Screenshare Test") - targetName:base::ASCIIToUTF16("https://foo.com") - requestAudio:true]); + initWithSourceLists:std::move(source_lists) + parent:nil + callback:callback + appName:base::ASCIIToUTF16("Screenshare Test") + targetName:base::ASCIIToUTF16("https://foo.com") + requestAudio:true]); } void TearDown() override {
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc index b7c9ae2..f9a6d0b 100644 --- a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc +++ b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc
@@ -56,9 +56,7 @@ DesktopMediaPickerViews* parent, const base::string16& app_name, const base::string16& target_name, - std::unique_ptr<DesktopMediaList> screen_list, - std::unique_ptr<DesktopMediaList> window_list, - std::unique_ptr<DesktopMediaList> tab_list, + std::vector<std::unique_ptr<DesktopMediaList>> source_lists, bool request_audio) : parent_(parent), description_label_(new views::Label()), @@ -75,103 +73,113 @@ description_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); AddChildView(description_label_); - if (screen_list) { - source_types_.push_back(DesktopMediaID::TYPE_SCREEN); + for (auto& source_list : source_lists) { + switch (source_list->GetMediaListType()) { + case DesktopMediaID::TYPE_NONE: { + NOTREACHED(); + break; + } + case DesktopMediaID::TYPE_SCREEN: { + source_types_.push_back(DesktopMediaID::TYPE_SCREEN); - const DesktopMediaSourceViewStyle kSingleScreenStyle( - 1, // columns - gfx::Size(360, 280), // item_size - gfx::Rect(), // icon_rect - gfx::Rect(), // label_rect - gfx::HorizontalAlignment::ALIGN_CENTER, // text_alignment - gfx::Rect(20, 20, 320, 240), // image_rect - 4, // selection_border_thickness - 5); // focus_rectangle_inset + const DesktopMediaSourceViewStyle kSingleScreenStyle( + 1, // columns + gfx::Size(360, 280), // item_size + gfx::Rect(), // icon_rect + gfx::Rect(), // label_rect + gfx::HorizontalAlignment::ALIGN_CENTER, // text_alignment + gfx::Rect(20, 20, 320, 240), // image_rect + 4, // selection_border_thickness + 5); // focus_rectangle_inset - const DesktopMediaSourceViewStyle kGenericScreenStyle( - 2, // columns - gfx::Size(270, 220), // item_size - gfx::Rect(), // icon_rect - gfx::Rect(15, 165, 240, 40), // label_rect - gfx::HorizontalAlignment::ALIGN_CENTER, // text_alignment - gfx::Rect(15, 15, 240, 150), // image_rect - 2, // selection_border_thickness - 5); // focus_rectangle_inset + const DesktopMediaSourceViewStyle kGenericScreenStyle( + 2, // columns + gfx::Size(270, 220), // item_size + gfx::Rect(), // icon_rect + gfx::Rect(15, 165, 240, 40), // label_rect + gfx::HorizontalAlignment::ALIGN_CENTER, // text_alignment + gfx::Rect(15, 15, 240, 150), // image_rect + 2, // selection_border_thickness + 5); // focus_rectangle_inset - views::ScrollView* screen_scroll_view = - views::ScrollView::CreateScrollViewWithBorder(); - base::string16 screen_title_text = - l10n_util::GetStringUTF16(IDS_DESKTOP_MEDIA_PICKER_SOURCE_TYPE_SCREEN); - list_views_.push_back(new DesktopMediaListView( - this, std::move(screen_list), kGenericScreenStyle, kSingleScreenStyle, - screen_title_text)); + views::ScrollView* screen_scroll_view = + views::ScrollView::CreateScrollViewWithBorder(); + base::string16 screen_title_text = l10n_util::GetStringUTF16( + IDS_DESKTOP_MEDIA_PICKER_SOURCE_TYPE_SCREEN); + list_views_.push_back(new DesktopMediaListView( + this, std::move(source_list), kGenericScreenStyle, + kSingleScreenStyle, screen_title_text)); - screen_scroll_view->SetContents(list_views_.back()); - screen_scroll_view->ClipHeightTo( - kGenericScreenStyle.item_size.height(), - kGenericScreenStyle.item_size.height() * 2); - screen_scroll_view->set_hide_horizontal_scrollbar(true); + screen_scroll_view->SetContents(list_views_.back()); + screen_scroll_view->ClipHeightTo( + kGenericScreenStyle.item_size.height(), + kGenericScreenStyle.item_size.height() * 2); + screen_scroll_view->set_hide_horizontal_scrollbar(true); - pane_->AddTab(screen_title_text, screen_scroll_view); - pane_->set_listener(this); - } + pane_->AddTab(screen_title_text, screen_scroll_view); + pane_->set_listener(this); + break; + } + case DesktopMediaID::TYPE_WINDOW: { + source_types_.push_back(DesktopMediaID::TYPE_WINDOW); - if (window_list) { - source_types_.push_back(DesktopMediaID::TYPE_WINDOW); + const DesktopMediaSourceViewStyle kWindowStyle( + 3, // columns + gfx::Size(180, 160), // item_size + gfx::Rect(10, 120, 20, 20), // icon_rect + gfx::Rect(32, 110, 138, 40), // label_rect + gfx::HorizontalAlignment::ALIGN_LEFT, // text_alignment + gfx::Rect(8, 8, 164, 104), // image_rect + 2, // selection_border_thickness + 5); // focus_rectangle_inset - const DesktopMediaSourceViewStyle kWindowStyle( - 3, // columns - gfx::Size(180, 160), // item_size - gfx::Rect(10, 120, 20, 20), // icon_rect - gfx::Rect(32, 110, 138, 40), // label_rect - gfx::HorizontalAlignment::ALIGN_LEFT, // text_alignment - gfx::Rect(8, 8, 164, 104), // image_rect - 2, // selection_border_thickness - 5); // focus_rectangle_inset + views::ScrollView* window_scroll_view = + views::ScrollView::CreateScrollViewWithBorder(); + base::string16 window_title_text = l10n_util::GetStringUTF16( + IDS_DESKTOP_MEDIA_PICKER_SOURCE_TYPE_WINDOW); + list_views_.push_back( + new DesktopMediaListView(this, std::move(source_list), kWindowStyle, + kWindowStyle, window_title_text)); + window_scroll_view->SetContents(list_views_.back()); + window_scroll_view->ClipHeightTo(kWindowStyle.item_size.height(), + kWindowStyle.item_size.height() * 2); + window_scroll_view->set_hide_horizontal_scrollbar(true); - views::ScrollView* window_scroll_view = - views::ScrollView::CreateScrollViewWithBorder(); - base::string16 window_title_text = - l10n_util::GetStringUTF16(IDS_DESKTOP_MEDIA_PICKER_SOURCE_TYPE_WINDOW); - list_views_.push_back(new DesktopMediaListView(this, std::move(window_list), - kWindowStyle, kWindowStyle, - window_title_text)); - window_scroll_view->SetContents(list_views_.back()); - window_scroll_view->ClipHeightTo(kWindowStyle.item_size.height(), - kWindowStyle.item_size.height() * 2); - window_scroll_view->set_hide_horizontal_scrollbar(true); + pane_->AddTab(window_title_text, window_scroll_view); + pane_->set_listener(this); + break; + } + case DesktopMediaID::TYPE_WEB_CONTENTS: { + source_types_.push_back(DesktopMediaID::TYPE_WEB_CONTENTS); - pane_->AddTab(window_title_text, window_scroll_view); - pane_->set_listener(this); - } + const DesktopMediaSourceViewStyle kTabStyle( + 1, // columns + gfx::Size(600, 30), // item_size + gfx::Rect(), // icon_rect + gfx::Rect(46, 0, 490, 30), // label_rect + gfx::HorizontalAlignment::ALIGN_LEFT, // text_alignment + gfx::Rect(10, 2, 26, 26), // image_rect + 1, // selection_border_thickness + 0); // focus_rectangle_inset - if (tab_list) { - source_types_.push_back(DesktopMediaID::TYPE_WEB_CONTENTS); + views::ScrollView* tab_scroll_view = + views::ScrollView::CreateScrollViewWithBorder(); + base::string16 tab_title_text = + l10n_util::GetStringUTF16(IDS_DESKTOP_MEDIA_PICKER_SOURCE_TYPE_TAB); + list_views_.push_back( + new DesktopMediaListView(this, std::move(source_list), kTabStyle, + kTabStyle, tab_title_text)); - const DesktopMediaSourceViewStyle kTabStyle( - 1, // columns - gfx::Size(600, 30), // item_size - gfx::Rect(), // icon_rect - gfx::Rect(46, 0, 490, 30), // label_rect - gfx::HorizontalAlignment::ALIGN_LEFT, // text_alignment - gfx::Rect(10, 2, 26, 26), // image_rect - 1, // selection_border_thickness - 0); // focus_rectangle_inset + tab_scroll_view->SetContents(list_views_.back()); + tab_scroll_view->ClipHeightTo(kTabStyle.item_size.height(), + kTabStyle.item_size.height() * 10); + tab_scroll_view->set_hide_horizontal_scrollbar(true); - views::ScrollView* tab_scroll_view = - views::ScrollView::CreateScrollViewWithBorder(); - base::string16 tab_title_text = - l10n_util::GetStringUTF16(IDS_DESKTOP_MEDIA_PICKER_SOURCE_TYPE_TAB); - list_views_.push_back(new DesktopMediaListView( - this, std::move(tab_list), kTabStyle, kTabStyle, tab_title_text)); - - tab_scroll_view->SetContents(list_views_.back()); - tab_scroll_view->ClipHeightTo(kTabStyle.item_size.height(), - kTabStyle.item_size.height() * 10); - tab_scroll_view->set_hide_horizontal_scrollbar(true); - - pane_->AddTab(tab_title_text, tab_scroll_view); - pane_->set_listener(this); + pane_->AddTab(tab_title_text, tab_scroll_view); + pane_->set_listener(this); + break; + } + } } if (app_name == target_name) { @@ -413,16 +421,13 @@ gfx::NativeWindow parent, const base::string16& app_name, const base::string16& target_name, - std::unique_ptr<DesktopMediaList> screen_list, - std::unique_ptr<DesktopMediaList> window_list, - std::unique_ptr<DesktopMediaList> tab_list, + std::vector<std::unique_ptr<DesktopMediaList>> source_lists, bool request_audio, const DoneCallback& done_callback) { callback_ = done_callback; dialog_ = new DesktopMediaPickerDialogView( web_contents, context, this, app_name, target_name, - std::move(screen_list), std::move(window_list), std::move(tab_list), - request_audio); + std::move(source_lists), request_audio); } void DesktopMediaPickerViews::NotifyDialogResult(DesktopMediaID source) {
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.h b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.h index 854a3e0..6f0cf0d 100644 --- a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.h +++ b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.h
@@ -24,15 +24,14 @@ class DesktopMediaPickerDialogView : public views::DialogDelegateView, public views::TabbedPaneListener { public: - DesktopMediaPickerDialogView(content::WebContents* parent_web_contents, - gfx::NativeWindow context, - DesktopMediaPickerViews* parent, - const base::string16& app_name, - const base::string16& target_name, - std::unique_ptr<DesktopMediaList> screen_list, - std::unique_ptr<DesktopMediaList> window_list, - std::unique_ptr<DesktopMediaList> tab_list, - bool request_audio); + DesktopMediaPickerDialogView( + content::WebContents* parent_web_contents, + gfx::NativeWindow context, + DesktopMediaPickerViews* parent, + const base::string16& app_name, + const base::string16& target_name, + std::vector<std::unique_ptr<DesktopMediaList>> source_lists, + bool request_audio); ~DesktopMediaPickerDialogView() override; // Called by parent (DesktopMediaPickerViews) when it's destroyed. @@ -97,9 +96,7 @@ gfx::NativeWindow parent, const base::string16& app_name, const base::string16& target_name, - std::unique_ptr<DesktopMediaList> screen_list, - std::unique_ptr<DesktopMediaList> window_list, - std::unique_ptr<DesktopMediaList> tab_list, + std::vector<std::unique_ptr<DesktopMediaList>> source_lists, bool request_audio, const DoneCallback& done_callback) override;
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views_unittest.cc b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views_unittest.cc index 4c3b109d..a152700 100644 --- a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views_unittest.cc +++ b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views_unittest.cc
@@ -44,23 +44,19 @@ void SetUp() override { test_helper_.test_views_delegate()->set_layout_provider( ChromeLayoutProvider::CreateLayoutProvider()); - media_lists_[DesktopMediaID::TYPE_SCREEN] = new FakeDesktopMediaList(); - media_lists_[DesktopMediaID::TYPE_WINDOW] = new FakeDesktopMediaList(); - media_lists_[DesktopMediaID::TYPE_WEB_CONTENTS] = - new FakeDesktopMediaList(); - std::unique_ptr<FakeDesktopMediaList> screen_list( - media_lists_[DesktopMediaID::TYPE_SCREEN]); - std::unique_ptr<FakeDesktopMediaList> window_list( - media_lists_[DesktopMediaID::TYPE_WINDOW]); - std::unique_ptr<FakeDesktopMediaList> tab_list( - media_lists_[DesktopMediaID::TYPE_WEB_CONTENTS]); + + std::vector<std::unique_ptr<DesktopMediaList>> source_lists; + for (auto type : kSourceTypes) { + media_lists_[type] = new FakeDesktopMediaList(type); + source_lists.push_back( + std::unique_ptr<FakeDesktopMediaList>(media_lists_[type])); + } base::string16 app_name = base::ASCIIToUTF16("foo"); picker_views_.reset(new DesktopMediaPickerViews()); picker_views_->Show(nullptr, test_helper_.GetContext(), nullptr, app_name, - app_name, std::move(screen_list), - std::move(window_list), std::move(tab_list), true, + app_name, std::move(source_lists), true, base::Bind(&DesktopMediaPickerViewsTest::OnPickerDone, base::Unretained(this))); }
diff --git a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc index f8d13d1..49a7f9a 100644 --- a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
@@ -17,11 +17,13 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "base/values.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/chromeos/printing/combining_printer_detector.h" #include "chrome/browser/chromeos/printing/ppd_provider_factory.h" #include "chrome/browser/chromeos/printing/printer_configurer.h" -#include "chrome/browser/chromeos/printing/printer_discoverer.h" #include "chrome/browser/chromeos/printing/printer_info.h" #include "chrome/browser/chromeos/printing/printers_manager_factory.h" +#include "chrome/browser/chromeos/printing/usb_printer_detector.h" +#include "chrome/browser/chromeos/printing/usb_printer_detector_factory.h" #include "chrome/browser/download/download_prefs.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_finder.h" @@ -126,11 +128,11 @@ } // namespace CupsPrintersHandler::CupsPrintersHandler(content::WebUI* webui) - : printer_discoverer_(nullptr), + : printer_detector_(nullptr), profile_(Profile::FromWebUI(webui)), weak_factory_(this) { ppd_provider_ = printing::CreateProvider(profile_); - printer_configurer_ = chromeos::PrinterConfigurer::Create(profile_); + printer_configurer_ = PrinterConfigurer::Create(profile_); } CupsPrintersHandler::~CupsPrintersHandler() {} @@ -224,8 +226,7 @@ Printer::PrinterProtocol protocol = printer->GetProtocol(); prefs->RemovePrinter(printer_id); - chromeos::DebugDaemonClient* client = - chromeos::DBusThreadManager::Get()->GetDebugDaemonClient(); + DebugDaemonClient* client = DBusThreadManager::Get()->GetDebugDaemonClient(); client->CupsRemovePrinter(printer_name, base::Bind(&OnRemovedPrinter, protocol), base::Bind(&base::DoNothing)); @@ -290,10 +291,9 @@ } } - ::chromeos::QueryIppPrinter( - host.as_string(), port, printer_queue, - base::Bind(&CupsPrintersHandler::OnPrinterInfo, - weak_factory_.GetWeakPtr(), callback_id)); + QueryIppPrinter(host.as_string(), port, printer_queue, + base::Bind(&CupsPrintersHandler::OnPrinterInfo, + weak_factory_.GetWeakPtr(), callback_id)); } void CupsPrintersHandler::OnPrinterInfo(const std::string& callback_id, @@ -390,14 +390,13 @@ weak_factory_.GetWeakPtr(), base::Passed(&printer))); } -void CupsPrintersHandler::OnAddedPrinter( - std::unique_ptr<Printer> printer, - chromeos::PrinterSetupResult result_code) { +void CupsPrintersHandler::OnAddedPrinter(std::unique_ptr<Printer> printer, + PrinterSetupResult result_code) { std::string printer_name = printer->display_name(); UMA_HISTOGRAM_ENUMERATION("Printing.CUPS.PrinterSetupResult", result_code, - chromeos::PrinterSetupResult::kMaxValue); + PrinterSetupResult::kMaxValue); switch (result_code) { - case chromeos::PrinterSetupResult::kSuccess: { + case PrinterSetupResult::kSuccess: { UMA_HISTOGRAM_ENUMERATION("Printing.CUPS.PrinterAdded", printer->GetProtocol(), Printer::kProtocolMax); auto* manager = PrintersManagerFactory::GetForBrowserContext(profile_); @@ -405,32 +404,32 @@ manager->RegisterPrinter(std::move(printer)); break; } - case chromeos::PrinterSetupResult::kPpdNotFound: + case PrinterSetupResult::kPpdNotFound: LOG(WARNING) << "Could not locate requested PPD"; break; - case chromeos::PrinterSetupResult::kPpdTooLarge: + case PrinterSetupResult::kPpdTooLarge: LOG(WARNING) << "PPD is too large"; break; - case chromeos::PrinterSetupResult::kPpdUnretrievable: + case PrinterSetupResult::kPpdUnretrievable: LOG(WARNING) << "Could not retrieve PPD from server"; break; - case chromeos::PrinterSetupResult::kInvalidPpd: + case PrinterSetupResult::kInvalidPpd: LOG(WARNING) << "Provided PPD is invalid."; break; - case chromeos::PrinterSetupResult::kPrinterUnreachable: + case PrinterSetupResult::kPrinterUnreachable: LOG(WARNING) << "Could not contact printer for configuration"; break; - case chromeos::PrinterSetupResult::kDbusError: - case chromeos::PrinterSetupResult::kFatalError: + case PrinterSetupResult::kDbusError: + case PrinterSetupResult::kFatalError: LOG(ERROR) << "Unrecoverable error. Reboot required."; break; - case chromeos::PrinterSetupResult::kMaxValue: + case PrinterSetupResult::kMaxValue: NOTREACHED() << "This is not an expected value"; break; } CallJavascriptFunction( "cr.webUIListenerCallback", base::Value("on-add-cups-printer"), - base::Value(result_code == chromeos::PrinterSetupResult::kSuccess), + base::Value(result_code == PrinterSetupResult::kSuccess), base::Value(printer_name)); } @@ -495,30 +494,28 @@ void CupsPrintersHandler::ResolveManufacturersDone( const std::string& js_callback, - chromeos::printing::PpdProvider::CallbackResultCode result_code, + printing::PpdProvider::CallbackResultCode result_code, const std::vector<std::string>& manufacturers) { auto manufacturers_value = base::MakeUnique<base::ListValue>(); - if (result_code == chromeos::printing::PpdProvider::SUCCESS) { + if (result_code == printing::PpdProvider::SUCCESS) { manufacturers_value->AppendStrings(manufacturers); } base::DictionaryValue response; - response.SetBoolean("success", - result_code == chromeos::printing::PpdProvider::SUCCESS); + response.SetBoolean("success", result_code == printing::PpdProvider::SUCCESS); response.Set("manufacturers", std::move(manufacturers_value)); ResolveJavascriptCallback(base::Value(js_callback), response); } void CupsPrintersHandler::ResolvePrintersDone( const std::string& js_callback, - chromeos::printing::PpdProvider::CallbackResultCode result_code, + printing::PpdProvider::CallbackResultCode result_code, const std::vector<std::string>& printers) { auto printers_value = base::MakeUnique<base::ListValue>(); - if (result_code == chromeos::printing::PpdProvider::SUCCESS) { + if (result_code == printing::PpdProvider::SUCCESS) { printers_value->AppendStrings(printers); } base::DictionaryValue response; - response.SetBoolean("success", - result_code == chromeos::printing::PpdProvider::SUCCESS); + response.SetBoolean("success", result_code == printing::PpdProvider::SUCCESS); response.Set("models", std::move(printers_value)); ResolveJavascriptCallback(base::Value(js_callback), response); } @@ -533,31 +530,45 @@ } void CupsPrintersHandler::HandleStartDiscovery(const base::ListValue* args) { - if (!printer_discoverer_.get()) { - printer_discoverer_ = - chromeos::PrinterDiscoverer::CreateForProfile(profile_); - } - - printer_discoverer_->AddObserver(this); + // Create (or recreate) the printer_detector_. If one already existed, we + // want to start over anyways. + printer_detector_ = CombiningPrinterDetector::Create(); + PrinterDetector* usb_detector = + UsbPrinterDetectorFactory::GetInstance()->Get(profile_); + DCHECK(usb_detector); + printer_detector_->AddDetector(usb_detector); + printer_detector_->AddObserver(this); + OnPrintersFound(printer_detector_->GetPrinters()); + printer_detector_->Start(); } void CupsPrintersHandler::HandleStopDiscovery(const base::ListValue* args) { - printer_discoverer_.reset(); + printer_detector_.reset(); } void CupsPrintersHandler::OnPrintersFound( const std::vector<Printer>& printers) { std::unique_ptr<base::ListValue> printers_list = base::MakeUnique<base::ListValue>(); - for (const auto& printer : printers) { - printers_list->Append(GetPrinterInfo(printer)); + // Filter out already-configured printers as we go. + PrintersManager* printers_manager = + PrintersManagerFactory::GetForBrowserContext(profile_); + if (printers_manager != nullptr) { + for (const auto& printer : printers) { + if (printers_manager->GetPrinter(printer.id()).get() == nullptr) { + printers_list->Append(GetPrinterInfo(printer)); + } + } + } else { + LOG(WARNING) << "Failing to get available printers because no " + "PrintersManager exists."; } - FireWebUIListener("on-printer-discovered", *printers_list); } -void CupsPrintersHandler::OnDiscoveryInitialScanDone(int printer_count) { - UMA_HISTOGRAM_COUNTS_100("Printing.CUPS.PrintersDiscovered", printer_count); +void CupsPrintersHandler::OnPrinterScanComplete() { + UMA_HISTOGRAM_COUNTS_100("Printing.CUPS.PrintersDiscovered", + printer_detector_->GetPrinters().size()); FireWebUIListener("on-printer-discovery-done"); }
diff --git a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h index ee93a93..424ff52c 100644 --- a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h +++ b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h
@@ -12,7 +12,7 @@ #include "base/files/file_path.h" #include "base/memory/weak_ptr.h" #include "chrome/browser/chromeos/printing/printer_configurer.h" -#include "chrome/browser/chromeos/printing/printer_discoverer.h" +#include "chrome/browser/chromeos/printing/printer_detector.h" #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" #include "chromeos/printing/ppd_provider.h" #include "chromeos/printing/printer_configuration.h" @@ -28,12 +28,15 @@ namespace printing { class PpdProvider; } + +class CombiningPrinterDetector; + namespace settings { // Chrome OS CUPS printing settings page UI handler. class CupsPrintersHandler : public ::settings::SettingsPageUIHandler, public ui::SelectFileDialog::Listener, - public chromeos::PrinterDiscoverer::Observer { + public PrinterDetector::Observer { public: explicit CupsPrintersHandler(content::WebUI* webui); ~CupsPrintersHandler() override; @@ -68,7 +71,7 @@ void HandleAddCupsPrinter(const base::ListValue* args); void OnAddedPrinter(std::unique_ptr<Printer> printer, - chromeos::PrinterSetupResult result); + PrinterSetupResult result); void OnAddPrinterError(); // Get a list of all manufacturers for which we have at least one model of @@ -88,11 +91,11 @@ // PpdProvider callback handlers. void ResolveManufacturersDone( const std::string& js_callback, - chromeos::printing::PpdProvider::CallbackResultCode result_code, + printing::PpdProvider::CallbackResultCode result_code, const std::vector<std::string>& available); void ResolvePrintersDone( const std::string& js_callback, - chromeos::printing::PpdProvider::CallbackResultCode result_code, + printing::PpdProvider::CallbackResultCode result_code, const std::vector<std::string>& available); // ui::SelectFileDialog::Listener override: @@ -103,9 +106,9 @@ void HandleStartDiscovery(const base::ListValue* args); void HandleStopDiscovery(const base::ListValue* args); - // chromeos::PrinterDiscoverer::Observer override: + // PrinterDetector::Observer implementations: void OnPrintersFound(const std::vector<Printer>& printers) override; - void OnDiscoveryInitialScanDone(int printer_count) override; + void OnPrinterScanComplete() override; // Invokes debugd to add the printer to CUPS. If |ipp_everywhere| is true, // automatic configuration will be attempted and |ppd_path| is ignored. @@ -116,9 +119,9 @@ const base::FilePath& ppd_path, bool ipp_everywhere); - std::unique_ptr<chromeos::PrinterDiscoverer> printer_discoverer_; - scoped_refptr<chromeos::printing::PpdProvider> ppd_provider_; - std::unique_ptr<chromeos::PrinterConfigurer> printer_configurer_; + std::unique_ptr<CombiningPrinterDetector> printer_detector_; + scoped_refptr<printing::PpdProvider> ppd_provider_; + std::unique_ptr<PrinterConfigurer> printer_configurer_; Profile* profile_; scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
diff --git a/chrome/common/extensions/api/desktop_capture.json b/chrome/common/extensions/api/desktop_capture.json index 7c20978..9d99897f 100644 --- a/chrome/common/extensions/api/desktop_capture.json +++ b/chrome/common/extensions/api/desktop_capture.json
@@ -24,7 +24,7 @@ "type": "array", "items": { "$ref": "DesktopCaptureSourceType" }, "name": "sources", - "description": "Set of sources that should be shown to the user." + "description": "Set of sources that should be shown to the user. The sources order in the set decides the tab order in the picker." }, { "$ref": "tabs.Tab",
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index ee36981..764e6d03 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -1937,11 +1937,6 @@ // and get enrolled into a domain automatically. const char kOobeControllerDetected[] = "OobeControllerDetected"; -// A 64-bit signed integer pref (encoded as a string) which stores the time -// of the last OOBE-initiated update check not resulting in an update. -const char kOobeTimeOfLastUpdateCheckWithoutUpdate[] = - "OobeTimeOfLastUpdateCheckWithoutUpdate"; - // A boolean pref for whether the Goodies promotion webpage has been displayed, // or otherwise disqualified for auto-display, on this device. const char kCanShowOobeGoodiesPage[] = "CanShowOobeGoodiesPage";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 985b3aa..5584f43 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -687,7 +687,6 @@ extern const char kOobeScreenPending[]; extern const char kOobeMdMode[]; extern const char kOobeControllerDetected[]; -extern const char kOobeTimeOfLastUpdateCheckWithoutUpdate[]; extern const char kCanShowOobeGoodiesPage[]; extern const char kDeviceRegistered[]; extern const char kEnrollmentRecoveryRequired[];
diff --git a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc index 9e449139f..551dd8a9 100644 --- a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc +++ b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
@@ -717,6 +717,53 @@ UTF16ToUTF8(password3_), true); } +// Fill a password field if the stored username is a prefix of username in +// read-only field. +TEST_F(PasswordAutofillAgentTest, + AutocompletePasswordForReadonlyUsernamePrefixMatched) { + base::string16 username_at = username3_ + base::UTF8ToUTF16("@example.com"); + username_element_.SetValue(WebString::FromUTF16(username_at)); + SetElementReadOnly(username_element_, true); + + // Filled even though the username in the form is only a proper prefix of the + // stored username. + SimulateOnFillPasswordForm(fill_data_); + CheckTextFieldsState(UTF16ToUTF8(username_at), false, UTF16ToUTF8(password3_), + true); +} + +// Do not fill a password field if the stored username is a prefix without @ +// of username in read-only field. +TEST_F(PasswordAutofillAgentTest, + DontAutocompletePasswordForReadonlyUsernamePrefixMatched) { + base::string16 prefilled_username = + username3_ + base::UTF8ToUTF16("example.com"); + username_element_.SetValue(WebString::FromUTF16(prefilled_username)); + SetElementReadOnly(username_element_, true); + + // Filled even though the username in the form is only a proper prefix of the + // stored username. + SimulateOnFillPasswordForm(fill_data_); + CheckTextFieldsState(UTF16ToUTF8(prefilled_username), false, std::string(), + false); +} + +// Do not fill a password field if the field isn't readonly despite the stored +// username is a prefix without @ of username in read-only field. +TEST_F( + PasswordAutofillAgentTest, + DontAutocompletePasswordForNotReadonlyUsernameFieldEvenWhenPrefixMatched) { + base::string16 prefilled_username = + username3_ + base::UTF8ToUTF16("@example.com"); + username_element_.SetValue(WebString::FromUTF16(prefilled_username)); + + // Filled even though the username in the form is only a proper prefix of the + // stored username. + SimulateOnFillPasswordForm(fill_data_); + CheckTextFieldsState(UTF16ToUTF8(prefilled_username), false, std::string(), + false); +} + // If a username field is empty and readonly, don't autofill. TEST_F(PasswordAutofillAgentTest, NoAutocompletePasswordForReadonlyUsernameUnmatched) {
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/BottomSheetTestRule.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/BottomSheetTestRule.java index d94dfcb..d9151d2 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/BottomSheetTestRule.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/BottomSheetTestRule.java
@@ -4,10 +4,15 @@ package org.chromium.chrome.test; +import static org.chromium.chrome.browser.ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE; +import static org.chromium.chrome.test.BottomSheetTestRule.ENABLE_CHROME_HOME; +import static org.chromium.chrome.test.ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG; + import android.support.v7.widget.RecyclerView; import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.CallbackHelper; +import org.chromium.base.test.util.CommandLineFlags; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.preferences.ChromePreferenceManager; @@ -20,6 +25,8 @@ /** * Junit4 rule for tests testing the Chrome Home bottom sheet. */ +@CommandLineFlags.Add({ENABLE_CHROME_HOME, DISABLE_FIRST_RUN_EXPERIENCE, + DISABLE_NETWORK_PREDICTION_FLAG}) public class BottomSheetTestRule extends ChromeTabbedActivityTestRule { /** An observer used to record events that occur with respect to the bottom sheet. */ public static class Observer extends EmptyBottomSheetObserver { @@ -158,7 +165,7 @@ /** * Set the bottom sheet's state on the UI thread. * - * @param state The state to set the sheet to. + * @param state The state to set the sheet to. * @param animate If the sheet should animate to the provided state. */ public void setSheetState(final int state, final boolean animate) { @@ -190,7 +197,7 @@ /** * @param itemId The id of the MenuItem corresponding to the {@link BottomSheetContent} to - * select. + * select. */ public void selectBottomSheetContent(final int itemId) { ThreadUtils.runOnUiThreadBlocking(new Runnable() {
diff --git a/chrome/test/base/default_ash_event_generator_delegate.cc b/chrome/test/base/default_ash_event_generator_delegate.cc index b5a9e47..7038982 100644 --- a/chrome/test/base/default_ash_event_generator_delegate.cc +++ b/chrome/test/base/default_ash_event_generator_delegate.cc
@@ -27,9 +27,10 @@ return nullptr; } -void DefaultAshEventGeneratorDelegate::DispatchKeyEventToIME( - ui::EventTarget* target, - ui::KeyEvent* event) { +ui::EventDispatchDetails +DefaultAshEventGeneratorDelegate::DispatchKeyEventToIME(ui::EventTarget* target, + ui::KeyEvent* event) { + return ui::EventDispatchDetails(); } DefaultAshEventGeneratorDelegate::DefaultAshEventGeneratorDelegate()
diff --git a/chrome/test/base/default_ash_event_generator_delegate.h b/chrome/test/base/default_ash_event_generator_delegate.h index 54c543c3..9327ed7 100644 --- a/chrome/test/base/default_ash_event_generator_delegate.h +++ b/chrome/test/base/default_ash_event_generator_delegate.h
@@ -26,8 +26,8 @@ aura::client::ScreenPositionClient* GetScreenPositionClient( const aura::Window* window) const override; - void DispatchKeyEventToIME(ui::EventTarget* target, - ui::KeyEvent* event) override; + ui::EventDispatchDetails DispatchKeyEventToIME(ui::EventTarget* target, + ui::KeyEvent* event) override; private: friend struct base::DefaultSingletonTraits<DefaultAshEventGeneratorDelegate>;
diff --git a/chrome/test/data/extensions/api_test/bindings/unavailable_bindings_never_registered/background.js b/chrome/test/data/extensions/api_test/bindings/unavailable_bindings_never_registered/background.js index d5fd5454..cdab7cec 100644 --- a/chrome/test/data/extensions/api_test/bindings/unavailable_bindings_never_registered/background.js +++ b/chrome/test/data/extensions/api_test/bindings/unavailable_bindings_never_registered/background.js
@@ -39,10 +39,15 @@ assertRuntimeIsRegistered(); assertStorageIsRegistered(); + var jsBindingsError = + "'storage' requires a different Feature that is not present."; + var nativeBindingsError = + "'storage.get' is not available in this context."; + var regexp = new RegExp(nativeBindingsError + '|' + jsBindingsError); // Although storage should throw an error on use since it's removed. chrome.test.assertThrows( chrome.storage.local.get, chrome.storage.local, [function(){}], - "'storage' requires a different Feature that is not present."); + regexp); chrome.test.succeed(); }));
diff --git a/chrome/test/data/extensions/api_test/lazy_events/chrome_updates/listener/background.js b/chrome/test/data/extensions/api_test/lazy_events/chrome_updates/listener/background.js new file mode 100644 index 0000000..dbed65f --- /dev/null +++ b/chrome/test/data/extensions/api_test/lazy_events/chrome_updates/listener/background.js
@@ -0,0 +1,9 @@ +// 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. + +chrome.runtime.onInstalled.addListener(function(info) { + if (info.reason == 'chrome_update') + chrome.test.sendMessage('update event'); +}); +chrome.test.notifyPass();
diff --git a/chrome/test/data/extensions/api_test/lazy_events/chrome_updates/listener/manifest.json b/chrome/test/data/extensions/api_test/lazy_events/chrome_updates/listener/manifest.json new file mode 100644 index 0000000..aa93c99 --- /dev/null +++ b/chrome/test/data/extensions/api_test/lazy_events/chrome_updates/listener/manifest.json
@@ -0,0 +1,10 @@ +{ + "name": "chrome updates listener", + "description": "listens for chrome updates", + "background": { + "scripts": ["background.js"], + "persistent": false + }, + "version": "0.1", + "manifest_version": 2 +}
diff --git a/chrome/test/data/extensions/api_test/lazy_events/chrome_updates/non_listener/background.js b/chrome/test/data/extensions/api_test/lazy_events/chrome_updates/non_listener/background.js new file mode 100644 index 0000000..7be7f34 --- /dev/null +++ b/chrome/test/data/extensions/api_test/lazy_events/chrome_updates/non_listener/background.js
@@ -0,0 +1,6 @@ +// 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. + +chrome.test.sendMessage('not listening'); +chrome.test.notifyPass();
diff --git a/chrome/test/data/extensions/api_test/lazy_events/chrome_updates/non_listener/manifest.json b/chrome/test/data/extensions/api_test/lazy_events/chrome_updates/non_listener/manifest.json new file mode 100644 index 0000000..c14c0fe80 --- /dev/null +++ b/chrome/test/data/extensions/api_test/lazy_events/chrome_updates/non_listener/manifest.json
@@ -0,0 +1,10 @@ +{ + "name": "chrome updates non listener", + "description": "does not listen for chrome updates", + "background": { + "scripts": ["background.js"], + "persistent": false + }, + "version": "0.1", + "manifest_version": 2 +}
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc index 893d84f3..e55f198 100644 --- a/components/autofill/content/renderer/password_autofill_agent.cc +++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -268,13 +268,13 @@ return element.IsEnabled() && !element.IsReadOnly(); } -bool DoUsernamesMatch(const base::string16& username1, - const base::string16& username2, +bool DoUsernamesMatch(const base::string16& potential_suggestion, + const base::string16& current_username, bool exact_match) { - if (exact_match) - return username1 == username2; - return FieldIsSuggestionSubstringStartingOnTokenBoundary(username1, username2, - true); + if (potential_suggestion == current_username) + return true; + return !exact_match && IsPrefixOfEmailEndingWithAtSign(current_username, + potential_suggestion); } // Returns whether the given |element| is editable. @@ -373,6 +373,54 @@ } } +// This function attempts to find the matching credentials for the +// |current_username| by scanning |fill_data|. The result is written in +// |username| and |password| parameters. +void FindMatchesByUsername(const PasswordFormFillData& fill_data, + const base::string16& current_username, + bool exact_username_match, + RendererSavePasswordProgressLogger* logger, + base::string16* username, + base::string16* password) { + // Look for any suitable matches to current field text. + if (DoUsernamesMatch(fill_data.username_field.value, current_username, + exact_username_match)) { + *username = fill_data.username_field.value; + *password = fill_data.password_field.value; + if (logger) + logger->LogMessage(Logger::STRING_USERNAMES_MATCH); + } else { + // Scan additional logins for a match. + for (const auto& it : fill_data.additional_logins) { + if (DoUsernamesMatch(it.first, current_username, exact_username_match)) { + *username = it.first; + *password = it.second.password; + break; + } + } + if (logger) { + logger->LogBoolean(Logger::STRING_MATCH_IN_ADDITIONAL, + !(username->empty() && password->empty())); + } + + // Check possible usernames. + if (username->empty() && password->empty()) { + for (const auto& it : fill_data.other_possible_usernames) { + for (size_t i = 0; i < it.second.size(); ++i) { + if (DoUsernamesMatch(it.second[i], current_username, + exact_username_match)) { + *username = it.second[i]; + *password = it.first.password; + break; + } + } + if (!password->empty()) + break; + } + } + } +} + // This function attempts to fill |username_element| and |password_element| // with values from |fill_data|. The |password_element| will only have the // suggestedValue set, and will be registered for copying that to the real @@ -404,43 +452,9 @@ base::string16 username; base::string16 password; - // Look for any suitable matches to current field text. - if (DoUsernamesMatch(fill_data.username_field.value, current_username, - exact_username_match)) { - username = fill_data.username_field.value; - password = fill_data.password_field.value; - if (logger) - logger->LogMessage(Logger::STRING_USERNAMES_MATCH); - } else { - // Scan additional logins for a match. - for (const auto& it : fill_data.additional_logins) { - if (DoUsernamesMatch(it.first, current_username, exact_username_match)) { - username = it.first; - password = it.second.password; - break; - } - } - if (logger) { - logger->LogBoolean(Logger::STRING_MATCH_IN_ADDITIONAL, - !(username.empty() && password.empty())); - } + FindMatchesByUsername(fill_data, current_username, exact_username_match, + logger, &username, &password); - // Check possible usernames. - if (username.empty() && password.empty()) { - for (const auto& it : fill_data.other_possible_usernames) { - for (size_t i = 0; i < it.second.size(); ++i) { - if (DoUsernamesMatch( - it.second[i], current_username, exact_username_match)) { - username = it.second[i]; - password = it.first.password; - break; - } - } - if (!username.empty() && !password.empty()) - break; - } - } - } if (password.empty()) return false; @@ -462,10 +476,6 @@ form_util::PreviewSuggestion(username, current_username, username_element); } - } else if (current_username != username) { - // If the username can't be filled and it doesn't match a saved password - // as is, don't autofill a password. - return false; } // Wait to fill in the password until a user gesture occurs. This is to make @@ -550,12 +560,14 @@ blink::WebString::FromUTF16(fill_data.username_field.value)); } - // Fill if we have an exact match for the username. Note that this sets - // username to autofilled. + bool exact_username_match = + username_element.IsNull() || IsElementEditable(username_element); + // Use the exact match for the editable username fields and allow prefix + // match for read-only username fields. return FillUserNameAndPassword( - &username_element, &password_element, fill_data, - true /* exact_username_match */, false /* set_selection */, - field_value_and_properties_map, registration_callback, logger); + &username_element, &password_element, fill_data, exact_username_match, + false /* set_selection */, field_value_and_properties_map, + registration_callback, logger); } // Annotate |forms| with form and field signatures as HTML attributes.
diff --git a/components/autofill/core/common/autofill_util.cc b/components/autofill/core/common/autofill_util.cc index 50e5017..718f9221 100644 --- a/components/autofill/core/common/autofill_util.cc +++ b/components/autofill/core/common/autofill_util.cc
@@ -115,6 +115,12 @@ base::string16::npos; } +bool IsPrefixOfEmailEndingWithAtSign(const base::string16& full_string, + const base::string16& prefix) { + return base::StartsWith(full_string, prefix + base::UTF8ToUTF16("@"), + base::CompareCase::SENSITIVE); +} + size_t GetTextSelectionStart(const base::string16& suggestion, const base::string16& field_contents, bool case_sensitive) {
diff --git a/components/autofill/core/common/autofill_util.h b/components/autofill/core/common/autofill_util.h index 6a67f3e..e51d7bd 100644 --- a/components/autofill/core/common/autofill_util.h +++ b/components/autofill/core/common/autofill_util.h
@@ -56,6 +56,12 @@ const base::string16& field_contents, bool case_sensitive); +// Currently, a token for the purposes of this method is defined as {'@'}. +// Returns true if the |full_string| has a |prefix| as a prefix and the prefix +// ends on a token. +bool IsPrefixOfEmailEndingWithAtSign(const base::string16& full_string, + const base::string16& prefix); + // Finds the first occurrence of a searched substring |field_contents| within // the string |suggestion| starting at token boundaries and returns the index to // the end of the located substring, or base::string16::npos if the substring is
diff --git a/components/autofill/core/common/autofill_util_unittest.cc b/components/autofill/core/common/autofill_util_unittest.cc index 6e04dc7..6a59b0d 100644 --- a/components/autofill/core/common/autofill_util_unittest.cc +++ b/components/autofill/core/common/autofill_util_unittest.cc
@@ -70,6 +70,48 @@ FieldIsTokenBoundarySubstringCase{"ab", "", false, true}, FieldIsTokenBoundarySubstringCase{"ab", "", true, true})); +struct AtSignPrefixCase { + const char* const field_suggestion; + const char* const field_contents; + const bool expected_result; +}; + +class PrefixEndingOnTokenBoundaryTest + : public testing::TestWithParam<AtSignPrefixCase> {}; + +TEST_P(PrefixEndingOnTokenBoundaryTest, IsPrefixOfEmailEndingWithAtSign) { + auto test_case = GetParam(); + SCOPED_TRACE(testing::Message() + << "suggestion = " << test_case.field_suggestion + << ", contents = " << test_case.field_contents); + + EXPECT_EQ(test_case.expected_result, + IsPrefixOfEmailEndingWithAtSign( + base::ASCIIToUTF16(test_case.field_suggestion), + base::ASCIIToUTF16(test_case.field_contents))); +} + +INSTANTIATE_TEST_CASE_P( + AutofillUtilTest, + PrefixEndingOnTokenBoundaryTest, + testing::Values(AtSignPrefixCase{"ab@cd.b", "a", false}, + AtSignPrefixCase{"ab@cd.b", "b", false}, + AtSignPrefixCase{"ab@cd.b", "Ab", false}, + AtSignPrefixCase{"ab@cd.b", "cd", false}, + AtSignPrefixCase{"ab@cd.b", "d", false}, + AtSignPrefixCase{"ab@cd.b", "b@", false}, + AtSignPrefixCase{"ab@cd.b", "cd.b", false}, + AtSignPrefixCase{"ab@cd.b", "b@cd", false}, + AtSignPrefixCase{"ab@cd.b", "ab@c", false}, + AtSignPrefixCase{"ba.a.ab", "a.a", false}, + AtSignPrefixCase{"", "ab", false}, + AtSignPrefixCase{"ab@c", "ab@", false}, + AtSignPrefixCase{"ab@cd@g", "ab", true}, + AtSignPrefixCase{"ab@cd@g", "ab@cd", true}, + AtSignPrefixCase{"abc", "abc", false}, + AtSignPrefixCase{"ab", "", false}, + AtSignPrefixCase{"ab@cd.b", "ab", true})); + // Tests for GetTextSelectionStart(). struct GetTextSelectionStartCase { const char* const field_suggestion;
diff --git a/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl_unittest.cc b/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl_unittest.cc index 0a01cb4..74f3454 100644 --- a/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl_unittest.cc +++ b/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl_unittest.cc
@@ -195,6 +195,67 @@ EXPECT_EQ(count, trigger_event.events(0).count()); } + void VerifyUserActionsTriggerChecks( + const base::UserActionTester& user_action_tester, + int expected_foo_count, + int expected_bar_count, + int expected_qux_count) { + EXPECT_EQ(expected_foo_count, + user_action_tester.GetActionCount( + "InProductHelp.ShouldTriggerHelpUI.test_foo")); + EXPECT_EQ(expected_bar_count, + user_action_tester.GetActionCount( + "InProductHelp.ShouldTriggerHelpUI.test_bar")); + EXPECT_EQ(expected_qux_count, + user_action_tester.GetActionCount( + "InProductHelp.ShouldTriggerHelpUI.test_qux")); + } + + void VerifyUserActionsTriggered( + const base::UserActionTester& user_action_tester, + int expected_foo_count, + int expected_bar_count, + int expected_qux_count) { + EXPECT_EQ( + expected_foo_count, + user_action_tester.GetActionCount( + "InProductHelp.ShouldTriggerHelpUIResult.Triggered.test_foo")); + EXPECT_EQ( + expected_bar_count, + user_action_tester.GetActionCount( + "InProductHelp.ShouldTriggerHelpUIResult.Triggered.test_bar")); + EXPECT_EQ( + expected_qux_count, + user_action_tester.GetActionCount( + "InProductHelp.ShouldTriggerHelpUIResult.Triggered.test_qux")); + } + + void VerifyUserActionsNotTriggered( + const base::UserActionTester& user_action_tester, + int expected_foo_count, + int expected_bar_count, + int expected_qux_count) { + EXPECT_EQ( + expected_foo_count, + user_action_tester.GetActionCount( + "InProductHelp.ShouldTriggerHelpUIResult.NotTriggered.test_foo")); + EXPECT_EQ( + expected_bar_count, + user_action_tester.GetActionCount( + "InProductHelp.ShouldTriggerHelpUIResult.NotTriggered.test_bar")); + EXPECT_EQ( + expected_qux_count, + user_action_tester.GetActionCount( + "InProductHelp.ShouldTriggerHelpUIResult.NotTriggered.test_qux")); + } + + void VerifyUserActionsDismissed( + const base::UserActionTester& user_action_tester, + int expected_dismissed_count) { + EXPECT_EQ(expected_dismissed_count, + user_action_tester.GetActionCount("InProductHelp.Dismissed")); + } + protected: virtual std::unique_ptr<TestInMemoryStore> CreateStore() { // Returns a Store that will successfully initialize. @@ -399,6 +460,7 @@ tracker_->AddOnInitializedCallback(base::Bind( &StoringInitializedCallback::OnInitialized, base::Unretained(&callback))); base::RunLoop().RunUntilIdle(); + base::UserActionTester user_action_tester; // The first time a feature triggers it should be shown. EXPECT_TRUE(tracker_->ShouldTriggerHelpUI(kTestFeatureFoo)); @@ -407,6 +469,10 @@ VerifyEventTriggerEvents(kTestFeatureFoo, 1u); EXPECT_FALSE(tracker_->ShouldTriggerHelpUI(kTestFeatureQux)); VerifyEventTriggerEvents(kTestFeatureQux, 0); + VerifyUserActionsTriggerChecks(user_action_tester, 2, 0, 1); + VerifyUserActionsTriggered(user_action_tester, 1, 0, 0); + VerifyUserActionsNotTriggered(user_action_tester, 1, 0, 1); + VerifyUserActionsDismissed(user_action_tester, 0); // While in-product help is currently showing, no other features should be // shown. @@ -414,6 +480,10 @@ VerifyEventTriggerEvents(kTestFeatureBar, 0); EXPECT_FALSE(tracker_->ShouldTriggerHelpUI(kTestFeatureQux)); VerifyEventTriggerEvents(kTestFeatureQux, 0); + VerifyUserActionsTriggerChecks(user_action_tester, 2, 1, 2); + VerifyUserActionsTriggered(user_action_tester, 1, 0, 0); + VerifyUserActionsNotTriggered(user_action_tester, 1, 1, 2); + VerifyUserActionsDismissed(user_action_tester, 0); // After dismissing the current in-product help, that feature can not be shown // again, but a different feature should. @@ -424,6 +494,10 @@ VerifyEventTriggerEvents(kTestFeatureBar, 1u); EXPECT_FALSE(tracker_->ShouldTriggerHelpUI(kTestFeatureQux)); VerifyEventTriggerEvents(kTestFeatureQux, 0); + VerifyUserActionsTriggerChecks(user_action_tester, 3, 2, 3); + VerifyUserActionsTriggered(user_action_tester, 1, 1, 0); + VerifyUserActionsNotTriggered(user_action_tester, 2, 1, 3); + VerifyUserActionsDismissed(user_action_tester, 1); // After dismissing the second registered feature, no more in-product help // should be shown, since kTestFeatureQux is invalid. @@ -434,6 +508,10 @@ VerifyEventTriggerEvents(kTestFeatureBar, 1u); EXPECT_FALSE(tracker_->ShouldTriggerHelpUI(kTestFeatureQux)); VerifyEventTriggerEvents(kTestFeatureQux, 0); + VerifyUserActionsTriggerChecks(user_action_tester, 4, 3, 4); + VerifyUserActionsTriggered(user_action_tester, 1, 1, 0); + VerifyUserActionsNotTriggered(user_action_tester, 3, 2, 4); + VerifyUserActionsDismissed(user_action_tester, 2); } TEST_F(FeatureEngagementTrackerImplTest, TestNotifyEvent) {
diff --git a/components/feature_engagement_tracker/internal/stats.cc b/components/feature_engagement_tracker/internal/stats.cc index a424bf4..8b0b88f 100644 --- a/components/feature_engagement_tracker/internal/stats.cc +++ b/components/feature_engagement_tracker/internal/stats.cc
@@ -97,11 +97,18 @@ name.append(feature.name); base::RecordComputedAction(name); - // Total count histogram, used to compute the percentage of each failure type. + // Total count histogram, used to compute the percentage of each failure type, + // in addition to a user action for whether the result was to trigger or not. if (result.NoErrors()) { LogTriggerHelpUIResult(name, TriggerHelpUIResult::SUCCESS); + std::string name = "InProductHelp.ShouldTriggerHelpUIResult.Triggered."; + name.append(feature.name); + base::RecordComputedAction(name); } else { LogTriggerHelpUIResult(name, TriggerHelpUIResult::FAILURE); + std::string name = "InProductHelp.ShouldTriggerHelpUIResult.NotTriggered."; + name.append(feature.name); + base::RecordComputedAction(name); } // Histogram about the failure reasons.
diff --git a/components/offline_pages/core/DEPS b/components/offline_pages/core/DEPS index 5ef8eb9f..5d8bc16 100644 --- a/components/offline_pages/core/DEPS +++ b/components/offline_pages/core/DEPS
@@ -1,8 +1,4 @@ include_rules = [ "+components/keyed_service", - "+components/gcm_driver", - "+components/ntp_snippets", - "+components/version_info", - "+net", "+sql", ]
diff --git a/components/offline_pages/core/prefetch/DEPS b/components/offline_pages/core/prefetch/DEPS index 9a26362..4a85e6c 100644 --- a/components/offline_pages/core/prefetch/DEPS +++ b/components/offline_pages/core/prefetch/DEPS
@@ -1,3 +1,7 @@ include_rules = [ "+google_apis", + "+components/gcm_driver", + "+components/ntp_snippets", + "+components/version_info", + "+net", ]
diff --git a/components/page_info_strings.grdp b/components/page_info_strings.grdp index 22d9aeeb..9a35a8b 100644 --- a/components/page_info_strings.grdp +++ b/components/page_info_strings.grdp
@@ -60,10 +60,10 @@ <!-- Administrator-provided certificate notifications --> <!-- TODO(crbug.com/717802): Only include this on Chrome OS. --> - <message name="IDS_CERT_POLICY_PROVIDED_CERT_MESSAGE" desc="Text that is displayed in the Website Settings popup when using an administrator-provided certificate"> + <message name="IDS_CERT_POLICY_PROVIDED_CERT_MESSAGE" desc="Text that is displayed in the Page Info popup when using an administrator-provided certificate"> You have accessed content using an administrator-provided certificate. Data you provide to <ph name="DOMAIN">$1<ex>www.google.com</ex></ph> can be intercepted by your administrator. </message> - + <!-- Certificate exception decision UI (after clicking through an SSL certificate error) --> <!-- TODO(crbug.com/502473): Support revoking certificate overrides on iOS Page Info. --> <message name="IDS_PAGE_INFO_INVALID_CERTIFICATE_DESCRIPTION" desc="A short paragraph to the user that security warnings are disabled. This is the case when the user has encountered a certificate error for the current site and chosen to override it."> @@ -176,68 +176,68 @@ </if> <!-- Permission names --> - <message name="IDS_PAGE_INFO_TYPE_ADS" desc="The label used for the ads permission controls in the Website Settings popup."> + <message name="IDS_PAGE_INFO_TYPE_ADS" desc="The label used for the ads permission controls in the Page Info popup."> Ads </message> - <message name="IDS_PAGE_INFO_TYPE_AUTOPLAY" desc="The label used for the autoplay permission controls in the Website Settings popup."> + <message name="IDS_PAGE_INFO_TYPE_AUTOPLAY" desc="The label used for the autoplay permission controls in the Page Info popup."> Autoplay </message> - <message name="IDS_PAGE_INFO_TYPE_BACKGROUND_SYNC" desc="The label used for the background sync permission controls in the Website Settings popup."> + <message name="IDS_PAGE_INFO_TYPE_BACKGROUND_SYNC" desc="The label used for the background sync permission controls in the Page Info popup."> Background Sync </message> - <message name="IDS_PAGE_INFO_TYPE_IMAGES" desc="The label used for images permission controls in the Website Settings popup."> + <message name="IDS_PAGE_INFO_TYPE_IMAGES" desc="The label used for images permission controls in the Page Info popup."> Images </message> - <message name="IDS_PAGE_INFO_TYPE_JAVASCRIPT" desc="The label used for JavaScript permission controls in the Website Settings popup."> + <message name="IDS_PAGE_INFO_TYPE_JAVASCRIPT" desc="The label used for JavaScript permission controls in the Page Info popup."> JavaScript </message> - <message name="IDS_PAGE_INFO_TYPE_POPUPS" desc="The label used for popups permission controls in the Website Settings popup."> + <message name="IDS_PAGE_INFO_TYPE_POPUPS" desc="The label used for popups permission controls in the Page Info popup."> Popups </message> - <message name="IDS_PAGE_INFO_TYPE_FLASH" desc="The label used for Flash permissions in the Website Settings popup."> + <message name="IDS_PAGE_INFO_TYPE_FLASH" desc="The label used for Flash permissions in the Page Info popup."> Flash </message> - <message name="IDS_PAGE_INFO_TYPE_LOCATION" desc="The label used for location permission controls in the Website Settings popup."> + <message name="IDS_PAGE_INFO_TYPE_LOCATION" desc="The label used for location permission controls in the Page Info popup."> Location </message> - <message name="IDS_PAGE_INFO_TYPE_NOTIFICATIONS" desc="The label used for notifications permission controls in the Website Settings popup."> + <message name="IDS_PAGE_INFO_TYPE_NOTIFICATIONS" desc="The label used for notifications permission controls in the Page Info popup."> Notifications </message> - <message name="IDS_PAGE_INFO_TYPE_MIC" desc="The label used for the microphone permission controls in the Website Settings popup."> + <message name="IDS_PAGE_INFO_TYPE_MIC" desc="The label used for the microphone permission controls in the Page Info popup."> Microphone </message> - <message name="IDS_PAGE_INFO_TYPE_CAMERA" desc="The label used for the camera permission controls in the Website Settings popup."> + <message name="IDS_PAGE_INFO_TYPE_CAMERA" desc="The label used for the camera permission controls in the Page Info popup."> Camera </message> - <message name="IDS_PAGE_INFO_TYPE_MIDI_SYSEX" desc="The label used for MIDI system exclusive message permission controls in the Website Settings popup."> + <message name="IDS_PAGE_INFO_TYPE_MIDI_SYSEX" desc="The label used for MIDI system exclusive message permission controls in the Page Info popup."> MIDI devices full control </message> <!-- TODO(crbug.com/716303): A few permissions are missing here. --> <!-- Permission values --> - <message name="IDS_PAGE_INFO_BUTTON_TEXT_ALLOWED_BY_USER" desc="The Website Settings popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button was explicitly set to allow by the user."> + <message name="IDS_PAGE_INFO_BUTTON_TEXT_ALLOWED_BY_USER" desc="The Page Info popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button was explicitly set to allow by the user."> Allow </message> - <message name="IDS_PAGE_INFO_BUTTON_TEXT_BLOCKED_BY_USER" desc="The Website Settings popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button was explicitly set to block by the user."> + <message name="IDS_PAGE_INFO_BUTTON_TEXT_BLOCKED_BY_USER" desc="The Page Info popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button was explicitly set to block by the user."> Block </message> - <message name="IDS_PAGE_INFO_BUTTON_TEXT_ASK_BY_USER" desc="The Website Settings popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button was explicitly set to ask by the user."> + <message name="IDS_PAGE_INFO_BUTTON_TEXT_ASK_BY_USER" desc="The Page Info popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button was explicitly set to ask by the user."> Ask </message> - <message name="IDS_PAGE_INFO_BUTTON_TEXT_DETECT_IMPORTANT_CONTENT_BY_USER" desc="The Website Settings popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button was explicitly set to detect important content by the user."> + <message name="IDS_PAGE_INFO_BUTTON_TEXT_DETECT_IMPORTANT_CONTENT_BY_USER" desc="The Page Info popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button was explicitly set to detect important content by the user."> Detect </message> - <message name="IDS_PAGE_INFO_BUTTON_TEXT_ALLOWED_BY_DEFAULT" desc="The Website Settings popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button is set to the default setting and the default settings is allow."> + <message name="IDS_PAGE_INFO_BUTTON_TEXT_ALLOWED_BY_DEFAULT" desc="The Page Info popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button is set to the default setting and the default settings is allow."> Allow (default) </message> - <message name="IDS_PAGE_INFO_BUTTON_TEXT_BLOCKED_BY_DEFAULT" desc="The Website Settings popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button is set to the default setting and the default settings is block."> + <message name="IDS_PAGE_INFO_BUTTON_TEXT_BLOCKED_BY_DEFAULT" desc="The Page Info popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button is set to the default setting and the default settings is block."> Block (default) </message> - <message name="IDS_PAGE_INFO_BUTTON_TEXT_ASK_BY_DEFAULT" desc="The Website Settings popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button is set to the default setting and the default settings is ask."> + <message name="IDS_PAGE_INFO_BUTTON_TEXT_ASK_BY_DEFAULT" desc="The Page Info popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button is set to the default setting and the default settings is ask."> Ask (default) </message> - <message name="IDS_PAGE_INFO_BUTTON_TEXT_DETECT_IMPORTANT_CONTENT_BY_DEFAULT" desc="The Website Settings popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button is set to the default setting and the default settings is detect important content."> + <message name="IDS_PAGE_INFO_BUTTON_TEXT_DETECT_IMPORTANT_CONTENT_BY_DEFAULT" desc="The Page Info popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button is set to the default setting and the default settings is detect important content."> Detect (default) </message>
diff --git a/components/safe_browsing/csd.proto b/components/safe_browsing/csd.proto index eb6fe64..132372dc 100644 --- a/components/safe_browsing/csd.proto +++ b/components/safe_browsing/csd.proto
@@ -161,7 +161,6 @@ // is safe for the purposes of entering user credentials for logging in. message LoginReputationClientRequest { // The top level frame URL of the webpage that hosts the login form. - // The client will strip CGI parameters. optional string page_url = 1; // Type for the request.
diff --git a/components/safe_browsing_db/util.h b/components/safe_browsing_db/util.h index dd03f5f..ff47d837 100644 --- a/components/safe_browsing_db/util.h +++ b/components/safe_browsing_db/util.h
@@ -24,7 +24,7 @@ namespace safe_browsing { // Metadata that indicates what kind of URL match this is. -enum class ThreatPatternType { +enum class ThreatPatternType : int { NONE = 0, // Pattern type didn't appear in the metadata MALWARE_LANDING = 1, // The match is a malware landing page MALWARE_DISTRIBUTION = 2, // The match is a malware distribution page
diff --git a/components/search_engines/default_search_manager.cc b/components/search_engines/default_search_manager.cc index a69aa74..ebe9a87 100644 --- a/components/search_engines/default_search_manager.cc +++ b/components/search_engines/default_search_manager.cc
@@ -53,6 +53,7 @@ const char DefaultSearchManager::kContextualSearchURL[] = "contextual_search_url"; const char DefaultSearchManager::kFaviconURL[] = "favicon_url"; +const char DefaultSearchManager::kLogoURL[] = "logo_url"; const char DefaultSearchManager::kOriginatingURL[] = "originating_url"; const char DefaultSearchManager::kSearchURLPostParams[] =
diff --git a/components/search_engines/default_search_manager.h b/components/search_engines/default_search_manager.h index 975c70e..7f0853a 100644 --- a/components/search_engines/default_search_manager.h +++ b/components/search_engines/default_search_manager.h
@@ -42,6 +42,7 @@ static const char kNewTabURL[]; static const char kContextualSearchURL[]; static const char kFaviconURL[]; + static const char kLogoURL[]; static const char kOriginatingURL[]; static const char kSearchURLPostParams[];
diff --git a/components/search_engines/prepopulated_engines.json b/components/search_engines/prepopulated_engines.json index 58f4ae0..da820086 100644 --- a/components/search_engines/prepopulated_engines.json +++ b/components/search_engines/prepopulated_engines.json
@@ -21,6 +21,8 @@ // - NOTIFY the Chrome Webstore team if you add/delete a search engine or // change domain of an existing one (send email to webstore-eng@google.com). // They need to know the mapping between an engine's "id" and its URLs. +// - Use HTTPS URLs when adding new search engines or adding URLs to existing +// ones. It's not the 90s anymore. { "int_variables": { @@ -111,7 +113,7 @@ "google": { "name": "Google", "keyword": "google.com", - "favicon_url": "http://www.google.com/favicon.ico", + "favicon_url": "https://www.google.com/favicon.ico", "search_url": "{google:baseURL}search?q={searchTerms}&{google:RLZ}{google:originalQueryForSuggestion}{google:assistedQueryStats}{google:searchFieldtrialParameter}{google:iOSSearchLanguage}{google:searchClient}{google:sourceId}{google:instantExtendedEnabledParameter}{google:contextualSearchVersion}ie={inputEncoding}", "suggest_url": "{google:baseSuggestURL}search?{google:searchFieldtrialParameter}client={google:suggestClient}&gs_ri={google:suggestRid}&xssi=t&q={searchTerms}&{google:inputType}{google:cursorPosition}{google:currentPageUrl}{google:pageClassification}{google:searchVersion}{google:sessionToken}{google:prefetchQuery}sugkey={google:suggestAPIKeyParameter}", "instant_url": "{google:baseURL}webhp?sourceid=chrome-instant&{google:RLZ}{google:forceInstantResults}{google:instantExtendedEnabledParameter}ie={inputEncoding}",
diff --git a/components/search_engines/prepopulated_engines_schema.json b/components/search_engines/prepopulated_engines_schema.json index ffe3810..b27caf2 100644 --- a/components/search_engines/prepopulated_engines_schema.json +++ b/components/search_engines/prepopulated_engines_schema.json
@@ -32,6 +32,7 @@ { "field": "new_tab_url", "type": "string", "optional": true }, // If omitted, this engine does not support contextual search. { "field": "contextual_search_url", "type": "string", "optional": true }, + { "field": "logo_url", "type": "string", "optional": true }, // The followings are post parameters for the corresponding search URL. // If omitted, a GET request will be sent when using the corresponding // search URL. Otherwise, a POST request will be sent.
diff --git a/components/search_engines/template_url.h b/components/search_engines/template_url.h index 169997d..7fd245b1 100644 --- a/components/search_engines/template_url.h +++ b/components/search_engines/template_url.h
@@ -568,6 +568,8 @@ } const GURL& favicon_url() const { return data_.favicon_url; } + const GURL& logo_url() const { return data_.logo_url; } + const GURL& originating_url() const { return data_.originating_url; } bool safe_for_autoreplace() const { return data_.safe_for_autoreplace; }
diff --git a/components/search_engines/template_url_data.cc b/components/search_engines/template_url_data.cc index 549d63e..84adb1aa 100644 --- a/components/search_engines/template_url_data.cc +++ b/components/search_engines/template_url_data.cc
@@ -34,6 +34,7 @@ base::StringPiece image_url, base::StringPiece new_tab_url, base::StringPiece contextual_search_url, + base::StringPiece logo_url, base::StringPiece search_url_post_params, base::StringPiece suggest_url_post_params, base::StringPiece instant_url_post_params, @@ -48,6 +49,7 @@ image_url(image_url.as_string()), new_tab_url(new_tab_url.as_string()), contextual_search_url(contextual_search_url.as_string()), + logo_url(GURL(logo_url)), search_url_post_params(search_url_post_params.as_string()), suggestions_url_post_params(suggest_url_post_params.as_string()), instant_url_post_params(instant_url_post_params.as_string()),
diff --git a/components/search_engines/template_url_data.h b/components/search_engines/template_url_data.h index 93088a8d..6ad8be2 100644 --- a/components/search_engines/template_url_data.h +++ b/components/search_engines/template_url_data.h
@@ -37,6 +37,7 @@ base::StringPiece image_url, base::StringPiece new_tab_url, base::StringPiece contextual_search_url, + base::StringPiece logo_url, base::StringPiece search_url_post_params, base::StringPiece suggest_url_post_params, base::StringPiece instant_url_post_params, @@ -71,6 +72,9 @@ std::string new_tab_url; std::string contextual_search_url; + // Optional URL for the logo. + GURL logo_url; + // The following post_params are comma-separated lists used to specify the // post parameters for the corresponding URL. std::string search_url_post_params; @@ -78,7 +82,7 @@ std::string instant_url_post_params; std::string image_url_post_params; - // Optional favicon for the TemplateURL. + // Favicon for the TemplateURL. GURL favicon_url; // URL to the OSD file this came from. May be empty.
diff --git a/components/search_engines/template_url_data_util.cc b/components/search_engines/template_url_data_util.cc index fd3138b..8712307 100644 --- a/components/search_engines/template_url_data_util.cc +++ b/components/search_engines/template_url_data_util.cc
@@ -49,10 +49,13 @@ &result->contextual_search_url); std::string favicon_url; std::string originating_url; + std::string logo_url; dict.GetString(DefaultSearchManager::kFaviconURL, &favicon_url); dict.GetString(DefaultSearchManager::kOriginatingURL, &originating_url); + dict.GetString(DefaultSearchManager::kLogoURL, &logo_url); result->favicon_url = GURL(favicon_url); result->originating_url = GURL(originating_url); + result->logo_url = GURL(logo_url); dict.GetString(DefaultSearchManager::kSearchURLPostParams, &result->search_url_post_params); @@ -133,6 +136,7 @@ data.favicon_url.spec()); url_dict->SetString(DefaultSearchManager::kOriginatingURL, data.originating_url.spec()); + url_dict->SetString(DefaultSearchManager::kLogoURL, data.logo_url.spec()); url_dict->SetString(DefaultSearchManager::kSearchURLPostParams, data.search_url_post_params); @@ -187,10 +191,10 @@ base::WideToUTF16(engine.name), base::WideToUTF16(engine.keyword), engine.search_url, engine.suggest_url, engine.instant_url, engine.image_url, engine.new_tab_url, engine.contextual_search_url, - engine.search_url_post_params, engine.suggest_url_post_params, - engine.instant_url_post_params, engine.image_url_post_params, - engine.favicon_url, engine.encoding, alternate_urls, - engine.search_terms_replacement_key, engine.id); + engine.logo_url, engine.search_url_post_params, + engine.suggest_url_post_params, engine.instant_url_post_params, + engine.image_url_post_params, engine.favicon_url, engine.encoding, + alternate_urls, engine.search_terms_replacement_key, engine.id); } std::unique_ptr<TemplateURLData> TemplateURLDataFromOverrideDictionary( @@ -214,6 +218,7 @@ std::string image_url; std::string new_tab_url; std::string contextual_search_url; + std::string logo_url; std::string search_url_post_params; std::string suggest_url_post_params; std::string instant_url_post_params; @@ -226,6 +231,7 @@ engine.GetString("image_url", &image_url); engine.GetString("new_tab_url", &new_tab_url); engine.GetString("contextual_search_url", &contextual_search_url); + engine.GetString("logo_url", &logo_url); engine.GetString("search_url_post_params", &search_url_post_params); engine.GetString("suggest_url_post_params", &suggest_url_post_params); engine.GetString("instant_url_post_params", &instant_url_post_params); @@ -235,7 +241,7 @@ &search_terms_replacement_key); return base::MakeUnique<TemplateURLData>( name, keyword, search_url, suggest_url, instant_url, image_url, - new_tab_url, contextual_search_url, search_url_post_params, + new_tab_url, contextual_search_url, logo_url, search_url_post_params, suggest_url_post_params, instant_url_post_params, image_url_post_params, favicon_url, encoding, *alternate_urls, search_terms_replacement_key, id);
diff --git a/components/search_engines/template_url_prepopulate_data_unittest.cc b/components/search_engines/template_url_prepopulate_data_unittest.cc index 75517f2..3b0a86d 100644 --- a/components/search_engines/template_url_prepopulate_data_unittest.cc +++ b/components/search_engines/template_url_prepopulate_data_unittest.cc
@@ -22,6 +22,7 @@ #include "components/search_engines/template_url.h" #include "components/search_engines/template_url_data_util.h" #include "components/search_engines/template_url_service.h" +#include "components/search_engines/testing_search_terms_data.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "testing/gtest/include/gtest/gtest.h" @@ -369,3 +370,58 @@ TemplateURL(*data).GetEngineType(SearchTermsData())); } } + +namespace { + +void CheckTemplateUrlRefIsCryptographic(const TemplateURLRef& url_ref) { + TestingSearchTermsData search_terms_data("https://www.google.com/"); + if (!url_ref.IsValid(search_terms_data)) { + ADD_FAILURE() << url_ref.GetURL(); + return; + } + + // Double parentheses around the string16 constructor to prevent the compiler + // from parsing it as a function declaration. + TemplateURLRef::SearchTermsArgs search_term_args((base::string16())); + GURL url(url_ref.ReplaceSearchTerms(search_term_args, search_terms_data)); + EXPECT_TRUE(url.is_empty() || url.SchemeIsCryptographic()) << url; +} + +} // namespace + +TEST_F(TemplateURLPrepopulateDataTest, HttpsUrls) { + // Preexisting search engines that don't use HTTPS URLs. + // Don't add new entries to this list! + std::set<int> exceptions{ + 4, 6, 16, 17, 21, 27, 35, 36, 43, 44, 45, 50, 54, 55, 56, 60, 61, + 62, 63, 64, 65, 66, 68, 70, 74, 75, 76, 77, 78, 79, 80, 81, 85, 90, + }; + using PrepopulatedEngine = TemplateURLPrepopulateData::PrepopulatedEngine; + const std::vector<const PrepopulatedEngine*> all_engines = + TemplateURLPrepopulateData::GetAllPrepopulatedEngines(); + for (const PrepopulatedEngine* engine : all_engines) { + std::unique_ptr<TemplateURLData> data = + TemplateURLDataFromPrepopulatedEngine(*engine); + if (base::ContainsValue(exceptions, data->prepopulate_id)) + continue; + + GURL logo_url = data->logo_url; + EXPECT_TRUE(logo_url.is_empty() || logo_url.SchemeIsCryptographic()) + << logo_url; + GURL favicon_url = data->favicon_url; + EXPECT_TRUE(favicon_url.is_empty() || favicon_url.SchemeIsCryptographic()) + << favicon_url; + + TemplateURL template_url(*data); + + // Intentionally don't check alternate URLs, because those are only used + // for matching. + CheckTemplateUrlRefIsCryptographic(template_url.url_ref()); + CheckTemplateUrlRefIsCryptographic(template_url.suggestions_url_ref()); + CheckTemplateUrlRefIsCryptographic(template_url.instant_url_ref()); + CheckTemplateUrlRefIsCryptographic(template_url.image_url_ref()); + CheckTemplateUrlRefIsCryptographic(template_url.new_tab_url_ref()); + CheckTemplateUrlRefIsCryptographic( + template_url.contextual_search_url_ref()); + } +}
diff --git a/components/search_provider_logos/BUILD.gn b/components/search_provider_logos/BUILD.gn index 8b3c839..da7b796 100644 --- a/components/search_provider_logos/BUILD.gn +++ b/components/search_provider_logos/BUILD.gn
@@ -4,6 +4,8 @@ static_library("search_provider_logos") { sources = [ + "fixed_logo_api.cc", + "fixed_logo_api.h", "google_logo_api.cc", "google_logo_api.h", "logo_cache.cc",
diff --git a/components/search_provider_logos/OWNERS b/components/search_provider_logos/OWNERS index 7bd15d5..db0aa59 100644 --- a/components/search_provider_logos/OWNERS +++ b/components/search_provider_logos/OWNERS
@@ -1 +1,3 @@ -justincohen@chromium.org \ No newline at end of file +bauerb@chromium.org +justincohen@chromium.org +treib@chromium.org
diff --git a/components/search_provider_logos/fixed_logo_api.cc b/components/search_provider_logos/fixed_logo_api.cc new file mode 100644 index 0000000..f9a5f5e --- /dev/null +++ b/components/search_provider_logos/fixed_logo_api.cc
@@ -0,0 +1,35 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/search_provider_logos/fixed_logo_api.h" + +#include "base/memory/ptr_util.h" +#include "base/memory/ref_counted_memory.h" +#include "components/search_provider_logos/logo_common.h" +#include "url/gurl.h" + +namespace search_provider_logos { + +std::unique_ptr<EncodedLogo> ParseFixedLogoResponse( + std::unique_ptr<std::string> response, + base::Time response_time, + bool* parsing_failed) { + auto logo = base::MakeUnique<EncodedLogo>(); + logo->encoded_image = base::RefCountedString::TakeString(response.get()); + + // If |can_show_after_expiration| is true, the |expiration_time| has little + // effect. Set it as far as possible in the future just as an approximation. + logo->metadata.expiration_time = + response_time + base::TimeDelta::FromMilliseconds(kMaxTimeToLiveMS); + logo->metadata.can_show_after_expiration = true; + + *parsing_failed = false; + return logo; +} + +GURL UseFixedLogoUrl(const GURL& logo_url, const std::string& fingerprint) { + return logo_url; +} + +} // namespace search_provider_logos
diff --git a/components/search_provider_logos/fixed_logo_api.h b/components/search_provider_logos/fixed_logo_api.h new file mode 100644 index 0000000..7801357 --- /dev/null +++ b/components/search_provider_logos/fixed_logo_api.h
@@ -0,0 +1,31 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SEARCH_PROVIDER_LOGOS_FIXED_LOGO_API_H_ +#define COMPONENTS_SEARCH_PROVIDER_LOGOS_FIXED_LOGO_API_H_ + +#include <memory> +#include <string> + +#include "base/time/time.h" + +class GURL; + +namespace search_provider_logos { + +struct EncodedLogo; + +// Implements AppendFingerprintToLogoURL, defined in logo_tracker.h, +// for static logos. +GURL UseFixedLogoUrl(const GURL& logo_url, const std::string& fingerprint); + +// Implements ParseLogoResponse, defined in logo_tracker.h, for static logos. +std::unique_ptr<EncodedLogo> ParseFixedLogoResponse( + std::unique_ptr<std::string> response, + base::Time response_time, + bool* parsing_failed); + +} // namespace search_provider_logos + +#endif // COMPONENTS_SEARCH_PROVIDER_LOGOS_FIXED_LOGO_API_H_
diff --git a/components/search_provider_logos/google_logo_api.cc b/components/search_provider_logos/google_logo_api.cc index f0ab64f..91d8218d 100644 --- a/components/search_provider_logos/google_logo_api.cc +++ b/components/search_provider_logos/google_logo_api.cc
@@ -21,48 +21,42 @@ const char kResponsePreamble[] = ")]}'"; } -GURL GoogleAppendQueryparamsToLogoURL(const GURL& logo_url, - const std::string& fingerprint, - bool wants_cta, - bool gray_background) { +GURL GoogleAppendQueryparamsToLogoURL(bool gray_background, + const GURL& logo_url, + const std::string& fingerprint) { // Note: we can't just use net::AppendQueryParameter() because it escapes // ":" to "%3A", but the server requires the colon not to be escaped. // See: http://crbug.com/413845 // TODO(newt): Switch to using net::AppendQueryParameter once it no longer // escapes ":" - if (!fingerprint.empty() || wants_cta) { - std::string query(logo_url.query()); - if (!query.empty()) - query += "&"; + std::string query(logo_url.query()); + if (!query.empty()) + query += "&"; - query += "async="; - std::vector<base::StringPiece> params; - std::string fingerprint_param; - if (!fingerprint.empty()) { - fingerprint_param = "es_dfp:" + fingerprint; - params.push_back(fingerprint_param); - } - - if (wants_cta) - params.push_back("cta:1"); - - if (gray_background) { - params.push_back("transp:1"); - params.push_back("graybg:1"); - } - - query += base::JoinString(params, ","); - GURL::Replacements replacements; - replacements.SetQueryStr(query); - return logo_url.ReplaceComponents(replacements); + query += "async="; + std::vector<base::StringPiece> params; + std::string fingerprint_param; + if (!fingerprint.empty()) { + fingerprint_param = "es_dfp:" + fingerprint; + params.push_back(fingerprint_param); } - return logo_url; + params.push_back("cta:1"); + + if (gray_background) { + params.push_back("transp:1"); + params.push_back("graybg:1"); + } + + query += base::JoinString(params, ","); + GURL::Replacements replacements; + replacements.SetQueryStr(query); + return logo_url.ReplaceComponents(replacements); } std::unique_ptr<EncodedLogo> GoogleParseLogoResponse( - const std::unique_ptr<std::string>& response, + std::unique_ptr<std::string> response, base::Time response_time, bool* parsing_failed) { // Google doodles are sent as JSON with a prefix. Example:
diff --git a/components/search_provider_logos/google_logo_api.h b/components/search_provider_logos/google_logo_api.h index d1d85b9..d5f85c71 100644 --- a/components/search_provider_logos/google_logo_api.h +++ b/components/search_provider_logos/google_logo_api.h
@@ -16,14 +16,13 @@ // Implements AppendFingerprintToLogoURL, defined in logo_tracker.h, for Google // doodles. -GURL GoogleAppendQueryparamsToLogoURL(const GURL& logo_url, - const std::string& fingerprint, - bool wants_cta, - bool gray_background); +GURL GoogleAppendQueryparamsToLogoURL(bool gray_background, + const GURL& logo_url, + const std::string& fingerprint); // Implements ParseLogoResponse, defined in logo_tracker.h, for Google doodles. std::unique_ptr<EncodedLogo> GoogleParseLogoResponse( - const std::unique_ptr<std::string>& response, + std::unique_ptr<std::string> response, base::Time response_time, bool* parsing_failed);
diff --git a/components/search_provider_logos/logo_tracker.cc b/components/search_provider_logos/logo_tracker.cc index a2fc7f9..d4d0bcf 100644 --- a/components/search_provider_logos/logo_tracker.cc +++ b/components/search_provider_logos/logo_tracker.cc
@@ -94,9 +94,7 @@ void LogoTracker::SetServerAPI( const GURL& logo_url, const ParseLogoResponse& parse_logo_response_func, - const AppendQueryparamsToLogoURL& append_queryparams_func, - bool wants_cta, - bool gray_background) { + const AppendQueryparamsToLogoURL& append_queryparams_func) { if (logo_url == logo_url_) return; @@ -105,8 +103,6 @@ logo_url_ = logo_url; parse_logo_response_func_ = parse_logo_response_func; append_queryparams_func_ = append_queryparams_func; - wants_cta_ = wants_cta; - gray_background_ = gray_background; } void LogoTracker::GetLogo(LogoObserver* observer) { @@ -223,8 +219,7 @@ if (command_line->HasSwitch(switches::kGoogleDoodleUrl)) { url = GURL(command_line->GetSwitchValueASCII(switches::kGoogleDoodleUrl)); } else { - url = append_queryparams_func_.Run(logo_url_, fingerprint, wants_cta_, - gray_background_); + url = append_queryparams_func_.Run(logo_url_, fingerprint); } net::NetworkTrafficAnnotationTag traffic_annotation =
diff --git a/components/search_provider_logos/logo_tracker.h b/components/search_provider_logos/logo_tracker.h index 402b640..af8a10b 100644 --- a/components/search_provider_logos/logo_tracker.h +++ b/components/search_provider_logos/logo_tracker.h
@@ -68,20 +68,16 @@ }; // Parses the response from the server and returns it as an EncodedLogo. Returns -// NULL if the response is invalid. -typedef base::Callback<std::unique_ptr<EncodedLogo>( - const std::unique_ptr<std::string>& response, +// null if the response is invalid. +using ParseLogoResponse = base::Callback<std::unique_ptr<EncodedLogo>( + std::unique_ptr<std::string> response, base::Time response_time, - bool* parsing_failed)> - ParseLogoResponse; + bool* parsing_failed)>; // Encodes the fingerprint of the cached logo in the logo URL. This enables the // server to verify whether the cached logo is up to date. -typedef base::Callback<GURL(const GURL& logo_url, - const std::string& fingerprint, - bool wants_cta, - bool gray_background)> - AppendQueryparamsToLogoURL; +using AppendQueryparamsToLogoURL = + base::Callback<GURL(const GURL& logo_url, const std::string& fingerprint)>; // This class provides the logo for a search provider. Logos are downloaded from // the search provider's logo URL and cached on disk. @@ -124,17 +120,9 @@ // |parse_logo_response_func| is a callback that will be used to parse the // server's response into a EncodedLogo object. |append_queryparams_func| is a // callback that will return the URL from which to download the logo. - // |wants_cta| determines if the url should return a call to action image. - // |gray_background| determines whether to request a logo with a gray - // background. The gray will match the NTP background color. - // Note: |parse_logo_response_func| and |append_queryparams_func| must be - // suitable for running multiple times, concurrently, and on multiple threads. - // TODO(ianwen): remove wants_cta from parameter. void SetServerAPI(const GURL& logo_url, const ParseLogoResponse& parse_logo_response_func, - const AppendQueryparamsToLogoURL& append_queryparams_func, - bool wants_cta, - bool gray_background); + const AppendQueryparamsToLogoURL& append_queryparams_func); // Retrieves the current search provider's logo from the local cache and/or // over the network, and registers |observer| to be called when the cached @@ -221,12 +209,6 @@ // action request in the logo URL. AppendQueryparamsToLogoURL append_queryparams_func_; - // If |true| request call to action in server API. - bool wants_cta_; - - // If |true| request a doodle with a gray background. - bool gray_background_; - // False if an asynchronous task is currently running. bool is_idle_;
diff --git a/components/search_provider_logos/logo_tracker_unittest.cc b/components/search_provider_logos/logo_tracker_unittest.cc index 926f485f..acd3c7b 100644 --- a/components/search_provider_logos/logo_tracker_unittest.cc +++ b/components/search_provider_logos/logo_tracker_unittest.cc
@@ -326,10 +326,9 @@ new net::TestURLRequestContextGetter( base::ThreadTaskRunnerHandle::Get()), std::unique_ptr<LogoDelegate>(new TestLogoDelegate())); - logo_tracker_->SetServerAPI(logo_url_, base::Bind(&GoogleParseLogoResponse), - base::Bind(&GoogleAppendQueryparamsToLogoURL), - false, - false); + logo_tracker_->SetServerAPI( + logo_url_, base::Bind(&GoogleParseLogoResponse), + base::Bind(&GoogleAppendQueryparamsToLogoURL, false)); logo_tracker_->SetClockForTests(std::unique_ptr<base::Clock>(test_clock_)); logo_tracker_->SetLogoCacheForTests( std::unique_ptr<LogoCache>(logo_cache_)); @@ -385,8 +384,8 @@ const std::string& response, net::URLRequestStatus::Status request_status, net::HttpStatusCode response_code) { - fake_url_fetcher_factory_.SetFakeResponse( - logo_url_, response, response_code, request_status); + SetServerResponseWhenFingerprint(std::string(), response, request_status, + response_code); } void LogoTrackerTest::SetServerResponseWhenFingerprint( @@ -395,7 +394,7 @@ net::URLRequestStatus::Status request_status, net::HttpStatusCode response_code) { GURL url_with_fp = - GoogleAppendQueryparamsToLogoURL(logo_url_, fingerprint, false, false); + GoogleAppendQueryparamsToLogoURL(false, logo_url_, fingerprint); fake_url_fetcher_factory_.SetFakeResponse( url_with_fp, response_when_fingerprint, response_code, request_status); } @@ -407,36 +406,26 @@ // Tests ----------------------------------------------------------------------- -TEST_F(LogoTrackerTest, FingerprintURLHasColon) { - GURL url_with_fp = GoogleAppendQueryparamsToLogoURL( - GURL("http://logourl.com/path"), "abc123", false, false); - EXPECT_EQ("http://logourl.com/path?async=es_dfp:abc123", url_with_fp.spec()); - - url_with_fp = GoogleAppendQueryparamsToLogoURL( - GURL("http://logourl.com/?a=b"), "cafe0", false, false); - EXPECT_EQ("http://logourl.com/?a=b&async=es_dfp:cafe0", url_with_fp.spec()); -} - TEST_F(LogoTrackerTest, CTAURLHasComma) { GURL url_with_fp = GoogleAppendQueryparamsToLogoURL( - GURL("http://logourl.com/path"), "abc123", true, false); + false, GURL("http://logourl.com/path"), "abc123"); EXPECT_EQ("http://logourl.com/path?async=es_dfp:abc123,cta:1", url_with_fp.spec()); url_with_fp = GoogleAppendQueryparamsToLogoURL( - GURL("http://logourl.com/?a=b"), "", true, false); + false, GURL("http://logourl.com/?a=b"), ""); EXPECT_EQ("http://logourl.com/?a=b&async=cta:1", url_with_fp.spec()); } TEST_F(LogoTrackerTest, CTAGrayBackgroundHasCommas) { GURL url_with_fp = GoogleAppendQueryparamsToLogoURL( - GURL("http://logourl.com/path"), "abc123", true, true); + true, GURL("http://logourl.com/path"), "abc123"); EXPECT_EQ( "http://logourl.com/path?async=es_dfp:abc123,cta:1,transp:1,graybg:1", url_with_fp.spec()); url_with_fp = GoogleAppendQueryparamsToLogoURL( - GURL("http://logourl.com/?a=b"), "", true, true); + true, GURL("http://logourl.com/?a=b"), ""); EXPECT_EQ("http://logourl.com/?a=b&async=cta:1,transp:1,graybg:1", url_with_fp.spec()); } @@ -744,10 +733,9 @@ logo_tracker_->GetLogo(&listener1); logo_url_ = GURL("http://example.com/new-logo-url"); - logo_tracker_->SetServerAPI(logo_url_, base::Bind(&GoogleParseLogoResponse), - base::Bind(&GoogleAppendQueryparamsToLogoURL), - false, - false); + logo_tracker_->SetServerAPI( + logo_url_, base::Bind(&GoogleParseLogoResponse), + base::Bind(&GoogleAppendQueryparamsToLogoURL, false)); Logo logo = GetSampleLogo(logo_url_, test_clock_->Now()); SetServerResponse(ServerResponse(logo));
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc index 8e62225..6517e58 100644 --- a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc +++ b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc
@@ -212,6 +212,8 @@ } } +// Blocking popups here should trigger the standard popup blocking UI, so don't +// force the subresource filter specific UI. bool ContentSubresourceFilterThrottleManager::ShouldDisallowNewWindow( const content::OpenURLParams* open_url_params) { auto it = activated_frame_hosts_.find(web_contents()->GetMainFrame()); @@ -225,17 +227,14 @@ return false; } - // It is very tricky to filter out popups from OpenURLFromTab. For right now, - // just allow all of them. |open_url_params| will be nullptr if it is coming - // from window.open, which should remain blocked. - // - // TODO(csharrison): Add additional parameters to OpenURLParams like a trusted - // bit to determined if the event that led to this was issued via JS. - if (open_url_params) - return false; - - // This should trigger the standard popup blocking UI, so don't force the - // subresource filter specific UI here. + // Block new windows from navigations whose triggering JS Event has an + // isTrusted bit set to false. This bit is set to true if the event is + // generated via a user action. See docs: + // https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted + if (open_url_params) { + return open_url_params->triggering_event_info == + blink::WebTriggeringEventInfo::kFromUntrustedEvent; + } return true; }
diff --git a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.cc b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.cc index d5bc6a7c..fd97742f 100644 --- a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.cc +++ b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.cc
@@ -11,12 +11,25 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/single_thread_task_runner.h" +#include "base/trace_event/trace_event.h" +#include "base/trace_event/trace_event_argument.h" #include "components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.h" #include "components/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.h" #include "content/public/browser/browser_thread.h" namespace subresource_filter { +std::unique_ptr<base::trace_event::TracedValue> +SubresourceFilterSafeBrowsingClient::CheckResult::ToTracedValue() const { + auto value = base::MakeUnique<base::trace_event::TracedValue>(); + value->SetInteger("request_id", request_id); + value->SetInteger("threat_type", threat_type); + value->SetInteger("pattern_type", static_cast<int>(pattern_type)); + value->SetInteger("check_time (us)", check_time.InMicroseconds()); + value->SetBoolean("finished", finished); + return value; +} + SubresourceFilterSafeBrowsingClient::SubresourceFilterSafeBrowsingClient( scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager, base::WeakPtr<SubresourceFilterSafeBrowsingActivationThrottle> throttle, @@ -39,6 +52,10 @@ auto* raw_request = request.get(); DCHECK(requests_.find(raw_request) == requests_.end()); requests_[raw_request] = std::move(request); + TRACE_EVENT_ASYNC_BEGIN1(TRACE_DISABLED_BY_DEFAULT("loading"), + "SubresourceFilterSBCheck", raw_request, + "check_result", + base::MakeUnique<base::trace_event::TracedValue>()); raw_request->Start(); // Careful, |raw_request| can be destroyed after this line. } @@ -47,6 +64,9 @@ SubresourceFilterSafeBrowsingClientRequest* request, const CheckResult& check_result) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + TRACE_EVENT_ASYNC_END1(TRACE_DISABLED_BY_DEFAULT("loading"), + "SubresourceFilterSBCheck", request, "check_result", + check_result.ToTracedValue()); throttle_task_runner_->PostTask( FROM_HERE, base::Bind(&SubresourceFilterSafeBrowsingActivationThrottle:: OnCheckUrlResultOnUI,
diff --git a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.h b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.h index 41eae188..5b06b85 100644 --- a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.h +++ b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.h
@@ -20,6 +20,9 @@ namespace base { class SingleThreadTaskRunner; +namespace trace_event { +class TracedValue; +} // namespace trace_event } // namespace base namespace safe_browsing { @@ -46,6 +49,8 @@ safe_browsing::ThreatPatternType::NONE; base::TimeDelta check_time; bool finished = false; + + std::unique_ptr<base::trace_event::TracedValue> ToTracedValue() const; }; SubresourceFilterSafeBrowsingClient(
diff --git a/content/browser/device_sensors/device_sensor_browsertest.cc b/content/browser/device_sensors/device_sensor_browsertest.cc index 971fc6c6..ef16d38 100644 --- a/content/browser/device_sensors/device_sensor_browsertest.cc +++ b/content/browser/device_sensors/device_sensor_browsertest.cc
@@ -17,8 +17,6 @@ #include "content/public/test/test_utils.h" #include "content/shell/browser/shell.h" #include "content/shell/browser/shell_javascript_dialog_manager.h" -#include "device/generic_sensor/platform_sensor.h" -#include "device/generic_sensor/platform_sensor_provider.h" #include "device/sensors/data_fetcher_shared_memory.h" #include "device/sensors/device_sensor_service.h" #include "device/sensors/public/cpp/device_motion_hardware_buffer.h" @@ -33,6 +31,14 @@ FakeDataFetcher() : sensor_data_available_(true) {} ~FakeDataFetcher() override {} + void SetMotionStartedCallback(base::Closure motion_started_callback) { + motion_started_callback_ = motion_started_callback; + } + + void SetMotionStoppedCallback(base::Closure motion_stopped_callback) { + motion_stopped_callback_ = motion_stopped_callback; + } + void SetOrientationStartedCallback( base::Closure orientation_started_callback) { orientation_started_callback_ = orientation_started_callback; @@ -59,6 +65,15 @@ EXPECT_TRUE(buffer); switch (consumer_type) { + case device::CONSUMER_TYPE_MOTION: { + device::DeviceMotionHardwareBuffer* motion_buffer = + static_cast<device::DeviceMotionHardwareBuffer*>(buffer); + if (sensor_data_available_) + UpdateMotion(motion_buffer); + SetMotionBufferReady(motion_buffer); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + motion_started_callback_); + } break; case device::CONSUMER_TYPE_ORIENTATION: { device::DeviceOrientationHardwareBuffer* orientation_buffer = static_cast<device::DeviceOrientationHardwareBuffer*>(buffer); @@ -85,6 +100,10 @@ bool Stop(device::ConsumerType consumer_type) override { switch (consumer_type) { + case device::CONSUMER_TYPE_MOTION: + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + motion_stopped_callback_); + break; case device::CONSUMER_TYPE_ORIENTATION: BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, orientation_stopped_callback_); @@ -109,6 +128,12 @@ sensor_data_available_ = available; } + void SetMotionBufferReady(device::DeviceMotionHardwareBuffer* buffer) { + buffer->seqlock.WriteBegin(); + buffer->data.all_available_sensors_are_active = true; + buffer->seqlock.WriteEnd(); + } + void SetOrientationBufferReady( device::DeviceOrientationHardwareBuffer* buffer) { buffer->seqlock.WriteBegin(); @@ -116,6 +141,34 @@ buffer->seqlock.WriteEnd(); } + void UpdateMotion(device::DeviceMotionHardwareBuffer* buffer) { + buffer->seqlock.WriteBegin(); + buffer->data.acceleration_x = 1; + buffer->data.has_acceleration_x = true; + buffer->data.acceleration_y = 2; + buffer->data.has_acceleration_y = true; + buffer->data.acceleration_z = 3; + buffer->data.has_acceleration_z = true; + + buffer->data.acceleration_including_gravity_x = 4; + buffer->data.has_acceleration_including_gravity_x = true; + buffer->data.acceleration_including_gravity_y = 5; + buffer->data.has_acceleration_including_gravity_y = true; + buffer->data.acceleration_including_gravity_z = 6; + buffer->data.has_acceleration_including_gravity_z = true; + + buffer->data.rotation_rate_alpha = 7; + buffer->data.has_rotation_rate_alpha = true; + buffer->data.rotation_rate_beta = 8; + buffer->data.has_rotation_rate_beta = true; + buffer->data.rotation_rate_gamma = 9; + buffer->data.has_rotation_rate_gamma = true; + + buffer->data.interval = 100; + buffer->data.all_available_sensors_are_active = true; + buffer->seqlock.WriteEnd(); + } + void UpdateOrientation(device::DeviceOrientationHardwareBuffer* buffer) { buffer->seqlock.WriteBegin(); buffer->data.alpha = 1; @@ -143,8 +196,10 @@ } // The below callbacks should be run on the UI thread. + base::Closure motion_started_callback_; base::Closure orientation_started_callback_; base::Closure orientation_absolute_started_callback_; + base::Closure motion_stopped_callback_; base::Closure orientation_stopped_callback_; base::Closure orientation_absolute_stopped_callback_; bool sensor_data_available_; @@ -153,187 +208,6 @@ DISALLOW_COPY_AND_ASSIGN(FakeDataFetcher); }; -class FakeAccelerometer : public device::PlatformSensor { - public: - FakeAccelerometer(mojo::ScopedSharedBufferMapping mapping, - device::PlatformSensorProvider* provider) - : PlatformSensor(device::mojom::SensorType::ACCELEROMETER, - std::move(mapping), - provider) {} - - device::mojom::ReportingMode GetReportingMode() override { - return device::mojom::ReportingMode::ON_CHANGE; - } - - bool StartSensor( - const device::PlatformSensorConfiguration& configuration) override { - device::SensorReading reading; - reading.timestamp = - (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); - reading.values[0] = 4; - reading.values[1] = 5; - reading.values[2] = 6; - UpdateSensorReading(reading, true); - return true; - } - - void StopSensor() override {} - - protected: - ~FakeAccelerometer() override = default; - - bool CheckSensorConfiguration( - const device::PlatformSensorConfiguration& configuration) override { - return true; - } - - device::PlatformSensorConfiguration GetDefaultConfiguration() override { - return device::PlatformSensorConfiguration(60 /* frequency */); - } - - private: - DISALLOW_COPY_AND_ASSIGN(FakeAccelerometer); -}; - -class FakeLinearAccelerationSensor : public device::PlatformSensor { - public: - FakeLinearAccelerationSensor(mojo::ScopedSharedBufferMapping mapping, - device::PlatformSensorProvider* provider) - : PlatformSensor(device::mojom::SensorType::LINEAR_ACCELERATION, - std::move(mapping), - provider) {} - - device::mojom::ReportingMode GetReportingMode() override { - return device::mojom::ReportingMode::CONTINUOUS; - } - - bool StartSensor( - const device::PlatformSensorConfiguration& configuration) override { - device::SensorReading reading; - reading.timestamp = - (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); - reading.values[0] = 1; - reading.values[1] = 2; - reading.values[2] = 3; - UpdateSensorReading(reading, true); - return true; - } - - void StopSensor() override {} - - protected: - ~FakeLinearAccelerationSensor() override = default; - - bool CheckSensorConfiguration( - const device::PlatformSensorConfiguration& configuration) override { - return true; - } - - device::PlatformSensorConfiguration GetDefaultConfiguration() override { - return device::PlatformSensorConfiguration(60 /* frequency */); - } - - private: - DISALLOW_COPY_AND_ASSIGN(FakeLinearAccelerationSensor); -}; - -class FakeGyroscope : public device::PlatformSensor { - public: - FakeGyroscope(mojo::ScopedSharedBufferMapping mapping, - device::PlatformSensorProvider* provider) - : PlatformSensor(device::mojom::SensorType::GYROSCOPE, - std::move(mapping), - provider) {} - - device::mojom::ReportingMode GetReportingMode() override { - return device::mojom::ReportingMode::ON_CHANGE; - } - - bool StartSensor( - const device::PlatformSensorConfiguration& configuration) override { - device::SensorReading reading; - reading.timestamp = - (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); - reading.values[0] = 7; - reading.values[1] = 8; - reading.values[2] = 9; - UpdateSensorReading(reading, true); - return true; - } - - void StopSensor() override {} - - protected: - ~FakeGyroscope() override = default; - - bool CheckSensorConfiguration( - const device::PlatformSensorConfiguration& configuration) override { - return true; - } - - device::PlatformSensorConfiguration GetDefaultConfiguration() override { - return device::PlatformSensorConfiguration(60 /* frequency */); - } - - private: - DISALLOW_COPY_AND_ASSIGN(FakeGyroscope); -}; - -class FakeSensorProvider : public device::PlatformSensorProvider { - public: - static FakeSensorProvider* GetInstance() { - return base::Singleton<FakeSensorProvider, base::LeakySingletonTraits< - FakeSensorProvider>>::get(); - } - FakeSensorProvider() {} - ~FakeSensorProvider() override = default; - - void set_accelerometer_is_available(bool accelerometer_is_available) { - accelerometer_is_available_ = accelerometer_is_available; - } - - void set_linear_acceleration_sensor_is_available( - bool linear_acceleration_sensor_is_available) { - linear_acceleration_sensor_is_available_ = - linear_acceleration_sensor_is_available; - } - - void set_gyroscope_is_available(bool gyroscope_is_available) { - gyroscope_is_available_ = gyroscope_is_available; - } - - protected: - void CreateSensorInternal(device::mojom::SensorType type, - mojo::ScopedSharedBufferMapping mapping, - const CreateSensorCallback& callback) override { - // Create Sensors here. - scoped_refptr<device::PlatformSensor> sensor; - - switch (type) { - case device::mojom::SensorType::ACCELEROMETER: - if (accelerometer_is_available_) - sensor = new FakeAccelerometer(std::move(mapping), this); - break; - case device::mojom::SensorType::LINEAR_ACCELERATION: - if (linear_acceleration_sensor_is_available_) - sensor = new FakeLinearAccelerationSensor(std::move(mapping), this); - break; - case device::mojom::SensorType::GYROSCOPE: - if (gyroscope_is_available_) - sensor = new FakeGyroscope(std::move(mapping), this); - break; - default: - NOTIMPLEMENTED(); - } - - callback.Run(std::move(sensor)); - } - - bool accelerometer_is_available_ = true; - bool linear_acceleration_sensor_is_available_ = true; - bool gyroscope_is_available_ = true; -}; - class DeviceSensorBrowserTest : public ContentBrowserTest { public: DeviceSensorBrowserTest() @@ -344,6 +218,8 @@ void SetUpOnMainThread() override { // Initialize the RunLoops now that the main thread has been created. + motion_started_runloop_.reset(new base::RunLoop()); + motion_stopped_runloop_.reset(new base::RunLoop()); orientation_started_runloop_.reset(new base::RunLoop()); orientation_stopped_runloop_.reset(new base::RunLoop()); orientation_absolute_started_runloop_.reset(new base::RunLoop()); @@ -351,16 +227,20 @@ #if defined(OS_ANDROID) // On Android, the DeviceSensorService lives on the UI thread. SetUpFetcher(); -#endif // defined(OS_ANDROID) +#else + // On all other platforms, the DeviceSensorService lives on the IO thread. BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, base::Bind(&DeviceSensorBrowserTest::SetUpOnIOThread, base::Unretained(this))); io_loop_finished_event_.Wait(); +#endif } void SetUpFetcher() { fetcher_ = new FakeDataFetcher(); + fetcher_->SetMotionStartedCallback(motion_started_runloop_->QuitClosure()); + fetcher_->SetMotionStoppedCallback(motion_stopped_runloop_->QuitClosure()); fetcher_->SetOrientationStartedCallback( orientation_started_runloop_->QuitClosure()); fetcher_->SetOrientationStoppedCallback( @@ -374,19 +254,10 @@ } void SetUpOnIOThread() { -#if !defined(OS_ANDROID) - // On non-Android platforms, the DeviceSensorService lives on the IO thread. SetUpFetcher(); -#endif // !defined(OS_ANDROID) - sensor_provider_ = FakeSensorProvider::GetInstance(); - device::PlatformSensorProvider::SetProviderForTesting(sensor_provider_); io_loop_finished_event_.Signal(); } - void TearDown() override { - device::PlatformSensorProvider::SetProviderForTesting(nullptr); - } - void DelayAndQuit(base::TimeDelta delay) { base::PlatformThread::Sleep(delay); base::MessageLoop::current()->QuitWhenIdle(); @@ -405,10 +276,11 @@ } FakeDataFetcher* fetcher_; - FakeSensorProvider* sensor_provider_; // NOTE: These can only be initialized once the main thread has been created // and so must be pointers instead of plain objects. + std::unique_ptr<base::RunLoop> motion_started_runloop_; + std::unique_ptr<base::RunLoop> motion_stopped_runloop_; std::unique_ptr<base::RunLoop> orientation_started_runloop_; std::unique_ptr<base::RunLoop> orientation_stopped_runloop_; std::unique_ptr<base::RunLoop> orientation_absolute_started_runloop_; @@ -451,6 +323,8 @@ NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2); EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref()); + motion_started_runloop_->Run(); + motion_stopped_runloop_->Run(); } IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, OrientationNullTest) { @@ -485,27 +359,13 @@ // The test page registers an event handler for motion events and // expects to get an event with null values, because no sensor data can be // provided. - sensor_provider_->set_accelerometer_is_available(false); - sensor_provider_->set_linear_acceleration_sensor_is_available(false); - sensor_provider_->set_gyroscope_is_available(false); + fetcher_->SetSensorDataAvailable(false); GURL test_url = GetTestUrl("device_sensors", "device_motion_null_test.html"); NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2); EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref()); -} - -IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, - MotionOnlySomeSensorsAreAvailableTest) { - // The test page registers an event handler for motion events and - // expects to get an event with only the gyroscope and linear acceleration - // sensor values, because no accelerometer values can be provided. - sensor_provider_->set_accelerometer_is_available(false); - GURL test_url = - GetTestUrl("device_sensors", - "device_motion_only_some_sensors_are_available_test.html"); - NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2); - - EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref()); + motion_started_runloop_->Run(); + motion_stopped_runloop_->Run(); } IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, NullTestWithAlert) { @@ -515,9 +375,6 @@ // window after the alert is dismissed and the callbacks are invoked which // eventually navigate to #pass. fetcher_->SetSensorDataAvailable(false); - sensor_provider_->set_accelerometer_is_available(false); - sensor_provider_->set_linear_acceleration_sensor_is_available(false); - sensor_provider_->set_gyroscope_is_available(false); TestNavigationObserver same_tab_observer(shell()->web_contents(), 2); GURL test_url = @@ -528,6 +385,8 @@ // delay, crbug.com/360044. WaitForAlertDialogAndQuitAfterDelay(base::TimeDelta::FromMilliseconds(500)); + motion_started_runloop_->Run(); + motion_stopped_runloop_->Run(); orientation_started_runloop_->Run(); orientation_stopped_runloop_->Run(); same_tab_observer.Wait();
diff --git a/content/browser/net/quota_policy_cookie_store.cc b/content/browser/net/quota_policy_cookie_store.cc index 22637fe..1fcb926 100644 --- a/content/browser/net/quota_policy_cookie_store.cc +++ b/content/browser/net/quota_policy_cookie_store.cc
@@ -93,8 +93,8 @@ special_storage_policy_ = nullptr; } -void QuotaPolicyCookieStore::Flush(const base::Closure& callback) { - persistent_store_->Flush(callback); +void QuotaPolicyCookieStore::Flush(base::OnceClosure callback) { + persistent_store_->Flush(std::move(callback)); } void QuotaPolicyCookieStore::OnLoad(
diff --git a/content/browser/net/quota_policy_cookie_store.h b/content/browser/net/quota_policy_cookie_store.h index 8ea03ef..8eeb3f1 100644 --- a/content/browser/net/quota_policy_cookie_store.h +++ b/content/browser/net/quota_policy_cookie_store.h
@@ -49,7 +49,7 @@ void UpdateCookieAccessTime(const net::CanonicalCookie& cc) override; void DeleteCookie(const net::CanonicalCookie& cc) override; void SetForceKeepSessionState() override; - void Flush(const base::Closure& callback) override; + void Flush(base::OnceClosure callback) override; private: typedef std::map<net::SQLitePersistentCookieStore::CookieOrigin, size_t>
diff --git a/content/browser/service_manager/service_manager_context.cc b/content/browser/service_manager/service_manager_context.cc index 820d78b..94bade54 100644 --- a/content/browser/service_manager/service_manager_context.cc +++ b/content/browser/service_manager/service_manager_context.cc
@@ -51,6 +51,7 @@ #include "services/service_manager/public/cpp/service.h" #include "services/service_manager/public/interfaces/service.mojom.h" #include "services/service_manager/runner/common/client_util.h" +#include "services/service_manager/runner/host/service_process_launcher.h" #include "services/service_manager/service_manager.h" #include "services/shape_detection/public/interfaces/constants.mojom.h" #include "services/video_capture/public/cpp/constants.h"
diff --git a/content/browser/webrtc/webrtc_image_capture_browsertest.cc b/content/browser/webrtc/webrtc_image_capture_browsertest.cc index 3248de6..22b925a 100644 --- a/content/browser/webrtc/webrtc_image_capture_browsertest.cc +++ b/content/browser/webrtc/webrtc_image_capture_browsertest.cc
@@ -112,6 +112,8 @@ return true; } + LookupAndLogNameAndIdOfFirstCamera(); + std::string result; if (!ExecuteScriptAndExtractString(shell(), command, &result)) return false;
diff --git a/content/public/test/content_browser_test_utils.cc b/content/public/test/content_browser_test_utils.cc index a2a13eb..2c8f63f 100644 --- a/content/public/test/content_browser_test_utils.cc +++ b/content/public/test/content_browser_test_utils.cc
@@ -9,6 +9,9 @@ #include "base/path_service.h" #include "base/run_loop.h" #include "base/threading/thread_restrictions.h" +#include "content/browser/browser_main_loop.h" +#include "content/browser/renderer_host/media/media_stream_manager.h" +#include "content/browser/renderer_host/media/video_capture_manager.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/notification_source.h" #include "content/public/browser/web_contents.h" @@ -80,8 +83,7 @@ bool NavigateToURL(Shell* window, const GURL& url) { NavigateToURLBlockUntilNavigationsComplete(window, url, 1); - if (!IsLastCommittedEntryOfPageType(window->web_contents(), - PAGE_TYPE_NORMAL)) + if (!IsLastCommittedEntryOfPageType(window->web_contents(), PAGE_TYPE_NORMAL)) return false; return window->web_contents()->GetLastCommittedURL() == url; } @@ -109,14 +111,42 @@ return shell->web_contents()->GetMainFrame(); } -ShellAddedObserver::ShellAddedObserver() - : shell_(NULL) { +void LookupAndLogNameAndIdOfFirstCamera() { + DCHECK(BrowserMainLoop::GetInstance()); + MediaStreamManager* media_stream_manager = + BrowserMainLoop::GetInstance()->media_stream_manager(); + base::RunLoop run_loop; + BrowserThread::PostTask( + content::BrowserThread::IO, FROM_HERE, + base::Bind( + [](MediaStreamManager* media_stream_manager, + base::Closure quit_closure) { + media_stream_manager->video_capture_manager()->EnumerateDevices( + base::Bind( + [](base::Closure quit_closure, + const media::VideoCaptureDeviceDescriptors& + descriptors) { + if (descriptors.empty()) { + LOG(WARNING) << "No camera found"; + return; + } + LOG(INFO) + << "Using camera " << descriptors.front().display_name + << " (" << descriptors.front().model_id << ")"; + quit_closure.Run(); + }, + quit_closure)); + }, + media_stream_manager, run_loop.QuitClosure())); + run_loop.Run(); +} + +ShellAddedObserver::ShellAddedObserver() : shell_(NULL) { Shell::SetShellCreatedCallback( base::Bind(&ShellAddedObserver::ShellCreated, base::Unretained(this))); } -ShellAddedObserver::~ShellAddedObserver() { -} +ShellAddedObserver::~ShellAddedObserver() {} Shell* ShellAddedObserver::GetShell() { if (shell_)
diff --git a/content/public/test/content_browser_test_utils.h b/content/public/test/content_browser_test_utils.h index 2049d47..a3c20df5 100644 --- a/content/public/test/content_browser_test_utils.h +++ b/content/public/test/content_browser_test_utils.h
@@ -91,6 +91,12 @@ // Extends the ToRenderFrameHost mechanism to content::Shells. RenderFrameHost* ConvertToRenderFrameHost(Shell* shell); +// Writes an entry with the name and id of the first camera to the logs or +// an entry indicating that no camera is available. This must be invoked from +// the test method body, because at the time of invocation of +// testing::Test::SetUp() the BrowserMainLoop does not yet exist. +void LookupAndLogNameAndIdOfFirstCamera(); + // Used to wait for a new Shell window to be created. Instantiate this object // before the operation that will create the window. class ShellAddedObserver {
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index 3d5b36b53..7bf5386c 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -458,7 +458,6 @@ "//device/base/synchronization", "//device/gamepad/public/cpp:shared_with_blink", "//device/gamepad/public/interfaces", - "//device/generic_sensor/public/cpp", "//device/screen_orientation/public/interfaces", "//device/sensors/public/cpp:full", "//device/sensors/public/interfaces",
diff --git a/content/renderer/DEPS b/content/renderer/DEPS index 0c3962ab..54e6e7b 100644 --- a/content/renderer/DEPS +++ b/content/renderer/DEPS
@@ -18,8 +18,6 @@ "+device/base/synchronization", "+device/gamepad/public/cpp", "+device/gamepad/public/interfaces", - "+device/generic_sensor/public/cpp", - "+device/generic_sensor/public/interfaces", "+device/screen_orientation/public/interfaces", "+device/sensors/public", "+device/usb/public",
diff --git a/content/renderer/device_sensors/device_motion_event_pump.cc b/content/renderer/device_sensors/device_motion_event_pump.cc index 240ca24..94d7f3f 100644 --- a/content/renderer/device_sensors/device_motion_event_pump.cc +++ b/content/renderer/device_sensors/device_motion_event_pump.cc
@@ -2,328 +2,38 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/renderer/device_sensors/device_motion_event_pump.h" +#include "device_motion_event_pump.h" -#include "base/memory/ptr_util.h" -#include "content/public/common/service_names.mojom.h" #include "content/public/renderer/render_thread.h" -#include "mojo/public/cpp/bindings/interface_request.h" -#include "services/device/public/interfaces/constants.mojom.h" -#include "services/service_manager/public/cpp/connector.h" #include "third_party/WebKit/public/platform/modules/device_orientation/WebDeviceMotionListener.h" -namespace { - -constexpr int kMaxReadAttemptsCount = 10; - -// TODO(juncai): Extracting mojo::ScopedSharedBufferMapping reading -// functionality into a helper class. -// http://crbug.com/727788 -bool TryReadFromBuffer(const device::SensorReadingSharedBuffer* buffer, - device::SensorReading* result) { - const device::OneWriterSeqLock& seqlock = buffer->seqlock.value(); - auto version = seqlock.ReadBegin(); - auto reading_data = buffer->reading; - if (seqlock.ReadRetry(version)) - return false; - *result = reading_data; - return true; -} - -// Updates sensor reading from shared buffer. -bool UpdateSensorReading(const device::SensorReadingSharedBuffer* buffer, - device::SensorReading* result) { - int read_attempts = 0; - while (!TryReadFromBuffer(buffer, result)) { - if (++read_attempts == kMaxReadAttemptsCount) - return false; - } - - return true; -} - -} // namespace - namespace content { DeviceMotionEventPump::DeviceMotionEventPump(RenderThread* thread) - : PlatformEventObserver<blink::WebDeviceMotionListener>(thread), - accelerometer_(this, device::mojom::SensorType::ACCELEROMETER), - linear_acceleration_sensor_( - this, - device::mojom::SensorType::LINEAR_ACCELERATION), - gyroscope_(this, device::mojom::SensorType::GYROSCOPE), - state_(PumpState::STOPPED) {} + : DeviceSensorMojoClientMixin< + DeviceSensorEventPump<blink::WebDeviceMotionListener>, + device::mojom::MotionSensor>(thread) {} DeviceMotionEventPump::~DeviceMotionEventPump() { - PlatformEventObserver<blink::WebDeviceMotionListener>::StopIfObserving(); } -void DeviceMotionEventPump::Start(blink::WebPlatformEventListener* listener) { - DVLOG(2) << "requested start"; - - if (state_ != PumpState::STOPPED) - return; - - DCHECK(!timer_.IsRunning()); - - state_ = PumpState::PENDING_START; - PlatformEventObserver<blink::WebDeviceMotionListener>::Start(listener); +void DeviceMotionEventPump::FireEvent() { + DCHECK(listener()); + device::MotionData data; + if (reader_->GetLatestData(&data) && data.all_available_sensors_are_active) + listener()->DidChangeDeviceMotion(data); } -void DeviceMotionEventPump::Stop() { - DVLOG(2) << "requested stop"; - - if (state_ == PumpState::STOPPED) - return; - - DCHECK((state_ == PumpState::PENDING_START && !timer_.IsRunning()) || - (state_ == PumpState::RUNNING && timer_.IsRunning())); - - if (timer_.IsRunning()) - timer_.Stop(); - - PlatformEventObserver<blink::WebDeviceMotionListener>::Stop(); - state_ = PumpState::STOPPED; -} - -void DeviceMotionEventPump::SendStartMessage() { - auto request = mojo::MakeRequest(&sensor_provider_); - - // When running layout tests, those observers should not listen to the - // actual hardware changes. In order to make that happen, don't connect - // the other end of the mojo pipe to anything. - if (!RenderThreadImpl::current() || - RenderThreadImpl::current()->layout_test_mode()) { - return; - } - - if (!accelerometer_.sensor && !linear_acceleration_sensor_.sensor && - !gyroscope_.sensor) { - RenderThread::Get()->GetConnector()->BindInterface( - device::mojom::kServiceName, std::move(request)); - sensor_provider_.set_connection_error_handler( - base::Bind(&DeviceMotionEventPump::HandleSensorProviderError, - base::Unretained(this))); - GetSensor(&accelerometer_); - GetSensor(&linear_acceleration_sensor_); - GetSensor(&gyroscope_); - } else { - if (accelerometer_.sensor) - accelerometer_.sensor->Resume(); - - if (linear_acceleration_sensor_.sensor) - linear_acceleration_sensor_.sensor->Resume(); - - if (gyroscope_.sensor) - gyroscope_.sensor->Resume(); - - DidStart(); - } -} - -void DeviceMotionEventPump::SendStopMessage() { - // SendStopMessage() gets called both when the page visibility changes and if - // all device motion event listeners are unregistered. Since removing the - // event listener is more rare than the page visibility changing, - // Sensor::Suspend() is used to optimize this case for not doing extra work. - if (accelerometer_.sensor) - accelerometer_.sensor->Suspend(); - - if (linear_acceleration_sensor_.sensor) - linear_acceleration_sensor_.sensor->Suspend(); - - if (gyroscope_.sensor) - gyroscope_.sensor->Suspend(); +bool DeviceMotionEventPump::InitializeReader(base::SharedMemoryHandle handle) { + if (!reader_) + reader_.reset(new DeviceMotionSharedMemoryReader()); + return reader_->Initialize(handle); } void DeviceMotionEventPump::SendFakeDataForTesting(void* fake_data) { device::MotionData data = *static_cast<device::MotionData*>(fake_data); + listener()->DidChangeDeviceMotion(data); } -DeviceMotionEventPump::SensorEntry::SensorEntry( - DeviceMotionEventPump* pump, - device::mojom::SensorType sensor_type) - : event_pump(pump), type(sensor_type), client_binding(this) {} - -DeviceMotionEventPump::SensorEntry::~SensorEntry() {} - -void DeviceMotionEventPump::SensorEntry::RaiseError() { - HandleSensorError(); -} - -void DeviceMotionEventPump::SensorEntry::SensorReadingChanged() { - // Since DeviceMotionEventPump::FireEvent is called in a certain - // frequency, the |shared_buffer| is read frequently, and - // PlatformSensorConfiguration::set_suppress_on_change_events() - // is set to true, so this method is not called and doesn't need - // to be implemented. - NOTREACHED(); -} - -void DeviceMotionEventPump::SensorEntry::OnSensorCreated( - device::mojom::SensorInitParamsPtr params, - device::mojom::SensorClientRequest client_request) { - if (!params) { - HandleSensorError(); - if (event_pump->CanStart()) - event_pump->DidStart(); - return; - } - - constexpr size_t kReadBufferSize = sizeof(device::SensorReadingSharedBuffer); - - DCHECK_EQ(0u, params->buffer_offset % kReadBufferSize); - - mode = params->mode; - default_config = params->default_configuration; - - DCHECK(sensor.is_bound()); - client_binding.Bind(std::move(client_request)); - - shared_buffer_handle = std::move(params->memory); - DCHECK(!shared_buffer); - shared_buffer = - shared_buffer_handle->MapAtOffset(kReadBufferSize, params->buffer_offset); - - if (!shared_buffer) { - HandleSensorError(); - if (event_pump->CanStart()) - event_pump->DidStart(); - return; - } - - DCHECK_GT(params->minimum_frequency, 0.0); - DCHECK_GE(params->maximum_frequency, params->minimum_frequency); - DCHECK_GE(device::mojom::SensorConfiguration::kMaxAllowedFrequency, - params->maximum_frequency); - - default_config.set_frequency(kDefaultPumpFrequencyHz); - default_config.set_suppress_on_change_events(true); - - sensor->AddConfiguration(default_config, - base::Bind(&SensorEntry::OnSensorAddConfiguration, - base::Unretained(this))); -} - -void DeviceMotionEventPump::SensorEntry::OnSensorAddConfiguration( - bool success) { - if (!success) - HandleSensorError(); - if (event_pump->CanStart()) - event_pump->DidStart(); -} - -void DeviceMotionEventPump::SensorEntry::HandleSensorError() { - sensor.reset(); - shared_buffer_handle.reset(); - shared_buffer.reset(); - client_binding.Close(); -} - -bool DeviceMotionEventPump::SensorEntry::SensorReadingCouldBeRead() { - if (!sensor) - return false; - - const device::SensorReadingSharedBuffer* buffer = - static_cast<const device::SensorReadingSharedBuffer*>( - shared_buffer.get()); - if (!UpdateSensorReading(buffer, &reading)) { - HandleSensorError(); - return false; - } - - return true; -} - -void DeviceMotionEventPump::FireEvent() { - device::MotionData data; - // The device orientation spec states that interval should be in milliseconds. - // https://w3c.github.io/deviceorientation/spec-source-orientation.html#devicemotion - data.interval = kDefaultPumpDelayMicroseconds / 1000; - - DCHECK(listener()); - - GetDataFromSharedMemory(&data); - listener()->DidChangeDeviceMotion(data); -} - -void DeviceMotionEventPump::DidStart() { - DVLOG(2) << "did start sensor event pump"; - - if (state_ != PumpState::PENDING_START) - return; - - DCHECK(!timer_.IsRunning()); - - timer_.Start(FROM_HERE, - base::TimeDelta::FromMicroseconds(kDefaultPumpDelayMicroseconds), - this, &DeviceMotionEventPump::FireEvent); - state_ = PumpState::RUNNING; -} - -bool DeviceMotionEventPump::CanStart() const { - if (accelerometer_.sensor && !accelerometer_.shared_buffer) - return false; - - if (linear_acceleration_sensor_.sensor && - !linear_acceleration_sensor_.shared_buffer) { - return false; - } - - if (gyroscope_.sensor && !gyroscope_.shared_buffer) - return false; - - return true; -} - -void DeviceMotionEventPump::GetDataFromSharedMemory(device::MotionData* data) { - if (accelerometer_.SensorReadingCouldBeRead()) { - data->acceleration_including_gravity_x = - accelerometer_.reading.values[0].value(); - data->acceleration_including_gravity_y = - accelerometer_.reading.values[1].value(); - data->acceleration_including_gravity_z = - accelerometer_.reading.values[2].value(); - data->has_acceleration_including_gravity_x = true; - data->has_acceleration_including_gravity_y = true; - data->has_acceleration_including_gravity_z = true; - } - - if (linear_acceleration_sensor_.SensorReadingCouldBeRead()) { - data->acceleration_x = - linear_acceleration_sensor_.reading.values[0].value(); - data->acceleration_y = - linear_acceleration_sensor_.reading.values[1].value(); - data->acceleration_z = - linear_acceleration_sensor_.reading.values[2].value(); - data->has_acceleration_x = true; - data->has_acceleration_y = true; - data->has_acceleration_z = true; - } - - if (gyroscope_.SensorReadingCouldBeRead()) { - data->rotation_rate_alpha = gyroscope_.reading.values[0].value(); - data->rotation_rate_beta = gyroscope_.reading.values[1].value(); - data->rotation_rate_gamma = gyroscope_.reading.values[2].value(); - data->has_rotation_rate_alpha = true; - data->has_rotation_rate_beta = true; - data->has_rotation_rate_gamma = true; - } -} - -void DeviceMotionEventPump::GetSensor(SensorEntry* sensor_entry) { - auto request = mojo::MakeRequest(&sensor_entry->sensor); - sensor_provider_->GetSensor(sensor_entry->type, std::move(request), - base::Bind(&SensorEntry::OnSensorCreated, - base::Unretained(sensor_entry))); - sensor_entry->sensor.set_connection_error_handler(base::Bind( - &SensorEntry::HandleSensorError, base::Unretained(sensor_entry))); -} - -void DeviceMotionEventPump::HandleSensorProviderError() { - sensor_provider_.reset(); -} - } // namespace content
diff --git a/content/renderer/device_sensors/device_motion_event_pump.h b/content/renderer/device_sensors/device_motion_event_pump.h index 5089aff..5846db1 100644 --- a/content/renderer/device_sensors/device_motion_event_pump.h +++ b/content/renderer/device_sensors/device_motion_event_pump.h
@@ -6,105 +6,38 @@ #define CONTENT_RENDERER_DEVICE_SENSORS_DEVICE_MOTION_EVENT_PUMP_H_ #include <memory> -#include <utility> -#include <vector> -#include "base/bind.h" -#include "base/bind_helpers.h" #include "base/macros.h" -#include "base/time/time.h" -#include "base/timer/timer.h" -#include "content/public/renderer/platform_event_observer.h" -#include "content/renderer/render_thread_impl.h" -#include "device/generic_sensor/public/cpp/sensor_reading.h" -#include "device/generic_sensor/public/interfaces/sensor.mojom.h" -#include "device/generic_sensor/public/interfaces/sensor_provider.mojom.h" +#include "content/renderer/device_sensors/device_sensor_event_pump.h" +#include "content/renderer/shared_memory_seqlock_reader.h" #include "device/sensors/public/cpp/motion_data.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "third_party/WebKit/public/platform/modules/device_orientation/WebDeviceMotionListener.h" +#include "device/sensors/public/interfaces/motion.mojom.h" + +namespace blink { +class WebDeviceMotionListener; +} namespace content { +typedef SharedMemorySeqLockReader<device::MotionData> + DeviceMotionSharedMemoryReader; + class CONTENT_EXPORT DeviceMotionEventPump - : NON_EXPORTED_BASE( - public PlatformEventObserver<blink::WebDeviceMotionListener>) { + : public DeviceSensorMojoClientMixin< + DeviceSensorEventPump<blink::WebDeviceMotionListener>, + device::mojom::MotionSensor> { public: explicit DeviceMotionEventPump(RenderThread* thread); ~DeviceMotionEventPump() override; - // PlatformEventObserver: - void Start(blink::WebPlatformEventListener* listener) override; - void Stop() override; - void SendStartMessage() override; - void SendStopMessage() override; + // PlatformEventObserver. void SendFakeDataForTesting(void* fake_data) override; protected: - // Default rate for firing events. - static constexpr int kDefaultPumpFrequencyHz = 60; - static constexpr int kDefaultPumpDelayMicroseconds = - base::Time::kMicrosecondsPerSecond / kDefaultPumpFrequencyHz; + void FireEvent() override; + bool InitializeReader(base::SharedMemoryHandle handle) override; - struct CONTENT_EXPORT SensorEntry : public device::mojom::SensorClient { - SensorEntry(DeviceMotionEventPump* pump, - device::mojom::SensorType sensor_type); - ~SensorEntry() override; - - // device::mojom::SensorClient: - void RaiseError() override; - void SensorReadingChanged() override; - - // Mojo callback for SensorProvider::GetSensor(). - void OnSensorCreated(device::mojom::SensorInitParamsPtr params, - device::mojom::SensorClientRequest client_request); - - // Mojo callback for Sensor::AddConfiguration(). - void OnSensorAddConfiguration(bool success); - - void HandleSensorError(); - - bool SensorReadingCouldBeRead(); - - DeviceMotionEventPump* event_pump; - device::mojom::SensorPtr sensor; - device::mojom::SensorType type; - device::mojom::ReportingMode mode; - device::PlatformSensorConfiguration default_config; - mojo::ScopedSharedBufferHandle shared_buffer_handle; - mojo::ScopedSharedBufferMapping shared_buffer; - device::SensorReading reading; - mojo::Binding<device::mojom::SensorClient> client_binding; - }; - - friend struct SensorEntry; - - virtual void FireEvent(); - - void DidStart(); - - SensorEntry accelerometer_; - SensorEntry linear_acceleration_sensor_; - SensorEntry gyroscope_; - - private: - // TODO(juncai): refactor DeviceMotionEventPump to use DeviceSensorEventPump - // when refactoring DeviceOrientation. - // - // The pump is a tri-state automaton with allowed transitions as follows: - // STOPPED -> PENDING_START - // PENDING_START -> RUNNING - // PENDING_START -> STOPPED - // RUNNING -> STOPPED - enum class PumpState { STOPPED, RUNNING, PENDING_START }; - - bool CanStart() const; - void GetDataFromSharedMemory(device::MotionData* data); - void GetSensor(SensorEntry* sensor_entry); - void HandleSensorProviderError(); - - mojo::InterfacePtr<device::mojom::SensorProvider> sensor_provider_; - PumpState state_; - base::RepeatingTimer timer_; + std::unique_ptr<DeviceMotionSharedMemoryReader> reader_; DISALLOW_COPY_AND_ASSIGN(DeviceMotionEventPump); };
diff --git a/content/renderer/device_sensors/device_motion_event_pump_unittest.cc b/content/renderer/device_sensors/device_motion_event_pump_unittest.cc index 00a82fd..a87462441 100644 --- a/content/renderer/device_sensors/device_motion_event_pump_unittest.cc +++ b/content/renderer/device_sensors/device_motion_event_pump_unittest.cc
@@ -11,32 +11,16 @@ #include "base/location.h" #include "base/logging.h" #include "base/macros.h" -#include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" -#include "base/time/time.h" #include "content/public/test/test_utils.h" -#include "device/generic_sensor/public/cpp/sensor_reading.h" -#include "device/generic_sensor/public/interfaces/sensor.mojom.h" -#include "device/generic_sensor/public/interfaces/sensor_provider.mojom.h" -#include "device/sensors/public/cpp/motion_data.h" -#include "mojo/public/cpp/bindings/interface_request.h" +#include "device/sensors/public/cpp/device_motion_hardware_buffer.h" #include "mojo/public/cpp/system/buffer.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/public/platform/modules/device_orientation/WebDeviceMotionListener.h" -namespace { - -constexpr uint64_t kReadingBufferSize = - sizeof(device::SensorReadingSharedBuffer); - -constexpr uint64_t kSharedBufferSizeInBytes = - kReadingBufferSize * static_cast<uint64_t>(device::mojom::SensorType::LAST); - -} // namespace - namespace content { class MockDeviceMotionListener : public blink::WebDeviceMotionListener { @@ -72,94 +56,22 @@ class DeviceMotionEventPumpForTesting : public DeviceMotionEventPump { public: DeviceMotionEventPumpForTesting() - : DeviceMotionEventPump(nullptr), stop_on_fire_event_(true) {} + : DeviceMotionEventPump(0), stop_on_fire_event_(true) {} ~DeviceMotionEventPumpForTesting() override {} - // DeviceMotionEventPump: - void SendStartMessage() override { - accelerometer_.mode = device::mojom::ReportingMode::CONTINUOUS; - linear_acceleration_sensor_.mode = device::mojom::ReportingMode::ON_CHANGE; - gyroscope_.mode = device::mojom::ReportingMode::CONTINUOUS; - - shared_memory_ = mojo::SharedBufferHandle::Create(kSharedBufferSizeInBytes); - - accelerometer_.shared_buffer = shared_memory_->MapAtOffset( - kReadingBufferSize, - device::SensorReadingSharedBuffer::GetOffset(accelerometer_.type)); - accelerometer_buffer_ = static_cast<device::SensorReadingSharedBuffer*>( - accelerometer_.shared_buffer.get()); - - linear_acceleration_sensor_.shared_buffer = shared_memory_->MapAtOffset( - kReadingBufferSize, device::SensorReadingSharedBuffer::GetOffset( - linear_acceleration_sensor_.type)); - linear_acceleration_sensor_buffer_ = - static_cast<device::SensorReadingSharedBuffer*>( - linear_acceleration_sensor_.shared_buffer.get()); - - gyroscope_.shared_buffer = shared_memory_->MapAtOffset( - kReadingBufferSize, - device::SensorReadingSharedBuffer::GetOffset(gyroscope_.type)); - gyroscope_buffer_ = static_cast<device::SensorReadingSharedBuffer*>( - gyroscope_.shared_buffer.get()); - } - - void StartFireEvent() { DeviceMotionEventPump::DidStart(); } - - void SetAccelerometerSensorData(bool active, - double d0, - double d1, - double d2) { - if (active) { - mojo::MakeRequest(&accelerometer_.sensor); - accelerometer_buffer_->reading.timestamp = - (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); - accelerometer_buffer_->reading.values[0].value() = d0; - accelerometer_buffer_->reading.values[1].value() = d1; - accelerometer_buffer_->reading.values[2].value() = d2; - } else { - accelerometer_.sensor.reset(); - } - } - - void SetLinearAccelerationSensorData(bool active, - double d0, - double d1, - double d2) { - if (active) { - mojo::MakeRequest(&linear_acceleration_sensor_.sensor); - linear_acceleration_sensor_buffer_->reading.timestamp = - (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); - linear_acceleration_sensor_buffer_->reading.values[0].value() = d0; - linear_acceleration_sensor_buffer_->reading.values[1].value() = d1; - linear_acceleration_sensor_buffer_->reading.values[2].value() = d2; - } else { - linear_acceleration_sensor_.sensor.reset(); - } - } - - void SetGyroscopeSensorData(bool active, double d0, double d1, double d2) { - if (active) { - mojo::MakeRequest(&gyroscope_.sensor); - gyroscope_buffer_->reading.timestamp = - (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); - gyroscope_buffer_->reading.values[0].value() = d0; - gyroscope_buffer_->reading.values[1].value() = d1; - gyroscope_buffer_->reading.values[2].value() = d2; - } else { - gyroscope_.sensor.reset(); - } - } - void set_stop_on_fire_event(bool stop_on_fire_event) { stop_on_fire_event_ = stop_on_fire_event; } bool stop_on_fire_event() { return stop_on_fire_event_; } - int pump_delay_microseconds() const { return kDefaultPumpDelayMicroseconds; } + int pump_delay_microseconds() const { return pump_delay_microseconds_; } - protected: - // DeviceMotionEventPump: + void DidStart(mojo::ScopedSharedBufferHandle renderer_handle) { + DeviceMotionEventPump::DidStart(std::move(renderer_handle)); + } + void SendStartMessage() override {} + void SendStopMessage() override {} void FireEvent() override { DeviceMotionEventPump::FireEvent(); if (stop_on_fire_event_) { @@ -170,10 +82,6 @@ private: bool stop_on_fire_event_; - mojo::ScopedSharedBufferHandle shared_memory_; - device::SensorReadingSharedBuffer* accelerometer_buffer_; - device::SensorReadingSharedBuffer* linear_acceleration_sensor_buffer_; - device::SensorReadingSharedBuffer* gyroscope_buffer_; DISALLOW_COPY_AND_ASSIGN(DeviceMotionEventPumpForTesting); }; @@ -185,102 +93,90 @@ protected: void SetUp() override { listener_.reset(new MockDeviceMotionListener); - motion_pump_.reset(new DeviceMotionEventPumpForTesting()); + motion_pump_.reset(new DeviceMotionEventPumpForTesting); + shared_memory_ = mojo::SharedBufferHandle::Create( + sizeof(device::DeviceMotionHardwareBuffer)); + mapping_ = shared_memory_->Map(sizeof(device::DeviceMotionHardwareBuffer)); + ASSERT_TRUE(mapping_); + memset(buffer(), 0, sizeof(device::DeviceMotionHardwareBuffer)); + } + + void InitBuffer(bool allAvailableSensorsActive) { + device::MotionData& data = buffer()->data; + data.acceleration_x = 1; + data.has_acceleration_x = true; + data.acceleration_y = 2; + data.has_acceleration_y = true; + data.acceleration_z = 3; + data.has_acceleration_z = true; + data.all_available_sensors_are_active = allAvailableSensorsActive; } MockDeviceMotionListener* listener() { return listener_.get(); } DeviceMotionEventPumpForTesting* motion_pump() { return motion_pump_.get(); } + mojo::ScopedSharedBufferHandle handle() { + return shared_memory_->Clone( + mojo::SharedBufferHandle::AccessMode::READ_ONLY); + } + device::DeviceMotionHardwareBuffer* buffer() { + return reinterpret_cast<device::DeviceMotionHardwareBuffer*>( + mapping_.get()); + } private: base::MessageLoop loop_; std::unique_ptr<MockDeviceMotionListener> listener_; std::unique_ptr<DeviceMotionEventPumpForTesting> motion_pump_; + mojo::ScopedSharedBufferHandle shared_memory_; + mojo::ScopedSharedBufferMapping mapping_; DISALLOW_COPY_AND_ASSIGN(DeviceMotionEventPumpTest); }; -TEST_F(DeviceMotionEventPumpTest, AllSensorsAreActive) { +TEST_F(DeviceMotionEventPumpTest, DidStartPolling) { + InitBuffer(true); + motion_pump()->Start(listener()); - motion_pump()->SetAccelerometerSensorData(true /* active */, 1, 2, 3); - motion_pump()->SetLinearAccelerationSensorData(true /* active */, 4, 5, 6); - motion_pump()->SetGyroscopeSensorData(true /* active */, 7, 8, 9); - motion_pump()->StartFireEvent(); + motion_pump()->DidStart(handle()); base::RunLoop().Run(); - device::MotionData received_data = listener()->data(); + const device::MotionData& received_data = listener()->data(); EXPECT_TRUE(listener()->did_change_device_motion()); - - EXPECT_TRUE(received_data.has_acceleration_including_gravity_x); - EXPECT_EQ(1, received_data.acceleration_including_gravity_x); - EXPECT_TRUE(received_data.has_acceleration_including_gravity_y); - EXPECT_EQ(2, received_data.acceleration_including_gravity_y); - EXPECT_TRUE(received_data.has_acceleration_including_gravity_z); - EXPECT_EQ(3, received_data.acceleration_including_gravity_z); - EXPECT_TRUE(received_data.has_acceleration_x); - EXPECT_EQ(4, received_data.acceleration_x); + EXPECT_EQ(1, static_cast<double>(received_data.acceleration_x)); + EXPECT_TRUE(received_data.has_acceleration_x); + EXPECT_EQ(2, static_cast<double>(received_data.acceleration_y)); EXPECT_TRUE(received_data.has_acceleration_y); - EXPECT_EQ(5, received_data.acceleration_y); + EXPECT_EQ(3, static_cast<double>(received_data.acceleration_z)); EXPECT_TRUE(received_data.has_acceleration_z); - EXPECT_EQ(6, received_data.acceleration_z); - - EXPECT_TRUE(received_data.has_rotation_rate_alpha); - EXPECT_EQ(7, received_data.rotation_rate_alpha); - EXPECT_TRUE(received_data.has_rotation_rate_beta); - EXPECT_EQ(8, received_data.rotation_rate_beta); - EXPECT_TRUE(received_data.has_rotation_rate_gamma); - EXPECT_EQ(9, received_data.rotation_rate_gamma); -} - -TEST_F(DeviceMotionEventPumpTest, TwoSensorsAreActive) { - motion_pump()->Start(listener()); - motion_pump()->SetAccelerometerSensorData(true /* active */, 1, 2, 3); - motion_pump()->SetLinearAccelerationSensorData(false /* active */, 4, 5, 6); - motion_pump()->SetGyroscopeSensorData(true /* active */, 7, 8, 9); - motion_pump()->StartFireEvent(); - - base::RunLoop().Run(); - - device::MotionData received_data = listener()->data(); - EXPECT_TRUE(listener()->did_change_device_motion()); - - EXPECT_TRUE(received_data.has_acceleration_including_gravity_x); - EXPECT_EQ(1, received_data.acceleration_including_gravity_x); - EXPECT_TRUE(received_data.has_acceleration_including_gravity_y); - EXPECT_EQ(2, received_data.acceleration_including_gravity_y); - EXPECT_TRUE(received_data.has_acceleration_including_gravity_z); - EXPECT_EQ(3, received_data.acceleration_including_gravity_z); - - EXPECT_FALSE(received_data.has_acceleration_x); - EXPECT_FALSE(received_data.has_acceleration_y); - EXPECT_FALSE(received_data.has_acceleration_z); - - EXPECT_TRUE(received_data.has_rotation_rate_alpha); - EXPECT_EQ(7, received_data.rotation_rate_alpha); - EXPECT_TRUE(received_data.has_rotation_rate_beta); - EXPECT_EQ(8, received_data.rotation_rate_beta); - EXPECT_TRUE(received_data.has_rotation_rate_gamma); - EXPECT_EQ(9, received_data.rotation_rate_gamma); -} - -TEST_F(DeviceMotionEventPumpTest, NoActiveSensors) { - motion_pump()->Start(listener()); - motion_pump()->StartFireEvent(); - - base::RunLoop().Run(); - - device::MotionData received_data = listener()->data(); - EXPECT_TRUE(listener()->did_change_device_motion()); - - EXPECT_FALSE(received_data.has_acceleration_x); - EXPECT_FALSE(received_data.has_acceleration_y); - EXPECT_FALSE(received_data.has_acceleration_z); - EXPECT_FALSE(received_data.has_acceleration_including_gravity_x); EXPECT_FALSE(received_data.has_acceleration_including_gravity_y); EXPECT_FALSE(received_data.has_acceleration_including_gravity_z); + EXPECT_FALSE(received_data.has_rotation_rate_alpha); + EXPECT_FALSE(received_data.has_rotation_rate_beta); + EXPECT_FALSE(received_data.has_rotation_rate_gamma); +} +TEST_F(DeviceMotionEventPumpTest, DidStartPollingNotAllSensorsActive) { + InitBuffer(false); + + motion_pump()->Start(listener()); + motion_pump()->DidStart(handle()); + + base::RunLoop().Run(); + + const device::MotionData& received_data = listener()->data(); + // No change in device motion because all_available_sensors_are_active is + // false. + EXPECT_FALSE(listener()->did_change_device_motion()); + EXPECT_FALSE(received_data.has_acceleration_x); + EXPECT_FALSE(received_data.has_acceleration_x); + EXPECT_FALSE(received_data.has_acceleration_y); + EXPECT_FALSE(received_data.has_acceleration_z); + EXPECT_FALSE(received_data.has_acceleration_including_gravity_x); + EXPECT_FALSE(received_data.has_acceleration_including_gravity_y); + EXPECT_FALSE(received_data.has_acceleration_including_gravity_z); EXPECT_FALSE(received_data.has_rotation_rate_alpha); EXPECT_FALSE(received_data.has_rotation_rate_beta); EXPECT_FALSE(received_data.has_rotation_rate_gamma); @@ -293,11 +189,11 @@ EXPECT_GE(60, base::Time::kMicrosecondsPerSecond / motion_pump()->pump_delay_microseconds()); - motion_pump()->Start(listener()); - motion_pump()->SetLinearAccelerationSensorData(true /* active */, 4, 5, 6); + InitBuffer(true); motion_pump()->set_stop_on_fire_event(false); - motion_pump()->StartFireEvent(); + motion_pump()->Start(listener()); + motion_pump()->DidStart(handle()); base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
diff --git a/content/renderer/presentation/presentation_dispatcher.cc b/content/renderer/presentation/presentation_dispatcher.cc index 2c704a6..8e7c200 100644 --- a/content/renderer/presentation/presentation_dispatcher.cc +++ b/content/renderer/presentation/presentation_dispatcher.cc
@@ -510,7 +510,12 @@ callback->OnSuccess(blink::WebPresentationInfo( presentation_info->presentation_url, blink::WebString::FromUTF8(presentation_info->presentation_id))); - SetControllerConnection(presentation_info.value(), callback->GetConnection()); + + auto* connection = callback->GetConnection(); + if (!connection) + return; + + SetControllerConnection(presentation_info.value(), connection); } void PresentationDispatcher::OnReceiverConnectionAvailable(
diff --git a/content/renderer/presentation/presentation_dispatcher.h b/content/renderer/presentation/presentation_dispatcher.h index 7556b87..4ee61a7 100644 --- a/content/renderer/presentation/presentation_dispatcher.h +++ b/content/renderer/presentation/presentation_dispatcher.h
@@ -64,6 +64,8 @@ TestReconnectPresentation); FRIEND_TEST_ALL_PREFIXES(PresentationDispatcherTest, TestReconnectPresentationError); + FRIEND_TEST_ALL_PREFIXES(PresentationDispatcherTest, + TestReconnectPresentationNoConnection); FRIEND_TEST_ALL_PREFIXES(PresentationDispatcherTest, TestSendString); FRIEND_TEST_ALL_PREFIXES(PresentationDispatcherTest, TestSendArrayBuffer); FRIEND_TEST_ALL_PREFIXES(PresentationDispatcherTest, TestSendBlobData);
diff --git a/content/renderer/presentation/presentation_dispatcher_unittest.cc b/content/renderer/presentation/presentation_dispatcher_unittest.cc index 42a03c3..633b7ad 100644 --- a/content/renderer/presentation/presentation_dispatcher_unittest.cc +++ b/content/renderer/presentation/presentation_dispatcher_unittest.cc
@@ -432,6 +432,35 @@ EXPECT_TRUE(connection.proxy()); } +TEST_F(PresentationDispatcherTest, TestReconnectPresentationNoConnection) { + TestPresentationConnection connection; + EXPECT_FALSE(connection.proxy()); + { + base::RunLoop run_loop; + EXPECT_CALL(presentation_service_, SetPresentationConnection(_, _)) + .Times(0); + EXPECT_CALL(presentation_service_, + ReconnectPresentationInternal(gurls_, _, _)) + .WillOnce(Invoke( + [this]( + const std::vector<GURL>& presentation_urls, + const base::Optional<std::string>& presentation_id, + PresentationService::ReconnectPresentationCallback& callback) { + EXPECT_TRUE(presentation_id.has_value()); + EXPECT_EQ(presentation_id_.Utf8(), presentation_id.value()); + std::move(callback).Run( + PresentationInfo(gurl1_, presentation_id_.Utf8()), + base::nullopt); + })); + + dispatcher_.ReconnectPresentation( + urls_, presentation_id_, + base::MakeUnique<TestWebPresentationConnectionCallback>( + url1_, presentation_id_, nullptr)); + run_loop.RunUntilIdle(); + } +} + TEST_F(PresentationDispatcherTest, TestSendString) { WebString message = WebString::FromUTF8("test message"); TestPresentationConnection connection;
diff --git a/content/shell/browser/layout_test/blink_test_controller.cc b/content/shell/browser/layout_test/blink_test_controller.cc index 00ef8dc..5b61ab4 100644 --- a/content/shell/browser/layout_test/blink_test_controller.cc +++ b/content/shell/browser/layout_test/blink_test_controller.cc
@@ -736,8 +736,10 @@ } void BlinkTestController::OnAllServiceWorkersCleared() { - Send(new ShellViewMsg_Reset( - main_window_->web_contents()->GetRenderViewHost()->GetRoutingID())); + if (main_window_) { + Send(new ShellViewMsg_Reset( + main_window_->web_contents()->GetRenderViewHost()->GetRoutingID())); + } } void BlinkTestController::OnImageDump(const std::string& actual_pixel_hash,
diff --git a/content/shell/test_runner/web_ax_object_proxy.cc b/content/shell/test_runner/web_ax_object_proxy.cc index 65f5241..e9a4919 100644 --- a/content/shell/test_runner/web_ax_object_proxy.cc +++ b/content/shell/test_runner/web_ax_object_proxy.cc
@@ -646,8 +646,13 @@ .SetMethod("allAttributes", &WebAXObjectProxy::AllAttributes) .SetMethod("attributesOfChildren", &WebAXObjectProxy::AttributesOfChildren) + .SetMethod("ariaActiveDescendantElement", + &WebAXObjectProxy::AriaActiveDescendantElement) .SetMethod("ariaControlsElementAtIndex", &WebAXObjectProxy::AriaControlsElementAtIndex) + .SetMethod("ariaDetailsElement", &WebAXObjectProxy::AriaDetailsElement) + .SetMethod("ariaErrorMessageElement", + &WebAXObjectProxy::AriaErrorMessageElement) .SetMethod("ariaFlowToElementAtIndex", &WebAXObjectProxy::AriaFlowToElementAtIndex) .SetMethod("ariaOwnsElementAtIndex", @@ -1263,6 +1268,16 @@ return accessibility_object_.IsClickable(); } +v8::Local<v8::Object> WebAXObjectProxy::AriaActiveDescendantElement() { + accessibility_object_.UpdateLayoutAndCheckValidity(); + SparseAttributeAdapter attribute_adapter; + accessibility_object_.GetSparseAXAttributes(attribute_adapter); + blink::WebAXObject element = + attribute_adapter.object_attributes + [blink::WebAXObjectAttribute::kAriaActiveDescendant]; + return factory_->GetOrCreate(element); +} + v8::Local<v8::Object> WebAXObjectProxy::AriaControlsElementAtIndex( unsigned index) { accessibility_object_.UpdateLayoutAndCheckValidity(); @@ -1278,6 +1293,26 @@ return factory_->GetOrCreate(elements[index]); } +v8::Local<v8::Object> WebAXObjectProxy::AriaDetailsElement() { + accessibility_object_.UpdateLayoutAndCheckValidity(); + SparseAttributeAdapter attribute_adapter; + accessibility_object_.GetSparseAXAttributes(attribute_adapter); + blink::WebAXObject element = + attribute_adapter + .object_attributes[blink::WebAXObjectAttribute::kAriaDetails]; + return factory_->GetOrCreate(element); +} + +v8::Local<v8::Object> WebAXObjectProxy::AriaErrorMessageElement() { + accessibility_object_.UpdateLayoutAndCheckValidity(); + SparseAttributeAdapter attribute_adapter; + accessibility_object_.GetSparseAXAttributes(attribute_adapter); + blink::WebAXObject element = + attribute_adapter + .object_attributes[blink::WebAXObjectAttribute::kAriaErrorMessage]; + return factory_->GetOrCreate(element); +} + v8::Local<v8::Object> WebAXObjectProxy::AriaFlowToElementAtIndex( unsigned index) { accessibility_object_.UpdateLayoutAndCheckValidity();
diff --git a/content/shell/test_runner/web_ax_object_proxy.h b/content/shell/test_runner/web_ax_object_proxy.h index 6e852499..2da568e 100644 --- a/content/shell/test_runner/web_ax_object_proxy.h +++ b/content/shell/test_runner/web_ax_object_proxy.h
@@ -145,7 +145,10 @@ float BoundsHeight(); // Bound methods. + v8::Local<v8::Object> AriaActiveDescendantElement(); v8::Local<v8::Object> AriaControlsElementAtIndex(unsigned index); + v8::Local<v8::Object> AriaDetailsElement(); + v8::Local<v8::Object> AriaErrorMessageElement(); v8::Local<v8::Object> AriaFlowToElementAtIndex(unsigned index); v8::Local<v8::Object> AriaOwnsElementAtIndex(unsigned index); std::string AllAttributes();
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 42b77b3..383aab4 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1530,7 +1530,6 @@ "//device/gamepad", "//device/gamepad:test_helpers", "//device/gamepad/public/cpp:shared_with_blink", - "//device/generic_sensor/public/cpp", "//device/sensors/public/cpp:full", "//device/sensors/public/interfaces", "//gin",
diff --git a/content/test/DEPS b/content/test/DEPS index a756522..74d9797 100644 --- a/content/test/DEPS +++ b/content/test/DEPS
@@ -12,7 +12,6 @@ "+content", "+device/bluetooth", # For WebBluetooth tests "+device/gamepad/public/cpp", - "+device/generic_sensor/public/cpp", "+device/sensors/public/cpp", # For loading V8's initial snapshot from external files. "+gin/v8_initializer.h",
diff --git a/content/test/data/device_sensors/device_motion_only_some_sensors_are_available_test.html b/content/test/data/device_sensors/device_motion_only_some_sensors_are_available_test.html deleted file mode 100644 index b0286e7..0000000 --- a/content/test/data/device_sensors/device_motion_only_some_sensors_are_available_test.html +++ /dev/null
@@ -1,41 +0,0 @@ -<html> - <head> - <title>DeviceMotion only some sensors are available test</title> - <script type="text/javascript"> - let expectedInterval = Math.floor(1000 / 60); - function checkMotionEvent(event) { - return event.acceleration.x == 1 && - event.acceleration.y == 2 && - event.acceleration.z == 3 && - event.accelerationIncludingGravity.x == null && - event.accelerationIncludingGravity.y == null && - event.accelerationIncludingGravity.z == null && - event.rotationRate.alpha == 7 && - event.rotationRate.beta == 8 && - event.rotationRate.gamma == 9 && - event.interval == expectedInterval; - } - - function onMotion(event) { - if (checkMotionEvent(event)) { - window.removeEventListener('devicemotion', onMotion); - pass(); - } else { - fail(); - } - } - - function pass() { - document.getElementById('status').innerHTML = 'PASS'; - document.location = '#pass'; - } - - function fail() { - document.location = '#fail'; - } - </script> - </head> - <body onLoad="window.addEventListener('devicemotion', onMotion)"> - <div id="status">FAIL</div> - </body> -</html>
diff --git a/content/test/data/device_sensors/device_motion_test.html b/content/test/data/device_sensors/device_motion_test.html index e98aa40..11b4e05 100644 --- a/content/test/data/device_sensors/device_motion_test.html +++ b/content/test/data/device_sensors/device_motion_test.html
@@ -2,7 +2,6 @@ <head> <title>DeviceMotion test</title> <script type="text/javascript"> - let expectedInterval = Math.floor(1000 / 60); function checkMotionEvent(event) { return event.acceleration.x == 1 && event.acceleration.y == 2 && @@ -13,7 +12,7 @@ event.rotationRate.alpha == 7 && event.rotationRate.beta == 8 && event.rotationRate.gamma == 9 && - event.interval == expectedInterval; + event.interval == 100; } function onMotion(event) {
diff --git a/device/generic_sensor/BUILD.gn b/device/generic_sensor/BUILD.gn index cdf3e95..dfebf26 100644 --- a/device/generic_sensor/BUILD.gn +++ b/device/generic_sensor/BUILD.gn
@@ -52,7 +52,6 @@ deps = [ "//base", "//device/base/synchronization", - "//services/device/public/cpp:device_features", ] public_deps = [
diff --git a/device/generic_sensor/DEPS b/device/generic_sensor/DEPS index 79cb4cdf..162bc1c 100644 --- a/device/generic_sensor/DEPS +++ b/device/generic_sensor/DEPS
@@ -1,6 +1,5 @@ include_rules = [ "+device/base/synchronization", "+jni", - "+services/device/public/cpp/device_features.h", "+third_party/sudden_motion_sensor", ]
diff --git a/device/generic_sensor/sensor_provider_impl.cc b/device/generic_sensor/sensor_provider_impl.cc index c7a2dfa..3e78e3a1 100644 --- a/device/generic_sensor/sensor_provider_impl.cc +++ b/device/generic_sensor/sensor_provider_impl.cc
@@ -6,13 +6,11 @@ #include <utility> -#include "base/feature_list.h" #include "base/memory/ptr_util.h" #include "base/threading/thread_task_runner_handle.h" #include "device/generic_sensor/platform_sensor_provider.h" #include "device/generic_sensor/sensor_impl.h" #include "mojo/public/cpp/bindings/strong_binding.h" -#include "services/device/public/cpp/device_features.h" namespace device { @@ -56,17 +54,6 @@ void SensorProviderImpl::GetSensor(mojom::SensorType type, mojom::SensorRequest sensor_request, GetSensorCallback callback) { - // TODO(juncai): remove when the GenericSensor feature goes stable. - // For sensors that are used by DeviceMotionEvent, don't check the - // features::kGenericSensor flag. - if (!base::FeatureList::IsEnabled(features::kGenericSensor) && - !(type == mojom::SensorType::ACCELEROMETER || - type == mojom::SensorType::LINEAR_ACCELERATION || - type == mojom::SensorType::GYROSCOPE)) { - NotifySensorCreated(nullptr, nullptr, std::move(callback)); - return; - } - auto cloned_handle = provider_->CloneSharedBufferHandle(); if (!cloned_handle.is_valid()) { NotifySensorCreated(nullptr, nullptr, std::move(callback));
diff --git a/extensions/browser/api/runtime/runtime_api.cc b/extensions/browser/api/runtime/runtime_api.cc index 4f5137a0..0864fde 100644 --- a/extensions/browser/api/runtime/runtime_api.cc +++ b/extensions/browser/api/runtime/runtime_api.cc
@@ -443,6 +443,18 @@ if (!system) return; + // Only dispatch runtime.onInstalled events if: + // 1. the extension has just been installed/updated + // 2. chrome has updated and the extension had runtime.onInstalled listener. + // TODO(devlin): Having the chrome_update event tied to onInstalled has caused + // some issues in the past, see crbug.com/451268. We might want to eventually + // decouple the chrome_updated event from onInstalled and/or throttle + // dispatching the chrome_updated event. + if (chrome_updated && !EventRouter::Get(context)->ExtensionHasEventListener( + extension_id, runtime::OnInstalled::kEventName)) { + return; + } + std::unique_ptr<base::ListValue> event_args(new base::ListValue()); std::unique_ptr<base::DictionaryValue> info(new base::DictionaryValue()); if (old_version.IsValid()) {
diff --git a/extensions/renderer/api_bindings_system.cc b/extensions/renderer/api_bindings_system.cc index 1101190..c39be87b 100644 --- a/extensions/renderer/api_bindings_system.cc +++ b/extensions/renderer/api_bindings_system.cc
@@ -139,7 +139,7 @@ DCHECK(iter != custom_types_.end()) << "Custom type not found: " << type_name; return iter->second.Run(isolate, property_name, property_values, &request_handler_, &event_handler_, - &type_reference_map_); + &type_reference_map_, &access_checker_); } } // namespace extensions
diff --git a/extensions/renderer/api_bindings_system.h b/extensions/renderer/api_bindings_system.h index 928d9f9..a030371d 100644 --- a/extensions/renderer/api_bindings_system.h +++ b/extensions/renderer/api_bindings_system.h
@@ -40,7 +40,8 @@ const base::ListValue* property_values, APIRequestHandler* request_handler, APIEventHandler* event_handler, - APITypeReferenceMap* type_refs)>; + APITypeReferenceMap* type_refs, + const BindingAccessChecker* access_checker)>; APIBindingsSystem( const binding::RunJSFunction& call_js,
diff --git a/extensions/renderer/chrome_setting.cc b/extensions/renderer/chrome_setting.cc index 2509bfb..0f5b5f0d6 100644 --- a/extensions/renderer/chrome_setting.cc +++ b/extensions/renderer/chrome_setting.cc
@@ -11,6 +11,7 @@ #include "extensions/renderer/api_request_handler.h" #include "extensions/renderer/api_signature.h" #include "extensions/renderer/api_type_reference_map.h" +#include "extensions/renderer/binding_access_checker.h" #include "gin/arguments.h" #include "gin/handle.h" #include "gin/object_template_builder.h" @@ -23,7 +24,8 @@ const base::ListValue* property_values, APIRequestHandler* request_handler, APIEventHandler* event_handler, - APITypeReferenceMap* type_refs) { + APITypeReferenceMap* type_refs, + const BindingAccessChecker* access_checker) { std::string pref_name; CHECK(property_values->GetString(0u, &pref_name)); const base::DictionaryValue* value_spec = nullptr; @@ -31,18 +33,20 @@ gin::Handle<ChromeSetting> handle = gin::CreateHandle( isolate, new ChromeSetting(request_handler, event_handler, type_refs, - pref_name, *value_spec)); + access_checker, pref_name, *value_spec)); return handle.ToV8().As<v8::Object>(); } ChromeSetting::ChromeSetting(APIRequestHandler* request_handler, APIEventHandler* event_handler, const APITypeReferenceMap* type_refs, + const BindingAccessChecker* access_checker, const std::string& pref_name, const base::DictionaryValue& set_value_spec) : request_handler_(request_handler), event_handler_(event_handler), type_refs_(type_refs), + access_checker_(access_checker), pref_name_(pref_name), argument_spec_(ArgumentType::OBJECT) { // The set() call takes an object { value: { type: <t> }, ... }, where <t> @@ -135,6 +139,10 @@ std::vector<v8::Local<v8::Value>> argument_list = arguments->GetAll(); std::string full_name = "types.ChromeSetting." + method_name; + + if (!access_checker_->HasAccessOrThrowError(context, full_name)) + return; + std::unique_ptr<base::ListValue> converted_arguments; v8::Local<v8::Function> callback; std::string error;
diff --git a/extensions/renderer/chrome_setting.h b/extensions/renderer/chrome_setting.h index 11b7dc2..76724f1 100644 --- a/extensions/renderer/chrome_setting.h +++ b/extensions/renderer/chrome_setting.h
@@ -24,6 +24,7 @@ namespace extensions { class APIEventHandler; class APIRequestHandler; +class BindingAccessChecker; // The custom implementation of the ChromeSetting type exposed to APIs. class ChromeSetting final : public gin::Wrappable<ChromeSetting> { @@ -31,12 +32,14 @@ ~ChromeSetting() override; // Creates a ChromeSetting object for the given property. - static v8::Local<v8::Object> Create(v8::Isolate* isolate, - const std::string& property_name, - const base::ListValue* property_values, - APIRequestHandler* request_handler, - APIEventHandler* event_handler, - APITypeReferenceMap* type_refs); + static v8::Local<v8::Object> Create( + v8::Isolate* isolate, + const std::string& property_name, + const base::ListValue* property_values, + APIRequestHandler* request_handler, + APIEventHandler* event_handler, + APITypeReferenceMap* type_refs, + const BindingAccessChecker* access_checker); static gin::WrapperInfo kWrapperInfo; @@ -47,6 +50,7 @@ ChromeSetting(APIRequestHandler* request_handler, APIEventHandler* event_handler, const APITypeReferenceMap* type_refs, + const BindingAccessChecker* access_checker, const std::string& pref_name, const base::DictionaryValue& argument_spec); @@ -68,6 +72,8 @@ const APITypeReferenceMap* type_refs_; + const BindingAccessChecker* const access_checker_; + // The name of the preference this ChromeSetting is managing. std::string pref_name_;
diff --git a/extensions/renderer/content_setting.cc b/extensions/renderer/content_setting.cc index b21f729..51495cd 100644 --- a/extensions/renderer/content_setting.cc +++ b/extensions/renderer/content_setting.cc
@@ -11,6 +11,7 @@ #include "extensions/renderer/api_request_handler.h" #include "extensions/renderer/api_signature.h" #include "extensions/renderer/api_type_reference_map.h" +#include "extensions/renderer/binding_access_checker.h" #include "extensions/renderer/console.h" #include "extensions/renderer/script_context_set.h" #include "gin/arguments.h" @@ -40,26 +41,29 @@ const base::ListValue* property_values, APIRequestHandler* request_handler, APIEventHandler* event_handler, - APITypeReferenceMap* type_refs) { + APITypeReferenceMap* type_refs, + const BindingAccessChecker* access_checker) { std::string pref_name; CHECK(property_values->GetString(0u, &pref_name)); const base::DictionaryValue* value_spec = nullptr; CHECK(property_values->GetDictionary(1u, &value_spec)); gin::Handle<ContentSetting> handle = gin::CreateHandle( - isolate, new ContentSetting(run_js, request_handler, type_refs, pref_name, - *value_spec)); + isolate, new ContentSetting(run_js, request_handler, type_refs, + access_checker, pref_name, *value_spec)); return handle.ToV8().As<v8::Object>(); } ContentSetting::ContentSetting(const binding::RunJSFunction& run_js, APIRequestHandler* request_handler, const APITypeReferenceMap* type_refs, + const BindingAccessChecker* access_checker, const std::string& pref_name, const base::DictionaryValue& set_value_spec) : run_js_(run_js), request_handler_(request_handler), type_refs_(type_refs), + access_checker_(access_checker), pref_name_(pref_name), argument_spec_(ArgumentType::OBJECT) { // The set() call takes an object { setting: { type: <t> }, ... }, where <t> @@ -129,6 +133,10 @@ std::vector<v8::Local<v8::Value>> argument_list = arguments->GetAll(); std::string full_name = "contentSettings.ContentSetting." + method_name; + + if (!access_checker_->HasAccessOrThrowError(context, full_name)) + return; + std::unique_ptr<base::ListValue> converted_arguments; v8::Local<v8::Function> callback; std::string error;
diff --git a/extensions/renderer/content_setting.h b/extensions/renderer/content_setting.h index 8f1dfb9..ac3619ca 100644 --- a/extensions/renderer/content_setting.h +++ b/extensions/renderer/content_setting.h
@@ -25,6 +25,7 @@ namespace extensions { class APIEventHandler; class APIRequestHandler; +class BindingAccessChecker; // The custom implementation of the contentSettings.ContentSetting type exposed // to APIs. @@ -33,13 +34,15 @@ ~ContentSetting() override; // Creates a ContentSetting object for the given property. - static v8::Local<v8::Object> Create(const binding::RunJSFunction& run_js, - v8::Isolate* isolate, - const std::string& property_name, - const base::ListValue* property_values, - APIRequestHandler* request_handler, - APIEventHandler* event_handler, - APITypeReferenceMap* type_refs); + static v8::Local<v8::Object> Create( + const binding::RunJSFunction& run_js, + v8::Isolate* isolate, + const std::string& property_name, + const base::ListValue* property_values, + APIRequestHandler* request_handler, + APIEventHandler* event_handler, + APITypeReferenceMap* type_refs, + const BindingAccessChecker* access_checker); static gin::WrapperInfo kWrapperInfo; @@ -50,6 +53,7 @@ ContentSetting(const binding::RunJSFunction& run_js, APIRequestHandler* request_handler, const APITypeReferenceMap* type_refs, + const BindingAccessChecker* access_checker, const std::string& pref_name, const base::DictionaryValue& argument_spec); @@ -69,6 +73,8 @@ const APITypeReferenceMap* type_refs_; + const BindingAccessChecker* const access_checker_; + // The name of the preference this ContentSetting is managing. std::string pref_name_;
diff --git a/extensions/renderer/storage_area.cc b/extensions/renderer/storage_area.cc index e8d0ce6..bf684b8 100644 --- a/extensions/renderer/storage_area.cc +++ b/extensions/renderer/storage_area.cc
@@ -10,6 +10,7 @@ #include "extensions/renderer/api_request_handler.h" #include "extensions/renderer/api_signature.h" #include "extensions/renderer/api_type_reference_map.h" +#include "extensions/renderer/binding_access_checker.h" #include "gin/arguments.h" #include "gin/handle.h" #include "gin/object_template_builder.h" @@ -42,8 +43,9 @@ class LocalStorageArea final : public gin::Wrappable<LocalStorageArea> { public: LocalStorageArea(APIRequestHandler* request_handler, - const APITypeReferenceMap* type_refs) - : storage_area_(request_handler, type_refs, "local") {} + const APITypeReferenceMap* type_refs, + const BindingAccessChecker* access_checker) + : storage_area_(request_handler, type_refs, "local", access_checker) {} ~LocalStorageArea() override = default; static gin::WrapperInfo kWrapperInfo; @@ -72,8 +74,9 @@ class SyncStorageArea final : public gin::Wrappable<SyncStorageArea> { public: SyncStorageArea(APIRequestHandler* request_handler, - const APITypeReferenceMap* type_refs) - : storage_area_(request_handler, type_refs, "sync") {} + const APITypeReferenceMap* type_refs, + const BindingAccessChecker* access_checker) + : storage_area_(request_handler, type_refs, "sync", access_checker) {} ~SyncStorageArea() override = default; static gin::WrapperInfo kWrapperInfo; @@ -112,8 +115,9 @@ class ManagedStorageArea final : public gin::Wrappable<ManagedStorageArea> { public: ManagedStorageArea(APIRequestHandler* request_handler, - const APITypeReferenceMap* type_refs) - : storage_area_(request_handler, type_refs, "managed") {} + const APITypeReferenceMap* type_refs, + const BindingAccessChecker* access_checker) + : storage_area_(request_handler, type_refs, "managed", access_checker) {} ~ManagedStorageArea() override = default; static gin::WrapperInfo kWrapperInfo; @@ -144,8 +148,12 @@ StorageArea::StorageArea(APIRequestHandler* request_handler, const APITypeReferenceMap* type_refs, - const std::string& name) - : request_handler_(request_handler), type_refs_(type_refs), name_(name) {} + const std::string& name, + const BindingAccessChecker* access_checker) + : request_handler_(request_handler), + type_refs_(type_refs), + name_(name), + access_checker_(access_checker) {} StorageArea::~StorageArea() = default; // static @@ -155,20 +163,24 @@ const base::ListValue* property_values, APIRequestHandler* request_handler, APIEventHandler* event_handler, - APITypeReferenceMap* type_refs) { + APITypeReferenceMap* type_refs, + const BindingAccessChecker* access_checker) { v8::Local<v8::Object> object; if (property_name == "local") { gin::Handle<LocalStorageArea> handle = gin::CreateHandle( - isolate, new LocalStorageArea(request_handler, type_refs)); + isolate, + new LocalStorageArea(request_handler, type_refs, access_checker)); object = handle.ToV8().As<v8::Object>(); } else if (property_name == "sync") { gin::Handle<SyncStorageArea> handle = gin::CreateHandle( - isolate, new SyncStorageArea(request_handler, type_refs)); + isolate, + new SyncStorageArea(request_handler, type_refs, access_checker)); object = handle.ToV8().As<v8::Object>(); } else { CHECK_EQ("managed", property_name); gin::Handle<ManagedStorageArea> handle = gin::CreateHandle( - isolate, new ManagedStorageArea(request_handler, type_refs)); + isolate, + new ManagedStorageArea(request_handler, type_refs, access_checker)); object = handle.ToV8().As<v8::Object>(); } return object; @@ -180,6 +192,10 @@ v8::HandleScope handle_scope(isolate); v8::Local<v8::Context> context = arguments->GetHolderCreationContext(); + std::string full_method_name = "storage." + method_name; + if (!access_checker_->HasAccessOrThrowError(context, full_method_name)) + return; + std::vector<v8::Local<v8::Value>> argument_list = arguments->GetAll(); std::unique_ptr<base::ListValue> converted_arguments; @@ -197,8 +213,8 @@ converted_arguments->Insert(0u, base::MakeUnique<base::Value>(name_)); request_handler_->StartRequest( - context, "storage." + method_name, std::move(converted_arguments), - callback, v8::Local<v8::Function>(), binding::RequestThread::UI); + context, full_method_name, std::move(converted_arguments), callback, + v8::Local<v8::Function>(), binding::RequestThread::UI); } } // namespace extensions
diff --git a/extensions/renderer/storage_area.h b/extensions/renderer/storage_area.h index f5abaeb..e37e28c4 100644 --- a/extensions/renderer/storage_area.h +++ b/extensions/renderer/storage_area.h
@@ -23,6 +23,7 @@ class APIEventHandler; class APIRequestHandler; class APITypeReferenceMap; +class BindingAccessChecker; // Implementation of the storage.StorageArea custom type used in the // chrome.storage API. @@ -30,7 +31,8 @@ public: StorageArea(APIRequestHandler* request_handler, const APITypeReferenceMap* type_refs, - const std::string& name); + const std::string& name, + const BindingAccessChecker* access_checker); ~StorageArea(); // Creates a StorageArea object for the given context and property name. @@ -40,7 +42,8 @@ const base::ListValue* property_values, APIRequestHandler* request_handler, APIEventHandler* event_handler, - APITypeReferenceMap* type_refs); + APITypeReferenceMap* type_refs, + const BindingAccessChecker* access_checker); void HandleFunctionCall(const std::string& method_name, gin::Arguments* arguments); @@ -52,6 +55,8 @@ std::string name_; + const BindingAccessChecker* const access_checker_; + DISALLOW_COPY_AND_ASSIGN(StorageArea); };
diff --git a/headless/public/util/testing/generic_url_request_mocks.cc b/headless/public/util/testing/generic_url_request_mocks.cc index a4053dc..844945c0 100644 --- a/headless/public/util/testing/generic_url_request_mocks.cc +++ b/headless/public/util/testing/generic_url_request_mocks.cc
@@ -63,24 +63,23 @@ const GURL& url, const std::string& cookie_line, const net::CookieOptions& options, - const SetCookiesCallback& callback) { + SetCookiesCallback callback) { CHECK(false); } -void MockCookieStore::SetCookieWithDetailsAsync( - const GURL& url, - const std::string& name, - const std::string& value, - const std::string& domain, - const std::string& path, - base::Time creation_time, - base::Time expiration_time, - base::Time last_access_time, - bool secure, - bool http_only, - net::CookieSameSite same_site, - net::CookiePriority priority, - const SetCookiesCallback& callback) { +void MockCookieStore::SetCookieWithDetailsAsync(const GURL& url, + const std::string& name, + const std::string& value, + const std::string& domain, + const std::string& path, + base::Time creation_time, + base::Time expiration_time, + base::Time last_access_time, + bool secure, + bool http_only, + net::CookieSameSite same_site, + net::CookiePriority priority, + SetCookiesCallback callback) { CHECK(false); } @@ -88,47 +87,47 @@ std::unique_ptr<net::CanonicalCookie> cookie, bool secure_source, bool can_modify_httponly, - const SetCookiesCallback& callback) { + SetCookiesCallback callback) { CHECK(false); } void MockCookieStore::GetCookiesWithOptionsAsync( const GURL& url, const net::CookieOptions& options, - const GetCookiesCallback& callback) { + GetCookiesCallback callback) { CHECK(false); } void MockCookieStore::GetCookieListWithOptionsAsync( const GURL& url, const net::CookieOptions& options, - const GetCookieListCallback& callback) { + GetCookieListCallback callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&MockCookieStore::SendCookies, - base::Unretained(this), url, options, callback)); + FROM_HERE, + base::BindOnce(&MockCookieStore::SendCookies, base::Unretained(this), url, + options, std::move(callback))); } -void MockCookieStore::GetAllCookiesAsync( - const GetCookieListCallback& callback) { +void MockCookieStore::GetAllCookiesAsync(GetCookieListCallback callback) { CHECK(false); } void MockCookieStore::DeleteCookieAsync(const GURL& url, const std::string& cookie_name, - const base::Closure& callback) { + base::OnceClosure callback) { CHECK(false); } void MockCookieStore::DeleteCanonicalCookieAsync( const net::CanonicalCookie& cookie, - const DeleteCallback& callback) { + DeleteCallback callback) { CHECK(false); } void MockCookieStore::DeleteAllCreatedBetweenAsync( const base::Time& delete_begin, const base::Time& delete_end, - const DeleteCallback& callback) { + DeleteCallback callback) { CHECK(false); } @@ -136,15 +135,15 @@ const base::Time& delete_begin, const base::Time& delete_end, const CookiePredicate& predicate, - const DeleteCallback& callback) { + DeleteCallback callback) { CHECK(false); } -void MockCookieStore::DeleteSessionCookiesAsync(const DeleteCallback&) { +void MockCookieStore::DeleteSessionCookiesAsync(DeleteCallback) { CHECK(false); } -void MockCookieStore::FlushStore(const base::Closure& callback) { +void MockCookieStore::FlushStore(base::OnceClosure callback) { CHECK(false); } @@ -167,13 +166,13 @@ void MockCookieStore::SendCookies(const GURL& url, const net::CookieOptions& options, - const GetCookieListCallback& callback) { + GetCookieListCallback callback) { net::CookieList result; for (const auto& cookie : cookies_) { if (cookie.IncludeForRequestURL(url, options)) result.push_back(cookie); } - callback.Run(result); + std::move(callback).Run(result); } // MockURLRequestDelegate
diff --git a/headless/public/util/testing/generic_url_request_mocks.h b/headless/public/util/testing/generic_url_request_mocks.h index 98f5e9d..96b4965 100644 --- a/headless/public/util/testing/generic_url_request_mocks.h +++ b/headless/public/util/testing/generic_url_request_mocks.h
@@ -58,7 +58,7 @@ void SetCookieWithOptionsAsync(const GURL& url, const std::string& cookie_line, const net::CookieOptions& options, - const SetCookiesCallback& callback) override; + SetCookiesCallback callback) override; void SetCookieWithDetailsAsync(const GURL& url, const std::string& name, @@ -72,44 +72,43 @@ bool http_only, net::CookieSameSite same_site, net::CookiePriority priority, - const SetCookiesCallback& callback) override; + SetCookiesCallback callback) override; void SetCanonicalCookieAsync(std::unique_ptr<net::CanonicalCookie> cookie, bool secure_source, bool modify_http_only, - const SetCookiesCallback& callback) override; + SetCookiesCallback callback) override; void GetCookiesWithOptionsAsync(const GURL& url, const net::CookieOptions& options, - const GetCookiesCallback& callback) override; + GetCookiesCallback callback) override; - void GetCookieListWithOptionsAsync( - const GURL& url, - const net::CookieOptions& options, - const GetCookieListCallback& callback) override; + void GetCookieListWithOptionsAsync(const GURL& url, + const net::CookieOptions& options, + GetCookieListCallback callback) override; - void GetAllCookiesAsync(const GetCookieListCallback& callback) override; + void GetAllCookiesAsync(GetCookieListCallback callback) override; void DeleteCookieAsync(const GURL& url, const std::string& cookie_name, - const base::Closure& callback) override; + base::OnceClosure callback) override; void DeleteCanonicalCookieAsync(const net::CanonicalCookie& cookie, - const DeleteCallback& callback) override; + DeleteCallback callback) override; void DeleteAllCreatedBetweenAsync(const base::Time& delete_begin, const base::Time& delete_end, - const DeleteCallback& callback) override; + DeleteCallback callback) override; void DeleteAllCreatedBetweenWithPredicateAsync( const base::Time& delete_begin, const base::Time& delete_end, const CookiePredicate& predicate, - const DeleteCallback& callback) override; + DeleteCallback callback) override; - void DeleteSessionCookiesAsync(const DeleteCallback&) override; + void DeleteSessionCookiesAsync(DeleteCallback) override; - void FlushStore(const base::Closure& callback) override; + void FlushStore(base::OnceClosure callback) override; void SetForceKeepSessionState() override; @@ -125,7 +124,7 @@ private: void SendCookies(const GURL& url, const net::CookieOptions& options, - const GetCookieListCallback& callback); + GetCookieListCallback callback); net::CookieList cookies_;
diff --git a/ios/chrome/browser/google/google_logo_service.mm b/ios/chrome/browser/google/google_logo_service.mm index 69252ec..d7da9c3 100644 --- a/ios/chrome/browser/google/google_logo_service.mm +++ b/ios/chrome/browser/google/google_logo_service.mm
@@ -111,8 +111,8 @@ logo_tracker_->SetServerAPI( GetGoogleDoodleURL(browser_state_), base::Bind(&search_provider_logos::GoogleParseLogoResponse), - base::Bind(&search_provider_logos::GoogleAppendQueryparamsToLogoURL), - true, false /* gray_background */); + base::Bind(&search_provider_logos::GoogleAppendQueryparamsToLogoURL, + false /* gray_background */)); logo_tracker_->GetLogo(observer); }
diff --git a/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h b/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h index db91a6e..571635ca 100644 --- a/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h +++ b/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h
@@ -38,6 +38,16 @@ // Whether the text field is enabled for editing. @property(nonatomic, getter=isTextFieldEnabled) BOOL textFieldEnabled; +// Controls the display of the return key when the keyboard is displaying. +@property(nonatomic, assign) UIReturnKeyType returnKeyType; + +// Keyboard type to be displayed when the text field becomes first responder. +@property(nonatomic, assign) UIKeyboardType keyboardType; + +// Controls autocapitalization behavior of the text field. +@property(nonatomic, assign) + UITextAutocapitalizationType autoCapitalizationType; + @end // AutofillEditCell implements an MDCCollectionViewCell subclass containing a
diff --git a/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.mm b/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.mm index c5941ba..4b08a5f 100644 --- a/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.mm +++ b/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.mm
@@ -33,11 +33,17 @@ @synthesize textFieldEnabled = _textFieldEnabled; @synthesize autofillUIType = _autofillUIType; @synthesize required = _required; +@synthesize returnKeyType = _returnKeyType; +@synthesize keyboardType = _keyboardType; +@synthesize autoCapitalizationType = _autoCapitalizationType; - (instancetype)initWithType:(NSInteger)type { self = [super initWithType:type]; if (self) { self.cellClass = [AutofillEditCell class]; + _returnKeyType = UIReturnKeyNext; + _keyboardType = UIKeyboardTypeDefault; + _autoCapitalizationType = UITextAutocapitalizationTypeWords; } return self; } @@ -62,6 +68,9 @@ action:@selector(textFieldChanged:) forControlEvents:UIControlEventEditingChanged]; cell.textField.inputView = self.inputView; + cell.textField.returnKeyType = self.returnKeyType; + cell.textField.keyboardType = self.keyboardType; + cell.textField.autocapitalizationType = self.autoCapitalizationType; cell.identifyingIconView.image = self.identifyingIcon; } @@ -104,9 +113,7 @@ _textField.font = [[MDCTypography fontLoader] lightFontOfSize:16]; _textField.textColor = [[MDCPalette greyPalette] tint500]; - _textField.autocapitalizationType = UITextAutocapitalizationTypeWords; _textField.autocorrectionType = UITextAutocorrectionTypeNo; - _textField.returnKeyType = UIReturnKeyDone; _textField.clearButtonMode = UITextFieldViewModeWhileEditing; _textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; @@ -180,9 +187,11 @@ [super prepareForReuse]; self.textLabel.text = nil; self.textField.text = nil; + self.textField.returnKeyType = UIReturnKeyNext; + self.textField.keyboardType = UIKeyboardTypeDefault; self.textField.autocapitalizationType = UITextAutocapitalizationTypeWords; self.textField.autocorrectionType = UITextAutocorrectionTypeNo; - self.textField.returnKeyType = UIReturnKeyDone; + self.textField.clearButtonMode = UITextFieldViewModeWhileEditing; self.textField.accessibilityIdentifier = nil; self.textField.enabled = NO; self.textField.delegate = nil;
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm index 9780d13..c766a31c 100644 --- a/ios/chrome/browser/ui/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -1638,6 +1638,7 @@ if (self.foregroundTabWasAddedCompletionBlock) { self.foregroundTabWasAddedCompletionBlock(); + self.foregroundTabWasAddedCompletionBlock = nil; } }); } else { @@ -1676,10 +1677,11 @@ [topTab updateSnapshotWithOverlay:YES visibleFrameOnly:YES]; startVoiceSearchIfNecessaryBlock(); }); + // Reset the foreground tab completion block so that it can never be + // called more than once regardless of foreground/background tab + // appearances. + self.foregroundTabWasAddedCompletionBlock = nil; } - // Reset the foreground tab completion block so that it can never be - // called more than once regardless of foreground/background tab appearances. - self.foregroundTabWasAddedCompletionBlock = nil; } #pragma mark - UI Configuration and Layout
diff --git a/ios/chrome/browser/ui/dialogs/dialog_presenter.mm b/ios/chrome/browser/ui/dialogs/dialog_presenter.mm index 05749db..123efba 100644 --- a/ios/chrome/browser/ui/dialogs/dialog_presenter.mm +++ b/ios/chrome/browser/ui/dialogs/dialog_presenter.mm
@@ -31,12 +31,6 @@ NSString* const kJavaScriptDialogTextFieldAccessibiltyIdentifier = @"JavaScriptDialogTextFieldAccessibiltyIdentifier"; -namespace { -// The hostname to use for JavaScript alerts when there is no valid hostname in -// the URL passed to |+localizedTitleForJavaScriptAlertFromPage:type:|. -const char kAboutNullHostname[] = "about:null"; -} // namespace - @interface DialogPresenter () { // Queue of WebStates which correspond to the keys in // |_dialogCoordinatorsForWebStates|. @@ -356,11 +350,16 @@ } + (NSString*)localizedTitleForJavaScriptAlertFromPage:(const GURL&)pageURL { + NSString* localizedTitle = nil; NSString* hostname = base::SysUTF8ToNSString(pageURL.host()); - if (!hostname.length) - hostname = base::SysUTF8ToNSString(kAboutNullHostname); - return l10n_util::GetNSStringF(IDS_JAVASCRIPT_MESSAGEBOX_TITLE, - base::SysNSStringToUTF16(hostname)); + if (!hostname.length) { + localizedTitle = l10n_util::GetNSString( + IDS_JAVASCRIPT_MESSAGEBOX_TITLE_NONSTANDARD_URL_IFRAME); + } else { + localizedTitle = l10n_util::GetNSStringF( + IDS_JAVASCRIPT_MESSAGEBOX_TITLE, base::SysNSStringToUTF16(hostname)); + } + return localizedTitle; } #pragma mark - Private methods.
diff --git a/ios/chrome/browser/ui/payments/address_edit_mediator.mm b/ios/chrome/browser/ui/payments/address_edit_mediator.mm index 90128fc..1dc7e72 100644 --- a/ios/chrome/browser/ui/payments/address_edit_mediator.mm +++ b/ios/chrome/browser/ui/payments/address_edit_mediator.mm
@@ -260,6 +260,15 @@ label:nil value:value required:required]; + // Set the keyboardType and autoCapitalizationType as appropriate. + if (autofillUIType == AutofillUITypeProfileEmailAddress) { + field.keyboardType = UIKeyboardTypeEmailAddress; + field.autoCapitalizationType = UITextAutocapitalizationTypeNone; + } else if (autofillUIType == AutofillUITypeProfileHomeAddressZip) { + field.autoCapitalizationType = + UITextAutocapitalizationTypeAllCharacters; + } + [self.fieldsMap setObject:field forKey:fieldKey]; } @@ -321,6 +330,8 @@ label:l10n_util::GetNSString(IDS_IOS_AUTOFILL_PHONE) value:value required:YES]; + field.keyboardType = UIKeyboardTypePhonePad; + field.returnKeyType = UIReturnKeyDone; [self.fieldsMap setObject:field forKey:phoneNumberFieldKey]; } [self.fields addObject:field];
diff --git a/ios/chrome/browser/ui/payments/contact_info_edit_mediator.mm b/ios/chrome/browser/ui/payments/contact_info_edit_mediator.mm index 98e20b8..0649a8b 100644 --- a/ios/chrome/browser/ui/payments/contact_info_edit_mediator.mm +++ b/ios/chrome/browser/ui/payments/contact_info_edit_mediator.mm
@@ -107,6 +107,10 @@ IDS_PAYMENTS_NAME_FIELD_IN_CONTACT_DETAILS) value:name required:YES]; + if (!_paymentRequest->request_payer_phone() && + !_paymentRequest->request_payer_email()) { + nameField.returnKeyType = UIReturnKeyDone; + } [self.fields addObject:nameField]; } @@ -125,6 +129,9 @@ IDS_PAYMENTS_PHONE_FIELD_IN_CONTACT_DETAILS) value:phone required:YES]; + phoneField.keyboardType = UIKeyboardTypePhonePad; + if (!_paymentRequest->request_payer_email()) + phoneField.returnKeyType = UIReturnKeyDone; [self.fields addObject:phoneField]; } @@ -138,6 +145,9 @@ IDS_PAYMENTS_EMAIL_FIELD_IN_CONTACT_DETAILS) value:email required:YES]; + emailField.keyboardType = UIKeyboardTypeEmailAddress; + emailField.autoCapitalizationType = UITextAutocapitalizationTypeNone; + emailField.returnKeyType = UIReturnKeyDone; [self.fields addObject:emailField]; }
diff --git a/ios/chrome/browser/ui/payments/credit_card_edit_mediator.mm b/ios/chrome/browser/ui/payments/credit_card_edit_mediator.mm index a88b846..65b5496 100644 --- a/ios/chrome/browser/ui/payments/credit_card_edit_mediator.mm +++ b/ios/chrome/browser/ui/payments/credit_card_edit_mediator.mm
@@ -257,6 +257,7 @@ label:l10n_util::GetNSString(IDS_PAYMENTS_CARD_NUMBER) value:creditCardNumber required:YES]; + creditCardNumberField.keyboardType = UIKeyboardTypeNumberPad; [self.fieldsMap setObject:creditCardNumberField forKey:fieldKey]; } [fields addObject:creditCardNumberField];
diff --git a/ios/chrome/browser/ui/payments/payment_request_edit_view_controller.mm b/ios/chrome/browser/ui/payments/payment_request_edit_view_controller.mm index ba77afa..6128089 100644 --- a/ios/chrome/browser/ui/payments/payment_request_edit_view_controller.mm +++ b/ios/chrome/browser/ui/payments/payment_request_edit_view_controller.mm
@@ -250,6 +250,9 @@ item.textFieldValue = field.value; item.required = field.isRequired; item.autofillUIType = field.autofillUIType; + item.returnKeyType = field.returnKeyType; + item.keyboardType = field.keyboardType; + item.autoCapitalizationType = field.autoCapitalizationType; item.identifyingIcon = [_dataSource iconIdentifyingEditorField:field]; [model addItem:item toSectionWithIdentifier:sectionIdentifier]; field.item = item;
diff --git a/ios/chrome/browser/ui/payments/payment_request_editor_field.h b/ios/chrome/browser/ui/payments/payment_request_editor_field.h index 27c0c6a..5e091400 100644 --- a/ios/chrome/browser/ui/payments/payment_request_editor_field.h +++ b/ios/chrome/browser/ui/payments/payment_request_editor_field.h
@@ -5,7 +5,7 @@ #ifndef IOS_CHROME_BROWSER_UI_PAYMENTS_PAYMENT_REQUEST_EDITOR_FIELD_H_ #define IOS_CHROME_BROWSER_UI_PAYMENTS_PAYMENT_REQUEST_EDITOR_FIELD_H_ -#import <Foundation/Foundation.h> +#import <UIKit/UIKit.h> #import "ios/chrome/browser/ui/autofill/autofill_ui_type.h" @@ -37,6 +37,13 @@ @property(nonatomic, getter=isRequired) BOOL required; // Whether the field is enabled. @property(nonatomic, getter=isEnabled) BOOL enabled; +// Controls the display of the return key when the keyboard is displaying. +@property(nonatomic, assign) UIReturnKeyType returnKeyType; +// Keyboard type to be displayed when the text field becomes first responder. +@property(nonatomic, assign) UIKeyboardType keyboardType; +// Controls autocapitalization behavior of the text field. +@property(nonatomic, assign) + UITextAutocapitalizationType autoCapitalizationType; // The associated CollectionViewItem instance. May be nil. @property(nonatomic, strong) CollectionViewItem* item; // The section identifier for the associated AutofillEditItem.
diff --git a/ios/chrome/browser/ui/payments/payment_request_editor_field.mm b/ios/chrome/browser/ui/payments/payment_request_editor_field.mm index e861027..8ecf7e2 100644 --- a/ios/chrome/browser/ui/payments/payment_request_editor_field.mm +++ b/ios/chrome/browser/ui/payments/payment_request_editor_field.mm
@@ -17,6 +17,9 @@ @synthesize displayValue = _displayValue; @synthesize required = _required; @synthesize enabled = _enabled; +@synthesize returnKeyType = _returnKeyType; +@synthesize keyboardType = _keyboardType; +@synthesize autoCapitalizationType = _autoCapitalizationType; @synthesize item = _item; @synthesize sectionIdentifier = _sectionIdentifier; @@ -33,6 +36,9 @@ _value = value; _required = required; _enabled = YES; + _returnKeyType = UIReturnKeyNext; + _keyboardType = UIKeyboardTypeDefault; + _autoCapitalizationType = UITextAutocapitalizationTypeWords; } return self; }
diff --git a/ios/chrome/browser/ui/sad_tab/sad_tab_view.mm b/ios/chrome/browser/ui/sad_tab/sad_tab_view.mm index 89e24dd7..cad5607 100644 --- a/ios/chrome/browser/ui/sad_tab/sad_tab_view.mm +++ b/ios/chrome/browser/ui/sad_tab/sad_tab_view.mm
@@ -242,7 +242,6 @@ initWithString:feedbackIntroductionString]; NSAttributedString* bulletedListString = [[self class] bulletedAttributedStringFromStrings:@[ - l10n_util::GetNSString(IDS_SAD_TAB_RELOAD_CLOSE_NOTABS), l10n_util::GetNSString(IDS_SAD_TAB_RELOAD_INCOGNITO), l10n_util::GetNSString(IDS_SAD_TAB_RELOAD_RESTART_BROWSER), l10n_util::GetNSString(IDS_SAD_TAB_RELOAD_RESTART_DEVICE)
diff --git a/ios/chrome/browser/ui/settings/autofill_credit_card_edit_collection_view_controller.mm b/ios/chrome/browser/ui/settings/autofill_credit_card_edit_collection_view_controller.mm index 24ef3f6..d90d44d 100644 --- a/ios/chrome/browser/ui/settings/autofill_credit_card_edit_collection_view_controller.mm +++ b/ios/chrome/browser/ui/settings/autofill_credit_card_edit_collection_view_controller.mm
@@ -164,6 +164,7 @@ : base::SysUTF16ToNSString(_creditCard.LastFourDigits()); cardNumberitem.textFieldEnabled = isEditing; cardNumberitem.autofillUIType = AutofillUITypeCreditCardNumber; + cardNumberitem.keyboardType = UIKeyboardTypeNumberPad; cardNumberitem.identifyingIcon = [self cardTypeIconFromCardNumber:cardNumberitem.textFieldValue]; [model addItem:cardNumberitem @@ -178,6 +179,7 @@ [NSString stringWithFormat:@"%02d", _creditCard.expiration_month()]; expirationMonthItem.textFieldEnabled = isEditing; expirationMonthItem.autofillUIType = AutofillUITypeCreditCardExpMonth; + expirationMonthItem.keyboardType = UIKeyboardTypeNumberPad; [model addItem:expirationMonthItem toSectionWithIdentifier:SectionIdentifierFields]; @@ -190,6 +192,8 @@ [NSString stringWithFormat:@"%04d", _creditCard.expiration_year()]; expirationYearItem.textFieldEnabled = isEditing; expirationYearItem.autofillUIType = AutofillUITypeCreditCardExpYear; + expirationYearItem.keyboardType = UIKeyboardTypeNumberPad; + expirationYearItem.returnKeyType = UIReturnKeyDone; [model addItem:expirationYearItem toSectionWithIdentifier:SectionIdentifierFields]; @@ -262,28 +266,9 @@ textFieldCell.textField.delegate = self; switch (itemType) { case ItemTypeCardholderName: - textFieldCell.textField.autocapitalizationType = - UITextAutocapitalizationTypeWords; - textFieldCell.textField.keyboardType = UIKeyboardTypeDefault; - textFieldCell.textField.returnKeyType = UIReturnKeyNext; - break; case ItemTypeCardNumber: - textFieldCell.textField.autocapitalizationType = - UITextAutocapitalizationTypeSentences; - textFieldCell.textField.keyboardType = UIKeyboardTypeNumberPad; - textFieldCell.textField.returnKeyType = UIReturnKeyNext; - break; case ItemTypeExpirationMonth: - textFieldCell.textField.autocapitalizationType = - UITextAutocapitalizationTypeSentences; - textFieldCell.textField.keyboardType = UIKeyboardTypeNumberPad; - textFieldCell.textField.returnKeyType = UIReturnKeyNext; - break; case ItemTypeExpirationYear: - textFieldCell.textField.autocapitalizationType = - UITextAutocapitalizationTypeSentences; - textFieldCell.textField.keyboardType = UIKeyboardTypeNumberPad; - textFieldCell.textField.returnKeyType = UIReturnKeyDone; break; case ItemTypeCopiedToChrome: { CopiedToChromeCell* copiedToChromeCell =
diff --git a/ios/chrome/browser/ui/settings/autofill_profile_edit_collection_view_controller.mm b/ios/chrome/browser/ui/settings/autofill_profile_edit_collection_view_controller.mm index 86adb76..1c7c3b3d 100644 --- a/ios/chrome/browser/ui/settings/autofill_profile_edit_collection_view_controller.mm +++ b/ios/chrome/browser/ui/settings/autofill_profile_edit_collection_view_controller.mm
@@ -63,7 +63,7 @@ {autofill::ADDRESS_HOME_STATE, IDS_IOS_AUTOFILL_STATE, UIReturnKeyNext, UIKeyboardTypeDefault, UITextAutocapitalizationTypeSentences}, {autofill::ADDRESS_HOME_ZIP, IDS_IOS_AUTOFILL_ZIP, UIReturnKeyNext, - UIKeyboardTypeNumberPad, UITextAutocapitalizationTypeSentences}, + UIKeyboardTypeDefault, UITextAutocapitalizationTypeAllCharacters}, {autofill::ADDRESS_HOME_COUNTRY, IDS_IOS_AUTOFILL_COUNTRY, UIReturnKeyNext, UIKeyboardTypeDefault, UITextAutocapitalizationTypeSentences}, {autofill::PHONE_HOME_WHOLE_NUMBER, IDS_IOS_AUTOFILL_PHONE, UIReturnKeyNext, @@ -187,6 +187,9 @@ autofill::AutofillType(field.autofillType), locale)); item.autofillUIType = AutofillUITypeFromAutofillType(field.autofillType); item.textFieldEnabled = self.editor.editing; + item.autoCapitalizationType = field.autoCapitalizationType; + item.returnKeyType = field.returnKeyType; + item.keyboardType = field.keyboardType; [model addItem:item toSectionWithIdentifier:SectionIdentifierFields]; } } @@ -215,13 +218,7 @@ AutofillEditCell* textFieldCell = base::mac::ObjCCastStrict<AutofillEditCell>(cell); - NSUInteger index = - [self.collectionViewModel indexInItemTypeForIndexPath:indexPath]; - const AutofillFieldDisplayInfo& field = kFieldsToDisplay[index]; textFieldCell.accessibilityIdentifier = textFieldCell.textLabel.text; - textFieldCell.textField.autocapitalizationType = field.autoCapitalizationType; - textFieldCell.textField.returnKeyType = field.returnKeyType; - textFieldCell.textField.keyboardType = field.keyboardType; textFieldCell.textField.delegate = self; return textFieldCell; }
diff --git a/ios/chrome/browser/ui/stack_view/stack_view_controller.mm b/ios/chrome/browser/ui/stack_view/stack_view_controller.mm index 0f69111d..91ed3a1 100644 --- a/ios/chrome/browser/ui/stack_view/stack_view_controller.mm +++ b/ios/chrome/browser/ui/stack_view/stack_view_controller.mm
@@ -2076,7 +2076,7 @@ double duration = [NSDate timeIntervalSinceReferenceDate] - startTime; if (_activeCardSet.tabModel.isOffTheRecord) { UMA_HISTOGRAM_TIMES( - "Toolbar.TabSwitcher.NewIncognitoTabPresentationDurationn", + "Toolbar.TabSwitcher.NewIncognitoTabPresentationDuration", base::TimeDelta::FromSecondsD(duration)); } else { UMA_HISTOGRAM_TIMES("Toolbar.TabSwitcher.NewTabPresentationDuration",
diff --git a/ios/net/cookies/cookie_store_ios.h b/ios/net/cookies/cookie_store_ios.h index 68ac20f..04a37f19 100644 --- a/ios/net/cookies/cookie_store_ios.h +++ b/ios/net/cookies/cookie_store_ios.h
@@ -75,7 +75,7 @@ void SetCookieWithOptionsAsync(const GURL& url, const std::string& cookie_line, const net::CookieOptions& options, - const SetCookiesCallback& callback) override; + SetCookiesCallback callback) override; void SetCookieWithDetailsAsync(const GURL& url, const std::string& name, const std::string& value, @@ -88,35 +88,33 @@ bool http_only, CookieSameSite same_site, CookiePriority priority, - const SetCookiesCallback& callback) override; + SetCookiesCallback callback) override; void SetCanonicalCookieAsync(std::unique_ptr<CanonicalCookie> cookie, bool secure_source, bool modify_http_only, - const SetCookiesCallback& callback) override; + SetCookiesCallback callback) override; void GetCookiesWithOptionsAsync(const GURL& url, const net::CookieOptions& options, - const GetCookiesCallback& callback) override; - void GetCookieListWithOptionsAsync( - const GURL& url, - const net::CookieOptions& options, - const GetCookieListCallback& callback) override; - void GetAllCookiesAsync(const GetCookieListCallback& callback) override; + GetCookiesCallback callback) override; + void GetCookieListWithOptionsAsync(const GURL& url, + const net::CookieOptions& options, + GetCookieListCallback callback) override; + void GetAllCookiesAsync(GetCookieListCallback callback) override; void DeleteCookieAsync(const GURL& url, const std::string& cookie_name, - const base::Closure& callback) override; - void DeleteCanonicalCookieAsync( - const CanonicalCookie& cookie, - const DeleteCallback& callback) override; + base::OnceClosure callback) override; + void DeleteCanonicalCookieAsync(const CanonicalCookie& cookie, + DeleteCallback callback) override; void DeleteAllCreatedBetweenAsync(const base::Time& delete_begin, const base::Time& delete_end, - const DeleteCallback& callback) override; + DeleteCallback callback) override; void DeleteAllCreatedBetweenWithPredicateAsync( const base::Time& delete_begin, const base::Time& delete_end, const CookiePredicate& predicate, - const DeleteCallback& callback) override; - void DeleteSessionCookiesAsync(const DeleteCallback& callback) override; - void FlushStore(const base::Closure& callback) override; + DeleteCallback callback) override; + void DeleteSessionCookiesAsync(DeleteCallback callback) override; + void FlushStore(base::OnceClosure callback) override; std::unique_ptr<CookieChangedSubscription> AddCallbackForCookie( const GURL& url, @@ -134,9 +132,9 @@ // callback that invokes UpdateCachesFromCookieMonster() to schedule an // asynchronous synchronization of the cookie cache and then calls the // original callback. - SetCookiesCallback WrapSetCallback(const SetCookiesCallback& callback); - DeleteCallback WrapDeleteCallback(const DeleteCallback& callback); - base::Closure WrapClosure(const base::Closure& callback); + SetCookiesCallback WrapSetCallback(SetCookiesCallback callback); + DeleteCallback WrapDeleteCallback(DeleteCallback callback); + base::OnceClosure WrapClosure(base::OnceClosure callback); bool metrics_enabled() { return metrics_enabled_; } @@ -162,7 +160,7 @@ void OnSystemCookiesChanged() override; void DeleteCookiesWithFilter(const CookieFilterFunction& filter, - const DeleteCallback& callback); + DeleteCallback callback); std::unique_ptr<net::CookieMonster> cookie_monster_; base::scoped_nsobject<NSHTTPCookieStorage> system_store_; @@ -225,7 +223,7 @@ // cookies are deleted (with the total number of cookies deleted). // |num_deleted| contains the number of cookies deleted from // NSHTTPCookieStorage. - void DidClearNSHTTPCookieStorageCookies(const DeleteCallback& callback, + void DidClearNSHTTPCookieStorageCookies(DeleteCallback callback, int num_deleted); // Called after cookies are cleared from .binarycookies files. |callback| is // called after all the cookies are deleted with the total number of cookies @@ -233,7 +231,7 @@ // |num_deleted_from_nshttp_cookie_storage| contains the number of cookies // deleted from NSHTTPCookieStorage. void DidClearBinaryCookiesFileCookies( - const DeleteCallback& callback, + DeleteCallback callback, int num_deleted_from_nshttp_cookie_storage); // Callback-wrapping: @@ -254,9 +252,9 @@ // asynchronous cache update (using UpdateCachesFromCookieMonster()) and // calling the provided callback. - void UpdateCachesAfterSet(const SetCookiesCallback& callback, bool success); - void UpdateCachesAfterDelete(const DeleteCallback& callback, int num_deleted); - void UpdateCachesAfterClosure(const base::Closure& callback); + void UpdateCachesAfterSet(SetCookiesCallback callback, bool success); + void UpdateCachesAfterDelete(DeleteCallback callback, int num_deleted); + void UpdateCachesAfterClosure(base::OnceClosure callback); // Takes an NSArray of NSHTTPCookies as returns a net::CookieList. // The returned cookies are ordered by longest path, then earliest
diff --git a/ios/net/cookies/cookie_store_ios.mm b/ios/net/cookies/cookie_store_ios.mm index f24def3..edb3bad 100644 --- a/ios/net/cookies/cookie_store_ios.mm +++ b/ios/net/cookies/cookie_store_ios.mm
@@ -303,7 +303,7 @@ const GURL& url, const std::string& cookie_line, const net::CookieOptions& options, - const SetCookiesCallback& callback) { + SetCookiesCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); // The exclude_httponly() option would only be used by a javascript @@ -348,23 +348,22 @@ } if (!callback.is_null()) - callback.Run(success); + std::move(callback).Run(success); } -void CookieStoreIOS::SetCookieWithDetailsAsync( - const GURL& url, - const std::string& name, - const std::string& value, - const std::string& domain, - const std::string& path, - base::Time creation_time, - base::Time expiration_time, - base::Time last_access_time, - bool secure, - bool http_only, - CookieSameSite same_site, - CookiePriority priority, - const SetCookiesCallback& callback) { +void CookieStoreIOS::SetCookieWithDetailsAsync(const GURL& url, + const std::string& name, + const std::string& value, + const std::string& domain, + const std::string& path, + base::Time creation_time, + base::Time expiration_time, + base::Time last_access_time, + bool secure, + bool http_only, + CookieSameSite same_site, + CookiePriority priority, + SetCookiesCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); // If cookies are not allowed, they are stashed in the CookieMonster, and // should be written there instead. @@ -381,7 +380,7 @@ ParsedCookie::ParseValueString(domain) != domain || ParsedCookie::ParseValueString(path) != path) { if (!callback.is_null()) - callback.Run(false); + std::move(callback).Run(false); return; } @@ -392,7 +391,7 @@ !cookie_util::GetCookieDomainWithString(url, domain, &cookie_domain) || (!path.empty() && cookie_path != path)) { if (!callback.is_null()) - callback.Run(false); + std::move(callback).Run(false); return; } @@ -424,14 +423,14 @@ } if (!callback.is_null()) - callback.Run(success); + std::move(callback).Run(success); } void CookieStoreIOS::SetCanonicalCookieAsync( std::unique_ptr<net::CanonicalCookie> cookie, bool secure_source, bool modify_http_only, - const SetCookiesCallback& callback) { + SetCookiesCallback callback) { DCHECK(cookie->IsCanonical()); // The exclude_httponly() option would only be used by a javascript // engine. @@ -439,7 +438,7 @@ if (cookie->IsSecure() && !secure_source) { if (!callback.is_null()) - callback.Run(false); + std::move(callback).Run(false); return; } @@ -453,18 +452,18 @@ cookie->CreationDate().is_null() ? base::Time::Now() : cookie->CreationDate())); if (!callback.is_null()) - callback.Run(true); + std::move(callback).Run(true); return; } if (!callback.is_null()) - callback.Run(false); + std::move(callback).Run(false); } void CookieStoreIOS::GetCookiesWithOptionsAsync( const GURL& url, const net::CookieOptions& options, - const GetCookiesCallback& callback) { + GetCookiesCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); // If cookies are not allowed, they are stashed in the CookieMonster, and @@ -479,18 +478,19 @@ NSArray* cookies = GetCookiesForURL(system_store_, url, creation_time_manager_.get()); if (!callback.is_null()) - callback.Run(BuildCookieLineWithOptions(cookies, options)); + std::move(callback).Run(BuildCookieLineWithOptions(cookies, options)); } void CookieStoreIOS::GetCookieListWithOptionsAsync( const GURL& url, const net::CookieOptions& options, - const GetCookieListCallback& callback) { + GetCookieListCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); if (!SystemCookiesAllowed()) { // If cookies are not allowed, the cookies are stashed in the // CookieMonster, so get them from there. - cookie_monster_->GetCookieListWithOptionsAsync(url, options, callback); + cookie_monster_->GetCookieListWithOptionsAsync(url, options, + std::move(callback)); return; } @@ -500,29 +500,29 @@ GetCookiesForURL(system_store_, url, creation_time_manager_.get()); net::CookieList cookie_list = CanonicalCookieListFromSystemCookies(cookies); if (!callback.is_null()) - callback.Run(cookie_list); + std::move(callback).Run(cookie_list); } -void CookieStoreIOS::GetAllCookiesAsync(const GetCookieListCallback& callback) { +void CookieStoreIOS::GetAllCookiesAsync(GetCookieListCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); if (!SystemCookiesAllowed()) { // If cookies are not allowed, the cookies are stashed in the // CookieMonster, so get them from there. - cookie_monster_->GetAllCookiesAsync(callback); + cookie_monster_->GetAllCookiesAsync(std::move(callback)); return; } NSArray* cookies = GetAllCookies(system_store_, creation_time_manager_.get()); net::CookieList cookie_list = CanonicalCookieListFromSystemCookies(cookies); if (!callback.is_null()) { - callback.Run(cookie_list); + std::move(callback).Run(cookie_list); } } void CookieStoreIOS::DeleteCookieAsync(const GURL& url, const std::string& cookie_name, - const base::Closure& callback) { + base::OnceClosure callback) { DCHECK(thread_checker_.CalledOnValidThread()); NSArray* cookies = @@ -535,24 +535,23 @@ } if (!callback.is_null()) - callback.Run(); + std::move(callback).Run(); } -void CookieStoreIOS::DeleteCanonicalCookieAsync( - const CanonicalCookie& cookie, - const DeleteCallback& callback) { +void CookieStoreIOS::DeleteCanonicalCookieAsync(const CanonicalCookie& cookie, + DeleteCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); // This relies on the fact cookies are given unique creation dates. CookieFilterFunction filter = base::Bind( IsCookieCreatedBetween, cookie.CreationDate(), cookie.CreationDate()); - DeleteCookiesWithFilter(filter, callback); + DeleteCookiesWithFilter(filter, std::move(callback)); } void CookieStoreIOS::DeleteAllCreatedBetweenAsync( const base::Time& delete_begin, const base::Time& delete_end, - const DeleteCallback& callback) { + DeleteCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); if (metrics_enabled_) @@ -560,14 +559,14 @@ CookieFilterFunction filter = base::Bind( &IsCookieCreatedBetween, delete_begin, delete_end); - DeleteCookiesWithFilter(filter, callback); + DeleteCookiesWithFilter(filter, std::move(callback)); } void CookieStoreIOS::DeleteAllCreatedBetweenWithPredicateAsync( const base::Time& delete_begin, const base::Time& delete_end, const CookiePredicate& predicate, - const DeleteCallback& callback) { + DeleteCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); if (metrics_enabled_) @@ -575,20 +574,20 @@ CookieFilterFunction filter = base::Bind( IsCookieCreatedBetweenWithPredicate, delete_begin, delete_end, predicate); - DeleteCookiesWithFilter(filter, callback); + DeleteCookiesWithFilter(filter, std::move(callback)); } -void CookieStoreIOS::DeleteSessionCookiesAsync(const DeleteCallback& callback) { +void CookieStoreIOS::DeleteSessionCookiesAsync(DeleteCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); if (metrics_enabled_) ResetCookieCountMetrics(); CookieFilterFunction filter = base::Bind(&IsCookieSessionCookie); - DeleteCookiesWithFilter(filter, callback); + DeleteCookiesWithFilter(filter, std::move(callback)); } -void CookieStoreIOS::FlushStore(const base::Closure& closure) { +void CookieStoreIOS::FlushStore(base::OnceClosure closure) { DCHECK(thread_checker_.CalledOnValidThread()); if (SystemCookiesAllowed()) { @@ -596,7 +595,7 @@ // stashed on disk. Do not delete the cookies on the disk in this case. WriteToCookieMonster([system_store_ cookies]); } - cookie_monster_->FlushStore(closure); + cookie_monster_->FlushStore(std::move(closure)); flush_closure_.Cancel(); } @@ -621,23 +620,23 @@ } CookieStoreIOS::SetCookiesCallback CookieStoreIOS::WrapSetCallback( - const SetCookiesCallback& callback) { + SetCookiesCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); - return base::Bind(&CookieStoreIOS::UpdateCachesAfterSet, - weak_factory_.GetWeakPtr(), callback); + return base::BindOnce(&CookieStoreIOS::UpdateCachesAfterSet, + weak_factory_.GetWeakPtr(), std::move(callback)); } CookieStoreIOS::DeleteCallback CookieStoreIOS::WrapDeleteCallback( - const DeleteCallback& callback) { + DeleteCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); - return base::Bind(&CookieStoreIOS::UpdateCachesAfterDelete, - weak_factory_.GetWeakPtr(), callback); + return base::BindOnce(&CookieStoreIOS::UpdateCachesAfterDelete, + weak_factory_.GetWeakPtr(), std::move(callback)); } -base::Closure CookieStoreIOS::WrapClosure(const base::Closure& callback) { +base::OnceClosure CookieStoreIOS::WrapClosure(base::OnceClosure callback) { DCHECK(thread_checker_.CalledOnValidThread()); - return base::Bind(&CookieStoreIOS::UpdateCachesAfterClosure, - weak_factory_.GetWeakPtr(), callback); + return base::BindOnce(&CookieStoreIOS::UpdateCachesAfterClosure, + weak_factory_.GetWeakPtr(), std::move(callback)); } #pragma mark - @@ -677,7 +676,7 @@ } void CookieStoreIOS::DeleteCookiesWithFilter(const CookieFilterFunction& filter, - const DeleteCallback& callback) { + DeleteCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); NSArray* cookies = [system_store_ cookies]; @@ -697,7 +696,7 @@ } if (!callback.is_null()) - callback.Run([to_delete count]); + std::move(callback).Run([to_delete count]); } void CookieStoreIOS::OnSystemCookiesChanged() { @@ -814,7 +813,7 @@ } void CookieStoreIOS::DidClearNSHTTPCookieStorageCookies( - const DeleteCallback& delete_callback, + DeleteCallback delete_callback, int num_deleted) { DCHECK(thread_checker_.CalledOnValidThread()); @@ -822,15 +821,16 @@ DCHECK(client); auto sequenced_task_runner = client->GetTaskRunner(); DCHECK(sequenced_task_runner); - auto callback = - base::Bind(&CookieStoreIOS::DidClearBinaryCookiesFileCookies, - weak_factory_.GetWeakPtr(), delete_callback, num_deleted); + auto callback = base::BindOnce( + &CookieStoreIOS::DidClearBinaryCookiesFileCookies, + weak_factory_.GetWeakPtr(), std::move(delete_callback), num_deleted); sequenced_task_runner.get()->PostTaskAndReply( - FROM_HERE, base::Bind(&ClearAllCookiesFromBinaryCookiesFile), callback); + FROM_HERE, base::Bind(&ClearAllCookiesFromBinaryCookiesFile), + std::move(callback)); } void CookieStoreIOS::DidClearBinaryCookiesFileCookies( - const DeleteCallback& callback, + DeleteCallback callback, int num_deleted_from_nshttp_cookie_storage) { DCHECK(thread_checker_.CalledOnValidThread()); @@ -838,41 +838,41 @@ DCHECK(client); client->DidChangeCookieStorage(); if (!callback.is_null()) - callback.Run(num_deleted_from_nshttp_cookie_storage); + std::move(callback).Run(num_deleted_from_nshttp_cookie_storage); } void CookieStoreIOS::UpdateCachesFromCookieMonster() { DCHECK(thread_checker_.CalledOnValidThread()); for (const auto& hook_map_entry : hook_map_) { std::pair<GURL, std::string> key = hook_map_entry.first; - GetCookieListCallback callback = base::Bind( + GetCookieListCallback callback = base::BindOnce( &CookieStoreIOS::GotCookieListFor, weak_factory_.GetWeakPtr(), key); - cookie_monster_->GetAllCookiesForURLAsync(key.first, callback); + cookie_monster_->GetAllCookiesForURLAsync(key.first, std::move(callback)); } } -void CookieStoreIOS::UpdateCachesAfterSet(const SetCookiesCallback& callback, +void CookieStoreIOS::UpdateCachesAfterSet(SetCookiesCallback callback, bool success) { DCHECK(thread_checker_.CalledOnValidThread()); if (success) UpdateCachesFromCookieMonster(); if (!callback.is_null()) - callback.Run(success); + std::move(callback).Run(success); } -void CookieStoreIOS::UpdateCachesAfterDelete(const DeleteCallback& callback, +void CookieStoreIOS::UpdateCachesAfterDelete(DeleteCallback callback, int num_deleted) { DCHECK(thread_checker_.CalledOnValidThread()); UpdateCachesFromCookieMonster(); if (!callback.is_null()) - callback.Run(num_deleted); + std::move(callback).Run(num_deleted); } -void CookieStoreIOS::UpdateCachesAfterClosure(const base::Closure& callback) { +void CookieStoreIOS::UpdateCachesAfterClosure(base::OnceClosure callback) { DCHECK(thread_checker_.CalledOnValidThread()); UpdateCachesFromCookieMonster(); if (!callback.is_null()) - callback.Run(); + std::move(callback).Run(); } net::CookieList
diff --git a/ios/net/cookies/cookie_store_ios_persistent.h b/ios/net/cookies/cookie_store_ios_persistent.h index 18dba8fb..70f798b 100644 --- a/ios/net/cookies/cookie_store_ios_persistent.h +++ b/ios/net/cookies/cookie_store_ios_persistent.h
@@ -39,7 +39,7 @@ void SetCookieWithOptionsAsync(const GURL& url, const std::string& cookie_line, const net::CookieOptions& options, - const SetCookiesCallback& callback) override; + SetCookiesCallback callback) override; void SetCookieWithDetailsAsync(const GURL& url, const std::string& name, const std::string& value, @@ -52,33 +52,32 @@ bool http_only, CookieSameSite same_site, CookiePriority priority, - const SetCookiesCallback& callback) override; + SetCookiesCallback callback) override; void SetCanonicalCookieAsync(std::unique_ptr<CanonicalCookie> cookie, bool secure_source, bool modify_http_only, - const SetCookiesCallback& callback) override; + SetCookiesCallback callback) override; void GetCookiesWithOptionsAsync(const GURL& url, const net::CookieOptions& options, - const GetCookiesCallback& callback) override; - void GetCookieListWithOptionsAsync( - const GURL& url, - const net::CookieOptions& options, - const GetCookieListCallback& callback) override; - void GetAllCookiesAsync(const GetCookieListCallback& callback) override; + GetCookiesCallback callback) override; + void GetCookieListWithOptionsAsync(const GURL& url, + const net::CookieOptions& options, + GetCookieListCallback callback) override; + void GetAllCookiesAsync(GetCookieListCallback callback) override; void DeleteCookieAsync(const GURL& url, const std::string& cookie_name, - const base::Closure& callback) override; + base::OnceClosure callback) override; void DeleteCanonicalCookieAsync(const CanonicalCookie& cookie, - const DeleteCallback& callback) override; + DeleteCallback callback) override; void DeleteAllCreatedBetweenAsync(const base::Time& delete_begin, const base::Time& delete_end, - const DeleteCallback& callback) override; + DeleteCallback callback) override; void DeleteAllCreatedBetweenWithPredicateAsync( const base::Time& delete_begin, const base::Time& delete_end, const CookiePredicate& predicate, - const DeleteCallback& callback) override; - void DeleteSessionCookiesAsync(const DeleteCallback& callback) override; + DeleteCallback callback) override; + void DeleteSessionCookiesAsync(DeleteCallback callback) override; private: // No-op functions for this class.
diff --git a/ios/net/cookies/cookie_store_ios_persistent.mm b/ios/net/cookies/cookie_store_ios_persistent.mm index 9a8527c..609e3a9 100644 --- a/ios/net/cookies/cookie_store_ios_persistent.mm +++ b/ios/net/cookies/cookie_store_ios_persistent.mm
@@ -28,11 +28,11 @@ const GURL& url, const std::string& cookie_line, const net::CookieOptions& options, - const SetCookiesCallback& callback) { + SetCookiesCallback callback) { DCHECK(thread_checker().CalledOnValidThread()); - cookie_monster()->SetCookieWithOptionsAsync(url, cookie_line, options, - WrapSetCallback(callback)); + cookie_monster()->SetCookieWithOptionsAsync( + url, cookie_line, options, WrapSetCallback(std::move(callback))); } void CookieStoreIOSPersistent::SetCookieWithDetailsAsync( @@ -48,99 +48,103 @@ bool http_only, CookieSameSite same_site, CookiePriority priority, - const SetCookiesCallback& callback) { + SetCookiesCallback callback) { DCHECK(thread_checker().CalledOnValidThread()); cookie_monster()->SetCookieWithDetailsAsync( url, name, value, domain, path, creation_time, expiration_time, last_access_time, secure, http_only, same_site, priority, - WrapSetCallback(callback)); + WrapSetCallback(std::move(callback))); } void CookieStoreIOSPersistent::SetCanonicalCookieAsync( std::unique_ptr<CanonicalCookie> cookie, bool secure_source, bool modify_http_only, - const SetCookiesCallback& callback) { + SetCookiesCallback callback) { DCHECK(thread_checker().CalledOnValidThread()); - cookie_monster()->SetCanonicalCookieAsync(std::move(cookie), secure_source, - modify_http_only, - WrapSetCallback(callback)); + cookie_monster()->SetCanonicalCookieAsync( + std::move(cookie), secure_source, modify_http_only, + WrapSetCallback(std::move(callback))); } void CookieStoreIOSPersistent::GetCookiesWithOptionsAsync( const GURL& url, const net::CookieOptions& options, - const GetCookiesCallback& callback) { + GetCookiesCallback callback) { DCHECK(thread_checker().CalledOnValidThread()); - cookie_monster()->GetCookiesWithOptionsAsync(url, options, callback); + cookie_monster()->GetCookiesWithOptionsAsync(url, options, + std::move(callback)); } void CookieStoreIOSPersistent::GetCookieListWithOptionsAsync( const GURL& url, const net::CookieOptions& options, - const GetCookieListCallback& callback) { + GetCookieListCallback callback) { DCHECK(thread_checker().CalledOnValidThread()); - cookie_monster()->GetCookieListWithOptionsAsync(url, options, callback); + cookie_monster()->GetCookieListWithOptionsAsync(url, options, + std::move(callback)); } void CookieStoreIOSPersistent::GetAllCookiesAsync( - const GetCookieListCallback& callback) { + GetCookieListCallback callback) { DCHECK(thread_checker().CalledOnValidThread()); - cookie_monster()->GetAllCookiesAsync(callback); + cookie_monster()->GetAllCookiesAsync(std::move(callback)); } -void CookieStoreIOSPersistent::DeleteCookieAsync( - const GURL& url, - const std::string& cookie_name, - const base::Closure& callback) { +void CookieStoreIOSPersistent::DeleteCookieAsync(const GURL& url, + const std::string& cookie_name, + base::OnceClosure callback) { DCHECK(thread_checker().CalledOnValidThread()); - cookie_monster()->DeleteCookieAsync(url, cookie_name, WrapClosure(callback)); + cookie_monster()->DeleteCookieAsync(url, cookie_name, + WrapClosure(std::move(callback))); } void CookieStoreIOSPersistent::DeleteCanonicalCookieAsync( const CanonicalCookie& cookie, - const DeleteCallback& callback) { + DeleteCallback callback) { DCHECK(thread_checker().CalledOnValidThread()); - cookie_monster()->DeleteCanonicalCookieAsync(cookie, - WrapDeleteCallback(callback)); + cookie_monster()->DeleteCanonicalCookieAsync( + cookie, WrapDeleteCallback(std::move(callback))); } void CookieStoreIOSPersistent::DeleteAllCreatedBetweenAsync( const base::Time& delete_begin, const base::Time& delete_end, - const DeleteCallback& callback) { + DeleteCallback callback) { DCHECK(thread_checker().CalledOnValidThread()); if (metrics_enabled()) ResetCookieCountMetrics(); - cookie_monster()->DeleteAllCreatedBetweenAsync(delete_begin, delete_end, - WrapDeleteCallback(callback)); + cookie_monster()->DeleteAllCreatedBetweenAsync( + delete_begin, delete_end, WrapDeleteCallback(std::move(callback))); } void CookieStoreIOSPersistent::DeleteAllCreatedBetweenWithPredicateAsync( const base::Time& delete_begin, const base::Time& delete_end, const CookiePredicate& predicate, - const DeleteCallback& callback) { + DeleteCallback callback) { DCHECK(thread_checker().CalledOnValidThread()); if (metrics_enabled()) ResetCookieCountMetrics(); cookie_monster()->DeleteAllCreatedBetweenWithPredicateAsync( - delete_begin, delete_end, predicate, WrapDeleteCallback(callback)); + delete_begin, delete_end, predicate, + WrapDeleteCallback(std::move(callback))); } void CookieStoreIOSPersistent::DeleteSessionCookiesAsync( - const DeleteCallback& callback) { + DeleteCallback callback) { DCHECK(thread_checker().CalledOnValidThread()); if (metrics_enabled()) ResetCookieCountMetrics(); - cookie_monster()->DeleteSessionCookiesAsync(WrapDeleteCallback(callback)); + cookie_monster()->DeleteSessionCookiesAsync( + WrapDeleteCallback(std::move(callback))); } #pragma mark -
diff --git a/ios/net/cookies/cookie_store_ios_persistent_unittest.mm b/ios/net/cookies/cookie_store_ios_persistent_unittest.mm index 9cb9ed7..86736e0 100644 --- a/ios/net/cookies/cookie_store_ios_persistent_unittest.mm +++ b/ios/net/cookies/cookie_store_ios_persistent_unittest.mm
@@ -67,10 +67,11 @@ ~CookieStoreIOSPersistentTest() override {} // Gets the cookies. |callback| will be called on completion. - void GetCookies(const net::CookieStore::GetCookiesCallback& callback) { + void GetCookies(net::CookieStore::GetCookiesCallback callback) { net::CookieOptions options; options.set_include_httponly(); - store_->GetCookiesWithOptionsAsync(kTestCookieURL, options, callback); + store_->GetCookiesWithOptionsAsync(kTestCookieURL, options, + std::move(callback)); } // Sets a cookie. @@ -123,7 +124,8 @@ TEST_F(CookieStoreIOSPersistentTest, NotSynchronized) { // Start fetching the cookie. GetCookieCallback callback; - GetCookies(base::Bind(&GetCookieCallback::Run, base::Unretained(&callback))); + GetCookies( + base::BindOnce(&GetCookieCallback::Run, base::Unretained(&callback))); // Backend loading completes. backend_->RunLoadedCallback(); EXPECT_TRUE(callback.did_run());
diff --git a/ios/net/cookies/cookie_store_ios_test_util.h b/ios/net/cookies/cookie_store_ios_test_util.h index 436ffebf..82c33c3 100644 --- a/ios/net/cookies/cookie_store_ios_test_util.h +++ b/ios/net/cookies/cookie_store_ios_test_util.h
@@ -38,7 +38,7 @@ void UpdateCookieAccessTime(const net::CanonicalCookie& cc) override; void DeleteCookie(const net::CanonicalCookie& cc) override; void SetForceKeepSessionState() override; - void Flush(const base::Closure& callback) override; + void Flush(base::OnceClosure callback) override; ~TestPersistentCookieStore() override;
diff --git a/ios/net/cookies/cookie_store_ios_test_util.mm b/ios/net/cookies/cookie_store_ios_test_util.mm index e96e734..67d06ac 100644 --- a/ios/net/cookies/cookie_store_ios_test_util.mm +++ b/ios/net/cookies/cookie_store_ios_test_util.mm
@@ -84,7 +84,7 @@ void TestPersistentCookieStore::SetForceKeepSessionState() {} -void TestPersistentCookieStore::Flush(const base::Closure& callback) { +void TestPersistentCookieStore::Flush(base::OnceClosure callback) { flushed_ = true; }
diff --git a/ios/net/cookies/cookie_store_ios_unittest.mm b/ios/net/cookies/cookie_store_ios_unittest.mm index 1280af0..31e0046 100644 --- a/ios/net/cookies/cookie_store_ios_unittest.mm +++ b/ios/net/cookies/cookie_store_ios_unittest.mm
@@ -100,10 +100,11 @@ ~CookieStoreIOSTest() override {} // Gets the cookies. |callback| will be called on completion. - void GetCookies(const net::CookieStore::GetCookiesCallback& callback) { + void GetCookies(net::CookieStore::GetCookiesCallback callback) { net::CookieOptions options; options.set_include_httponly(); - store_->GetCookiesWithOptionsAsync(kTestCookieURL, options, callback); + store_->GetCookiesWithOptionsAsync(kTestCookieURL, options, + std::move(callback)); } // Sets a cookie.
diff --git a/ios/public/provider/chrome/browser/signin/chrome_identity_service.h b/ios/public/provider/chrome/browser/signin/chrome_identity_service.h index 201bb61..17054c7f 100644 --- a/ios/public/provider/chrome/browser/signin/chrome_identity_service.h +++ b/ios/public/provider/chrome/browser/signin/chrome_identity_service.h
@@ -9,7 +9,6 @@ #include <string> #include <vector> -#include "base/mac/scoped_nsobject.h" #include "base/macros.h" #include "base/observer_list.h" @@ -118,25 +117,6 @@ ios::ChromeBrowserState* browser_state, id<ChromeIdentityInteractionManagerDelegate> delegate) const; - // Deprecated. Returns a new account details controller to present. A cancel - // button is present as leading navigation item. - virtual base::scoped_nsobject<UINavigationController> NewAccountDetails( - ChromeIdentity* identity, - id<ChromeIdentityBrowserOpener> browser_opener); - - // Deprecated. Returns a new Web and App Setting Details controller to - // present. - virtual base::scoped_nsobject<UINavigationController> - NewWebAndAppSettingDetails(ChromeIdentity* identity, - id<ChromeIdentityBrowserOpener> browser_opener); - - // Deprecated. Returns a new ChromeIdentityInteractionManager with |delegate| - // as its delegate. - virtual base::scoped_nsobject<ChromeIdentityInteractionManager> - NewChromeIdentityInteractionManager( - ios::ChromeBrowserState* browser_state, - id<ChromeIdentityInteractionManagerDelegate> delegate) const; - // Returns YES if |identity| is valid and if the service has it in its list of // identitites. virtual bool IsValidIdentity(ChromeIdentity* identity) const;
diff --git a/ios/public/provider/chrome/browser/signin/chrome_identity_service.mm b/ios/public/provider/chrome/browser/signin/chrome_identity_service.mm index 05cbbbd7..c2e347e 100644 --- a/ios/public/provider/chrome/browser/signin/chrome_identity_service.mm +++ b/ios/public/provider/chrome/browser/signin/chrome_identity_service.mm
@@ -43,27 +43,6 @@ return nil; } -base::scoped_nsobject<UINavigationController> -ChromeIdentityService::NewAccountDetails( - ChromeIdentity* identity, - id<ChromeIdentityBrowserOpener> browser_opener) { - return base::scoped_nsobject<UINavigationController>(); -} - -base::scoped_nsobject<UINavigationController> -ChromeIdentityService::NewWebAndAppSettingDetails( - ChromeIdentity* identity, - id<ChromeIdentityBrowserOpener> browser_opener) { - return base::scoped_nsobject<UINavigationController>(); -} - -base::scoped_nsobject<ChromeIdentityInteractionManager> -ChromeIdentityService::NewChromeIdentityInteractionManager( - ios::ChromeBrowserState* browser_state, - id<ChromeIdentityInteractionManagerDelegate> delegate) const { - return base::scoped_nsobject<ChromeIdentityInteractionManager>(); -} - bool ChromeIdentityService::IsValidIdentity(ChromeIdentity* identity) const { return false; }
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index d2abac3..10994509c 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -4482,6 +4482,9 @@ didCommitNavigation:(WKNavigation*)navigation { [self displayWebView]; + bool navigationFinished = [_navigationStates stateForNavigation:navigation] == + web::WKNavigationState::FINISHED; + // Record the navigation state. [_navigationStates setState:web::WKNavigationState::COMMITTED forNavigation:navigation]; @@ -4573,10 +4576,21 @@ UMA_HISTOGRAM_BOOLEAN("WebController.WKWebViewHasCertForSecureConnection", static_cast<bool>(cert)); } + + if (navigationFinished) { + // webView:didFinishNavigation: was called before + // webView:didCommitNavigation:, so remove the navigation now and signal + // that navigation was finished. + [_navigationStates removeNavigation:navigation]; + [self didFinishNavigation:navigation]; + } } - (void)webView:(WKWebView*)webView didFinishNavigation:(WKNavigation*)navigation { + bool navigationCommitted = + [_navigationStates stateForNavigation:navigation] == + web::WKNavigationState::COMMITTED; [_navigationStates setState:web::WKNavigationState::FINISHED forNavigation:navigation]; @@ -4587,7 +4601,12 @@ // appropriate time rather than invoking here. web::ExecuteJavaScript(webView, @"__gCrWeb.didFinishNavigation()", nil); [self didFinishNavigation:navigation]; - [_navigationStates removeNavigation:navigation]; + + // Remove navigation only if it has been committed. Otherwise it will be + // removed in webView:didCommitNavigation: callback. + if (navigationCommitted) { + [_navigationStates removeNavigation:navigation]; + } } - (void)webView:(WKWebView*)webView
diff --git a/ios/web/web_state/ui/crw_wk_navigation_states.h b/ios/web/web_state/ui/crw_wk_navigation_states.h index 6052538..35731ec 100644 --- a/ios/web/web_state/ui/crw_wk_navigation_states.h +++ b/ios/web/web_state/ui/crw_wk_navigation_states.h
@@ -56,6 +56,9 @@ - (void)setState:(web::WKNavigationState)state forNavigation:(WKNavigation*)navigation; +// Returns state for a given |navigation| or NONE if navigation does not exist. +- (web::WKNavigationState)stateForNavigation:(WKNavigation*)navigation; + // Removes given |navigation|. Fails if |navigation| does not exist. // |navigation| can be null. - (void)removeNavigation:(WKNavigation*)navigation;
diff --git a/ios/web/web_state/ui/crw_wk_navigation_states.mm b/ios/web/web_state/ui/crw_wk_navigation_states.mm index 235562e4..24389a8 100644 --- a/ios/web/web_state/ui/crw_wk_navigation_states.mm +++ b/ios/web/web_state/ui/crw_wk_navigation_states.mm
@@ -122,14 +122,24 @@ [[CRWWKNavigationsStateRecord alloc] initWithState:state index:++_lastStateIndex]; } else { - DCHECK( - record.state < state || - (record.state == state && state == web::WKNavigationState::REDIRECTED)); + DCHECK(record.state < state || + // Redirect can be called multiple times. + (record.state == state && + state == web::WKNavigationState::REDIRECTED) || + // didFinishNavigation can be called before didCommitNvigation. + (record.state == web::WKNavigationState::FINISHED && + state == web::WKNavigationState::COMMITTED)); record.state = state; } [_records setObject:record forKey:key]; } +- (web::WKNavigationState)stateForNavigation:(WKNavigation*)navigation { + id key = [self keyForNavigation:navigation]; + CRWWKNavigationsStateRecord* record = [_records objectForKey:key]; + return record ? record.state : web::WKNavigationState::NONE; +} + - (void)removeNavigation:(WKNavigation*)navigation { id key = [self keyForNavigation:navigation]; DCHECK([_records objectForKey:key]);
diff --git a/ios/web/web_state/ui/crw_wk_navigation_states_unittest.mm b/ios/web/web_state/ui/crw_wk_navigation_states_unittest.mm index 85c77da..9266aa9 100644 --- a/ios/web/web_state/ui/crw_wk_navigation_states_unittest.mm +++ b/ios/web/web_state/ui/crw_wk_navigation_states_unittest.mm
@@ -43,30 +43,41 @@ TEST_F(CRWWKNavigationStatesTest, RemovingNavigation) { // navigation_1 is the only navigation and it is the latest. [states_ setState:WKNavigationState::REQUESTED forNavigation:navigation1_]; + ASSERT_EQ(WKNavigationState::REQUESTED, + [states_ stateForNavigation:navigation1_]); ASSERT_EQ(navigation1_, [states_ lastAddedNavigation]); [states_ removeNavigation:navigation1_]; - ASSERT_FALSE([states_ lastAddedNavigation]); + EXPECT_FALSE([states_ lastAddedNavigation]); + EXPECT_EQ(WKNavigationState::NONE, [states_ stateForNavigation:navigation1_]); } // Tests |lastAddedNavigation| method. TEST_F(CRWWKNavigationStatesTest, LastAddedNavigation) { // navigation_1 is the only navigation and it is the latest. [states_ setState:WKNavigationState::REQUESTED forNavigation:navigation1_]; + EXPECT_EQ(WKNavigationState::REQUESTED, + [states_ stateForNavigation:navigation1_]); EXPECT_EQ(navigation1_, [states_ lastAddedNavigation]); EXPECT_EQ(WKNavigationState::REQUESTED, [states_ lastAddedNavigationState]); // navigation_2 is added later and hence the latest. [states_ setState:WKNavigationState::REQUESTED forNavigation:navigation2_]; + EXPECT_EQ(WKNavigationState::REQUESTED, + [states_ stateForNavigation:navigation2_]); EXPECT_EQ(navigation2_, [states_ lastAddedNavigation]); EXPECT_EQ(WKNavigationState::REQUESTED, [states_ lastAddedNavigationState]); // Updating state for existing navigation does not make it the latest. [states_ setState:WKNavigationState::STARTED forNavigation:navigation1_]; + EXPECT_EQ(WKNavigationState::STARTED, + [states_ stateForNavigation:navigation1_]); EXPECT_EQ(navigation2_, [states_ lastAddedNavigation]); EXPECT_EQ(WKNavigationState::REQUESTED, [states_ lastAddedNavigationState]); // navigation_2 is still the latest. [states_ setState:WKNavigationState::STARTED forNavigation:navigation2_]; + EXPECT_EQ(WKNavigationState::STARTED, + [states_ stateForNavigation:navigation2_]); EXPECT_EQ(navigation2_, [states_ lastAddedNavigation]); EXPECT_EQ(WKNavigationState::STARTED, [states_ lastAddedNavigationState]); @@ -122,11 +133,14 @@ TEST_F(CRWWKNavigationStatesTest, NullNavigation) { // navigation_1 is the only navigation and it is the latest. [states_ setState:WKNavigationState::REQUESTED forNavigation:navigation1_]; + EXPECT_EQ(WKNavigationState::REQUESTED, + [states_ stateForNavigation:navigation1_]); ASSERT_EQ(navigation1_, [states_ lastAddedNavigation]); EXPECT_EQ(WKNavigationState::REQUESTED, [states_ lastAddedNavigationState]); // null navigation is added later and hence the latest. [states_ setState:WKNavigationState::STARTED forNavigation:nil]; + EXPECT_EQ(WKNavigationState::STARTED, [states_ stateForNavigation:nil]); EXPECT_FALSE([states_ lastAddedNavigation]); EXPECT_EQ(WKNavigationState::STARTED, [states_ lastAddedNavigationState]); @@ -142,17 +156,23 @@ // Add pending navigation_1. [states_ setState:WKNavigationState::REQUESTED forNavigation:navigation1_]; + ASSERT_EQ(WKNavigationState::REQUESTED, + [states_ stateForNavigation:navigation1_]); ASSERT_EQ(1U, [states_ pendingNavigations].count); EXPECT_TRUE([[states_ pendingNavigations] containsObject:navigation1_]); // Add pending navigation_2. [states_ setState:WKNavigationState::STARTED forNavigation:navigation2_]; + ASSERT_EQ(WKNavigationState::STARTED, + [states_ stateForNavigation:navigation2_]); ASSERT_EQ(2U, [states_ pendingNavigations].count); EXPECT_TRUE([[states_ pendingNavigations] containsObject:navigation1_]); EXPECT_TRUE([[states_ pendingNavigations] containsObject:navigation2_]); // Add pending navigation_3. [states_ setState:WKNavigationState::STARTED forNavigation:navigation3_]; + ASSERT_EQ(WKNavigationState::STARTED, + [states_ stateForNavigation:navigation3_]); ASSERT_EQ(3U, [states_ pendingNavigations].count); EXPECT_TRUE([[states_ pendingNavigations] containsObject:navigation1_]); EXPECT_TRUE([[states_ pendingNavigations] containsObject:navigation2_]); @@ -160,6 +180,7 @@ // Add pending null navigation. [states_ setState:WKNavigationState::STARTED forNavigation:nil]; + ASSERT_EQ(WKNavigationState::STARTED, [states_ stateForNavigation:nil]); ASSERT_EQ(4U, [states_ pendingNavigations].count); EXPECT_TRUE([[states_ pendingNavigations] containsObject:navigation1_]); EXPECT_TRUE([[states_ pendingNavigations] containsObject:navigation2_]); @@ -168,6 +189,8 @@ // Provisionally fail null navigation. [states_ setState:WKNavigationState::PROVISIONALY_FAILED forNavigation:nil]; + ASSERT_EQ(WKNavigationState::PROVISIONALY_FAILED, + [states_ stateForNavigation:nil]); ASSERT_EQ(3U, [states_ pendingNavigations].count); EXPECT_TRUE([[states_ pendingNavigations] containsObject:navigation2_]); EXPECT_TRUE([[states_ pendingNavigations] containsObject:navigation3_]); @@ -175,12 +198,16 @@ // Commit navigation_1. [states_ setState:WKNavigationState::COMMITTED forNavigation:navigation1_]; + ASSERT_EQ(WKNavigationState::COMMITTED, + [states_ stateForNavigation:navigation1_]); ASSERT_EQ(2U, [states_ pendingNavigations].count); EXPECT_TRUE([[states_ pendingNavigations] containsObject:navigation2_]); EXPECT_TRUE([[states_ pendingNavigations] containsObject:navigation3_]); // Finish navigation_1. [states_ setState:WKNavigationState::FINISHED forNavigation:navigation1_]; + ASSERT_EQ(WKNavigationState::FINISHED, + [states_ stateForNavigation:navigation1_]); ASSERT_EQ(2U, [states_ pendingNavigations].count); EXPECT_TRUE([[states_ pendingNavigations] containsObject:navigation2_]); EXPECT_TRUE([[states_ pendingNavigations] containsObject:navigation3_]); @@ -192,6 +219,8 @@ // Fail navigation_3. [states_ setState:WKNavigationState::FAILED forNavigation:navigation3_]; + ASSERT_EQ(WKNavigationState::FAILED, + [states_ stateForNavigation:navigation3_]); ASSERT_EQ(0U, [states_ pendingNavigations].count); }
diff --git a/mash/BUILD.gn b/mash/BUILD.gn index c4fc6db..7172fc6 100644 --- a/mash/BUILD.gn +++ b/mash/BUILD.gn
@@ -107,10 +107,10 @@ "test/mash_unittests.cc", ] deps = [ - "//ash:common_unittests", "//ash/mus:resources", "//ash/mus:unittests", "//ash/public/cpp:ash_public_cpp", + "//ash/test:test_support_without_content", "//base", "//base/test:test_support", "//cc",
diff --git a/media/capture/video/video_capture_device_unittest.cc b/media/capture/video/video_capture_device_unittest.cc index 3c4f1f2..4aa5f483 100644 --- a/media/capture/video/video_capture_device_unittest.cc +++ b/media/capture/video/video_capture_device_unittest.cc
@@ -308,6 +308,13 @@ } #endif + if (device_descriptors_->empty()) + LOG(WARNING) << "No camera found"; + else { + LOG(INFO) << "Using camera " << device_descriptors_->front().display_name + << " (" << device_descriptors_->front().model_id << ")"; + } + return !device_descriptors_->empty(); }
diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc index 60eccfe..85b658e 100644 --- a/net/cookies/cookie_monster.cc +++ b/net/cookies/cookie_monster.cc
@@ -431,7 +431,7 @@ bool http_only, CookieSameSite same_site, CookiePriority priority, - const SetCookiesCallback& callback) + SetCookiesCallback callback) : CookieMonsterTask(cookie_monster), url_(url), name_(name), @@ -445,7 +445,7 @@ http_only_(http_only), same_site_(same_site), priority_(priority), - callback_(callback) {} + callback_(std::move(callback)) {} // CookieMonsterTask: void Run() override; @@ -476,15 +476,15 @@ url_, name_, value_, domain_, path_, creation_time_, expiration_time_, last_access_time_, secure_, http_only_, same_site_, priority_); if (!callback_.is_null()) - callback_.Run(success); + std::move(callback_).Run(success); } // Task class for GetAllCookies call. class CookieMonster::GetAllCookiesTask : public CookieMonsterTask { public: GetAllCookiesTask(CookieMonster* cookie_monster, - const GetCookieListCallback& callback) - : CookieMonsterTask(cookie_monster), callback_(callback) {} + GetCookieListCallback callback) + : CookieMonsterTask(cookie_monster), callback_(std::move(callback)) {} // CookieMonsterTask void Run() override; @@ -501,7 +501,7 @@ void CookieMonster::GetAllCookiesTask::Run() { if (!callback_.is_null()) { CookieList cookies = this->cookie_monster()->GetAllCookies(); - callback_.Run(cookies); + std::move(callback_).Run(cookies); } } @@ -511,11 +511,11 @@ GetCookieListWithOptionsTask(CookieMonster* cookie_monster, const GURL& url, const CookieOptions& options, - const GetCookieListCallback& callback) + GetCookieListCallback callback) : CookieMonsterTask(cookie_monster), url_(url), options_(options), - callback_(callback) {} + callback_(std::move(callback)) {} // CookieMonsterTask: void Run() override; @@ -535,18 +535,18 @@ if (!callback_.is_null()) { CookieList cookies = this->cookie_monster()->GetCookieListWithOptions(url_, options_); - callback_.Run(cookies); + std::move(callback_).Run(cookies); } } template <typename Result> struct CallbackType { - typedef base::Callback<void(Result)> Type; + typedef base::OnceCallback<void(Result)> Type; }; template <> struct CallbackType<void> { - typedef base::Closure Type; + typedef base::OnceClosure Type; }; // Base task class for Delete*Task. @@ -554,8 +554,8 @@ class CookieMonster::DeleteTask : public CookieMonsterTask { public: DeleteTask(CookieMonster* cookie_monster, - const typename CallbackType<Result>::Type& callback) - : CookieMonsterTask(cookie_monster), callback_(callback) {} + typename CallbackType<Result>::Type callback) + : CookieMonsterTask(cookie_monster), callback_(std::move(callback)) {} // CookieMonsterTask: void Run() override; @@ -570,7 +570,7 @@ // flushing the persistent store. // TODO(mmenke): This seems like a pretty ugly and needlessly confusing API. // Simplify it? - base::Closure RunDeleteTaskAndBindCallback(); + base::OnceClosure RunDeleteTaskAndBindCallback(); typename CallbackType<Result>::Type callback_; @@ -582,29 +582,31 @@ } template <typename Result> -base::Closure +base::OnceClosure CookieMonster::DeleteTask<Result>::RunDeleteTaskAndBindCallback() { Result result = RunDeleteTask(); if (callback_.is_null()) - return base::Closure(); - return base::Bind(callback_, result); + return base::OnceClosure(); + return base::BindOnce(std::move(callback_), result); } template <> -base::Closure CookieMonster::DeleteTask<void>::RunDeleteTaskAndBindCallback() { +base::OnceClosure +CookieMonster::DeleteTask<void>::RunDeleteTaskAndBindCallback() { RunDeleteTask(); - return callback_; + return std::move(callback_); } template <typename Result> void CookieMonster::DeleteTask<Result>::Run() { - base::Closure callback = RunDeleteTaskAndBindCallback(); + base::OnceClosure callback = RunDeleteTaskAndBindCallback(); if (!callback.is_null()) { - callback = base::Bind( - &CookieMonster::RunCallback, - this->cookie_monster()->weak_ptr_factory_.GetWeakPtr(), callback); + callback = + base::BindOnce(&CookieMonster::RunCallback, + this->cookie_monster()->weak_ptr_factory_.GetWeakPtr(), + std::move(callback)); } - this->cookie_monster()->FlushStore(callback); + this->cookie_monster()->FlushStore(std::move(callback)); } // Task class for DeleteAllCreatedBetween call. @@ -613,8 +615,8 @@ DeleteAllCreatedBetweenTask(CookieMonster* cookie_monster, const Time& delete_begin, const Time& delete_end, - const DeleteCallback& callback) - : DeleteTask<int>(cookie_monster, callback), + DeleteCallback callback) + : DeleteTask<int>(cookie_monster, std::move(callback)), delete_begin_(delete_begin), delete_end_(delete_end) {} @@ -645,8 +647,8 @@ Time delete_begin, Time delete_end, base::Callback<bool(const CanonicalCookie&)> predicate, - const DeleteCallback& callback) - : DeleteTask<int>(cookie_monster, callback), + DeleteCallback callback) + : DeleteTask<int>(cookie_monster, std::move(callback)), delete_begin_(delete_begin), delete_end_(delete_end), predicate_(predicate) {} @@ -675,8 +677,8 @@ public: DeleteCanonicalCookieTask(CookieMonster* cookie_monster, const CanonicalCookie& cookie, - const DeleteCallback& callback) - : DeleteTask<int>(cookie_monster, callback), cookie_(cookie) {} + DeleteCallback callback) + : DeleteTask<int>(cookie_monster, std::move(callback)), cookie_(cookie) {} // DeleteTask: int RunDeleteTask() override; @@ -701,12 +703,12 @@ std::unique_ptr<CanonicalCookie> cookie, bool secure_source, bool modify_http_only, - const SetCookiesCallback& callback) + SetCookiesCallback callback) : CookieMonsterTask(cookie_monster), cookie_(std::move(cookie)), secure_source_(secure_source), modify_http_only_(modify_http_only), - callback_(callback) {} + callback_(std::move(callback)) {} // CookieMonsterTask: void Run() override; @@ -727,7 +729,7 @@ bool result = this->cookie_monster()->SetCanonicalCookie( std::move(cookie_), secure_source_, modify_http_only_); if (!callback_.is_null()) - callback_.Run(result); + std::move(callback_).Run(result); } // Task class for SetCookieWithOptions call. @@ -737,12 +739,12 @@ const GURL& url, const std::string& cookie_line, const CookieOptions& options, - const SetCookiesCallback& callback) + SetCookiesCallback callback) : CookieMonsterTask(cookie_monster), url_(url), cookie_line_(cookie_line), options_(options), - callback_(callback) {} + callback_(std::move(callback)) {} // CookieMonsterTask: void Run() override; @@ -763,7 +765,7 @@ bool result = this->cookie_monster()->SetCookieWithOptions(url_, cookie_line_, options_); if (!callback_.is_null()) - callback_.Run(result); + std::move(callback_).Run(result); } // Task class for SetAllCookies call. @@ -771,8 +773,10 @@ public: SetAllCookiesTask(CookieMonster* cookie_monster, const CookieList& list, - const SetCookiesCallback& callback) - : CookieMonsterTask(cookie_monster), list_(list), callback_(callback) {} + SetCookiesCallback callback) + : CookieMonsterTask(cookie_monster), + list_(list), + callback_(std::move(callback)) {} // CookieMonsterTask: void Run() override; @@ -804,7 +808,7 @@ result = this->cookie_monster()->SetAllCookies(list_); if (!callback_.is_null()) - callback_.Run(result); + std::move(callback_).Run(result); } // Task class for GetCookiesWithOptions call. @@ -813,11 +817,11 @@ GetCookiesWithOptionsTask(CookieMonster* cookie_monster, const GURL& url, const CookieOptions& options, - const GetCookiesCallback& callback) + GetCookiesCallback callback) : CookieMonsterTask(cookie_monster), url_(url), options_(options), - callback_(callback) {} + callback_(std::move(callback)) {} // CookieMonsterTask: void Run() override; @@ -837,7 +841,7 @@ std::string cookie = this->cookie_monster()->GetCookiesWithOptions(url_, options_); if (!callback_.is_null()) - callback_.Run(cookie); + std::move(callback_).Run(cookie); } // Task class for DeleteCookie call. @@ -846,8 +850,8 @@ DeleteCookieTask(CookieMonster* cookie_monster, const GURL& url, const std::string& cookie_name, - const base::Closure& callback) - : DeleteTask<void>(cookie_monster, callback), + base::OnceClosure callback) + : DeleteTask<void>(cookie_monster, std::move(callback)), url_(url), cookie_name_(cookie_name) {} @@ -872,8 +876,8 @@ class CookieMonster::DeleteSessionCookiesTask : public DeleteTask<int> { public: DeleteSessionCookiesTask(CookieMonster* cookie_monster, - const DeleteCallback& callback) - : DeleteTask<int>(cookie_monster, callback) {} + DeleteCallback callback) + : DeleteTask<int>(cookie_monster, std::move(callback)) {} // DeleteTask: int RunDeleteTask() override; @@ -891,36 +895,37 @@ // Asynchronous CookieMonster API -void CookieMonster::SetCookieWithDetailsAsync( - const GURL& url, - const std::string& name, - const std::string& value, - const std::string& domain, - const std::string& path, - Time creation_time, - Time expiration_time, - Time last_access_time, - bool secure, - bool http_only, - CookieSameSite same_site, - CookiePriority priority, - const SetCookiesCallback& callback) { +void CookieMonster::SetCookieWithDetailsAsync(const GURL& url, + const std::string& name, + const std::string& value, + const std::string& domain, + const std::string& path, + Time creation_time, + Time expiration_time, + Time last_access_time, + bool secure, + bool http_only, + CookieSameSite same_site, + CookiePriority priority, + SetCookiesCallback callback) { scoped_refptr<SetCookieWithDetailsTask> task = new SetCookieWithDetailsTask( this, url, name, value, domain, path, creation_time, expiration_time, - last_access_time, secure, http_only, same_site, priority, callback); + last_access_time, secure, http_only, same_site, priority, + std::move(callback)); DoCookieTaskForURL(task, url); } -void CookieMonster::FlushStore(const base::Closure& callback) { +void CookieMonster::FlushStore(base::OnceClosure callback) { DCHECK(thread_checker_.CalledOnValidThread()); if (initialized_ && store_.get()) { if (channel_id_service_) { channel_id_service_->GetChannelIDStore()->Flush(); } - store_->Flush(callback); + store_->Flush(std::move(callback)); } else if (!callback.is_null()) { - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, + std::move(callback)); } } @@ -932,9 +937,9 @@ } void CookieMonster::SetAllCookiesAsync(const CookieList& list, - const SetCookiesCallback& callback) { + SetCookiesCallback callback) { scoped_refptr<SetAllCookiesTask> task = - new SetAllCookiesTask(this, list, callback); + new SetAllCookiesTask(this, list, std::move(callback)); DoCookieTask(task); } @@ -942,10 +947,11 @@ std::unique_ptr<CanonicalCookie> cookie, bool secure_source, bool modify_http_only, - const SetCookiesCallback& callback) { + SetCookiesCallback callback) { DCHECK(cookie->IsCanonical()); - scoped_refptr<SetCanonicalCookieTask> task = new SetCanonicalCookieTask( - this, std::move(cookie), secure_source, modify_http_only, callback); + scoped_refptr<SetCanonicalCookieTask> task = + new SetCanonicalCookieTask(this, std::move(cookie), secure_source, + modify_http_only, std::move(callback)); // TODO(rdsmith): Switch to DoCookieTaskForURL (or the equivalent). // This is tricky because we don't have the scheme in this routine @@ -954,23 +960,21 @@ DoCookieTask(task); } -void CookieMonster::SetCookieWithOptionsAsync( - const GURL& url, - const std::string& cookie_line, - const CookieOptions& options, - const SetCookiesCallback& callback) { - scoped_refptr<SetCookieWithOptionsTask> task = - new SetCookieWithOptionsTask(this, url, cookie_line, options, callback); +void CookieMonster::SetCookieWithOptionsAsync(const GURL& url, + const std::string& cookie_line, + const CookieOptions& options, + SetCookiesCallback callback) { + scoped_refptr<SetCookieWithOptionsTask> task = new SetCookieWithOptionsTask( + this, url, cookie_line, options, std::move(callback)); DoCookieTaskForURL(task, url); } -void CookieMonster::GetCookiesWithOptionsAsync( - const GURL& url, - const CookieOptions& options, - const GetCookiesCallback& callback) { +void CookieMonster::GetCookiesWithOptionsAsync(const GURL& url, + const CookieOptions& options, + GetCookiesCallback callback) { scoped_refptr<GetCookiesWithOptionsTask> task = - new GetCookiesWithOptionsTask(this, url, options, callback); + new GetCookiesWithOptionsTask(this, url, options, std::move(callback)); DoCookieTaskForURL(task, url); } @@ -978,42 +982,43 @@ void CookieMonster::GetCookieListWithOptionsAsync( const GURL& url, const CookieOptions& options, - const GetCookieListCallback& callback) { + GetCookieListCallback callback) { scoped_refptr<GetCookieListWithOptionsTask> task = - new GetCookieListWithOptionsTask(this, url, options, callback); + new GetCookieListWithOptionsTask(this, url, options, std::move(callback)); DoCookieTaskForURL(task, url); } -void CookieMonster::GetAllCookiesAsync(const GetCookieListCallback& callback) { - scoped_refptr<GetAllCookiesTask> task = new GetAllCookiesTask(this, callback); +void CookieMonster::GetAllCookiesAsync(GetCookieListCallback callback) { + scoped_refptr<GetAllCookiesTask> task = + new GetAllCookiesTask(this, std::move(callback)); DoCookieTask(task); } void CookieMonster::DeleteCookieAsync(const GURL& url, const std::string& cookie_name, - const base::Closure& callback) { + base::OnceClosure callback) { scoped_refptr<DeleteCookieTask> task = - new DeleteCookieTask(this, url, cookie_name, callback); + new DeleteCookieTask(this, url, cookie_name, std::move(callback)); DoCookieTaskForURL(task, url); } void CookieMonster::DeleteCanonicalCookieAsync(const CanonicalCookie& cookie, - const DeleteCallback& callback) { + DeleteCallback callback) { scoped_refptr<DeleteCanonicalCookieTask> task = - new DeleteCanonicalCookieTask(this, cookie, callback); + new DeleteCanonicalCookieTask(this, cookie, std::move(callback)); DoCookieTask(task); } -void CookieMonster::DeleteAllCreatedBetweenAsync( - const Time& delete_begin, - const Time& delete_end, - const DeleteCallback& callback) { +void CookieMonster::DeleteAllCreatedBetweenAsync(const Time& delete_begin, + const Time& delete_end, + DeleteCallback callback) { scoped_refptr<DeleteAllCreatedBetweenTask> task = - new DeleteAllCreatedBetweenTask(this, delete_begin, delete_end, callback); + new DeleteAllCreatedBetweenTask(this, delete_begin, delete_end, + std::move(callback)); DoCookieTask(task); } @@ -1022,21 +1027,21 @@ const Time& delete_begin, const Time& delete_end, const base::Callback<bool(const CanonicalCookie&)>& predicate, - const DeleteCallback& callback) { + DeleteCallback callback) { if (predicate.is_null()) { - callback.Run(0); + std::move(callback).Run(0); return; } scoped_refptr<DeleteAllCreatedBetweenWithPredicateTask> task = new DeleteAllCreatedBetweenWithPredicateTask( - this, delete_begin, delete_end, predicate, callback); + this, delete_begin, delete_end, predicate, std::move(callback)); DoCookieTask(task); } void CookieMonster::DeleteSessionCookiesAsync( - const CookieStore::DeleteCallback& callback) { + CookieStore::DeleteCallback callback) { scoped_refptr<DeleteSessionCookiesTask> task = - new DeleteSessionCookiesTask(this, callback); + new DeleteSessionCookiesTask(this, std::move(callback)); DoCookieTask(task); } @@ -2473,9 +2478,9 @@ FullDiffCookieSorter); } -void CookieMonster::RunCallback(const base::Closure& callback) { +void CookieMonster::RunCallback(base::OnceClosure callback) { DCHECK(thread_checker_.CalledOnValidThread()); - callback.Run(); + std::move(callback).Run(); } void CookieMonster::RunCookieChangedCallbacks(const CanonicalCookie& cookie,
diff --git a/net/cookies/cookie_monster.h b/net/cookies/cookie_monster.h index 9382e935..6d8a533 100644 --- a/net/cookies/cookie_monster.h +++ b/net/cookies/cookie_monster.h
@@ -155,14 +155,13 @@ // TODO(rdsmith, mmenke): Do not use this function; it is deprecated // and should be removed. // See https://codereview.chromium.org/2882063002/#msg64. - void SetAllCookiesAsync(const CookieList& list, - const SetCookiesCallback& callback); + void SetAllCookiesAsync(const CookieList& list, SetCookiesCallback callback); // CookieStore implementation. void SetCookieWithOptionsAsync(const GURL& url, const std::string& cookie_line, const CookieOptions& options, - const SetCookiesCallback& callback) override; + SetCookiesCallback callback) override; void SetCookieWithDetailsAsync(const GURL& url, const std::string& name, const std::string& value, @@ -175,34 +174,33 @@ bool http_only, CookieSameSite same_site, CookiePriority priority, - const SetCookiesCallback& callback) override; + SetCookiesCallback callback) override; void SetCanonicalCookieAsync(std::unique_ptr<CanonicalCookie> cookie, bool secure_source, bool modify_http_only, - const SetCookiesCallback& callback) override; + SetCookiesCallback callback) override; void GetCookiesWithOptionsAsync(const GURL& url, const CookieOptions& options, - const GetCookiesCallback& callback) override; - void GetCookieListWithOptionsAsync( - const GURL& url, - const CookieOptions& options, - const GetCookieListCallback& callback) override; - void GetAllCookiesAsync(const GetCookieListCallback& callback) override; + GetCookiesCallback callback) override; + void GetCookieListWithOptionsAsync(const GURL& url, + const CookieOptions& options, + GetCookieListCallback callback) override; + void GetAllCookiesAsync(GetCookieListCallback callback) override; void DeleteCookieAsync(const GURL& url, const std::string& cookie_name, - const base::Closure& callback) override; + base::OnceClosure callback) override; void DeleteCanonicalCookieAsync(const CanonicalCookie& cookie, - const DeleteCallback& callback) override; + DeleteCallback callback) override; void DeleteAllCreatedBetweenAsync(const base::Time& delete_begin, const base::Time& delete_end, - const DeleteCallback& callback) override; + DeleteCallback callback) override; void DeleteAllCreatedBetweenWithPredicateAsync( const base::Time& delete_begin, const base::Time& delete_end, const base::Callback<bool(const CanonicalCookie&)>& predicate, - const DeleteCallback& callback) override; - void DeleteSessionCookiesAsync(const DeleteCallback&) override; - void FlushStore(const base::Closure& callback) override; + DeleteCallback callback) override; + void DeleteSessionCookiesAsync(DeleteCallback) override; + void FlushStore(base::OnceClosure callback) override; void SetForceKeepSessionState() override; // Resets the list of cookieable schemes to the supplied schemes. Does @@ -667,7 +665,7 @@ // Runs the given callback. Used to avoid running callbacks after the store // has been destroyed. - void RunCallback(const base::Closure& callback); + void RunCallback(base::OnceClosure callback); // Run all cookie changed callbacks that are monitoring |cookie|. // |removed| is true if the cookie was deleted. @@ -825,7 +823,7 @@ // Flushes the store and posts |callback| when complete. |callback| may be // NULL. - virtual void Flush(const base::Closure& callback) = 0; + virtual void Flush(base::OnceClosure callback) = 0; protected: PersistentCookieStore() {}
diff --git a/net/cookies/cookie_monster_store_test.cc b/net/cookies/cookie_monster_store_test.cc index 36bafc6c..0f60e41 100644 --- a/net/cookies/cookie_monster_store_test.cc +++ b/net/cookies/cookie_monster_store_test.cc
@@ -87,9 +87,10 @@ commands_.push_back(CookieStoreCommand(CookieStoreCommand::REMOVE, cookie)); } -void MockPersistentCookieStore::Flush(const base::Closure& callback) { +void MockPersistentCookieStore::Flush(base::OnceClosure callback) { if (!callback.is_null()) - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, + std::move(callback)); } void MockPersistentCookieStore::SetForceKeepSessionState() { @@ -195,9 +196,10 @@ cookies_.erase(it); } -void MockSimplePersistentCookieStore::Flush(const base::Closure& callback) { +void MockSimplePersistentCookieStore::Flush(base::OnceClosure callback) { if (!callback.is_null()) - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, + std::move(callback)); } void MockSimplePersistentCookieStore::SetForceKeepSessionState() {
diff --git a/net/cookies/cookie_monster_store_test.h b/net/cookies/cookie_monster_store_test.h index 29b063f..816077b 100644 --- a/net/cookies/cookie_monster_store_test.h +++ b/net/cookies/cookie_monster_store_test.h
@@ -99,7 +99,7 @@ void DeleteCookie(const CanonicalCookie& cookie) override; - void Flush(const base::Closure& callback) override; + void Flush(base::OnceClosure callback) override; void SetForceKeepSessionState() override; @@ -174,7 +174,7 @@ void DeleteCookie(const CanonicalCookie& cookie) override; - void Flush(const base::Closure& callback) override; + void Flush(base::OnceClosure callback) override; void SetForceKeepSessionState() override;
diff --git a/net/cookies/cookie_monster_unittest.cc b/net/cookies/cookie_monster_unittest.cc index 6878898..aace43f 100644 --- a/net/cookies/cookie_monster_unittest.cc +++ b/net/cookies/cookie_monster_unittest.cc
@@ -59,9 +59,10 @@ MOCK_METHOD1(AddCookie, void(const CanonicalCookie& cc)); MOCK_METHOD1(UpdateCookieAccessTime, void(const CanonicalCookie& cc)); MOCK_METHOD1(DeleteCookie, void(const CanonicalCookie& cc)); - virtual void Flush(const base::Closure& callback) { + virtual void Flush(base::OnceClosure callback) { if (!callback.is_null()) - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, + std::move(callback)); } MOCK_METHOD0(SetForceKeepSessionState, void()); @@ -2455,10 +2456,10 @@ void DeleteCookie(const CanonicalCookie&) override {} void SetForceKeepSessionState() override {} - void Flush(const base::Closure& callback) override { + void Flush(base::OnceClosure callback) override { ++flush_count_; if (!callback.is_null()) - callback.Run(); + std::move(callback).Run(); } int flush_count() { return flush_count_; }
diff --git a/net/cookies/cookie_store.cc b/net/cookies/cookie_store.cc index 20f2dad..ffe939b 100644 --- a/net/cookies/cookie_store.cc +++ b/net/cookies/cookie_store.cc
@@ -48,23 +48,23 @@ return cookie_line; } -void CookieStore::DeleteAllAsync(const DeleteCallback& callback) { - DeleteAllCreatedBetweenAsync(base::Time(), base::Time::Max(), callback); +void CookieStore::DeleteAllAsync(DeleteCallback callback) { + DeleteAllCreatedBetweenAsync(base::Time(), base::Time::Max(), + std::move(callback)); } void CookieStore::SetForceKeepSessionState() { // By default, do nothing. } -void CookieStore::GetAllCookiesForURLAsync( - const GURL& url, - const GetCookieListCallback& callback) { +void CookieStore::GetAllCookiesForURLAsync(const GURL& url, + GetCookieListCallback callback) { CookieOptions options; options.set_include_httponly(); options.set_same_site_cookie_mode( CookieOptions::SameSiteCookieMode::INCLUDE_STRICT_AND_LAX); options.set_do_not_update_access_time(); - GetCookieListWithOptionsAsync(url, options, callback); + GetCookieListWithOptionsAsync(url, options, std::move(callback)); } void CookieStore::SetChannelIDServiceID(int id) {
diff --git a/net/cookies/cookie_store.h b/net/cookies/cookie_store.h index 931b2ea1..9ef7535 100644 --- a/net/cookies/cookie_store.h +++ b/net/cookies/cookie_store.h
@@ -64,10 +64,13 @@ static bool ChangeCauseIsDeletion(ChangeCause cause); // Callback definitions. - typedef base::Callback<void(const CookieList& cookies)> GetCookieListCallback; - typedef base::Callback<void(const std::string& cookie)> GetCookiesCallback; - typedef base::Callback<void(bool success)> SetCookiesCallback; - typedef base::Callback<void(int num_deleted)> DeleteCallback; + typedef base::OnceCallback<void(const CookieList& cookies)> + GetCookieListCallback; + typedef base::OnceCallback<void(const std::string& cookie)> + GetCookiesCallback; + typedef base::OnceCallback<void(bool success)> SetCookiesCallback; + typedef base::OnceCallback<void(int num_deleted)> DeleteCallback; + typedef base::Callback<void(const CanonicalCookie& cookie, ChangeCause cause)> CookieChangedCallback; typedef base::CallbackList<void(const CanonicalCookie& cookie, @@ -95,11 +98,10 @@ // Fails either if the cookie is invalid or if this is a non-HTTPONLY cookie // and it would overwrite an existing HTTPONLY cookie. // Returns true if the cookie is successfully set. - virtual void SetCookieWithOptionsAsync( - const GURL& url, - const std::string& cookie_line, - const CookieOptions& options, - const SetCookiesCallback& callback) = 0; + virtual void SetCookieWithOptionsAsync(const GURL& url, + const std::string& cookie_line, + const CookieOptions& options, + SetCookiesCallback callback) = 0; // Sets a cookie given explicit user-provided cookie attributes. The cookie // name, value, domain, etc. are each provided as separate strings. This @@ -112,20 +114,19 @@ // If |last_access_time| is null, it be set to |creation_time|. // // If unable to set a cookie, will invoke |callback| with false. - virtual void SetCookieWithDetailsAsync( - const GURL& url, - const std::string& name, - const std::string& value, - const std::string& domain, - const std::string& path, - base::Time creation_time, - base::Time expiration_time, - base::Time last_access_time, - bool secure, - bool http_only, - CookieSameSite same_site, - CookiePriority priority, - const SetCookiesCallback& callback) = 0; + virtual void SetCookieWithDetailsAsync(const GURL& url, + const std::string& name, + const std::string& value, + const std::string& domain, + const std::string& path, + base::Time creation_time, + base::Time expiration_time, + base::Time last_access_time, + bool secure, + bool http_only, + CookieSameSite same_site, + CookiePriority priority, + SetCookiesCallback callback) = 0; // TODO(rdsmith): Remove SetCookieWithDetailsAsync in favor of this. // Set the cookie on the cookie store. |cookie.IsCanonical()| must @@ -137,7 +138,7 @@ virtual void SetCanonicalCookieAsync(std::unique_ptr<CanonicalCookie> cookie, bool secure_source, bool modify_http_only, - const SetCookiesCallback& callback) = 0; + SetCookiesCallback callback) = 0; // TODO(???): what if the total size of all the cookies >4k, can we have a // header that big or do we need multiple Cookie: headers? @@ -152,10 +153,9 @@ // // TODO(mkwst): This method is deprecated; callsites should be updated to // use 'GetCookieListWithOptionsAsync'. - virtual void GetCookiesWithOptionsAsync( - const GURL& url, - const CookieOptions& options, - const GetCookiesCallback& callback) = 0; + virtual void GetCookiesWithOptionsAsync(const GURL& url, + const CookieOptions& options, + GetCookiesCallback callback) = 0; // Obtains a CookieList for the given |url| and |options|. The returned // cookies are passed into |callback|, ordered by longest path, then earliest @@ -163,7 +163,7 @@ virtual void GetCookieListWithOptionsAsync( const GURL& url, const CookieOptions& options, - const GetCookieListCallback& callback) = 0; + GetCookieListCallback callback) = 0; // Returns all cookies associated with |url|, including http-only, and // same-site cookies. The returned cookies are ordered by longest path, then @@ -173,30 +173,30 @@ // updating callsites to use 'GetCookieListWithOptionsAsync' with an explicit // CookieOptions, or by changing CookieOptions' defaults. void GetAllCookiesForURLAsync(const GURL& url, - const GetCookieListCallback& callback); + GetCookieListCallback callback); // Returns all the cookies, for use in management UI, etc. This does not mark // the cookies as having been accessed. The returned cookies are ordered by // longest path, then by earliest creation date. - virtual void GetAllCookiesAsync(const GetCookieListCallback& callback) = 0; + virtual void GetAllCookiesAsync(GetCookieListCallback callback) = 0; // Deletes all cookies that might apply to |url| that have |cookie_name|. virtual void DeleteCookieAsync(const GURL& url, const std::string& cookie_name, - const base::Closure& callback) = 0; + base::OnceClosure callback) = 0; // Deletes one specific cookie. |cookie| must have been returned by a previous // query on this CookieStore. Invokes |callback| with 1 if a cookie was // deleted, 0 otherwise. virtual void DeleteCanonicalCookieAsync(const CanonicalCookie& cookie, - const DeleteCallback& callback) = 0; + DeleteCallback callback) = 0; // Deletes all of the cookies that have a creation_date greater than or equal // to |delete_begin| and less than |delete_end| // Calls |callback| with the number of cookies deleted. virtual void DeleteAllCreatedBetweenAsync(const base::Time& delete_begin, const base::Time& delete_end, - const DeleteCallback& callback) = 0; + DeleteCallback callback) = 0; // Deletes all of the cookies that match the given predicate and that have a // creation_date greater than or equal to |delete_begin| and smaller than @@ -208,16 +208,16 @@ const base::Time& delete_begin, const base::Time& delete_end, const CookiePredicate& predicate, - const DeleteCallback& callback) = 0; + DeleteCallback callback) = 0; - virtual void DeleteSessionCookiesAsync(const DeleteCallback&) = 0; + virtual void DeleteSessionCookiesAsync(DeleteCallback) = 0; // Deletes all cookies in the store. - void DeleteAllAsync(const DeleteCallback& callback); + void DeleteAllAsync(DeleteCallback callback); // Flush the backing store (if any) to disk and post the given callback when // done. - virtual void FlushStore(const base::Closure& callback) = 0; + virtual void FlushStore(base::OnceClosure callback) = 0; // Protects session cookies from deletion on shutdown, if the underlying // CookieStore implemention is currently configured to store them to disk.
diff --git a/net/cookies/cookie_store_test_helpers.cc b/net/cookies/cookie_store_test_helpers.cc index d1c1ed5..3a1f349 100644 --- a/net/cookies/cookie_store_test_helpers.cc +++ b/net/cookies/cookie_store_test_helpers.cc
@@ -62,7 +62,7 @@ const GURL& url, const std::string& cookie_line, const CookieOptions& options, - const CookieMonster::SetCookiesCallback& callback) { + CookieMonster::SetCookiesCallback callback) { did_run_ = false; cookie_monster_->SetCookieWithOptionsAsync( url, cookie_line, options, @@ -70,8 +70,9 @@ base::Unretained(this))); DCHECK_EQ(did_run_, true); base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, base::Bind(&DelayedCookieMonster::InvokeSetCookiesCallback, - base::Unretained(this), callback), + FROM_HERE, + base::BindOnce(&DelayedCookieMonster::InvokeSetCookiesCallback, + base::Unretained(this), std::move(callback)), base::TimeDelta::FromMilliseconds(kDelayedTime)); } @@ -88,7 +89,7 @@ bool http_only, CookieSameSite same_site, CookiePriority priority, - const SetCookiesCallback& callback) { + SetCookiesCallback callback) { NOTREACHED(); } @@ -96,14 +97,14 @@ std::unique_ptr<CanonicalCookie> cookie, bool secure_source, bool modify_http_only, - const SetCookiesCallback& callback) { + SetCookiesCallback callback) { NOTREACHED(); } void DelayedCookieMonster::GetCookiesWithOptionsAsync( const GURL& url, const CookieOptions& options, - const CookieMonster::GetCookiesCallback& callback) { + CookieMonster::GetCookiesCallback callback) { did_run_ = false; cookie_monster_->GetCookiesWithOptionsAsync( url, options, @@ -112,15 +113,15 @@ DCHECK_EQ(did_run_, true); base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, - base::Bind(&DelayedCookieMonster::InvokeGetCookieStringCallback, - base::Unretained(this), callback), + base::BindOnce(&DelayedCookieMonster::InvokeGetCookieStringCallback, + base::Unretained(this), std::move(callback)), base::TimeDelta::FromMilliseconds(kDelayedTime)); } void DelayedCookieMonster::GetCookieListWithOptionsAsync( const GURL& url, const CookieOptions& options, - const CookieMonster::GetCookieListCallback& callback) { + CookieMonster::GetCookieListCallback callback) { did_run_ = false; cookie_monster_->GetCookieListWithOptionsAsync( url, options, @@ -129,32 +130,32 @@ base::Unretained(this))); DCHECK_EQ(did_run_, true); base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, base::Bind(&DelayedCookieMonster::InvokeGetCookieListCallback, - base::Unretained(this), callback), + FROM_HERE, + base::BindOnce(&DelayedCookieMonster::InvokeGetCookieListCallback, + base::Unretained(this), std::move(callback)), base::TimeDelta::FromMilliseconds(kDelayedTime)); } -void DelayedCookieMonster::GetAllCookiesAsync( - const GetCookieListCallback& callback) { - cookie_monster_->GetAllCookiesAsync(callback); +void DelayedCookieMonster::GetAllCookiesAsync(GetCookieListCallback callback) { + cookie_monster_->GetAllCookiesAsync(std::move(callback)); } void DelayedCookieMonster::InvokeSetCookiesCallback( - const CookieMonster::SetCookiesCallback& callback) { + CookieMonster::SetCookiesCallback callback) { if (!callback.is_null()) - callback.Run(result_); + std::move(callback).Run(result_); } void DelayedCookieMonster::InvokeGetCookieStringCallback( - const CookieMonster::GetCookiesCallback& callback) { + CookieMonster::GetCookiesCallback callback) { if (!callback.is_null()) - callback.Run(cookie_); + std::move(callback).Run(cookie_); } void DelayedCookieMonster::InvokeGetCookieListCallback( - const CookieMonster::GetCookieListCallback& callback) { + CookieMonster::GetCookieListCallback callback) { if (!callback.is_null()) - callback.Run(cookie_list_); + std::move(callback).Run(cookie_list_); } bool DelayedCookieMonster::SetCookieWithOptions( @@ -179,20 +180,20 @@ void DelayedCookieMonster::DeleteCookieAsync(const GURL& url, const std::string& cookie_name, - const base::Closure& callback) { + base::OnceClosure callback) { ADD_FAILURE(); } void DelayedCookieMonster::DeleteCanonicalCookieAsync( const CanonicalCookie& cookie, - const DeleteCallback& callback) { + DeleteCallback callback) { ADD_FAILURE(); } void DelayedCookieMonster::DeleteAllCreatedBetweenAsync( const base::Time& delete_begin, const base::Time& delete_end, - const DeleteCallback& callback) { + DeleteCallback callback) { ADD_FAILURE(); } @@ -200,15 +201,15 @@ const base::Time& delete_begin, const base::Time& delete_end, const base::Callback<bool(const CanonicalCookie&)>& predicate, - const DeleteCallback& callback) { + DeleteCallback callback) { ADD_FAILURE(); } -void DelayedCookieMonster::DeleteSessionCookiesAsync(const DeleteCallback&) { +void DelayedCookieMonster::DeleteSessionCookiesAsync(DeleteCallback) { ADD_FAILURE(); } -void DelayedCookieMonster::FlushStore(const base::Closure& callback) { +void DelayedCookieMonster::FlushStore(base::OnceClosure callback) { ADD_FAILURE(); }
diff --git a/net/cookies/cookie_store_test_helpers.h b/net/cookies/cookie_store_test_helpers.h index 7a9c34c..bd55a3d 100644 --- a/net/cookies/cookie_store_test_helpers.h +++ b/net/cookies/cookie_store_test_helpers.h
@@ -29,7 +29,7 @@ const GURL& url, const std::string& cookie_line, const CookieOptions& options, - const CookieMonster::SetCookiesCallback& callback) override; + CookieMonster::SetCookiesCallback callback) override; void SetCookieWithDetailsAsync(const GURL& url, const std::string& name, @@ -43,24 +43,23 @@ bool http_only, CookieSameSite same_site, CookiePriority priority, - const SetCookiesCallback& callback) override; + SetCookiesCallback callback) override; void SetCanonicalCookieAsync(std::unique_ptr<CanonicalCookie> cookie, bool secure_source, bool modify_http_only, - const SetCookiesCallback& callback) override; + SetCookiesCallback callback) override; void GetCookiesWithOptionsAsync( const GURL& url, const CookieOptions& options, - const CookieMonster::GetCookiesCallback& callback) override; + CookieMonster::GetCookiesCallback callback) override; - void GetCookieListWithOptionsAsync( - const GURL& url, - const CookieOptions& options, - const GetCookieListCallback& callback) override; + void GetCookieListWithOptionsAsync(const GURL& url, + const CookieOptions& options, + GetCookieListCallback callback) override; - void GetAllCookiesAsync(const GetCookieListCallback& callback) override; + void GetAllCookiesAsync(GetCookieListCallback callback) override; virtual bool SetCookieWithOptions(const GURL& url, const std::string& cookie_line, @@ -74,24 +73,24 @@ void DeleteCookieAsync(const GURL& url, const std::string& cookie_name, - const base::Closure& callback) override; + base::OnceClosure callback) override; void DeleteCanonicalCookieAsync(const CanonicalCookie& cookie, - const DeleteCallback& callback) override; + DeleteCallback callback) override; void DeleteAllCreatedBetweenAsync(const base::Time& delete_begin, const base::Time& delete_end, - const DeleteCallback& callback) override; + DeleteCallback callback) override; void DeleteAllCreatedBetweenWithPredicateAsync( const base::Time& delete_begin, const base::Time& delete_end, const base::Callback<bool(const CanonicalCookie&)>& predicate, - const DeleteCallback& callback) override; + DeleteCallback callback) override; - void DeleteSessionCookiesAsync(const DeleteCallback&) override; + void DeleteSessionCookiesAsync(DeleteCallback) override; - void FlushStore(const base::Closure& callback) override; + void FlushStore(base::OnceClosure callback) override; std::unique_ptr<CookieStore::CookieChangedSubscription> AddCallbackForCookie( const GURL& url, @@ -110,14 +109,13 @@ // Invoke the original callbacks. - void InvokeSetCookiesCallback( - const CookieMonster::SetCookiesCallback& callback); + void InvokeSetCookiesCallback(CookieMonster::SetCookiesCallback callback); void InvokeGetCookieStringCallback( - const CookieMonster::GetCookiesCallback& callback); + CookieMonster::GetCookiesCallback callback); void InvokeGetCookieListCallback( - const CookieMonster::GetCookieListCallback& callback); + CookieMonster::GetCookieListCallback callback); friend class base::RefCountedThreadSafe<DelayedCookieMonster>;
diff --git a/net/extras/sqlite/sqlite_persistent_cookie_store.cc b/net/extras/sqlite/sqlite_persistent_cookie_store.cc index 9d93a6452..5b6f2abf 100644 --- a/net/extras/sqlite/sqlite_persistent_cookie_store.cc +++ b/net/extras/sqlite/sqlite_persistent_cookie_store.cc
@@ -124,7 +124,7 @@ void DeleteCookie(const CanonicalCookie& cc); // Commit pending operations as soon as possible. - void Flush(const base::Closure& callback); + void Flush(base::OnceClosure callback); // Commit any pending operations and close the database. This must be called // before the object is destructed. @@ -182,7 +182,7 @@ // Flushes (Commits) pending operations on the background runner, and invokes // |callback| on the client thread when done. - void FlushAndNotifyInBackground(const base::Closure& callback); + void FlushAndNotifyInBackground(base::OnceClosure callback); // Sends notification when the entire store is loaded, and reports metrics // for the total time to load and aggregated results from any priority loads @@ -231,9 +231,9 @@ void KillDatabase(); void PostBackgroundTask(const tracked_objects::Location& origin, - const base::Closure& task); + base::OnceClosure task); void PostClientTask(const tracked_objects::Location& origin, - const base::Closure& task); + base::OnceClosure task); // Shared code between the different load strategies to be used after all // cookies have been loaded. @@ -546,10 +546,10 @@ } void SQLitePersistentCookieStore::Backend::FlushAndNotifyInBackground( - const base::Closure& callback) { + base::OnceClosure callback) { Commit(); if (!callback.is_null()) - PostClientTask(FROM_HERE, callback); + PostClientTask(FROM_HERE, std::move(callback)); } void SQLitePersistentCookieStore::Backend::CompleteLoadForKeyInForeground( @@ -1201,11 +1201,11 @@ succeeded ? 0 : 1, 2); } -void SQLitePersistentCookieStore::Backend::Flush( - const base::Closure& callback) { +void SQLitePersistentCookieStore::Backend::Flush(base::OnceClosure callback) { DCHECK(!background_task_runner_->RunsTasksInCurrentSequence()); - PostBackgroundTask(FROM_HERE, base::Bind(&Backend::FlushAndNotifyInBackground, - this, callback)); + PostBackgroundTask(FROM_HERE, + base::BindOnce(&Backend::FlushAndNotifyInBackground, this, + std::move(callback))); } // Fire off a close message to the background runner. We could still have a @@ -1342,8 +1342,8 @@ void SQLitePersistentCookieStore::Backend::PostBackgroundTask( const tracked_objects::Location& origin, - const base::Closure& task) { - if (!background_task_runner_->PostTask(origin, task)) { + base::OnceClosure task) { + if (!background_task_runner_->PostTask(origin, std::move(task))) { LOG(WARNING) << "Failed to post task from " << origin.ToString() << " to background_task_runner_."; } @@ -1351,8 +1351,8 @@ void SQLitePersistentCookieStore::Backend::PostClientTask( const tracked_objects::Location& origin, - const base::Closure& task) { - if (!client_task_runner_->PostTask(origin, task)) { + base::OnceClosure task) { + if (!client_task_runner_->PostTask(origin, std::move(task))) { LOG(WARNING) << "Failed to post task from " << origin.ToString() << " to client_task_runner_."; } @@ -1433,9 +1433,9 @@ // This store never discards session-only cookies, so this call has no effect. } -void SQLitePersistentCookieStore::Flush(const base::Closure& callback) { +void SQLitePersistentCookieStore::Flush(base::OnceClosure callback) { if (backend_) - backend_->Flush(callback); + backend_->Flush(std::move(callback)); } SQLitePersistentCookieStore::~SQLitePersistentCookieStore() {
diff --git a/net/extras/sqlite/sqlite_persistent_cookie_store.h b/net/extras/sqlite/sqlite_persistent_cookie_store.h index 6350457d..2335de8 100644 --- a/net/extras/sqlite/sqlite_persistent_cookie_store.h +++ b/net/extras/sqlite/sqlite_persistent_cookie_store.h
@@ -62,7 +62,7 @@ void UpdateCookieAccessTime(const CanonicalCookie& cc) override; void DeleteCookie(const CanonicalCookie& cc) override; void SetForceKeepSessionState() override; - void Flush(const base::Closure& callback) override; + void Flush(base::OnceClosure callback) override; private: ~SQLitePersistentCookieStore() override;
diff --git a/services/device/device_service.cc b/services/device/device_service.cc index f2a82c6..ca19aa5 100644 --- a/services/device/device_service.cc +++ b/services/device/device_service.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/bind.h" +#include "base/feature_list.h" #include "base/memory/ptr_util.h" #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" @@ -17,6 +18,7 @@ #include "mojo/public/cpp/system/message_pipe.h" #include "services/device/fingerprint/fingerprint.h" #include "services/device/power_monitor/power_monitor_message_broadcaster.h" +#include "services/device/public/cpp/device_features.h" #include "services/device/public/interfaces/battery_monitor.mojom.h" #include "services/device/time_zone_monitor/time_zone_monitor.h" #include "services/service_manager/public/cpp/bind_source_info.h" @@ -88,6 +90,8 @@ void DeviceService::OnStart() { registry_.AddInterface<mojom::Fingerprint>(base::Bind( &DeviceService::BindFingerprintRequest, base::Unretained(this))); + registry_.AddInterface<mojom::MotionSensor>(base::Bind( + &DeviceService::BindMotionSensorRequest, base::Unretained(this))); registry_.AddInterface<mojom::OrientationSensor>(base::Bind( &DeviceService::BindOrientationSensorRequest, base::Unretained(this))); registry_.AddInterface<mojom::OrientationAbsoluteSensor>( @@ -98,8 +102,10 @@ registry_.AddInterface<mojom::ScreenOrientationListener>( base::Bind(&DeviceService::BindScreenOrientationListenerRequest, base::Unretained(this))); - registry_.AddInterface<mojom::SensorProvider>(base::Bind( - &DeviceService::BindSensorProviderRequest, base::Unretained(this))); + if (base::FeatureList::IsEnabled(features::kGenericSensor)) { + registry_.AddInterface<mojom::SensorProvider>(base::Bind( + &DeviceService::BindSensorProviderRequest, base::Unretained(this))); + } registry_.AddInterface<mojom::TimeZoneMonitor>(base::Bind( &DeviceService::BindTimeZoneMonitorRequest, base::Unretained(this))); registry_.AddInterface<mojom::WakeLockProvider>(base::Bind( @@ -158,6 +164,23 @@ Fingerprint::Create(std::move(request)); } +void DeviceService::BindMotionSensorRequest( + const service_manager::BindSourceInfo& source_info, + mojom::MotionSensorRequest request) { +#if defined(OS_ANDROID) + // On Android the device sensors implementations need to run on the UI thread + // to communicate to Java. + DeviceMotionHost::Create(std::move(request)); +#else + // On platforms other than Android the device sensors implementations run on + // the IO thread. + if (io_task_runner_) { + io_task_runner_->PostTask(FROM_HERE, base::Bind(&DeviceMotionHost::Create, + base::Passed(&request))); + } +#endif // defined(OS_ANDROID) +} + void DeviceService::BindOrientationSensorRequest( const service_manager::BindSourceInfo& source_info, mojom::OrientationSensorRequest request) {
diff --git a/services/device/device_service.h b/services/device/device_service.h index 2e98031..69ddb654 100644 --- a/services/device/device_service.h +++ b/services/device/device_service.h
@@ -8,6 +8,7 @@ #include "base/memory/ref_counted.h" #include "device/generic_sensor/public/interfaces/sensor_provider.mojom.h" #include "device/screen_orientation/public/interfaces/screen_orientation.mojom.h" +#include "device/sensors/public/interfaces/motion.mojom.h" #include "device/sensors/public/interfaces/orientation.mojom.h" #include "device/wake_lock/public/interfaces/wake_lock_provider.mojom.h" #include "device/wake_lock/wake_lock_context.h" @@ -74,6 +75,10 @@ const service_manager::BindSourceInfo& source_info, mojom::FingerprintRequest request); + void BindMotionSensorRequest( + const service_manager::BindSourceInfo& source_info, + mojom::MotionSensorRequest request); + void BindOrientationSensorRequest( const service_manager::BindSourceInfo& source_info, mojom::OrientationSensorRequest request);
diff --git a/services/service_manager/background/background_service_manager.h b/services/service_manager/background/background_service_manager.h index d5292046..551f673 100644 --- a/services/service_manager/background/background_service_manager.h +++ b/services/service_manager/background/background_service_manager.h
@@ -11,15 +11,12 @@ #include "base/macros.h" #include "base/threading/thread.h" #include "base/values.h" +#include "build/build_config.h" #include "services/service_manager/public/cpp/identity.h" #include "services/service_manager/public/interfaces/connector.mojom.h" #include "services/service_manager/public/interfaces/service.mojom.h" #include "services/service_manager/runner/host/service_process_launcher_delegate.h" -#if !defined(OS_IOS) -#include "services/service_manager/runner/host/service_process_launcher.h" -#endif - namespace base { class SingleThreadTaskRunner; class WaitableEvent;
diff --git a/services/service_manager/service_manager.cc b/services/service_manager/service_manager.cc index abaabd5..1f9d3fd 100644 --- a/services/service_manager/service_manager.cc +++ b/services/service_manager/service_manager.cc
@@ -19,6 +19,7 @@ #include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/trace_event/trace_event.h" +#include "build/build_config.h" #include "mojo/public/cpp/bindings/associated_binding.h" #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding_set.h" @@ -36,6 +37,10 @@ #include "services/service_manager/public/interfaces/service_control.mojom.h" #include "services/service_manager/public/interfaces/service_manager.mojom.h" +#if !defined(OS_IOS) +#include "services/service_manager/runner/host/service_process_launcher.h" +#endif + namespace service_manager { namespace {
diff --git a/services/service_manager/service_manager.h b/services/service_manager/service_manager.h index 1547c33..2469c95e 100644 --- a/services/service_manager/service_manager.h +++ b/services/service_manager/service_manager.h
@@ -27,10 +27,6 @@ #include "services/service_manager/runner/host/service_process_launcher_factory.h" #include "services/service_manager/service_overrides.h" -#if !defined(OS_IOS) -#include "services/service_manager/runner/host/service_process_launcher.h" -#endif - namespace catalog { class ManifestProvider; }
diff --git a/testing/android/docs/junit4.md b/testing/android/docs/junit4.md index 89baaaa..719bbd9 100644 --- a/testing/android/docs/junit4.md +++ b/testing/android/docs/junit4.md
@@ -145,6 +145,25 @@ } ``` +## Command Line Flags + +In our Junit3 tests command line flags (set by the CommandLineFlag annotations) were inherited from the +test base classes. As an example, ChromeActivityTestBase is annotated with: + +```java +@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, ... +``` + +and as a result any test in a class derived from ChromeActivityTestBase will disable the first run experience. + +The Junit4 tests classes are not however, derived from test base classes; instead their behavior is defined by +test rules. To support this our Junit4 test runner will examine the command line flag annotations on all rules +referenced with @Rule annotations in the test class. In addition, where one rule is derived from another, the +command line flags propogate through the hierarchy of rules. See, for example, [BottomSheetTestRule][11] + +Note:- This has only recently been implemented, so is not yet used in all tests. See [this bug][12] + +The CommandLineFlags annonations are more fully documented in the [CommandLineFlags class][13] ## Common Errors @@ -263,3 +282,6 @@ [8]: http://junit.org/junit4/javadoc/4.12/org/junit/rules/RuleChain.html [9]: https://developer.android.com/reference/android/app/Instrumentation.html#runOnMainSync(java.lang.Runnable) [10]: https://developer.android.com/reference/android/support/test/rule/UiThreadTestRule.html#runOnUiThread(java.lang.Runnable) +[11]: /chrome/test/android/javatests/src/org/chromium/chrome/test/BottomSheetTestRule.java +[12]: https://bugs.chromium.org/p/chromium/issues/detail?id=734553 +[13]: /base/test/android/javatests/src/org/chromium/base/test/util/CommandLineFlags.java \ No newline at end of file
diff --git a/testing/buildbot/filters/fuchsia.base_unittests.filter b/testing/buildbot/filters/fuchsia.base_unittests.filter index 92502c7b..3cb4886ad 100644 --- a/testing/buildbot/filters/fuchsia.base_unittests.filter +++ b/testing/buildbot/filters/fuchsia.base_unittests.filter
@@ -206,6 +206,3 @@ -VerifyPathControlledByUserTest.OwnershipChecks -VerifyPathControlledByUserTest.Symlinks -VerifyPathControlledByUserTest.WriteBitChecks - -# https://crbug.com/734218 --MemoryPeakDetectorTest.StartStopQuickly
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-network-service b/third_party/WebKit/LayoutTests/FlagExpectations/enable-network-service index 7e1563b..0d399e3 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-network-service +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-network-service
@@ -13,6 +13,8 @@ Bug(none) battery-status/promise-with-eventlisteners.html [ Timeout ] Bug(none) battery-status/restricted-level-precision.html [ Timeout ] Bug(none) bluetooth/characteristic/characteristicProperties.html [ Timeout ] +Bug(none) bluetooth/characteristic/getDescriptor/gen-descriptor-get-same-object.html [ Timeout ] +Bug(none) bluetooth/characteristic/getDescriptors/gen-descriptor-get-same-object.html [ Timeout ] Bug(none) bluetooth/characteristic/notifications/gc-with-pending-start.html [ Timeout ] Bug(none) bluetooth/characteristic/readValue/add-multiple-event-listeners.html [ Timeout ] Bug(none) bluetooth/characteristic/readValue/event-is-fired.html [ Timeout ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 index 5b96653..08f695e 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
@@ -1024,7 +1024,6 @@ Bug(none) paint/invalidation/border-image-outset-add-repaint.html [ Failure ] Bug(none) paint/invalidation/border-image-outset-change-repaint.html [ Failure ] Bug(none) paint/invalidation/border-radius-repaint-2.html [ Failure ] -Bug(none) paint/invalidation/border-radius-repaint.html [ Failure ] Bug(none) paint/invalidation/border-repaint-glitch.html [ Failure ] Bug(none) paint/invalidation/box-sizing.html [ Failure ] Bug(none) paint/invalidation/bugzilla-5699.html [ Failure ] @@ -1061,7 +1060,6 @@ Bug(none) paint/invalidation/compositing/invalidate-when-leaving-squashed-layer.html [ Failure ] Bug(none) paint/invalidation/compositing/invalidation-for-subpixel-offset-of-squashed-layer.html [ Failure ] Bug(none) paint/invalidation/compositing/invalidations-on-composited-layers.html [ Failure ] -Bug(none) paint/invalidation/compositing/invalidations-with-large-negative-margin.html [ Failure ] Bug(none) paint/invalidation/compositing/new-stacking-context.html [ Failure ] Bug(none) paint/invalidation/compositing/newly-composited-on-scroll.html [ Failure ] Bug(none) paint/invalidation/compositing/newly-composited-repaint-rect.html [ Pass Failure ] @@ -1129,8 +1127,6 @@ Bug(none) paint/invalidation/fixed-child-move-after-scroll.html [ Failure ] Bug(none) paint/invalidation/fixed-child-of-fixed-move-after-scroll.html [ Failure ] Bug(none) paint/invalidation/fixed-child-of-transformed-move-after-scroll.html [ Failure ] -Bug(none) paint/invalidation/fixed-child-of-transformed-scrolled.html [ Failure ] -Bug(none) paint/invalidation/fixed-descendant-of-transformed-scrolled.html [ Failure ] Bug(none) paint/invalidation/fixed-element-repaint-after-compositing-update.html [ Failure ] Bug(none) paint/invalidation/fixed-img-src-change-after-scroll.html [ Failure ] Bug(none) paint/invalidation/fixed-move-after-scroll.html [ Failure ] @@ -1536,6 +1532,7 @@ crbug.com/644358 compositing/iframes/repaint-after-losing-scrollbars.html [ Failure ] crbug.com/644358 compositing/squashing/squashed-layer-loses-graphicslayer.html [ Failure ] crbug.com/644358 fast/canvas/canvas-composite-video-shadow.html [ Failure ] +crbug.com/644358 fast/canvas/imagebitmap/transferFromImageBitmap-no-alpha.html [ Failure ] crbug.com/644358 fast/css3-text/css3-text-decoration/repaint/repaint-text-decoration-style.html [ Failure ] crbug.com/644358 fast/forms/relayout-shifts-inner-editor.html [ Failure ] crbug.com/644358 images/color-profile-munsell-adobe-to-srgb.html [ Failure ] @@ -1545,9 +1542,6 @@ crbug.com/644358 paint/invalidation/multi-subsequence-scrolled.html [ Failure ] crbug.com/644358 paint/invalidation/repaint-subsequence-on-ancestor-clip-change.html [ Failure ] crbug.com/644358 paint/invalidation/svg/overflow-repaint.html [ Failure ] -crbug.com/644358 paint/invalidation/svg/svg-percent-scale-block.html [ Failure ] -crbug.com/644358 paint/invalidation/svg/svg-percent-scale-vonly.html [ Failure ] -crbug.com/644358 paint/invalidation/svg/svg-percent-scale.html [ Failure ] crbug.com/644358 paint/invalidation/table-collapsed-border.html [ Crash ] crbug.com/644358 paint/invalidation/table-cell-collapsed-border.html [ Crash ] crbug.com/644358 paint/invalidation/table/cached-change-cell-border-color.html [ Failure ] @@ -1558,7 +1552,6 @@ crbug.com/644358 paint/invalidation/table/cached-change-table-border-color.html [ Crash ] crbug.com/644358 paint/invalidation/table/cached-change-tbody-border-color.html [ Crash ] crbug.com/644358 paint/invalidation/table/collapsed-border-current-color.html [ Crash ] -crbug.com/644358 paint/invalidation/table/table-section-visual-overflow.html [ Failure ] crbug.com/644358 paint/invalidation/video-paint-invalidation.html [ Crash ] crbug.com/644358 svg/animations/animateMotion_changingPath.html [ Failure ] crbug.com/644358 svg/custom/object-current-scale.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/accessibility/aom-relation-properties.html b/third_party/WebKit/LayoutTests/accessibility/aom-relation-properties.html new file mode 100644 index 0000000..f9396af --- /dev/null +++ b/third_party/WebKit/LayoutTests/accessibility/aom-relation-properties.html
@@ -0,0 +1,76 @@ +<!DOCTYPE HTML> +<script src="../resources/gc.js"></script> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> + +<!-- + +Accessibility Object Model +Explainer: https://github.com/WICG/aom/blob/master/explainer.md +Spec: https://wicg.github.io/aom/spec/ + +--> + +<script> +test(function(t) { + assert_true(internals.runtimeFlags.accessibilityObjectModelEnabled); +}, "Make sure that Accessibility Object Model is enabled"); +</script> + +<div role="listbox" id="listbox" tabindex=0> + <div role="option" id="option1">Option 1</div> + <div role="option" id="option2">Option 2</div> + <div role="option" id="option3">Option 3</div> +</div> + +<script> +test(function(t) { + var listbox = document.getElementById("listbox"); + var option1 = document.getElementById("option1"); + listbox.focus(); + var axListbox = accessibilityController.accessibleElementById("listbox"); + var axOption1 = accessibilityController.accessibleElementById("option1"); + assert_false(axOption1.isSelected); + assert_equals(axListbox.ariaActiveDescendantElement(), undefined); + + listbox.accessibleNode.activeDescendant = option1.accessibleNode; + + assert_true(axListbox.ariaActiveDescendantElement().isEqual(axOption1)); + // Active Descendant also makes the option selected. + assert_true(axOption1.isSelected); +}, "AccessibleNode.activeDescendant"); +</script> + +<input id="input1"> +<div id="details">Details</div> + +<script> +test(function(t) { + var input1 = document.getElementById("input1"); + var details = document.getElementById("details"); + var axInput1 = accessibilityController.accessibleElementById("input1"); + var axDetails = accessibilityController.accessibleElementById("details"); + assert_equals(axInput1.ariaDetailsElement(), undefined); + + input1.accessibleNode.details = details.accessibleNode; + + assert_true(axInput1.ariaDetailsElement().isEqual(axDetails)); +}, "AccessibleNode.details"); +</script> + +<input id="input2"> +<div id="errorMessage">ErrorMessage</div> + +<script> +test(function(t) { + var input2 = document.getElementById("input2"); + var errorMessage = document.getElementById("errorMessage"); + var axInput2 = accessibilityController.accessibleElementById("input2"); + var axErrorMessage = accessibilityController.accessibleElementById("errorMessage"); + assert_equals(axInput2.ariaErrorMessageElement(), undefined); + + input2.accessibleNode.errorMessage = errorMessage.accessibleNode; + + assert_true(axInput2.ariaErrorMessageElement().isEqual(axErrorMessage)); +}, "AccessibleNode.errorMessage"); +</script>
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/accelerated-scrolling-with-clip-path-expected.png b/third_party/WebKit/LayoutTests/compositing/overflow/accelerated-scrolling-with-clip-path-expected.png index 31ce3d9..c68cd2b 100644 --- a/third_party/WebKit/LayoutTests/compositing/overflow/accelerated-scrolling-with-clip-path-expected.png +++ b/third_party/WebKit/LayoutTests/compositing/overflow/accelerated-scrolling-with-clip-path-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/compositing/text-on-scaled-surface-expected.html b/third_party/WebKit/LayoutTests/compositing/text-on-scaled-surface-expected.html deleted file mode 100644 index b67f858..0000000 --- a/third_party/WebKit/LayoutTests/compositing/text-on-scaled-surface-expected.html +++ /dev/null
@@ -1,19 +0,0 @@ -<!DOCTYPE html> -<html> -<script> -if (window.testRunner) { - testRunner.dumpAsTextWithPixelResults(); -} -</script> -<body style="overflow:hidden"> -<div style="-webkit-transform-origin: 0 0; transform:translate(50px,50px) scale(1.5); background: green; width:30em; height:8em;"> - <div style="-webkit-transform-origin: 0 0; transform:scale(1.5);"> - <!-- Use short lines of text to avoid accumulating error --> - Text on<br/> - a scaled<br/> - composited<br/> - layer<br/> - </div> -</div> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/compositing/text-on-scaled-surface-expected.txt b/third_party/WebKit/LayoutTests/compositing/text-on-scaled-surface-expected.txt new file mode 100644 index 0000000..e456258f --- /dev/null +++ b/third_party/WebKit/LayoutTests/compositing/text-on-scaled-surface-expected.txt
@@ -0,0 +1,5 @@ +Text on +a scaled +composited +layer +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid-1/test-plan/index.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid-1/test-plan/index.html new file mode 100644 index 0000000..039f3a87 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid-1/test-plan/index.html
@@ -0,0 +1,558 @@ +<!DOCTYPE html> +<html> + <head> + <title>CSS Grid Layout Module Level 1 Test Plan</title> + <meta http-equiv='Content-Type' content='text/html;charset=utf-8'/> + <!-- + === NOTA BENE === + For the three scripts below, if your spec resides on dev.w3 you can check them + out in the same tree and use relative links so that they'll work offline, + --> + <script src='http://www.w3.org/Tools/respec/respec-w3c-common' class='remove' async></script> + <script class='remove'> + var respecConfig = { + publishDate: "2015-07-10", + shortName: "css-grid-1-test-plan", + specStatus: "unofficial", + editors: [ + { + name: "Manuel Rego Casasnovas", mailto: "rego@igalia.com", + company: "Igalia, S.L.", companyURL: "http://www.igalia.com/" + }, + ], + testSuiteURI: "http://test.csswg.org/suites/css-grid-1_dev/nightly-unstable/", + }; + </script> + <style> + a.bibref, + #references dt { + text-transform: uppercase; + } + </style> + </head> + <body> + <section id='abstract'> + <p> + This document is intended to be used as a guideline for the testing + activities related to the CSS Grid Layout Level 1 spec + [[!css3-grid-layout]]. Its main goal is to provide an overview of the + general testing areas, possible caveats and testing aspects not + immediately apparent from the spec. Also, it provides a means of + tracking the progress of the CSS Grid Layout spec testing. + </p> + <p> + This document is not meant to replace the spec in determining the + normative and non-normative assertions to be tested, but rather + complement it. + </p> + </section> + + <section> + <h2>Introduction</h2> + <p> + As CSS moved away from the monolithic development of CSS 2.1 to the + modular development of CSS 3, the number of proposed new features and + the complexity of the layout landscape have increased dramatically. + While this directly translates to increased flexibility and agility in + adopting and implementing new CSS features, it also increases the + complexity of testing CSS features and the need for coordinating the + testing efforts. Also, the need for testing coordination increases as + crowd-sourcing efforts like + <a href="http://testthewebforward.org/" target="_blank">Test the Web + Forward</a> present people less familiar with the processes and + policies of the W3C with the opportunity to contribute new tests. + </p> + <p> + Except when defining new behaviors or redefining old behaviors, the + implicit assumption for new CSS modules is that they play nicely with + other modules or properties defined in CSS 2.1 [[!CSS21]]. As CSS Grid + Layout is a spec that touches many aspects of layout, styling and + CSSOM, it's not unreasonable to want to test the spec against these + implicit assumptions, too. + </p> + <p> + This testing strategy document is meant to complement the CSS Grid + Layout spec and the existing test suite by providing an overview of + the testing areas (especially the less apparent ones) and tracking + the progress of the testing activities against these test areas. + </p> + </section> + + <section> + <h2>Goals</h2> + <p> + To ensure a comprehensive test suite with useful, high quality tests, + a number of goals are proposed. They range from process goals (how to + conduct testing) to implementation goals (how to write good tests). + </p> + <section> + <h3>Enabling easy test contribution</h3> + <p> + An important vector in successfully testing CSS Grid Layout is to + enable easy test contributions, both from W3C partners and from + non-W3C members that wish to contribute. This is achieved by clearly + marking and explaining the areas that need testing, linking to + existing tests, and general testing progress. + </p> + </section> + <section> + <h3>Providing guidance on testing</h3> + <p> + In order to increase the quality of the test contributions, this + document offers a set of guidelines for conducting testing (see + <a href="#approach" class="sectionRef"></a>) and a testing progress + tracker to increase the surface coverage of tests (see + <a href="#test-progress-tracking" class="sectionRef"></a>). + </p> + </section> + <section> + <h3>Creating automation-friendly tests</h3> + <p> + In terms of actual tests produced for the CSS Grid Layout + specification, the main goal is to ensure that most tests are + automatable (i.e. they're either reftests or use + <code>testharness.js</code>). Even where manual tests are absolutely + necessary they should be written so that they can be easily + automated – as there are ongoing efforts to make WebDriver + [[webdriver]] automated tests a first class citizen in W3C testing. + This means that even if a manual test requires user interaction, + the validation or PASS/FAIL conditions should still be clear enough + as to allow automatic validation if said interaction is later + automated. + </p> + </section> + </section> + <section> + <h2>Approach</h2> + <p> + As spec testing cannot be realistically separated from testing a + particular implementation (except for the very simple cases), the + approach proposed for testing is one that tries to first cover as + many areas as possible, instead of deep diving on a certain + feature or aspect of the spec first. A side benefit of this + approach is that the spec tests can be used at any time to gauge + the level of support of a certain implementation. + </p> + <p> + Having this <em>breadth-first</em> approach in mind, tests will be + created for the testing areas listed in <a href="#testing-areas" + class="sectionRef"></a>. Testing will be done in multiple passes, + each aimed at covering more specific edge-cases. + </p> + </section> + <section> + <h2>Testing areas</h2> + <section> + <h3>Explicit testing areas</h3> + <p> + These are testing areas normatively defined by the spec. They cover + things explicitly or implicitly defined in the CSS Grid Layout spec. + Please note that while detailed, this list is not necessarily + exhaustive and normative behaviors may not be contained in it. + When in doubt, consult the CSS Grid Layout spec or ask a question on + the <a href="http://lists.w3.org/Archives/Public/www-style/">mailing + list</a> adding <kbd>[css-grid]</kbd> to the subject. + </p> + <section> + <h4>Grid Containers (<kbd>grid-model</kbd>)</h4> + <ul> + <li> + <code>grid</code> and <code>inline-grid</code> values for + <code>display</code> property + [<a href="https://github.com/w3c/csswg-test/issues/627">#627</a>]. + </li> + <li> + Grid container’s margins do not collapse with the margins of its + contents + [<a href="https://github.com/w3c/csswg-test/issues/661">#661</a>]. + </li> + <li> + <code>column-*</code> properties have no effect on a grid + container + [<a href="https://github.com/w3c/csswg-test/issues/628">#628</a>]. + </li> + <li> + <code>float</code> and <code>clear</code> have no effect on a + grid item + [<a href="https://github.com/w3c/csswg-test/issues/629">#629</a>]. + </li> + <li> + <code>float</code> affects to the computed value of display on + grid items + [<a href="https://github.com/w3c/csswg-test/issues/630">#630</a>]. + </li> + <li> + <code>vertical-align</code> has no effect on a grid item + [<a href="https://github.com/w3c/csswg-test/issues/631">#631</a>]. + </li> + <li> + <code>first-line</code> and <code>first-letter</code> do not + apply to grid containers + [<a href="https://github.com/w3c/csswg-test/issues/632">#632</a>]. + </li> + <li> + Sizing grid containers + [<a href="https://github.com/w3c/csswg-test/issues/638">#638</a>]. + </li> + </ul> + </section> + <section> + <h4>Grid Items (<kbd>grid-items</kbd>)</h4> + <ul> + <li> + Each child of a grid container becomes a grid item + [<a href="https://github.com/w3c/csswg-test/issues/639">#639</a>]. + </li> + <li> + Each contiguous run of text that is directly contained inside + grid container is wrapped in an anonymous grid item + [<a href="https://github.com/w3c/csswg-test/issues/640">#640</a>]. + </li> + <li> + <code>visibility</code> property. + <div class="note">Still undefined in the spec.</div> + </li> + <li> + <code>order</code> property + [<a href="https://github.com/w3c/csswg-test/issues/641">#641</a>]. + </li> + <li> + Static position + [<a href="https://github.com/w3c/csswg-test/issues/642">#642</a> + & + <a href="https://github.com/w3c/csswg-test/issues/643">#643</a>]. + </li> + <li> + Z-axis ordering: + <ul> + <li> + <code>z-index</code> property + [<a href="https://github.com/w3c/csswg-test/issues/677">#677</a>]. + </li> + </ul> + </li> + <li> + Minimum size of grid items + [<a href="https://github.com/w3c/csswg-test/issues/799">#799</a>]. + </li> + </ul> + </section> + <section> + <h4>The Explicit Grid (<kbd>grid-definition</kbd>)</h4> + <ul> + <li> + Track sizing: + <ul> + <li> + <code>grid-template-columns</code> and + <code>grid-template-rows</code> properties + [<a href="https://github.com/w3c/csswg-test/issues/644">#644</a>]. + </li> + <li> + <kbd><track-size></kbd>: <code>length</code>, + <code>percentage</code>, <code>max-content</code>, + <code>min-content</code>, <code>minmax(min, max)</code>, + <code>auto</code>. + </li> + <li> + Named grid lines (<kbd><custom-ident></kbd>) + [<a href="https://github.com/w3c/csswg-test/issues/645">#645</a>]. + </li> + <li> + <code>repeat()</code> notation + [<a href="https://github.com/w3c/csswg-test/issues/646">#646</a>]. + </li> + <li> + Flexible lengths: <code>fr</code> unit + [<a href="https://github.com/w3c/csswg-test/issues/647">#647</a>]. + </li> + <li> + <code>subgrid</code> keyword. + <div class="note">Subgrid feature is currently at-risk.</div> + </li> + <li> + Resolved values + [<a href="https://github.com/w3c/csswg-test/issues/648">#648</a>]. + </li> + </ul> + </li> + <li> + Named areas: + <ul> + <li> + <code>grid-template-areas</code> property + [<a href="https://github.com/w3c/csswg-test/issues/649">#649</a>]. + </li> + <li> + Implicit named grid lines + [<a href="https://github.com/w3c/csswg-test/issues/650">#650</a>]. + </li> + <li> + Implicit named areas + [<a href="https://github.com/w3c/csswg-test/issues/651">#651</a>]. + </li> + </ul> + </li> + <li> + Explicit grid shorthand: + <ul> + <li> + <code>grid-template</code> property + [<a href="https://github.com/w3c/csswg-test/issues/652">#652</a>]. + </li> + </ul> + </li> + </ul> + </section> + <section> + <h4>The Implicit Grid (<kbd>implicit-grids</kbd>)</h4> + <ul> + <li> + <code>grid-auto-rows</code> and <code>grid-auto-columns</code> + properties + [<a href="https://github.com/w3c/csswg-test/issues/662">#662</a>]. + </li> + <li> + <code>grid-auto-flow</code> property + [<a href="https://github.com/w3c/csswg-test/issues/663">#663</a>]. + </li> + </ul> + </section> + <section> + <h4>Grid Definition Shorthand (<kbd>grid-shorthand</kbd>)</h4> + <ul> + <li> + <code>grid</code> property + [<a href="https://github.com/w3c/csswg-test/issues/664">#664</a>]. + </li> + </ul> + </section> + <section> + <h4>Placing Grid Items (<kbd>placement</kbd>)</h4> + <ul> + <li> + Common patterns: + <ul> + <li> + Named areas + [<a href="https://github.com/w3c/csswg-test/issues/665">#665</a>]. + </li> + <li> + Numeric indexes and spans + [<a href="https://github.com/w3c/csswg-test/issues/666">#666</a>]. + </li> + <li> + Named lines and spans + [<a href="https://github.com/w3c/csswg-test/issues/667">#667</a>]. + </li> + <li> + Auto placement + [<a href="https://github.com/w3c/csswg-test/issues/668">#668</a>]. + </li> + <li> + Auto sizing siblings. + <div class="note">Subgrid feature is currently at-risk.</div> + </li> + </ul> + </li> + <li> + Line-based placement: + <ul> + <li> + <code>grid-row-start</code>, <code>grid-column-start</code>, + <code>grid-row-end</code> and <code>grid-column-end</code> + properties + [<a href="https://github.com/w3c/csswg-test/issues/669">#669</a>]. + </li> + <li> + Grid placement conflict handling + [<a href="https://github.com/w3c/csswg-test/issues/670">#670</a>]. + </li> + </ul> + </li> + <li> + Placement shorthands: + <ul> + <li> + <code>grid-column</code>, <code>grid-row</code> and + <code>grid-area</code> properties + [<a href="https://github.com/w3c/csswg-test/issues/671">#671</a>]. + </li> + </ul> + </li> + <li> + Absolutely-positioned grid items + [<a href="https://github.com/w3c/csswg-test/issues/672">#672</a>]. + </li> + <li> + Grid item placement algorithm + [<a href="https://github.com/w3c/csswg-test/issues/683">#683</a>]. + </li> + </ul> + </section> + <section> + <h4>Alignment (<kbd>alignment</kbd>)</h4> + <ul> + <li> + Aligning with auto margins + [<a href="https://github.com/w3c/csswg-test/issues/673">#673</a>]. + </li> + <li> + Row-axis alignment: + <ul> + <li> + <code>justify-self</code> and <code>justify-items</code> + properties. + [<a href="https://github.com/w3c/csswg-test/issues/674">#674</a>]. + </li> + </ul> + </li> + <li> + Column-axis alignment: + <ul> + <li> + <code>align-self</code> and <code>align-items</code> + properties + [<a href="https://github.com/w3c/csswg-test/issues/675">#675</a>]. + </li> + </ul> + </li> + <li> + Aligning the grid: + <ul> + <li> + <code>justify-content</code> and <code>align-content</code> + properties + [<a href="https://github.com/w3c/csswg-test/issues/676">#676</a>]. + </li> + </ul> + </li> + <li> + Grid baselines + [<a href="https://github.com/w3c/csswg-test/issues/678">#678</a>]. + </li> + </ul> + </section> + <section> + <h4>Track Sizing Algorithm (<kbd>layout-algorithm</kbd>)</h4> + <ul> + <li> + Content-based track sizing + [<a href="https://github.com/w3c/csswg-test/issues/679">#679</a>]. + </li> + <li> + Grow tracks using free space + [<a href="https://github.com/w3c/csswg-test/issues/680">#680</a>]. + </li> + <li> + Flexible tracks + [<a href="https://github.com/w3c/csswg-test/issues/681">#681</a>]. + </li> + </ul> + </section> + <section> + <h4>Fragmenting Grid Layout (<kbd>pagination</kbd>)</h4> + <ul> + <li> + Fragmentation algorithm + [<a href="https://github.com/w3c/csswg-test/issues/682">#682</a>]. + </li> + </ul> + </section> + </section> + <section> + <h3>Specification examples</h3> + <p> + The spec examples should become tests (maybe some of them need to be + defined as manual tests). This will allow to increase the coverage + with more tests, but also to check the spec itself. + </p> + </section> + <section> + <h3>Implicit testing areas</h3> + <p> + These are testing areas either normatively defined in other specs + that explicitly refer to the CSS Grid Layout spec or simply not + explicitly defined, but implied by various aspects of the spec. + Please note that while detailed, this list is not necessarily + exhaustive and normative behaviors may not be contained in it. When + in doubt, consult the CSS Grid Layout spec or ask a question on the + <a href="http://lists.w3.org/Archives/Public/www-style/">mailing + list</a> adding <kbd>[css-grid]</kbd> to the subject. + </p> + <p> + Below is the list of implicit testing areas: + </p> + <ul> + <li> + CSS Grid Layout and other layout models: + <ul> + <li>Floats [[!CSS21]].</li> + <li>Positioned elements [[!css3-positioning]].</li> + <li>CSS Flexbox [[!css3-flexbox]].</li> + <li>CSS Multicolumn [[!css3-multicol]].</li> + <li>CSS Regions [[!css3-regions]].</li> + <li>CSS Shapes [[!css-shapes-1]].</li> + </ul> + </li> + <li> + CSS Grid Layout and different type of elements [[!html5]]: + <ul> + <li><code>img</code>.</li> + <li><code>video</code>.</li> + <li><code>iframe</code>.</li> + <li><code>canvas</code>.</li> + <li><code>table</code>.</li> + </ul> + </li> + <li> + Dynamic content: + <ul> + <li>Changing the content of the grid items at runtime.</li> + <li> + Interactive content <code>contentEditable</code>, + <code>designMode</code> and input elements [[!html5]]. + </li> + </ul> + </li> + <li>Writing modes [[!css3-writing-modes]].</li> + <li>Transforms [[!css3-transforms]].</li> + <li> + Transitions [[!css3-transitions]] and animations + [[!css3-animations]]. + </li> + <li>Pseudo-elements in grid items [[!CSS21]].</li> + </ul> + </section> + </section> + <section> + <h2>People and responsibilities</h2> + <p> + Below is a list of people you should reach out to if you have any + questions related to this document or testing CSS Grid Layout in + general: + </p> + <ul> + <li>Manuel Rego – Test Coordinator for CSS Grid Layout</li> + </ul> + </section> + <section> + <h2>Test progress tracking</h2> + <p> + Currently test progress tracking is done via GitHub + <a href="https://github.com/w3c/csswg-test/issues?labels=spec%3Agrid&milestone=&page=1&state=open"> + milestones and issues</a>. + <!-- + FIXME: This link doesn't work yet. + TODO: + * Label "spec:grid" has to be created + (https://github.com/w3c/csswg-test/labels) + * Milestone "css-grid-1_dev" has to be created + https://github.com/w3c/csswg-test/milestones + * Once issues are created, add references from the different + sections. + --> + </p> + </section> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-shapes-1/test-plan/index.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-shapes-1/test-plan/index.html new file mode 100644 index 0000000..ed3590ce --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-shapes-1/test-plan/index.html
@@ -0,0 +1,446 @@ +<!DOCTYPE html> +<html> + <head> + <title>CSS Shapes Level 1 Test Plan</title> + <meta http-equiv='Content-Type' content='text/html;charset=utf-8'/> + <!-- + === NOTA BENE === + For the three scripts below, if your spec resides on dev.w3 you can check them + out in the same tree and use relative links so that they'll work offline, + --> + <script src='http://www.w3.org/Tools/respec/respec-w3c-common' class='remove' async></script> + <script class='remove'> + var respecConfig = { + specStatus: "unofficial", + shortName: "css-shapes-1-test-plan", + editors: [ + { + name: "Rebecca Hauck", mailto: "rhauck@adobe.com", + company: "Adobe Systems, Inc.", companyURL: "http://www.adobe.com/" + }, + ], + testSuiteURI: "http://test.csswg.org/suites/css3-shapes/nightly-unstable/", + }; + </script> + <style> + a.bibref, + #references dt { + text-transform: uppercase; + } + </style> + </head> + <body> + <section id='abstract'> + <p> + This document is intended to be used as a guideline for the testing + activities related to the CSS Shapes Level 1 spec [[!css-shapes-1]]. Its main + goal is to provide an overview of the general testing areas, possible + caveats and testing aspects not immediately apparent from the spec. + Also, it provides a means of tracking the progress of the CSS Shapes + spec testing. + </p> + <p> + This document is not meant to replace the spec in determining the + normative and non-normative assertions to be tested, but rather + complement it. + </p> + </section> + + <section> + <h2>Goals</h2> + <p> + To ensure a comprehensive test suite with useful, high quality tests, a + number of goals are proposed. They range from process goals (how to + conduct testing) to implementation goals (how to write good tests). + </p> + <section> + <h3>Enabling easy test contribution</h3> + <p> + An important vector in successfully testing CSS Shapes is to + enable easy test contributions, both from W3C partners and from + non-W3C members that wish to contribute. This is achieved by clearly + marking and explaining the areas that need testing, linking to existing + tests, and general testing progress. + </p> + </section> + <section> + <h3>Providing guidance on testing</h3> + <p> + In order to increase the quality of the test contributions, this + document offers a set of guidelines for conducting testing (see + <a href="#approach" class="sectionRef"></a>) and a testing progress + tracker to increase the surface coverage of tests (see + <a href="#test-progress-tracking" class="sectionRef"></a>). + </p> + </section> + <section> + <h3>Creating automation-friendly tests</h3> + <p> + In terms of actual tests produced for the CSS Shapes specification, the main goal + is to ensure that most tests are automatable (i.e. they're either + reftests or use <code>testharness.js</code>). Even where manual tests + are absolutely necessary they should be written so that they can be + easily automated – as there are ongoing efforts to make + WebDriver [[webdriver]] automated tests a first class citizen in W3C + testing. This means that even if a manual test requires user + interaction, the validation or PASS/FAIL conditions should still be + clear enough as to allow automatic validation if said interaction is + later automated. + </p> + </section> + </section> + <section> + <h2>Approach</h2> + <p> + Since the CSS Shapes Level 1 spec introduces only three new CSS properties, + the approach is to deep dive into every aspect of the spec as much as possible. + + Tests will be created for the testing areas listed in <a href="#testing-areas" class="sectionRef"></a>. + </p> + </section> + <section> + <h2>Testing areas</h2> + <section> + <h3>Explicit testing areas</h3> + <p> + These are testing areas normatively defined by the spec. They cover + things explicitly or implicitly defined in the CSS Shapes spec. + Please note that while detailed, this list is not necessarily + exhaustive and normative behaviors may not be contained in it. + When in doubt, consult the CSS Shapes spec or ask a question on the + <a href="http://lists.w3.org/Archives/Public/www-style/">mailing + list</a>. + </p> + <p> + <section> + <h4>Proper parsing of the CSS properties and values according to the spec</h4> + <p class=note> + Note: For all of the tests below, where length parameters are tested, + the supported <a class="production css-code" data-link-type=type href=http://www.w3.org/TR/css3-values/#lengths title="<length>"><length></a> + units defined in the CSS Values & Units [[!CSS3VAL]] specification, but not all permutations will not be + tested. Instead, a sampling of these units will be used across the parsing and layout tests. + </p> + <ul> + <li> + <code>shape-outside</code> + <ul> + <li>none</li> + <li> + <code><basic-shape></code> + <ul> + <li> + <code>inset()</code> + <ul> + <li>0-4 arguments</li> + <li>length units</li> + <li>percentages</li> + <li>positive/negative lengths</li> + <li>decimal/non-decimal lengths</li> + <li>calc() lengths</li> + <li>no unit or %</li> + <li>commas / no commas</li> + <li>invalid arg values</li> + <li><code>round</code> keyword + <ul> + <li><code><border-radius></code> + <ul> + <li>0-8 arguments</li> + <li>position of '/'</li> + <li>length units</li> + <li>percentages</li> + <li>positive/negative lengths</li> + <li>decimal/non-decimal lengths</li> + <li>calc() lengths</li> + <li>no unit or %</li> + <li>commas / no commas</li> + <li>invalid values</li> + </ul> + </li> + </ul> + </li> + </ul> + </li> + <li><code>circle()</code> + <ul> + <li><code><shape-radius></code> + <ul> + <li>0-1 args (valid), 2 args (invalid)</li> + <li>length units</li> + <li>percentages</li> + <li>positive/negative lengths</li> + <li>decimal/non-decimal lengths</li> + <li>calc() lengths</li> + <li>no unit or %</li> + <li>commas / no commas</li> + <li>invalid arg values</li> + <li><code>closest-side, farthest-side</code> keywords</li> + </ul> + </li> + <li><code>at</code> keyword + <ul> + <li><code><position></code> + <ul> + <li>0-4 arguments</li> + <li>length units</li> + <li>percentages</li> + <li>positive/negative lengths</li> + <li>decimal/non-decimal lengths</li> + <li>calc() lengths</li> + <li>no unit or %</li> + <li>commas / no commas</li> + <li>invalid values</li> + <li><code>top, left, bottom, right</code> keywords</li> + </ul> + </li> + </ul> + </li> + </ul> + </li> + <li><code>ellipse()</code> + <ul> + <li><code><shape-radius></code> + <ul> + <li>0-2 args (valid), 3 args (invalid)</li> + <li><i>Plus all of the same shape-radius tests listed above for circle()</i></li> + </ul> + </li> + <li><i>Plus all of the <code>at <position></code> tests listed above for circle()</i></li> + </ul> + </li> + <li><code>polygon()</code> + <li><code><shape-arg></code>'s + <ul> + <li>1-6 vertices (valid), 0 vertices (invalid)</li> + <li>length units</li> + <li>percentages</li> + <li>positive/negative lengths</li> + <li>decimal/non-decimal lengths</li> + <li>calc() lengths</li> + <li>no unit or %</li> + <li>commas / no commas</li> + <li>invalid arg values</li> + </ul> + <li><code><fill-rule></code> + <ul> + <li><code>not specified (default: nonzero)</code></li> + <li><code>nonzero</code></li> + <li><code>evenodd</code></li> + <li>invalid values</li> + </ul> + </li> + </li> + </ul> + </li> + <li><code><box></code> + <ul> + <li><code>margin-box</code></li> + <li><code>border-box</code></li> + <li><code>padding-box</code></li> + <li><code>content-box</code></li> + </ul> + </li> + <li><code><basic-shape> + <box></code> + <ul> + <li>A sampling of the tests above combined together to test basic-shape with shape-box</li> + </ul> + </li> + <li><code><image></code></li> + </ul> + </li> + <li><code>shape-margin</code> + <ul> + <li>length units</li> + <li>percentages</li> + <li>positive/negative lengths</li> + <li>decimal/non-decimal lengths</li> + <li>calc() lengths</li> + <li>no unit or %</li> + <li>invalid values</li> + </ul> + </li> + <li><code>shape-image-threshold</code> + <ul> + <li>decimal - 0-5 places</li> + <li>no decimal</li> + <li>percentage (invalid)</li> + <li>positive/negative values</li> + <li>decimal/non-decimal lengths</li> + <li>calc() lengths</li> + <li>+ / - signs</li> + <li>invalid values</li> + </ul> + </li> + </ul> + </section> + <section> + <h4>Proper serialization of the CSS properties and values according to the spec</h4> + <ul> + <li><code><position></code> values in <code>circle</code> and <code>ellipse</code> serialize to 2- and 4-value forms + <ul> + <li><code>top, left, bottom, right</code> serialize to percentages</li> + <li>omitting radii omits radii from serialization</li> + </ul> + </li> + <li><code>inset</code> serialized shape-args omit args when possible</li> + <li><code><round></code> values in <code>inset</code> serialize to as few as possible</li> + <li>unspecified <code><fill-rule></code> serializes <code>nonzero</code></li> + <li>0% is preferred over zero length</li> + <li>calc() is avoided</li> + </ul> + </section> + <section> + <h4>Proper computed values of the CSS properties and values according to the spec</h4> + <ul> + <li>lengths compute to px</li> + <li>percentages keep %</li> + <li>calc() preserved</li> + </ul> + </section> + <section> + <h4>Proper rendering & layout of text around shapes according to the spec</h4> + <ul> + <li>Basic Shapes + <ul> + <li>inset + <ul> + <li>square corners</li> + <li>rounded corners</li> + <li>rounded corners to make circles & ellipses</li> + </ul> + </li> + <li>circle, ellipse + <ul> + <li>explicit/implicit radii</li> + <li>explicit/implicit position</li> + <li>closest-side / farthest-side</li> + </ul> + </li> + <li>polygon + <ul> + <li>relative/absolute units</li> + <li>fill-rule: evenodd/nonzero</li> + </ul> + </li> + <li>float left / right</li> + <li>shape-margin</li> + <li>shape-box</code> + <ul> + <li>unspecified</li> + <li>specified: + <ul> + <li>margin-box</li> + <li>border-box</li> + <li>padding-box</li> + <li>content-box</li> + </ul> + </li> + </ul> + </li> + </ul> + </li> + <li>Shapes from Box Values + <ul> + <li>margin-box, border-box, padding-box, content-box</li> + <li>all, top, left, bottom, right, top-left, top-bottom, top-right, left-right, left-bottom, right-bottom</li> + <li>float left / right</li> + <li>border-radius</li> + </ul> + </li> + <li>Shapes from Images + <ul> + <li>url + <ul> + <li>png, svg, gif, jpeg</li> + <li>transparency/no transparency</li> + </ul> + </li> + <li>image-list + <ul> + <li>png, svg, gif, jpeg</li> + <li>transparency/no transparency</li> + </ul> + </li> + <li>gradient + <ul> + <li>linear</li> + <li>radial</li> + <li>repeating</li> + </ul> + </li> + <li>float left / right</li> + <li>shape-margin</li> + <li>shape-image-threshold</li> + </ul> + </li> + <li>Float Tests + <ul> + <li>Float stacking</li> + <li>Line boxes affected by both float right and float left shapes at the same time</li> + <li>Empty float areas</li> + <li>Shapes that extend past the margin box edge</li> + </ul> + </li> + </ul> + </li> + </section> + </section> + <section> + <h3>Implicit testing areas</h3> + <p> + These are testing areas either normatively defined in other specs + that are explicitly referred to in the CSS Shapes spec. Additionally, the + CSS Shapes spec is explicitly referred to by other specs. Please note that + while detailed, this list is not necessarily exhaustive and normative behaviors + may not be contained in it. When in doubt, consult the CSS Regions spec or ask + a question on the <a href="http://lists.w3.org/Archives/Public/www-style/">mailing list</a>. + </p> + <p> + Below is the list of implicit testing areas: + <ul> + <li>CSS 2.1 [[!CSS21]]</li> + <li>CSS Box Model [[!CSS3BOX]]</li> + <li>CSS Values & Units [[!CSS3VAL]]</li> + <li>CSS Backgrounds & Borders [[!CSS3BG]]</li> + <li>HTML5 [[!HTML5]]</li> + <li>CSS Masking [[CSS-MASKING]]</li> + <li>CSS Exclusions [[CSS-EXCLUSIONS]]</li> + </ul> + </p> + </section> + <section> + <h3>Interactions with other CSS features & specifications</h3> + <p>When the CSS Shapes spec has a full suite of tests covering the behaviors defined in the spec, + additional tests will be needed to assure that the implementation works properly with other + CSS features defined in other specifications. + </p> + <p>Below is a list of features that should work properly with CSS Shapes:</p> + <ul> + <li>CSS Transforms</li> + <li>CSS Transitions</li> + <li>CSS Animations</li> + <li>CSS Exclusions</li> + <li>CSS Writing Modes - when the float and container have different 'writing-mode' and 'direction' properties</li> + </ul> + </section> + <section> + <h2>People and responsibilities</h2> + <p> + Below is a list of people you should reach out to if you have any + questions related to this document or testing CSS Shapes in general: + <ul> + <li>Alan Stearns – Editor for CSS Shapes spec</li> + <li>Rebecca Hauck – Test Coordinator for CSS Regions</li> + </ul> + </p> + </section> + <section> + <h2>Test progress tracking</h2> + <p> + Currently test progress tracking is done via gitHub + <a href="https://github.com/w3c/csswg-test/issues?labels=spec%3Ashapes&milestone=&page=1&state=open">milestones + and issues</a>. + <!-- FIXME: Add more details once issues were created for all test areas. --> + </p> + </section> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/figure-over_and_under-fail.svg b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/figure-over_and_under-fail.svg new file mode 100644 index 0000000..76b48499 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/figure-over_and_under-fail.svg
@@ -0,0 +1,4 @@ +<?xml version="1.0" standalone="yes"?> + +<svg version="1.1" viewBox="0.0 0.0 400.0 240.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l400.0 0l0 240.0l-400.0 0l0 -240.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l400.0 0l0 240.0l-400.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m24.0 200.0l192.0 0l0 16.0l-192.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m24.0 24.0l192.0 0l0 16.0l-192.0 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m216.0 63.244095l102.39371 0l0 113.51181l-102.39371 0z" fill-rule="nonzero"></path><path fill="#000000" d="m262.19684 107.549995q10.0 7.8125 17.1875 16.5625l-6.5625 6.8749924q-7.8125 -9.687492 -16.874985 -18.124992l6.2499847 -5.3125z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m107.43044 63.244095l102.3937 0l0 113.51181l-102.3937 0z" fill-rule="nonzero"></path><path fill="#000000" d="m153.62729 107.549995q10.0 7.8125 17.1875 16.5625l-6.5625 6.8749924q-7.8125 -9.687492 -16.875 -18.124992l6.25 -5.3125z" fill-rule="nonzero"></path></g></svg> +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/figure-over_and_under-pass.svg b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/figure-over_and_under-pass.svg new file mode 100644 index 0000000..fe247161 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/figure-over_and_under-pass.svg
@@ -0,0 +1,4 @@ +<?xml version="1.0" standalone="yes"?> + +<svg version="1.1" viewBox="0.0 0.0 400.0 240.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l400.0 0l0 240.0l-400.0 0l0 -240.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l400.0 0l0 240.0l-400.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m24.0 200.0l192.0 0l0 16.0l-192.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m24.0 24.0l192.0 0l0 16.0l-192.0 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m216.0 63.244095l102.39371 0l0 113.51181l-102.39371 0z" fill-rule="nonzero"></path><path fill="#000000" d="m262.19684 107.549995q10.0 7.8125 17.1875 16.5625l-6.5625 6.8749924q-7.8125 -9.687492 -16.874985 -18.124992l6.2499847 -5.3125z" fill-rule="nonzero"></path></g></svg> +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/figure-rendering-tcu.svg b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/figure-rendering-tcu.svg new file mode 100644 index 0000000..5b03e426 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/figure-rendering-tcu.svg
@@ -0,0 +1,4 @@ +<?xml version="1.0" standalone="yes"?> + +<svg version="1.1" viewBox="0.0 0.0 960.0 720.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l960.0 0l0 720.0l-960.0 0l0 -720.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l960.0 0l0 720.0l-960.0 0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m63.885353 13.473236l115.87162 0l0 115.87163l-115.87162 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m63.885353 13.473236l115.87162 0l0 115.87163l-115.87162 0z" fill-rule="nonzero"></path><path fill="#000000" d="m110.18054 88.489044l9.09375 -12.9375l-8.421875 -11.953125l5.28125 0l3.8125 5.828125q1.078125 1.671875 1.734375 2.796875q1.03125 -1.546875 1.90625 -2.75l4.1875 -5.875l5.046875 0l-8.609375 11.71875l9.265625 13.171875l-5.1875 0l-5.109375 -7.734375l-1.359375 -2.09375l-6.53125 9.828125l-5.109375 0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m224.5116 13.472183l115.880615 0l0 115.880615l-115.880615 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m224.5116 13.472183l115.880615 0l0 115.880615l-115.880615 0z" fill-rule="nonzero"></path><path fill="#000000" d="m286.99487 88.492485l-4.21875 0l0 -26.890625q-1.53125 1.453125 -4.0 2.90625q-2.46875 1.453125 -4.4375 2.1875l0 -4.078125q3.53125 -1.671875 6.171875 -4.03125q2.65625 -2.375 3.765625 -4.59375l2.71875 0l0 34.5z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m224.5116 129.3528l115.880615 0l0 115.8806l-115.880615 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m224.5116 129.3528l115.880615 0l0 115.8806l-115.880615 0z" fill-rule="nonzero"></path><path fill="#000000" d="m293.27612 200.3106l0 4.0625l-22.71875 0q-0.046875 -1.53125 0.5 -2.9375q0.859375 -2.3125 2.765625 -4.5625q1.921875 -2.25 5.53125 -5.203125q5.59375 -4.59375 7.5625 -7.28125q1.96875 -2.6875 1.96875 -5.078125q0 -2.5 -1.796875 -4.21875q-1.78125 -1.734375 -4.671875 -1.734375q-3.046875 0 -4.875 1.828125q-1.828125 1.828125 -1.84375 5.0625l-4.34375 -0.4375q0.453125 -4.859375 3.359375 -7.390625q2.90625 -2.546875 7.796875 -2.546875q4.953125 0 7.828125 2.75q2.890625 2.734375 2.890625 6.78125q0 2.0625 -0.84375 4.0625q-0.84375 1.984375 -2.8125 4.1875q-1.953125 2.203125 -6.5 6.046875q-3.796875 3.1875 -4.875 4.328125q-1.078125 1.140625 -1.78125 2.28125l16.859375 0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m224.5116 245.2334l115.880615 0l0 115.880615l-115.880615 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m224.5116 245.2334l115.880615 0l0 115.880615l-115.880615 0z" fill-rule="nonzero"></path><path fill="#000000" d="m271.11987 311.17557l4.21875 -0.5625q0.734375 3.59375 2.46875 5.171875q1.75 1.578125 4.265625 1.578125q2.96875 0 5.015625 -2.0625q2.0625 -2.0625 2.0625 -5.109375q0 -2.90625 -1.90625 -4.78125q-1.890625 -1.890625 -4.828125 -1.890625q-1.1875 0 -2.96875 0.46875l0.46875 -3.703125q0.421875 0.046875 0.671875 0.046875q2.703125 0 4.859375 -1.40625q2.15625 -1.40625 2.15625 -4.34375q0 -2.3125 -1.578125 -3.828125q-1.5625 -1.53125 -4.046875 -1.53125q-2.46875 0 -4.109375 1.546875q-1.640625 1.546875 -2.109375 4.640625l-4.21875 -0.75q0.78125 -4.25 3.515625 -6.578125q2.75 -2.328125 6.828125 -2.328125q2.8125 0 5.171875 1.203125q2.375 1.203125 3.625 3.296875q1.25 2.078125 1.25 4.421875q0 2.234375 -1.203125 4.0625q-1.1875 1.828125 -3.53125 2.90625q3.046875 0.703125 4.734375 2.921875q1.6875 2.203125 1.6875 5.53125q0 4.5 -3.28125 7.640625q-3.28125 3.125 -8.296875 3.125q-4.515625 0 -7.515625 -2.6875q-2.984375 -2.703125 -3.40625 -7.0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m63.313194 417.94904l115.871635 0l0 115.87164l-115.871635 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m63.313194 417.94904l115.871635 0l0 115.87164l-115.871635 0z" fill-rule="nonzero"></path><path fill="#000000" d="m109.60838 492.96484l9.09375 -12.9375l-8.421875 -11.953125l5.28125 0l3.8125 5.828125q1.078125 1.671875 1.734375 2.796875q1.03125 -1.546875 1.90625 -2.75l4.1875 -5.875l5.046875 0l-8.609375 11.71875l9.265625 13.171875l-5.1875 0l-5.109375 -7.734375l-1.359375 -2.09375l-6.53125 9.828125l-5.109375 0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m223.93929 417.94904l39.008408 0l0 115.87164l-39.008408 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m223.93929 417.94904l39.008408 0l0 115.87164l-39.008408 0z" fill-rule="nonzero"></path><path fill="#000000" d="m247.98647 492.96484l-4.21875 0l0 -26.890625q-1.53125 1.453125 -4.0 2.90625q-2.46875 1.453125 -4.4375 2.1875l0 -4.078125q3.53125 -1.671875 6.171875 -4.03125q2.65625 -2.375 3.765625 -4.59375l2.71875 0l0 34.5z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m262.9477 417.94904l39.008423 0l0 115.87164l-39.008423 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m262.9477 417.94904l39.008423 0l0 115.87164l-39.008423 0z" fill-rule="nonzero"></path><path fill="#000000" d="m293.27612 488.90234l0 4.0625l-22.71875 0q-0.046875 -1.53125 0.5 -2.9375q0.859375 -2.3125 2.765625 -4.5625q1.921875 -2.25 5.53125 -5.203125q5.59375 -4.59375 7.5625 -7.28125q1.96875 -2.6875 1.96875 -5.078125q0 -2.5 -1.796875 -4.21875q-1.78125 -1.734375 -4.671875 -1.734375q-3.046875 0 -4.875 1.828125q-1.828125 1.828125 -1.84375 5.0625l-4.34375 -0.4375q0.453125 -4.859375 3.359375 -7.390625q2.90625 -2.546875 7.796875 -2.546875q4.953125 0 7.828125 2.75q2.890625 2.734375 2.890625 6.78125q0 2.0625 -0.84375 4.0625q-0.84375 1.984375 -2.8125 4.1875q-1.953125 2.203125 -6.5 6.046875q-3.796875 3.1875 -4.875 4.328125q-1.078125 1.140625 -1.78125 2.28125l16.859375 0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m301.95612 417.94904l39.008392 0l0 115.87164l-39.008392 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m301.95612 417.94904l39.008392 0l0 115.87164l-39.008392 0z" fill-rule="nonzero"></path><path fill="#000000" d="m310.1283 483.88672l4.21875 -0.5625q0.734375 3.59375 2.46875 5.171875q1.75 1.578125 4.265625 1.578125q2.96875 0 5.015625 -2.0625q2.0625 -2.0625 2.0625 -5.109375q0 -2.90625 -1.90625 -4.78125q-1.890625 -1.890625 -4.828125 -1.890625q-1.1875 0 -2.96875 0.46875l0.46875 -3.703125q0.421875 0.046875 0.671875 0.046875q2.703125 0 4.859375 -1.40625q2.15625 -1.40625 2.15625 -4.34375q0 -2.3125 -1.578125 -3.828125q-1.5625 -1.53125 -4.046875 -1.53125q-2.46875 0 -4.109375 1.546875q-1.640625 1.546875 -2.109375 4.640625l-4.21875 -0.75q0.78125 -4.25 3.515625 -6.578125q2.75 -2.328125 6.828125 -2.328125q2.8125 0 5.171875 1.203125q2.375 1.203125 3.625 3.296875q1.25 2.078125 1.25 4.421875q0 2.234375 -1.203125 4.0625q-1.1875 1.828125 -3.53125 2.90625q3.046875 0.703125 4.734375 2.921875q1.6875 2.203125 1.6875 5.53125q0 4.5 -3.28125 7.640625q-3.28125 3.125 -8.296875 3.125q-4.515625 0 -7.515625 -2.6875q-2.984375 -2.703125 -3.40625 -7.0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m63.293144 590.65405l115.90551 0l0 115.87402l-115.90551 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m63.293144 590.65405l115.90551 0l0 115.87402l-115.90551 0z" fill-rule="nonzero"></path><path fill="#000000" d="m109.60528 665.6711l9.09375 -12.9375l-8.421875 -11.953125l5.28125 0l3.8125 5.828125q1.078125 1.671875 1.734375 2.796875q1.03125 -1.546875 1.90625 -2.75l4.1875 -5.875l5.0468826 0l-8.609383 11.71875l9.265633 13.171875l-5.1875076 0l-5.109375 -7.734375l-1.359375 -2.09375l-6.53125 9.828125l-5.109375 0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m225.0786 590.65405l115.9055 0l0 115.87402l-115.9055 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m225.0786 590.65405l115.9055 0l0 115.87402l-115.9055 0z" fill-rule="nonzero"></path><path fill="#000000" d="m271.39072 665.6711l9.09375 -12.9375l-8.421875 -11.953125l5.28125 0l3.8125 5.828125q1.078125 1.671875 1.734375 2.796875q1.03125 -1.546875 1.90625 -2.75l4.1875 -5.875l5.0469055 0l-8.6094055 11.71875l9.2656555 13.171875l-5.1875 0l-5.1094055 -7.734375l-1.359375 -2.09375l-6.53125 9.828125l-5.109375 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m411.0525 129.35564l506.5197 0l0 115.87402l-506.5197 0z" fill-rule="nonzero"></path><path fill="#000000" d="m424.27124 199.79564l0 -33.1875l5.0625 0l0 4.71875q3.65625 -5.46875 10.5625 -5.46875q3.0 0 5.515625 1.078125q2.515625 1.078125 3.765625 2.828125q1.25 1.75 1.75 4.15625q0.3125 1.5625 0.3125 5.46875l0 20.40625l-5.625 0l0 -20.1875q0 -3.4375 -0.65625 -5.140625q-0.65625 -1.703125 -2.328125 -2.71875q-1.671875 -1.015625 -3.921875 -1.015625q-3.59375 0 -6.203125 2.28125q-2.609375 2.28125 -2.609375 8.65625l0 18.125l-5.625 0zm33.5 -16.59375q0 -9.21875 5.125 -13.65625q4.28125 -3.6875 10.4375 -3.6875q6.84375 0 11.1875 4.484375q4.34375 4.484375 4.34375 12.390625q0 6.40625 -1.921875 10.078125q-1.921875 3.671875 -5.59375 5.703125q-3.671875 2.03125 -8.015625 2.03125q-6.96875 0 -11.265625 -4.46875q-4.296875 -4.46875 -4.296875 -12.875zm5.78125 0q0 6.375 2.78125 9.546875q2.78125 3.171875 7.0 3.171875q4.1875 0 6.96875 -3.1875q2.78125 -3.1875 2.78125 -9.71875q0 -6.15625 -2.796875 -9.328125q-2.796875 -3.171875 -6.953125 -3.171875q-4.21875 0 -7.0 3.15625q-2.78125 3.15625 -2.78125 9.53125zm61.96875 11.5625l0.8125 4.96875q-2.375 0.5 -4.25 0.5q-3.0625 0 -4.75 -0.96875q-1.6875 -0.96875 -2.375 -2.546875q-0.6875 -1.578125 -0.6875 -6.640625l0 -19.09375l-4.125 0l0 -4.375l4.125 0l0 -8.21875l5.59375 -3.375l0 11.59375l5.65625 0l0 4.375l-5.65625 0l0 19.40625q0 2.40625 0.296875 3.09375q0.296875 0.6875 0.96875 1.09375q0.671875 0.40625 1.921875 0.40625q0.9375 0 2.46875 -0.21875zm27.15625 -7.125l5.53125 0.71875q-0.90625 5.71875 -4.640625 8.953125q-3.734375 3.234375 -9.171875 3.234375q-6.8125 0 -10.953125 -4.453125q-4.140625 -4.453125 -4.140625 -12.765625q0 -5.375 1.78125 -9.40625q1.78125 -4.03125 5.421875 -6.046875q3.640625 -2.015625 7.921875 -2.015625q5.40625 0 8.84375 2.734375q3.4375 2.734375 4.40625 7.765625l-5.46875 0.84375q-0.78125 -3.34375 -2.765625 -5.03125q-1.984375 -1.6875 -4.796875 -1.6875q-4.25 0 -6.90625 3.046875q-2.65625 3.046875 -2.65625 9.640625q0 6.6875 2.5625 9.71875q2.5625 3.03125 6.6875 3.03125q3.3125 0 5.53125 -2.03125q2.21875 -2.03125 2.8125 -6.25zm32.09375 12.15625l0 -4.875q-3.875 5.625 -10.53125 5.625q-2.9375 0 -5.484375 -1.125q-2.546875 -1.125 -3.78125 -2.828125q-1.234375 -1.703125 -1.734375 -4.171875q-0.34375 -1.65625 -0.34375 -5.25l0 -20.5625l5.625 0l0 18.40625q0 4.40625 0.34375 5.9375q0.53125 2.21875 2.25 3.484375q1.71875 1.265625 4.25 1.265625q2.53125 0 4.75 -1.296875q2.21875 -1.296875 3.140625 -3.53125q0.921875 -2.234375 0.921875 -6.484375l0 -17.78125l5.625 0l0 33.1875l-5.03125 0zm11.65625 -13.75l0 -5.65625l17.28125 0l0 5.65625l-17.28125 0zm21.25 3.84375l5.5625 -0.875q0.46875 3.34375 2.609375 5.125q2.140625 1.78125 5.984375 1.78125q3.875 0 5.75 -1.578125q1.875 -1.578125 1.875 -3.703125q0 -1.90625 -1.65625 -3.0q-1.15625 -0.75 -5.75 -1.90625q-6.1875 -1.5625 -8.578125 -2.703125q-2.390625 -1.140625 -3.625 -3.15625q-1.234375 -2.015625 -1.234375 -4.453125q0 -2.21875 1.015625 -4.109375q1.015625 -1.890625 2.765625 -3.140625q1.3125 -0.96875 3.578125 -1.640625q2.265625 -0.671875 4.859375 -0.671875q3.90625 0 6.859375 1.125q2.953125 1.125 4.359375 3.046875q1.40625 1.921875 1.9375 5.140625l-5.5 0.75q-0.375 -2.5625 -2.171875 -4.0q-1.796875 -1.4375 -5.078125 -1.4375q-3.875 0 -5.53125 1.28125q-1.65625 1.28125 -1.65625 3.0q0 1.09375 0.6875 1.96875q0.6875 0.90625 2.15625 1.5q0.84375 0.3125 4.96875 1.4375q5.96875 1.59375 8.328125 2.609375q2.359375 1.015625 3.703125 2.953125q1.34375 1.9375 1.34375 4.8125q0 2.8125 -1.640625 5.296875q-1.640625 2.484375 -4.734375 3.84375q-3.09375 1.359375 -7.0 1.359375q-6.46875 0 -9.859375 -2.6875q-3.390625 -2.6875 -4.328125 -7.96875zm56.0 9.90625l0 -4.875q-3.875 5.625 -10.53125 5.625q-2.9375 0 -5.484375 -1.125q-2.546875 -1.125 -3.78125 -2.828125q-1.234375 -1.703125 -1.734375 -4.171875q-0.34375 -1.65625 -0.34375 -5.25l0 -20.5625l5.625 0l0 18.40625q0 4.40625 0.34375 5.9375q0.53125 2.21875 2.25 3.484375q1.71875 1.265625 4.25 1.265625q2.53125 0 4.75 -1.296875q2.21875 -1.296875 3.140625 -3.53125q0.921875 -2.234375 0.921875 -6.484375l0 -17.78125l5.625 0l0 33.1875l-5.03125 0zm13.84375 12.71875l0 -45.90625l5.125 0l0 4.3125q1.8125 -2.53125 4.09375 -3.796875q2.28125 -1.265625 5.53125 -1.265625q4.25 0 7.5 2.1875q3.25 2.1875 4.90625 6.171875q1.65625 3.984375 1.65625 8.734375q0 5.09375 -1.828125 9.171875q-1.828125 4.078125 -5.3125 6.25q-3.484375 2.171875 -7.328125 2.171875q-2.8125 0 -5.046875 -1.1875q-2.234375 -1.1875 -3.671875 -3.0l0 16.15625l-5.625 0zm5.09375 -29.125q0 6.40625 2.59375 9.46875q2.59375 3.0625 6.28125 3.0625q3.75 0 6.421875 -3.171875q2.671875 -3.171875 2.671875 -9.828125q0 -6.34375 -2.609375 -9.5q-2.609375 -3.15625 -6.234375 -3.15625q-3.59375 0 -6.359375 3.359375q-2.765625 3.359375 -2.765625 9.765625zm30.5 29.125l0 -45.90625l5.125 0l0 4.3125q1.8125 -2.53125 4.09375 -3.796875q2.28125 -1.265625 5.53125 -1.265625q4.25 0 7.5 2.1875q3.25 2.1875 4.90625 6.171875q1.65625 3.984375 1.65625 8.734375q0 5.09375 -1.828125 9.171875q-1.828125 4.078125 -5.3125 6.25q-3.484375 2.171875 -7.328125 2.171875q-2.8125 0 -5.046875 -1.1875q-2.234375 -1.1875 -3.671875 -3.0l0 16.15625l-5.625 0zm5.09375 -29.125q0 6.40625 2.59375 9.46875q2.59375 3.0625 6.28125 3.0625q3.75 0 6.421875 -3.171875q2.671875 -3.171875 2.671875 -9.828125q0 -6.34375 -2.609375 -9.5q-2.609375 -3.15625 -6.234375 -3.15625q-3.59375 0 -6.359375 3.359375q-2.765625 3.359375 -2.765625 9.765625zm28.40625 -0.1875q0 -9.21875 5.125 -13.65625q4.28125 -3.6875 10.4375 -3.6875q6.84375 0 11.1875 4.484375q4.34375 4.484375 4.34375 12.390625q0 6.40625 -1.921875 10.078125q-1.921875 3.671875 -5.59375 5.703125q-3.671875 2.03125 -8.015625 2.03125q-6.96875 0 -11.265625 -4.46875q-4.296875 -4.46875 -4.296875 -12.875zm5.78125 0q0 6.375 2.78125 9.546875q2.78125 3.171875 7.0 3.171875q4.1875 0 6.96875 -3.1875q2.78125 -3.1875 2.78125 -9.71875q0 -6.15625 -2.796875 -9.328125q-2.796875 -3.171875 -6.953125 -3.171875q-4.21875 0 -7.0 3.15625q-2.78125 3.15625 -2.78125 9.53125zm31.84375 16.59375l0 -33.1875l5.0625 0l0 5.03125q1.9375 -3.53125 3.578125 -4.65625q1.640625 -1.125 3.609375 -1.125q2.84375 0 5.78125 1.8125l-1.9375 5.21875q-2.0625 -1.21875 -4.125 -1.21875q-1.84375 0 -3.3125 1.109375q-1.46875 1.109375 -2.09375 3.078125q-0.9375 3.0 -0.9375 6.5625l0 17.375l-5.625 0zm33.65625 -5.03125l0.8125 4.96875q-2.375 0.5 -4.25 0.5q-3.0625 0 -4.75 -0.96875q-1.6875 -0.96875 -2.375 -2.546875q-0.6875 -1.578125 -0.6875 -6.640625l0 -19.09375l-4.125 0l0 -4.375l4.125 0l0 -8.21875l5.59375 -3.375l0 11.59375l5.65625 0l0 4.375l-5.65625 0l0 19.40625q0 2.40625 0.296875 3.09375q0.296875 0.6875 0.96875 1.09375q0.671875 0.40625 1.921875 0.40625q0.9375 0 2.46875 -0.21875z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m411.0525 417.9475l506.5197 0l0 115.87402l-506.5197 0z" fill-rule="nonzero"></path><path fill="#000000" d="m430.39624 488.3875l-10.15625 -33.1875l5.8125 0l5.28125 19.15625l1.96875 7.125q0.125 -0.53125 1.71875 -6.84375l5.28125 -19.4375l5.78125 0l4.96875 19.25l1.65625 6.34375l1.90625 -6.40625l5.6875 -19.1875l5.46875 0l-10.375 33.1875l-5.84375 0l-5.28125 -19.875l-1.28125 -5.65625l-6.71875 25.53125l-5.875 0zm40.125 -39.34375l0 -6.46875l5.625 0l0 6.46875l-5.625 0zm0 39.34375l0 -33.1875l5.625 0l0 33.1875l-5.625 0zm26.46875 -5.03125l0.8125 4.96875q-2.375 0.5 -4.25 0.5q-3.0625 0 -4.75 -0.96875q-1.6875 -0.96875 -2.375 -2.546875q-0.6875 -1.578125 -0.6875 -6.640625l0 -19.09375l-4.125 0l0 -4.375l4.125 0l0 -8.21875l5.59375 -3.375l0 11.59375l5.65625 0l0 4.375l-5.65625 0l0 19.40625q0 2.40625 0.296875 3.09375q0.296875 0.6875 0.96875 1.09375q0.671875 0.40625 1.921875 0.40625q0.9375 0 2.46875 -0.21875zm5.5 5.03125l0 -45.8125l5.625 0l0 16.4375q3.9375 -4.5625 9.9375 -4.5625q3.6875 0 6.40625 1.453125q2.71875 1.453125 3.890625 4.015625q1.171875 2.5625 1.171875 7.4375l0 21.03125l-5.625 0l0 -21.03125q0 -4.21875 -1.828125 -6.140625q-1.828125 -1.921875 -5.171875 -1.921875q-2.5 0 -4.703125 1.296875q-2.203125 1.296875 -3.140625 3.515625q-0.9375 2.21875 -0.9375 6.125l0 18.15625l-5.625 0zm65.65625 -5.03125l0.8125 4.96875q-2.375 0.5 -4.25 0.5q-3.0625 0 -4.75 -0.96875q-1.6875 -0.96875 -2.375 -2.546875q-0.6875 -1.578125 -0.6875 -6.640625l0 -19.09375l-4.125 0l0 -4.375l4.125 0l0 -8.21875l5.59375 -3.375l0 11.59375l5.65625 0l0 4.375l-5.65625 0l0 19.40625q0 2.40625 0.296875 3.09375q0.296875 0.6875 0.96875 1.09375q0.671875 0.40625 1.921875 0.40625q0.9375 0 2.46875 -0.21875zm27.15625 -7.125l5.53125 0.71875q-0.90625 5.71875 -4.640625 8.953125q-3.734375 3.234375 -9.171875 3.234375q-6.8125 0 -10.953125 -4.453125q-4.140625 -4.453125 -4.140625 -12.765625q0 -5.375 1.78125 -9.40625q1.78125 -4.03125 5.421875 -6.046875q3.640625 -2.015625 7.921875 -2.015625q5.40625 0 8.84375 2.734375q3.4375 2.734375 4.40625 7.765625l-5.46875 0.84375q-0.78125 -3.34375 -2.765625 -5.03125q-1.984375 -1.6875 -4.796875 -1.6875q-4.25 0 -6.90625 3.046875q-2.65625 3.046875 -2.65625 9.640625q0 6.6875 2.5625 9.71875q2.5625 3.03125 6.6875 3.03125q3.3125 0 5.53125 -2.03125q2.21875 -2.03125 2.8125 -6.25zm32.09375 12.15625l0 -4.875q-3.875 5.625 -10.53125 5.625q-2.9375 0 -5.484375 -1.125q-2.546875 -1.125 -3.78125 -2.828125q-1.234375 -1.703125 -1.734375 -4.171875q-0.34375 -1.65625 -0.34375 -5.25l0 -20.5625l5.625 0l0 18.40625q0 4.40625 0.34375 5.9375q0.53125 2.21875 2.25 3.484375q1.71875 1.265625 4.25 1.265625q2.53125 0 4.75 -1.296875q2.21875 -1.296875 3.140625 -3.53125q0.921875 -2.234375 0.921875 -6.484375l0 -17.78125l5.625 0l0 33.1875l-5.03125 0zm11.65625 -13.75l0 -5.65625l17.28125 0l0 5.65625l-17.28125 0zm21.25 3.84375l5.5625 -0.875q0.46875 3.34375 2.609375 5.125q2.140625 1.78125 5.984375 1.78125q3.875 0 5.75 -1.578125q1.875 -1.578125 1.875 -3.703125q0 -1.90625 -1.65625 -3.0q-1.15625 -0.75 -5.75 -1.90625q-6.1875 -1.5625 -8.578125 -2.703125q-2.390625 -1.140625 -3.625 -3.15625q-1.234375 -2.015625 -1.234375 -4.453125q0 -2.21875 1.015625 -4.109375q1.015625 -1.890625 2.765625 -3.140625q1.3125 -0.96875 3.578125 -1.640625q2.265625 -0.671875 4.859375 -0.671875q3.90625 0 6.859375 1.125q2.953125 1.125 4.359375 3.046875q1.40625 1.921875 1.9375 5.140625l-5.5 0.75q-0.375 -2.5625 -2.171875 -4.0q-1.796875 -1.4375 -5.078125 -1.4375q-3.875 0 -5.53125 1.28125q-1.65625 1.28125 -1.65625 3.0q0 1.09375 0.6875 1.96875q0.6875 0.90625 2.15625 1.5q0.84375 0.3125 4.96875 1.4375q5.96875 1.59375 8.328125 2.609375q2.359375 1.015625 3.703125 2.953125q1.34375 1.9375 1.34375 4.8125q0 2.8125 -1.640625 5.296875q-1.640625 2.484375 -4.734375 3.84375q-3.09375 1.359375 -7.0 1.359375q-6.46875 0 -9.859375 -2.6875q-3.390625 -2.6875 -4.328125 -7.96875zm56.0 9.90625l0 -4.875q-3.875 5.625 -10.53125 5.625q-2.9375 0 -5.484375 -1.125q-2.546875 -1.125 -3.78125 -2.828125q-1.234375 -1.703125 -1.734375 -4.171875q-0.34375 -1.65625 -0.34375 -5.25l0 -20.5625l5.625 0l0 18.40625q0 4.40625 0.34375 5.9375q0.53125 2.21875 2.25 3.484375q1.71875 1.265625 4.25 1.265625q2.53125 0 4.75 -1.296875q2.21875 -1.296875 3.140625 -3.53125q0.921875 -2.234375 0.921875 -6.484375l0 -17.78125l5.625 0l0 33.1875l-5.03125 0zm13.84375 12.71875l0 -45.90625l5.125 0l0 4.3125q1.8125 -2.53125 4.09375 -3.796875q2.28125 -1.265625 5.53125 -1.265625q4.25 0 7.5 2.1875q3.25 2.1875 4.90625 6.171875q1.65625 3.984375 1.65625 8.734375q0 5.09375 -1.828125 9.171875q-1.828125 4.078125 -5.3125 6.25q-3.484375 2.171875 -7.328125 2.171875q-2.8125 0 -5.046875 -1.1875q-2.234375 -1.1875 -3.671875 -3.0l0 16.15625l-5.625 0zm5.09375 -29.125q0 6.40625 2.59375 9.46875q2.59375 3.0625 6.28125 3.0625q3.75 0 6.421875 -3.171875q2.671875 -3.171875 2.671875 -9.828125q0 -6.34375 -2.609375 -9.5q-2.609375 -3.15625 -6.234375 -3.15625q-3.59375 0 -6.359375 3.359375q-2.765625 3.359375 -2.765625 9.765625zm30.5 29.125l0 -45.90625l5.125 0l0 4.3125q1.8125 -2.53125 4.09375 -3.796875q2.28125 -1.265625 5.53125 -1.265625q4.25 0 7.5 2.1875q3.25 2.1875 4.90625 6.171875q1.65625 3.984375 1.65625 8.734375q0 5.09375 -1.828125 9.171875q-1.828125 4.078125 -5.3125 6.25q-3.484375 2.171875 -7.328125 2.171875q-2.8125 0 -5.046875 -1.1875q-2.234375 -1.1875 -3.671875 -3.0l0 16.15625l-5.625 0zm5.09375 -29.125q0 6.40625 2.59375 9.46875q2.59375 3.0625 6.28125 3.0625q3.75 0 6.421875 -3.171875q2.671875 -3.171875 2.671875 -9.828125q0 -6.34375 -2.609375 -9.5q-2.609375 -3.15625 -6.234375 -3.15625q-3.59375 0 -6.359375 3.359375q-2.765625 3.359375 -2.765625 9.765625zm28.40625 -0.1875q0 -9.21875 5.125 -13.65625q4.28125 -3.6875 10.4375 -3.6875q6.84375 0 11.1875 4.484375q4.34375 4.484375 4.34375 12.390625q0 6.40625 -1.921875 10.078125q-1.921875 3.671875 -5.59375 5.703125q-3.671875 2.03125 -8.015625 2.03125q-6.96875 0 -11.265625 -4.46875q-4.296875 -4.46875 -4.296875 -12.875zm5.78125 0q0 6.375 2.78125 9.546875q2.78125 3.171875 7.0 3.171875q4.1875 0 6.96875 -3.1875q2.78125 -3.1875 2.78125 -9.71875q0 -6.15625 -2.796875 -9.328125q-2.796875 -3.171875 -6.953125 -3.171875q-4.21875 0 -7.0 3.15625q-2.78125 3.15625 -2.78125 9.53125zm31.84375 16.59375l0 -33.1875l5.0625 0l0 5.03125q1.9375 -3.53125 3.578125 -4.65625q1.640625 -1.125 3.609375 -1.125q2.84375 0 5.78125 1.8125l-1.9375 5.21875q-2.0625 -1.21875 -4.125 -1.21875q-1.84375 0 -3.3125 1.109375q-1.46875 1.109375 -2.09375 3.078125q-0.9375 3.0 -0.9375 6.5625l0 17.375l-5.625 0zm33.65625 -5.03125l0.8125 4.96875q-2.375 0.5 -4.25 0.5q-3.0625 0 -4.75 -0.96875q-1.6875 -0.96875 -2.375 -2.546875q-0.6875 -1.578125 -0.6875 -6.640625l0 -19.09375l-4.125 0l0 -4.375l4.125 0l0 -8.21875l5.59375 -3.375l0 11.59375l5.65625 0l0 4.375l-5.65625 0l0 19.40625q0 2.40625 0.296875 3.09375q0.296875 0.6875 0.96875 1.09375q0.671875 0.40625 1.921875 0.40625q0.9375 0 2.46875 -0.21875z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m411.0525 590.65356l506.5197 0l0 115.87402l-506.5197 0z" fill-rule="nonzero"></path><path fill="#000000" d="m424.20874 661.09357l0 -33.1875l5.0625 0l0 5.03125q1.9375 -3.53125 3.578125 -4.65625q1.640625 -1.125 3.609375 -1.125q2.84375 0 5.78125 1.8125l-1.9375 5.21875q-2.0625 -1.21875 -4.125 -1.21875q-1.84375 0 -3.3125 1.109375q-1.46875 1.109375 -2.09375 3.078125q-0.9375 3.0 -0.9375 6.5625l0 17.375l-5.625 0zm44.09375 -10.6875l5.8125 0.71875q-1.375 5.09375 -5.09375 7.90625q-3.71875 2.8125 -9.5 2.8125q-7.28125 0 -11.546875 -4.484375q-4.265625 -4.484375 -4.265625 -12.578125q0 -8.375 4.3125 -13.0q4.3125 -4.625 11.1875 -4.625q6.65625 0 10.875 4.53125q4.21875 4.53125 4.21875 12.75q0 0.5 -0.03125 1.5l-24.75 0q0.3125 5.46875 3.09375 8.375q2.78125 2.90625 6.9375 2.90625q3.09375 0 5.28125 -1.625q2.1875 -1.625 3.46875 -5.1875zm-18.46875 -9.09375l18.53125 0q-0.375 -4.1875 -2.125 -6.28125q-2.6875 -3.25 -6.96875 -3.25q-3.875 0 -6.515625 2.59375q-2.640625 2.59375 -2.921875 6.9375zm32.6875 19.78125l0 -28.8125l-4.96875 0l0 -4.375l4.96875 0l0 -3.53125q0 -3.34375 0.59375 -4.96875q0.8125 -2.1875 2.859375 -3.546875q2.046875 -1.359375 5.734375 -1.359375q2.375 0 5.25 0.5625l-0.84375 4.90625q-1.75 -0.3125 -3.3125 -0.3125q-2.5625 0 -3.625 1.09375q-1.0625 1.09375 -1.0625 4.09375l0 3.0625l6.46875 0l0 4.375l-6.46875 0l0 28.8125l-5.59375 0zm39.15625 -10.6875l5.8125 0.71875q-1.375 5.09375 -5.09375 7.90625q-3.71875 2.8125 -9.5 2.8125q-7.28125 0 -11.546875 -4.484375q-4.265625 -4.484375 -4.265625 -12.578125q0 -8.375 4.3125 -13.0q4.3125 -4.625 11.1875 -4.625q6.65625 0 10.875 4.53125q4.21875 4.53125 4.21875 12.75q0 0.5 -0.03125 1.5l-24.75 0q0.3125 5.46875 3.09375 8.375q2.78125 2.90625 6.9375 2.90625q3.09375 0 5.28125 -1.625q2.1875 -1.625 3.46875 -5.1875zm-18.46875 -9.09375l18.53125 0q-0.375 -4.1875 -2.125 -6.28125q-2.6875 -3.25 -6.96875 -3.25q-3.875 0 -6.515625 2.59375q-2.640625 2.59375 -2.921875 6.9375zm31.28125 19.78125l0 -33.1875l5.0625 0l0 5.03125q1.9375 -3.53125 3.578125 -4.65625q1.640625 -1.125 3.609375 -1.125q2.84375 0 5.78125 1.8125l-1.9375 5.21875q-2.0625 -1.21875 -4.125 -1.21875q-1.84375 0 -3.3125 1.109375q-1.46875 1.109375 -2.09375 3.078125q-0.9375 3.0 -0.9375 6.5625l0 17.375l-5.625 0zm44.09375 -10.6875l5.8125 0.71875q-1.375 5.09375 -5.09375 7.90625q-3.71875 2.8125 -9.5 2.8125q-7.28125 0 -11.546875 -4.484375q-4.265625 -4.484375 -4.265625 -12.578125q0 -8.375 4.3125 -13.0q4.3125 -4.625 11.1875 -4.625q6.65625 0 10.875 4.53125q4.21875 4.53125 4.21875 12.75q0 0.5 -0.03125 1.5l-24.75 0q0.3125 5.46875 3.09375 8.375q2.78125 2.90625 6.9375 2.90625q3.09375 0 5.28125 -1.625q2.1875 -1.625 3.46875 -5.1875zm-18.46875 -9.09375l18.53125 0q-0.375 -4.1875 -2.125 -6.28125q-2.6875 -3.25 -6.96875 -3.25q-3.875 0 -6.515625 2.59375q-2.640625 2.59375 -2.921875 6.9375zm31.34375 19.78125l0 -33.1875l5.0625 0l0 4.71875q3.65625 -5.46875 10.5625 -5.46875q3.0 0 5.515625 1.078125q2.515625 1.078125 3.765625 2.828125q1.25 1.75 1.75 4.15625q0.3125 1.5625 0.3125 5.46875l0 20.40625l-5.625 0l0 -20.1875q0 -3.4375 -0.65625 -5.140625q-0.65625 -1.703125 -2.328125 -2.71875q-1.671875 -1.015625 -3.921875 -1.015625q-3.59375 0 -6.203125 2.28125q-2.609375 2.28125 -2.609375 8.65625l0 18.125l-5.625 0zm57.25 -12.15625l5.53125 0.71875q-0.90625 5.71875 -4.640625 8.953125q-3.734375 3.234375 -9.171875 3.234375q-6.8125 0 -10.953125 -4.453125q-4.140625 -4.453125 -4.140625 -12.765625q0 -5.375 1.78125 -9.40625q1.78125 -4.03125 5.421875 -6.046875q3.640625 -2.015625 7.921875 -2.015625q5.40625 0 8.84375 2.734375q3.4375 2.734375 4.40625 7.765625l-5.46875 0.84375q-0.78125 -3.34375 -2.765625 -5.03125q-1.984375 -1.6875 -4.796875 -1.6875q-4.25 0 -6.90625 3.046875q-2.65625 3.046875 -2.65625 9.640625q0 6.6875 2.5625 9.71875q2.5625 3.03125 6.6875 3.03125q3.3125 0 5.53125 -2.03125q2.21875 -2.03125 2.8125 -6.25zm33.0625 1.46875l5.8125 0.71875q-1.375 5.09375 -5.09375 7.90625q-3.71875 2.8125 -9.5 2.8125q-7.28125 0 -11.546875 -4.484375q-4.265625 -4.484375 -4.265625 -12.578125q0 -8.375 4.3125 -13.0q4.3125 -4.625 11.1875 -4.625q6.65625 0 10.875 4.53125q4.21875 4.53125 4.21875 12.75q0 0.5 -0.03125 1.5l-24.75 0q0.3125 5.46875 3.09375 8.375q2.78125 2.90625 6.9375 2.90625q3.09375 0 5.28125 -1.625q2.1875 -1.625 3.46875 -5.1875zm-18.46875 -9.09375l18.53125 0q-0.375 -4.1875 -2.125 -6.28125q-2.6875 -3.25 -6.96875 -3.25q-3.875 0 -6.515625 2.59375q-2.640625 2.59375 -2.921875 6.9375z" fill-rule="nonzero"></path></g></svg> +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/figure-tcufont.svg b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/figure-tcufont.svg new file mode 100644 index 0000000..f0b3aa2d --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/figure-tcufont.svg
@@ -0,0 +1,4 @@ +<?xml version="1.0" standalone="yes"?> + +<svg version="1.1" viewBox="0.0 0.0 720.0 540.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l720.0 0l0 540.0l-720.0 0l0 -540.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l720.0 0l0 540.0l-720.0 0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m43.997375 105.64454l98.39371 0l0 98.393715l-98.39371 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m43.997375 105.64454l98.39371 0l0 98.393715l-98.39371 0z" fill-rule="nonzero"></path><path fill="#000000" d="m77.66298 177.78139l12.125 -17.25l-11.21875 -15.9375l7.03125 0l5.09375 7.78125q1.4375 2.21875 2.3125 3.71875q1.375 -2.0625 2.53125 -3.65625l5.59375 -7.84375l6.71875 0l-11.46875 15.625l12.34375 17.5625l-6.90625 0l-6.8125 -10.3125l-1.8125 -2.78125l-8.71875 13.09375l-6.8125 0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m199.21577 105.64279l98.38435 0l0 98.38435l-98.38435 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m199.21577 105.64279l98.38435 0l0 98.38435l-98.38435 0z" fill-rule="nonzero"></path><path fill="#000000" d="m254.45482 177.77496l-5.625 0l0 -35.84375q-2.03125 1.9375 -5.328125 3.875q-3.296875 1.9375 -5.921875 2.90625l0 -5.4375q4.71875 -2.21875 8.25 -5.375q3.53125 -3.15625 5.0 -6.125l3.625 0l0 46.0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m199.21577 204.02715l98.38435 0l0 98.38435l-98.38435 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m199.21577 204.02715l98.38435 0l0 98.38435l-98.38435 0z" fill-rule="nonzero"></path><path fill="#000000" d="m262.82983 270.75305l0 5.40625l-30.281265 0q-0.0625 -2.03125 0.65625 -3.90625q1.15625 -3.09375 3.703125 -6.09375q2.546875 -3.0 7.359375 -6.9375q7.46875 -6.1249847 10.09375 -9.70311q2.6250153 -3.578125 2.6250153 -6.765625q0 -3.34375 -2.3906403 -5.640625q-2.390625 -2.296875 -6.234375 -2.296875q-4.0625 0 -6.5 2.4375q-2.4375 2.4375 -2.46875 6.75l-5.78125 -0.59375q0.59375 -6.46875 4.46875 -9.859375q3.875 -3.390625 10.40625 -3.390625q6.59375 0 10.437515 3.65625q3.84375 3.65625 3.84375 9.0625q0 2.75 -1.125 5.40625q-1.125 2.65625 -3.734375 5.59375q-2.6093903 2.9374847 -8.67189 8.062485q-5.0625 4.25 -6.5 5.765625q-1.4375 1.515625 -2.375 3.046875l22.468765 0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m199.21577 302.4115l98.38435 0l0 98.38434l-98.38435 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m199.21577 302.4115l98.38435 0l0 98.38434l-98.38435 0z" fill-rule="nonzero"></path><path fill="#000000" d="m233.29857 362.44992l5.625 -0.75q0.96875 4.78125 3.296875 6.890625q2.328125 2.109375 5.671875 2.109375q3.96875 0 6.703125 -2.75q2.7343903 -2.75 2.7343903 -6.8125q0 -3.875 -2.5312653 -6.390625q-2.53125 -2.515625 -6.4375 -2.515625q-1.59375 0 -3.96875 0.625l0.625 -4.9375q0.5625 0.0625 0.90625 0.0625q3.59375 0 6.46875 -1.875q2.875 -1.875 2.875 -5.78125q0 -3.09375 -2.09375 -5.125q-2.09375 -2.03125 -5.40625 -2.03125q-3.28125 0 -5.46875 2.0625q-2.1875 2.0625 -2.8125 6.1875l-5.625 -1.0q1.03125 -5.65625 4.6875 -8.765625q3.65625 -3.109375 9.09375 -3.109375q3.75 0 6.90625 1.609375q3.1562653 1.609375 4.8281403 4.390625q1.671875 2.78125 1.671875 5.90625q0 2.96875 -1.59375 5.40625q-1.59375 2.4375 -4.7187653 3.875q4.0625153 0.9375 6.3125153 3.890625q2.2499695 2.953125 2.2499695 7.390625q0 6.0 -4.3749695 10.171875q-4.3750153 4.171875 -11.062515 4.171875q-6.03125 0 -10.015625 -3.59375q-3.984375 -3.59375 -4.546875 -9.3125z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m577.6097 105.64454l98.39374 0l0 98.393715l-98.39374 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m577.6097 105.64454l98.39374 0l0 98.393715l-98.39374 0z" fill-rule="nonzero"></path><path fill="#000000" d="m611.2753 177.78139l12.125 -17.25l-11.21875 -15.9375l7.03125 0l5.09375 7.78125q1.4375 2.21875 2.3125 3.71875q1.375 -2.0625 2.53125 -3.65625l5.59375 -7.84375l6.71875 0l-11.46875 15.625l12.34375 17.5625l-6.90625 0l-6.8125 -10.3125l-1.8125 -2.78125l-8.71875 13.09375l-6.8125 0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m419.72928 105.64454l98.39371 0l0 98.393715l-98.39371 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m419.72928 105.64454l98.39371 0l0 98.393715l-98.39371 0z" fill-rule="nonzero"></path><path fill="#000000" d="m453.3949 177.78139l12.125 -17.25l-11.21875 -15.9375l7.03125 0l5.09375 7.78125q1.4375 2.21875 2.3125 3.71875q1.375 -2.0625 2.53125 -3.65625l5.59375 -7.84375l6.71875 0l-11.46875 15.625l12.34375 17.5625l-6.90625 0l-6.8125 -10.3125l-1.8125 -2.78125l-8.71875 13.09375l-6.8125 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m57.50656 20.08399l240.09448 0l0 79.55906l-240.09448 0z" fill-rule="nonzero"></path><path fill="#000000" d="m93.881935 71.38274l0.609375 3.734375q-1.78125 0.375 -3.1875 0.375q-2.296875 0 -3.5625 -0.71875q-1.265625 -0.734375 -1.78125 -1.921875q-0.515625 -1.1875 -0.515625 -4.984375l0 -14.3125l-3.09375 0l0 -3.28125l3.09375 0l0 -6.171875l4.203125 -2.53125l0 8.703125l4.234375 0l0 3.28125l-4.234375 0l0 14.546875q0 1.8125 0.21875 2.328125q0.21875 0.515625 0.71875 0.828125q0.515625 0.296875 1.453125 0.296875q0.703125 0 1.84375 -0.171875zm21.164062 -4.234375l4.359375 0.53125q-1.03125 3.828125 -3.828125 5.9375q-2.78125 2.109375 -7.109375 2.109375q-5.46875 0 -8.671875 -3.359375q-3.1875 -3.375 -3.1875 -9.4375q0 -6.28125 3.234375 -9.75q3.234375 -3.46875 8.390625 -3.46875q4.984375 0 8.140625 3.40625q3.171875 3.390625 3.171875 9.546875q0 0.375 -0.015625 1.125l-18.5625 0q0.234375 4.109375 2.3125 6.296875q2.09375 2.171875 5.203125 2.171875q2.328125 0 3.96875 -1.21875q1.640625 -1.21875 2.59375 -3.890625zm-13.84375 -6.828125l13.890625 0q-0.28125 -3.140625 -1.59375 -4.703125q-2.015625 -2.4375 -5.21875 -2.4375q-2.90625 0 -4.890625 1.953125q-1.984375 1.9375 -2.1875 5.1875zm21.820312 7.40625l4.171875 -0.65625q0.34375 2.515625 1.9531326 3.859375q1.609375 1.328125 4.484375 1.328125q2.90625 0 4.3125 -1.1875q1.40625 -1.1875 1.40625 -2.78125q0 -1.421875 -1.234375 -2.25q-0.875 -0.5625 -4.3125 -1.421875q-4.640625 -1.171875 -6.4375076 -2.03125q-1.796875 -0.859375 -2.71875 -2.359375q-0.921875 -1.515625 -0.921875 -3.34375q0 -1.671875 0.75 -3.078125q0.765625 -1.421875 2.078125 -2.359375q0.984375 -0.734375 2.6875076 -1.234375q1.703125 -0.5 3.640625 -0.5q2.9375 0 5.140625 0.84375q2.21875 0.84375 3.265625 2.28125q1.0625 1.4375 1.46875 3.859375l-4.125 0.5625q-0.28125 -1.921875 -1.640625 -3.0q-1.34375 -1.078125 -3.796875 -1.078125q-2.90625 0 -4.15625 0.96875q-1.2343826 0.953125 -1.2343826 2.234375q0 0.828125 0.5156326 1.484375q0.515625 0.671875 1.609375 1.125q0.640625 0.234375 3.734375 1.078125q4.46875 1.1875 6.234375 1.953125q1.78125 0.765625 2.78125 2.21875q1.015625 1.453125 1.015625 3.609375q0 2.109375 -1.234375 3.96875q-1.234375 1.859375 -3.5625 2.890625q-2.3125 1.015625 -5.234375 1.015625q-4.859375 0 -7.4062576 -2.015625q-2.53125 -2.015625 -3.234375 -5.984375zm34.890633 3.65625l0.609375 3.734375q-1.78125 0.375 -3.1875 0.375q-2.296875 0 -3.5625 -0.71875q-1.265625 -0.734375 -1.78125 -1.921875q-0.515625 -1.1875 -0.515625 -4.984375l0 -14.3125l-3.09375 0l0 -3.28125l3.09375 0l0 -6.171875l4.203125 -2.53125l0 8.703125l4.234375 0l0 3.28125l-4.234375 0l0 14.546875q0 1.8125 0.21875 2.328125q0.21875 0.515625 0.71875 0.828125q0.515625 0.296875 1.453125 0.296875q0.703125 0 1.84375 -0.171875zm33.70311 -5.34375l4.15625 0.546875q-0.6875 4.28125 -3.484375 6.71875q-2.796875 2.421875 -6.8749847 2.421875q-5.109375 0 -8.21875 -3.34375q-3.109375 -3.34375 -3.109375 -9.578125q0 -4.03125 1.328125 -7.046875q1.34375 -3.03125 4.078125 -4.53125q2.734375 -1.515625 5.9375 -1.515625q4.0624847 0 6.6406097 2.046875q2.578125 2.046875 3.296875 5.828125l-4.09375 0.625q-0.59375 -2.5 -2.078125 -3.765625q-1.484375 -1.265625 -3.59375 -1.265625q-3.1874847 0 -5.1874847 2.28125q-1.984375 2.28125 -1.984375 7.234375q0 5.015625 1.921875 7.296875q1.921875 2.265625 5.015625 2.265625q2.4843597 0 4.1406097 -1.515625q1.671875 -1.53125 2.109375 -4.703125zm24.0 6.046875q-2.34375 2.0 -4.515625 2.828125q-2.15625 0.8125 -4.640625 0.8125q-4.109375 0 -6.3125 -2.0q-2.203125 -2.015625 -2.203125 -5.125q0 -1.828125 0.828125 -3.34375q0.84375 -1.515625 2.1875 -2.421875q1.34375 -0.921875 3.03125 -1.390625q1.25 -0.328125 3.75 -0.625q5.109375 -0.609375 7.53125 -1.453125q0.015625 -0.875 0.015625 -1.109375q0 -2.578125 -1.1875 -3.625q-1.625 -1.4375 -4.8125 -1.4375q-2.96875 0 -4.390625 1.046875q-1.421875 1.046875 -2.09375 3.6875l-4.125 -0.5625q0.5625 -2.640625 1.84375 -4.265625q1.296875 -1.640625 3.734375 -2.515625q2.4375 -0.875 5.640625 -0.875q3.1875 0 5.171875 0.75q2.0 0.75 2.9375 1.890625q0.9375 1.125 1.3125 2.859375q0.21875 1.078125 0.21875 3.890625l0 5.625q0 5.890625 0.265625 7.453125q0.265625 1.546875 1.0625 2.984375l-4.40625 0q-0.65625 -1.3125 -0.84375 -3.078125zm-0.34375 -9.421875q-2.296875 0.9375 -6.890625 1.59375q-2.609375 0.375 -3.6875 0.84375q-1.078125 0.46875 -1.671875 1.375q-0.578125 0.90625 -0.578125 2.0q0 1.6875 1.28125 2.8125q1.28125 1.125 3.734375 1.125q2.4375 0 4.328125 -1.0625q1.90625 -1.0625 2.796875 -2.921875q0.6875 -1.421875 0.6875 -4.21875l0 -1.546875zm9.1171875 5.0625l4.171875 -0.65625q0.34375 2.515625 1.953125 3.859375q1.609375 1.328125 4.484375 1.328125q2.90625 0 4.3125 -1.1875q1.40625 -1.1875 1.40625 -2.78125q0 -1.421875 -1.234375 -2.25q-0.875 -0.5625 -4.3125 -1.421875q-4.640625 -1.171875 -6.4375 -2.03125q-1.796875 -0.859375 -2.71875 -2.359375q-0.921875 -1.515625 -0.921875 -3.34375q0 -1.671875 0.75 -3.078125q0.765625 -1.421875 2.078125 -2.359375q0.984375 -0.734375 2.6875 -1.234375q1.703125 -0.5 3.640625 -0.5q2.9375 0 5.140625 0.84375q2.21875 0.84375 3.265625 2.28125q1.0625 1.4375 1.46875 3.859375l-4.125 0.5625q-0.28125 -1.921875 -1.640625 -3.0q-1.34375 -1.078125 -3.796875 -1.078125q-2.90625 0 -4.15625 0.96875q-1.234375 0.953125 -1.234375 2.234375q0 0.828125 0.515625 1.484375q0.515625 0.671875 1.609375 1.125q0.640625 0.234375 3.734375 1.078125q4.46875 1.1875 6.234375 1.953125q1.78125 0.765625 2.78125 2.21875q1.015625 1.453125 1.015625 3.609375q0 2.109375 -1.234375 3.96875q-1.234375 1.859375 -3.5625 2.890625q-2.3125 1.015625 -5.234375 1.015625q-4.859375 0 -7.40625 -2.015625q-2.53125 -2.015625 -3.234375 -5.984375zm42.71875 -0.578125l4.359375 0.53125q-1.03125 3.828125 -3.828125 5.9375q-2.78125 2.109375 -7.109375 2.109375q-5.46875 0 -8.671875 -3.359375q-3.1875 -3.375 -3.1875 -9.4375q0 -6.28125 3.234375 -9.75q3.234375 -3.46875 8.390625 -3.46875q4.984375 0 8.140625 3.40625q3.171875 3.390625 3.171875 9.546875q0 0.375 -0.015625 1.125l-18.5625 0q0.234375 4.109375 2.3125 6.296875q2.09375 2.171875 5.203125 2.171875q2.328125 0 3.96875 -1.21875q1.640625 -1.21875 2.59375 -3.890625zm-13.84375 -6.828125l13.890625 0q-0.28125 -3.140625 -1.59375 -4.703125q-2.015625 -2.4375 -5.21875 -2.4375q-2.90625 0 -4.890625 1.953125q-1.984375 1.9375 -2.1875 5.1875z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m435.90814 20.08399l240.09448 0l0 79.55906l-240.09448 0z" fill-rule="nonzero"></path><path fill="#000000" d="m457.68976 75.16399l0 -24.890625l3.796875 0l0 3.765625q1.453125 -2.640625 2.671875 -3.484375q1.234375 -0.84375 2.71875 -0.84375q2.125 0 4.328125 1.359375l-1.453125 3.90625q-1.546875 -0.90625 -3.09375 -0.90625q-1.375 0 -2.484375 0.828125q-1.09375 0.828125 -1.5625 2.3125q-0.703125 2.25 -0.703125 4.921875l0 13.03125l-4.21875 0zm33.0625 -8.015625l4.359375 0.53125q-1.03125 3.828125 -3.828125 5.9375q-2.78125 2.109375 -7.109375 2.109375q-5.46875 0 -8.671875 -3.359375q-3.1875 -3.375 -3.1875 -9.4375q0 -6.28125 3.234375 -9.75q3.234375 -3.46875 8.390625 -3.46875q4.984375 0 8.140625 3.40625q3.171875 3.390625 3.171875 9.546875q0 0.375 -0.015625 1.125l-18.5625 0q0.234375 4.109375 2.3125 6.296875q2.09375 2.171875 5.203125 2.171875q2.328125 0 3.96875 -1.21875q1.640625 -1.21875 2.59375 -3.890625zm-13.84375 -6.828125l13.890625 0q-0.28125 -3.140625 -1.59375 -4.703125q-2.015625 -2.4375 -5.21875 -2.4375q-2.90625 0 -4.890625 1.953125q-1.984375 1.9375 -2.1875 5.1875zm24.507812 14.84375l0 -21.609375l-3.71875 0l0 -3.28125l3.71875 0l0 -2.65625q0 -2.5 0.453125 -3.71875q0.609375 -1.640625 2.140625 -2.65625q1.53125 -1.03125 4.296875 -1.03125q1.78125 0 3.9375 0.421875l-0.625 3.6875q-1.3125 -0.234375 -2.484375 -0.234375q-1.921875 0 -2.71875 0.828125q-0.796875 0.8125 -0.796875 3.0625l0 2.296875l4.84375 0l0 3.28125l-4.84375 0l0 21.609375l-4.203125 0zm29.367188 -8.015625l4.359375 0.53125q-1.03125 3.828125 -3.828125 5.9375q-2.78125 2.109375 -7.109375 2.109375q-5.46875 0 -8.671875 -3.359375q-3.1875 -3.375 -3.1875 -9.4375q0 -6.28125 3.234375 -9.75q3.234375 -3.46875 8.390625 -3.46875q4.984375 0 8.140625 3.40625q3.171875 3.390625 3.171875 9.546875q0 0.375 -0.015625 1.125l-18.5625 0q0.234375 4.109375 2.3125 6.296875q2.09375 2.171875 5.203125 2.171875q2.328125 0 3.96875 -1.21875q1.640625 -1.21875 2.59375 -3.890625zm-13.84375 -6.828125l13.890625 0q-0.28125 -3.140625 -1.59375 -4.703125q-2.015625 -2.4375 -5.21875 -2.4375q-2.90625 0 -4.890625 1.953125q-1.984375 1.9375 -2.1875 5.1875zm23.460938 14.84375l0 -24.890625l3.796875 0l0 3.765625q1.453125 -2.640625 2.671875 -3.484375q1.234375 -0.84375 2.71875 -0.84375q2.125 0 4.328125 1.359375l-1.453125 3.90625q-1.546875 -0.90625 -3.09375 -0.90625q-1.375 0 -2.484375 0.828125q-1.09375 0.828125 -1.5625 2.3125q-0.703125 2.25 -0.703125 4.921875l0 13.03125l-4.21875 0zm33.0625 -8.015625l4.359375 0.53125q-1.03125 3.828125 -3.828125 5.9375q-2.78125 2.109375 -7.109375 2.109375q-5.46875 0 -8.671875 -3.359375q-3.1875 -3.375 -3.1875 -9.4375q0 -6.28125 3.234375 -9.75q3.234375 -3.46875 8.390625 -3.46875q4.984375 0 8.140625 3.40625q3.171875 3.390625 3.171875 9.546875q0 0.375 -0.015625 1.125l-18.5625 0q0.234375 4.109375 2.3125 6.296875q2.09375 2.171875 5.203125 2.171875q2.328125 0 3.96875 -1.21875q1.640625 -1.21875 2.59375 -3.890625zm-13.84375 -6.828125l13.890625 0q-0.28125 -3.140625 -1.59375 -4.703125q-2.015625 -2.4375 -5.21875 -2.4375q-2.90625 0 -4.890625 1.953125q-1.984375 1.9375 -2.1875 5.1875zm23.507812 14.84375l0 -24.890625l3.796875 0l0 3.53125q2.734375 -4.09375 7.921875 -4.09375q2.25 0 4.125 0.8125q1.890625 0.796875 2.828125 2.109375q0.9375 1.3125 1.3125 3.125q0.234375 1.171875 0.234375 4.09375l0 15.3125l-4.21875 0l0 -15.140625q0 -2.578125 -0.5 -3.859375q-0.484375 -1.28125 -1.734375 -2.03125q-1.25 -0.765625 -2.9375 -0.765625q-2.703125 0 -4.65625 1.71875q-1.953125 1.703125 -1.953125 6.484375l0 13.59375l-4.21875 0zm42.929688 -9.125l4.15625 0.546875q-0.6875 4.28125 -3.484375 6.71875q-2.796875 2.421875 -6.875 2.421875q-5.109375 0 -8.21875 -3.34375q-3.109375 -3.34375 -3.109375 -9.578125q0 -4.03125 1.328125 -7.046875q1.34375 -3.03125 4.078125 -4.53125q2.734375 -1.515625 5.9375 -1.515625q4.0625 0 6.640625 2.046875q2.578125 2.046875 3.296875 5.828125l-4.09375 0.625q-0.59375 -2.5 -2.078125 -3.765625q-1.484375 -1.265625 -3.59375 -1.265625q-3.1875 0 -5.1875 2.28125q-1.984375 2.28125 -1.984375 7.234375q0 5.015625 1.921875 7.296875q1.921875 2.265625 5.015625 2.265625q2.484375 0 4.140625 -1.515625q1.671875 -1.53125 2.109375 -4.703125zm24.796875 1.109375l4.359375 0.53125q-1.03125 3.828125 -3.828125 5.9375q-2.78125 2.109375 -7.109375 2.109375q-5.46875 0 -8.671875 -3.359375q-3.1875 -3.375 -3.1875 -9.4375q0 -6.28125 3.234375 -9.75q3.234375 -3.46875 8.390625 -3.46875q4.984375 0 8.140625 3.40625q3.171875 3.390625 3.171875 9.546875q0 0.375 -0.015625 1.125l-18.5625 0q0.234375 4.109375 2.3125 6.296875q2.09375 2.171875 5.203125 2.171875q2.328125 0 3.96875 -1.21875q1.640625 -1.21875 2.59375 -3.890625zm-13.84375 -6.828125l13.890625 0q-0.28125 -3.140625 -1.59375 -4.703125q-2.015625 -2.4375 -5.21875 -2.4375q-2.90625 0 -4.890625 1.953125q-1.984375 1.9375 -2.1875 5.1875z" fill-rule="nonzero"></path></g></svg> +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/heavy_h.svg b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/heavy_h.svg new file mode 100644 index 0000000..29aa9988 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/heavy_h.svg
@@ -0,0 +1,4 @@ +<?xml version="1.0" standalone="yes"?> + +<svg version="1.1" viewBox="0.0 0.0 1152.0 1152.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l1152.0 0l0 1152.0l-1152.0 0l0 -1152.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l1152.0 0l0 1152.0l-1152.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m418.51968 418.51968l314.9606 0l0 314.9606l-314.9606 0z" fill-rule="nonzero"></path><path stroke="#09f" stroke-width="24.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="40.0,30.0" d="m418.51968 418.51968l314.9606 0l0 314.9606l-314.9606 0z" fill-rule="nonzero"></path><path fill="#000000" d="m103.55905 103.55905l314.96063 0l0 944.88184l-314.96063 0z" fill-rule="nonzero"></path><path fill="#000000" d="m733.4803 103.55905l314.96063 0l0 944.88184l-314.96063 0z" fill-rule="nonzero"></path></g></svg> +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/heavy_h_rotated.svg b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/heavy_h_rotated.svg new file mode 100644 index 0000000..4616bf32 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/heavy_h_rotated.svg
@@ -0,0 +1,4 @@ +<?xml version="1.0" standalone="yes"?> + +<svg version="1.1" viewBox="0.0 0.0 1152.0 1152.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l1152.0 0l0 1152.0l-1152.0 0l0 -1152.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l1152.0 0l0 1152.0l-1152.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m733.4803 418.51968l0 314.9606l-314.9606 0l0 -314.9606z" fill-rule="nonzero"></path><path stroke="#09f" stroke-width="24.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="40.0,30.0" d="m733.4803 418.51968l0 314.9606l-314.9606 0l0 -314.9606z" fill-rule="nonzero"></path><path fill="#000000" d="m1048.4409 103.55905l0 314.96063l-944.88184 0l0 -314.96063z" fill-rule="nonzero"></path><path fill="#000000" d="m1048.4409 733.4803l0 314.96063l-944.88184 0l0 -314.96063z" fill-rule="nonzero"></path></g></svg> +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/over_and_under.svg b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/over_and_under.svg new file mode 100644 index 0000000..29b3c17 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/over_and_under.svg
@@ -0,0 +1,4 @@ +<?xml version="1.0" standalone="yes"?> + +<svg version="1.1" viewBox="0.0 0.0 400.0 240.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l400.0 0l0 240.0l-400.0 0l0 -240.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l400.0 0l0 240.0l-400.0 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m104.0 24.0l192.0 0l0 192.0l-192.0 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m104.0 24.0l192.0 0l0 192.0l-192.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m104.0 200.0l192.0 0l0 16.0l-192.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m104.0 24.0l192.0 0l0 16.0l-192.0 0z" fill-rule="nonzero"></path></g></svg> +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/pointing_right.svg b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/pointing_right.svg new file mode 100644 index 0000000..9e5dd37 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/pointing_right.svg
@@ -0,0 +1,4 @@ +<?xml version="1.0" standalone="yes"?> + +<svg version="1.1" viewBox="0.0 0.0 400.0 240.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l400.0 0l0 240.0l-400.0 0l0 -240.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l400.0 0l0 240.0l-400.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m104.0 24.0l192.0 0l0 192.0l-192.0 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m104.0 24.0l192.0 0l0 192.0l-192.0 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m153.37007 66.07874l93.25986 53.921257l-93.25986 53.921265z" fill-rule="nonzero"></path></g></svg> +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/pointing_up.svg b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/pointing_up.svg new file mode 100644 index 0000000..1abffd49 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/pointing_up.svg
@@ -0,0 +1,4 @@ +<?xml version="1.0" standalone="yes"?> + +<svg version="1.1" viewBox="0.0 0.0 400.0 240.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l400.0 0l0 240.0l-400.0 0l0 -240.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l400.0 0l0 240.0l-400.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m104.0 24.0l192.0 0l0 192.0l-192.0 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m104.0 24.0l192.0 0l0 192.0l-192.0 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m146.07874 166.62993l53.921265 -93.25985l53.921265 93.25985z" fill-rule="nonzero"></path></g></svg> +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/square_black.svg b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/square_black.svg new file mode 100644 index 0000000..9198fe5d --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/square_black.svg
@@ -0,0 +1,4 @@ +<?xml version="1.0" standalone="yes"?> + +<svg version="1.1" viewBox="0.0 0.0 400.0 240.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l400.0 0l0 240.0l-400.0 0l0 -240.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l400.0 0l0 240.0l-400.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m104.0 24.0l192.0 0l0 192.0l-192.0 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m104.0 24.0l192.0 0l0 192.0l-192.0 0z" fill-rule="nonzero"></path></g></svg> +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/square_blank.svg b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/square_blank.svg new file mode 100644 index 0000000..14a2b3ee --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/square_blank.svg
@@ -0,0 +1,4 @@ +<?xml version="1.0" standalone="yes"?> + +<svg version="1.1" viewBox="0.0 0.0 400.0 240.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l400.0 0l0 240.0l-400.0 0l0 -240.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l400.0 0l0 240.0l-400.0 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m104.0 24.0l192.0 0l0 192.0l-192.0 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m104.0 24.0l192.0 0l0 192.0l-192.0 0z" fill-rule="nonzero"></path></g></svg> +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/stripe_double.svg b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/stripe_double.svg new file mode 100644 index 0000000..9b4f5df9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/stripe_double.svg
@@ -0,0 +1,4 @@ +<?xml version="1.0" standalone="yes"?> + +<svg version="1.1" viewBox="0.0 0.0 400.0 240.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l400.0 0l0 240.0l-400.0 0l0 -240.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l400.0 0l0 240.0l-400.0 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m44.0 24.0l192.0 0l0 192.0l-192.0 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m44.0 24.0l192.0 0l0 192.0l-192.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m44.0 200.0l192.0 0l0 16.0l-192.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m44.0 168.0l192.0 0l0 16.0l-192.0 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m260.0 24.0l96.0 0l0 192.0l-96.0 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m260.0 24.0l96.0 0l0 192.0l-96.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m260.0 200.0l96.0 0l0 16.0l-96.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m260.0 168.0l96.0 0l0 16.0l-96.0 0z" fill-rule="nonzero"></path></g></svg> +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/stripe_quad.svg b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/stripe_quad.svg new file mode 100644 index 0000000..64c47fa --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/stripe_quad.svg
@@ -0,0 +1,4 @@ +<?xml version="1.0" standalone="yes"?> + +<svg version="1.1" viewBox="0.0 0.0 400.0 240.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l400.0 0l0 240.0l-400.0 0l0 -240.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l400.0 0l0 240.0l-400.0 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m68.0 24.0l192.0 0l0 192.0l-192.0 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m68.0 24.0l192.0 0l0 192.0l-192.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m68.0 200.0l192.0 0l0 16.0l-192.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m68.0 168.0l192.0 0l0 16.0l-192.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m68.0 136.0l192.0 0l0 16.0l-192.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m68.0 104.0l192.0 0l0 16.0l-192.0 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m284.0 24.0l48.0 0l0 192.0l-48.0 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m284.0 24.0l48.0 0l0 192.0l-48.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m284.0 200.0l48.0 0l0 16.0l-48.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m284.0 168.0l48.0 0l0 16.0l-48.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m284.0 136.0l48.0 0l0 16.0l-48.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m284.0 104.0l48.0 0l0 16.0l-48.0 0z" fill-rule="nonzero"></path></g></svg> +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/stripe_triple.svg b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/stripe_triple.svg new file mode 100644 index 0000000..9a2ef79 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/img/stripe_triple.svg
@@ -0,0 +1,4 @@ +<?xml version="1.0" standalone="yes"?> + +<svg version="1.1" viewBox="0.0 0.0 400.0 240.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l400.0 0l0 240.0l-400.0 0l0 -240.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l400.0 0l0 240.0l-400.0 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m60.0036 24.0l192.0 0l0 192.0l-192.0 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m60.0036 24.0l192.0 0l0 192.0l-192.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m60.0036 200.0l192.0 0l0 16.0l-192.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m60.0036 168.0l192.0 0l0 16.0l-192.0 0z" fill-rule="nonzero"></path><path fill="#000000" d="m60.0036 136.0l192.0 0l0 16.0l-192.0 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m276.0028 24.0l63.99359 0l0 192.0l-63.99359 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m276.0028 24.0l63.99359 0l0 192.0l-63.99359 0z" fill-rule="nonzero"></path><path fill="#000000" d="m276.0028 200.0l63.99359 0l0 16.0l-63.99359 0z" fill-rule="nonzero"></path><path fill="#000000" d="m276.0028 168.0l63.99359 0l0 16.0l-63.99359 0z" fill-rule="nonzero"></path><path fill="#000000" d="m276.0028 136.0l63.99359 0l0 16.0l-63.99359 0z" fill-rule="nonzero"></path></g></svg> +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/index.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/index.html new file mode 100644 index 0000000..95c7cf10 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/index.html
@@ -0,0 +1,503 @@ +<!DOCTYPE html> +<html> + <head> + <title>CSS Writing Modes testing strategy</title> + <meta http-equiv='Content-Type' content='text/html;charset=utf-8'/> + <!-- + === NOTA BENE === + For the three scripts below, if your spec resides on dev.w3 you can check them + out in the same tree and use relative links so that they'll work offline, + --> + <script src='http://www.w3.org/Tools/respec/respec-w3c-common' class='remove' async></script> + <script class='remove'> + var respecConfig = { + specStatus: "unofficial", + shortName: "css3-writingmodes-test-strategy", + editors: [ + { + name: "Shinsuke Matsuki", mailto: "shinsuke.matsuki@access-company.com", + company: "ACCESS", companyURL: "" + }, + { + name: "Masataka Yakura", mailto: "masataka.yakura@gmail.com", + company: "", companyURL: "" + }, + ], + testSuiteURI: "http://test.csswg.org/suites/css3-writing-modes/nightly-unstable/", + }; + </script> + <style> + a.bibref, + #references dt { + text-transform: uppercase; + } + </style> + + <style> + table + { + border-collapse:collapse; + } + table, td, th + { + border:1px solid black; + padding: 13px; + } + table + { + width: 100%; + } + img + { + width: 400px; + } + </style> + <style>/***************************************************************** + * ReSpec 3 CSS + * Robin Berjon - http://berjon.com/ + *****************************************************************/ + +/* --- INLINES --- */ +em.rfc2119 { + text-transform: lowercase; + font-variant: small-caps; + font-style: normal; + color: #900; +} + +h1 acronym, h2 acronym, h3 acronym, h4 acronym, h5 acronym, h6 acronym, a acronym, +h1 abbr, h2 abbr, h3 abbr, h4 abbr, h5 abbr, h6 abbr, a abbr { + border: none; +} + +dfn { + font-weight: bold; +} + +a.internalDFN { + color: inherit; + border-bottom: 1px solid #99c; + text-decoration: none; +} + +a.externalDFN { + color: inherit; + border-bottom: 1px dotted #ccc; + text-decoration: none; +} + +a.bibref { + text-decoration: none; +} + +cite .bibref { + font-style: normal; +} + +code { + color: #ff4500; +} + +/* --- TOC --- */ +.toc a, .tof a { + text-decoration: none; +} + +a .secno, a .figno { + color: #000; +} + +ul.tof, ol.tof { + list-style: none outside none; +} + +.caption { + margin-top: 0.5em; + font-style: italic; +} + +/* --- TABLE --- */ +table.simple { + border-spacing: 0; + border-collapse: collapse; + border-bottom: 3px solid #005a9c; +} + +.simple th { + background: #005a9c; + color: #fff; + padding: 3px 5px; + text-align: left; +} + +.simple th[scope="row"] { + background: inherit; + color: inherit; + border-top: 1px solid #ddd; +} + +.simple td { + padding: 3px 10px; + border-top: 1px solid #ddd; +} + +.simple tr:nth-child(even) { + background: #f0f6ff; +} + +/* --- DL --- */ +.section dd > p:first-child { + margin-top: 0; +} + +.section dd > p:last-child { + margin-bottom: 0; +} + +.section dd { + margin-bottom: 1em; +} + +.section dl.attrs dd, .section dl.eldef dd { + margin-bottom: 0; +} +</style><link rel="stylesheet" href="https://www.w3.org/StyleSheets/TR/w3c-unofficial"><!--[if lt IE 9]><script src='https://www.w3.org/2008/site/js/html5shiv.js'></script><![endif]--> + + </head> + <body> + <section id='abstract'> + <p> + This document is intended to be used as a guideline for the testing + activities related to the CSS Writing Modes spec [[!css3-writing-modes]]. Its main + goal is to provide an overview of the general testing areas, possible + caveats and testing aspects not immediately apparent from the spec. + Also, it provides a means of tracking the progress of the CSS Writing Modes + spec testing. + </p> + <p> + This document is not meant to replace the spec in determining the + normative and non-normative assertions to be tested, but rather + complement it. + </p> + </section> + + <section> + <h2>Introduction</h2> + <p> + As CSS moved away from the monolithic development of CSS 2.1 to the + modular development of CSS 3, the number of proposed new features and + the complexity of the layout landscape have increased dramatically. + While this directly translates to increased flexibility and agility in + adopting and implementing new CSS features, it also increases the + complexity of testing CSS features and the need for coordinating the + testing efforts. Also, the need for testing coordination increases as + crowd-sourcing efforts like + <a href="http://testthewebforward.org/" target="_blank">Test the Web + Forward</a> present people less familiar with the processes and policies + of the W3C with the opportunity to contribute new tests. + </p> + <p> + Except when defining new behaviors or redefining old behaviors, the + implicit assumption for new CSS modules is that they play nicely with + other modules or properties defined in CSS 2.1 [[CSS21]]. As CSS + Writing Modes is a spec that touches many aspects of layout, styling and CSSOM, + it's not unreasonable to want to test the spec against these implicit + assumptions, too. + </p> + <p> + This testing strategy document is meant to complement the CSS Writing Modes + spec and the existing test suite by providing an overview of the testing + areas (especially the less apparent ones) and tracking the progress of + the testing activities against these test areas. + </p> + </section> + <section> + <h2>Goals</h2> + <p> + To ensure a comprehensive test suite with useful, high quality tests, a + number of goals are proposed. They range from process goals (how to + conduct testing) to implementation goals (how to write good tests). + </p> + <section> + <h3>Enabling easy test contribution</h3> + <p> + An important vector in successfully testing CSS Writing Modes is to + enable easy test contributions, both from W3C partners and from + non-W3C members that wish to contribute. This is achieved by clearly + marking and explaining the areas that need testing, linked to existing + tests and general testing progress. + </p> + </section> + <section> + <h3>Providing guidance on testing</h3> + <p> + In order to increase the quality of the test contributions, this + document offers a set of guidelines for conducting testing (see + <a href="#approach" class="sectionRef"></a>) and a testing progress + tracker to increase the surface coverage of tests (see + <a href="#test-progress-tracking" class="sectionRef"></a>). + </p> + </section> + <section> + <h3>Creating automation-friendly tests</h3> + <p> + In terms of actual tests produced for the CSS Writing Modes, the main goal + is to ensure that most tests are automatable (i.e. they're either + reftests or use <code>testharness.js</code>). Even where manual tests + are absolutely necessary they should be written so that they can be + easily automated – as there are on-going efforts to make + WebDriver [[webdriver]] automated tests a first class citized in W3C + testing. This means that even if a manual test requires user + interaction, the validation or PASS/FAIL conditions should still be + clear enough as to allow automatic validation if said interaction is + later automated. + </p> + + <p> + In particular need a special font in the test of CSS Writing Modes. Since these are is assumed of many tests, people who try to create the test now, check to see whether any available font. + </p> + </section> + </section> + <section> + <h2>Risks and mitigation</h2> + <p> + There are a number of risks associated with creating a high-quality + test suite for CSS Writing Modes. The most important ones are listed below. + </p> + <section> + <h3>Implicit interactions with a lot of other specs (and commonly accepted + browser behavior)</h3> + <p> + The CSS Writing Modes spec introduces a significant change in the way layout + can be done and as a consequence, many of the assumptions that hold in + the context of CSS 2.1 must be re-validated in the context of CSS + Writing Modes. In the meanwhile, a lot of new layout modules have been + proposed, with various degrees of implementer support and maturity. + Also, non-CSS specific specs introduced concepts that affect how style + is propagated (e.g. Shadow DOM [[shadow-dom]]) or how elements are + rendered and interact with their containing documents (e.g. + <code><iframe seamless></code> in HTML 5 [[HTML5]]). + </p> + <p> + All the above factors increase the testing surface and the number of + the possible cases that might need an explicitly specified behavior in + order to ensure intuitive and predictable results as well as stable + interaction with widely used browser features (that might not be <em>yet</em> + so strictly specified). + </p> + <p> + In terms of specifying the expected behavior, the current approach is + to try and specify it for specs that are final or nearly-final and to + just make a note of the possible interactions and unspecified behaviors + in the case of specs that are still in flux. In exceptional cases, a + new spec might be created to cater for the needs of multiple specs + (e.g. the CSS Fragmentation spec [[css3-break]]). + </p> + </section> + <section> + <h3>Big number of tests required</h3> + <div class="note"> + Add here the estimation of tests required produced by + <a href="https://github.com/w3c/web-platform-tests/tree/master/tools/coverage" target="_blank">W3C test coverage</a> + tool. If possible, provide a better informed guess on the number of tests. + </div> + <p> + Given the complexity of the spec, a big number of tests will need to + be created to produce a test suite that can ensure interoperability + between implementations. + </p> + <p> + In this context, the main purpose of this document is to provide + useful informations for creating and contributing tests in an effective + manner in terms of coverage and test quality. + </p> + </section> + <section> + <h3>Special fonts required</h3> + <p> + For building reftest, several special fonts are necessary. + If could not get some fonts, a test will be manual or reftest waiting fonts. + </p> + </section> + </section> + <section> + <h2>Approach</h2> + <p> + As spec testing cannot be realistically separated from testing a + particular implementation (except for the very simple cases), the + approach proposed for testing is one that tries to first cover as many + areas as possible, instead of deep diving on a certain feature or aspect + of the spec first. A side benefit of this approach is that the spec + tests can be used at any time to gauge the level of support of a certain + implementation. + </p> + <p> + Having this <em>breadth-first</em> approach in mind, tests will be + created for the testing areas listed in <a href="#testing-areas" + class="sectionRef"></a>. Testing will be done in multiple passes, each + aimed at covering more specific edge-cases. + </p> + <p> + The selection of test data, in terms of parsing, rendering, choose only one typical values ​​from the data set on the same effect (It is a test technique known "equivalence partitioning"). + </p> + + </section> + <section> + <h2>Testing areas</h2> + <section> + <h3>Explicit testing areas</h3> + <p> + These are testing areas normatively defined by the spec. They cover + things explicitly or implicitly defined in the CSS Writing Modes spec. + Please note that while detailed, this list is not necessarily + exhaustive and normative behaviors may not be contained in it. + When in doubt, consult the CSS Writing Modes spec or ask a question on the + <a href="http://lists.w3.org/Archives/Public/www-style/">mailing + list</a>. + </p> + <p> + <h4>Overview</h4> + Below is the list of explicit testing areas: + <ol> + <li> + Proper parsing of the CSS properties and rules, rendering + according to the spec. + <ul> + <li><code>direction</code></li> + <li><code>unicode-bidi</code></li> + <li><code>writing-mode</code></li> + <li><code>text-orientation</code></li> + <li><code>caption-side</code></li> + <li><code>text-combine-upright</code></li> + </ul> + </li> + Test the following set of elements as a group to the 'Applies to' description. + <ul> + <li>inline element, inline block, replaced elements, block element, list-item +, table, inline-table, table-header-group, table-footer-group, table-cell, table-caption</li> + <li><code>display:none</code></li> + <li>inherit</li> + </ul> + Selected as a representative following four frequently used as 'replace element'. + <ul> + <li><code>button</code></li> + <li><code>input:text</code></li> + <li><code>select</code></li> + <li><code>text-area</code></li> + </ul> + </li> + <li> + Box related specifications that are affected as specified by <code>writing-mode</code>, <code>text-orientation</code>. The original definition about 'Box model' see [[CSS21]] for details. Calculation of the following in particular: + <ul> + <li><code>margin</code></li> + <li><code>border</code></li> + <li><code>padding</code></li> + </ul> + </li> + <li> + Compression of the glyph in horizontal-in-vertical(tate-chu-yoko) when using the text-transform [[!css3-text]] and OpenType properties. + </li> + <li> + Positioning, sizing and Auto-sizing of the box in orthogonal flows. + </li> + <li> + Text Baselines in vertical writing mode. + <ul> + <li>alphabetic</li> + <li>central</li> + </ul> + </li> + </ol> + </p> + <h3>Each Section</h3> + <ol> + <h3>Sec 2.Inline Direction and Bidirectionality</h3> + <p> + Parse, Rendering fundamental when combined the <code>direction</code> property and the <code>unicode-bidi</code> property. Applying Unicode bidirectional algorithm, behavior when the value is a newline. Placement of split inline-box. Calculation positioning of the box element. + </p> + <h3>Sec 3.Introduction to Vertical Text</h3> + <p> + Parse, Rendering fundamental for the <code>writing-mode</code> property. Character should be considered in particular the placement in vertical writing mode(Punctuation, etc. Onbiki in Japanese). Rendering for principal writing mode. Handling of child block in the case of line feed direction different from the container block. Converte value of the SVG in the writing-mode. + </p> + + <h3>Sec 4.Inline-level Alignment</h3> + <p> + Consider baseline alphabetic, central in this specification. Baseline in vertical alignment for glyph, processing of dominant baseline. + <div class="note"> + 'dominant baseline' testing in CSS21 side? + </div> + </p> + <h3>Sec 5.Introduction to Vertical Text Layout</h3> + <p> + Parse, Rendering fundamental for the <code>text-orientation</code> property. rendering when the vertical writing mode. Rules of Appendix C. + </p> + <h3>Sec 6.Abstract Box Terminology</h3> + <p> + Processing over and under in line-relative directions. left, right adding in vertical writing mode to line-box. The processing of before, after, start, end of each block-level-element, inline-level-element in flow-relative directions. + </p> + <h3>Sec 7.Abstract Box Layout</h3> + <p> + Layout rule that refers to property in the box when in vertical writing mode and margin collapsing. Sizing, auto-sizing of the writing modes in Orthogonal Flow. Margin calculation in the case of Flow-Relative. Position calculation in the case of Line-Relative. Properties that do not affect the WritingMode. rendering and parsing of <code>caption-side</code> property. + </p> + <h3>Sec 8.Page Flow: the page progression direction</h3> + <p> + It is a page feed flow specification of UA, is beyond the scope of the current test environment. + </p> + <h3>Sec 9.Glyph Composition</h3> + <p> + Parse, Rendering fundamental for the <code>text-combine-upright</code> property. rendering when the vertical writing mode. Interrupted by a box boundary in text run-rules. Glyph of centering in 1em box. Several algorithms to compress the 1em glyph of multiple. + </p> + </ol> + + </section> + <section> + <h3>Implicit testing areas</h3> + <p> + These are testing areas either normatively defined in other specs + that explicitly refer to the CSS Writing Modes spec (e.g. [[css3-text]]) + or simply not explicitly defined, but implied by various aspects of + the spec (e.g. processing model, CSS 2.1 compliance, etc.). + Please note that while detailed, this list is not necessarily + exhaustive and normative behaviors may not be contained in it. + When in doubt, consult the CSS Writing Modes spec or ask a question on the + <a href="http://lists.w3.org/Archives/Public/www-style/">mailing + list</a>. + </p> + <p> + Below is the list of implicit testing areas: + <ol> + <li> + CSS Writing Modes and layout modules: + <ul> + <li><code>overflow</code></li> + <li><code>clip</code></li> + <li><code>line-height</code></li> + <li>the <code>alt</code> attribute </li> + </ul> + </li> + </ol> + </p> + </section> + </section> + <section> + <h2>People and responsibilities</h2> + <p> + Below is a list of people you should reach out to if you have any + questions related to this document or testing CSS Writing Modes in general: + <ul> + <li>fantasai – editor for CSS Writing Modes spec</li> + <li>Koji Ishii – editor for CSS Writing Modes spec</li> + <li>Rebecca Hauck – CSSWG testing owner</li> + </ul> + </p> + </section> + <section> + <h2>Test progress tracking</h2> + <p> + Currently test progress tracking is done via gitHub + <a href="https://github.com/w3c/csswg-test/issues/milestones?with_issues=yes">milestones</a> + and <a href="https://github.com/w3c/csswg-test/issues?milestone=9&state=open">issues</a>. + </p> + </section> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/req-tcu-font.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/req-tcu-font.html new file mode 100644 index 0000000..d33d297 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/test-plan/req-tcu-font.html
@@ -0,0 +1,502 @@ +<!DOCTYPE html> +<html> +<head> +<title>Requirements for fonts for testing text-combine-upright</title> +<meta charset='utf-8'> +<script class='remove'> +var respecConfig = { + specStatus: "unofficial", + shortName: "req-tcu-font", + editors: [ { name: "Masataka Yakura", url: "https://google.com/+MasatakaYakura" } ], + publishDate: "2015-01-28", +}; +</script> +<style> +/***************************************************************** + * ReSpec 3 CSS + * Robin Berjon - http://berjon.com/ + *****************************************************************/ + +/* --- INLINES --- */ +em.rfc2119 { text-transform: lowercase; font-variant: small-caps; font-style: normal; color: #900; } +h1 abbr, h2 abbr, h3 abbr, h4 abbr, h5 abbr, h6 abbr, a abbr { border: none; } +dfn { font-weight: bold; } +a.internalDFN { color: inherit; border-bottom: 1px solid #99c; text-decoration: none; } +a.externalDFN { color: inherit; border-bottom: 1px dotted #ccc; text-decoration: none; } +a.bibref { text-decoration: none; } +cite .bibref { font-style: normal; } +code { color: #C83500; } + +/* --- TOC --- */ +.toc a, .tof a { text-decoration: none; } +a .secno, a .figno { color: #000; } +ul.tof, ol.tof { list-style: none outside none; } +.caption { margin-top: 0.5em; font-style: italic; } + +/* --- TABLE --- */ +table.simple { border-spacing: 0; border-collapse: collapse; border-bottom: 3px solid #005a9c; } +.simple th { background: #005a9c; color: #fff; padding: 3px 5px; text-align: left; } +.simple th[scope="row"] { background: inherit; color: inherit; border-top: 1px solid #ddd; } +.simple td { padding: 3px 10px; border-top: 1px solid #ddd; } +.simple tr:nth-child(even) { background: #f0f6ff; } + +/* --- DL --- */ +.section dd > p:first-child { margin-top: 0; } +.section dd > p:last-child { margin-bottom: 0; } +.section dd { margin-bottom: 1em; } +.section dl.attrs dd, .section dl.eldef dd { margin-bottom: 0; } + +@media print { .removeOnSave { display: none; } } +</style> +<style>/* --- ISSUES/NOTES --- */ +div.issue-title, div.note-title { padding-right: 1em; min-width: 7.5em; color: #b9ab2d; } +div.issue-title { color: #e05252; } +div.note-title { color: #2b2; } +div.issue-title span, div.note-title span { text-transform: uppercase; } +div.note, div.issue { margin-top: 1em; margin-bottom: 1em; } +.note > p:first-child, .issue > p:first-child { margin-top: 0 } +.issue, .note { padding: .5em; border-left-width: .5em; border-left-style: solid; } +div.issue, div.note { padding: 1em 1.2em 0.5em; margin: 1em 0; position: relative; clear: both; } +span.note, span.issue { padding: .1em .5em .15em; } +.issue { border-color: #e05252; background: #fbe9e9; } +.note { border-color: #52e052; background: #e9fbe9; } +</style> +<style>/* HIGHLIGHTS */ +code.prettyprint { color: inherit; } + +/* this from google-code-prettify */ +.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} +</style> +<link rel="stylesheet" href="https://www.w3.org/StyleSheets/TR/w3c-unofficial"> +</head> +<body> + +<section id="abstract"> +<p>The <a href="https://drafts.csswg.org/css-writing-modes/">CSS Writing Modes</a> specification defines a property <code>text-combine-upright</code> which enables a <i>tate-chu-yoko</i> (<span lang="ja">ç¸¦ä¸æ¨ª</span>) effect; applying the property to a span of text will combine the text inside it horizontally so that it looks a single character in vertical writing modes. + +<p>While invesitigating the specification for developing test suite, test authors found the need for a new font specifically designed to test the property. This document gives a fairly basic guide to CSS testing and testing <code>text-combine-upright</code> specifically, and lists the requiremnts of the font needed to test the property. +</section> + +<section> +<h2>CSS testing terminology</h2> +<p>Before getting into the requirements of fonts, let me explain some terms specific to CSS testing. + +<section> +<h3>Reftests (reference tests)</h3> +<p>A <a href="http://testthewebforward.org/docs/reftests.html">reftest</a> are one of the testing format used in W3C and browser vendors for testing features that add visual effects to a page such as CSS and SVG. A reftest are madte of two (or more) files: a test case made using features to test, and reference file(s) made using widely-implemented-and-deployed features (e.g. CSS2). On conforming implementation the reference and the test case will visually match. +<p>For ease of testing, references often use simple geometric shapes such as <a href="http://test.csswg.org/source/css-flexbox-1/reference/flexbox-flex-wrap-nowrap-ref.htm">green square</a>. +<figure> +<iframe src="../../css-flexbox-1/reference/flexbox-flex-wrap-nowrap-ref.htm" frameborder="0" width="400" height="200"></iframe> +<figcaption>A reference of green rectangle, used for a flexbox test</figcaption> +</figure> +</section> + +<section> +<h3>The Ahem font</h3> +<p>In order to test CSS features, it is required to install the <a href="http://www.w3.org/Style/CSS/Test/Fonts/Ahem/">Ahem font</a> in a testing system. The Ahem font only contains simple geometric glyphs such as a square and rectangles. With those simple glyphs it is easy to craft references and test cases. Here's a design specification of Ahem quoting from the README file: +<blockquote cite="http://www.w3.org/Style/CSS/Test/Fonts/Ahem/"> +<pre>The font's em square is exactly square. +Its ascent and descent is exactly the size of the em square. This +means that the font's extent is exactly the same as its line-height, +meaning that it can be exactly aligned with padding, borders, margins, +and so forth. + +The font's alphabetic baseline is 0.2em above its bottom, and 0.8em +below its top. The font has an x-height of 0.8em. + +The font has four glyphs: + + 'X' U+0058 A square exactly 1em in height and width. + + 'p' U+0070 A rectangle exactly 0.2em high, 1em wide, and aligned so + that its top is flush with the baseline. + + 'É' U+00C9 A rectangle exactly 0.8em high, 1em wide, and aligned so + that its bottom is flush with the baseline. + + ' ' U+0020 A transparent space exactly 1em high and wide. + +Most other US-ASCII characters in the font have the same glyph as X.</pre> +</blockquote> +</section> + +</section> + + +<section> +<h2>Testing <code>text-combine-upright</code></h2> +<p>The <a href="https://drafts.csswg.org/css-writing-modes/#text-combine-upright"><code>text-combine-upright</code></a> property combines a short run of text horizontally in vertical writing modes. The resulting effect is called <i>tate-chu-yoko</i> (<span lang="ja">ç¸¦ä¸æ¨ª</span>, sometimes abbreviated as <abbr>TCY</abbr> in CSSWG mailing lists) and used for short digits in vertical Japanese layout. +<figure class="example"> +<img src="https://drafts.csswg.org/css-writing-modes/tate-chu-yoko.png"> +<figcaption>Example of tate-chu-yoko (borrowed from the Writing Modes spec). The digits "20" and "16" are aligned horizontally. Also the digit "4" is rotated upright even it looks an ASCII digit; this is because "4" is also composed thus rotated.</figcaption> +</figure> +<p>In order to make reftests, it needs a font which contains geometric glyphs designed so that horizontally-combined glyphs and the reference would look the same (e.g. a 1em × 1em square glyph). With such font, a test can be written as follows: +<pre class="highlight"><code><style> +.test { + writing-mode: vertical-rl; + font-family: Ahem; +} +.tcy { + text-combine-upright: all; +} +</style> + +<p>Test passes if the following is identical:</p> + +<div class="test"> + <p><span class="tcy">123</span></p> + <p>x</p> +</div></code></pre> +<p>In conforming user agent with the font installed on the system, the span "123" will be combined horizontally thus rendered as a single square, resulting to match the reference. In non-conforming user agents the span will neither be combined nor be compressed as a single square, it will thus not match the reference rendering. +<figure class="example"> +<img src="img/figure-rendering-tcu.svg" width="480"> +<figcaption>An illustration of output from â‘ no-tcu-support UA, â‘¡ conforming UA, â‘¢ reference file</figcaption> +</figure> + +<p>The above example uses Ahem; some tests can be written using Ahem. However, many features of <code>text-combine-upright</code> cannot be tested with only a black square glyph. Also the spec requires UAs with OpenType support to use OpenType features on rendering particular properties; to test this, the font must be an OpenType font with required fetures. +</section> + + +</section> + +<section> +<h2>Glyphs</h2> + +<p>This section describes requirements for glyphs that the font needs and gives some ideas of glyphs. + + +<section> +<h3>Glyphs that can be used as an alternative to Ahem glyphs</h3> +<p>In the prior section we demonstrate how we can test <code>text-combine-upright</code> using Ahem. In some cases tests can be written only using Ahem, but there are cases where we need additional glyphs. +<ul> + <li>A black square is a 1em × 1em square glyph; it is pretty much the same as Ahem's glyph for <code>x</code> + <li>A blank of 1em × 1em +</ul> +<figure> +<img src="img/square_black.svg" width="300"> +<img src="img/square_blank.svg" width="300"> +</figure> + +<p class="note">It might be okay with just using Ahem if tests needing black square only contain codepoints in ASCII-range. +</section> + + +<section> +<h3>Glyphs to check whether a character is rotated or not</h3> +<p><code>text-combine-upright</code> combines a span of text horizontally and make the resulting compression rendered upright, even when the element has just one character. +<p>If the element contains two or more characters, Ahem can be used to check if user agents support composition effect. However, if it is just a single character, Ahem cannot be used since most character in Ahem is a 1em square and thus cannot figure out whether the resulting coposition is rendered upright or not. +<p>Therefore, we need two glyphs where: +<ul> +<li>their widths and heights are 1em +<li>one matches another visually when another rotated 90° counterclockwise +</ul> +<figure> +<img src="img/pointing_right.svg" width="300"> +<img src="img/pointing_up.svg" width="300"> +<figcaption>example glyphs that satisfy the requirements above: "pointing-right" on left and "pointing-up" on right</figcaption> +</figure> +<p class="note">Yes, I stole the glyph idea from <a href="http://blogs.adobe.com/CCJKType/2013/05/css-orientation-test-opentype-fonts.html">CSS Orientation Test</a> font. +<figure> +<pre class="highlight"><code><style> +body { + writing-mode: vertical-rl; + font-family: SomeFont; +} +.test { + text-combine-upright: all; +} +.reference { + text-orientaiton: upright; +} +</style> + +<p class="test">A</p> +<p class="reference">B</p></code></pre> +<figcaption>Test code might look like this</figcaption> +</figure> + +<p class="note">These glyphs are not directly related to TCY so perhaps it should go to CSS Orientation Test font. +</section> + + +<section> +<h3>Glyph to check whether the composition has no text decoration inside it</h3> +<p>In <a href="https://drafts.csswg.org/css-writing-modes/#text-combine-layout">Section 9.1.2 Layout Rules</a> it says: +<blockquote> +When combining text as for text-combine-upright: all, the glyphs of the combined text are composed horizontally (<mark>ignoring letter-spacing and any forced line breaks, but using the specified font settings</mark>), similar to the contents of an inline-box with a horizontal writing mode and a line-height of 1em. +</blockquote> +<p>Later in the section it says: +<blockquote> +For other text layout purposes, e.g. emphasis marks, text-decoration, spacing, etc. the resulting composition is treated as a single glyph representing the Object Replacement Character U+FFFC. +</blockquote> +<p>So we need to test if user agents ignore spacing, emphasis marks, decorations applied to <em>each</em> character inside the composition but rather apply those effects to the resulting composition, treating as if it were a single characeter. +<p>The test should be written to check if there is no emphasis mark or ruby character inside the composition. To make this easy to observe, we need a glyph where: +<ul> +<li>it does not overlap ruby text, emphasis mark, or any decoration +</ul> +<p>The following is an idea for such glyph: it draws overline and underline but does not do so in between them. +<figure> +<img src="img/over_and_under.svg" width="300"> +</figure> +<p>With such glyph, the test would be written as: +<figure> +<pre class="highlight"><code><style> +.test { + writing-mode: vertical-rl; + font-family: TCU-test; +} +.tcy { + text-combine-upright: all; + text-emphasis: sesame; +} +</style> + +<p><span class="tcy">AB</span></p></code></pre> +</figure> +<p>This will make the test reftestable. +<figure> +<img src="img/figure-over_and_under-pass.svg" width="300"> +<img src="img/figure-over_and_under-fail.svg" width="300"> +<figcaption>Conforming user agents apply text-emphasis as if the content inside <code><span class="tcy"></code> were a single character (left). Non-conforming user agents might apply text-emphasis to each character inside <code><span class="tcy"></code> (right)</figcaption> +</figure> +<p class="issue">This glyph cannot cover the assertion <q>the resulting composition is treated as a single glyph representing the Object Replacement Character U+FFFC</q>. Test authors are not sure if that will cause a visual effect that can be tested. +</section> + + +<section> +<h3>Glyphs that is larger than 1em square</h3> +<p>In <a href="https://drafts.csswg.org/css-writing-modes/#text-combine-layout">9.1.2 Layout Rules</a> the spec says: +<blockquote> +The effective size of the composition is assumed to be 1em square; anything outside the square is not measured for layout purposes. +</blockquote> +<p>Hence, we need a glyph where: +<ul> +<li>its size is greater than 1em square +</ul> +<figure> +<img src="img/heavy_h.svg" width="200"> +<!-- <img src="img/heavy_h_rotated.svg" width="200"> --> +<figcaption>The "Heavy H". The dashed region in the center of the glyph indicates the 1em square and the lines besides the square has the length of 3em and the thickness of 1em.</figcaption> +</figure> +<p>By using this glyph with two square glyphs we can make a 3em square. +<figure> +<pre class="highlight"><code><style> +body { + writing-mode: vertical-rl; + font-family: SomeFont; +} +.tcy { + text-combine-upright: all; +} +.reference { + font-size: 3em; + margin: 2em 0; +} +</style> + +<div class="test"> + <p>x<span class="tcy">H</span>x</p> + <p class="reference">x</p> +</div></code></pre> +<figcaption>The test code might look like this: it assumes that a black square glyph maps to <code>x</code> and the "Heavy H" glyph maps to <code>H</code></figcaption> +</figure> +</section> + +<section> +<h3>TBD</h3> +<p>In <a href="https://drafts.csswg.org/css-writing-modes/#text-combine-layout">9.1.2 Layout Rules</a> the spec says: +<blockquote> +The UA should center the glyphs horizontally and vertically within the measured 1em square. +</blockquote> +<p class="issue">work in progress. test authors are struggling with the look of shape(s) to use to create a reftest +<!-- +<p> +<ul> +<li> +</ul> +<figure> +<img src=""> +<figcaption></figcaption> +</figure> +<p> +--> +</section> + + +<section> +<h3>Glyphs to check whether <code><var>n</var>wid</code> OpenType features are used</h3> +<p>In <a href="https://drafts.csswg.org/css-writing-modes/#text-combine-compression">9.1.3 Compression Rules</a> the spec says: +<blockquote> +OpenType implementations must use width-specific variants (OpenType features hwid/twid/qwid; other glyph-width features such as fwid or pwid are not included) to compress text in cases where those variants are available for all characters in the composition. +</blockquote> +<p>In order to test this, we need glyphs for hwid, twid, and qwid; they need to be distinguishable from each other and also distinguishable from fwid/pwid glyphs. For the use in reference, we also need "extended" versions of hwid/twid/qwid glyphs; the widths of the extended version are all 1em. +</ul> + +<section> +<h4>A double stripe</h4> +<p>Used for the <i>hwid</i> feature. +<figure> +<img src="img/stripe_double.svg" width="300"> +<figcaption>double stripe. reference glyph on left, hwid glyph on right.</figure> +</figure> +</section> + +<section> +<h4>A triple stripe</h4> +<p>Used for the <i>twid</i> feature. +<figure> +<img src="img/stripe_triple.svg" width="300"> +<figcaption>triple stripe. reference glyph on left, twid glyph on right.</figure> +</figure> +</section> + +<section> +<h4>A quadruple stripe</h4> +<p>Used for the <i>qwid</i> feature. +<figure> +<img src="img/stripe_quad.svg" width="300"> +<figcaption>quadruple stripe. reference glyph on left, qwid glyph on right.</figure> +</figure> +</section> + +<p class="note">There might be cases where a character inside TCY does not have all features, the font need to have characters that only have (or miss) hwid/twid/qwid feature. Tests need to check combination of characters with different feature sets. + +<p class="issue">Since the processing details of compression rules are up to User Agents, when the resulting glyphs from composition differs from each other, the test can only be verified using negative references. +</section> + + +<section> +<h3>Glyphs to check the optional processing regarding U+6C34</h3> +<p>The last paragraph in <a href="https://drafts.csswg.org/css-writing-modes/#text-combine-compression">9.1.3 Compression Rules</a> says: +<blockquote> +In some fonts, the ideographic glyphs are given a compressed design such that they are 1em wide but shorter than 1em tall. To accommodate such fonts, the UA may vertically scale the the composition to match the advance height of æ°´ U+6C34. +</blockquote> +<p>We need two glyphs: +<ul> +<li>a glyph of horizontal rectangle (e.g. 1em × .8em), mapping to 0x6C34 +<li>a glyph of thinner horizontal rectangle (e.g. 1em × .3em), mapping to a certain codepoint +</ul> + +<p class="note">There is <a href="http://lists.w3.org/Archives/Public/www-style/2014Jul/0310.html">a spec issue</a>. +</section> + + +</section> + + +<section> +<h2>Glyph mappings</h2> + +<p>This section describes which glyph should map to which code points. + +<p class="note">This section is work-in-progress.</p> + +<section> +<h3>Font A <span class="issue">TODO: Name</span></h3> + +<p>Font A contains all glyphs except ones for checking <a href="#glyphs-to-check-whether-nwid-opentype-features-are-used">width-related features</a>.</p> + +<p class="note">Unless otherwise specified, glyphs are mapped to both in horizontal and in vetical (using the <code>vert</code> feature) modes.</p> + +<table class="simple" border> +<tr> +<th>Code Point +<th>Glyph +<th>Note + +<tr> +<td>x (U+0078) +<td>Black +<td> + +<tr> +<td>SPACE (U+0020) +<td>Blank +<td> + +<tr> +<td>R (U+0052) +<td>Pointing Right +<td> + +<tr> +<td>U (U+0055) +<td>Pointing Up +<td> + +<tr> +<td>O (U+004F) +<td>Overline+Underline +<td> + +<tr> +<td>h (U+0048) +<td>Heavy H +<td> + +<tr> +<td>r (U+072) +<td>Pointing Right and Pointing Up +<td> +default: Pointing Right<br> +vert: Pointing Up +</table> + +</section> + +<section> +<h3>Fonts to test width-variant features</h3> + +<p>These fonts test the <a href="#glyphs-to-check-whether-nwid-opentype-features-are-used">width-related features</a>. One font contains only <code>hwid</code> feature, and another contains all the five features (<code>hwid</code>, <code>twid</code>, <code>qwid</code>, <code>fwid</code>, and <code>pwid</code>).</p> + +<p>Below is a table for the latter font; the former (only contains <code>hwid</code> feature) lacks other four features.</p> + +<table class="simple" border> +<tr> +<th>Code Point +<th>Glyph +<th>Note + +<tr> +<td>a (U+0078) +<td>Double Stripe<br>Triple Stripe<br>Quadruple Stripe<br>Black +<td> +hwid: Double Stripe<br> +twid: Triple Stripe<br> +qwid: Quadruple Stripe<br> +fwid: Black<br> +pwid: Black<br> + +<tr> +<td>H (U+0078) +<td>Double Stripe +<td> +Used in reference + +<tr> +<td>T (U+0078) +<td>Triple Stripe +<td> +Used in reference + +<tr> +<td>Q (U+0078) +<td>Quadruple Stripe +<td> +Used in reference +</table> + +</section> + +</section> + + + +<section> +<h2>Acknowledgements</h2> +<p>Special thnks goes to the current and former editors of the Writing Modes specification: fantasai, Koji Ishii, and Shinyu Murakami +<p>In addition to the editors, this work wouldn't have been possible without help from: Taichi Kawabata +</section> + + +<script src='http://www.w3.org/Tools/respec/respec-w3c-common' async class='remove'></script> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/fast/css/hover-after-clicking-embed-expected.txt b/third_party/WebKit/LayoutTests/fast/css/hover-after-clicking-embed-expected.txt index 6cdc248f..ea1908b8 100644 --- a/third_party/WebKit/LayoutTests/fast/css/hover-after-clicking-embed-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/css/hover-after-clicking-embed-expected.txt
@@ -5,6 +5,5 @@ PASS successfullyParsed is true TEST COMPLETE -PASS window.getComputedStyle(document.getElementById("test")).color is "rgb(0, 0, 255)" PASS window.getComputedStyle(document.getElementById("test")).color is "rgb(0, 128, 0)"
diff --git a/third_party/WebKit/LayoutTests/fast/css/hover-after-clicking-embed.html b/third_party/WebKit/LayoutTests/fast/css/hover-after-clicking-embed.html index a75145b..9666c9e 100644 --- a/third_party/WebKit/LayoutTests/fast/css/hover-after-clicking-embed.html +++ b/third_party/WebKit/LayoutTests/fast/css/hover-after-clicking-embed.html
@@ -32,11 +32,6 @@ x = testElement.offsetLeft + testElement.offsetWidth / 2; y = testElement.offsetTop + testElement.offsetHeight / 2; - // Due to how mouse press / hover state is updated, the first mouse move is expected to generate incorrect hover state. - eventSender.mouseMoveTo(x, y); - verify('rgb(0, 0, 255)'); - - eventSender.mouseMoveTo(x - 100, y); eventSender.mouseMoveTo(x, y); verify('rgb(0, 128, 0)'); }
diff --git a/third_party/WebKit/LayoutTests/fast/css/hover-after-drag-expected.txt b/third_party/WebKit/LayoutTests/fast/css/hover-after-drag-expected.txt index 5afbd970..869a090 100644 --- a/third_party/WebKit/LayoutTests/fast/css/hover-after-drag-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/css/hover-after-drag-expected.txt
@@ -6,6 +6,5 @@ TEST COMPLETE PASS window.getComputedStyle(document.getElementById("drag")).color is "rgb(0, 0, 255)" PASS window.getComputedStyle(document.getElementById("drag")).color is "rgb(255, 0, 0)" -PASS window.getComputedStyle(document.getElementById("drag")).color is "rgb(255, 0, 0)" PASS window.getComputedStyle(document.getElementById("drag")).color is "rgb(0, 128, 0)"
diff --git a/third_party/WebKit/LayoutTests/fast/css/hover-after-drag.html b/third_party/WebKit/LayoutTests/fast/css/hover-after-drag.html index 7aed400..75097f2 100644 --- a/third_party/WebKit/LayoutTests/fast/css/hover-after-drag.html +++ b/third_party/WebKit/LayoutTests/fast/css/hover-after-drag.html
@@ -33,11 +33,6 @@ verify('rgb(255, 0, 0)'); eventSender.mouseUp(); - // Due to how mouse press / hover state is updated, the first mouse move is expected to generate incorrect hover state. - eventSender.mouseMoveTo(x, y); - verify('rgb(255, 0, 0)'); - - eventSender.mouseMoveTo(x, y + 200); eventSender.mouseMoveTo(x, y); verify('rgb(0, 128, 0)'); }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/clip-with-layout-delta-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/clip-with-layout-delta-expected.txt index 6dc22e41..658357e 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/clip-with-layout-delta-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/clip-with-layout-delta-expected.txt
@@ -14,7 +14,7 @@ { "object": "LayoutBlockFlow (relative positioned) DIV", "rect": [108, 8, 100, 100], - "reason": "disappeared" + "reason": "chunk reordered" }, { "object": "LayoutBlockFlow DIV", @@ -23,6 +23,16 @@ }, { "object": "LayoutBlockFlow DIV", + "rect": [8, 8, 100, 100], + "reason": "disappeared" + }, + { + "object": "LayoutBlockFlow (relative positioned) DIV", + "rect": [108, 8, 4, 19], + "reason": "disappeared" + }, + { + "object": "LayoutBlockFlow DIV", "rect": [8, 8, 4, 19], "reason": "appeared" }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/float-overflow-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/float-overflow-expected.txt index 2527c0a..d1e1ce6 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/float-overflow-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/float-overflow-expected.txt
@@ -476,94 +476,9 @@ "drawsContent": true, "paintInvalidations": [ { - "object": "LayoutBlockFlow DIV class='outer'", - "rect": [2, 72, 62, 22], - "reason": "geometry" - }, - { - "object": "LayoutBlockFlow DIV class='outer'", - "rect": [2, 66, 62, 22], - "reason": "geometry" - }, - { - "object": "LayoutBlockFlow DIV", - "rect": [8, 78, 50, 10], - "reason": "geometry" - }, - { - "object": "LayoutBlockFlow DIV", - "rect": [8, 72, 50, 10], - "reason": "geometry" - }, - { - "object": "LayoutBlockFlow DIV", - "rect": [8, 39, 50, 10], - "reason": "geometry" - }, - { - "object": "LayoutBlockFlow DIV", - "rect": [8, 33, 50, 10], - "reason": "geometry" - }, - { "object": "LayoutBlockFlow (floating) DIV", - "rect": [0, 78, 40, 10], - "reason": "geometry" - }, - { - "object": "LayoutBlockFlow (floating) DIV", - "rect": [0, 72, 40, 10], - "reason": "geometry" - }, - { - "object": "LayoutBlockFlow (floating) DIV", - "rect": [0, 39, 40, 10], - "reason": "geometry" - }, - { - "object": "LayoutBlockFlow (floating) DIV", - "rect": [0, 33, 40, 10], - "reason": "geometry" - }, - { - "object": "LayoutBlockFlow (floating) DIV", - "rect": [0, 0, 40, 10], - "reason": "geometry" - }, - { - "object": "LayoutBlockFlow (floating) DIV", - "rect": [0, -6, 40, 10], - "reason": "geometry" - }, - { - "object": "InlineTextBox 'x'", - "rect": [0, 80, 16, 17], - "reason": "geometry" - }, - { - "object": "InlineTextBox 'x'", - "rect": [0, 74, 16, 17], - "reason": "geometry" - }, - { - "object": "InlineTextBox 'x'", - "rect": [0, 41, 16, 17], - "reason": "geometry" - }, - { - "object": "InlineTextBox 'x'", - "rect": [0, 35, 16, 17], - "reason": "geometry" - }, - { - "object": "InlineTextBox 'x'", - "rect": [0, 2, 16, 17], - "reason": "geometry" - }, - { - "object": "InlineTextBox 'x'", - "rect": [0, -4, 16, 17], - "reason": "geometry" + "rect": [0, 0, 64, 97], + "reason": "full layer" } ] }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/float-overflow-right-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/float-overflow-right-expected.txt index 8d49645..cc14f0af 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/float-overflow-right-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/float-overflow-right-expected.txt
@@ -476,94 +476,9 @@ "drawsContent": true, "paintInvalidations": [ { - "object": "LayoutBlockFlow DIV class='outer'", - "rect": [0, 72, 62, 22], - "reason": "geometry" - }, - { - "object": "LayoutBlockFlow DIV class='outer'", - "rect": [0, 66, 62, 22], - "reason": "geometry" - }, - { - "object": "LayoutBlockFlow DIV", - "rect": [6, 78, 50, 10], - "reason": "geometry" - }, - { - "object": "LayoutBlockFlow DIV", - "rect": [6, 72, 50, 10], - "reason": "geometry" - }, - { - "object": "LayoutBlockFlow DIV", - "rect": [6, 39, 50, 10], - "reason": "geometry" - }, - { - "object": "LayoutBlockFlow DIV", - "rect": [6, 33, 50, 10], - "reason": "geometry" - }, - { "object": "LayoutBlockFlow (floating) DIV", - "rect": [24, 78, 40, 10], - "reason": "geometry" - }, - { - "object": "LayoutBlockFlow (floating) DIV", - "rect": [24, 72, 40, 10], - "reason": "geometry" - }, - { - "object": "LayoutBlockFlow (floating) DIV", - "rect": [24, 39, 40, 10], - "reason": "geometry" - }, - { - "object": "LayoutBlockFlow (floating) DIV", - "rect": [24, 33, 40, 10], - "reason": "geometry" - }, - { - "object": "LayoutBlockFlow (floating) DIV", - "rect": [24, 0, 40, 10], - "reason": "geometry" - }, - { - "object": "LayoutBlockFlow (floating) DIV", - "rect": [24, -6, 40, 10], - "reason": "geometry" - }, - { - "object": "InlineTextBox 'x'", - "rect": [48, 80, 16, 17], - "reason": "geometry" - }, - { - "object": "InlineTextBox 'x'", - "rect": [48, 74, 16, 17], - "reason": "geometry" - }, - { - "object": "InlineTextBox 'x'", - "rect": [48, 41, 16, 17], - "reason": "geometry" - }, - { - "object": "InlineTextBox 'x'", - "rect": [48, 35, 16, 17], - "reason": "geometry" - }, - { - "object": "InlineTextBox 'x'", - "rect": [48, 2, 16, 17], - "reason": "geometry" - }, - { - "object": "InlineTextBox 'x'", - "rect": [48, -4, 16, 17], - "reason": "geometry" + "rect": [0, 0, 64, 97], + "reason": "full layer" } ] }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/hover-pseudo-borders-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/hover-pseudo-borders-expected.txt index 0ce7114..c40943e3 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/hover-pseudo-borders-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/hover-pseudo-borders-expected.txt
@@ -12,26 +12,6 @@ "reason": "style change" }, { - "object": "LayoutBlockFlow (positioned) \u003Cpseudo:after\u003E", - "rect": [138, 8, 100, 100], - "reason": "style change" - }, - { - "object": "LayoutBlockFlow (positioned) \u003Cpseudo:after\u003E", - "rect": [138, 8, 100, 100], - "reason": "style change" - }, - { - "object": "LayoutBlockFlow DIV class='hitregion'", - "rect": [8, 8, 100, 100], - "reason": "style change" - }, - { - "object": "LayoutBlockFlow DIV class='hitregion'", - "rect": [8, 8, 100, 100], - "reason": "style change" - }, - { "object": "LayoutBlockFlow DIV class='hitregion'", "rect": [8, 8, 100, 100], "reason": "style change"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/multi-layout-one-frame-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/multi-layout-one-frame-expected.txt index 181ae38..9a9e113 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/multi-layout-one-frame-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/multi-layout-one-frame-expected.txt
@@ -7,11 +7,6 @@ "drawsContent": true, "paintInvalidations": [ { - "object": "InlineTextBox '\n'", - "rect": [162, 8, 158, 22], - "reason": "full" - }, - { "object": "InlineTextBox 'PASSED'", "rect": [168, 11, 53, 16], "reason": "appeared"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/overflow-hidden-in-overflow-hidden-scrolled-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/overflow-hidden-in-overflow-hidden-scrolled-expected.txt index 13fdaf9..79389ffc 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/overflow-hidden-in-overflow-hidden-scrolled-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/overflow-hidden-in-overflow-hidden-scrolled-expected.txt
@@ -10,6 +10,11 @@ "object": "LayoutBlockFlow DIV class='innerWrapper'", "rect": [8, 18, 100, 190], "reason": "appeared" + }, + { + "object": "LayoutBlockFlow DIV class='innerWrapper'", + "rect": [8, 18, 100, 190], + "reason": "disappeared" } ] }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/overflow-scroll-composited-non-stacking-child-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/overflow-scroll-composited-non-stacking-child-expected.txt index 917cf6cc..c49bfed 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/overflow-scroll-composited-non-stacking-child-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/overflow-scroll-composited-non-stacking-child-expected.txt
@@ -9,12 +9,12 @@ { "object": "LayoutBlockFlow DIV class='scroller'", "rect": [18, 60, 310, 200], - "reason": "full" + "reason": "subtree" }, { "object": "LayoutBlockFlow DIV class='scroller'", "rect": [18, 60, 310, 200], - "reason": "full" + "reason": "subtree" }, { "object": "LayoutBlockFlow (positioned) DIV class='back'",
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/scroll-in-clipped-layer-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/scroll-in-clipped-layer-expected.txt index e224742..1a3156c 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/scroll-in-clipped-layer-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/scroll-in-clipped-layer-expected.txt
@@ -7,6 +7,11 @@ "drawsContent": true, "paintInvalidations": [ { + "object": "LayoutBlockFlow (positioned) DIV class='absolute red'", + "rect": [100, 150, 100, 100], + "reason": "disappeared" + }, + { "object": "LayoutBlockFlow (relative positioned) DIV class='relative green'", "rect": [100, 150, 100, 100], "reason": "appeared"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/scroll-inside-table-cell-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/scroll-inside-table-cell-expected.txt index d449ac9..f713bf1 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/scroll-inside-table-cell-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/scroll-inside-table-cell-expected.txt
@@ -9,7 +9,7 @@ { "object": "LayoutTableCell (relative positioned) TD id='cellToScroll' class='relative'", "rect": [312, 112, 454, 469], - "reason": "full" + "reason": "subtree" }, { "object": "LayoutTableCell (relative positioned) TD id='cellToScroll' class='relative'", @@ -22,6 +22,11 @@ "reason": "appeared" }, { + "object": "LayoutBlockFlow (relative positioned) DIV class='relative red'", + "rect": [314, 114, 435, 450], + "reason": "disappeared" + }, + { "object": "HorizontalScrollbar", "rect": [314, 564, 435, 15], "reason": "scroll control"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/scroll-relative-table-inside-table-cell-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/scroll-relative-table-inside-table-cell-expected.txt index 8c10c7f..b4a6f34 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/scroll-relative-table-inside-table-cell-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/scroll-relative-table-inside-table-cell-expected.txt
@@ -9,7 +9,7 @@ { "object": "LayoutTableCell (relative positioned) TD id='cellToScroll' class='relative'", "rect": [1112, 1312, 454, 469], - "reason": "full" + "reason": "subtree" }, { "object": "LayoutTableCell (relative positioned) TD id='cellToScroll' class='relative'", @@ -22,6 +22,11 @@ "reason": "appeared" }, { + "object": "LayoutBlockFlow (relative positioned) DIV class='relative red'", + "rect": [1114, 1314, 435, 450], + "reason": "disappeared" + }, + { "object": "HorizontalScrollbar", "rect": [1114, 1764, 435, 15], "reason": "scroll control"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/scrollbar-invalidation-on-resize-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/scrollbar-invalidation-on-resize-expected.txt index 986851e..66fd6fb9 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/scrollbar-invalidation-on-resize-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/scrollbar-invalidation-on-resize-expected.txt
@@ -9,7 +9,7 @@ { "object": "LayoutBlockFlow (positioned) DIV id='scrollable'", "rect": [8, 50, 300, 100], - "reason": "full" + "reason": "geometry" }, { "object": "HorizontalScrollbar",
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/scrollbar-invalidation-on-resize-with-border-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/scrollbar-invalidation-on-resize-with-border-expected.txt index 06fda6f..02ca92aa 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/scrollbar-invalidation-on-resize-with-border-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/scrollbar-invalidation-on-resize-with-border-expected.txt
@@ -9,7 +9,7 @@ { "object": "LayoutBlockFlow (positioned) DIV id='scrollable'", "rect": [8, 50, 320, 120], - "reason": "full" + "reason": "geometry" }, { "object": "LayoutBlockFlow (positioned) DIV id='scrollable'",
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/absolute-sized-document-no-scrollbars-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/absolute-sized-document-no-scrollbars-expected.txt index 47647db..dabffbf 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/absolute-sized-document-no-scrollbars-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/absolute-sized-document-no-scrollbars-expected.txt
@@ -10,6 +10,11 @@ "object": "LayoutSVGRoot svg", "rect": [-1, -1, 578, 434], "reason": "appeared" + }, + { + "object": "LayoutSVGRoot svg", + "rect": [-1, -1, 482, 362], + "reason": "disappeared" } ] }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/circle-move-invalidation-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/circle-move-invalidation-expected.txt index 1fc3749..ea8502b 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/circle-move-invalidation-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/circle-move-invalidation-expected.txt
@@ -7,11 +7,6 @@ "drawsContent": true, "paintInvalidations": [ { - "object": "InlineTextBox '\n'", - "rect": [8, 295, 552, 55], - "reason": "full" - }, - { "object": "LayoutSVGEllipse circle id='c1'", "rect": [196, 196, 76, 76], "reason": "full"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/color-fill-currentColor-and-css-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/color-fill-currentColor-and-css-expected.txt index 4b194ec..ea1bedb2 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/color-fill-currentColor-and-css-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/color-fill-currentColor-and-css-expected.txt
@@ -15,11 +15,6 @@ "object": "LayoutSVGEllipse circle", "rect": [8, 8, 80, 80], "reason": "style change" - }, - { - "object": "LayoutSVGEllipse circle", - "rect": [8, 8, 80, 80], - "reason": "style change" } ] }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/inner-svg-change-viewPort-relative-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/inner-svg-change-viewPort-relative-expected.txt index 9c90f2cb..5d20e08 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/inner-svg-change-viewPort-relative-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/inner-svg-change-viewPort-relative-expected.txt
@@ -14,7 +14,17 @@ { "object": "InlineTextBox 'right-aligned text'", "rect": [93, 85, 107, 19], - "reason": "full" + "reason": "appeared" + }, + { + "object": "InlineTextBox 'right-aligned text'", + "rect": [0, 85, 101, 19], + "reason": "disappeared" + }, + { + "object": "LayoutSVGContainer use", + "rect": [180, 120, 20, 20], + "reason": "chunk reordered" }, { "object": "LayoutSVGRect rect", @@ -22,6 +32,11 @@ "reason": "full" }, { + "object": "LayoutSVGContainer use", + "rect": [80, 120, 20, 20], + "reason": "chunk reordered" + }, + { "object": "LayoutSVGRect rect", "rect": [80, 60, 20, 20], "reason": "full"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-document-scrollbars-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-document-scrollbars-expected.txt index c4977ee..937546dd 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-document-scrollbars-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-document-scrollbars-expected.txt
@@ -10,6 +10,11 @@ "object": "LayoutSVGRoot svg", "rect": [6, 2, 788, 595], "reason": "appeared" + }, + { + "object": "LayoutSVGRoot svg", + "rect": [6, 4, 788, 592], + "reason": "disappeared" } ] }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-shadow-tree-content-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-shadow-tree-content-expected.txt index c988ee54..5f143aa3 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-shadow-tree-content-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-shadow-tree-content-expected.txt
@@ -19,7 +19,7 @@ { "object": "LayoutSVGRect rect id='targetRect1'", "rect": [9, 73, 200, 200], - "reason": "full" + "reason": "geometry" } ] }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/resource-client-removal-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/resource-client-removal-expected.txt index 6f91ebb..4fdf38b 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/resource-client-removal-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/resource-client-removal-expected.txt
@@ -34,26 +34,6 @@ { "object": "LayoutSVGPath path id='hp'", "rect": [0, 0, 100, 100], - "reason": "appeared" - }, - { - "object": "LayoutSVGPath path id='hp'", - "rect": [0, 0, 100, 100], - "reason": "appeared" - }, - { - "object": "LayoutSVGPath path id='hp'", - "rect": [0, 0, 100, 100], - "reason": "appeared" - }, - { - "object": "LayoutSVGPath path id='hp'", - "rect": [0, 0, 100, 100], - "reason": "appeared" - }, - { - "object": "LayoutSVGPath path id='hp'", - "rect": [0, 0, 100, 100], "reason": "disappeared" }, { @@ -79,46 +59,6 @@ { "object": "LayoutSVGPath path id='hp'", "rect": [0, 0, 100, 100], - "reason": "disappeared" - }, - { - "object": "LayoutSVGPath path id='hp'", - "rect": [0, 0, 100, 100], - "reason": "disappeared" - }, - { - "object": "LayoutSVGPath path id='hp'", - "rect": [0, 0, 100, 100], - "reason": "disappeared" - }, - { - "object": "LayoutSVGPath path id='hp'", - "rect": [0, 0, 100, 100], - "reason": "disappeared" - }, - { - "object": "LayoutSVGPath path id='hp'", - "rect": [0, 0, 100, 100], - "reason": "SVG resource change" - }, - { - "object": "LayoutSVGPath path id='hp'", - "rect": [0, 0, 100, 100], - "reason": "SVG resource change" - }, - { - "object": "LayoutSVGPath path id='hp'", - "rect": [0, 0, 100, 100], - "reason": "SVG resource change" - }, - { - "object": "LayoutSVGPath path id='hp'", - "rect": [0, 0, 100, 100], - "reason": "SVG resource change" - }, - { - "object": "LayoutSVGPath path id='hp'", - "rect": [0, 0, 100, 100], "reason": "SVG resource change" }, {
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/use-setAttribute-crash-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/use-setAttribute-crash-expected.txt index 5e6cf162..4f26a5de 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/use-setAttribute-crash-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/use-setAttribute-crash-expected.txt
@@ -10,6 +10,11 @@ "object": "LayoutSVGEllipse svg:circle id='circle'", "rect": [27, 27, 62, 62], "reason": "appeared" + }, + { + "object": "LayoutSVGEllipse svg:circle id='circle'", + "rect": [51, 51, 14, 14], + "reason": "disappeared" } ] }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt index 7c729cd..4be70bb 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt
@@ -16,7 +16,7 @@ { "object": "LayoutTableSection TBODY id='target'", "rect": [0, 0, 186, 134], - "reason": "appeared" + "reason": "full layer" } ] },
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/svg/overflow-repaint-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/svg/overflow-repaint-expected.txt new file mode 100644 index 0000000..dd91964 --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/invalidation/svg/overflow-repaint-expected.txt
@@ -0,0 +1,46 @@ +{ + "layers": [ + { + "name": "LayoutView #document", + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "paintInvalidations": [ + { + "object": "LayoutSVGRoot svg id='svg'", + "rect": [8, 8, 100, 200], + "reason": "style change" + }, + { + "object": "LayoutSVGRect rect", + "rect": [8, 108, 100, 100], + "reason": "appeared" + }, + { + "object": "LayoutBlockFlow DIV", + "rect": [8, 8, 100, 100], + "reason": "geometry" + } + ] + } + ], + "objectPaintInvalidations": [ + { + "object": "LayoutBlockFlow DIV", + "reason": "geometry" + }, + { + "object": "RootInlineBox", + "reason": "geometry" + }, + { + "object": "LayoutSVGRoot svg id='svg'", + "reason": "style change" + }, + { + "object": "LayoutSVGRect rect", + "reason": "appeared" + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/svg/overflow-repaint.html b/third_party/WebKit/LayoutTests/paint/invalidation/svg/overflow-repaint.html index 183dde27..85940a4 100644 --- a/third_party/WebKit/LayoutTests/paint/invalidation/svg/overflow-repaint.html +++ b/third_party/WebKit/LayoutTests/paint/invalidation/svg/overflow-repaint.html
@@ -2,7 +2,6 @@ <head> <script src="../resources/text-based-repaint.js" type="text/javascript"></script> <script> - window.outputRepaintRects = false; function repaintTest() { document.getElementById("svg").style.overflow="visible"; }
diff --git a/third_party/WebKit/LayoutTests/platform/linux/compositing/masks/mask-with-removed-filters-expected.png b/third_party/WebKit/LayoutTests/platform/linux/compositing/masks/mask-with-removed-filters-expected.png index 14c7efa..d74c112 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/compositing/masks/mask-with-removed-filters-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/compositing/masks/mask-with-removed-filters-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/compositing/overflow/tiled-mask-expected.png b/third_party/WebKit/LayoutTests/platform/linux/compositing/overflow/tiled-mask-expected.png index ba320740..f0d3620c4 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/compositing/overflow/tiled-mask-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/compositing/overflow/tiled-mask-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/compositing/text-on-scaled-surface-expected.png b/third_party/WebKit/LayoutTests/platform/linux/compositing/text-on-scaled-surface-expected.png new file mode 100644 index 0000000..c6129603 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/compositing/text-on-scaled-surface-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-radius-mask-video-ratio-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-radius-mask-video-ratio-expected.png index c2adc3cd..b9c4cb24 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-radius-mask-video-ratio-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-radius-mask-video-ratio-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-radius-mask-video-shadow-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-radius-mask-video-shadow-expected.png index 5021baf6..8f8a62a 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-radius-mask-video-shadow-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-radius-mask-video-shadow-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/compositing/masks/mask-with-removed-filters-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/compositing/masks/mask-with-removed-filters-expected.png new file mode 100644 index 0000000..d74c112 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/compositing/masks/mask-with-removed-filters-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/compositing/overflow/tiled-mask-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/compositing/overflow/tiled-mask-expected.png new file mode 100644 index 0000000..f0d3620c4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/compositing/overflow/tiled-mask-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/compositing/text-on-scaled-surface-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/compositing/text-on-scaled-surface-expected.png new file mode 100644 index 0000000..c6129603 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/compositing/text-on-scaled-surface-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/prefer_compositing_to_lcd_text/compositing/overflow/tiled-mask-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/prefer_compositing_to_lcd_text/compositing/overflow/tiled-mask-expected.png index ba320740..f0d3620c4 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/prefer_compositing_to_lcd_text/compositing/overflow/tiled-mask-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/prefer_compositing_to_lcd_text/compositing/overflow/tiled-mask-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/off-main-thread-fetch/external/wpt/service-workers/service-worker/fetch-canvas-tainting.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/off-main-thread-fetch/external/wpt/service-workers/service-worker/fetch-canvas-tainting.https-expected.txt new file mode 100644 index 0000000..d639d286 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/off-main-thread-fetch/external/wpt/service-workers/service-worker/fetch-canvas-tainting.https-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Verify canvas tainting of fetched image in a Service Worker assert_equals: expected "finish" but got "failure:Result of url:https://web-platform.test:8444/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2Fwww1.web-platform.test%3A8444%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Fweb-platform.test%3A8444 cross_origin: use-credentials must be LOAD_ERROR but NOT_TAINTED" +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/off-main-thread-fetch/external/wpt/service-workers/service-worker/fetch-canvas-tainting.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/off-main-thread-fetch/external/wpt/service-workers/service-worker/fetch-canvas-tainting.https-expected.txt new file mode 100644 index 0000000..d639d286 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/off-main-thread-fetch/external/wpt/service-workers/service-worker/fetch-canvas-tainting.https-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Verify canvas tainting of fetched image in a Service Worker assert_equals: expected "finish" but got "failure:Result of url:https://web-platform.test:8444/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&url=https%3A%2F%2Fwww1.web-platform.test%3A8444%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Fweb-platform.test%3A8444 cross_origin: use-credentials must be LOAD_ERROR but NOT_TAINTED" +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/platform/mac/compositing/masks/mask-with-removed-filters-expected.png b/third_party/WebKit/LayoutTests/platform/mac/compositing/masks/mask-with-removed-filters-expected.png index 5b568110..0481bdbb 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/compositing/masks/mask-with-removed-filters-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/compositing/masks/mask-with-removed-filters-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/compositing/overflow/tiled-mask-expected.png b/third_party/WebKit/LayoutTests/platform/mac/compositing/overflow/tiled-mask-expected.png index ba320740..f0d3620c4 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/compositing/overflow/tiled-mask-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/compositing/overflow/tiled-mask-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/compositing/text-on-scaled-surface-expected.png b/third_party/WebKit/LayoutTests/platform/mac/compositing/text-on-scaled-surface-expected.png new file mode 100644 index 0000000..94cb2fbf --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/compositing/text-on-scaled-surface-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-radius-mask-video-ratio-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-radius-mask-video-ratio-expected.png index 7c9dd39..0ac166cc 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-radius-mask-video-ratio-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-radius-mask-video-ratio-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-radius-mask-video-shadow-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-radius-mask-video-shadow-expected.png index 34365e4d..a064404 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-radius-mask-video-shadow-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-radius-mask-video-shadow-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/masks/mask-with-removed-filters-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/masks/mask-with-removed-filters-expected.png new file mode 100644 index 0000000..0481bdbb --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/masks/mask-with-removed-filters-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/overflow/tiled-mask-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/overflow/tiled-mask-expected.png new file mode 100644 index 0000000..f0d3620c4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/overflow/tiled-mask-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/text-on-scaled-surface-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/text-on-scaled-surface-expected.png new file mode 100644 index 0000000..94cb2fbf --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/compositing/text-on-scaled-surface-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/off-main-thread-fetch/external/wpt/service-workers/service-worker/fetch-canvas-tainting.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/off-main-thread-fetch/external/wpt/service-workers/service-worker/fetch-canvas-tainting.https-expected.txt new file mode 100644 index 0000000..a4b6320 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/off-main-thread-fetch/external/wpt/service-workers/service-worker/fetch-canvas-tainting.https-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Verify canvas tainting of fetched image in a Service Worker assert_equals: expected "finish" but got "failure:Result of url:https://www1.web-platform.test:8444/service-workers/service-worker/resources/fetch-access-control.py?PNGIMAGE&mode=cors&credentials=same-origin&url=https%3A%2F%2Fwww1.web-platform.test%3A8444%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FPNGIMAGE%26ACAOrigin%3Dhttps%3A%2F%2Fweb-platform.test%3A8444 cross_origin: must be TAINTED but NOT_TAINTED" +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/prefer_compositing_to_lcd_text/compositing/overflow/tiled-mask-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/prefer_compositing_to_lcd_text/compositing/overflow/tiled-mask-expected.png index ba320740..f0d3620c4 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/prefer_compositing_to_lcd_text/compositing/overflow/tiled-mask-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/prefer_compositing_to_lcd_text/compositing/overflow/tiled-mask-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/compositing/masks/mask-with-removed-filters-expected.png b/third_party/WebKit/LayoutTests/platform/win/compositing/masks/mask-with-removed-filters-expected.png index 8079d94b..a469aba 100644 --- a/third_party/WebKit/LayoutTests/platform/win/compositing/masks/mask-with-removed-filters-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/compositing/masks/mask-with-removed-filters-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/compositing/overflow/tiled-mask-expected.png b/third_party/WebKit/LayoutTests/platform/win/compositing/overflow/tiled-mask-expected.png index 005e10d..c79b681 100644 --- a/third_party/WebKit/LayoutTests/platform/win/compositing/overflow/tiled-mask-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/compositing/overflow/tiled-mask-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/compositing/text-on-scaled-surface-expected.png b/third_party/WebKit/LayoutTests/platform/win/compositing/text-on-scaled-surface-expected.png new file mode 100644 index 0000000..7dad5c3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/compositing/text-on-scaled-surface-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-radius-mask-video-ratio-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-radius-mask-video-ratio-expected.png index 4959247..3bb34d3 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-radius-mask-video-ratio-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-radius-mask-video-ratio-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-radius-mask-video-shadow-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-radius-mask-video-shadow-expected.png index 4ad5437..86f6aca 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-radius-mask-video-shadow-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-radius-mask-video-shadow-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/compositing/masks/mask-with-removed-filters-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/compositing/masks/mask-with-removed-filters-expected.png new file mode 100644 index 0000000..a469aba --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/compositing/masks/mask-with-removed-filters-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/compositing/overflow/tiled-mask-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/compositing/overflow/tiled-mask-expected.png new file mode 100644 index 0000000..c79b681 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/compositing/overflow/tiled-mask-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/compositing/text-on-scaled-surface-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/compositing/text-on-scaled-surface-expected.png new file mode 100644 index 0000000..7dad5c3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/compositing/text-on-scaled-surface-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/prefer_compositing_to_lcd_text/compositing/overflow/tiled-mask-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/prefer_compositing_to_lcd_text/compositing/overflow/tiled-mask-expected.png index 005e10d..c79b681 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/prefer_compositing_to_lcd_text/compositing/overflow/tiled-mask-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/prefer_compositing_to_lcd_text/compositing/overflow/tiled-mask-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt index f2a2a06..e937fac1 100644 --- a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt
@@ -16,6 +16,7 @@ method constructor interface AccessibleNode attribute @@toStringTag + getter activeDescendant getter atomic getter autocomplete getter busy @@ -24,7 +25,9 @@ getter colIndex getter colSpan getter current + getter details getter disabled + getter errorMessage getter expanded getter hidden getter invalid @@ -55,6 +58,7 @@ getter valueNow getter valueText method constructor + setter activeDescendant setter atomic setter autocomplete setter busy @@ -63,7 +67,9 @@ setter colIndex setter colSpan setter current + setter details setter disabled + setter errorMessage setter expanded setter hidden setter invalid
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt index b64c7cba..ce2a04f 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -16,6 +16,7 @@ method constructor interface AccessibleNode attribute @@toStringTag + getter activeDescendant getter atomic getter autocomplete getter busy @@ -24,7 +25,9 @@ getter colIndex getter colSpan getter current + getter details getter disabled + getter errorMessage getter expanded getter hidden getter invalid @@ -55,6 +58,7 @@ getter valueNow getter valueText method constructor + setter activeDescendant setter atomic setter autocomplete setter busy @@ -63,7 +67,9 @@ setter colIndex setter colSpan setter current + setter details setter disabled + setter errorMessage setter expanded setter hidden setter invalid
diff --git a/third_party/WebKit/Source/core/BUILD.gn b/third_party/WebKit/Source/core/BUILD.gn index fb2cea90..eefc614 100644 --- a/third_party/WebKit/Source/core/BUILD.gn +++ b/third_party/WebKit/Source/core/BUILD.gn
@@ -3,6 +3,7 @@ # found in the LICENSE file. import("//build/config/chromecast_build.gni") +import("//build/config/compiler/compiler.gni") import("//build/toolchain/toolchain.gni") import("//build/config/ui.gni") import("//build/split_static_library.gni") @@ -207,12 +208,14 @@ "//third_party/WebKit/Source/core/xmlhttprequest", ] - if (is_win && is_debug && is_component_build && current_cpu == "x64") { - # Incremental linking doesn't work on this target in debug mode for - # 64-bit builds - the .ilk file gets too large and the incremental - # link silently fails. Therefore 32-bit builds or 64-bit release builds - # (component either way) should be used for fastest incremental build - # performance. VC++ bug filed for 64-bit debug incremental link failures: + if (is_win && is_debug && is_component_build && + (current_cpu == "x64" || is_clang)) { + # Incremental linking fails when the .ilk file gets too large. + # 64-bit debug builds and Clang builds with full symbols trigger this + # problem, so we turn off incremental linking in those configurations. + # For fastest builds, use component release builds without debug + # information. + # VC++ bug filed for 64-bit debug incremental link failures: # https://connect.microsoft.com/VisualStudio/feedback/details/2846790 configs -= [ "//build/config/win:default_incremental_linking" ] configs += [ "//build/config/win:no_incremental_linking" ]
diff --git a/third_party/WebKit/Source/core/dom/AccessibleNode.cpp b/third_party/WebKit/Source/core/dom/AccessibleNode.cpp index 0d387847..05f23c0 100644 --- a/third_party/WebKit/Source/core/dom/AccessibleNode.cpp +++ b/third_party/WebKit/Source/core/dom/AccessibleNode.cpp
@@ -13,6 +13,167 @@ using namespace HTMLNames; +namespace { + +QualifiedName GetCorrespondingARIAAttribute(AOMStringProperty property) { + switch (property) { + case AOMStringProperty::kAutocomplete: + return aria_autocompleteAttr; + case AOMStringProperty::kChecked: + return aria_checkedAttr; + case AOMStringProperty::kCurrent: + return aria_currentAttr; + case AOMStringProperty::kInvalid: + return aria_invalidAttr; + case AOMStringProperty::kKeyShortcuts: + return aria_keyshortcutsAttr; + case AOMStringProperty::kLabel: + return aria_labelAttr; + case AOMStringProperty::kLive: + return aria_liveAttr; + case AOMStringProperty::kOrientation: + return aria_orientationAttr; + case AOMStringProperty::kPlaceholder: + return aria_placeholderAttr; + case AOMStringProperty::kPressed: + return aria_pressedAttr; + case AOMStringProperty::kRelevant: + return aria_relevantAttr; + case AOMStringProperty::kRole: + return roleAttr; + case AOMStringProperty::kRoleDescription: + return aria_roledescriptionAttr; + case AOMStringProperty::kSort: + return aria_sortAttr; + case AOMStringProperty::kValueText: + return aria_valuetextAttr; + } + + NOTREACHED(); + return g_null_name; +} + +QualifiedName GetCorrespondingARIAAttribute(AOMRelationProperty property) { + switch (property) { + case AOMRelationProperty::kActiveDescendant: + return aria_activedescendantAttr; + break; + case AOMRelationProperty::kDetails: + return aria_detailsAttr; + break; + case AOMRelationProperty::kErrorMessage: + return aria_errormessageAttr; + break; + } + + NOTREACHED(); + return g_null_name; +} + +QualifiedName GetCorrespondingARIAAttribute(AOMBooleanProperty property) { + switch (property) { + case AOMBooleanProperty::kAtomic: + return aria_atomicAttr; + break; + case AOMBooleanProperty::kBusy: + return aria_busyAttr; + break; + case AOMBooleanProperty::kDisabled: + return aria_disabledAttr; + break; + case AOMBooleanProperty::kExpanded: + return aria_expandedAttr; + break; + case AOMBooleanProperty::kHidden: + return aria_hiddenAttr; + break; + case AOMBooleanProperty::kModal: + return aria_modalAttr; + break; + case AOMBooleanProperty::kMultiline: + return aria_multilineAttr; + break; + case AOMBooleanProperty::kMultiselectable: + return aria_multiselectableAttr; + break; + case AOMBooleanProperty::kReadOnly: + return aria_readonlyAttr; + break; + case AOMBooleanProperty::kRequired: + return aria_requiredAttr; + break; + case AOMBooleanProperty::kSelected: + return aria_selectedAttr; + break; + } + + NOTREACHED(); + return g_null_name; +} + +QualifiedName GetCorrespondingARIAAttribute(AOMFloatProperty property) { + AtomicString attr_value; + switch (property) { + case AOMFloatProperty::kValueMax: + return aria_valuemaxAttr; + break; + case AOMFloatProperty::kValueMin: + return aria_valueminAttr; + break; + case AOMFloatProperty::kValueNow: + return aria_valuenowAttr; + break; + } + + NOTREACHED(); + return g_null_name; +} + +QualifiedName GetCorrespondingARIAAttribute(AOMUIntProperty property) { + switch (property) { + case AOMUIntProperty::kColIndex: + return aria_colindexAttr; + break; + case AOMUIntProperty::kColSpan: + return aria_colspanAttr; + break; + case AOMUIntProperty::kLevel: + return aria_levelAttr; + break; + case AOMUIntProperty::kPosInSet: + return aria_posinsetAttr; + break; + case AOMUIntProperty::kRowIndex: + return aria_rowindexAttr; + break; + case AOMUIntProperty::kRowSpan: + return aria_rowspanAttr; + break; + } + + NOTREACHED(); + return g_null_name; +} + +QualifiedName GetCorrespondingARIAAttribute(AOMIntProperty property) { + switch (property) { + case AOMIntProperty::kColCount: + return aria_colcountAttr; + break; + case AOMIntProperty::kRowCount: + return aria_rowcountAttr; + break; + case AOMIntProperty::kSetSize: + return aria_setsizeAttr; + break; + } + + NOTREACHED(); + return g_null_name; +} + +} // namespace + AccessibleNode::AccessibleNode(Element* element) : element_(element) { DCHECK(RuntimeEnabledFeatures::AccessibilityObjectModelEnabled()); } @@ -35,6 +196,22 @@ return g_null_atom; } +// static +AccessibleNode* AccessibleNode::GetProperty(Element* element, + AOMRelationProperty property) { + if (!element) + return nullptr; + + if (AccessibleNode* accessible_node = element->ExistingAccessibleNode()) { + for (const auto& item : accessible_node->relation_properties_) { + if (item.first == property && item.second) + return item.second; + } + } + + return nullptr; +} + template <typename P, typename T> static T FindPropertyValue(P property, bool& is_null, @@ -122,41 +299,28 @@ return result; // Fall back on the equivalent ARIA attribute. - switch (property) { - case AOMStringProperty::kAutocomplete: - return element->FastGetAttribute(aria_autocompleteAttr); - case AOMStringProperty::kChecked: - return element->FastGetAttribute(aria_checkedAttr); - case AOMStringProperty::kCurrent: - return element->FastGetAttribute(aria_currentAttr); - case AOMStringProperty::kInvalid: - return element->FastGetAttribute(aria_invalidAttr); - case AOMStringProperty::kKeyShortcuts: - return element->FastGetAttribute(aria_keyshortcutsAttr); - case AOMStringProperty::kLabel: - return element->FastGetAttribute(aria_labelAttr); - case AOMStringProperty::kLive: - return element->FastGetAttribute(aria_liveAttr); - case AOMStringProperty::kOrientation: - return element->FastGetAttribute(aria_orientationAttr); - case AOMStringProperty::kPlaceholder: - return element->FastGetAttribute(aria_placeholderAttr); - case AOMStringProperty::kPressed: - return element->FastGetAttribute(aria_pressedAttr); - case AOMStringProperty::kRelevant: - return element->FastGetAttribute(aria_relevantAttr); - case AOMStringProperty::kRole: - return element->FastGetAttribute(roleAttr); - case AOMStringProperty::kRoleDescription: - return element->FastGetAttribute(aria_roledescriptionAttr); - case AOMStringProperty::kSort: - return element->FastGetAttribute(aria_sortAttr); - case AOMStringProperty::kValueText: - return element->FastGetAttribute(aria_valuetextAttr); - } + QualifiedName attribute = GetCorrespondingARIAAttribute(property); + return element->FastGetAttribute(attribute); +} - NOTREACHED(); - return g_null_atom; +// static +AccessibleNode* AccessibleNode::GetPropertyOrARIAAttribute( + Element* element, + AOMRelationProperty property) { + if (!element) + return nullptr; + + if (AccessibleNode* result = GetProperty(element, property)) + return result; + + // Fall back on the equivalent ARIA attribute. + QualifiedName attribute = GetCorrespondingARIAAttribute(property); + AtomicString value = element->FastGetAttribute(attribute); + Element* target = element->GetTreeScope().getElementById(value); + if (!target) + return nullptr; + + return target->accessibleNode(); } // static @@ -172,43 +336,8 @@ return result; // Fall back on the equivalent ARIA attribute. - AtomicString attr_value; - switch (property) { - case AOMBooleanProperty::kAtomic: - attr_value = element->FastGetAttribute(aria_atomicAttr); - break; - case AOMBooleanProperty::kBusy: - attr_value = element->FastGetAttribute(aria_busyAttr); - break; - case AOMBooleanProperty::kDisabled: - attr_value = element->FastGetAttribute(aria_disabledAttr); - break; - case AOMBooleanProperty::kExpanded: - attr_value = element->FastGetAttribute(aria_expandedAttr); - break; - case AOMBooleanProperty::kHidden: - attr_value = element->FastGetAttribute(aria_hiddenAttr); - break; - case AOMBooleanProperty::kModal: - attr_value = element->FastGetAttribute(aria_modalAttr); - break; - case AOMBooleanProperty::kMultiline: - attr_value = element->FastGetAttribute(aria_multilineAttr); - break; - case AOMBooleanProperty::kMultiselectable: - attr_value = element->FastGetAttribute(aria_multiselectableAttr); - break; - case AOMBooleanProperty::kReadOnly: - attr_value = element->FastGetAttribute(aria_readonlyAttr); - break; - case AOMBooleanProperty::kRequired: - attr_value = element->FastGetAttribute(aria_requiredAttr); - break; - case AOMBooleanProperty::kSelected: - attr_value = element->FastGetAttribute(aria_selectedAttr); - break; - } - + QualifiedName attribute = GetCorrespondingARIAAttribute(property); + AtomicString attr_value = element->FastGetAttribute(attribute); is_null = attr_value.IsNull(); return EqualIgnoringASCIICase(attr_value, "true"); } @@ -226,19 +355,8 @@ return result; // Fall back on the equivalent ARIA attribute. - AtomicString attr_value; - switch (property) { - case AOMFloatProperty::kValueMax: - attr_value = element->FastGetAttribute(aria_valuemaxAttr); - break; - case AOMFloatProperty::kValueMin: - attr_value = element->FastGetAttribute(aria_valueminAttr); - break; - case AOMFloatProperty::kValueNow: - attr_value = element->FastGetAttribute(aria_valuenowAttr); - break; - } - + QualifiedName attribute = GetCorrespondingARIAAttribute(property); + AtomicString attr_value = element->FastGetAttribute(attribute); is_null = attr_value.IsNull(); return attr_value.ToFloat(); } @@ -256,28 +374,8 @@ return result; // Fall back on the equivalent ARIA attribute. - AtomicString attr_value; - switch (property) { - case AOMUIntProperty::kColIndex: - attr_value = element->FastGetAttribute(aria_colindexAttr); - break; - case AOMUIntProperty::kColSpan: - attr_value = element->FastGetAttribute(aria_colspanAttr); - break; - case AOMUIntProperty::kLevel: - attr_value = element->FastGetAttribute(aria_levelAttr); - break; - case AOMUIntProperty::kPosInSet: - attr_value = element->FastGetAttribute(aria_posinsetAttr); - break; - case AOMUIntProperty::kRowIndex: - attr_value = element->FastGetAttribute(aria_rowindexAttr); - break; - case AOMUIntProperty::kRowSpan: - attr_value = element->FastGetAttribute(aria_rowspanAttr); - break; - } - + QualifiedName attribute = GetCorrespondingARIAAttribute(property); + AtomicString attr_value = element->FastGetAttribute(attribute); is_null = attr_value.IsNull(); return attr_value.GetString().ToUInt(); } @@ -295,23 +393,57 @@ return result; // Fall back on the equivalent ARIA attribute. - AtomicString attr_value; - switch (property) { - case AOMIntProperty::kColCount: - attr_value = element->FastGetAttribute(aria_colcountAttr); - break; - case AOMIntProperty::kRowCount: - attr_value = element->FastGetAttribute(aria_rowcountAttr); - break; - case AOMIntProperty::kSetSize: - attr_value = element->FastGetAttribute(aria_setsizeAttr); - break; - } - + QualifiedName attribute = GetCorrespondingARIAAttribute(property); + AtomicString attr_value = element->FastGetAttribute(attribute); is_null = attr_value.IsNull(); return attr_value.ToInt(); } +// static +void AccessibleNode::GetAllAOMProperties( + Element* element, + AOMPropertyClient* client, + HashSet<QualifiedName>& shadowed_aria_attributes) { + AccessibleNode* accessible_node = element->ExistingAccessibleNode(); + if (!accessible_node) + return; + + for (auto& item : accessible_node->string_properties_) { + client->AddStringProperty(item.first, item.second); + shadowed_aria_attributes.insert(GetCorrespondingARIAAttribute(item.first)); + } + for (auto& item : accessible_node->boolean_properties_) { + client->AddBooleanProperty(item.first, item.second); + shadowed_aria_attributes.insert(GetCorrespondingARIAAttribute(item.first)); + } + for (auto& item : accessible_node->float_properties_) { + client->AddFloatProperty(item.first, item.second); + shadowed_aria_attributes.insert(GetCorrespondingARIAAttribute(item.first)); + } + for (auto& item : accessible_node->int_properties_) { + client->AddIntProperty(item.first, item.second); + shadowed_aria_attributes.insert(GetCorrespondingARIAAttribute(item.first)); + } + for (auto& item : accessible_node->uint_properties_) { + client->AddUIntProperty(item.first, item.second); + shadowed_aria_attributes.insert(GetCorrespondingARIAAttribute(item.first)); + } + for (auto& item : accessible_node->relation_properties_) { + client->AddRelationProperty(item.first, *item.second); + shadowed_aria_attributes.insert(GetCorrespondingARIAAttribute(item.first)); + } +} + +AccessibleNode* AccessibleNode::activeDescendant() const { + return GetProperty(element_, AOMRelationProperty::kActiveDescendant); +} + +void AccessibleNode::setActiveDescendant(AccessibleNode* active_descendant) { + SetRelationProperty(AOMRelationProperty::kActiveDescendant, + active_descendant); + NotifyAttributeChanged(aria_activedescendantAttr); +} + bool AccessibleNode::atomic(bool& is_null) const { return GetProperty(element_, AOMBooleanProperty::kAtomic, is_null); } @@ -386,6 +518,15 @@ cache->HandleAttributeChanged(aria_currentAttr, element_); } +AccessibleNode* AccessibleNode::details() const { + return GetProperty(element_, AOMRelationProperty::kDetails); +} + +void AccessibleNode::setDetails(AccessibleNode* details) { + SetRelationProperty(AOMRelationProperty::kDetails, details); + NotifyAttributeChanged(aria_detailsAttr); +} + bool AccessibleNode::disabled(bool& is_null) const { return GetProperty(element_, AOMBooleanProperty::kDisabled, is_null); } @@ -395,6 +536,15 @@ NotifyAttributeChanged(aria_disabledAttr); } +AccessibleNode* AccessibleNode::errorMessage() const { + return GetProperty(element_, AOMRelationProperty::kErrorMessage); +} + +void AccessibleNode::setErrorMessage(AccessibleNode* error_message) { + SetRelationProperty(AOMRelationProperty::kErrorMessage, error_message); + NotifyAttributeChanged(aria_errormessageAttr); +} + bool AccessibleNode::expanded(bool& is_null) const { return GetProperty(element_, AOMBooleanProperty::kExpanded, is_null); } @@ -669,6 +819,18 @@ string_properties_.push_back(std::make_pair(property, value)); } +void AccessibleNode::SetRelationProperty(AOMRelationProperty property, + AccessibleNode* value) { + for (auto& item : relation_properties_) { + if (item.first == property) { + item.second = value; + return; + } + } + + relation_properties_.push_back(std::make_pair(property, value)); +} + template <typename P, typename T> static void SetProperty(P property, T value, @@ -726,6 +888,7 @@ DEFINE_TRACE(AccessibleNode) { visitor->Trace(element_); + visitor->Trace(relation_properties_); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/AccessibleNode.h b/third_party/WebKit/Source/core/dom/AccessibleNode.h index 709f787..aacad2d3 100644 --- a/third_party/WebKit/Source/core/dom/AccessibleNode.h +++ b/third_party/WebKit/Source/core/dom/AccessibleNode.h
@@ -6,8 +6,10 @@ #define AccessibleNode_h #include "core/CoreExport.h" +#include "core/dom/QualifiedName.h" #include "platform/bindings/ScriptWrappable.h" #include "platform/wtf/HashMap.h" +#include "platform/wtf/HashSet.h" #include "platform/wtf/text/AtomicString.h" #include "platform/wtf/text/AtomicStringHash.h" @@ -18,8 +20,6 @@ class QualifiedName; // All of the properties of AccessibleNode that have type "string". -// TODO(dmazzoni): Add similar enums for all of the properties with -// type bool, float, reference, and reference list. enum class AOMStringProperty { kAutocomplete, kChecked, @@ -63,6 +63,12 @@ kRowSpan, }; +enum class AOMRelationProperty { + kActiveDescendant, + kDetails, + kErrorMessage, +}; + // All of the properties of AccessibleNode that have a signed integer type. // (These all allow the value -1.) enum class AOMIntProperty { kColCount, kRowCount, kSetSize }; @@ -70,6 +76,19 @@ // All of the properties of AccessibleNode that have a floating-point type. enum class AOMFloatProperty { kValueMax, kValueMin, kValueNow }; +class AccessibleNode; + +class CORE_EXPORT AOMPropertyClient { + public: + virtual void AddStringProperty(AOMStringProperty, const String&) = 0; + virtual void AddBooleanProperty(AOMBooleanProperty, bool) = 0; + virtual void AddIntProperty(AOMIntProperty, int32_t) = 0; + virtual void AddUIntProperty(AOMUIntProperty, uint32_t) = 0; + virtual void AddFloatProperty(AOMFloatProperty, float) = 0; + virtual void AddRelationProperty(AOMRelationProperty, + const AccessibleNode&) = 0; +}; + // Accessibility Object Model node // Explainer: https://github.com/WICG/aom/blob/master/explainer.md // Spec: https://wicg.github.io/aom/spec/ @@ -82,9 +101,15 @@ explicit AccessibleNode(Element*); virtual ~AccessibleNode(); + // Gets the associated element, if any. + Element* element() const { return element_; } + // Returns the given string property if the Element has an AccessibleNode. static const AtomicString& GetProperty(Element*, AOMStringProperty); + // Returns the given relation property if the Element has an AccessibleNode. + static AccessibleNode* GetProperty(Element*, AOMRelationProperty); + // Returns the value of the given property if the // Element has an AccessibleNode. Sets |isNull| if the property and // attribute are not present. @@ -99,6 +124,11 @@ static const AtomicString& GetPropertyOrARIAAttribute(Element*, AOMStringProperty); + // Returns the given relation property if the Element has an AccessibleNode, + // otherwise returns the equivalent ARIA attribute. + static AccessibleNode* GetPropertyOrARIAAttribute(Element*, + AOMRelationProperty); + // Returns the value of the given property if the // Element has an AccessibleNode, otherwise returns the equivalent // ARIA attribute. Sets |isNull| if the property and attribute are not @@ -116,6 +146,18 @@ AOMUIntProperty, bool& is_null); + // Iterates over all AOM properties. For each one, calls AOMPropertyClient + // with the value of the AOM property if set. Updates + // |shadowed_aria_attributes| to contain a list of the ARIA attributes that + // would be shadowed by these AOM properties. + static void GetAllAOMProperties( + Element*, + AOMPropertyClient*, + HashSet<QualifiedName>& shadowed_aria_attributes); + + AccessibleNode* activeDescendant() const; + void setActiveDescendant(AccessibleNode*); + bool atomic(bool& is_null) const; void setAtomic(bool, bool is_null); @@ -140,9 +182,15 @@ AtomicString current() const; void setCurrent(const AtomicString&); + AccessibleNode* details() const; + void setDetails(AccessibleNode*); + bool disabled(bool& is_null) const; void setDisabled(bool, bool is_null); + AccessibleNode* errorMessage() const; + void setErrorMessage(AccessibleNode*); + bool expanded(bool& is_null) const; void setExpanded(bool, bool is_null); @@ -234,6 +282,7 @@ private: void SetStringProperty(AOMStringProperty, const AtomicString&); + void SetRelationProperty(AOMRelationProperty, AccessibleNode*); void SetBooleanProperty(AOMBooleanProperty, bool value, bool is_null); void SetFloatProperty(AOMFloatProperty, float value, bool is_null); void SetUIntProperty(AOMUIntProperty, uint32_t value, bool is_null); @@ -246,6 +295,8 @@ Vector<std::pair<AOMFloatProperty, float>> float_properties_; Vector<std::pair<AOMIntProperty, int32_t>> int_properties_; Vector<std::pair<AOMUIntProperty, uint32_t>> uint_properties_; + HeapVector<std::pair<AOMRelationProperty, Member<AccessibleNode>>> + relation_properties_; // This object's owner Element. Member<Element> element_;
diff --git a/third_party/WebKit/Source/core/dom/AccessibleNode.idl b/third_party/WebKit/Source/core/dom/AccessibleNode.idl index 6be7392..cb5ce8f 100644 --- a/third_party/WebKit/Source/core/dom/AccessibleNode.idl +++ b/third_party/WebKit/Source/core/dom/AccessibleNode.idl
@@ -8,6 +8,7 @@ [ RuntimeEnabled=AccessibilityObjectModel ] interface AccessibleNode { + attribute AccessibleNode? activeDescendant; attribute boolean? atomic; attribute DOMString? autocomplete; attribute boolean? busy; @@ -16,7 +17,9 @@ attribute unsigned long? colIndex; attribute unsigned long? colSpan; attribute DOMString? current; + attribute AccessibleNode? details; attribute boolean? disabled; + attribute AccessibleNode? errorMessage; attribute boolean? expanded; attribute boolean? hidden; attribute DOMString? invalid;
diff --git a/third_party/WebKit/Source/core/editing/markers/ActiveSuggestionMarkerListImpl.cpp b/third_party/WebKit/Source/core/editing/markers/ActiveSuggestionMarkerListImpl.cpp index 600eeed..678d4c8 100644 --- a/third_party/WebKit/Source/core/editing/markers/ActiveSuggestionMarkerListImpl.cpp +++ b/third_party/WebKit/Source/core/editing/markers/ActiveSuggestionMarkerListImpl.cpp
@@ -30,6 +30,14 @@ return markers_; } +HeapVector<Member<DocumentMarker>> +ActiveSuggestionMarkerListImpl::MarkersIntersectingRange( + unsigned start_offset, + unsigned end_offset) const { + return DocumentMarkerListEditor::MarkersIntersectingRange( + markers_, start_offset, end_offset); +} + bool ActiveSuggestionMarkerListImpl::MoveMarkers( int length, DocumentMarkerList* dst_markers_) {
diff --git a/third_party/WebKit/Source/core/editing/markers/ActiveSuggestionMarkerListImpl.h b/third_party/WebKit/Source/core/editing/markers/ActiveSuggestionMarkerListImpl.h index c001823..05cd85b 100644 --- a/third_party/WebKit/Source/core/editing/markers/ActiveSuggestionMarkerListImpl.h +++ b/third_party/WebKit/Source/core/editing/markers/ActiveSuggestionMarkerListImpl.h
@@ -29,6 +29,9 @@ void Clear() final; const HeapVector<Member<DocumentMarker>>& GetMarkers() const final; + HeapVector<Member<DocumentMarker>> MarkersIntersectingRange( + unsigned start_offset, + unsigned end_offset) const final; bool MoveMarkers(int length, DocumentMarkerList* dst_list) final; bool RemoveMarkers(unsigned start_offset, int length) final;
diff --git a/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImpl.cpp b/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImpl.cpp index c78e3ec..322c468 100644 --- a/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImpl.cpp +++ b/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImpl.cpp
@@ -30,6 +30,13 @@ return markers_; } +HeapVector<Member<DocumentMarker>> +CompositionMarkerListImpl::MarkersIntersectingRange(unsigned start_offset, + unsigned end_offset) const { + return DocumentMarkerListEditor::MarkersIntersectingRange( + markers_, start_offset, end_offset); +} + bool CompositionMarkerListImpl::MoveMarkers(int length, DocumentMarkerList* dst_markers_) { return DocumentMarkerListEditor::MoveMarkers(&markers_, length, dst_markers_);
diff --git a/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImpl.h b/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImpl.h index 9f5c9d7..4abd4da0 100644 --- a/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImpl.h +++ b/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImpl.h
@@ -28,6 +28,9 @@ void Clear() final; const HeapVector<Member<DocumentMarker>>& GetMarkers() const final; + HeapVector<Member<DocumentMarker>> MarkersIntersectingRange( + unsigned start_offset, + unsigned end_offset) const final; bool MoveMarkers(int length, DocumentMarkerList* dst_list) final; bool RemoveMarkers(unsigned start_offset, int length) final;
diff --git a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerList.h b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerList.h index 457507e..b589000 100644 --- a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerList.h +++ b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerList.h
@@ -31,7 +31,13 @@ virtual void Add(DocumentMarker*) = 0; virtual void Clear() = 0; + // Returns all markers virtual const HeapVector<Member<DocumentMarker>>& GetMarkers() const = 0; + // Returns markers that have non-empty overlap with the range + // [start_offset, end_offset] + virtual HeapVector<Member<DocumentMarker>> MarkersIntersectingRange( + unsigned start_offset, + unsigned end_offset) const = 0; // Returns true if at least one marker is copied, false otherwise virtual bool MoveMarkers(int length, DocumentMarkerList* dst_list) = 0;
diff --git a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerListEditor.cpp b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerListEditor.cpp index f8c1e23..15e67cb 100644 --- a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerListEditor.cpp +++ b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerListEditor.cpp
@@ -166,4 +166,26 @@ return did_shift_marker; } +HeapVector<Member<DocumentMarker>> +DocumentMarkerListEditor::MarkersIntersectingRange(const MarkerList& list, + unsigned start_offset, + unsigned end_offset) { + DCHECK_LE(start_offset, end_offset); + + const auto& start_it = + std::lower_bound(list.begin(), list.end(), start_offset, + [](const DocumentMarker* marker, unsigned start_offset) { + return marker->EndOffset() <= start_offset; + }); + const auto& end_it = + std::upper_bound(list.begin(), list.end(), end_offset, + [](unsigned end_offset, const DocumentMarker* marker) { + return end_offset <= marker->StartOffset(); + }); + + HeapVector<Member<DocumentMarker>> results; + std::copy(start_it, end_it, std::back_inserter(results)); + return results; +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerListEditor.h b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerListEditor.h index f0ba08f2..ec2bb76 100644 --- a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerListEditor.h +++ b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerListEditor.h
@@ -45,6 +45,11 @@ unsigned offset, unsigned old_length, unsigned new_length); + + static HeapVector<Member<DocumentMarker>> MarkersIntersectingRange( + const MarkerList&, + unsigned start_offset, + unsigned end_offset); }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerListEditorTest.cpp b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerListEditorTest.cpp index 30c4bdfd..8c6b8a0 100644 --- a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerListEditorTest.cpp +++ b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerListEditorTest.cpp
@@ -399,4 +399,79 @@ EXPECT_EQ(20u, markers[2]->EndOffset()); } +TEST_F(DocumentMarkerListEditorTest, MarkersIntersectingRange_Empty) { + DocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 5)); + + DocumentMarkerListEditor::MarkerList markers_intersecting_range = + DocumentMarkerListEditor::MarkersIntersectingRange(markers, 10, 15); + EXPECT_EQ(0u, markers_intersecting_range.size()); +} + +TEST_F(DocumentMarkerListEditorTest, MarkersIntersectingRange_TouchingAfter) { + DocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 5)); + + DocumentMarkerListEditor::MarkerList markers_intersecting_range = + DocumentMarkerListEditor::MarkersIntersectingRange(markers, 5, 10); + EXPECT_EQ(0u, markers_intersecting_range.size()); +} + +TEST_F(DocumentMarkerListEditorTest, MarkersIntersectingRange_TouchingBefore) { + DocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(5, 10)); + + DocumentMarkerListEditor::MarkerList markers_intersecting_range = + DocumentMarkerListEditor::MarkersIntersectingRange(markers, 0, 5); + EXPECT_EQ(0u, markers_intersecting_range.size()); +} + +TEST_F(DocumentMarkerListEditorTest, + MarkersIntersectingRange_IntersectingAfter) { + DocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(5, 10)); + + DocumentMarkerListEditor::MarkerList markers_intersecting_range = + DocumentMarkerListEditor::MarkersIntersectingRange(markers, 0, 6); + EXPECT_EQ(1u, markers_intersecting_range.size()); + + EXPECT_EQ(5u, markers_intersecting_range[0]->StartOffset()); + EXPECT_EQ(10u, markers_intersecting_range[0]->EndOffset()); +} + +TEST_F(DocumentMarkerListEditorTest, + MarkersIntersectingRange_IntersectingBefore) { + DocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(5, 10)); + + DocumentMarkerListEditor::MarkerList markers_intersecting_range = + DocumentMarkerListEditor::MarkersIntersectingRange(markers, 9, 15); + EXPECT_EQ(1u, markers_intersecting_range.size()); + + EXPECT_EQ(5u, markers_intersecting_range[0]->StartOffset()); + EXPECT_EQ(10u, markers_intersecting_range[0]->EndOffset()); +} + +TEST_F(DocumentMarkerListEditorTest, MarkersIntersectingRange_MultipleMarkers) { + DocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 5)); + markers.push_back(CreateMarker(5, 10)); + markers.push_back(CreateMarker(10, 15)); + markers.push_back(CreateMarker(15, 20)); + markers.push_back(CreateMarker(20, 25)); + + DocumentMarkerListEditor::MarkerList markers_intersecting_range = + DocumentMarkerListEditor::MarkersIntersectingRange(markers, 7, 17); + EXPECT_EQ(3u, markers_intersecting_range.size()); + + EXPECT_EQ(5u, markers_intersecting_range[0]->StartOffset()); + EXPECT_EQ(10u, markers_intersecting_range[0]->EndOffset()); + + EXPECT_EQ(10u, markers_intersecting_range[1]->StartOffset()); + EXPECT_EQ(15u, markers_intersecting_range[1]->EndOffset()); + + EXPECT_EQ(15u, markers_intersecting_range[2]->StartOffset()); + EXPECT_EQ(20u, markers_intersecting_range[2]->EndOffset()); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/markers/SpellCheckMarkerListImpl.cpp b/third_party/WebKit/Source/core/editing/markers/SpellCheckMarkerListImpl.cpp index cc62f80..372e79c 100644 --- a/third_party/WebKit/Source/core/editing/markers/SpellCheckMarkerListImpl.cpp +++ b/third_party/WebKit/Source/core/editing/markers/SpellCheckMarkerListImpl.cpp
@@ -66,6 +66,13 @@ return markers_; } +HeapVector<Member<DocumentMarker>> +SpellCheckMarkerListImpl::MarkersIntersectingRange(unsigned start_offset, + unsigned end_offset) const { + return DocumentMarkerListEditor::MarkersIntersectingRange( + markers_, start_offset, end_offset); +} + bool SpellCheckMarkerListImpl::MoveMarkers(int length, DocumentMarkerList* dst_list) { return DocumentMarkerListEditor::MoveMarkers(&markers_, length, dst_list);
diff --git a/third_party/WebKit/Source/core/editing/markers/SpellCheckMarkerListImpl.h b/third_party/WebKit/Source/core/editing/markers/SpellCheckMarkerListImpl.h index 3aec9dd..6aa2a3a 100644 --- a/third_party/WebKit/Source/core/editing/markers/SpellCheckMarkerListImpl.h +++ b/third_party/WebKit/Source/core/editing/markers/SpellCheckMarkerListImpl.h
@@ -23,6 +23,9 @@ void Clear() final; const HeapVector<Member<DocumentMarker>>& GetMarkers() const final; + HeapVector<Member<DocumentMarker>> MarkersIntersectingRange( + unsigned start_offset, + unsigned end_offset) const final; bool MoveMarkers(int length, DocumentMarkerList* dst_list) final; bool RemoveMarkers(unsigned start_offset, int length) final;
diff --git a/third_party/WebKit/Source/core/editing/markers/TextMatchMarkerListImpl.cpp b/third_party/WebKit/Source/core/editing/markers/TextMatchMarkerListImpl.cpp index 1bf76df..8293e39 100644 --- a/third_party/WebKit/Source/core/editing/markers/TextMatchMarkerListImpl.cpp +++ b/third_party/WebKit/Source/core/editing/markers/TextMatchMarkerListImpl.cpp
@@ -35,6 +35,13 @@ return markers_; } +HeapVector<Member<DocumentMarker>> +TextMatchMarkerListImpl::MarkersIntersectingRange(unsigned start_offset, + unsigned end_offset) const { + return DocumentMarkerListEditor::MarkersIntersectingRange( + markers_, start_offset, end_offset); +} + bool TextMatchMarkerListImpl::MoveMarkers(int length, DocumentMarkerList* dst_list) { return DocumentMarkerListEditor::MoveMarkers(&markers_, length, dst_list);
diff --git a/third_party/WebKit/Source/core/editing/markers/TextMatchMarkerListImpl.h b/third_party/WebKit/Source/core/editing/markers/TextMatchMarkerListImpl.h index f7470788..28d30c5c 100644 --- a/third_party/WebKit/Source/core/editing/markers/TextMatchMarkerListImpl.h +++ b/third_party/WebKit/Source/core/editing/markers/TextMatchMarkerListImpl.h
@@ -27,6 +27,9 @@ void Clear() final; const HeapVector<Member<DocumentMarker>>& GetMarkers() const final; + HeapVector<Member<DocumentMarker>> MarkersIntersectingRange( + unsigned start_offset, + unsigned end_offset) const final; bool MoveMarkers(int length, DocumentMarkerList* dst_list) final; bool RemoveMarkers(unsigned start_offset, int length) final;
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameView.cpp b/third_party/WebKit/Source/core/frame/LocalFrameView.cpp index dad20ad4..a45c465c 100644 --- a/third_party/WebKit/Source/core/frame/LocalFrameView.cpp +++ b/third_party/WebKit/Source/core/frame/LocalFrameView.cpp
@@ -3794,8 +3794,10 @@ paint_controller_ = PaintController::Create(); paint_controller_->SetTracksRasterInvalidations( track_paint_invalidations); - if (paint_artifact_compositor_) - paint_artifact_compositor_->ResetTrackedRasterInvalidations(); + if (paint_artifact_compositor_) { + paint_artifact_compositor_->SetTracksRasterInvalidations( + track_paint_invalidations); + } } else { layout_view.Compositor()->SetTracksRasterInvalidations( track_paint_invalidations);
diff --git a/third_party/WebKit/Source/core/input/EventHandler.cpp b/third_party/WebKit/Source/core/input/EventHandler.cpp index b06d616..81d3157 100644 --- a/third_party/WebKit/Source/core/input/EventHandler.cpp +++ b/third_party/WebKit/Source/core/input/EventHandler.cpp
@@ -785,6 +785,18 @@ mouse_event_manager_->CancelFakeMouseMoveEvent(); mouse_event_manager_->HandleSvgPanIfNeeded(false); + // Mouse states need to be reset when mouse move with no button down. + // This is for popup/context_menu opened at mouse_down event and + // mouse_release is not handled in page. + // crbug/527582 + if (mouse_event.button == WebPointerProperties::Button::kNoButton && + !(mouse_event.GetModifiers() & + WebInputEvent::Modifiers::kRelativeMotionEvent)) { + mouse_event_manager_->HandleMouseReleaseEventUpdateStates(); + if (event_handler_will_reset_capturing_mouse_events_node_) + capturing_mouse_events_node_ = nullptr; + } + if (RuntimeEnabledFeatures::MiddleClickAutoscrollEnabled()) { if (Page* page = frame_->GetPage()) { if (mouse_event.GetType() == WebInputEvent::kMouseLeave && @@ -819,8 +831,9 @@ } else if (only_update_scrollbars) { // Mouse events should be treated as "read-only" if we're updating only // scrollbars. This means that :hover and :active freeze in the state they - // were in, rather than updating for nodes the mouse moves while the window - // is not key (which will be the case if onlyUpdateScrollbars is true). + // were in, rather than updating for nodes the mouse moves while the + // window is not key (which will be the case if onlyUpdateScrollbars is + // true). hit_type |= HitTestRequest::kReadOnly; } @@ -832,10 +845,10 @@ MouseEventWithHitTestResults mev = MouseEventWithHitTestResults( mouse_event, HitTestResult(request, LayoutPoint())); - // We don't want to do a hit-test in forceLeave scenarios because there might - // actually be some other frame above this one at the specified co-ordinate. - // So we must force the hit-test to fail, while still clearing hover/active - // state. + // We don't want to do a hit-test in forceLeave scenarios because there + // might actually be some other frame above this one at the specified + // co-ordinate. So we must force the hit-test to fail, while still clearing + // hover/active state. if (force_leave) { frame_->GetDocument()->UpdateHoverActiveState(request, nullptr); } else { @@ -861,18 +874,20 @@ } WebInputEventResult event_result = WebInputEventResult::kNotHandled; - LocalFrame* new_subframe = capturing_mouse_events_node_.Get() - ? EventHandlingUtil::SubframeForTargetNode( - capturing_mouse_events_node_.Get()) - : EventHandlingUtil::SubframeForHitTestResult(mev); + LocalFrame* new_subframe = + capturing_mouse_events_node_.Get() + ? EventHandlingUtil::SubframeForTargetNode( + capturing_mouse_events_node_.Get()) + : EventHandlingUtil::SubframeForHitTestResult(mev); - // We want mouseouts to happen first, from the inside out. First send a move - // event to the last subframe so that it will fire mouseouts. + // We want mouseouts to happen first, from the inside out. First send a + // move event to the last subframe so that it will fire mouseouts. if (last_mouse_move_event_subframe_ && last_mouse_move_event_subframe_->Tree().IsDescendantOf(frame_) && - last_mouse_move_event_subframe_ != new_subframe) + last_mouse_move_event_subframe_ != new_subframe) { last_mouse_move_event_subframe_->GetEventHandler().HandleMouseLeaveEvent( mev.Event()); + } if (new_subframe) { // Update over/out state before passing the event to the subframe.
diff --git a/third_party/WebKit/Source/core/input/MouseEventManager.cpp b/third_party/WebKit/Source/core/input/MouseEventManager.cpp index a7a0eb7..e4a1ec7d 100644 --- a/third_party/WebKit/Source/core/input/MouseEventManager.cpp +++ b/third_party/WebKit/Source/core/input/MouseEventManager.cpp
@@ -332,7 +332,8 @@ WebFloatPoint(last_known_mouse_global_position_.X(), last_known_mouse_global_position_.Y()), WebPointerProperties::Button::kNoButton, 0, - KeyboardEventManager::GetCurrentModifierState(), + KeyboardEventManager::GetCurrentModifierState() | + WebInputEvent::Modifiers::kRelativeMotionEvent, TimeTicks::Now().InSeconds()); // TODO(dtapuska): Update m_lastKnowMousePosition to be viewport coordinates. fake_mouse_move_event.SetFrameScale(1);
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp index ed6b8695c..caee0d1 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp +++ b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
@@ -528,7 +528,7 @@ context.GetPaintController(), paint_layer_, properties, // Force a new paint chunk, since it is required for subsequence // caching. - should_create_subsequence ? ForceNewChunk : DontForceNewChunk); + should_create_subsequence ? kForceNewChunk : kDontForceNewChunk); } bool selection_only =
diff --git a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp index e68f52e..924e391 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp
@@ -213,6 +213,66 @@ return ax_sparse_attribute_setter_map; } +class AXSparseAttributeAOMPropertyClient : public AOMPropertyClient { + public: + AXSparseAttributeAOMPropertyClient( + AXObjectCacheImpl& ax_object_cache, + AXSparseAttributeClient& sparse_attribute_client) + : ax_object_cache_(ax_object_cache), + sparse_attribute_client_(sparse_attribute_client) {} + + void AddStringProperty(AOMStringProperty property, + const String& value) override { + AXStringAttribute attribute; + switch (property) { + case AOMStringProperty::kKeyShortcuts: + attribute = AXStringAttribute::kAriaKeyShortcuts; + break; + case AOMStringProperty::kRoleDescription: + attribute = AXStringAttribute::kAriaRoleDescription; + break; + default: + return; + } + sparse_attribute_client_.AddStringAttribute(attribute, value); + } + + void AddBooleanProperty(AOMBooleanProperty property, bool value) override {} + + void AddIntProperty(AOMIntProperty property, int32_t value) override {} + + void AddUIntProperty(AOMUIntProperty property, uint32_t value) override {} + + void AddFloatProperty(AOMFloatProperty property, float value) override {} + + void AddRelationProperty(AOMRelationProperty property, + const AccessibleNode& value) override { + AXObjectAttribute attribute; + switch (property) { + case AOMRelationProperty::kActiveDescendant: + attribute = AXObjectAttribute::kAriaActiveDescendant; + break; + case AOMRelationProperty::kDetails: + attribute = AXObjectAttribute::kAriaDetails; + break; + case AOMRelationProperty::kErrorMessage: + attribute = AXObjectAttribute::kAriaErrorMessage; + break; + default: + return; + } + + Element* target_element = value.element(); + AXObject* target_obj = ax_object_cache_->GetOrCreate(target_element); + if (target_element) + sparse_attribute_client_.AddObjectAttribute(attribute, *target_obj); + } + + private: + Persistent<AXObjectCacheImpl> ax_object_cache_; + AXSparseAttributeClient& sparse_attribute_client_; +}; + AXNodeObject::AXNodeObject(Node* node, AXObjectCacheImpl& ax_object_cache) : AXObject(ax_object_cache), aria_role_(kUnknownRole), @@ -243,17 +303,12 @@ } AXObject* AXNodeObject::ActiveDescendant() { - if (!node_ || !node_->IsElementNode()) + Element* element = GetElement(); + if (!element) return nullptr; - const AtomicString& active_descendant_attr = - GetAttribute(aria_activedescendantAttr); - if (active_descendant_attr.IsNull() || active_descendant_attr.IsEmpty()) - return nullptr; - - Element* element = ToElement(GetNode()); Element* descendant = - element->GetTreeScope().getElementById(active_descendant_attr); + GetAOMPropertyOrARIAAttribute(AOMRelationProperty::kActiveDescendant); if (!descendant) return nullptr; @@ -915,36 +970,28 @@ void AXNodeObject::GetSparseAXAttributes( AXSparseAttributeClient& sparse_attribute_client) const { - Node* node = this->GetNode(); - if (!node || !node->IsElementNode()) + Element* element = GetElement(); + if (!element) return; + AXSparseAttributeAOMPropertyClient property_client(*ax_object_cache_, + sparse_attribute_client); + HashSet<QualifiedName> shadowed_aria_attributes; + AccessibleNode::GetAllAOMProperties(element, &property_client, + shadowed_aria_attributes); + AXSparseAttributeSetterMap& ax_sparse_attribute_setter_map = GetSparseAttributeSetterMap(); - AttributeCollection attributes = ToElement(node)->AttributesWithoutUpdate(); + AttributeCollection attributes = element->AttributesWithoutUpdate(); for (const Attribute& attr : attributes) { + if (shadowed_aria_attributes.Contains(attr.GetName())) + continue; + SparseAttributeSetter* setter = ax_sparse_attribute_setter_map.at(attr.GetName()); if (setter) setter->Run(*this, sparse_attribute_client, attr.Value()); } - - // TODO(dmazzoni): Efficiently iterate over AccessibleNode properties that are - // set and merge the two loops somehow. - if (ToElement(node)->ExistingAccessibleNode()) { - AtomicString key_shortcuts = - GetAOMPropertyOrARIAAttribute(AOMStringProperty::kKeyShortcuts); - if (!key_shortcuts.IsNull()) { - ax_sparse_attribute_setter_map.at(aria_keyshortcutsAttr) - ->Run(*this, sparse_attribute_client, key_shortcuts); - } - AtomicString role_description = - GetAOMPropertyOrARIAAttribute(AOMStringProperty::kRoleDescription); - if (!role_description.IsNull()) { - ax_sparse_attribute_setter_map.at(aria_roledescriptionAttr) - ->Run(*this, sparse_attribute_client, role_description); - } - } } bool AXNodeObject::IsAnchor() const {
diff --git a/third_party/WebKit/Source/modules/accessibility/AXObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXObject.cpp index 9f0dddb..f7145d1 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXObject.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AXObject.cpp
@@ -381,6 +381,17 @@ return g_null_atom; } +Element* AXObject::GetAOMPropertyOrARIAAttribute( + AOMRelationProperty property) const { + Element* element = this->GetElement(); + if (!element) + return nullptr; + + AccessibleNode* target = + AccessibleNode::GetPropertyOrARIAAttribute(element, property); + return target ? target->element() : nullptr; +} + bool AXObject::HasAOMPropertyOrARIAAttribute(AOMBooleanProperty property, bool& result) const { Element* element = this->GetElement(); @@ -829,7 +840,8 @@ return false; // Focusable, and not forwarding the focus somewhere else - if (elem->IsFocusable() && !elem->FastHasAttribute(aria_activedescendantAttr)) + if (elem->IsFocusable() && + !GetAOMPropertyOrARIAAttribute(AOMRelationProperty::kActiveDescendant)) return true; // aria-activedescendant focus @@ -847,7 +859,8 @@ return false; if (parent->SupportsActiveDescendant() && - parent->HasAttribute(aria_activedescendantAttr)) { + parent->GetAOMPropertyOrARIAAttribute( + AOMRelationProperty::kActiveDescendant)) { return true; }
diff --git a/third_party/WebKit/Source/modules/accessibility/AXObject.h b/third_party/WebKit/Source/modules/accessibility/AXObject.h index f62c261..ba79e1e 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXObject.h +++ b/third_party/WebKit/Source/modules/accessibility/AXObject.h
@@ -1,4 +1,3 @@ - /* * Copyright (C) 2008, 2009, 2011 Apple Inc. All rights reserved. * Copyright (C) 2008 Nuanti Ltd. @@ -60,6 +59,7 @@ enum class AOMUIntProperty; enum class AOMIntProperty; enum class AOMFloatProperty; +enum class AOMRelationProperty; typedef unsigned AXID; @@ -353,6 +353,7 @@ // Wrappers that retrieve either an Accessibility Object Model property, // or the equivalent ARIA attribute, in that order. const AtomicString& GetAOMPropertyOrARIAAttribute(AOMStringProperty) const; + Element* GetAOMPropertyOrARIAAttribute(AOMRelationProperty) const; bool HasAOMPropertyOrARIAAttribute(AOMBooleanProperty, bool& result) const; bool AOMPropertyOrARIAAttributeIsTrue(AOMBooleanProperty) const; bool AOMPropertyOrARIAAttributeIsFalse(AOMBooleanProperty) const;
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn index 6dfad22..1d788216 100644 --- a/third_party/WebKit/Source/platform/BUILD.gn +++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -1872,6 +1872,7 @@ "graphics/GraphicsContextTest.cpp", "graphics/PaintInvalidationReasonTest.cpp", "graphics/RecordingImageBufferSurfaceTest.cpp", + "graphics/compositing/ContentLayerClientImplTest.cpp", "graphics/compositing/PaintArtifactCompositorTest.cpp", "graphics/filters/ImageFilterBuilderTest.cpp", "graphics/gpu/DrawingBufferTest.cpp",
diff --git a/third_party/WebKit/Source/platform/graphics/PaintInvalidationReason.cpp b/third_party/WebKit/Source/platform/graphics/PaintInvalidationReason.cpp index 467ce001..974804a 100644 --- a/third_party/WebKit/Source/platform/graphics/PaintInvalidationReason.cpp +++ b/third_party/WebKit/Source/platform/graphics/PaintInvalidationReason.cpp
@@ -50,6 +50,12 @@ return "DocumentMarker change"; case PaintInvalidationReason::kImage: return "image"; + case PaintInvalidationReason::kChunkUncacheable: + return "chunk uncacheable"; + case PaintInvalidationReason::kChunkReordered: + return "chunk reordered"; + case PaintInvalidationReason::kFullLayer: + return "full layer"; case PaintInvalidationReason::kForTesting: return "for testing"; case PaintInvalidationReason::kDelayedFull:
diff --git a/third_party/WebKit/Source/platform/graphics/PaintInvalidationReason.h b/third_party/WebKit/Source/platform/graphics/PaintInvalidationReason.h index 42d41962..38108c5 100644 --- a/third_party/WebKit/Source/platform/graphics/PaintInvalidationReason.h +++ b/third_party/WebKit/Source/platform/graphics/PaintInvalidationReason.h
@@ -32,6 +32,9 @@ kCaret, kDocumentMarker, kImage, + kChunkUncacheable, + kChunkReordered, + kFullLayer, kForTesting, // kDelayedFull means that kFull is needed in order to fully paint the // content, but that painting of the object can be delayed until a future
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImpl.cpp b/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImpl.cpp index c1e9cfb..e398b5c 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImpl.cpp +++ b/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImpl.cpp
@@ -4,19 +4,15 @@ #include "platform/graphics/compositing/ContentLayerClientImpl.h" +#include "platform/graphics/compositing/PaintChunksToCcLayer.h" +#include "platform/graphics/paint/GeometryMapper.h" +#include "platform/graphics/paint/PaintArtifact.h" +#include "platform/graphics/paint/PaintChunk.h" +#include "platform/graphics/paint/RasterInvalidationTracking.h" +#include "platform/json/JSONValues.h" + namespace blink { -template class RasterInvalidationTrackingMap<const cc::Layer>; -static RasterInvalidationTrackingMap<const cc::Layer>& -CcLayersRasterInvalidationTrackingMap() { - DEFINE_STATIC_LOCAL(RasterInvalidationTrackingMap<const cc::Layer>, map, ()); - return map; -} - -ContentLayerClientImpl::~ContentLayerClientImpl() { - CcLayersRasterInvalidationTrackingMap().Remove(cc_picture_layer_.get()); -} - template <typename T> static std::unique_ptr<JSONArray> PointAsJSONArray(const T& point) { std::unique_ptr<JSONArray> array = JSONArray::Create(); @@ -33,21 +29,25 @@ return array; } -void ContentLayerClientImpl::ResetTrackedRasterInvalidations() { - RasterInvalidationTracking* tracking = - CcLayersRasterInvalidationTrackingMap().Find(cc_picture_layer_.get()); - if (!tracking) - return; +void ContentLayerClientImpl::SetTracksRasterInvalidations(bool should_track) { + if (should_track) { + raster_invalidation_tracking_info_ = + WTF::MakeUnique<RasterInvalidationTrackingInfo>(); - if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) - tracking->invalidations.clear(); - else - CcLayersRasterInvalidationTrackingMap().Remove(cc_picture_layer_.get()); + for (const auto& info : paint_chunks_info_) { + raster_invalidation_tracking_info_->old_client_debug_names.Set( + &info.id.client, info.id.client.DebugName()); + } + } else if (!RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) { + raster_invalidation_tracking_info_ = nullptr; + } else if (raster_invalidation_tracking_info_) { + raster_invalidation_tracking_info_->tracking.invalidations.clear(); + } } -RasterInvalidationTracking& -ContentLayerClientImpl::EnsureRasterInvalidationTracking() { - return CcLayersRasterInvalidationTrackingMap().Add(cc_picture_layer_.get()); +const Vector<RasterInvalidationInfo>& +ContentLayerClientImpl::TrackedRasterInvalidations() const { + return raster_invalidation_tracking_info_->tracking.invalidations; } std::unique_ptr<JSONObject> ContentLayerClientImpl::LayerAsJSON( @@ -76,9 +76,256 @@ json->SetArray("paintChunkContents", std::move(paint_chunk_contents_array)); } - CcLayersRasterInvalidationTrackingMap().AsJSON(cc_picture_layer_.get(), - json.get()); + if (raster_invalidation_tracking_info_) + raster_invalidation_tracking_info_->tracking.AsJSON(json.get()); + return json; } +IntRect ContentLayerClientImpl::MapRasterInvalidationRectFromChunkToLayer( + const FloatRect& r, + const PaintChunk& chunk, + const PropertyTreeState& layer_state) const { + FloatClipRect rect(r); + GeometryMapper::LocalToAncestorVisualRect( + chunk.properties.property_tree_state, layer_state, rect); + if (rect.Rect().IsEmpty()) + return IntRect(); + + // Now rect is in the space of the containing transform node of pending_layer, + // so need to subtract off the layer offset. + rect.Rect().Move(-layer_bounds_.x(), -layer_bounds_.y()); + rect.Rect().Inflate(chunk.outset_for_raster_effects); + return EnclosingIntRect(rect.Rect()); +} + +size_t ContentLayerClientImpl::MatchNewChunkToOldChunk( + const PaintChunk& new_chunk, + size_t old_index) { + if (paint_chunks_info_[old_index].Matches(new_chunk)) + return old_index; + + size_t i = old_index; + do { + ++i; + if (i == paint_chunks_info_.size()) + i = 0; + if (paint_chunks_info_[i].Matches(new_chunk)) + return i; + } while (i != old_index); + + return kNotFound; +} + +// Generates raster invalidations by checking changes (appearing, disappearing, +// reordering, property changes) of chunks. The logic is similar to +// PaintController::GenerateRasterInvalidations(). The complexity is between +// O(n) and O(m*n) where m and n are the numbers of old and new chunks, +// respectively. Normally both m and n are small numbers. The best caseis that +// all old chunks have matching new chunks in the same order. The worst case is +// that no matching chunks except the first one (which always matches otherwise +// we won't reuse the ContentLayerClientImpl), which is rare. In common cases +// that most of the chunks can be matched in-order, the complexity is slightly +// larger than O(n). +void ContentLayerClientImpl::GenerateRasterInvalidations( + const Vector<const PaintChunk*>& new_chunks, + const Vector<PaintChunkInfo>& new_chunks_info, + const PropertyTreeState& layer_state) { + Vector<bool> old_chunks_matched; + old_chunks_matched.resize(paint_chunks_info_.size()); + size_t old_index = 0; + for (size_t new_index = 0; new_index < new_chunks.size(); ++new_index) { + const auto& new_chunk = *new_chunks[new_index]; + const auto& new_chunk_info = new_chunks_info[new_index]; + + if (!new_chunk.is_cacheable) { + InvalidateRasterForNewChunk(new_chunk_info, + PaintInvalidationReason::kChunkUncacheable); + continue; + } + + size_t matched = MatchNewChunkToOldChunk(new_chunk, old_index); + if (matched == kNotFound) { + // The new chunk doesn't match any old chunk. + InvalidateRasterForNewChunk(new_chunk_info, + PaintInvalidationReason::kAppeared); + continue; + } + + old_chunks_matched[matched] = true; + if (matched == old_index) { + // TODO(wangxianzhu): Also fully invalidate for paint property changes. + // Add the raster invalidations found by PaintController within the chunk. + AddDisplayItemRasterInvalidations(new_chunk, layer_state); + } else { + // Invalidate both old and new bounds of the chunk if the chunk is + // reordered and may expose area that was previously covered by it. + const auto& old_chunks_info = paint_chunks_info_[matched]; + InvalidateRasterForOldChunk(old_chunks_info, + PaintInvalidationReason::kChunkReordered); + if (old_chunks_info.bounds_in_layer != new_chunk_info.bounds_in_layer) { + InvalidateRasterForNewChunk(new_chunk_info, + PaintInvalidationReason::kChunkReordered); + } + // Ignore the display item raster invalidations because we have fully + // invalidated the chunk. + } + + old_index = matched + 1; + if (old_index == paint_chunks_info_.size()) + old_index = 0; + } + + // Invalidate remaining unmatched (disappeared or uncacheable) old chunks. + for (size_t i = 0; i < paint_chunks_info_.size(); ++i) { + if (old_chunks_matched[i]) + continue; + InvalidateRasterForOldChunk( + paint_chunks_info_[i], + paint_chunks_info_[i].is_cacheable + ? PaintInvalidationReason::kDisappeared + : PaintInvalidationReason::kChunkUncacheable); + } +} + +void ContentLayerClientImpl::AddDisplayItemRasterInvalidations( + const PaintChunk& chunk, + const PropertyTreeState& layer_state) { + DCHECK(chunk.raster_invalidation_tracking.IsEmpty() || + chunk.raster_invalidation_rects.size() == + chunk.raster_invalidation_tracking.size()); + + for (size_t i = 0; i < chunk.raster_invalidation_rects.size(); ++i) { + auto rect = MapRasterInvalidationRectFromChunkToLayer( + chunk.raster_invalidation_rects[i], chunk, layer_state); + if (rect.IsEmpty()) + continue; + cc_picture_layer_->SetNeedsDisplayRect(rect); + + if (!chunk.raster_invalidation_tracking.IsEmpty()) { + const auto& info = chunk.raster_invalidation_tracking[i]; + raster_invalidation_tracking_info_->tracking.AddInvalidation( + info.client, info.client_debug_name, rect, info.reason); + } + } +} + +void ContentLayerClientImpl::InvalidateRasterForNewChunk( + const PaintChunkInfo& info, + PaintInvalidationReason reason) { + cc_picture_layer_->SetNeedsDisplayRect(info.bounds_in_layer); + + if (raster_invalidation_tracking_info_) { + raster_invalidation_tracking_info_->tracking.AddInvalidation( + &info.id.client, info.id.client.DebugName(), info.bounds_in_layer, + reason); + } +} + +void ContentLayerClientImpl::InvalidateRasterForOldChunk( + const PaintChunkInfo& info, + PaintInvalidationReason reason) { + cc_picture_layer_->SetNeedsDisplayRect(info.bounds_in_layer); + + if (raster_invalidation_tracking_info_) { + raster_invalidation_tracking_info_->tracking.AddInvalidation( + &info.id.client, + raster_invalidation_tracking_info_->old_client_debug_names.at( + &info.id.client), + info.bounds_in_layer, reason); + } +} + +void ContentLayerClientImpl::InvalidateRasterForWholeLayer() { + IntRect rect(0, 0, layer_bounds_.width(), layer_bounds_.height()); + cc_picture_layer_->SetNeedsDisplayRect(rect); + + if (raster_invalidation_tracking_info_) { + raster_invalidation_tracking_info_->tracking.AddInvalidation( + &paint_chunks_info_[0].id.client, debug_name_, rect, + PaintInvalidationReason::kFullLayer); + } +} + +scoped_refptr<cc::PictureLayer> ContentLayerClientImpl::UpdateCcPictureLayer( + const PaintArtifact& paint_artifact, + const gfx::Rect& layer_bounds, + const Vector<const PaintChunk*>& paint_chunks, + const PropertyTreeState& layer_state, + bool store_debug_info) { + // TODO(wangxianzhu): Avoid calling DebugName() in official release build. + debug_name_ = paint_chunks[0]->id.client.DebugName(); + + paint_chunk_debug_data_.clear(); + if (store_debug_info) { + for (const auto* chunk : paint_chunks) { + paint_chunk_debug_data_.push_back( + paint_artifact.GetDisplayItemList().SubsequenceAsJSON( + chunk->begin_index, chunk->end_index, + DisplayItemList::kSkipNonDrawings | + DisplayItemList::kShownOnlyDisplayItemTypes)); + } + } + + if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() && + !raster_invalidation_tracking_info_) { + raster_invalidation_tracking_info_ = + WTF::MakeUnique<RasterInvalidationTrackingInfo>(); + } + + bool layer_bounds_was_empty = layer_bounds_.IsEmpty(); + bool layer_origin_changed = layer_bounds_.origin() != layer_bounds.origin(); + layer_bounds_ = layer_bounds; + cc_picture_layer_->SetBounds(layer_bounds.size()); + cc_picture_layer_->SetIsDrawable(true); + + Vector<PaintChunkInfo> new_chunks_info; + new_chunks_info.ReserveCapacity(paint_chunks.size()); + for (const auto* chunk : paint_chunks) { + new_chunks_info.push_back( + PaintChunkInfo(MapRasterInvalidationRectFromChunkToLayer( + chunk->bounds, *chunk, layer_state), + *chunk)); + if (raster_invalidation_tracking_info_) { + raster_invalidation_tracking_info_->new_client_debug_names.insert( + &chunk->id.client, chunk->id.client.DebugName()); + } + } + + if (!layer_bounds_was_empty && !layer_bounds_.IsEmpty()) { + if (layer_origin_changed) + InvalidateRasterForWholeLayer(); + else + GenerateRasterInvalidations(paint_chunks, new_chunks_info, layer_state); + } + + Optional<RasterUnderInvalidationCheckingParams> params; + if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) { + params.emplace(raster_invalidation_tracking_info_->tracking, + IntRect(0, 0, layer_bounds_.width(), layer_bounds_.height()), + debug_name_); + } + cc_display_item_list_ = PaintChunksToCcLayer::Convert( + paint_chunks, layer_state, layer_bounds.OffsetFromOrigin(), + paint_artifact.GetDisplayItemList(), params ? &*params : nullptr); + + paint_chunks_info_.clear(); + std::swap(paint_chunks_info_, new_chunks_info); + if (raster_invalidation_tracking_info_) { + raster_invalidation_tracking_info_->old_client_debug_names.clear(); + std::swap(raster_invalidation_tracking_info_->old_client_debug_names, + raster_invalidation_tracking_info_->new_client_debug_names); + } + + for (const auto* chunk : paint_chunks) { + // TODO(wangxianzhu): This will be unnecessary if we don't call + // PaintArtifactCompositor::Update() when paint artifact is unchanged. + chunk->client_is_just_created = false; + chunk->raster_invalidation_rects.clear(); + chunk->raster_invalidation_tracking.clear(); + } + + return cc_picture_layer_; +} + } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImpl.h b/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImpl.h index 49156c45..ffd3e12 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImpl.h +++ b/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImpl.h
@@ -17,6 +17,7 @@ class JSONArray; class JSONObject; +class PaintArtifact; struct RasterInvalidationTracking; class PLATFORM_EXPORT ContentLayerClientImpl : public cc::ContentLayerClient { @@ -24,28 +25,14 @@ USING_FAST_MALLOC(ContentLayerClientImpl); public: - ContentLayerClientImpl(const PaintChunk& paint_chunk) - : id_(paint_chunk.id), - is_cacheable_(paint_chunk.is_cacheable), - debug_name_(paint_chunk.id.client.DebugName()), - cc_picture_layer_(cc::PictureLayer::Create(this)) {} - - ~ContentLayerClientImpl(); - - void SetDisplayList(scoped_refptr<cc::DisplayItemList> cc_display_item_list) { - cc_display_item_list_ = std::move(cc_display_item_list); - } - void SetPaintableRegion(const gfx::Rect& region) { - paintable_region_ = region; - } - - void AddPaintChunkDebugData(std::unique_ptr<JSONArray> json) { - paint_chunk_debug_data_.push_back(std::move(json)); - } - void ClearPaintChunkDebugData() { paint_chunk_debug_data_.clear(); } + ContentLayerClientImpl() + : cc_picture_layer_(cc::PictureLayer::Create(this)) {} + ~ContentLayerClientImpl() override {} // cc::ContentLayerClient - gfx::Rect PaintableRegion() override { return paintable_region_; } + gfx::Rect PaintableRegion() override { + return gfx::Rect(layer_bounds_.size()); + } scoped_refptr<cc::DisplayItemList> PaintContentsToDisplayList( PaintingControlSetting) override { return cc_display_item_list_; @@ -56,31 +43,75 @@ return 0; } - void ResetTrackedRasterInvalidations(); - RasterInvalidationTracking& EnsureRasterInvalidationTracking(); - - void SetNeedsDisplayRect(const gfx::Rect& rect) { - cc_picture_layer_->SetNeedsDisplayRect(rect); - } + void SetTracksRasterInvalidations(bool); std::unique_ptr<JSONObject> LayerAsJSON(LayerTreeFlags); - scoped_refptr<cc::PictureLayer> CcPictureLayer() { return cc_picture_layer_; } + scoped_refptr<cc::PictureLayer> UpdateCcPictureLayer( + const PaintArtifact&, + const gfx::Rect& layer_bounds, + const Vector<const PaintChunk*>&, + const PropertyTreeState& layer_state, + bool store_debug_info); bool Matches(const PaintChunk& paint_chunk) { - return is_cacheable_ && paint_chunk.Matches(id_); + return paint_chunks_info_.size() && paint_chunks_info_[0].is_cacheable && + paint_chunk.Matches(paint_chunks_info_[0].id); } - const String& DebugName() const { return debug_name_; } - private: - PaintChunk::Id id_; - bool is_cacheable_; - String debug_name_; + friend class ContentLayerClientImplTest; + const Vector<RasterInvalidationInfo>& TrackedRasterInvalidations() const; + + struct PaintChunkInfo { + PaintChunkInfo(const IntRect& bounds, const PaintChunk& chunk) + : bounds_in_layer(bounds), + id(chunk.id), + is_cacheable(chunk.is_cacheable) {} + + bool Matches(const PaintChunk& new_chunk) const { + return is_cacheable && new_chunk.Matches(id); + } + + IntRect bounds_in_layer; + PaintChunk::Id id; + bool is_cacheable; + }; + + IntRect MapRasterInvalidationRectFromChunkToLayer( + const FloatRect&, + const PaintChunk&, + const PropertyTreeState&) const; + + void GenerateRasterInvalidations( + const Vector<const PaintChunk*>& new_chunks, + const Vector<PaintChunkInfo>& new_chunks_info, + const PropertyTreeState&); + size_t MatchNewChunkToOldChunk(const PaintChunk& new_chunk, size_t old_index); + void AddDisplayItemRasterInvalidations(const PaintChunk&, + const PropertyTreeState&); + void InvalidateRasterForNewChunk(const PaintChunkInfo&, + PaintInvalidationReason); + void InvalidateRasterForOldChunk(const PaintChunkInfo&, + PaintInvalidationReason); + void InvalidateRasterForWholeLayer(); + scoped_refptr<cc::PictureLayer> cc_picture_layer_; scoped_refptr<cc::DisplayItemList> cc_display_item_list_; - gfx::Rect paintable_region_; + gfx::Rect layer_bounds_; + + Vector<PaintChunkInfo> paint_chunks_info_; Vector<std::unique_ptr<JSONArray>> paint_chunk_debug_data_; + String debug_name_; + + struct RasterInvalidationTrackingInfo { + using ClientDebugNamesMap = HashMap<const DisplayItemClient*, String>; + ClientDebugNamesMap new_client_debug_names; + ClientDebugNamesMap old_client_debug_names; + RasterInvalidationTracking tracking; + }; + std::unique_ptr<RasterInvalidationTrackingInfo> + raster_invalidation_tracking_info_; }; } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImplTest.cpp b/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImplTest.cpp new file mode 100644 index 0000000..016d8e6 --- /dev/null +++ b/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImplTest.cpp
@@ -0,0 +1,247 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "platform/graphics/compositing/ContentLayerClientImpl.h" + +#include "cc/layers/picture_layer.h" +#include "platform/graphics/paint/PaintArtifact.h" +#include "platform/testing/FakeDisplayItemClient.h" +#include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h" +#include "platform/wtf/dtoa/utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { + +static const IntRect kDefaultLayerBounds(-9999, -7777, 18888, 16666); + +class ContentLayerClientImplTest : public ::testing::Test, + private ScopedSlimmingPaintV2ForTest { + protected: + ContentLayerClientImplTest() : ScopedSlimmingPaintV2ForTest(true) {} + + static PropertyTreeState DefaultPropertyTreeState() { + return PropertyTreeState(TransformPaintPropertyNode::Root(), + ClipPaintPropertyNode::Root(), + EffectPaintPropertyNode::Root()); + } + + static PaintChunk Chunk( + int type, + int raster_invalidation_count = 0, + PaintChunk::Cacheable cacheable = PaintChunk::kCacheable) { + DEFINE_STATIC_LOCAL(FakeDisplayItemClient, fake_client, ()); + fake_client.ClearIsJustCreated(); + // The enum arithmetics and magic numbers are to produce different values + // of paint chunk and raster invalidation properties. + PaintChunk::Id id(fake_client, static_cast<DisplayItem::Type>( + DisplayItem::kDrawingFirst + type)); + PaintChunk chunk(0, 0, id, PaintChunkProperties(DefaultPropertyTreeState()), + cacheable); + chunk.bounds = + FloatRect(type * 110, type * 220, type * 220 + 200, type * 110 + 200); + for (int i = 0; i < raster_invalidation_count; ++i) { + chunk.raster_invalidation_rects.push_back(FloatRect( + type * 11, type * 22, type * 22 + 100 + i, type * 11 + 100 + i)); + RasterInvalidationInfo info; + info.client = &id.client; + info.reason = static_cast<PaintInvalidationReason>( + static_cast<int>(PaintInvalidationReason::kFull) + type + i); + chunk.raster_invalidation_tracking.push_back(info); + } + return chunk; + } + + static const Vector<RasterInvalidationInfo> TrackedRasterInvalidations( + const ContentLayerClientImpl& c) { + return c.TrackedRasterInvalidations(); + } + + static IntRect ChunkRectToLayer(const FloatRect& rect, + const IntPoint& layer_offset) { + FloatRect r = rect; + r.MoveBy(-layer_offset); + return EnclosingIntRect(r); + } + + static void ExpectDisplayItemInvalidations( + const Vector<RasterInvalidationInfo>& invalidations, + size_t index, + const PaintChunk& chunk, + const IntPoint& layer_offset = kDefaultLayerBounds.Location()) { + for (size_t i = 0; i < chunk.raster_invalidation_rects.size(); ++i) { + SCOPED_TRACE(index + i); + const auto& info = invalidations[index + i]; + EXPECT_EQ( + ChunkRectToLayer(chunk.raster_invalidation_rects[i], layer_offset), + info.rect); + EXPECT_EQ(&chunk.id.client, info.client); + EXPECT_EQ(chunk.raster_invalidation_tracking[i].reason, info.reason); + } + } + + static void ExpectChunkInvalidation( + const Vector<RasterInvalidationInfo>& invalidations, + size_t index, + const PaintChunk& chunk, + PaintInvalidationReason reason, + const IntPoint& layer_offset = kDefaultLayerBounds.Location()) { + SCOPED_TRACE(index); + const auto& info = invalidations[index]; + EXPECT_EQ(ChunkRectToLayer(chunk.bounds, layer_offset), info.rect); + EXPECT_EQ(&chunk.id.client, info.client); + EXPECT_EQ(reason, info.reason); + } +}; + +#define CHUNKS(name, ...) \ + PaintChunk name##_array[] = {__VA_ARGS__}; \ + Vector<const PaintChunk*> name; \ + for (size_t i = 0; i < ARRAY_SIZE(name##_array); ++i) \ + name.push_back(&name##_array[i]); + +TEST_F(ContentLayerClientImplTest, LayerBounds) { + ContentLayerClientImpl c; + c.SetTracksRasterInvalidations(true); + CHUNKS(chunks, Chunk(0)); + + auto cc_layer = + c.UpdateCcPictureLayer(PaintArtifact(), kDefaultLayerBounds, chunks, + DefaultPropertyTreeState(), false); + ASSERT_TRUE(cc_layer); + EXPECT_EQ(gfx::Rect(kDefaultLayerBounds.Size()), c.PaintableRegion()); + EXPECT_EQ(gfx::Size(kDefaultLayerBounds.Size()), cc_layer->bounds()); + // No raster invalidations needed for a new layer. + EXPECT_TRUE(TrackedRasterInvalidations(c).IsEmpty()); + + auto cc_layer1 = c.UpdateCcPictureLayer( + PaintArtifact(), + IntRect(kDefaultLayerBounds.Location(), IntSize(1234, 2345)), chunks, + DefaultPropertyTreeState(), false); + EXPECT_EQ(cc_layer, cc_layer1); + EXPECT_EQ(gfx::Rect(0, 0, 1234, 2345), c.PaintableRegion()); + EXPECT_EQ(gfx::Size(1234, 2345), cc_layer->bounds()); + // No raster invalidations needed if layer origin doesn't change. + EXPECT_TRUE(TrackedRasterInvalidations(c).IsEmpty()); + + auto cc_layer2 = + c.UpdateCcPictureLayer(PaintArtifact(), IntRect(-555, -666, 777, 888), + chunks, DefaultPropertyTreeState(), false); + EXPECT_EQ(cc_layer, cc_layer2); + EXPECT_EQ(gfx::Rect(0, 0, 777, 888), c.PaintableRegion()); + EXPECT_EQ(gfx::Size(777, 888), cc_layer->bounds()); + // Invalidate the whole layer on layer origin change. + const auto& invalidations = TrackedRasterInvalidations(c); + ASSERT_EQ(1u, invalidations.size()); + EXPECT_EQ(IntRect(0, 0, 777, 888), invalidations[0].rect); + EXPECT_EQ(PaintInvalidationReason::kFullLayer, invalidations[0].reason); +} + +TEST_F(ContentLayerClientImplTest, RasterInvalidationReorderChunks) { + ContentLayerClientImpl c; + CHUNKS(chunks, Chunk(0), Chunk(1), Chunk(2)); + c.SetTracksRasterInvalidations(true); + c.UpdateCcPictureLayer(PaintArtifact(), kDefaultLayerBounds, chunks, + DefaultPropertyTreeState(), false); + EXPECT_TRUE(TrackedRasterInvalidations(c).IsEmpty()); + + // Swap chunk 1 and 2. All chunks have their own local raster invalidations. + CHUNKS(new_chunks, Chunk(0, 2), Chunk(2, 4), Chunk(1, 3)); + new_chunks_array[1].bounds = FloatRect(11, 22, 33, 44); + c.UpdateCcPictureLayer(PaintArtifact(), kDefaultLayerBounds, new_chunks, + DefaultPropertyTreeState(), false); + const auto& invalidations = TrackedRasterInvalidations(c); + ASSERT_EQ(5u, invalidations.size()); + // The first chunk should always match because otherwise we won't reuse the + // ContentLayerClientImpl (which is according to the first chunk's id). + // For matched chunk, we issue raster invalidations if any found by + // PaintController. + ExpectDisplayItemInvalidations(invalidations, 0, *new_chunks[0]); + // Invalidated new chunk 1's old (as chunks[2]) and new (as new_chunks[1]) + // bounds. + ExpectChunkInvalidation(invalidations, 2, *chunks[2], + PaintInvalidationReason::kChunkReordered); + ExpectChunkInvalidation(invalidations, 3, *new_chunks[1], + PaintInvalidationReason::kChunkReordered); + // Invalidated new chunk 2's new bounds. Didn't invalidate old bounds because + // it's the same as the new bounds. + ExpectChunkInvalidation(invalidations, 4, *new_chunks[2], + PaintInvalidationReason::kChunkReordered); +} + +TEST_F(ContentLayerClientImplTest, RasterInvalidationAppearAndDisappear) { + ContentLayerClientImpl c; + CHUNKS(chunks, Chunk(0), Chunk(1), Chunk(2)); + c.SetTracksRasterInvalidations(true); + c.UpdateCcPictureLayer(PaintArtifact(), kDefaultLayerBounds, chunks, + DefaultPropertyTreeState(), false); + EXPECT_TRUE(TrackedRasterInvalidations(c).IsEmpty()); + + // Chunk 1 and 2 disappeared, 3 and 4 appeared. All chunks have their own + // local raster invalidations. + CHUNKS(new_chunks, Chunk(0, 2), Chunk(3, 3), Chunk(4, 3)); + c.UpdateCcPictureLayer(PaintArtifact(), kDefaultLayerBounds, new_chunks, + DefaultPropertyTreeState(), false); + const auto& invalidations = TrackedRasterInvalidations(c); + ASSERT_EQ(6u, invalidations.size()); + ExpectDisplayItemInvalidations(invalidations, 0, *new_chunks[0]); + ExpectChunkInvalidation(invalidations, 2, *new_chunks[1], + PaintInvalidationReason::kAppeared); + ExpectChunkInvalidation(invalidations, 3, *new_chunks[2], + PaintInvalidationReason::kAppeared); + ExpectChunkInvalidation(invalidations, 4, *chunks[1], + PaintInvalidationReason::kDisappeared); + ExpectChunkInvalidation(invalidations, 5, *chunks[2], + PaintInvalidationReason::kDisappeared); +} + +TEST_F(ContentLayerClientImplTest, RasterInvalidationAppearAtEnd) { + ContentLayerClientImpl c; + CHUNKS(chunks, Chunk(0)); + c.SetTracksRasterInvalidations(true); + c.UpdateCcPictureLayer(PaintArtifact(), kDefaultLayerBounds, chunks, + DefaultPropertyTreeState(), false); + EXPECT_TRUE(TrackedRasterInvalidations(c).IsEmpty()); + + CHUNKS(new_chunks, Chunk(0, 2), Chunk(1, 3), Chunk(2, 3)); + c.UpdateCcPictureLayer(PaintArtifact(), kDefaultLayerBounds, new_chunks, + DefaultPropertyTreeState(), false); + const auto& invalidations = TrackedRasterInvalidations(c); + ASSERT_EQ(4u, invalidations.size()); + ExpectDisplayItemInvalidations(invalidations, 0, *new_chunks[0]); + ExpectChunkInvalidation(invalidations, 2, *new_chunks[1], + PaintInvalidationReason::kAppeared); + ExpectChunkInvalidation(invalidations, 3, *new_chunks[2], + PaintInvalidationReason::kAppeared); +} + +TEST_F(ContentLayerClientImplTest, RasterInvalidationUncacheableChunks) { + ContentLayerClientImpl c; + CHUNKS(chunks, Chunk(0), Chunk(1, 0, PaintChunk::kUncacheable), Chunk(2)); + + c.SetTracksRasterInvalidations(true); + c.UpdateCcPictureLayer(PaintArtifact(), kDefaultLayerBounds, chunks, + DefaultPropertyTreeState(), false); + EXPECT_TRUE(TrackedRasterInvalidations(c).IsEmpty()); + + CHUNKS(new_chunks, Chunk(0, 2), Chunk(2, 3), + Chunk(1, 3, PaintChunk::kUncacheable)); + c.UpdateCcPictureLayer(PaintArtifact(), kDefaultLayerBounds, new_chunks, + DefaultPropertyTreeState(), false); + const auto& invalidations = TrackedRasterInvalidations(c); + ASSERT_EQ(5u, invalidations.size()); + ExpectDisplayItemInvalidations(invalidations, 0, *new_chunks[0]); + ExpectChunkInvalidation(invalidations, 2, *new_chunks[1], + PaintInvalidationReason::kChunkReordered); + ExpectChunkInvalidation(invalidations, 3, *new_chunks[2], + PaintInvalidationReason::kChunkUncacheable); + ExpectChunkInvalidation(invalidations, 4, *chunks[1], + PaintInvalidationReason::kChunkUncacheable); +} + +TEST_F(ContentLayerClientImplTest, RasterInvalidationPaintPropertyChange) { + // TODO(wangxianzhu): Add this test when implmenting raster invalidation on + // paint property change. +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp index 6210e27..4f78184 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp +++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp
@@ -11,7 +11,6 @@ #include "platform/RuntimeEnabledFeatures.h" #include "platform/graphics/GraphicsContext.h" #include "platform/graphics/compositing/ContentLayerClientImpl.h" -#include "platform/graphics/compositing/PaintChunksToCcLayer.h" #include "platform/graphics/compositing/PropertyTreeManager.h" #include "platform/graphics/paint/ClipPaintPropertyNode.h" #include "platform/graphics/paint/DisplayItem.h" @@ -29,22 +28,6 @@ namespace blink { -template <typename T> -static std::unique_ptr<JSONArray> PointAsJSONArray(const T& point) { - std::unique_ptr<JSONArray> array = JSONArray::Create(); - array->PushDouble(point.X()); - array->PushDouble(point.Y()); - return array; -} - -template <typename T> -static std::unique_ptr<JSONArray> SizeAsJSONArray(const T& size) { - std::unique_ptr<JSONArray> array = JSONArray::Create(); - array->PushDouble(size.Width()); - array->PushDouble(size.Height()); - return array; -} - // cc property trees make use of a sequence number to identify when tree // topology changes. For now we naively increment the sequence number each time // we update the property trees. We should explore optimizing our management of @@ -52,7 +35,8 @@ // http://crbug.com/692842#c4. static int g_s_property_tree_sequence_number = 1; -PaintArtifactCompositor::PaintArtifactCompositor() { +PaintArtifactCompositor::PaintArtifactCompositor() + : tracks_raster_invalidations_(false) { if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) return; root_layer_ = cc::Layer::Create(); @@ -62,9 +46,9 @@ PaintArtifactCompositor::~PaintArtifactCompositor() {} -void PaintArtifactCompositor::ResetTrackedRasterInvalidations() { +void PaintArtifactCompositor::SetTracksRasterInvalidations(bool should_track) { for (auto& client : content_layer_clients_) - client->ResetTrackedRasterInvalidations(); + client->SetTracksRasterInvalidations(should_track); } std::unique_ptr<JSONObject> PaintArtifactCompositor::LayersAsJSON( @@ -101,9 +85,7 @@ } std::unique_ptr<ContentLayerClientImpl> -PaintArtifactCompositor::ClientForPaintChunk( - const PaintChunk& paint_chunk, - const PaintArtifact& paint_artifact) { +PaintArtifactCompositor::ClientForPaintChunk(const PaintChunk& paint_chunk) { // TODO(chrishtr): for now, just using a linear walk. In the future we can // optimize this by using the same techniques used in PaintController for // display lists. @@ -112,26 +94,9 @@ return std::move(client); } - return WTF::WrapUnique(new ContentLayerClientImpl(paint_chunk)); -} - -IntRect PaintArtifactCompositor::MapRasterInvalidationRectFromChunkToLayer( - const FloatRect& r, - const PaintChunk& paint_chunk, - const PendingLayer& pending_layer, - const gfx::Vector2dF& layer_offset) { - FloatClipRect rect( - r == FloatRect(LayoutRect::InfiniteIntRect()) ? paint_chunk.bounds : r); - GeometryMapper::LocalToAncestorVisualRect( - paint_chunk.properties.property_tree_state, - pending_layer.property_tree_state, rect); - if (rect.Rect().IsEmpty()) - return IntRect(); - // Now rect is in the space of the containing transform node of pending_layer, - // so need to subtract off the layer offset. - rect.Rect().Move(-layer_offset.x(), -layer_offset.y()); - rect.Rect().Inflate(paint_chunk.outset_for_raster_effects); - return EnclosingIntRect(rect.Rect()); + auto client = WTF::MakeUnique<ContentLayerClientImpl>(); + client->SetTracksRasterInvalidations(tracks_raster_invalidations_); + return client; } scoped_refptr<cc::Layer> @@ -154,68 +119,16 @@ // The common case: create or reuse a PictureLayer for painted content. std::unique_ptr<ContentLayerClientImpl> content_layer_client = - ClientForPaintChunk(first_paint_chunk, paint_artifact); + ClientForPaintChunk(first_paint_chunk); gfx::Rect cc_combined_bounds(EnclosingIntRect(pending_layer.bounds)); - layer_offset = cc_combined_bounds.OffsetFromOrigin(); - scoped_refptr<cc::PictureLayer> cc_picture_layer = - content_layer_client->CcPictureLayer(); - cc_picture_layer->SetBounds(cc_combined_bounds.size()); - cc_picture_layer->SetIsDrawable(true); - cc_picture_layer->SetContentsOpaque(pending_layer.known_to_be_opaque); - content_layer_client->ClearPaintChunkDebugData(); - for (const auto& paint_chunk : pending_layer.paint_chunks) { - if (store_debug_info) { - content_layer_client->AddPaintChunkDebugData( - paint_artifact.GetDisplayItemList().SubsequenceAsJSON( - paint_chunk->begin_index, paint_chunk->end_index, - DisplayItemList::kSkipNonDrawings | - DisplayItemList::kShownOnlyDisplayItemTypes)); - } - - DCHECK(paint_chunk->raster_invalidation_tracking.IsEmpty() || - paint_chunk->raster_invalidation_rects.size() == - paint_chunk->raster_invalidation_tracking.size()); - - for (size_t i = 0; i < paint_chunk->raster_invalidation_rects.size(); ++i) { - auto rect = MapRasterInvalidationRectFromChunkToLayer( - paint_chunk->raster_invalidation_rects[i], *paint_chunk, - pending_layer, layer_offset); - if (rect.IsEmpty()) - continue; - content_layer_client->SetNeedsDisplayRect(rect); - - if (paint_chunk->raster_invalidation_tracking.IsEmpty()) - continue; - auto& cc_tracking = - content_layer_client->EnsureRasterInvalidationTracking(); - auto info = paint_chunk->raster_invalidation_tracking[i]; - info.rect = rect; - cc_tracking.invalidations.push_back(info); - cc_tracking.invalidation_region_since_last_paint.Unite(rect); - } - } - - Optional<RasterUnderInvalidationCheckingParams> params; - if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) { - params.emplace( - content_layer_client->EnsureRasterInvalidationTracking(), - IntRect(0, 0, cc_combined_bounds.width(), cc_combined_bounds.height()), - content_layer_client->DebugName()); - } - - auto display_list = PaintChunksToCcLayer::Convert( - pending_layer.paint_chunks, pending_layer.property_tree_state, - layer_offset, paint_artifact.GetDisplayItemList(), - params ? &*params : nullptr); - content_layer_client->SetDisplayList(std::move(display_list)); - content_layer_client->SetPaintableRegion( - gfx::Rect(cc_combined_bounds.size())); - + auto cc_layer = content_layer_client->UpdateCcPictureLayer( + paint_artifact, cc_combined_bounds, pending_layer.paint_chunks, + pending_layer.property_tree_state, store_debug_info); new_content_layer_clients.push_back(std::move(content_layer_client)); - return cc_picture_layer; + return cc_layer; } PaintArtifactCompositor::PendingLayer::PendingLayer( @@ -543,8 +456,7 @@ CollectPendingLayers(paint_artifact, pending_layers); Vector<std::unique_ptr<ContentLayerClientImpl>> new_content_layer_clients; - new_content_layer_clients.ReserveCapacity( - paint_artifact.PaintChunks().size()); + new_content_layer_clients.ReserveCapacity(pending_layers.size()); for (const PendingLayer& pending_layer : pending_layers) { gfx::Vector2dF layer_offset; scoped_refptr<cc::Layer> layer = CompositedLayerForPendingLayer( @@ -587,6 +499,7 @@ layer->SetEffectTreeIndex(effect_id); property_tree_manager.UpdateLayerScrollMapping(layer.get(), transform); + layer->SetContentsOpaque(pending_layer.known_to_be_opaque); layer->SetShouldCheckBackfaceVisibility(pending_layer.backface_hidden); if (extra_data_for_testing_enabled_)
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.h b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.h index 3f1bdd87..f64f580 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.h +++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.h
@@ -80,8 +80,7 @@ return extra_data_for_testing_.get(); } - void ResetTrackedRasterInvalidations(); - bool HasTrackedRasterInvalidations() const; + void SetTracksRasterInvalidations(bool); std::unique_ptr<JSONObject> LayersAsJSON(LayerTreeFlags) const; @@ -106,6 +105,7 @@ // applied by the compositor, and more properties will be applied internally // to the chunks as Skia commands. void Upcast(const PropertyTreeState&); + FloatRect bounds; Vector<const PaintChunk*> paint_chunks; bool known_to_be_opaque; @@ -145,12 +145,6 @@ static bool CanDecompositeEffect(const EffectPaintPropertyNode*, const PendingLayer&); - static IntRect MapRasterInvalidationRectFromChunkToLayer( - const FloatRect&, - const PaintChunk&, - const PendingLayer&, - const gfx::Vector2dF& layer_offset); - // Builds a leaf layer that represents a single paint chunk. // Note: cc::Layer API assumes the layer bounds start at (0, 0), but the // bounding box of a paint chunk does not necessarily start at (0, 0) (and @@ -168,8 +162,9 @@ // Finds a client among the current vector of clients that matches the paint // chunk's id, or otherwise allocates a new one. std::unique_ptr<ContentLayerClientImpl> ClientForPaintChunk( - const PaintChunk&, - const PaintArtifact&); + const PaintChunk&); + + bool tracks_raster_invalidations_; scoped_refptr<cc::Layer> root_layer_; std::unique_ptr<WebLayer> web_layer_; @@ -177,49 +172,9 @@ bool extra_data_for_testing_enabled_ = false; std::unique_ptr<ExtraDataForTesting> extra_data_for_testing_; + friend class StubChromeClientForSPv2; - - FRIEND_TEST_ALL_PREFIXES(PaintArtifactCompositorTestWithPropertyTrees, - ForeignLayerPassesThrough); - FRIEND_TEST_ALL_PREFIXES(PaintArtifactCompositorTestWithPropertyTrees, - MergeSimpleChunks); - FRIEND_TEST_ALL_PREFIXES(PaintArtifactCompositorTestWithPropertyTrees, - Merge2DTransform); - FRIEND_TEST_ALL_PREFIXES(PaintArtifactCompositorTestWithPropertyTrees, - Merge2DTransformDirectAncestor); - FRIEND_TEST_ALL_PREFIXES(PaintArtifactCompositorTestWithPropertyTrees, - MergeTransformOrigin); - FRIEND_TEST_ALL_PREFIXES(PaintArtifactCompositorTestWithPropertyTrees, - MergeClip); - FRIEND_TEST_ALL_PREFIXES(PaintArtifactCompositorTestWithPropertyTrees, - MergeOpacity); - FRIEND_TEST_ALL_PREFIXES(PaintArtifactCompositorTestWithPropertyTrees, - MergeNested); - FRIEND_TEST_ALL_PREFIXES(PaintArtifactCompositorTestWithPropertyTrees, - ClipPushedUp); - FRIEND_TEST_ALL_PREFIXES(PaintArtifactCompositorTestWithPropertyTrees, - EffectPushedUp); - FRIEND_TEST_ALL_PREFIXES(PaintArtifactCompositorTestWithPropertyTrees, - EffectAndClipPushedUp); - FRIEND_TEST_ALL_PREFIXES(PaintArtifactCompositorTestWithPropertyTrees, - ClipAndEffectNoTransform); - FRIEND_TEST_ALL_PREFIXES(PaintArtifactCompositorTestWithPropertyTrees, - TwoClips); - FRIEND_TEST_ALL_PREFIXES(PaintArtifactCompositorTestWithPropertyTrees, - TwoEffects); - FRIEND_TEST_ALL_PREFIXES(PaintArtifactCompositorTestWithPropertyTrees, - TwoTransformsClipBetween); - FRIEND_TEST_ALL_PREFIXES(PaintArtifactCompositorTestWithPropertyTrees, - OverlapTransform); - FRIEND_TEST_ALL_PREFIXES(PaintArtifactCompositorTestWithPropertyTrees, - MightOverlap); - - FRIEND_TEST_ALL_PREFIXES(PaintArtifactCompositorTestWithPropertyTrees, - PendingLayer); - FRIEND_TEST_ALL_PREFIXES(PaintArtifactCompositorTestWithPropertyTrees, - PendingLayerWithGeometry); - FRIEND_TEST_ALL_PREFIXES(PaintArtifactCompositorTestWithPropertyTrees, - PendingLayerKnownOpaque_DISABLED); + friend class PaintArtifactCompositorTestWithPropertyTrees; }; } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp index 9cb8d22..b3e8164 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp
@@ -32,14 +32,6 @@ namespace blink { -#define EXPECT_BLINK_FLOAT_RECT_EQ(expected, actual) \ - do { \ - EXPECT_FLOAT_EQ((expected).X(), (actual).X()); \ - EXPECT_FLOAT_EQ((expected).Y(), (actual).Y()); \ - EXPECT_FLOAT_EQ((expected).Width(), (actual).Width()); \ - EXPECT_FLOAT_EQ((expected).Height(), (actual).Height()); \ - } while (false) - using ::blink::testing::CreateOpacityOnlyEffect; using ::testing::Pointee; @@ -181,6 +173,12 @@ Update(artifact.Build()); } + using PendingLayer = PaintArtifactCompositor::PendingLayer; + + bool MightOverlap(const PendingLayer& a, const PendingLayer& b) { + return PaintArtifactCompositor::MightOverlap(a, b); + } + private: std::unique_ptr<PaintArtifactCompositor> paint_artifact_compositor_; scoped_refptr<base::TestSimpleTaskRunner> task_runner_; @@ -1519,15 +1517,14 @@ TEST_F(PaintArtifactCompositorTestWithPropertyTrees, MightOverlap) { PaintChunk paint_chunk = DefaultChunk(); paint_chunk.bounds = FloatRect(0, 0, 100, 100); - PaintArtifactCompositor::PendingLayer pending_layer(paint_chunk, false); + PendingLayer pending_layer(paint_chunk, false); PaintChunk paint_chunk2 = DefaultChunk(); paint_chunk2.bounds = FloatRect(0, 0, 100, 100); { - PaintArtifactCompositor::PendingLayer pending_layer2(paint_chunk2, false); - EXPECT_TRUE( - PaintArtifactCompositor::MightOverlap(pending_layer, pending_layer2)); + PendingLayer pending_layer2(paint_chunk2, false); + EXPECT_TRUE(MightOverlap(pending_layer, pending_layer2)); } RefPtr<TransformPaintPropertyNode> transform = @@ -1537,9 +1534,8 @@ false); { paint_chunk2.properties.property_tree_state.SetTransform(transform.Get()); - PaintArtifactCompositor::PendingLayer pending_layer2(paint_chunk2, false); - EXPECT_TRUE( - PaintArtifactCompositor::MightOverlap(pending_layer, pending_layer2)); + PendingLayer pending_layer2(paint_chunk2, false); + EXPECT_TRUE(MightOverlap(pending_layer, pending_layer2)); } RefPtr<TransformPaintPropertyNode> transform2 = @@ -1549,9 +1545,8 @@ false); { paint_chunk2.properties.property_tree_state.SetTransform(transform2.Get()); - PaintArtifactCompositor::PendingLayer pending_layer2(paint_chunk2, false); - EXPECT_FALSE( - PaintArtifactCompositor::MightOverlap(pending_layer, pending_layer2)); + PendingLayer pending_layer2(paint_chunk2, false); + EXPECT_FALSE(MightOverlap(pending_layer, pending_layer2)); } } @@ -1564,34 +1559,34 @@ chunk1.known_to_be_opaque = true; chunk1.bounds = FloatRect(0, 0, 30, 40); - PaintArtifactCompositor::PendingLayer pending_layer(chunk1, false); + PendingLayer pending_layer(chunk1, false); EXPECT_TRUE(pending_layer.backface_hidden); EXPECT_TRUE(pending_layer.known_to_be_opaque); - EXPECT_BLINK_FLOAT_RECT_EQ(FloatRect(0, 0, 30, 40), pending_layer.bounds); + EXPECT_EQ(FloatRect(0, 0, 30, 40), pending_layer.bounds); PaintChunk chunk2 = DefaultChunk(); chunk2.properties.property_tree_state = chunk1.properties.property_tree_state; chunk2.properties.backface_hidden = true; chunk2.known_to_be_opaque = true; chunk2.bounds = FloatRect(10, 20, 30, 40); - pending_layer.Merge(PaintArtifactCompositor::PendingLayer(chunk2, false)); + pending_layer.Merge(PendingLayer(chunk2, false)); EXPECT_TRUE(pending_layer.backface_hidden); // Bounds not equal to one PaintChunk. EXPECT_FALSE(pending_layer.known_to_be_opaque); - EXPECT_BLINK_FLOAT_RECT_EQ(FloatRect(0, 0, 40, 60), pending_layer.bounds); + EXPECT_EQ(FloatRect(0, 0, 40, 60), pending_layer.bounds); PaintChunk chunk3 = DefaultChunk(); chunk3.properties.property_tree_state = chunk1.properties.property_tree_state; chunk3.properties.backface_hidden = true; chunk3.known_to_be_opaque = true; chunk3.bounds = FloatRect(-5, -25, 20, 20); - pending_layer.Merge(PaintArtifactCompositor::PendingLayer(chunk3, false)); + pending_layer.Merge(PendingLayer(chunk3, false)); EXPECT_TRUE(pending_layer.backface_hidden); EXPECT_FALSE(pending_layer.known_to_be_opaque); - EXPECT_BLINK_FLOAT_RECT_EQ(FloatRect(-5, -25, 45, 85), pending_layer.bounds); + EXPECT_EQ(FloatRect(-5, -25, 45, 85), pending_layer.bounds); } TEST_F(PaintArtifactCompositorTestWithPropertyTrees, PendingLayerWithGeometry) { @@ -1607,17 +1602,17 @@ EffectPaintPropertyNode::Root()); chunk1.bounds = FloatRect(0, 0, 30, 40); - PaintArtifactCompositor::PendingLayer pending_layer(chunk1, false); + PendingLayer pending_layer(chunk1, false); - EXPECT_BLINK_FLOAT_RECT_EQ(FloatRect(0, 0, 30, 40), pending_layer.bounds); + EXPECT_EQ(FloatRect(0, 0, 30, 40), pending_layer.bounds); PaintChunk chunk2 = DefaultChunk(); chunk2.properties.property_tree_state = chunk1.properties.property_tree_state; chunk2.properties.property_tree_state.SetTransform(transform); chunk2.bounds = FloatRect(0, 0, 50, 60); - pending_layer.Merge(PaintArtifactCompositor::PendingLayer(chunk2, false)); + pending_layer.Merge(PendingLayer(chunk2, false)); - EXPECT_BLINK_FLOAT_RECT_EQ(FloatRect(0, 0, 70, 85), pending_layer.bounds); + EXPECT_EQ(FloatRect(0, 0, 70, 85), pending_layer.bounds); } // TODO(crbug.com/701991): @@ -1630,7 +1625,7 @@ EffectPaintPropertyNode::Root()); chunk1.bounds = FloatRect(0, 0, 30, 40); chunk1.known_to_be_opaque = false; - PaintArtifactCompositor::PendingLayer pending_layer(chunk1, false); + PendingLayer pending_layer(chunk1, false); EXPECT_FALSE(pending_layer.known_to_be_opaque); @@ -1638,7 +1633,7 @@ chunk2.properties.property_tree_state = chunk1.properties.property_tree_state; chunk2.bounds = FloatRect(0, 0, 25, 35); chunk2.known_to_be_opaque = true; - pending_layer.Merge(PaintArtifactCompositor::PendingLayer(chunk2, false)); + pending_layer.Merge(PendingLayer(chunk2, false)); // Chunk 2 doesn't cover the entire layer, so not opaque. EXPECT_FALSE(pending_layer.known_to_be_opaque); @@ -1647,7 +1642,7 @@ chunk3.properties.property_tree_state = chunk1.properties.property_tree_state; chunk3.bounds = FloatRect(0, 0, 50, 60); chunk3.known_to_be_opaque = true; - pending_layer.Merge(PaintArtifactCompositor::PendingLayer(chunk3, false)); + pending_layer.Merge(PendingLayer(chunk3, false)); // Chunk 3 covers the entire layer, so now it's opaque. EXPECT_TRUE(pending_layer.known_to_be_opaque);
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintChunk.h b/third_party/WebKit/Source/platform/graphics/paint/PaintChunk.h index 8fd6b2ea..a3d8686 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/PaintChunk.h +++ b/third_party/WebKit/Source/platform/graphics/paint/PaintChunk.h
@@ -43,7 +43,8 @@ properties(props), outset_for_raster_effects(0), known_to_be_opaque(false), - is_cacheable(cacheable == kCacheable) {} + is_cacheable(cacheable == kCacheable), + client_is_just_created(id.client.IsJustCreated()) {} size_t size() const { DCHECK_GE(end_index, begin_index); @@ -66,7 +67,7 @@ // even if it's id equals the old chunk's id (which may happen if this // chunk's client is just created at the same address of the old chunk's // deleted client). - return !id.client.IsJustCreated(); + return !client_is_just_created; } // Index of the first drawing in this chunk. @@ -102,11 +103,16 @@ bool is_cacheable : 1; - // SPv2 only. Rectangles that need to be re-rasterized in this chunk, in the - // coordinate space of the containing transform node. - Vector<FloatRect> raster_invalidation_rects; + // TODO(wangxianzhu): The following fields are 'mutable' for + // ContentLayerClientImpl to clear them, which will be unnecessary if we don't + // call PaintArtifactCompositor::Update() when paint artifact is unchanged. + mutable bool client_is_just_created : 1; - Vector<RasterInvalidationInfo> raster_invalidation_tracking; + // Rectangles that need to be re-rasterized in this chunk, in the coordinate + // space of the containing transform node. + mutable Vector<FloatRect> raster_invalidation_rects; + + mutable Vector<RasterInvalidationInfo> raster_invalidation_tracking; }; inline bool operator==(const PaintChunk& a, const PaintChunk& b) {
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintChunker.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintChunker.cpp index a1ce6f8..b844cd25 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/PaintChunker.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/PaintChunker.cpp
@@ -8,7 +8,7 @@ namespace blink { -PaintChunker::PaintChunker() : force_new_chunk_(DontForceNewChunk) {} +PaintChunker::PaintChunker() : force_new_chunk_(kDontForceNewChunk) {} PaintChunker::~PaintChunker() {} @@ -39,51 +39,41 @@ #endif ItemBehavior behavior; - Optional<PaintChunk::Id> new_chunk_id; - PaintChunk::Cacheable cacheable = - item.SkippedCache() ? PaintChunk::kUncacheable : PaintChunk::kCacheable; if (DisplayItem::IsForeignLayerType(item.GetType())) { behavior = kRequiresSeparateChunk; - // Use null chunkId if we are skipping cache, so that the chunk will not - // match any old chunk and will be treated as brand new. - new_chunk_id.emplace(item.GetId()); - - // Clear m_currentChunkId so that any display items after the foreign layer - // without a new chunk id will be treated as having no id to avoid the chunk - // from using the same id as the chunk before the foreign layer chunk. + // Clear current_chunk_id_ so that we will use the current display item's id + // as the chunk id, and any display items after the foreign layer without a + // new chunk id will be treated as having no id to avoid the chunk from + // using the same id as the chunk before the foreign layer chunk. current_chunk_id_ = WTF::nullopt; } else { behavior = kDefaultBehavior; - if (current_chunk_id_) { - new_chunk_id.emplace(*current_chunk_id_); - } else { - cacheable = PaintChunk::kUncacheable; - new_chunk_id.emplace(item.GetId()); - } } + size_t new_chunk_begin_index; if (chunks_.IsEmpty()) { - PaintChunk new_chunk(0, 1, *new_chunk_id, current_properties_, cacheable); - chunks_.push_back(new_chunk); - chunk_behavior_.push_back(behavior); - force_new_chunk_ = DontForceNewChunk; - return true; + new_chunk_begin_index = 0; + } else { + auto& last_chunk = chunks_.back(); + bool can_continue_chunk = + current_properties_ == last_chunk.properties && + behavior != kRequiresSeparateChunk && + chunk_behavior_.back() != kRequiresSeparateChunk && + force_new_chunk_ == kDontForceNewChunk; + if (can_continue_chunk) { + last_chunk.end_index++; + return false; + } + new_chunk_begin_index = last_chunk.end_index; } - auto& last_chunk = chunks_.back(); - bool can_continue_chunk = current_properties_ == last_chunk.properties && - behavior != kRequiresSeparateChunk && - chunk_behavior_.back() != kRequiresSeparateChunk && - force_new_chunk_ == DontForceNewChunk; - if (can_continue_chunk) { - last_chunk.end_index++; - return false; - } + force_new_chunk_ = kDontForceNewChunk; - force_new_chunk_ = DontForceNewChunk; - - PaintChunk new_chunk(last_chunk.end_index, last_chunk.end_index + 1, - *new_chunk_id, current_properties_, cacheable); + auto cacheable = + item.SkippedCache() ? PaintChunk::kUncacheable : PaintChunk::kCacheable; + PaintChunk new_chunk(new_chunk_begin_index, new_chunk_begin_index + 1, + current_chunk_id_ ? *current_chunk_id_ : item.GetId(), + current_properties_, cacheable); chunks_.push_back(new_chunk); chunk_behavior_.push_back(behavior); return true;
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintChunker.h b/third_party/WebKit/Source/platform/graphics/paint/PaintChunker.h index fab3b415..946dde8 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/PaintChunker.h +++ b/third_party/WebKit/Source/platform/graphics/paint/PaintChunker.h
@@ -15,7 +15,7 @@ namespace blink { -enum NewChunkForceState { DontForceNewChunk, ForceNewChunk }; +enum NewChunkForceState { kDontForceNewChunk, kForceNewChunk }; // Accepts information about changes to |PaintChunkProperties| as drawings are // accumulated, and produces a series of paint chunks: contiguous ranges of the @@ -38,7 +38,7 @@ void UpdateCurrentPaintChunkProperties( const PaintChunk::Id*, const PaintChunkProperties&, - NewChunkForceState force_new_chunk = DontForceNewChunk); + NewChunkForceState force_new_chunk = kDontForceNewChunk); // Returns true if a new chunk is created. bool IncrementDisplayItemIndex(const DisplayItem&);
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintChunkerTest.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintChunkerTest.cpp index 34843a28..4402a8f 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/PaintChunkerTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/PaintChunkerTest.cpp
@@ -201,7 +201,7 @@ PaintChunk(5, 7, id4, simple_transform_and_effect_with_updated_transform), PaintChunk(7, 9, item_after_restore.GetId(), - simple_transform_and_effect, PaintChunk::kUncacheable))); + simple_transform_and_effect))); } TEST_F(PaintChunkerTest, BuildChunksFromNestedTransforms) { @@ -242,8 +242,7 @@ ElementsAre(PaintChunk(0, 1, id1, DefaultPaintChunkProperties()), PaintChunk(1, 3, id2, simple_transform), PaintChunk(3, 4, item_after_restore.GetId(), - DefaultPaintChunkProperties(), - PaintChunk::kUncacheable))); + DefaultPaintChunkProperties()))); } TEST_F(PaintChunkerTest, ChangingPropertiesWithoutItems) { @@ -323,8 +322,7 @@ PaintChunk(1, 2, i1.GetId(), DefaultPaintChunkProperties()), PaintChunk(2, 3, i2.GetId(), DefaultPaintChunkProperties()), PaintChunk(3, 4, i3.GetId(), DefaultPaintChunkProperties()), - PaintChunk(4, 6, after_i3.GetId(), DefaultPaintChunkProperties(), - PaintChunk::kUncacheable), + PaintChunk(4, 6, after_i3.GetId(), DefaultPaintChunkProperties()), PaintChunk(6, 7, i6.GetId(), DefaultPaintChunkProperties()))); } @@ -372,10 +370,9 @@ PaintChunk(2, 4, id2, simple_transform, PaintChunk::kUncacheable), PaintChunk(4, 5, uncacheable_separate_chunk_item.GetId(), simple_transform, PaintChunk::kUncacheable), - PaintChunk(5, 6, after_separate_chunk.GetId(), simple_transform, - PaintChunk::kUncacheable), - PaintChunk(6, 7, after_restore.GetId(), DefaultPaintChunkProperties(), - PaintChunk::kUncacheable))); + PaintChunk(5, 6, after_separate_chunk.GetId(), simple_transform), + PaintChunk(6, 7, after_restore.GetId(), + DefaultPaintChunkProperties()))); } } // namespace
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp index de5a847..bf5ba98 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
@@ -485,7 +485,7 @@ UpdateCurrentPaintChunkProperties( cached_chunk->is_cacheable ? &cached_chunk->id : nullptr, - cached_chunk->properties, ForceNewChunk); + cached_chunk->properties, kForceNewChunk); } else { // Avoid uninitialized variable error on Windows. cached_chunk = current_paint_artifact_.PaintChunks().begin(); @@ -509,7 +509,7 @@ DCHECK(cached_chunk != current_paint_artifact_.PaintChunks().end()); UpdateCurrentPaintChunkProperties( cached_chunk->is_cacheable ? &cached_chunk->id : nullptr, - cached_chunk->properties, ForceNewChunk); + cached_chunk->properties, kForceNewChunk); } #if DCHECK_IS_ON() @@ -671,14 +671,9 @@ current_cached_subsequence_begin_index_in_new_list_) return; - static FloatRect infinite_float_rect(LayoutRect::InfiniteIntRect()); - if (!new_chunk.is_cacheable) { - // This chunk is not cacheable, so always invalidate the whole chunk. - AddRasterInvalidation( - new_display_item_list_[new_chunk.begin_index].Client(), new_chunk, - infinite_float_rect, PaintInvalidationReason::kFull); + // Uncacheable chunks will be invalidated in ContentLayerClientImpl. + if (!new_chunk.is_cacheable) return; - } // Try to match old chunk sequentially first. const auto& old_chunks = current_paint_artifact_.PaintChunks(); @@ -714,10 +709,6 @@ } } } - - // We reach here because the chunk is new. - AddRasterInvalidation(new_chunk.id.client, new_chunk, infinite_float_rect, - PaintInvalidationReason::kAppeared); } void PaintController::AddRasterInvalidation(const DisplayItemClient& client,
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintController.h b/third_party/WebKit/Source/platform/graphics/paint/PaintController.h index d156a90a..4b05f07 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/PaintController.h +++ b/third_party/WebKit/Source/platform/graphics/paint/PaintController.h
@@ -31,8 +31,6 @@ static const size_t kInitialDisplayItemListCapacityBytes = 512; -template class RasterInvalidationTrackingMap<const PaintChunk>; - // FrameFirstPaint stores first-paint, text or image painted for the // corresponding frame. They are never reset to false. First-paint is defined in // https://github.com/WICG/paint-timing. It excludes default background paint. @@ -76,7 +74,7 @@ void UpdateCurrentPaintChunkProperties( const PaintChunk::Id*, const PaintChunkProperties&, - NewChunkForceState force_new_chunk = DontForceNewChunk); + NewChunkForceState force_new_chunk = kDontForceNewChunk); // Retrieve the current paint properties. const PaintChunkProperties& CurrentPaintChunkProperties() const; @@ -198,7 +196,7 @@ } #endif - void SetTracksRasterInvalidations(bool value); + void SetTracksRasterInvalidations(bool); void SetupRasterUnderInvalidationChecking(); bool LastDisplayItemIsSubsequenceEnd() const;
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp index 358442117..1e1acd3 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
@@ -159,8 +159,11 @@ TestDisplayItem(client, kBackgroundDrawingType)); EXPECT_EQ(1u, GetPaintController().PaintChunks().size()); - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, - UnorderedElementsAre(FloatRect(LayoutRect::InfiniteIntRect()))); + // Raster invalidation for the whole chunk will be issued during + // PaintArtifactCompositor::Update(). + EXPECT_TRUE(GetPaintController() + .PaintChunks()[0] + .raster_invalidation_rects.IsEmpty()); } else { EXPECT_DISPLAY_LIST( GetPaintController().GetDisplayItemList(), 3, @@ -197,8 +200,11 @@ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) { EXPECT_EQ(1u, GetPaintController().PaintChunks().size()); - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, - UnorderedElementsAre(FloatRect(LayoutRect::InfiniteIntRect()))); + // Raster invalidation for the whole chunk will be issued during + // PaintArtifactCompositor::Update(). + EXPECT_TRUE(GetPaintController() + .PaintChunks()[0] + .raster_invalidation_rects.IsEmpty()); GetPaintController().UpdateCurrentPaintChunkProperties( &root_paint_chunk_id_, DefaultPaintChunkProperties()); @@ -782,9 +788,11 @@ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) { EXPECT_EQ(1u, GetPaintController().PaintChunks().size()); - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, - // This is a new chunk. - UnorderedElementsAre(FloatRect(LayoutRect::InfiniteIntRect()))); + // This is a new chunk. Raster invalidation for the whole chunk will be + // issued during PaintArtifactCompositor::Update(). + EXPECT_TRUE(GetPaintController() + .PaintChunks()[0] + .raster_invalidation_rects.IsEmpty()); GetPaintController().UpdateCurrentPaintChunkProperties( &root_paint_chunk_id_, DefaultPaintChunkProperties()); @@ -820,9 +828,11 @@ EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, // |second| disappeared from the first chunk. UnorderedElementsAre(FloatRect(100, 100, 200, 200))); - EXPECT_THAT(GetPaintController().PaintChunks()[1].raster_invalidation_rects, - // This is a new chunk. - UnorderedElementsAre(FloatRect(LayoutRect::InfiniteIntRect()))); + // This is a new chunk. Raster invalidation for the whole chunk will be + // issued during PaintArtifactCompositor::Update(). + EXPECT_TRUE(GetPaintController() + .PaintChunks()[1] + .raster_invalidation_rects.IsEmpty()); } else { EXPECT_DISPLAY_LIST( GetPaintController().GetDisplayItemList(), 4, @@ -1206,10 +1216,14 @@ GetPaintController().PaintChunks()[0].id); EXPECT_EQ(PaintChunk::Id(container2, kBackgroundDrawingType), GetPaintController().PaintChunks()[1].id); - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, - UnorderedElementsAre(FloatRect(LayoutRect::InfiniteIntRect()))); - EXPECT_THAT(GetPaintController().PaintChunks()[1].raster_invalidation_rects, - UnorderedElementsAre(FloatRect(LayoutRect::InfiniteIntRect()))); + // Raster invalidation for the whole chunks will be issued during + // PaintArtifactCompositor::Update(). + EXPECT_TRUE(GetPaintController() + .PaintChunks()[0] + .raster_invalidation_rects.IsEmpty()); + EXPECT_TRUE(GetPaintController() + .PaintChunks()[1] + .raster_invalidation_rects.IsEmpty()); } // Simulate the situation when |container1| gets a z-index that is greater @@ -1356,10 +1370,14 @@ GetPaintController().PaintChunks()[0].id); EXPECT_EQ(PaintChunk::Id(container2, kBackgroundDrawingType), GetPaintController().PaintChunks()[1].id); - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, - UnorderedElementsAre(FloatRect(LayoutRect::InfiniteIntRect()))); - EXPECT_THAT(GetPaintController().PaintChunks()[1].raster_invalidation_rects, - UnorderedElementsAre(FloatRect(LayoutRect::InfiniteIntRect()))); + // Raster invalidation for the whole chunks will be issued during + // PaintArtifactCompositor::Update(). + EXPECT_TRUE(GetPaintController() + .PaintChunks()[0] + .raster_invalidation_rects.IsEmpty()); + EXPECT_TRUE(GetPaintController() + .PaintChunks()[1] + .raster_invalidation_rects.IsEmpty()); } // Move content2 into container1, without invalidation. @@ -1568,16 +1586,23 @@ GetPaintController().PaintChunks()[3].id); EXPECT_EQ(PaintChunk::Id(content2, kBackgroundDrawingType), GetPaintController().PaintChunks()[4].id); - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, - UnorderedElementsAre(FloatRect(LayoutRect::InfiniteIntRect()))); - EXPECT_THAT(GetPaintController().PaintChunks()[1].raster_invalidation_rects, - UnorderedElementsAre(FloatRect(LayoutRect::InfiniteIntRect()))); - EXPECT_THAT(GetPaintController().PaintChunks()[2].raster_invalidation_rects, - UnorderedElementsAre(FloatRect(LayoutRect::InfiniteIntRect()))); - EXPECT_THAT(GetPaintController().PaintChunks()[3].raster_invalidation_rects, - UnorderedElementsAre(FloatRect(LayoutRect::InfiniteIntRect()))); - EXPECT_THAT(GetPaintController().PaintChunks()[4].raster_invalidation_rects, - UnorderedElementsAre(FloatRect(LayoutRect::InfiniteIntRect()))); + // Raster invalidation for the whole chunks will be issued during + // PaintArtifactCompositor::Update(). + EXPECT_TRUE(GetPaintController() + .PaintChunks()[0] + .raster_invalidation_rects.IsEmpty()); + EXPECT_TRUE(GetPaintController() + .PaintChunks()[1] + .raster_invalidation_rects.IsEmpty()); + EXPECT_TRUE(GetPaintController() + .PaintChunks()[2] + .raster_invalidation_rects.IsEmpty()); + EXPECT_TRUE(GetPaintController() + .PaintChunks()[3] + .raster_invalidation_rects.IsEmpty()); + EXPECT_TRUE(GetPaintController() + .PaintChunks()[4] + .raster_invalidation_rects.IsEmpty()); } // Invalidate container1 but not content1. @@ -1676,12 +1701,15 @@ GetPaintController().PaintChunks()[1].id); EXPECT_EQ(PaintChunk::Id(container1, kForegroundDrawingType), GetPaintController().PaintChunks()[2].id); - // This is a new chunk. - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, - UnorderedElementsAre(FloatRect(LayoutRect::InfiniteIntRect()))); + // This is a new chunk. Raster invalidation of the whole chunk will be + // issued during PaintArtifactCompositor::Update(). + EXPECT_TRUE(GetPaintController() + .PaintChunks()[0] + .raster_invalidation_rects.IsEmpty()); // This chunk didn't change. - EXPECT_THAT(GetPaintController().PaintChunks()[1].raster_invalidation_rects, - UnorderedElementsAre()); + EXPECT_TRUE(GetPaintController() + .PaintChunks()[1] + .raster_invalidation_rects.IsEmpty()); // |container1| is invalidated. EXPECT_THAT(GetPaintController().PaintChunks()[2].raster_invalidation_rects, UnorderedElementsAre(FloatRect(100, 100, 100, 100))); @@ -1727,8 +1755,11 @@ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) { EXPECT_EQ(1u, GetPaintController().PaintChunks().size()); - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, - UnorderedElementsAre(FloatRect(LayoutRect::InfiniteIntRect()))); + // Raster invalidation for the whole chunk will be issued during + // PaintArtifactCompositor::Update(). + EXPECT_TRUE(GetPaintController() + .PaintChunks()[0] + .raster_invalidation_rects.IsEmpty()); GetPaintController().UpdateCurrentPaintChunkProperties( &root_paint_chunk_id_, DefaultPaintChunkProperties());
diff --git a/third_party/WebKit/Source/platform/graphics/paint/RasterInvalidationTracking.h b/third_party/WebKit/Source/platform/graphics/paint/RasterInvalidationTracking.h index b466811..e65b3890 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/RasterInvalidationTracking.h +++ b/third_party/WebKit/Source/platform/graphics/paint/RasterInvalidationTracking.h
@@ -56,6 +56,19 @@ // Records under-invalidated pixels in dark red, accumulated. sk_sp<PaintRecord> under_invalidation_record; + void AddInvalidation(const DisplayItemClient* client, + const String& debug_name, + const IntRect& rect, + PaintInvalidationReason reason) { + RasterInvalidationInfo info; + info.client = client; + info.client_debug_name = debug_name; + info.rect = rect; + info.reason = reason; + invalidations.push_back(info); + invalidation_region_since_last_paint.Unite(info.rect); + } + // Compares the last recording against |new_record|, by rastering both into // bitmaps. If there are any differences outside of invalidated regions, // the corresponding pixels in under_invalidation_record will be drawn in
diff --git a/third_party/WebKit/Source/platform/graphics/paint/ScopedPaintChunkProperties.h b/third_party/WebKit/Source/platform/graphics/paint/ScopedPaintChunkProperties.h index ec0884c..bc270d6 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/ScopedPaintChunkProperties.h +++ b/third_party/WebKit/Source/platform/graphics/paint/ScopedPaintChunkProperties.h
@@ -24,7 +24,7 @@ const DisplayItemClient& client, DisplayItem::Type type, const PaintChunkProperties& properties, - NewChunkForceState force_new_chunk = DontForceNewChunk) + NewChunkForceState force_new_chunk = kDontForceNewChunk) : paint_controller_(paint_controller), previous_properties_(paint_controller.CurrentPaintChunkProperties()) { PaintChunk::Id id(client, type); @@ -38,7 +38,7 @@ PaintController& paint_controller, const DisplayItemClient& client, const PaintChunkProperties& properties, - NewChunkForceState force_new_chunk = DontForceNewChunk) + NewChunkForceState force_new_chunk = kDontForceNewChunk) : ScopedPaintChunkProperties(paint_controller, client, DisplayItem::kUninitializedType, @@ -49,9 +49,8 @@ // We should not return to the previous id, because that may cause a new // chunk to use the same id as that of the previous chunk before this // ScopedPaintChunkProperties. The painter should create another scope of - // paint properties with new id, or the new chunk will have no id and will - // not match any old chunk and will be treated as fully invalidated for - // rasterization. + // paint properties with new id, or the new chunk will use the id of the + // first display item as its id. paint_controller_.UpdateCurrentPaintChunkProperties(nullptr, previous_properties_); }
diff --git a/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp b/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp index d515bef71..8f4bf08 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp +++ b/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp
@@ -663,12 +663,7 @@ void Resource::WillAddClientOrObserver(PreloadReferencePolicy policy) { if (policy == kMarkAsReferenced && preload_result_ == kPreloadNotReferenced) { - if (IsLoaded()) - preload_result_ = kPreloadReferencedWhileComplete; - else if (IsLoading()) - preload_result_ = kPreloadReferencedWhileLoading; - else - preload_result_ = kPreloadReferenced; + preload_result_ = kPreloadReferenced; if (preload_discovery_time_) { int time_since_discovery = static_cast<int>(
diff --git a/third_party/WebKit/Source/platform/loader/fetch/Resource.h b/third_party/WebKit/Source/platform/loader/fetch/Resource.h index 605b835..4df41221 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/Resource.h +++ b/third_party/WebKit/Source/platform/loader/fetch/Resource.h
@@ -166,8 +166,6 @@ enum PreloadResult : uint8_t { kPreloadNotReferenced, kPreloadReferenced, - kPreloadReferencedWhileLoading, - kPreloadReferencedWhileComplete }; PreloadResult GetPreloadResult() const { return preload_result_; }
diff --git a/third_party/WebKit/Source/web/tests/AccessibilityObjectModelTest.cpp b/third_party/WebKit/Source/web/tests/AccessibilityObjectModelTest.cpp index 684063bb..1622da19 100644 --- a/third_party/WebKit/Source/web/tests/AccessibilityObjectModelTest.cpp +++ b/third_party/WebKit/Source/web/tests/AccessibilityObjectModelTest.cpp
@@ -232,6 +232,116 @@ EXPECT_EQ(7U, ax_cell2->AriaRowIndex()); } +class SparseAttributeAdapter : public AXSparseAttributeClient { + public: + SparseAttributeAdapter() {} + + std::map<AXBoolAttribute, bool> bool_attributes; + std::map<AXStringAttribute, String> string_attributes; + std::map<AXObjectAttribute, Persistent<AXObject>> object_attributes; + std::map<AXObjectVectorAttribute, HeapVector<Member<AXObject>>> + object_vector_attributes; + + private: + void AddBoolAttribute(AXBoolAttribute attribute, bool value) override { + ASSERT_TRUE(bool_attributes.find(attribute) == bool_attributes.end()); + bool_attributes[attribute] = value; + } + + void AddStringAttribute(AXStringAttribute attribute, + const String& value) override { + ASSERT_TRUE(string_attributes.find(attribute) == string_attributes.end()); + string_attributes[attribute] = value; + } + + void AddObjectAttribute(AXObjectAttribute attribute, + AXObject& value) override { + ASSERT_TRUE(object_attributes.find(attribute) == object_attributes.end()); + object_attributes[attribute] = value; + } + + void AddObjectVectorAttribute(AXObjectVectorAttribute attribute, + HeapVector<Member<AXObject>>& value) override { + ASSERT_TRUE(object_vector_attributes.find(attribute) == + object_vector_attributes.end()); + object_vector_attributes[attribute] = value; + } +}; + +TEST_F(AccessibilityObjectModelTest, SparseAttributes) { + SimRequest main_resource("https://example.com/", "text/html"); + LoadURL("https://example.com/"); + main_resource.Complete( + "<input id=target" + " aria-keyshortcuts=Ctrl+K" + " aria-roledescription=Widget" + " aria-activedescendant=active" + " aria-details=details" + " aria-errormessage=error>" + "<div id=active role=option></div>" + "<div id=active2 role=gridcell></div>" + "<div id=details role=contentinfo></div>" + "<div id=details2 role=form></div>" + "<div id=error role=article>Error</div>" + "<div id=error2 role=banner>Error 2</div>"); + + auto* target = GetDocument().getElementById("target"); + auto* cache = AXObjectCache(); + ASSERT_NE(nullptr, cache); + auto* ax_target = cache->GetOrCreate(target); + SparseAttributeAdapter sparse_attributes; + ax_target->GetSparseAXAttributes(sparse_attributes); + + ASSERT_EQ("Ctrl+K", + sparse_attributes + .string_attributes[AXStringAttribute::kAriaKeyShortcuts]); + ASSERT_EQ("Widget", + sparse_attributes + .string_attributes[AXStringAttribute::kAriaRoleDescription]); + ASSERT_EQ(kListBoxOptionRole, + sparse_attributes + .object_attributes[AXObjectAttribute::kAriaActiveDescendant] + ->RoleValue()); + ASSERT_EQ( + kContentInfoRole, + sparse_attributes.object_attributes[AXObjectAttribute::kAriaDetails] + ->RoleValue()); + ASSERT_EQ( + kArticleRole, + sparse_attributes.object_attributes[AXObjectAttribute::kAriaErrorMessage] + ->RoleValue()); + + target->accessibleNode()->setKeyShortcuts("Ctrl+L"); + target->accessibleNode()->setRoleDescription("Object"); + target->accessibleNode()->setActiveDescendant( + GetDocument().getElementById("active2")->accessibleNode()); + target->accessibleNode()->setDetails( + GetDocument().getElementById("details2")->accessibleNode()); + target->accessibleNode()->setErrorMessage( + GetDocument().getElementById("error2")->accessibleNode()); + + SparseAttributeAdapter sparse_attributes2; + ax_target->GetSparseAXAttributes(sparse_attributes2); + + ASSERT_EQ("Ctrl+L", + sparse_attributes2 + .string_attributes[AXStringAttribute::kAriaKeyShortcuts]); + ASSERT_EQ("Object", + sparse_attributes2 + .string_attributes[AXStringAttribute::kAriaRoleDescription]); + ASSERT_EQ(kCellRole, + sparse_attributes2 + .object_attributes[AXObjectAttribute::kAriaActiveDescendant] + ->RoleValue()); + ASSERT_EQ(kFormRole, sparse_attributes2 + .object_attributes[AXObjectAttribute::kAriaDetails] + ->RoleValue()); + ASSERT_EQ(kBannerRole, + sparse_attributes2 + .object_attributes[AXObjectAttribute::kAriaErrorMessage] + ->RoleValue()); +} + } // namespace } // namespace blink
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_copier.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_copier.py index 3cf8b98..2c7f4286 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_copier.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_copier.py
@@ -92,7 +92,7 @@ cur_dir = root.replace(self.dir_above_repo + '/', '') + '/' _log.debug('Scanning %s...', cur_dir) - dirs_to_skip = ('.git', 'test-plan') + dirs_to_skip = ('.git',) if dirs: for name in dirs_to_skip:
diff --git a/third_party/WebKit/public/platform/WebInputEvent.h b/third_party/WebKit/public/platform/WebInputEvent.h index 362d189b..6736e0a 100644 --- a/third_party/WebKit/public/platform/WebInputEvent.h +++ b/third_party/WebKit/public/platform/WebInputEvent.h
@@ -234,14 +234,17 @@ kBackButtonDown = 1 << 20, kForwardButtonDown = 1 << 21, + // Represents movement as a result of content changing under the cursor, + // not actual physical movement of the pointer + kRelativeMotionEvent = 1 << 22, + // The set of non-stateful modifiers that specifically change the // interpretation of the key being pressed. For example; IsLeft, // IsRight, IsComposing don't change the meaning of the key // being pressed. NumLockOn, ScrollLockOn, CapsLockOn are stateful // and don't indicate explicit depressed state. kKeyModifiers = kSymbolKey | kFnKey | kAltGrKey | kMetaKey | kAltKey | - kControlKey | - kShiftKey, + kControlKey | kShiftKey, kNoModifiers = 0, };
diff --git a/third_party/hamcrest/proguard.flags b/third_party/hamcrest/proguard.flags index e9caf63..695579df 100644 --- a/third_party/hamcrest/proguard.flags +++ b/third_party/hamcrest/proguard.flags
@@ -1 +1 @@ --dontobfuscate +-keepnames class org.hamcrest.** { *; }
diff --git a/tools/json_to_struct/json_to_struct.gni b/tools/json_to_struct/json_to_struct.gni index 8143922..5ebda45 100644 --- a/tools/json_to_struct/json_to_struct.gni +++ b/tools/json_to_struct/json_to_struct.gni
@@ -33,6 +33,7 @@ "//tools/json_to_struct/element_generator.py", "//tools/json_to_struct/struct_generator.py", invoker.source, + invoker.schema_file, ] out_dir = get_path_info(invoker.source, "gen_dir")
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 43fba2d..8e127ca 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -104,7 +104,7 @@ 'CFI Linux CF': 'cfi_full_cfi_diag_recover_release_static', 'CFI Linux ToT': 'cfi_full_clang_tot_release_static', 'CFI Linux': 'cfi_release_static', - 'CFI Linux Full': 'cfi_thin_lto_full_release_static_use_lld', + 'CFI Linux Full': 'cfi_full_cfi_diag_thin_lto_release_static_dcheck_always_on_goma', 'CFI ThinLTO Linux ToT': 'cfi_thin_lto_clang_tot_full_symbols_release_static_use_lld', 'Chromium Linux Goma Canary': 'release_bot', 'Chromium Linux Goma Canary': 'release_bot', @@ -529,7 +529,7 @@ 'linux_chromium_archive_rel_ng': 'release_bot', 'linux_chromium_asan_rel_ng': 'asan_lsan_release_trybot', 'linux_chromium_browser_side_navigation_rel': 'release_trybot', - 'linux_chromium_cfi_rel_ng': 'cfi_full_cfi_diag_thin_lto_release_static_dcheck_always_on', + 'linux_chromium_cfi_rel_ng': 'cfi_full_cfi_diag_thin_lto_release_static_dcheck_always_on_goma', 'linux_chromium_chromeos_asan_rel_ng': 'asan_lsan_chromeos_release_trybot', 'linux_chromium_chromeos_compile_dbg_ng': 'chromeos_with_codecs_debug_trybot', 'linux_chromium_chromeos_compile_rel_ng': 'chromeos_with_codecs_release_trybot', @@ -991,8 +991,8 @@ 'cfi_full', 'clang_tot', 'release', 'static', ], - 'cfi_full_cfi_diag_thin_lto_release_static_dcheck_always_on': [ - 'cfi_full', 'cfi_diag', 'thin_lto', 'release', 'static', 'dcheck_always_on', + 'cfi_full_cfi_diag_thin_lto_release_static_dcheck_always_on_goma': [ + 'cfi_full', 'cfi_diag', 'thin_lto', 'release', 'static', 'dcheck_always_on', 'goma', ], 'cfi_release_static': [ @@ -1003,10 +1003,6 @@ 'cfi', 'thin_lto', 'clang_tot', 'full_symbols', 'release', 'static', 'use_lld', ], - 'cfi_thin_lto_full_release_static_use_lld': [ - 'cfi', 'thin_lto', 'release', 'static', 'use_lld', - ], - 'chrome_with_codecs_blink_logging_release_trybot': [ 'chrome_with_codecs', 'blink_logging', 'release_trybot', ],
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 3fceb0f..2477883 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -5290,6 +5290,84 @@ </description> </action> +<action + name="InProductHelp.ShouldTriggerHelpUIResult.NotTriggered.IPH_DataSaverDetail"> + <owner>nyquist@chromium.org</owner> + <owner>xingliu@chromium.org</owner> + <description> + A user action that could have triggered In-Product Help did not. + </description> +</action> + +<action + name="InProductHelp.ShouldTriggerHelpUIResult.NotTriggered.IPH_DataSaverPreview"> + <owner>nyquist@chromium.org</owner> + <owner>xingliu@chromium.org</owner> + <description> + A user action that could have triggered In-Product Help did not. + </description> +</action> + +<action + name="InProductHelp.ShouldTriggerHelpUIResult.NotTriggered.IPH_DownloadHome"> + <owner>nyquist@chromium.org</owner> + <owner>xingliu@chromium.org</owner> + <description> + A user action that could have triggered In-Product Help did not. + </description> +</action> + +<action + name="InProductHelp.ShouldTriggerHelpUIResult.NotTriggered.IPH_DownloadPage"> + <owner>nyquist@chromium.org</owner> + <owner>xingliu@chromium.org</owner> + <description> + A user action that could have triggered In-Product Help did not. + </description> +</action> + +<action name="InProductHelp.ShouldTriggerHelpUIResult.NotTriggered.IPH_NewTab"> + <owner>nyquist@chromium.org</owner> + <owner>xingliu@chromium.org</owner> + <description> + A user action that could have triggered In-Product Help did not. + </description> +</action> + +<action + name="InProductHelp.ShouldTriggerHelpUIResult.Triggered.IPH_DataSaverDetail"> + <owner>nyquist@chromium.org</owner> + <owner>xingliu@chromium.org</owner> + <description>A user action triggered In-Product Help.</description> +</action> + +<action + name="InProductHelp.ShouldTriggerHelpUIResult.Triggered.IPH_DataSaverPreview"> + <owner>nyquist@chromium.org</owner> + <owner>xingliu@chromium.org</owner> + <description>A user action triggered In-Product Help.</description> +</action> + +<action + name="InProductHelp.ShouldTriggerHelpUIResult.Triggered.IPH_DownloadHome"> + <owner>nyquist@chromium.org</owner> + <owner>xingliu@chromium.org</owner> + <description>A user action triggered In-Product Help.</description> +</action> + +<action + name="InProductHelp.ShouldTriggerHelpUIResult.Triggered.IPH_DownloadPage"> + <owner>nyquist@chromium.org</owner> + <owner>xingliu@chromium.org</owner> + <description>A user action triggered In-Product Help.</description> +</action> + +<action name="InProductHelp.ShouldTriggerHelpUIResult.Triggered.IPH_NewTab"> + <owner>nyquist@chromium.org</owner> + <owner>xingliu@chromium.org</owner> + <description>A user action triggered In-Product Help.</description> +</action> + <action name="Indent"> <owner>Please list the metric's owners. Add more owner tags as needed.</owner> <description>Please enter the description of this user action.</description>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index e8474f2a..46b9759 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -47432,8 +47432,8 @@ <owner>fgorski@chromium.org</owner> <summary> Indicates whether the browser was connected when Open online button was - clicked on Website Settings popup, which causes a reload of an offline page - to online version. + clicked on Page Info popup, which causes a reload of an offline page to + online version. </summary> </histogram> @@ -47441,9 +47441,9 @@ enum="BooleanVisible"> <owner>fgorski@chromium.org</owner> <summary> - Indicates whether Open online was visible in Website Settings popup, when it - was shown for an offline page. (The button is visible only when Chrome is - connected when the Website Settings popup is opened for offline page.) + Indicates whether Open online was visible in Page Info popup, when it was + shown for an offline page. (The button is visible only when Chrome is + connected when the Page Info popup is opened for offline page.) </summary> </histogram> @@ -91773,21 +91773,9 @@ </histogram_suffixes> <histogram_suffixes name="NetHttpContentLengthType" separator="."> - <suffix name="Http"> - <obsolete> - Replaced by HttpContentLength Direct/ViaDRP variants. - </obsolete> - </suffix> - <suffix name="Https"> - <obsolete> - Replaced by HttpContentLength Direct/ViaDRP variants. - </obsolete> - </suffix> - <suffix name="Video"> - <obsolete> - Replaced by HttpContentLength Direct/ViaDRP variants. - </obsolete> - </suffix> + <suffix name="Http"/> + <suffix name="Https"/> + <suffix name="Video"/> <affected-histogram name="Net.HttpContentLength"/> <affected-histogram name="Net.HttpOriginalContentLength"/> </histogram_suffixes>
diff --git a/ui/aura/mus/input_method_mus.cc b/ui/aura/mus/input_method_mus.cc index 8fd6927..0292c97 100644 --- a/ui/aura/mus/input_method_mus.cc +++ b/ui/aura/mus/input_method_mus.cc
@@ -43,7 +43,7 @@ connector->BindInterface(ui::mojom::kServiceName, &ime_driver_); } -void InputMethodMus::DispatchKeyEvent( +ui::EventDispatchDetails InputMethodMus::DispatchKeyEvent( ui::KeyEvent* event, std::unique_ptr<EventResultCallback> ack_callback) { DCHECK(event->type() == ui::ET_KEY_PRESSED || @@ -51,15 +51,15 @@ // If no text input client, do nothing. if (!GetTextInputClient()) { - DispatchKeyEventPostIME(event); + ui::EventDispatchDetails dispatch_details = DispatchKeyEventPostIME(event); if (ack_callback) { ack_callback->Run(event->handled() ? EventResult::HANDLED : EventResult::UNHANDLED); } - return; + return dispatch_details; } - SendKeyEventToInputMethod(*event, std::move(ack_callback)); + return SendKeyEventToInputMethod(*event, std::move(ack_callback)); } //////////////////////////////////////////////////////////////////////////////// @@ -82,11 +82,12 @@ return false; } -void InputMethodMus::DispatchKeyEvent(ui::KeyEvent* event) { - DispatchKeyEvent(event, nullptr); +ui::EventDispatchDetails InputMethodMus::DispatchKeyEvent(ui::KeyEvent* event) { + ui::EventDispatchDetails dispatch_details = DispatchKeyEvent(event, nullptr); // Mark the event as handled so that EventGenerator doesn't attempt to // deliver event as well. event->SetHandled(); + return dispatch_details; } void InputMethodMus::OnTextInputTypeChanged(const ui::TextInputClient* client) { @@ -119,15 +120,14 @@ return false; } -void InputMethodMus::SendKeyEventToInputMethod( +ui::EventDispatchDetails InputMethodMus::SendKeyEventToInputMethod( const ui::KeyEvent& event, std::unique_ptr<EventResultCallback> ack_callback) { if (!input_method_) { // This code path is hit in tests that don't connect to the server. DCHECK(!ack_callback); std::unique_ptr<ui::Event> event_clone = ui::Event::Clone(event); - DispatchKeyEventPostIME(event_clone->AsKeyEvent()); - return; + return DispatchKeyEventPostIME(event_clone->AsKeyEvent()); } // IME driver will notify us whether it handled the event or not by calling // ProcessKeyEventCallback(), in which we will run the |ack_callback| to tell @@ -137,6 +137,8 @@ ui::Event::Clone(event), base::Bind(&InputMethodMus::ProcessKeyEventCallback, base::Unretained(this), event)); + + return ui::EventDispatchDetails(); } void InputMethodMus::OnDidChangeFocusedClient( @@ -207,7 +209,7 @@ // any client-side post-ime processing needs to be done. This includes cases // like backspace, return key, etc. std::unique_ptr<ui::Event> event_clone = ui::Event::Clone(event); - DispatchKeyEventPostIME(event_clone->AsKeyEvent()); + ignore_result(DispatchKeyEventPostIME(event_clone->AsKeyEvent())); event_result = event_clone->handled() ? EventResult::HANDLED : EventResult::UNHANDLED; } else {
diff --git a/ui/aura/mus/input_method_mus.h b/ui/aura/mus/input_method_mus.h index 52d77de5..f5d8bc8 100644 --- a/ui/aura/mus/input_method_mus.h +++ b/ui/aura/mus/input_method_mus.h
@@ -34,15 +34,16 @@ ~InputMethodMus() override; void Init(service_manager::Connector* connector); - void DispatchKeyEvent(ui::KeyEvent* event, - std::unique_ptr<EventResultCallback> ack_callback); + ui::EventDispatchDetails DispatchKeyEvent( + ui::KeyEvent* event, + std::unique_ptr<EventResultCallback> ack_callback) WARN_UNUSED_RESULT; // Overridden from ui::InputMethod: void OnFocus() override; void OnBlur() override; bool OnUntranslatedIMEMessage(const base::NativeEvent& event, NativeEventResult* result) override; - void DispatchKeyEvent(ui::KeyEvent* event) override; + ui::EventDispatchDetails DispatchKeyEvent(ui::KeyEvent* event) override; void OnTextInputTypeChanged(const ui::TextInputClient* client) override; void OnCaretBoundsChanged(const ui::TextInputClient* client) override; void CancelComposition(const ui::TextInputClient* client) override; @@ -54,9 +55,9 @@ friend TextInputClientImpl; // Called from DispatchKeyEvent() to call to the InputMethod. - void SendKeyEventToInputMethod( + ui::EventDispatchDetails SendKeyEventToInputMethod( const ui::KeyEvent& event, - std::unique_ptr<EventResultCallback> ack_callback); + std::unique_ptr<EventResultCallback> ack_callback) WARN_UNUSED_RESULT; // Overridden from ui::InputMethodBase: void OnDidChangeFocusedClient(ui::TextInputClient* focused_before,
diff --git a/ui/aura/mus/input_method_mus_unittest.cc b/ui/aura/mus/input_method_mus_unittest.cc index 9ee10bf..51ed8279 100644 --- a/ui/aura/mus/input_method_mus_unittest.cc +++ b/ui/aura/mus/input_method_mus_unittest.cc
@@ -86,13 +86,19 @@ std::unique_ptr<EventResultCallback> callback = base::MakeUnique<EventResultCallback>(base::Bind( &RunFunctionWithEventResult, &was_event_result_callback_run)); - InputMethodMusTestApi::CallSendKeyEventToInputMethod( - &input_method_mus, ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, 0), - std::move(callback)); + + ui::EventDispatchDetails details = + InputMethodMusTestApi::CallSendKeyEventToInputMethod( + &input_method_mus, + ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, 0), + std::move(callback)); + ASSERT_TRUE(!details.dispatcher_destroyed && !details.target_destroyed); + // Add a null callback as well, to make sure null is deal with. - InputMethodMusTestApi::CallSendKeyEventToInputMethod( + details = InputMethodMusTestApi::CallSendKeyEventToInputMethod( &input_method_mus, ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, 0), nullptr); + ASSERT_TRUE(!details.dispatcher_destroyed && !details.target_destroyed); // The event should have been queued. EXPECT_EQ(2u, test_input_method.process_key_event_callbacks()->size()); // Callback should not have been run yet. @@ -116,9 +122,12 @@ std::unique_ptr<EventResultCallback> callback = base::MakeUnique<EventResultCallback>(base::Bind( &RunFunctionWithEventResult, &was_event_result_callback_run)); - InputMethodMusTestApi::CallSendKeyEventToInputMethod( - &input_method_mus, ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, 0), - std::move(callback)); + ui::EventDispatchDetails details = + InputMethodMusTestApi::CallSendKeyEventToInputMethod( + &input_method_mus, + ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, 0), + std::move(callback)); + ASSERT_TRUE(!details.dispatcher_destroyed && !details.target_destroyed); // The event should have been queued. EXPECT_EQ(1u, test_input_method.process_key_event_callbacks()->size()); // Callback should not have been run yet. @@ -180,8 +189,10 @@ base::MakeUnique<EventResultCallback>(base::Bind( &RunFunctionWithEventResult, &was_event_result_callback_run)); const ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, 0); - InputMethodMusTestApi::CallSendKeyEventToInputMethod( - &input_method_mus, key_event, std::move(callback)); + ui::EventDispatchDetails details = + InputMethodMusTestApi::CallSendKeyEventToInputMethod( + &input_method_mus, key_event, std::move(callback)); + ASSERT_TRUE(!details.dispatcher_destroyed && !details.target_destroyed); // The event should have been queued. ASSERT_EQ(1u, test_input_method.process_key_event_callbacks()->size()); // Callback should not have been run yet.
diff --git a/ui/aura/mus/window_tree_client.cc b/ui/aura/mus/window_tree_client.cc index 36422a3c..b69d69d 100644 --- a/ui/aura/mus/window_tree_client.cc +++ b/ui/aura/mus/window_tree_client.cc
@@ -1357,8 +1357,8 @@ if (event->IsKeyEvent()) { InputMethodMus* input_method = GetWindowTreeHostMus(window)->input_method(); if (input_method) { - input_method->DispatchKeyEvent(event->AsKeyEvent(), - CreateEventResultCallback(event_id)); + ignore_result(input_method->DispatchKeyEvent( + event->AsKeyEvent(), CreateEventResultCallback(event_id))); return; } }
diff --git a/ui/aura/test/event_generator_delegate_aura.cc b/ui/aura/test/event_generator_delegate_aura.cc index 25a7e141..0fbdee8 100644 --- a/ui/aura/test/event_generator_delegate_aura.cc +++ b/ui/aura/test/event_generator_delegate_aura.cc
@@ -133,10 +133,11 @@ window->GetHost()->ConvertPixelsToDIP(point); } -void EventGeneratorDelegateAura::DispatchKeyEventToIME(ui::EventTarget* target, - ui::KeyEvent* event) { +ui::EventDispatchDetails EventGeneratorDelegateAura::DispatchKeyEventToIME( + ui::EventTarget* target, + ui::KeyEvent* event) { Window* window = static_cast<Window*>(target); - window->GetHost()->GetInputMethod()->DispatchKeyEvent(event); + return window->GetHost()->GetInputMethod()->DispatchKeyEvent(event); } void EventGeneratorDelegateAura::DispatchEventToPointerWatchers(
diff --git a/ui/aura/test/event_generator_delegate_aura.h b/ui/aura/test/event_generator_delegate_aura.h index 82b013d..c856e8a 100644 --- a/ui/aura/test/event_generator_delegate_aura.h +++ b/ui/aura/test/event_generator_delegate_aura.h
@@ -46,8 +46,8 @@ gfx::Point* point) const override; void ConvertPointFromHost(const ui::EventTarget* hosted_target, gfx::Point* point) const override; - void DispatchKeyEventToIME(ui::EventTarget* target, - ui::KeyEvent* event) override; + ui::EventDispatchDetails DispatchKeyEventToIME(ui::EventTarget* target, + ui::KeyEvent* event) override; void DispatchEventToPointerWatchers(ui::EventTarget* target, const ui::PointerEvent& event) override;
diff --git a/ui/aura/test/mus/input_method_mus_test_api.h b/ui/aura/test/mus/input_method_mus_test_api.h index 9e5efd2..4fd1bb2 100644 --- a/ui/aura/test/mus/input_method_mus_test_api.h +++ b/ui/aura/test/mus/input_method_mus_test_api.h
@@ -17,11 +17,13 @@ input_method_mus->input_method_ = input_method; } - static void CallSendKeyEventToInputMethod( + static ui::EventDispatchDetails CallSendKeyEventToInputMethod( InputMethodMus* input_method_mus, const ui::KeyEvent& event, - std::unique_ptr<InputMethodMus::EventResultCallback> ack_callback) { - input_method_mus->SendKeyEventToInputMethod(event, std::move(ack_callback)); + std::unique_ptr<InputMethodMus::EventResultCallback> ack_callback) + WARN_UNUSED_RESULT { + return input_method_mus->SendKeyEventToInputMethod(event, + std::move(ack_callback)); } static void Disable(InputMethodMus* input_method) {
diff --git a/ui/aura/window_event_dispatcher.cc b/ui/aura/window_event_dispatcher.cc index ea3e2fdc..e8eb94d6 100644 --- a/ui/aura/window_event_dispatcher.cc +++ b/ui/aura/window_event_dispatcher.cc
@@ -937,14 +937,14 @@ return PreDispatchLocatedEvent(target, event); } -ui::EventDispatchDetails WindowEventDispatcher::PreDispatchKeyEvent( +DispatchDetails WindowEventDispatcher::PreDispatchKeyEvent( ui::KeyEvent* event) { if (skip_ime_ || !host_->has_input_method() || (event->flags() & ui::EF_IS_SYNTHESIZED)) - return ui::EventDispatchDetails(); - host_->GetInputMethod()->DispatchKeyEvent(event); + return DispatchDetails(); + DispatchDetails details = host_->GetInputMethod()->DispatchKeyEvent(event); event->StopPropagation(); - return ui::EventDispatchDetails(); + return details; } } // namespace aura
diff --git a/ui/aura/window_tree_host_unittest.cc b/ui/aura/window_tree_host_unittest.cc index 7da3eb9..735d26d 100644 --- a/ui/aura/window_tree_host_unittest.cc +++ b/ui/aura/window_tree_host_unittest.cc
@@ -78,7 +78,9 @@ host()->AddEventRewriter(&event_rewriter); ui::KeyEvent key_event('A', ui::VKEY_A, 0); - host()->GetInputMethod()->DispatchKeyEvent(&key_event); + ui::EventDispatchDetails details = + host()->GetInputMethod()->DispatchKeyEvent(&key_event); + ASSERT_TRUE(!details.dispatcher_destroyed && !details.target_destroyed); EXPECT_EQ(0, event_rewriter.events_seen()); host()->RemoveEventRewriter(&event_rewriter);
diff --git a/ui/base/ime/dummy_input_method.cc b/ui/base/ime/dummy_input_method.cc index c5c6524..9b6b2cd 100644 --- a/ui/base/ime/dummy_input_method.cc +++ b/ui/base/ime/dummy_input_method.cc
@@ -37,7 +37,9 @@ return NULL; } -void DummyInputMethod::DispatchKeyEvent(ui::KeyEvent* event) { +ui::EventDispatchDetails DummyInputMethod::DispatchKeyEvent( + ui::KeyEvent* event) { + return ui::EventDispatchDetails(); } void DummyInputMethod::OnTextInputTypeChanged(const TextInputClient* client) {
diff --git a/ui/base/ime/dummy_input_method.h b/ui/base/ime/dummy_input_method.h index 4292aed..6a9201f 100644 --- a/ui/base/ime/dummy_input_method.h +++ b/ui/base/ime/dummy_input_method.h
@@ -26,7 +26,7 @@ void SetFocusedTextInputClient(TextInputClient* client) override; void DetachTextInputClient(TextInputClient* client) override; TextInputClient* GetTextInputClient() const override; - void DispatchKeyEvent(ui::KeyEvent* event) override; + ui::EventDispatchDetails DispatchKeyEvent(ui::KeyEvent* event) override; void OnTextInputTypeChanged(const TextInputClient* client) override; void OnCaretBoundsChanged(const TextInputClient* client) override; void CancelComposition(const TextInputClient* client) override;
diff --git a/ui/base/ime/input_method.h b/ui/base/ime/input_method.h index 6b1d526..fad2ecc 100644 --- a/ui/base/ime/input_method.h +++ b/ui/base/ime/input_method.h
@@ -15,6 +15,7 @@ #include "build/build_config.h" #include "ui/base/ime/text_input_mode.h" #include "ui/base/ime/text_input_type.h" +#include "ui/events/event_dispatcher.h" #include "ui/gfx/geometry/rect.h" namespace extensions { @@ -101,7 +102,8 @@ // dispatched back to the caller via // ui::InputMethodDelegate::DispatchKeyEventPostIME(), once it's processed by // the input method. It should only be called by a message dispatcher. - virtual void DispatchKeyEvent(ui::KeyEvent* event) = 0; + virtual ui::EventDispatchDetails DispatchKeyEvent(ui::KeyEvent* event) + WARN_UNUSED_RESULT = 0; // Called by the focused client whenever its text input type is changed. // Before calling this method, the focused client must confirm or clear
diff --git a/ui/base/ime/input_method_android.cc b/ui/base/ime/input_method_android.cc index 7ec33a6..65307f3e 100644 --- a/ui/base/ime/input_method_android.cc +++ b/ui/base/ime/input_method_android.cc
@@ -28,17 +28,12 @@ return false; } -void InputMethodAndroid::DispatchKeyEvent(ui::KeyEvent* event) { +ui::EventDispatchDetails InputMethodAndroid::DispatchKeyEvent( + ui::KeyEvent* event) { DCHECK(event->type() == ui::ET_KEY_PRESSED || event->type() == ui::ET_KEY_RELEASED); - // If no text input client, do nothing. - if (!GetTextInputClient()) { - ignore_result(DispatchKeyEventPostIME(event)); - return; - } - - ignore_result(DispatchKeyEventPostIME(event)); + return DispatchKeyEventPostIME(event); } void InputMethodAndroid::OnCaretBoundsChanged(
diff --git a/ui/base/ime/input_method_android.h b/ui/base/ime/input_method_android.h index 19ba2d98..02d3c0a 100644 --- a/ui/base/ime/input_method_android.h +++ b/ui/base/ime/input_method_android.h
@@ -20,7 +20,7 @@ // Overriden from InputMethod. bool OnUntranslatedIMEMessage(const base::NativeEvent& event, NativeEventResult* result) override; - void DispatchKeyEvent(ui::KeyEvent* event) override; + ui::EventDispatchDetails DispatchKeyEvent(ui::KeyEvent* event) override; void OnCaretBoundsChanged(const TextInputClient* client) override; void CancelComposition(const TextInputClient* client) override; bool IsCandidatePopupOpen() const override;
diff --git a/ui/base/ime/input_method_auralinux.cc b/ui/base/ime/input_method_auralinux.cc index 31023c3..03833c1 100644 --- a/ui/base/ime/input_method_auralinux.cc +++ b/ui/base/ime/input_method_auralinux.cc
@@ -57,27 +57,26 @@ return false; } -void InputMethodAuraLinux::DispatchKeyEvent(ui::KeyEvent* event) { +ui::EventDispatchDetails InputMethodAuraLinux::DispatchKeyEvent( + ui::KeyEvent* event) { DCHECK(event->type() == ET_KEY_PRESSED || event->type() == ET_KEY_RELEASED); // If no text input client, do nothing. - if (!GetTextInputClient()) { - ignore_result(DispatchKeyEventPostIME(event)); - return; - } + if (!GetTextInputClient()) + return DispatchKeyEventPostIME(event); if (!event->HasNativeEvent() && sending_key_event_) { // Faked key events that are sent from input.ime.sendKeyEvents. ui::EventDispatchDetails details = DispatchKeyEventPostIME(event); if (details.dispatcher_destroyed || details.target_destroyed || event->stopped_propagation()) { - return; + return details; } if ((event->is_char() || event->GetDomKey().IsCharacter()) && event->type() == ui::ET_KEY_PRESSED) { GetTextInputClient()->InsertChar(*event); } - return; + return details; } suppress_next_result_ = false; @@ -112,9 +111,10 @@ base::Owned(new ui::CompositionText(composition_)), base::Owned(new base::string16(result_text_))); GetEngine()->ProcessKeyEvent(*event, callback); - } else { - ProcessKeyEventDone(event, filtered, false); + return ui::EventDispatchDetails(); } + + return ProcessKeyEventDone(event, filtered, false); } void InputMethodAuraLinux::ProcessKeyEventByEngineDone( @@ -127,15 +127,16 @@ composition_changed_ = composition_changed; composition_.CopyFrom(*composition); result_text_ = *result_text; - ProcessKeyEventDone(event, filtered, is_handled); + ignore_result(ProcessKeyEventDone(event, filtered, is_handled)); } -void InputMethodAuraLinux::ProcessKeyEventDone(ui::KeyEvent* event, - bool filtered, - bool is_handled) { +ui::EventDispatchDetails InputMethodAuraLinux::ProcessKeyEventDone( + ui::KeyEvent* event, + bool filtered, + bool is_handled) { DCHECK(event); if (is_handled) - return; + return ui::EventDispatchDetails(); // If the IME extension has not handled the key event, passes the keyevent // back to the previous processing flow. Preconditions for this situation: @@ -148,12 +149,12 @@ else if (HasInputMethodResult()) details = SendFakeProcessKeyEvent(event); if (details.dispatcher_destroyed) - return; + return details; // If the KEYDOWN is stopped propagation (e.g. triggered an accelerator), // don't InsertChar/InsertText to the input field. if (event->stopped_propagation() || details.target_destroyed) { ResetContext(); - return; + return details; } // Don't send VKEY_PROCESSKEY event if there is no result text or @@ -207,7 +208,7 @@ if (details.dispatcher_destroyed) { if (should_stop_propagation) event->StopPropagation(); - return; + return details; } if (event->stopped_propagation() || details.target_destroyed) { ResetContext(); @@ -229,6 +230,8 @@ if (should_stop_propagation) event->StopPropagation(); + + return details; } void InputMethodAuraLinux::UpdateContextFocusState() {
diff --git a/ui/base/ime/input_method_auralinux.h b/ui/base/ime/input_method_auralinux.h index 85dcd77..88cd935 100644 --- a/ui/base/ime/input_method_auralinux.h +++ b/ui/base/ime/input_method_auralinux.h
@@ -29,7 +29,7 @@ // Overriden from InputMethod. bool OnUntranslatedIMEMessage(const base::NativeEvent& event, NativeEventResult* result) override; - void DispatchKeyEvent(ui::KeyEvent* event) override; + ui::EventDispatchDetails DispatchKeyEvent(ui::KeyEvent* event) override; void OnTextInputTypeChanged(const TextInputClient* client) override; void OnCaretBoundsChanged(const TextInputClient* client) override; void CancelComposition(const TextInputClient* client) override; @@ -51,14 +51,18 @@ private: bool HasInputMethodResult(); bool NeedInsertChar() const; - ui::EventDispatchDetails SendFakeProcessKeyEvent(ui::KeyEvent* event) const; + ui::EventDispatchDetails SendFakeProcessKeyEvent(ui::KeyEvent* event) const + WARN_UNUSED_RESULT; void ConfirmCompositionText(); void UpdateContextFocusState(); void ResetContext(); // Processes the key event after the event is processed by the system IME or // the extension. - void ProcessKeyEventDone(ui::KeyEvent* event, bool filtered, bool is_handled); + ui::EventDispatchDetails ProcessKeyEventDone(ui::KeyEvent* event, + bool filtered, + bool is_handled) + WARN_UNUSED_RESULT; // Callback function for IMEEngineHandlerInterface::ProcessKeyEvent(). // It recovers the context when the event is being passed to the extension and
diff --git a/ui/base/ime/input_method_base.cc b/ui/base/ime/input_method_base.cc index f436c5d5..2515ab1 100644 --- a/ui/base/ime/input_method_base.cc +++ b/ui/base/ime/input_method_base.cc
@@ -224,7 +224,8 @@ key_events_for_testing_.push_back( std::unique_ptr<ui::KeyEvent>(new KeyEvent(*event))); } - DispatchKeyEvent(event); + ui::EventDispatchDetails details = DispatchKeyEvent(event); + DCHECK(!details.dispatcher_destroyed); sending_key_event_ = false; }
diff --git a/ui/base/ime/input_method_base.h b/ui/base/ime/input_method_base.h index aa16c6f..dbf9df4 100644 --- a/ui/base/ime/input_method_base.h +++ b/ui/base/ime/input_method_base.h
@@ -94,8 +94,8 @@ // Convenience method to call delegate_->DispatchKeyEventPostIME(). // Returns true if the event was processed - ui::EventDispatchDetails DispatchKeyEventPostIME( - ui::KeyEvent* event) const; + ui::EventDispatchDetails DispatchKeyEventPostIME(ui::KeyEvent* event) const + WARN_UNUSED_RESULT; // Convenience method to notify all observers of TextInputClient changes. void NotifyTextInputStateChanged(const TextInputClient* client);
diff --git a/ui/base/ime/input_method_base_unittest.cc b/ui/base/ime/input_method_base_unittest.cc index 93c3b5a..f726e9d 100644 --- a/ui/base/ime/input_method_base_unittest.cc +++ b/ui/base/ime/input_method_base_unittest.cc
@@ -145,7 +145,9 @@ InputMethod::NativeEventResult* result) override { return false; } - void DispatchKeyEvent(ui::KeyEvent*) override {} + ui::EventDispatchDetails DispatchKeyEvent(ui::KeyEvent*) override { + return ui::EventDispatchDetails(); + } void OnCaretBoundsChanged(const TextInputClient* client) override {} void CancelComposition(const TextInputClient* client) override {} void OnInputLocaleChanged() override {}
diff --git a/ui/base/ime/input_method_chromeos.cc b/ui/base/ime/input_method_chromeos.cc index f1ed2f3..695e23ed 100644 --- a/ui/base/ime/input_method_chromeos.cc +++ b/ui/base/ime/input_method_chromeos.cc
@@ -57,7 +57,7 @@ ui::IMEBridge::Get()->SetInputContextHandler(NULL); } -void InputMethodChromeOS::DispatchKeyEvent( +ui::EventDispatchDetails InputMethodChromeOS::DispatchKeyEvent( ui::KeyEvent* event, std::unique_ptr<AckCallback> ack_callback) { DCHECK(event->IsKeyEvent()); @@ -73,35 +73,37 @@ // Note: We need to send the key event to ibus even if the |context_| is not // enabled, so that ibus can have a chance to enable the |context_|. if (!IsNonPasswordInputFieldFocused() || !GetEngine()) { + ui::EventDispatchDetails dispatch_details; if (event->type() == ET_KEY_PRESSED) { if (ExecuteCharacterComposer(*event)) { // Treating as PostIME event if character composer handles key event and // generates some IME event, - ProcessKeyEventPostIME(event, true); + dispatch_details = ProcessKeyEventPostIME(event, true); if (ack_callback) ack_callback->Run(true); - return; + return dispatch_details; } - ProcessUnfilteredKeyPressEvent(event); + dispatch_details = ProcessUnfilteredKeyPressEvent(event); } else { - ignore_result(DispatchKeyEventPostIME(event)); + dispatch_details = DispatchKeyEventPostIME(event); } if (ack_callback) ack_callback->Run(false); - return; + return dispatch_details; } handling_key_event_ = true; if (GetEngine()->IsInterestedInKeyEvent()) { ui::IMEEngineHandlerInterface::KeyEventDoneCallback callback = base::Bind( - &InputMethodChromeOS::ProcessKeyEventDone, + &InputMethodChromeOS::KeyEventDoneCallback, weak_ptr_factory_.GetWeakPtr(), // Pass the ownership of the new copied event. base::Owned(new ui::KeyEvent(*event)), Passed(&ack_callback)); GetEngine()->ProcessKeyEvent(*event, callback); - } else { - ProcessKeyEventDone(event, std::move(ack_callback), false); + return ui::EventDispatchDetails(); } + + return ProcessKeyEventDone(event, std::move(ack_callback), false); } bool InputMethodChromeOS::OnUntranslatedIMEMessage( @@ -110,7 +112,15 @@ return false; } -void InputMethodChromeOS::ProcessKeyEventDone( +void InputMethodChromeOS::KeyEventDoneCallback( + ui::KeyEvent* event, + std::unique_ptr<AckCallback> ack_callback, + bool is_handled) { + ignore_result( + ProcessKeyEventDone(event, std::move(ack_callback), is_handled)); +} + +ui::EventDispatchDetails InputMethodChromeOS::ProcessKeyEventDone( ui::KeyEvent* event, std::unique_ptr<AckCallback> ack_callback, bool is_handled) { @@ -130,14 +140,17 @@ if (ack_callback) ack_callback->Run(is_handled); + ui::EventDispatchDetails details; if (event->type() == ET_KEY_PRESSED || event->type() == ET_KEY_RELEASED) - ProcessKeyEventPostIME(event, is_handled); + details = ProcessKeyEventPostIME(event, is_handled); handling_key_event_ = false; + return details; } -void InputMethodChromeOS::DispatchKeyEvent(ui::KeyEvent* event) { - DispatchKeyEvent(event, nullptr); +ui::EventDispatchDetails InputMethodChromeOS::DispatchKeyEvent( + ui::KeyEvent* event) { + return DispatchKeyEvent(event, nullptr); } void InputMethodChromeOS::OnTextInputTypeChanged( @@ -310,28 +323,32 @@ OnCaretBoundsChanged(GetTextInputClient()); } -void InputMethodChromeOS::ProcessKeyEventPostIME(ui::KeyEvent* event, - bool handled) { +ui::EventDispatchDetails InputMethodChromeOS::ProcessKeyEventPostIME( + ui::KeyEvent* event, + bool handled) { TextInputClient* client = GetTextInputClient(); if (!client) { // As ibus works asynchronously, there is a chance that the focused client // loses focus before this method gets called. - ignore_result(DispatchKeyEventPostIME(event)); - return; + return DispatchKeyEventPostIME(event); } + ui::EventDispatchDetails dispatch_details; if (event->type() == ET_KEY_PRESSED && handled) { - ProcessFilteredKeyPressEvent(event); + dispatch_details = ProcessFilteredKeyPressEvent(event); if (event->stopped_propagation()) { ResetContext(); - return; + return dispatch_details; } + if (dispatch_details.dispatcher_destroyed || + dispatch_details.target_destroyed) + return dispatch_details; } // In case the focus was changed by the key event. The |context_| should have // been reset when the focused window changed. if (client != GetTextInputClient()) - return; + return dispatch_details; if (HasInputMethodResult()) ProcessInputMethodResult(event, handled); @@ -339,40 +356,45 @@ // In case the focus was changed when sending input method results to the // focused window. if (client != GetTextInputClient()) - return; + return dispatch_details; if (handled) - return; // IME handled the key event. do not forward. + return dispatch_details; // IME handled the key event. do not forward. if (event->type() == ET_KEY_PRESSED) - ProcessUnfilteredKeyPressEvent(event); - else if (event->type() == ET_KEY_RELEASED) - ignore_result(DispatchKeyEventPostIME(event)); + return ProcessUnfilteredKeyPressEvent(event); + + if (event->type() == ET_KEY_RELEASED) + return DispatchKeyEventPostIME(event); + + return dispatch_details; } -void InputMethodChromeOS::ProcessFilteredKeyPressEvent(ui::KeyEvent* event) { - if (NeedInsertChar()) { - ignore_result(DispatchKeyEventPostIME(event)); - return; - } +ui::EventDispatchDetails InputMethodChromeOS::ProcessFilteredKeyPressEvent( + ui::KeyEvent* event) { + if (NeedInsertChar()) + return DispatchKeyEventPostIME(event); + ui::KeyEvent fabricated_event(ET_KEY_PRESSED, VKEY_PROCESSKEY, event->code(), event->flags(), event->GetDomKey(), event->time_stamp()); - ignore_result(DispatchKeyEventPostIME(&fabricated_event)); + ui::EventDispatchDetails dispatch_details = + DispatchKeyEventPostIME(&fabricated_event); if (fabricated_event.stopped_propagation()) event->StopPropagation(); + return dispatch_details; } -void InputMethodChromeOS::ProcessUnfilteredKeyPressEvent( +ui::EventDispatchDetails InputMethodChromeOS::ProcessUnfilteredKeyPressEvent( ui::KeyEvent* event) { const TextInputClient* prev_client = GetTextInputClient(); - ignore_result(DispatchKeyEventPostIME(event)); + ui::EventDispatchDetails dispatch_details = DispatchKeyEventPostIME(event); if (event->stopped_propagation()) { ResetContext(); - return; + return dispatch_details; } // We shouldn't dispatch the character anymore if the key event dispatch @@ -384,7 +406,7 @@ // We should return here not to send the Tab key event to RWHV. TextInputClient* client = GetTextInputClient(); if (!client || client != prev_client) - return; + return dispatch_details; // If a key event was not filtered by |context_| and |character_composer_|, // then it means the key event didn't generate any result text. So we need @@ -392,6 +414,7 @@ uint16_t ch = event->GetCharacter(); if (ch) client->InsertChar(*event); + return dispatch_details; } void InputMethodChromeOS::ProcessInputMethodResult(ui::KeyEvent* event,
diff --git a/ui/base/ime/input_method_chromeos.h b/ui/base/ime/input_method_chromeos.h index 180595e5..3dc5a3b 100644 --- a/ui/base/ime/input_method_chromeos.h +++ b/ui/base/ime/input_method_chromeos.h
@@ -29,13 +29,14 @@ ~InputMethodChromeOS() override; using AckCallback = base::Callback<void(bool)>; - void DispatchKeyEvent(ui::KeyEvent* event, - std::unique_ptr<AckCallback> ack_callback); + ui::EventDispatchDetails DispatchKeyEvent( + ui::KeyEvent* event, + std::unique_ptr<AckCallback> ack_callback); // Overridden from InputMethod: bool OnUntranslatedIMEMessage(const base::NativeEvent& event, NativeEventResult* result) override; - void DispatchKeyEvent(ui::KeyEvent* event) override; + ui::EventDispatchDetails DispatchKeyEvent(ui::KeyEvent* event) override; void OnTextInputTypeChanged(const TextInputClient* client) override; void OnCaretBoundsChanged(const TextInputClient* client) override; void CancelComposition(const TextInputClient* client) override; @@ -48,8 +49,9 @@ CompositionText* out_composition) const; // Process a key returned from the input method. - virtual void ProcessKeyEventPostIME(ui::KeyEvent* event, - bool handled); + virtual ui::EventDispatchDetails ProcessKeyEventPostIME(ui::KeyEvent* event, + bool handled) + WARN_UNUSED_RESULT; // Resets context and abandon all pending results and key events. void ResetContext(); @@ -74,10 +76,12 @@ // A VKEY_PROCESSKEY may be dispatched to the EventTargets. // It returns the result of whether the event has been stopped propagation // when dispatching post IME. - void ProcessFilteredKeyPressEvent(ui::KeyEvent* event); + ui::EventDispatchDetails ProcessFilteredKeyPressEvent(ui::KeyEvent* event) + WARN_UNUSED_RESULT; // Processes a key event that was not filtered by the input method. - void ProcessUnfilteredKeyPressEvent(ui::KeyEvent* event); + ui::EventDispatchDetails ProcessUnfilteredKeyPressEvent(ui::KeyEvent* event) + WARN_UNUSED_RESULT; // Sends input method result caused by the given key event to the focused text // input client. @@ -105,9 +109,13 @@ void HidePreeditText(); // Callback function for IMEEngineHandlerInterface::ProcessKeyEvent. - void ProcessKeyEventDone(ui::KeyEvent* event, - std::unique_ptr<AckCallback> ack_callback, - bool is_handled); + void KeyEventDoneCallback(ui::KeyEvent* event, + std::unique_ptr<AckCallback> ack_callback, + bool is_handled); + ui::EventDispatchDetails ProcessKeyEventDone( + ui::KeyEvent* event, + std::unique_ptr<AckCallback> ack_callback, + bool is_handled) WARN_UNUSED_RESULT; // Returns whether an non-password input field is focused. bool IsNonPasswordInputFieldFocused();
diff --git a/ui/base/ime/input_method_chromeos_unittest.cc b/ui/base/ime/input_method_chromeos_unittest.cc index ac6fb7f7..174f26c 100644 --- a/ui/base/ime/input_method_chromeos_unittest.cc +++ b/ui/base/ime/input_method_chromeos_unittest.cc
@@ -77,12 +77,14 @@ }; // Overridden from InputMethodChromeOS: - void ProcessKeyEventPostIME(ui::KeyEvent* key_event, - bool handled) override { - InputMethodChromeOS::ProcessKeyEventPostIME(key_event, handled); + ui::EventDispatchDetails ProcessKeyEventPostIME(ui::KeyEvent* key_event, + bool handled) override { + ui::EventDispatchDetails details = + InputMethodChromeOS::ProcessKeyEventPostIME(key_event, handled); process_key_event_post_ime_args_.event = key_event; process_key_event_post_ime_args_.handled = handled; ++process_key_event_post_ime_call_count_; + return details; } void ResetCallCount() {
diff --git a/ui/base/ime/input_method_mac.h b/ui/base/ime/input_method_mac.h index f56b08f..25d3718 100644 --- a/ui/base/ime/input_method_mac.h +++ b/ui/base/ime/input_method_mac.h
@@ -22,7 +22,7 @@ // Overriden from InputMethod. bool OnUntranslatedIMEMessage(const base::NativeEvent& event, NativeEventResult* result) override; - void DispatchKeyEvent(ui::KeyEvent* event) override; + ui::EventDispatchDetails DispatchKeyEvent(ui::KeyEvent* event) override; void OnCaretBoundsChanged(const TextInputClient* client) override; void CancelComposition(const TextInputClient* client) override; bool IsCandidatePopupOpen() const override;
diff --git a/ui/base/ime/input_method_mac.mm b/ui/base/ime/input_method_mac.mm index e53f067..d048773 100644 --- a/ui/base/ime/input_method_mac.mm +++ b/ui/base/ime/input_method_mac.mm
@@ -20,9 +20,9 @@ return false; } -void InputMethodMac::DispatchKeyEvent(ui::KeyEvent* event) { +ui::EventDispatchDetails InputMethodMac::DispatchKeyEvent(ui::KeyEvent* event) { // This is used on Mac only to dispatch events post-IME. - ignore_result(DispatchKeyEventPostIME(event)); + return DispatchKeyEventPostIME(event); } void InputMethodMac::OnCaretBoundsChanged(const TextInputClient* client) {
diff --git a/ui/base/ime/input_method_minimal.cc b/ui/base/ime/input_method_minimal.cc index 506da84..d040d9f 100644 --- a/ui/base/ime/input_method_minimal.cc +++ b/ui/base/ime/input_method_minimal.cc
@@ -25,24 +25,25 @@ return false; } -void InputMethodMinimal::DispatchKeyEvent(ui::KeyEvent* event) { +ui::EventDispatchDetails InputMethodMinimal::DispatchKeyEvent( + ui::KeyEvent* event) { DCHECK(event->type() == ET_KEY_PRESSED || event->type() == ET_KEY_RELEASED); // If no text input client, do nothing. - if (!GetTextInputClient()) { - ignore_result(DispatchKeyEventPostIME(event)); - return; - } + if (!GetTextInputClient()) + return DispatchKeyEventPostIME(event); // Insert the character. - ignore_result(DispatchKeyEventPostIME(event)); - if (event->type() == ET_KEY_PRESSED && GetTextInputClient()) { + ui::EventDispatchDetails dispatch_details = DispatchKeyEventPostIME(event); + if (!dispatch_details.dispatcher_destroyed && + event->type() == ET_KEY_PRESSED && GetTextInputClient()) { const uint16_t ch = event->GetCharacter(); if (ch) { GetTextInputClient()->InsertChar(*event); event->StopPropagation(); } } + return dispatch_details; } void InputMethodMinimal::OnCaretBoundsChanged(const TextInputClient* client) {}
diff --git a/ui/base/ime/input_method_minimal.h b/ui/base/ime/input_method_minimal.h index 8cd9b75f..96359226 100644 --- a/ui/base/ime/input_method_minimal.h +++ b/ui/base/ime/input_method_minimal.h
@@ -20,7 +20,7 @@ // Overriden from InputMethod. bool OnUntranslatedIMEMessage(const base::NativeEvent& event, NativeEventResult* result) override; - void DispatchKeyEvent(ui::KeyEvent* event) override; + ui::EventDispatchDetails DispatchKeyEvent(ui::KeyEvent* event) override; void OnCaretBoundsChanged(const TextInputClient* client) override; void CancelComposition(const TextInputClient* client) override; bool IsCandidatePopupOpen() const override;
diff --git a/ui/base/ime/input_method_win.cc b/ui/base/ime/input_method_win.cc index e2bb5286..dae6ca0b 100644 --- a/ui/base/ime/input_method_win.cc +++ b/ui/base/ime/input_method_win.cc
@@ -107,11 +107,9 @@ return !!handled; } -void InputMethodWin::DispatchKeyEvent(ui::KeyEvent* event) { - if (!event->HasNativeEvent()) { - DispatchFabricatedKeyEvent(event); - return; - } +ui::EventDispatchDetails InputMethodWin::DispatchKeyEvent(ui::KeyEvent* event) { + if (!event->HasNativeEvent()) + return DispatchFabricatedKeyEvent(event); const base::NativeEvent& native_key_event = event->native_event(); BOOL handled = FALSE; @@ -121,7 +119,7 @@ &handled); if (handled) event->StopPropagation(); - return; + return ui::EventDispatchDetails(); } std::vector<MSG> char_msgs; @@ -192,27 +190,34 @@ base::Owned(new ui::KeyEvent(*event)), base::Owned(new std::vector<MSG>(char_msgs))); GetEngine()->ProcessKeyEvent(*event, callback); - } else { - ProcessKeyEventDone(event, &char_msgs, false); + return ui::EventDispatchDetails(); } + + return ProcessUnhandledKeyEvent(event, &char_msgs); } void InputMethodWin::ProcessKeyEventDone(ui::KeyEvent* event, const std::vector<MSG>* char_msgs, bool is_handled) { - DCHECK(event); if (is_handled) return; + ProcessUnhandledKeyEvent(event, char_msgs); +} +ui::EventDispatchDetails InputMethodWin::ProcessUnhandledKeyEvent( + ui::KeyEvent* event, + const std::vector<MSG>* char_msgs) { + DCHECK(event); ui::EventDispatchDetails details = DispatchKeyEventPostIME(event); if (details.dispatcher_destroyed || details.target_destroyed || event->stopped_propagation()) { - return; + return details; } BOOL handled; for (const auto& msg : (*char_msgs)) OnChar(msg.hwnd, msg.message, msg.wParam, msg.lParam, msg, &handled); + return details; } void InputMethodWin::OnTextInputTypeChanged(const TextInputClient* client) { @@ -686,17 +691,19 @@ GetActiveWindow() == toplevel_window_handle_; } -void InputMethodWin::DispatchFabricatedKeyEvent(ui::KeyEvent* event) { +ui::EventDispatchDetails InputMethodWin::DispatchFabricatedKeyEvent( + ui::KeyEvent* event) { // The key event if from calling input.ime.sendKeyEvent or test. ui::EventDispatchDetails details = DispatchKeyEventPostIME(event); if (details.dispatcher_destroyed || details.target_destroyed || event->stopped_propagation()) { - return; + return details; } if ((event->is_char() || event->GetDomKey().IsCharacter()) && event->type() == ui::ET_KEY_PRESSED && GetTextInputClient()) GetTextInputClient()->InsertChar(*event); + return details; } void InputMethodWin::ConfirmCompositionText() {
diff --git a/ui/base/ime/input_method_win.h b/ui/base/ime/input_method_win.h index 1eab715f..c41504e2 100644 --- a/ui/base/ime/input_method_win.h +++ b/ui/base/ime/input_method_win.h
@@ -29,7 +29,7 @@ // Overridden from InputMethod: bool OnUntranslatedIMEMessage(const base::NativeEvent& event, NativeEventResult* result) override; - void DispatchKeyEvent(ui::KeyEvent* event) override; + ui::EventDispatchDetails DispatchKeyEvent(ui::KeyEvent* event) override; void OnTextInputTypeChanged(const TextInputClient* client) override; void OnCaretBoundsChanged(const TextInputClient* client) override; void CancelComposition(const TextInputClient* client) override; @@ -97,7 +97,7 @@ // to be ready for receiving keyboard input. bool IsWindowFocused(const TextInputClient* client) const; - void DispatchFabricatedKeyEvent(ui::KeyEvent* event); + ui::EventDispatchDetails DispatchFabricatedKeyEvent(ui::KeyEvent* event); // Asks the client to confirm current composition text. void ConfirmCompositionText(); @@ -110,6 +110,10 @@ const std::vector<MSG>* char_msgs, bool is_handled); + ui::EventDispatchDetails ProcessUnhandledKeyEvent( + ui::KeyEvent* event, + const std::vector<MSG>* char_msgs); + // Windows IMM32 wrapper. // (See "ui/base/ime/win/ime_input.h" for its details.) ui::IMM32Manager imm32_manager_;
diff --git a/ui/base/ime/mock_input_method.cc b/ui/base/ime/mock_input_method.cc index d097005b..f0291cf2 100644 --- a/ui/base/ime/mock_input_method.cc +++ b/ui/base/ime/mock_input_method.cc
@@ -40,8 +40,9 @@ return text_input_client_; } -void MockInputMethod::DispatchKeyEvent(ui::KeyEvent* event) { - ignore_result(delegate_->DispatchKeyEventPostIME(event)); +ui::EventDispatchDetails MockInputMethod::DispatchKeyEvent( + ui::KeyEvent* event) { + return delegate_->DispatchKeyEventPostIME(event); } void MockInputMethod::OnFocus() {
diff --git a/ui/base/ime/mock_input_method.h b/ui/base/ime/mock_input_method.h index 4066924..f703e4a0 100644 --- a/ui/base/ime/mock_input_method.h +++ b/ui/base/ime/mock_input_method.h
@@ -38,7 +38,7 @@ void SetFocusedTextInputClient(TextInputClient* client) override; void DetachTextInputClient(TextInputClient* client) override; TextInputClient* GetTextInputClient() const override; - void DispatchKeyEvent(ui::KeyEvent* event) override; + ui::EventDispatchDetails DispatchKeyEvent(ui::KeyEvent* event) override; void OnTextInputTypeChanged(const TextInputClient* client) override; void OnCaretBoundsChanged(const TextInputClient* client) override; void CancelComposition(const TextInputClient* client) override;
diff --git a/ui/events/test/event_generator.h b/ui/events/test/event_generator.h index 1ce4542..2b224647 100644 --- a/ui/events/test/event_generator.h +++ b/ui/events/test/event_generator.h
@@ -13,6 +13,7 @@ #include "base/macros.h" #include "base/time/time.h" #include "ui/events/event.h" +#include "ui/events/event_dispatcher.h" #include "ui/events/keycodes/keyboard_codes.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/native_widget_types.h" @@ -72,8 +73,9 @@ // Determines if the input method should be the first to handle key events // before dispatching to Views. If it does, the given |event| will be // dispatched and processed by the input method from the host of |target|. - virtual void DispatchKeyEventToIME(EventTarget* target, - ui::KeyEvent* event) = 0; + virtual ui::EventDispatchDetails DispatchKeyEventToIME(EventTarget* target, + ui::KeyEvent* event) + WARN_UNUSED_RESULT = 0; // Offers the event to pointer watchers on systems that provide them. // Does not consume the event (pointer watchers cannot consume events).
diff --git a/ui/gfx/animation/tween.cc b/ui/gfx/animation/tween.cc index e608ee5..f9498d9 100644 --- a/ui/gfx/animation/tween.cc +++ b/ui/gfx/animation/tween.cc
@@ -61,6 +61,9 @@ case LINEAR_OUT_SLOW_IN: return gfx::CubicBezier(0, 0, .2, 1).Solve(state); + case SLOW_OUT_LINEAR_IN: + return gfx::CubicBezier(0, 0, 1, .2).Solve(state); + case FAST_OUT_LINEAR_IN: return gfx::CubicBezier(0.4, 0, 1, 1).Solve(state);
diff --git a/ui/gfx/animation/tween.h b/ui/gfx/animation/tween.h index dbc506e03..c2f76167 100644 --- a/ui/gfx/animation/tween.h +++ b/ui/gfx/animation/tween.h
@@ -20,22 +20,24 @@ class ANIMATION_EXPORT Tween { public: enum Type { - LINEAR, // Linear. - EASE_OUT, // Fast in, slow out (default). - EASE_IN, // Slow in, fast out. - EASE_IN_2, // Variant of EASE_IN that starts out slower than - // EASE_IN. - EASE_IN_OUT, // Slow in and out, fast in the middle. - FAST_IN_OUT, // Fast in and out, slow in the middle. - EASE_OUT_SNAP, // Fast in, slow out, snap to final value. - SMOOTH_IN_OUT, // Smooth, consistent speeds in and out (sine wave). - FAST_OUT_SLOW_IN, // Variant of EASE_IN_OUT which should be used in most - // cases. - LINEAR_OUT_SLOW_IN, // Variant of EASE_OUT which should be used for - // fading in from 0% or motion when entering a scene. - FAST_OUT_LINEAR_IN, // Variant of EASE_IN which should should be used for - // fading out to 0% or motion when exiting a scene. - ZERO, // Returns a value of 0 always. + LINEAR, // Linear. + EASE_OUT, // Fast in, slow out (default). + EASE_IN, // Slow in, fast out. + EASE_IN_2, // Variant of EASE_IN that starts out slower than + // EASE_IN. + EASE_IN_OUT, // Slow in and out, fast in the middle. + FAST_IN_OUT, // Fast in and out, slow in the middle. + EASE_OUT_SNAP, // Fast in, slow out, snap to final value. + SMOOTH_IN_OUT, // Smooth, consistent speeds in and out (sine wave). + FAST_OUT_SLOW_IN, // Variant of EASE_IN_OUT which should be used in most + // cases. + LINEAR_OUT_SLOW_IN, // Variant of EASE_OUT which should be used for + // fading in from 0% or motion when entering a scene. + SLOW_OUT_LINEAR_IN, // Reverse of LINEAR_OUT_SLOW_IN which should be used + // in reverse animation to create a rubberband effect. + FAST_OUT_LINEAR_IN, // Variant of EASE_IN which should should be used for + // fading out to 0% or motion when exiting a scene. + ZERO, // Returns a value of 0 always. }; // Returns the value based on the tween type. |state| is from 0-1.
diff --git a/ui/views/cocoa/bridged_content_view.mm b/ui/views/cocoa/bridged_content_view.mm index 39610ba6..46e34d8 100644 --- a/ui/views/cocoa/bridged_content_view.mm +++ b/ui/views/cocoa/bridged_content_view.mm
@@ -445,7 +445,8 @@ if (DispatchEventToMenu([self activeMenuController], event)) return; - hostedView_->GetWidget()->GetInputMethod()->DispatchKeyEvent(event); + ignore_result( + hostedView_->GetWidget()->GetInputMethod()->DispatchKeyEvent(event)); } - (BOOL)handleUnhandledKeyDownAsKeyEvent { @@ -476,7 +477,8 @@ if (textInputClient_ && textInputClient_->IsTextEditCommandEnabled(command)) textInputClient_->SetTextEditCommandForNextKeyEvent(command); - hostedView_->GetWidget()->GetInputMethod()->DispatchKeyEvent(&event); + ignore_result( + hostedView_->GetWidget()->GetInputMethod()->DispatchKeyEvent(&event)); } - (void)onFullKeyboardAccessModeChanged:(NSNotification*)notification {
diff --git a/ui/views/controls/textfield/textfield_unittest.cc b/ui/views/controls/textfield/textfield_unittest.cc index b1639dd..9d44b48 100644 --- a/ui/views/controls/textfield/textfield_unittest.cc +++ b/ui/views/controls/textfield/textfield_unittest.cc
@@ -85,7 +85,7 @@ // Overridden from InputMethod: bool OnUntranslatedIMEMessage(const base::NativeEvent& event, NativeEventResult* result) override; - void DispatchKeyEvent(ui::KeyEvent* key) override; + ui::EventDispatchDetails DispatchKeyEvent(ui::KeyEvent* key) override; void OnTextInputTypeChanged(const ui::TextInputClient* client) override; void OnCaretBoundsChanged(const ui::TextInputClient* client) override {} void CancelComposition(const ui::TextInputClient* client) override; @@ -151,15 +151,13 @@ return false; } -void MockInputMethod::DispatchKeyEvent(ui::KeyEvent* key) { +ui::EventDispatchDetails MockInputMethod::DispatchKeyEvent(ui::KeyEvent* key) { // On Mac, emulate InputMethodMac behavior for character events. Composition // still needs to be mocked, since it's not possible to generate test events // which trigger the appropriate NSResponder action messages for composition. #if defined(OS_MACOSX) - if (key->is_char()) { - ignore_result(DispatchKeyEventPostIME(key)); - return; - } + if (key->is_char()) + return DispatchKeyEventPostIME(key); #endif // Checks whether the key event is from EventGenerator on Windows which will @@ -167,9 +165,11 @@ // The MockInputMethod will insert char on WM_KEYDOWN so ignore WM_CHAR here. if (key->is_char() && key->HasNativeEvent()) { key->SetHandled(); - return; + return ui::EventDispatchDetails(); } + ui::EventDispatchDetails dispatch_details; + bool handled = !IsTextInputTypeNone() && HasComposition(); ClearStates(); if (handled) { @@ -177,11 +177,14 @@ ui::KeyEvent mock_key(ui::ET_KEY_PRESSED, ui::VKEY_PROCESSKEY, key->flags()); - DispatchKeyEventPostIME(&mock_key); + dispatch_details = DispatchKeyEventPostIME(&mock_key); } else { - DispatchKeyEventPostIME(key); + dispatch_details = DispatchKeyEventPostIME(key); } + if (dispatch_details.dispatcher_destroyed) + return dispatch_details; + ui::TextInputClient* client = GetTextInputClient(); if (client) { if (handled) { @@ -199,6 +202,8 @@ } ClearComposition(); + + return dispatch_details; } void MockInputMethod::OnTextInputTypeChanged(
diff --git a/ui/views/test/event_generator_delegate_mac.mm b/ui/views/test/event_generator_delegate_mac.mm index b5493ef..3203a23d 100644 --- a/ui/views/test/event_generator_delegate_mac.mm +++ b/ui/views/test/event_generator_delegate_mac.mm
@@ -309,11 +309,12 @@ gfx::Point* point) const override {} void ConvertPointFromHost(const ui::EventTarget* hosted_target, gfx::Point* point) const override {} - void DispatchKeyEventToIME(EventTarget* target, - ui::KeyEvent* event) override { + ui::EventDispatchDetails DispatchKeyEventToIME(EventTarget* target, + ui::KeyEvent* event) override { // InputMethodMac does not send native events nor do the necessary // translation. Key events must be handled natively by an NSResponder which // translates keyboard events into editing commands. + return ui::EventDispatchDetails(); } private: