diff --git a/DEPS b/DEPS index 5d1e8d2..9dbb441 100644 --- a/DEPS +++ b/DEPS
@@ -181,11 +181,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': '4cf1874981c345533de5aee0baaf06484d0dc09d', + 'skia_revision': 'c4b8eefe5653d7851e5328e1a500277ffabfecaf', # 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': 'cd34145326def51cb6dcf87aed7d0caf9f62bb4f', + 'v8_revision': '849589ecc0d727c36c90abb07cf2338f583834a7', # 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. @@ -197,11 +197,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '5349f3c9d90450e0b1c7aba89072975db5dd9662', + 'swiftshader_revision': '5fc197dc76693d0049d1f400a077f13fa1f6078b', # 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': 'de6595c714420b8d355c07649e70b6212c7e141e', + 'pdfium_revision': 'c86e356c31a90805c4e4c54e894b0097c111f09e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -216,7 +216,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling googletest # and whatever else without interference from each other. - 'googletest_revision': '5395345ca4f0c596110188688ed990e0de5a181c', + 'googletest_revision': '306f3754a71d6d1ac644681d3544d06744914228', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling lighttpd # and whatever else without interference from each other. @@ -244,7 +244,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': 'f7d73bb520283d2a06b8fde8a1b02aa33414fcd0', + 'catapult_revision': 'e5b0598dee84652234849ea3338023e6abecc9f3', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -252,7 +252,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '772588160e90f0dc34499d099d19294a22aee26c', + 'devtools_frontend_revision': '0cfd3dc2afae04c62040ed98c7c2760674704bae', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -312,7 +312,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '0ecc48ecb7a1353b9e1a3cd9d3a125f6a770477c', + 'dawn_revision': '631f4258a1ace016d6a10ebf7ff127ea46be8575', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -904,7 +904,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '2a04803267c61a53e9769bb2963b45e06a981804', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'e9730d75a00548a22e4392567243969d85c02dd4', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1297,7 +1297,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '47bc3d60ef2d608eb8a48c13ca1b6c6e135f7462', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '1039ef14d7ad6e9b17868c3817efea59103b3322', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1498,7 +1498,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '4f3976e9b368ccfe7b9dd02014351936296dc72c', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'ccab06fb72be1fd8b165d865aefad9daeff8631f', + Var('webrtc_git') + '/src.git' + '@' + '6ca908f48c88fda174516ec8edc5041f61a432b2', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1568,7 +1568,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@c885431d04dbde7c53fb854c3aba57361113950a', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@d5722304fcfcc8dda92a65a467b91273eb470652', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/browser/aw_contents_lifecycle_notifier.cc b/android_webview/browser/aw_contents_lifecycle_notifier.cc index c1fa1c0..5ace712 100644 --- a/android_webview/browser/aw_contents_lifecycle_notifier.cc +++ b/android_webview/browser/aw_contents_lifecycle_notifier.cc
@@ -5,19 +5,37 @@ #include "android_webview/browser/aw_contents_lifecycle_notifier.h" #include "android_webview/browser_jni_headers/AwContentsLifecycleNotifier_jni.h" +#include "content/public/browser/browser_thread.h" using base::android::AttachCurrentThread; +using content::BrowserThread; namespace android_webview { // static void AwContentsLifecycleNotifier::OnWebViewCreated() { - Java_AwContentsLifecycleNotifier_onWebViewCreated(AttachCurrentThread()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (getInstance().mNumWebViews++ == 0) { + Java_AwContentsLifecycleNotifier_onFirstWebViewCreated( + AttachCurrentThread()); + } } // static void AwContentsLifecycleNotifier::OnWebViewDestroyed() { - Java_AwContentsLifecycleNotifier_onWebViewDestroyed(AttachCurrentThread()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (--getInstance().mNumWebViews == 0) { + Java_AwContentsLifecycleNotifier_onLastWebViewDestroyed( + AttachCurrentThread()); + } } +// static +AwContentsLifecycleNotifier& AwContentsLifecycleNotifier::getInstance() { + static base::NoDestructor<AwContentsLifecycleNotifier> instance; + return *instance; +} + +AwContentsLifecycleNotifier::AwContentsLifecycleNotifier() = default; + } // namespace android_webview
diff --git a/android_webview/browser/aw_contents_lifecycle_notifier.h b/android_webview/browser/aw_contents_lifecycle_notifier.h index a2570d2..8c82499 100644 --- a/android_webview/browser/aw_contents_lifecycle_notifier.h +++ b/android_webview/browser/aw_contents_lifecycle_notifier.h
@@ -7,6 +7,7 @@ #include "base/android/jni_android.h" #include "base/macros.h" +#include "base/no_destructor.h" namespace android_webview { @@ -16,7 +17,16 @@ static void OnWebViewDestroyed(); private: - DISALLOW_IMPLICIT_CONSTRUCTORS(AwContentsLifecycleNotifier); + friend base::NoDestructor<AwContentsLifecycleNotifier>; + + static AwContentsLifecycleNotifier& getInstance(); + + AwContentsLifecycleNotifier(); + ~AwContentsLifecycleNotifier() = delete; + + int mNumWebViews = 0; + + DISALLOW_COPY_AND_ASSIGN(AwContentsLifecycleNotifier); }; } // namespace android_webview
diff --git a/android_webview/browser/gfx/BUILD.gn b/android_webview/browser/gfx/BUILD.gn index c54fb61..396f4a9 100644 --- a/android_webview/browser/gfx/BUILD.gn +++ b/android_webview/browser/gfx/BUILD.gn
@@ -7,6 +7,8 @@ source_set("gfx") { sources = [ + "aw_attaching_to_window_recorder.cc", + "aw_attaching_to_window_recorder.h", "aw_draw_fn_impl.cc", "aw_draw_fn_impl.h", "aw_gl_functor.cc",
diff --git a/android_webview/browser/gfx/aw_attaching_to_window_recorder.cc b/android_webview/browser/gfx/aw_attaching_to_window_recorder.cc new file mode 100644 index 0000000..66894b0 --- /dev/null +++ b/android_webview/browser/gfx/aw_attaching_to_window_recorder.cc
@@ -0,0 +1,101 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "android_webview/browser/gfx/aw_attaching_to_window_recorder.h" + +#include "base/bind.h" +#include "base/metrics/histogram_macros.h" +#include "base/sequenced_task_runner.h" +#include "base/task/post_task.h" + +namespace android_webview { + +namespace { + +constexpr base::TimeDelta kPingInterval[] = { + base::TimeDelta::FromSeconds(5), + base::TimeDelta::FromSeconds(30) - base::TimeDelta::FromSeconds(5), + base::TimeDelta::FromMinutes(3) - base::TimeDelta::FromSeconds(30)}; + +constexpr size_t kInterval5s = 0; +constexpr size_t kInterval30s = 1; +constexpr size_t kInterval3m = 2; + +} // namespace + +AwAttachingToWindowRecorder::AwAttachingToWindowRecorder() + : created_time_(base::TimeTicks::Now()), + thread_pool_runner_(base::CreateSequencedTaskRunner( + {base::ThreadPool(), base::TaskPriority::BEST_EFFORT, + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})) { + DETACH_FROM_SEQUENCE(thread_pool_sequence_checker_); +} + +AwAttachingToWindowRecorder::~AwAttachingToWindowRecorder() = default; + +void AwAttachingToWindowRecorder::Start() { + // Can't post the task in constructor, because at least one reference of this + // object is needed. + bool result = thread_pool_runner_->PostNonNestableDelayedTask( + FROM_HERE, + base::BindOnce(&AwAttachingToWindowRecorder::Ping, this, kInterval5s), + kPingInterval[kInterval5s]); + DCHECK(result); +} + +void AwAttachingToWindowRecorder::OnAttachedToWindow() { + thread_pool_runner_->PostNonNestableTask( + FROM_HERE, + base::BindOnce(&AwAttachingToWindowRecorder::RecordAttachedToWindow, this, + base::TimeTicks::Now() - created_time_)); +} + +void AwAttachingToWindowRecorder::OnDestroyed() { + thread_pool_runner_->PostNonNestableTask( + FROM_HERE, + base::BindOnce(&AwAttachingToWindowRecorder::RecordEverAttachedToWindow, + this)); +} + +void AwAttachingToWindowRecorder::RecordAttachedToWindow(base::TimeDelta time) { + DCHECK_CALLED_ON_VALID_SEQUENCE(thread_pool_sequence_checker_); + if (was_attached_) + return; + was_attached_ = true; + UMA_HISTOGRAM_MEDIUM_TIMES("Android.WebView.AttachedToWindowTime", time); +} + +void AwAttachingToWindowRecorder::RecordEverAttachedToWindow() { + DCHECK_CALLED_ON_VALID_SEQUENCE(thread_pool_sequence_checker_); + UMA_HISTOGRAM_BOOLEAN("Android.WebView.EverAttachedToWindow", was_attached_); +} + +void AwAttachingToWindowRecorder::Ping(size_t interval_index) { + DCHECK_CALLED_ON_VALID_SEQUENCE(thread_pool_sequence_checker_); + switch (interval_index) { + case kInterval5s: + UMA_HISTOGRAM_BOOLEAN("Android.WebView.AttachedToWindowIn5s", + was_attached_); + break; + case kInterval30s: + UMA_HISTOGRAM_BOOLEAN("Android.WebView.AttachedToWindowIn30s", + was_attached_); + break; + case kInterval3m: + UMA_HISTOGRAM_BOOLEAN("Android.WebView.AttachedToWindowIn3m", + was_attached_); + break; + } + + if (++interval_index == base::size(kPingInterval)) + return; + + bool result = thread_pool_runner_->PostNonNestableDelayedTask( + FROM_HERE, + base::BindOnce(&AwAttachingToWindowRecorder::Ping, this, interval_index), + kPingInterval[interval_index]); + DCHECK(result); +} + +} // namespace android_webview
diff --git a/android_webview/browser/gfx/aw_attaching_to_window_recorder.h b/android_webview/browser/gfx/aw_attaching_to_window_recorder.h new file mode 100644 index 0000000..672493a --- /dev/null +++ b/android_webview/browser/gfx/aw_attaching_to_window_recorder.h
@@ -0,0 +1,49 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ANDROID_WEBVIEW_BROWSER_GFX_AW_ATTACHING_TO_WINDOW_RECORDER_H_ +#define ANDROID_WEBVIEW_BROWSER_GFX_AW_ATTACHING_TO_WINDOW_RECORDER_H_ + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/sequence_checker.h" +#include "base/time/time.h" + +namespace base { +class SequencedTaskRunner; +} // namespace base + +namespace android_webview { + +class AwAttachingToWindowRecorder + : public base::RefCountedThreadSafe<AwAttachingToWindowRecorder> { + public: + AwAttachingToWindowRecorder(); + + // Start recording. + void Start(); + void OnAttachedToWindow(); + void OnDestroyed(); + + private: + friend class base::RefCountedThreadSafe<AwAttachingToWindowRecorder>; + + ~AwAttachingToWindowRecorder(); + + void RecordAttachedToWindow(base::TimeDelta time); + void RecordEverAttachedToWindow(); + void Ping(size_t interval_index); + + base::TimeTicks created_time_; + bool was_attached_ = false; + scoped_refptr<base::SequencedTaskRunner> thread_pool_runner_; + + SEQUENCE_CHECKER(thread_pool_sequence_checker_); + + DISALLOW_COPY_AND_ASSIGN(AwAttachingToWindowRecorder); +}; + +} // namespace android_webview + +#endif // ANDROID_WEBVIEW_BROWSER_GFX_AW_ATTACHING_TO_WINDOW_RECORDER_H_
diff --git a/android_webview/browser/gfx/aw_attaching_to_window_recorder_unittest.cc b/android_webview/browser/gfx/aw_attaching_to_window_recorder_unittest.cc new file mode 100644 index 0000000..495d914 --- /dev/null +++ b/android_webview/browser/gfx/aw_attaching_to_window_recorder_unittest.cc
@@ -0,0 +1,144 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "android_webview/browser/gfx/aw_attaching_to_window_recorder.h" + +#include "base/test/metrics/histogram_tester.h" +#include "base/test/task_environment.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace android_webview { +namespace { + +struct { + const base::TimeDelta interval; + const char* histogram_name; +} kPingInterval[] = { + {base::TimeDelta::FromSeconds(5), "Android.WebView.AttachedToWindowIn5s"}, + {base::TimeDelta::FromSeconds(30) - base::TimeDelta::FromSeconds(5), + "Android.WebView.AttachedToWindowIn30s"}, + {base::TimeDelta::FromMinutes(3) - base::TimeDelta::FromSeconds(30), + "Android.WebView.AttachedToWindowIn3m"}}; + +const char* kEverAttachedToWindow = "Android.WebView.EverAttachedToWindow"; +const char* kAttachedToWindowTime = "Android.WebView.AttachedToWindowTime"; + +} // namespace + +class AwAttachingToWindowRecorderTest : public testing::Test { + public: + void SetUp() override { + recorder_ = base::MakeRefCounted<AwAttachingToWindowRecorder>(); + recorder_->Start(); + } + + AwAttachingToWindowRecorder* recorder() { return recorder_.get(); } + base::test::TaskEnvironment& task_environment() { return task_environment_; } + + protected: + base::test::TaskEnvironment task_environment_{ + base::test::TaskEnvironment::TimeSource::MOCK_TIME}; + + private: + scoped_refptr<AwAttachingToWindowRecorder> recorder_; +}; + +TEST_F(AwAttachingToWindowRecorderTest, NeverAttached) { + base::HistogramTester tester; + task_environment().FastForwardBy(kPingInterval[0].interval); + tester.ExpectBucketCount(kPingInterval[0].histogram_name, false, 1); + + task_environment().FastForwardBy(kPingInterval[1].interval); + tester.ExpectBucketCount(kPingInterval[0].histogram_name, false, 1); + tester.ExpectBucketCount(kPingInterval[1].histogram_name, false, 1); + + task_environment().FastForwardBy(kPingInterval[2].interval); + tester.ExpectBucketCount(kPingInterval[0].histogram_name, false, 1); + tester.ExpectBucketCount(kPingInterval[1].histogram_name, false, 1); + tester.ExpectBucketCount(kPingInterval[2].histogram_name, false, 1); + + recorder()->OnDestroyed(); + task_environment().RunUntilIdle(); + tester.ExpectBucketCount(kPingInterval[0].histogram_name, false, 1); + tester.ExpectBucketCount(kPingInterval[1].histogram_name, false, 1); + tester.ExpectBucketCount(kPingInterval[2].histogram_name, false, 1); + tester.ExpectBucketCount(kEverAttachedToWindow, false, 1); +} + +TEST_F(AwAttachingToWindowRecorderTest, AttachedIn5s) { + base::HistogramTester tester; + recorder()->OnAttachedToWindow(); + task_environment().RunUntilIdle(); + tester.ExpectTotalCount(kAttachedToWindowTime, 1u); + task_environment().FastForwardBy(kPingInterval[0].interval); + tester.ExpectBucketCount(kPingInterval[0].histogram_name, true, 1); + + task_environment().FastForwardBy(kPingInterval[1].interval); + tester.ExpectBucketCount(kPingInterval[0].histogram_name, true, 1); + tester.ExpectBucketCount(kPingInterval[1].histogram_name, true, 1); + + task_environment().FastForwardBy(kPingInterval[2].interval); + tester.ExpectBucketCount(kPingInterval[0].histogram_name, true, 1); + tester.ExpectBucketCount(kPingInterval[1].histogram_name, true, 1); + tester.ExpectBucketCount(kPingInterval[2].histogram_name, true, 1); + + recorder()->OnDestroyed(); + task_environment().RunUntilIdle(); + tester.ExpectBucketCount(kPingInterval[0].histogram_name, true, 1); + tester.ExpectBucketCount(kPingInterval[1].histogram_name, true, 1); + tester.ExpectBucketCount(kPingInterval[2].histogram_name, true, 1); + tester.ExpectBucketCount(kEverAttachedToWindow, true, 1); +} + +TEST_F(AwAttachingToWindowRecorderTest, AttachedIn30s) { + base::HistogramTester tester; + task_environment().FastForwardBy(kPingInterval[0].interval); + tester.ExpectBucketCount(kPingInterval[0].histogram_name, false, 1); + + recorder()->OnAttachedToWindow(); + task_environment().RunUntilIdle(); + tester.ExpectTotalCount(kAttachedToWindowTime, 1u); + task_environment().FastForwardBy(kPingInterval[1].interval); + tester.ExpectBucketCount(kPingInterval[0].histogram_name, false, 1); + tester.ExpectBucketCount(kPingInterval[1].histogram_name, true, 1); + + task_environment().FastForwardBy(kPingInterval[2].interval); + tester.ExpectBucketCount(kPingInterval[0].histogram_name, false, 1); + tester.ExpectBucketCount(kPingInterval[1].histogram_name, true, 1); + tester.ExpectBucketCount(kPingInterval[2].histogram_name, true, 1); + + recorder()->OnDestroyed(); + task_environment().RunUntilIdle(); + tester.ExpectBucketCount(kPingInterval[0].histogram_name, false, 1); + tester.ExpectBucketCount(kPingInterval[1].histogram_name, true, 1); + tester.ExpectBucketCount(kPingInterval[2].histogram_name, true, 1); + tester.ExpectBucketCount(kEverAttachedToWindow, true, 1); +} + +TEST_F(AwAttachingToWindowRecorderTest, AttachedIn3m) { + base::HistogramTester tester; + task_environment().FastForwardBy(kPingInterval[0].interval); + tester.ExpectBucketCount(kPingInterval[0].histogram_name, false, 1); + + task_environment().FastForwardBy(kPingInterval[1].interval); + tester.ExpectBucketCount(kPingInterval[0].histogram_name, false, 1); + tester.ExpectBucketCount(kPingInterval[1].histogram_name, false, 1); + + recorder()->OnAttachedToWindow(); + task_environment().RunUntilIdle(); + tester.ExpectTotalCount(kAttachedToWindowTime, 1u); + task_environment().FastForwardBy(kPingInterval[2].interval); + tester.ExpectBucketCount(kPingInterval[0].histogram_name, false, 1); + tester.ExpectBucketCount(kPingInterval[1].histogram_name, false, 1); + tester.ExpectBucketCount(kPingInterval[2].histogram_name, true, 1); + + recorder()->OnDestroyed(); + task_environment().RunUntilIdle(); + tester.ExpectBucketCount(kPingInterval[0].histogram_name, false, 1); + tester.ExpectBucketCount(kPingInterval[1].histogram_name, false, 1); + tester.ExpectBucketCount(kPingInterval[2].histogram_name, true, 1); + tester.ExpectBucketCount(kEverAttachedToWindow, true, 1); +} + +} // namespace android_webview
diff --git a/android_webview/browser/gfx/browser_view_renderer.cc b/android_webview/browser/gfx/browser_view_renderer.cc index 49ba32d..f4e2003 100644 --- a/android_webview/browser/gfx/browser_view_renderer.cc +++ b/android_webview/browser/gfx/browser_view_renderer.cc
@@ -7,6 +7,7 @@ #include <memory> #include <utility> +#include "android_webview/browser/gfx/aw_attaching_to_window_recorder.h" #include "android_webview/browser/gfx/browser_view_renderer_client.h" #include "android_webview/browser/gfx/compositor_frame_consumer.h" #include "android_webview/browser/gfx/root_frame_sink.h" @@ -113,7 +114,8 @@ max_page_scale_factor_(0.f), on_new_picture_enable_(false), clear_view_(false), - offscreen_pre_raster_(false) { + offscreen_pre_raster_(false), + recorder_(base::MakeRefCounted<AwAttachingToWindowRecorder>()) { if (::features::IsUsingVizForWebView()) { root_frame_sink_proxy_ = std::make_unique<RootFrameSinkProxy>(ui_task_runner_, this); @@ -121,9 +123,11 @@ begin_frame_source_ = std::make_unique<BeginFrameSourceWebView>(); } UpdateBeginFrameSource(); + recorder_->Start(); } BrowserViewRenderer::~BrowserViewRenderer() { + recorder_->OnDestroyed(); DCHECK(compositor_map_.empty()); DCHECK(!current_compositor_frame_consumer_); } @@ -506,6 +510,7 @@ if (offscreen_pre_raster_) ComputeTileRectAndUpdateMemoryPolicy(); UpdateBeginFrameSource(); + recorder_->OnAttachedToWindow(); } void BrowserViewRenderer::OnDetachedFromWindow() {
diff --git a/android_webview/browser/gfx/browser_view_renderer.h b/android_webview/browser/gfx/browser_view_renderer.h index 641aff96..ea9e5db0 100644 --- a/android_webview/browser/gfx/browser_view_renderer.h +++ b/android_webview/browser/gfx/browser_view_renderer.h
@@ -38,6 +38,7 @@ namespace android_webview { +class AwAttachingToWindowRecorder; class BrowserViewRendererClient; class ChildFrame; class CompositorFrameConsumer; @@ -268,6 +269,8 @@ std::unique_ptr<BeginFrameSourceWebView> begin_frame_source_; + scoped_refptr<AwAttachingToWindowRecorder> recorder_; + base::WeakPtrFactory<CompositorFrameProducer> weak_ptr_factory_{this}; DISALLOW_COPY_AND_ASSIGN(BrowserViewRenderer);
diff --git a/android_webview/browser/gfx/test/rendering_test.cc b/android_webview/browser/gfx/test/rendering_test.cc index 7df1df4f..245b66c 100644 --- a/android_webview/browser/gfx/test/rendering_test.cc +++ b/android_webview/browser/gfx/test/rendering_test.cc
@@ -48,8 +48,7 @@ } // namespace RenderingTest::RenderingTest() - : task_environment_( - std::make_unique<base::test::SingleThreadTaskEnvironment>()) { + : task_environment_(std::make_unique<base::test::TaskEnvironment>()) { ui_task_runner_ = base::ThreadTaskRunnerHandle::Get(); }
diff --git a/android_webview/browser/gfx/test/rendering_test.h b/android_webview/browser/gfx/test/rendering_test.h index 25413c6..fa88eac 100644 --- a/android_webview/browser/gfx/test/rendering_test.h +++ b/android_webview/browser/gfx/test/rendering_test.h
@@ -17,14 +17,14 @@ namespace base { namespace test { -class SingleThreadTaskEnvironment; +class TaskEnvironment; } } // namespace base namespace content { class SynchronousCompositor; class TestSynchronousCompositor; -} +} // namespace content namespace ui { class TouchHandleDrawable; @@ -75,7 +75,6 @@ bool view_tree_force_dark_state) override {} protected: - RenderingTest(); ~RenderingTest() override; @@ -99,7 +98,7 @@ std::unique_ptr<content::TestSynchronousCompositor> compositor_; private: - std::unique_ptr<base::test::SingleThreadTaskEnvironment> task_environment_; + std::unique_ptr<base::test::TaskEnvironment> task_environment_; base::RunLoop run_loop_; DISALLOW_COPY_AND_ASSIGN(RenderingTest);
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentsLifecycleNotifier.java b/android_webview/java/src/org/chromium/android_webview/AwContentsLifecycleNotifier.java index 129958b1..21b372a9 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContentsLifecycleNotifier.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContentsLifecycleNotifier.java
@@ -28,7 +28,7 @@ private static final ObserverList<Observer> sLifecycleObservers = new ObserverList<Observer>(); - private static int sNumWebViews; + private static boolean sHasWebViewInstances; private AwContentsLifecycleNotifier() {} @@ -41,34 +41,28 @@ } public static boolean hasWebViewInstances() { - return sNumWebViews > 0; + return sHasWebViewInstances; } // Called on UI thread. @CalledByNative - private static void onWebViewCreated() { + private static void onFirstWebViewCreated() { ThreadUtils.assertOnUiThread(); - assert sNumWebViews >= 0; - sNumWebViews++; - if (sNumWebViews == 1) { - // first webview created, notify observers. - for (Observer observer : sLifecycleObservers) { - observer.onFirstWebViewCreated(); - } + sHasWebViewInstances = true; + // first webview created, notify observers. + for (Observer observer : sLifecycleObservers) { + observer.onFirstWebViewCreated(); } } // Called on UI thread. @CalledByNative - private static void onWebViewDestroyed() { + private static void onLastWebViewDestroyed() { ThreadUtils.assertOnUiThread(); - assert sNumWebViews > 0; - sNumWebViews--; - if (sNumWebViews == 0) { - // last webview destroyed, notify observers. - for (Observer observer : sLifecycleObservers) { - observer.onLastWebViewDestroyed(); - } + sHasWebViewInstances = false; + // last webview destroyed, notify observers. + for (Observer observer : sLifecycleObservers) { + observer.onLastWebViewDestroyed(); } } }
diff --git a/android_webview/test/BUILD.gn b/android_webview/test/BUILD.gn index e3d3e017..abd00eb 100644 --- a/android_webview/test/BUILD.gn +++ b/android_webview/test/BUILD.gn
@@ -401,6 +401,7 @@ "../browser/aw_form_database_service_unittest.cc", "../browser/aw_media_url_interceptor_unittest.cc", "../browser/aw_permission_manager_unittest.cc", + "../browser/gfx/aw_attaching_to_window_recorder_unittest.cc", "../browser/gfx/begin_frame_source_webview_unittest.cc", "../browser/gfx/browser_view_renderer_unittest.cc", "../browser/gfx/test/fake_window.cc",
diff --git a/ash/wm/tablet_mode/tablet_mode_controller.cc b/ash/wm/tablet_mode/tablet_mode_controller.cc index 6e5aef2..a95cd9e 100644 --- a/ash/wm/tablet_mode/tablet_mode_controller.cc +++ b/ash/wm/tablet_mode/tablet_mode_controller.cc
@@ -619,11 +619,6 @@ void TabletModeController::OnLayerAnimationEnded( ui::LayerAnimationSequence* sequence) { - // This may be called before |OnLayerAnimationScheduled()| if tablet is - // entered/exited while an animation is in progress, so we won't get - // stats/screenshot in those cases. - // TODO(sammiequon): We may want to remove the |fps_counter_| check and - // simplify things since those are edge cases. if (!fps_counter_ || !IsTransformAnimationSequence(sequence)) return; @@ -681,28 +676,21 @@ state_ = State::kEnteringTabletMode; // Take a screenshot if there is a top window that will get animated. + // Since with ash::features::kDragToSnapInClamshellMode enabled, we'll keep + // overview active after clamshell <-> tablet mode transition if it was + // active before transition, do not take screenshot if overview is active + // in this case. // TODO(sammiequon): Handle the case where the top window is not on the // primary display. aura::Window* top_window = TabletModeWindowManager::GetTopWindow(); const bool top_window_on_primary_display = top_window && top_window->GetRootWindow() == Shell::GetPrimaryRootWindow(); - // If the top window was already animating (eg. tablet mode event received - // while create window animation still running), skip taking the screenshot. - // It will take a performance hit but will remove cases where the screenshot - // might not get deleted because of the extra animation observer methods - // getting fired. - const bool top_window_animating = - top_window && top_window->layer()->GetAnimator()->is_animating(); - // Since with ash::features::kDragToSnapInClamshellMode enabled, we'll keep - // overview active after clamshell <-> tablet mode transition if it was - // active before transition, do not take screenshot if overview is active - // in this case. const bool overview_remain_active = IsClamshellSplitViewModeEnabled() && Shell::Get()->overview_controller()->InOverviewSession(); if (use_screenshot_for_test && top_window_on_primary_display && - !top_window_animating && !overview_remain_active) { + !overview_remain_active) { TakeScreenshot(top_window); } else { FinishInitTabletMode();
diff --git a/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc b/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc index b539fdd5..86a18a4 100644 --- a/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc +++ b/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc
@@ -1685,30 +1685,12 @@ EXPECT_FALSE(IsScreenshotShown()); } -// Regression test for screenshot staying visible when entering tablet mode when -// a window creation animation is still underway. See https://crbug.com/1035356. -TEST_P(TabletModeControllerScreenshotTest, EnterTabletModeWhileAnimating) { - auto window = CreateTestWindow(gfx::Rect(200, 200)); - ASSERT_TRUE(window->layer()->GetAnimator()->is_animating()); - - // Enter tablet mode. - TabletMode::Waiter waiter(/*enable=*/true); - SetTabletMode(true); - EXPECT_FALSE(IsScreenshotShown()); - - waiter.Wait(); - EXPECT_FALSE(IsScreenshotShown()); -} - // Tests that the screenshot is visible when a window animation happens when // entering tablet mode. TEST_P(TabletModeControllerScreenshotTest, ScreenshotVisibility) { auto window = CreateTestWindow(gfx::Rect(200, 200)); auto window2 = CreateTestWindow(gfx::Rect(300, 200)); - - window->layer()->GetAnimator()->StopAnimating(); ui::Layer* layer = window2->layer(); - layer->GetAnimator()->StopAnimating(); ASSERT_FALSE(IsScreenshotShown()); TabletMode::Waiter waiter(/*enable=*/true); @@ -1731,7 +1713,6 @@ TEST_P(TabletModeControllerScreenshotTest, NoCrashWhenExitingWithoutWaiting) { // One non-maximized window is needed for screenshot to be taken. auto window = CreateTestWindow(gfx::Rect(200, 200)); - window->layer()->GetAnimator()->StopAnimating(); SetTabletMode(true); SetTabletMode(false);
diff --git a/base/android/java/src/org/chromium/base/Promise.java b/base/android/java/src/org/chromium/base/Promise.java index 74a959bc..35982b5c 100644 --- a/base/android/java/src/org/chromium/base/Promise.java +++ b/base/android/java/src/org/chromium/base/Promise.java
@@ -271,6 +271,15 @@ return promise; } + /** + * Convenience method to return a rejected Promise. + */ + public static <T> Promise<T> rejected() { + Promise<T> promise = new Promise<>(); + promise.reject(); + return promise; + } + private void checkThread() { assert mThread == Thread.currentThread() : "Promise must only be used on a single Thread."; }
diff --git a/base/test/launcher/test_launcher.cc b/base/test/launcher/test_launcher.cc index 21f544be..b473c3c0 100644 --- a/base/test/launcher/test_launcher.cc +++ b/base/test/launcher/test_launcher.cc
@@ -1494,6 +1494,11 @@ } for (const TestIdentifier& test_id : tests) { TestInfo test_info(test_id); + if (test_id.test_case_name == "GoogleTestVerification") { + LOG(INFO) << "The following parameterized test case is not instantiated: " + << test_id.test_name; + continue; + } // TODO(isamsonov): crbug.com/1004417 remove when windows builders // stop flaking on MANAUAL_ tests. if (launcher_delegate_->ShouldRunTest(test_id))
diff --git a/base/test/launcher/test_launcher.h b/base/test/launcher/test_launcher.h index 8618e3f..f09385bc6 100644 --- a/base/test/launcher/test_launcher.h +++ b/base/test/launcher/test_launcher.h
@@ -165,6 +165,7 @@ bool Init(CommandLine* command_line) WARN_UNUSED_RESULT; // Gets tests from the delegate, and converts to TestInfo objects. + // Catches and logs uninstantiated parameterized tests. // Returns false if delegate fails to return tests. bool InitTests();
diff --git a/build/android/pylib/gtest/filter/content_browsertests_disabled b/build/android/pylib/gtest/filter/content_browsertests_disabled index 862c0e65..8ec9834 100644 --- a/build/android/pylib/gtest/filter/content_browsertests_disabled +++ b/build/android/pylib/gtest/filter/content_browsertests_disabled
@@ -50,5 +50,4 @@ MSE_ClearKey/EncryptedMediaTest.ConfigChangeVideo/0 # http://crbug.com/1039450 -*/WebRtcMediaRecorderTest.*/2 -*/WebRtcMediaRecorderTest.*/6 +ProprietaryCodec/WebRtcMediaRecorderTest.*
diff --git a/cc/metrics/frame_sequence_tracker.cc b/cc/metrics/frame_sequence_tracker.cc index e003f75..eddff7bb 100644 --- a/cc/metrics/frame_sequence_tracker.cc +++ b/cc/metrics/frame_sequence_tracker.cc
@@ -163,7 +163,7 @@ main_throughput_.frames_expected > 0; } -void FrameSequenceMetrics::ReportMetrics() { +void FrameSequenceMetrics::ReportMetrics(const std::string& debug_trace) { DCHECK_LE(impl_throughput_.frames_produced, impl_throughput_.frames_expected); DCHECK_LE(main_throughput_.frames_produced, main_throughput_.frames_expected); TRACE_EVENT_ASYNC_END2( @@ -176,6 +176,14 @@ type_, ThreadType::kCompositor, GetIndexForMetric(FrameSequenceMetrics::ThreadType::kCompositor, type_), impl_throughput_); +#if DCHECK_IS_ON() + if (impl_throughput_percent.has_value()) { + DCHECK_EQ(impl_throughput_.frames_received, + impl_throughput_.frames_processed) + << debug_trace << " " << type_; + } +#endif + base::Optional<int> main_throughput_percent = ThroughputData::ReportHistogram( type_, ThreadType::kMain, GetIndexForMetric(FrameSequenceMetrics::ThreadType::kMain, type_), @@ -358,8 +366,13 @@ metrics->Merge(std::move(accumulated_metrics_[tracker->type()])); accumulated_metrics_.erase(tracker->type()); } - if (metrics->HasEnoughDataForReporting()) + if (metrics->HasEnoughDataForReporting()) { +#if DCHECK_IS_ON() + metrics->ReportMetrics(tracker->frame_sequence_trace_.str()); +#else metrics->ReportMetrics(); +#endif + } if (metrics->HasDataLeftForReporting()) accumulated_metrics_[tracker->type()] = std::move(metrics); } @@ -429,6 +442,9 @@ if (last_processed_impl_sequence_ < last_started_impl_sequence_) { impl_throughput().frames_expected -= begin_impl_frame_data_.previous_sequence_delta; +#if DCHECK_IS_ON() + --impl_throughput().frames_received; +#endif } } @@ -471,6 +487,9 @@ args.frame_id.sequence_number); impl_throughput().frames_expected += begin_impl_frame_data_.previous_sequence_delta; +#if DCHECK_IS_ON() + ++impl_throughput().frames_received; +#endif if (first_frame_timestamp_.is_null()) first_frame_timestamp_ = args.frame_time; @@ -546,6 +565,10 @@ #if DCHECK_IS_ON() DCHECK(is_inside_frame_) << TRACKER_DCHECK_MSG; + DCHECK_LT(impl_throughput().frames_processed, + impl_throughput().frames_received) + << TRACKER_DCHECK_MSG; + ++impl_throughput().frames_processed; #endif last_processed_impl_sequence_ = ack.frame_id.sequence_number; @@ -616,6 +639,12 @@ impl_throughput().frames_produced) << TRACKER_DCHECK_MSG; --impl_throughput().frames_expected; +#if DCHECK_IS_ON() + DCHECK_LT(impl_throughput().frames_processed, + impl_throughput().frames_received) + << TRACKER_DCHECK_MSG; + ++impl_throughput().frames_processed; +#endif begin_impl_frame_data_.previous_sequence = 0; } frame_had_no_compositor_damage_ = false;
diff --git a/cc/metrics/frame_sequence_tracker.h b/cc/metrics/frame_sequence_tracker.h index cd9fdb4..3bb4df2c 100644 --- a/cc/metrics/frame_sequence_tracker.h +++ b/cc/metrics/frame_sequence_tracker.h
@@ -82,6 +82,10 @@ void Merge(const ThroughputData& data) { frames_expected += data.frames_expected; frames_produced += data.frames_produced; +#if DCHECK_IS_ON() + frames_processed += data.frames_processed; + frames_received += data.frames_received; +#endif } // Tracks the number of frames that were expected to be shown during this @@ -91,13 +95,22 @@ // Tracks the number of frames that were actually presented to the user // during this frame-sequence. uint32_t frames_produced = 0; + +#if DCHECK_IS_ON() + // Tracks the number of frames that is either submitted or reported as no + // damage. + uint32_t frames_processed = 0; + + // Tracks the number of begin-frames that are received. + uint32_t frames_received = 0; +#endif }; void Merge(std::unique_ptr<FrameSequenceMetrics> metrics); bool HasEnoughDataForReporting() const; bool HasDataLeftForReporting() const; // Report related metrics: throughput, checkboarding... - void ReportMetrics(); + void ReportMetrics(const std::string& debug_trace = std::string()); ThroughputData& impl_throughput() { return impl_throughput_; } ThroughputData& main_throughput() { return main_throughput_; }
diff --git a/cc/metrics/frame_sequence_tracker_unittest.cc b/cc/metrics/frame_sequence_tracker_unittest.cc index 19a372e..adc9645 100644 --- a/cc/metrics/frame_sequence_tracker_unittest.cc +++ b/cc/metrics/frame_sequence_tracker_unittest.cc
@@ -487,15 +487,20 @@ // args.frame_time is less than 5s of the tracker creation time, so won't // schedule this tracker to report its throughput. collection_.NotifyBeginImplFrame(args); + collection_.NotifyImplFrameCausedNoDamage(viz::BeginFrameAck(args, false)); + collection_.NotifyFrameEnd(args); + EXPECT_EQ(NumberOfTrackers(), 1u); EXPECT_EQ(NumberOfRemovalTrackers(), 0u); - ImplThroughput().frames_expected += 100; + ImplThroughput().frames_expected += 101; // Now args.frame_time is 5s since the tracker creation time, so this tracker // should be scheduled to report its throughput. args = CreateBeginFrameArgs(source, ++sequence, args.frame_time + TimeDeltaToReort()); collection_.NotifyBeginImplFrame(args); + collection_.NotifyImplFrameCausedNoDamage(viz::BeginFrameAck(args, false)); + collection_.NotifyFrameEnd(args); EXPECT_EQ(NumberOfTrackers(), 1u); EXPECT_EQ(NumberOfRemovalTrackers(), 1u); }
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index b447ede..ef55dbfbc 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -2004,6 +2004,13 @@ PresentationTimeCallbackBuffer::PendingCallbacks activated = presentation_time_callbacks_.PopPendingCallbacks(frame_token); + // The callbacks in |compositor_thread_callbacks| expect to be run on the + // compositor thread so we'll run them now. + for (LayerTreeHost::PresentationTimeCallback& callback : + activated.compositor_thread_callbacks) { + std::move(callback).Run(details.presentation_feedback); + } + // Send all the main-thread callbacks to the client in one batch. The client // is in charge of posting them to the main thread. client_->DidPresentCompositorFrameOnImplThread( @@ -2648,6 +2655,15 @@ SetRequiresHighResToDraw(); } +void LayerTreeHostImpl::RegisterMainThreadPresentationTimeCallback( + uint32_t frame_token, + LayerTreeHost::PresentationTimeCallback callback) { + std::vector<LayerTreeHost::PresentationTimeCallback> as_vector; + as_vector.emplace_back(std::move(callback)); + presentation_time_callbacks_.RegisterMainThreadPresentationCallbacks( + frame_token, std::move(as_vector)); +} + void LayerTreeHostImpl::RegisterCompositorPresentationTimeCallback( uint32_t frame_token, LayerTreeHost::PresentationTimeCallback callback) {
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index 943d8a7..a03b49c 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h
@@ -549,6 +549,14 @@ uint32_t next_frame_token() const { return *next_frame_token_; } // Buffers |callback| until a relevant frame swap ocurrs, at which point the + // callback will be posted to run on the main thread. A frame swap is + // considered relevant if the swapped frame's token is greater than or equal + // to |frame_token|. + void RegisterMainThreadPresentationTimeCallback( + uint32_t frame_token, + LayerTreeHost::PresentationTimeCallback callback); + + // Buffers |callback| until a relevant frame swap ocurrs, at which point the // callback will be run on the compositor thread. A frame swap is considered // relevant if the swapped frame's token is greater than or equal to // |frame_token|.
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 3403388b..72e3d54 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -19,6 +19,7 @@ #include "base/memory/ptr_util.h" #include "base/optional.h" #include "base/run_loop.h" +#include "base/test/bind_test_util.h" #include "base/test/metrics/histogram_tester.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" @@ -1430,6 +1431,79 @@ status.main_thread_scrolling_reasons); } +gfx::PresentationFeedback ExampleFeedback() { + return gfx::PresentationFeedback( + base::TimeTicks() + base::TimeDelta::FromMilliseconds(42), + base::TimeDelta::FromMicroseconds(18), + gfx::PresentationFeedback::Flags::kVSync | + gfx::PresentationFeedback::Flags::kHWCompletion); +} + +class LayerTreeHostImplTestInvokeMainThreadCallbacks + : public LayerTreeHostImplTest { + public: + void DidPresentCompositorFrameOnImplThread( + uint32_t frame_token, + std::vector<LayerTreeHost::PresentationTimeCallback> callbacks, + const viz::FrameTimingDetails& details) override { + for (LayerTreeHost::PresentationTimeCallback& callback : callbacks) { + std::move(callback).Run(details.presentation_feedback); + } + } +}; + +// Tests that, when the LayerTreeHostImpl receives presentation feedback, the +// feedback gets routed to a properly registered callback. +TEST_F(LayerTreeHostImplTestInvokeMainThreadCallbacks, + PresentationFeedbackCallbacksFire) { + bool compositor_thread_callback_fired = false; + bool main_thread_callback_fired = false; + gfx::PresentationFeedback feedback_seen_by_compositor_thread_callback; + gfx::PresentationFeedback feedback_seen_by_main_thread_callback; + + // Register a compositor-thread callback to run when the frame for + // |frame_token_1| gets presented. + constexpr uint32_t frame_token_1 = 1; + host_impl_->RegisterCompositorPresentationTimeCallback( + frame_token_1, base::BindLambdaForTesting( + [&](const gfx::PresentationFeedback& feedback) { + compositor_thread_callback_fired = true; + feedback_seen_by_compositor_thread_callback = + feedback; + })); + + // Register a main-thread callback to run when the frame for |frame_token_2| + // gets presented. + constexpr uint32_t frame_token_2 = 2; + ASSERT_GT(frame_token_2, frame_token_1); + host_impl_->RegisterMainThreadPresentationTimeCallback( + frame_token_2, base::BindLambdaForTesting( + [&](const gfx::PresentationFeedback& feedback) { + main_thread_callback_fired = true; + feedback_seen_by_main_thread_callback = feedback; + })); + + viz::FrameTimingDetails mock_details; + mock_details.presentation_feedback = ExampleFeedback(); + + host_impl_->DidPresentCompositorFrame(frame_token_1, mock_details); + + EXPECT_TRUE(compositor_thread_callback_fired); + EXPECT_EQ(feedback_seen_by_compositor_thread_callback, + mock_details.presentation_feedback); + + // Since |frame_token_2| is strictly greater than |frame_token_1|, the + // main-thread callback must remain queued for now. + EXPECT_FALSE(main_thread_callback_fired); + EXPECT_EQ(feedback_seen_by_main_thread_callback, gfx::PresentationFeedback()); + + host_impl_->DidPresentCompositorFrame(frame_token_2, mock_details); + + EXPECT_TRUE(main_thread_callback_fired); + EXPECT_EQ(feedback_seen_by_main_thread_callback, + mock_details.presentation_feedback); +} + TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionBasic) { SetupViewportLayersInnerScrolls(gfx::Size(100, 100), gfx::Size(200, 200));
diff --git a/chrome/VERSION b/chrome/VERSION index 320677ab..8f9c508 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=81 MINOR=0 -BUILD=4029 +BUILD=4030 PATCH=0
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index c333b08a..1a5f02a 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -1378,7 +1378,6 @@ "java/src/org/chromium/chrome/browser/settings/SeekBarPreference.java", "java/src/org/chromium/chrome/browser/settings/SettingsActivity.java", "java/src/org/chromium/chrome/browser/settings/SettingsLauncher.java", - "java/src/org/chromium/chrome/browser/settings/TextAndButtonPreference.java", "java/src/org/chromium/chrome/browser/settings/about/AboutChromePreferenceOSVersion.java", "java/src/org/chromium/chrome/browser/settings/about/AboutChromeSettings.java", "java/src/org/chromium/chrome/browser/settings/about/AboutSettingsBridge.java", @@ -1388,6 +1387,7 @@ "java/src/org/chromium/chrome/browser/settings/autofill/AndroidPaymentAppPreference.java", "java/src/org/chromium/chrome/browser/settings/autofill/AndroidPaymentAppsFragment.java", "java/src/org/chromium/chrome/browser/settings/autofill/AutofillCreditCardEditor.java", + "java/src/org/chromium/chrome/browser/settings/autofill/AutofillEditLinkPreference.java", "java/src/org/chromium/chrome/browser/settings/autofill/AutofillEditorBase.java", "java/src/org/chromium/chrome/browser/settings/autofill/AutofillLocalCardEditor.java", "java/src/org/chromium/chrome/browser/settings/autofill/AutofillPaymentMethodsFragment.java",
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantTextUtils.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantTextUtils.java index 3891e3f..4a8f21e3 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantTextUtils.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantTextUtils.java
@@ -12,6 +12,7 @@ import androidx.annotation.Nullable; import org.chromium.base.Callback; +import org.chromium.base.Log; import org.chromium.ui.text.NoUnderlineClickableSpan; import org.chromium.ui.text.SpanApplier; @@ -26,6 +27,8 @@ * Common text utilities used by autofill assistant. */ public class AssistantTextUtils { + private static final String TAG = "AssistantTextUtils"; + /** Bold tags of the form <b>...</b>. */ private static final SpanApplier.SpanInfo BOLD_SPAN_INFO = new SpanApplier.SpanInfo("<b>", "</b>", new StyleSpan(android.graphics.Typeface.BOLD)); @@ -33,7 +36,7 @@ private static final SpanApplier.SpanInfo ITALIC_SPAN_INFO = new SpanApplier.SpanInfo("<i>", "</i>", new StyleSpan(Typeface.ITALIC)); /** Links of the form <link0>...</link0>. */ - private static final Pattern LINK_PATTERN = Pattern.compile("<link(\\d+)>"); + private static final Pattern LINK_START_PATTERN = Pattern.compile("<link(\\d+)>"); /** * Sets the text of {@code view} by automatically applying all special appearance tags in {@code @@ -54,7 +57,7 @@ // We first collect the link IDs into a set to allow multiple links with same ID. Set<Integer> linkIds = new HashSet<>(); - Matcher matcher = LINK_PATTERN.matcher(text); + Matcher matcher = LINK_START_PATTERN.matcher(text); while (matcher.find()) { linkIds.add(Integer.parseInt(matcher.group(1))); } @@ -68,8 +71,20 @@ }))); } + List<SpanApplier.SpanInfo> successfulSpans = new ArrayList<>(); + for (SpanApplier.SpanInfo info : spans) { + try { + SpanApplier.applySpans(text, info); + + // Apply successful. Add the info to the list. + successfulSpans.add(info); + } catch (IllegalArgumentException e) { + Log.d(TAG, "Mismatching span", e); + } + } + view.setText(SpanApplier.applySpans( - text, spans.toArray(new SpanApplier.SpanInfo[spans.size()]))); + text, successfulSpans.toArray(new SpanApplier.SpanInfo[successfulSpans.size()]))); view.setMovementMethod(linkIds.isEmpty() ? null : LinkMovementMethod.getInstance()); } }
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantTextUtilsTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantTextUtilsTest.java index 26fe6af..a68f30a1 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantTextUtilsTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantTextUtilsTest.java
@@ -41,6 +41,20 @@ @Rule public CustomTabActivityTestRule mTestRule = new CustomTabActivityTestRule(); + /* Simple helper class that keeps track of the most recent callback result. */ + class LinkCallback implements Callback<Integer> { + private int mLastCallback = -1; + + private int getLastCallback() { + return mLastCallback; + } + + @Override + public void onResult(Integer result) { + mLastCallback = result; + } + } + @Before public void setUp() { AutofillAssistantUiTestUtil.startOnBlankPage(mTestRule); @@ -92,20 +106,26 @@ @Test @MediumTest + public void testMismatchingTextTags() throws Exception { + TextView textView = runOnUiThreadBlocking(() -> { + TextView view = new TextView(mTestRule.getActivity()); + mTestLayout.addView(view); + AssistantTextUtils.applyVisualAppearanceTags( + view, "<b>Fat</b>. <b>Not fat</br>. <i>Italic</i>. <i>Not italic</ii>.", null); + StyleSpan[] spans = + ((SpannedString) view.getText()).getSpans(0, view.length(), StyleSpan.class); + assertThat(spans.length, is(2)); + assertThat(spans[0].getStyle(), is(Typeface.BOLD)); + assertThat(spans[1].getStyle(), is(Typeface.ITALIC)); + return view; + }); + onView(is(textView)) + .check(matches(withText("Fat. <b>Not fat</br>. Italic. <i>Not italic</ii>."))); + } + + @Test + @MediumTest public void testTextLinks() throws Exception { - /* Simple helper class that keeps track of the most recent callback result. */ - class LinkCallback implements Callback<Integer> { - private int mLastCallback = -1; - - private int getLastCallback() { - return mLastCallback; - } - @Override - public void onResult(Integer result) { - mLastCallback = result; - } - } - LinkCallback linkCallback = new LinkCallback(); TextView multiLinkView = runOnUiThreadBlocking(() -> { TextView view = new TextView(mTestRule.getActivity()); @@ -125,4 +145,25 @@ onView(is(multiLinkView)).perform(openTextLink("there")); assertThat(linkCallback.getLastCallback(), is(2)); } + + @Test + @MediumTest + public void testMismatchingTextLinks() throws Exception { + LinkCallback linkCallback = new LinkCallback(); + + TextView singleLinkView = runOnUiThreadBlocking(() -> { + TextView view = new TextView(mTestRule.getActivity()); + mTestLayout.addView(view); + AssistantTextUtils.applyVisualAppearanceTags(view, + "Don't click <link0>here</link1> or <link2>this</lin2>, " + + "click <link3>me</link3>.", + linkCallback); + return view; + }); + onView(is(singleLinkView)) + .check(matches(withText( + "Don't click <link0>here</link1> or <link2>this</lin2>, click me."))); + onView(is(singleLinkView)).perform(openTextLink("me")); + assertThat(linkCallback.getLastCallback(), is(3)); + } } \ No newline at end of file
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java index 0cbc39b..eed3f5e5 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java
@@ -25,7 +25,7 @@ import android.support.test.espresso.ViewAssertion; import android.support.test.espresso.core.deps.guava.base.Preconditions; import android.support.test.espresso.matcher.BoundedMatcher; -import android.text.SpannableString; +import android.text.Spanned; import android.text.style.ClickableSpan; import android.view.Gravity; import android.view.LayoutInflater; @@ -235,13 +235,13 @@ @Override public void perform(UiController uiController, View view) { TextView textView = (TextView) view; - SpannableString spannableString = (SpannableString) textView.getText(); + Spanned spannedString = (Spanned) textView.getText(); ClickableSpan[] spans = - spannableString.getSpans(0, spannableString.length(), ClickableSpan.class); + spannedString.getSpans(0, spannedString.length(), ClickableSpan.class); for (ClickableSpan span : spans) { if (textLink.contentEquals( - spannableString.subSequence(spannableString.getSpanStart(span), - spannableString.getSpanEnd(span)))) { + spannedString.subSequence(spannedString.getSpanStart(span), + spannedString.getSpanEnd(span)))) { span.onClick(view); return; }
diff --git a/chrome/android/features/start_surface/internal/BUILD.gn b/chrome/android/features/start_surface/internal/BUILD.gn index dcd83a05..c7e9764 100644 --- a/chrome/android/features/start_surface/internal/BUILD.gn +++ b/chrome/android/features/start_surface/internal/BUILD.gn
@@ -46,6 +46,7 @@ ":java_resources", "//base:base_java", "//chrome/android:chrome_java", + "//chrome/android/third_party/compositor_animator:compositor_animator_java", "//chrome/browser/preferences:java", "//chrome/browser/ui/android/widget:java", "//components/browser_ui/widget/android:java",
diff --git a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceLayout.java b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceLayout.java index 33d61e1..30beff9 100644 --- a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceLayout.java +++ b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceLayout.java
@@ -17,6 +17,7 @@ import androidx.annotation.VisibleForTesting; import org.chromium.base.Log; +import org.chromium.base.MathUtils; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordUserAction; import org.chromium.base.supplier.Supplier; @@ -33,6 +34,7 @@ import org.chromium.chrome.browser.compositor.layouts.eventfilter.EventFilter; import org.chromium.chrome.browser.compositor.scene_layer.SceneLayer; import org.chromium.chrome.browser.compositor.scene_layer.TabListSceneLayer; +import org.chromium.chrome.browser.flags.FeatureUtilities; import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabFeatureUtilities; @@ -80,6 +82,7 @@ private long mLastFrameTime; private long mMaxFrameInterval; private int mStartFrame; + private float mThumbnailAspectRatio; interface PerfListener { void onAnimationDone( @@ -98,6 +101,11 @@ mController = mStartSurface.getController(); mController.addOverviewModeObserver(this); mTabListDelegate = mStartSurface.getTabListDelegate(); + if (FeatureUtilities.isTabThumbnailAspectRatioNotOne()) { + mThumbnailAspectRatio = (float) ChromeFeatureList.getFieldTrialParamByFeatureAsDouble( + ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID, "thumbnail_aspect_ratio", 1.0); + mThumbnailAspectRatio = MathUtils.clamp(mThumbnailAspectRatio, 0.5f, 2.0f); + } } // StartSurface.OverviewModeObserver implementation. @@ -302,7 +310,11 @@ // down, making the "create group" visible for a while. animationList.add(CompositorAnimator.ofFloatProperty(handler, sourceLayoutTab, LayoutTab.MAX_CONTENT_HEIGHT, sourceLayoutTab.getUnclampedOriginalContentHeight(), - getWidth(), ZOOMING_DURATION, Interpolators.FAST_OUT_SLOW_IN_INTERPOLATOR)); + FeatureUtilities.isTabThumbnailAspectRatioNotOne() + ? Math.min(getWidth() / mThumbnailAspectRatio, + sourceLayoutTab.getUnclampedOriginalContentHeight()) + : getWidth(), + ZOOMING_DURATION, Interpolators.FAST_OUT_SLOW_IN_INTERPOLATOR)); CompositorAnimator backgroundAlpha = CompositorAnimator.ofFloat(handler, 0f, 1f, BACKGROUND_FADING_DURATION_MS, @@ -353,7 +365,11 @@ // TODO(crbug.com/964406): when shrinking to the bottom row, bottom of the tab goes up and // down, making the "create group" visible for a while. animationList.add(CompositorAnimator.ofFloatProperty(handler, sourceLayoutTab, - LayoutTab.MAX_CONTENT_HEIGHT, getWidth(), + LayoutTab.MAX_CONTENT_HEIGHT, + FeatureUtilities.isTabThumbnailAspectRatioNotOne() + ? Math.min(getWidth() / mThumbnailAspectRatio, + sourceLayoutTab.getUnclampedOriginalContentHeight()) + : getWidth(), sourceLayoutTab.getUnclampedOriginalContentHeight(), ZOOMING_DURATION, Interpolators.FAST_OUT_SLOW_IN_INTERPOLATOR));
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java index 2c0e9944..ef2c042 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java
@@ -26,6 +26,7 @@ import static org.chromium.content_public.browser.test.util.CriteriaHelper.DEFAULT_POLLING_INTERVAL; import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; import android.os.Build; import android.support.annotation.Nullable; import android.support.test.InstrumentationRegistry; @@ -37,6 +38,7 @@ import android.support.v7.widget.RecyclerView; import android.text.TextUtils; import android.view.View; +import android.widget.ImageView; import org.junit.After; import org.junit.Before; @@ -59,9 +61,11 @@ import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.compositor.layouts.Layout; +import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.flags.FeatureUtilities; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabFeatureUtilities; +import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tasks.tab_management.TabSelectionEditorTestingRobot; import org.chromium.chrome.browser.tasks.tab_management.TabSuggestionMessageService; import org.chromium.chrome.browser.tasks.tab_management.TabSwitcher; @@ -84,7 +88,9 @@ import org.chromium.ui.base.PageTransition; import org.chromium.ui.test.util.DisableAnimationsTestRule; import org.chromium.ui.test.util.UiRestriction; +import org.chromium.ui.widget.ViewLookupCachingFrameLayout; +import java.io.FileOutputStream; import java.io.IOException; import java.lang.ref.WeakReference; import java.util.LinkedList; @@ -854,6 +860,272 @@ verifyTabSwitcherCardCount(cta, 0); } + @Test + @MediumTest + // clang-format off + @Features.EnableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study") + @CommandLineFlags.Add({BASE_PARAMS}) + public void testThumbnailAspectRatio_default() throws Exception { + // clang-format on + prepareTabs(2, 0, mUrl); + TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity()); + onView(withId(R.id.tab_list_view)) + .check(ThumbnailAspectRatioAssertion.havingAspectRatio(1.0)); + } + + @Test + @MediumTest + // clang-format off + @Features.EnableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study") + @CommandLineFlags.Add({BASE_PARAMS + "/thumbnail_aspect_ratio/0.75"}) + public void testThumbnailAspectRatio_point75() throws Exception { + prepareTabs(2, 0, mUrl); + TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity()); + onView(withId(R.id.tab_list_view)) + .check(ThumbnailAspectRatioAssertion.havingAspectRatio(0.75)); + leaveGTSAndVerifyThumbnailsAreReleased(); + + Tab tab = mActivityTestRule.getActivity().getTabModelSelector().getCurrentTab(); + mActivityTestRule.loadUrlInTab( + NTP_URL, PageTransition.TYPED | PageTransition.FROM_ADDRESS_BAR, tab); + TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity()); + onView(withId(R.id.tab_list_view)) + .check(ThumbnailAspectRatioAssertion.havingAspectRatio(0.75)); + } + + @Test + @MediumTest + // clang-format off + @Features.EnableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study") + @CommandLineFlags.Add({BASE_PARAMS + "/thumbnail_aspect_ratio/2.0/allow_to_refetch/true"}) + public void testThumbnailAspectRatio_fromTwoToPoint75() throws Exception { + // clang-format on + prepareTabs(2, 0, mUrl); + TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity()); + onView(withId(R.id.tab_list_view)) + .check(ThumbnailAspectRatioAssertion.havingAspectRatio(2.0)); + TabModel currentTabModel = + mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel(); + for (int i = 0; i < currentTabModel.getCount(); i++) { + TabUiTestHelper.checkThumbnailsExist(currentTabModel.getTabAt(i)); + } + leaveGTSAndVerifyThumbnailsAreReleased(); + + simulateAspectRatioChangedToPoint75(); + verifyAllThumbnailHasAspectRatio(0.75); + + TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity()); + onView(withId(R.id.tab_list_view)) + .check(ThumbnailAspectRatioAssertion.havingAspectRatio(2.0)); + ApplicationTestUtils.finishActivity(mActivityTestRule.getActivity()); + } + + @Test + @MediumTest + // clang-format off + @Features.EnableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study") + @CommandLineFlags.Add({BASE_PARAMS}) + public void testThumbnailFetchingResult_defaultAspectRatio() throws Exception { + // clang-format on + prepareTabs(2, 0, mUrl); + int oldJpegCount = RecordHistogram.getHistogramValueCountForTesting( + TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT, + TabContentManager.ThumbnailFetchingResult.GOT_JPEG); + int oldEtc1Count = RecordHistogram.getHistogramValueCountForTesting( + TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT, + TabContentManager.ThumbnailFetchingResult.GOT_ETC1); + int oldNothingCount = RecordHistogram.getHistogramValueCountForTesting( + TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT, + TabContentManager.ThumbnailFetchingResult.GOT_NOTHING); + int oldDifferentAspectRatioJpegCount = RecordHistogram.getHistogramValueCountForTesting( + TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT, + TabContentManager.ThumbnailFetchingResult.GOT_DIFFERENT_ASPECT_RATIO_JPEG); + + TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity()); + int currentJpegCount = RecordHistogram.getHistogramValueCountForTesting( + TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT, + TabContentManager.ThumbnailFetchingResult.GOT_JPEG); + int currentEtc1Count = RecordHistogram.getHistogramValueCountForTesting( + TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT, + TabContentManager.ThumbnailFetchingResult.GOT_ETC1); + int currentNothingCount = RecordHistogram.getHistogramValueCountForTesting( + TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT, + TabContentManager.ThumbnailFetchingResult.GOT_NOTHING); + int currentDifferentAspectRatioJpegCount = RecordHistogram.getHistogramValueCountForTesting( + TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT, + TabContentManager.ThumbnailFetchingResult.GOT_DIFFERENT_ASPECT_RATIO_JPEG); + + assertEquals(1, currentJpegCount - oldJpegCount); + assertEquals(0, currentEtc1Count - oldEtc1Count); + assertEquals(0, currentDifferentAspectRatioJpegCount - oldDifferentAspectRatioJpegCount); + // Get thumbnail from a live layer. + assertEquals(1, currentNothingCount - oldNothingCount); + + oldJpegCount = currentJpegCount; + oldEtc1Count = currentEtc1Count; + oldNothingCount = currentNothingCount; + oldDifferentAspectRatioJpegCount = currentDifferentAspectRatioJpegCount; + + TabModel currentTabModel = + mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel(); + for (int i = 0; i < currentTabModel.getCount(); i++) { + TabUiTestHelper.checkThumbnailsExist(currentTabModel.getTabAt(i)); + } + + ApplicationTestUtils.finishActivity(mActivityTestRule.getActivity()); + mActivityTestRule.startMainActivityFromLauncher(); + + TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity()); + assertEquals(2, + RecordHistogram.getHistogramValueCountForTesting( + TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT, + TabContentManager.ThumbnailFetchingResult.GOT_JPEG) + - oldJpegCount); + assertEquals(0, + RecordHistogram.getHistogramValueCountForTesting( + TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT, + TabContentManager.ThumbnailFetchingResult.GOT_ETC1) + - oldEtc1Count); + assertEquals(0, + RecordHistogram.getHistogramValueCountForTesting( + TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT, + TabContentManager.ThumbnailFetchingResult.GOT_NOTHING) + - oldNothingCount); + assertEquals(0, + RecordHistogram.getHistogramValueCountForTesting( + TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT, + TabContentManager.ThumbnailFetchingResult.GOT_DIFFERENT_ASPECT_RATIO_JPEG) + - oldDifferentAspectRatioJpegCount); + } + + @Test + @MediumTest + // clang-format off + @Features.EnableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study") + @CommandLineFlags.Add({BASE_PARAMS + "/thumbnail_aspect_ratio/2.0/allow_to_refetch/true"}) + public void testThumbnailFetchingResult_changingAspectRatio() throws Exception { + // clang-format on + prepareTabs(2, 0, mUrl); + int oldJpegCount = RecordHistogram.getHistogramValueCountForTesting( + TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT, + TabContentManager.ThumbnailFetchingResult.GOT_JPEG); + int oldEtc1Count = RecordHistogram.getHistogramValueCountForTesting( + TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT, + TabContentManager.ThumbnailFetchingResult.GOT_ETC1); + int oldNothingCount = RecordHistogram.getHistogramValueCountForTesting( + TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT, + TabContentManager.ThumbnailFetchingResult.GOT_NOTHING); + int oldDifferentAspectRatioJpegCount = RecordHistogram.getHistogramValueCountForTesting( + TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT, + TabContentManager.ThumbnailFetchingResult.GOT_DIFFERENT_ASPECT_RATIO_JPEG); + + TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity()); + int currentJpegCount = RecordHistogram.getHistogramValueCountForTesting( + TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT, + TabContentManager.ThumbnailFetchingResult.GOT_JPEG); + int currentEtc1Count = RecordHistogram.getHistogramValueCountForTesting( + TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT, + TabContentManager.ThumbnailFetchingResult.GOT_ETC1); + int currentNothingCount = RecordHistogram.getHistogramValueCountForTesting( + TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT, + TabContentManager.ThumbnailFetchingResult.GOT_NOTHING); + int currentDifferentAspectRatioJpegCount = RecordHistogram.getHistogramValueCountForTesting( + TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT, + TabContentManager.ThumbnailFetchingResult.GOT_DIFFERENT_ASPECT_RATIO_JPEG); + + assertEquals(1, currentJpegCount - oldJpegCount); + assertEquals(0, currentEtc1Count - oldEtc1Count); + assertEquals(0, currentDifferentAspectRatioJpegCount - oldDifferentAspectRatioJpegCount); + // Get thumbnail from a live layer. + assertEquals(1, currentNothingCount - oldNothingCount); + + oldJpegCount = currentJpegCount; + oldEtc1Count = currentEtc1Count; + oldNothingCount = currentNothingCount; + oldDifferentAspectRatioJpegCount = currentDifferentAspectRatioJpegCount; + + onView(withId(R.id.tab_list_view)) + .check(ThumbnailAspectRatioAssertion.havingAspectRatio(2.0)); + + TabModel currentTabModel = + mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel(); + for (int i = 0; i < currentTabModel.getCount(); i++) { + TabUiTestHelper.checkThumbnailsExist(currentTabModel.getTabAt(i)); + } + leaveGTSAndVerifyThumbnailsAreReleased(); + + simulateAspectRatioChangedToPoint75(); + verifyAllThumbnailHasAspectRatio(0.75); + + TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity()); + assertEquals(0, + RecordHistogram.getHistogramValueCountForTesting( + TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT, + TabContentManager.ThumbnailFetchingResult.GOT_JPEG) + - oldJpegCount); + assertEquals(2, + RecordHistogram.getHistogramValueCountForTesting( + TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT, + TabContentManager.ThumbnailFetchingResult.GOT_DIFFERENT_ASPECT_RATIO_JPEG) + - oldDifferentAspectRatioJpegCount); + assertEquals(0, + RecordHistogram.getHistogramValueCountForTesting( + TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT, + TabContentManager.ThumbnailFetchingResult.GOT_ETC1) + - oldEtc1Count); + assertEquals(0, + RecordHistogram.getHistogramValueCountForTesting( + TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT, + TabContentManager.ThumbnailFetchingResult.GOT_NOTHING) + - oldNothingCount); + onView(withId(R.id.tab_list_view)) + .check(ThumbnailAspectRatioAssertion.havingAspectRatio(2.0)); + } + + @Test + @MediumTest + // clang-format off + @Features.EnableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study") + @DisableIf.Build(sdk_is_less_than = Build.VERSION_CODES.M, + message = "https://crbug.com/1023833") + @CommandLineFlags.Add({BASE_PARAMS}) + public void testRecycling_defaultAspectRatio() throws InterruptedException { + // clang-format on + prepareTabs(10, 0, mUrl); + ChromeTabUtils.switchTabInCurrentTabModel(mActivityTestRule.getActivity(), 0); + enterGTSWithThumbnailChecking(); + onView(withId(R.id.tab_list_view)).perform(RecyclerViewActions.scrollToPosition(9)); + } + + @Test + @MediumTest + // clang-format off + @Features.EnableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study") + @DisableIf.Build(sdk_is_less_than = Build.VERSION_CODES.M, + message = "https://crbug.com/1023833") + @CommandLineFlags.Add({BASE_PARAMS + "/thumbnail_aspect_ratio/0.75"}) + public void testRecycling_aspectRatioPoint75() throws InterruptedException { + // clang-format on + prepareTabs(10, 0, mUrl); + ChromeTabUtils.switchTabInCurrentTabModel(mActivityTestRule.getActivity(), 0); + enterGTSWithThumbnailChecking(); + onView(withId(R.id.tab_list_view)).perform(RecyclerViewActions.scrollToPosition(9)); + } + + @Test + @MediumTest + // clang-format off + @Features.EnableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study") + @DisableIf.Build(sdk_is_less_than = Build.VERSION_CODES.M, + message = "https://crbug.com/1023833") + @CommandLineFlags.Add({BASE_PARAMS + "/thumbnail_aspect_ratio/0.75"}) + public void testExpandTab_withAspectRatioPoint75() throws InterruptedException { + // clang-format on + prepareTabs(1, 0, mUrl); + enterGTSWithThumbnailChecking(); + leaveGTSAndVerifyThumbnailsAreReleased(); + } + private static class TabCountAssertion implements ViewAssertion { private int mExpectedCount; @@ -874,6 +1146,43 @@ } } + private static class ThumbnailAspectRatioAssertion implements ViewAssertion { + private double mExpectedRatio; + + public static ThumbnailAspectRatioAssertion havingAspectRatio(double ratio) { + return new ThumbnailAspectRatioAssertion(ratio); + } + + private ThumbnailAspectRatioAssertion(double expectedRatio) { + mExpectedRatio = expectedRatio; + } + + @Override + public void check(View view, NoMatchingViewException noMatchException) { + if (noMatchException != null) throw noMatchException; + + RecyclerView recyclerView = (RecyclerView) view; + + RecyclerView.Adapter adapter = recyclerView.getAdapter(); + for (int i = 0; i < adapter.getItemCount(); i++) { + RecyclerView.ViewHolder viewHolder = + recyclerView.findViewHolderForAdapterPosition(i); + if (viewHolder != null) { + ViewLookupCachingFrameLayout tabView = + (ViewLookupCachingFrameLayout) viewHolder.itemView; + ImageView thumbnail = (ImageView) tabView.fastFindViewById(R.id.tab_thumbnail); + BitmapDrawable drawable = (BitmapDrawable) thumbnail.getDrawable(); + Bitmap bitmap = drawable.getBitmap(); + double bitmapRatio = bitmap.getWidth() * 1.0 / bitmap.getHeight(); + assertTrue( + "Actual ratio: " + bitmapRatio + "; Expected ratio: " + mExpectedRatio, + Math.abs(bitmapRatio - mExpectedRatio) + <= TabContentManager.ASPECT_RATIO_PRECISION); + } + } + } + } + private void switchTabModel(boolean isIncognito) { assertTrue(isIncognito != mActivityTestRule.getActivity().getTabModelSelector().isIncognitoSelected()); @@ -999,4 +1308,34 @@ } return true; } + + private void simulateAspectRatioChangedToPoint75() throws IOException { + TabModel currentModel = mActivityTestRule.getActivity().getCurrentTabModel(); + for (int i = 0; i < currentModel.getCount(); i++) { + Tab tab = currentModel.getTabAt(i); + Bitmap bitmap = TabContentManager.getJpegForTab(tab); + bitmap = Bitmap.createScaledBitmap( + bitmap, bitmap.getWidth(), (int) (bitmap.getWidth() * 1.0 / 0.75), false); + encodeJpeg(tab, bitmap); + } + } + + private void encodeJpeg(Tab tab, Bitmap bitmap) throws IOException { + FileOutputStream outputStream = + new FileOutputStream(TabContentManager.getTabThumbnailFileJpeg(tab)); + bitmap.compress(Bitmap.CompressFormat.JPEG, 50, outputStream); + outputStream.close(); + Bitmap decodedBitmap = TabContentManager.getJpegForTab(tab); + } + + private void verifyAllThumbnailHasAspectRatio(double ratio) { + TabModel currentModel = mActivityTestRule.getActivity().getCurrentTabModel(); + for (int i = 0; i < currentModel.getCount(); i++) { + Tab tab = currentModel.getTabAt(i); + Bitmap bitmap = TabContentManager.getJpegForTab(tab); + double bitmapRatio = bitmap.getWidth() * 1.0 / bitmap.getHeight(); + assertTrue("Actual ratio: " + bitmapRatio + "; Expected ratio: " + ratio, + Math.abs(bitmapRatio - ratio) <= TabContentManager.ASPECT_RATIO_PRECISION); + } + } }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/NewTabTileMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/NewTabTileMediator.java index 4670555a..38a9306 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/NewTabTileMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/NewTabTileMediator.java
@@ -6,7 +6,9 @@ import static org.chromium.chrome.browser.tasks.tab_management.NewTabTileViewProperties.IS_INCOGNITO; +import org.chromium.base.MathUtils; import org.chromium.base.metrics.RecordUserAction; +import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabCreatorManager; import org.chromium.chrome.browser.tabmodel.TabModel; @@ -25,7 +27,10 @@ TabCreatorManager tabCreatorManager) { mTabModelSelector = tabModelSelector; - model.set(NewTabTileViewProperties.THUMBNAIL_ASPECT_RATIO, 1.0f); + float aspectRatio = (float) ChromeFeatureList.getFieldTrialParamByFeatureAsDouble( + ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID, "thumbnail_aspect_ratio", 1.0); + aspectRatio = MathUtils.clamp(aspectRatio, 0.5f, 2.0f); + model.set(NewTabTileViewProperties.THUMBNAIL_ASPECT_RATIO, aspectRatio); model.set(NewTabTileViewProperties.CARD_HEIGHT_INTERCEPT, 0); model.set(NewTabTileViewProperties.ON_CLICK_LISTENER, view -> { tabCreatorManager.getTabCreator(tabModelSelector.isIncognitoSelected()).launchNTP();
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java index 5ef52a36..50e6207 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java
@@ -24,6 +24,8 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.Callback; +import org.chromium.base.MathUtils; +import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.flags.FeatureUtilities; import org.chromium.chrome.tab_ui.R; import org.chromium.ui.modelutil.PropertyKey; @@ -234,15 +236,12 @@ TabListMediator.ThumbnailFetcher fetcher = model.get(TabProperties.THUMBNAIL_FETCHER); ImageView thumbnail = (ImageView) view.fastFindViewById(R.id.tab_thumbnail); if (fetcher == null) { - // Release the thumbnail to save memory. - thumbnail.setImageDrawable(null); - thumbnail.setMinimumHeight(thumbnail.getWidth()); + releaseThumbnail(thumbnail); return; } Callback<Bitmap> callback = result -> { if (result == null) { - thumbnail.setImageDrawable(null); - thumbnail.setMinimumHeight(thumbnail.getWidth()); + releaseThumbnail(thumbnail); } else { thumbnail.setImageBitmap(result); } @@ -250,6 +249,23 @@ fetcher.fetch(callback); } + private static void releaseThumbnail(ImageView thumbnail) { + if (FeatureUtilities.isTabThumbnailAspectRatioNotOne()) { + float expectedThumbnailAspectRatio = + (float) ChromeFeatureList.getFieldTrialParamByFeatureAsDouble( + ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID, "thumbnail_aspect_ratio", + 1.0); + expectedThumbnailAspectRatio = + MathUtils.clamp(expectedThumbnailAspectRatio, 0.5f, 2.0f); + int height = (int) (thumbnail.getWidth() * 1.0 / expectedThumbnailAspectRatio); + thumbnail.setMinimumHeight(Math.min(thumbnail.getHeight(), height)); + thumbnail.setImageDrawable(null); + } else { + thumbnail.setImageDrawable(null); + thumbnail.setMinimumHeight(thumbnail.getWidth()); + } + } + private static void updateColor(ViewLookupCachingFrameLayout rootView, boolean isIncognito, @TabProperties.UiType int viewType) { View cardView = rootView.fastFindViewById(R.id.card_view);
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiMediator.java index 4f70e4d..424370c 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiMediator.java
@@ -179,6 +179,7 @@ (TabGroupModelFilter) mTabModelSelector.getTabModelFilterProvider() .getCurrentTabModelFilter(); Tab currentTab = mTabModelSelector.getCurrentTab(); + if (currentTab == null) return false; List<Tab> tabgroup = filter.getRelatedTabList(currentTab.getId()); return tabgroup.size() > 1; }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java index 71c28da..cf4ca342 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java
@@ -22,7 +22,9 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import org.chromium.base.MathUtils; import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.flags.FeatureUtilities; import org.chromium.chrome.browser.lifecycle.Destroyable; import org.chromium.chrome.browser.profiles.Profile; @@ -147,8 +149,20 @@ ViewLookupCachingFrameLayout root = (ViewLookupCachingFrameLayout) holder.itemView; ImageView thumbnail = (ImageView) root.fastFindViewById(R.id.tab_thumbnail); if (thumbnail == null) return; - thumbnail.setImageDrawable(null); - thumbnail.setMinimumHeight(thumbnail.getWidth()); + if (FeatureUtilities.isTabThumbnailAspectRatioNotOne()) { + float expectedThumbnailAspectRatio = + (float) ChromeFeatureList.getFieldTrialParamByFeatureAsDouble( + ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID, + "thumbnail_aspect_ratio", 1.0); + expectedThumbnailAspectRatio = + MathUtils.clamp(expectedThumbnailAspectRatio, 0.5f, 2.0f); + int height = (int) (thumbnail.getWidth() * 1.0 / expectedThumbnailAspectRatio); + thumbnail.setMinimumHeight(Math.min(thumbnail.getHeight(), height)); + thumbnail.setImageDrawable(null); + } else { + thumbnail.setImageDrawable(null); + thumbnail.setMinimumHeight(thumbnail.getWidth()); + } }; } else if (mMode == TabListMode.STRIP) { mAdapter.registerType(UiType.STRIP, () -> {
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java index 8bb783bd..90909ad 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java
@@ -28,6 +28,7 @@ import org.junit.runner.RunWith; import org.chromium.base.Callback; +import org.chromium.chrome.browser.flags.FeatureUtilities; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.widget.selection.SelectionDelegate; import org.chromium.chrome.tab_ui.R; @@ -117,6 +118,7 @@ @Override public void setUpTest() throws Exception { super.setUpTest(); + FeatureUtilities.enableTabThumbnailAspectRatioForTesting(false); ViewGroup view = new LinearLayout(getActivity()); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); @@ -486,6 +488,7 @@ mStripMCP.destroy(); mGridMCP.destroy(); mSelectableMCP.destroy(); + FeatureUtilities.enableTabThumbnailAspectRatioForTesting(null); super.tearDownTest(); } }
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiMediatorUnitTest.java index 246e0de..49f4ee4 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiMediatorUnitTest.java
@@ -436,6 +436,19 @@ } @Test + public void testNoCurrentTab_NotShow() { + // Mock overview mode is hiding, and current tab is null. + doReturn(null).when(mTabModelSelector).getCurrentTab(); + mOverviewModeObserverCaptor.getValue().onOverviewModeFinishedHiding(); + assertThat(mMediator.getIsOverviewModeVisibleForTesting(), equalTo(false)); + assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(false)); + + mMediator.maybeShowTabStrip(); + + assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(false)); + } + + @Test public void testDestroy() { mMediator.destroy(); verify(mKeyboardVisibilityDelegate)
diff --git a/chrome/android/java/res/xml/autofill_server_profile_preferences.xml b/chrome/android/java/res/xml/autofill_server_profile_preferences.xml index 5643ac3..87156eeb 100644 --- a/chrome/android/java/res/xml/autofill_server_profile_preferences.xml +++ b/chrome/android/java/res/xml/autofill_server_profile_preferences.xml
@@ -9,9 +9,7 @@ android:key="server_profile_description" android:selectable="false" /> - <org.chromium.chrome.browser.settings.TextAndButtonPreference - android:key="server_profile_edit_link" - android:widgetLayout="@layout/autofill_server_data_edit_link" - android:title="@string/autofill_from_google_account_long" /> + <org.chromium.chrome.browser.settings.autofill.AutofillEditLinkPreference + android:key="server_profile_edit_link" /> </PreferenceScreen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabCoordinator.java index 5b9fc4d..7e89f9c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabCoordinator.java
@@ -20,6 +20,7 @@ import org.chromium.chrome.browser.favicon.FaviconHelper; import org.chromium.chrome.browser.favicon.FaviconUtils; import org.chromium.chrome.browser.favicon.RoundedIconGenerator; +import org.chromium.chrome.browser.feature_engagement.TrackerFactory; import org.chromium.chrome.browser.ntp.NewTabPage; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.ssl.SecurityStateModel; @@ -30,6 +31,8 @@ import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetController.SheetState; import org.chromium.chrome.browser.widget.bottomsheet.EmptyBottomSheetObserver; import org.chromium.components.embedder_support.view.ContentView; +import org.chromium.components.feature_engagement.EventConstants; +import org.chromium.components.feature_engagement.Tracker; import org.chromium.components.security_state.ConnectionSecurityLevel; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.NavigationHandle; @@ -124,6 +127,8 @@ getContent().getWebContents(), (ContentView) getContent().getContainerView()); mSheetContent.updateTitle(title); mBottomSheetController.requestShowContent(mSheetContent, true); + Tracker tracker = TrackerFactory.getTrackerForProfile(Profile.getLastUsedProfile()); + if (tracker.isInitialized()) tracker.notifyEvent(EventConstants.EPHEMERAL_TAB_USED); // TODO(donnd): Collect UMA with OverlayPanel.StateChangeReason.CLICK. }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java index 12e184fa..d9bed9b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java
@@ -21,6 +21,7 @@ import org.chromium.base.Callback; import org.chromium.base.CommandLine; +import org.chromium.base.MathUtils; import org.chromium.base.PathUtils; import org.chromium.base.ThreadUtils; import org.chromium.base.TraceEvent; @@ -30,6 +31,7 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.task.AsyncTask; import org.chromium.chrome.R; +import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.flags.FeatureUtilities; import org.chromium.chrome.browser.native_page.FrozenNativePage; @@ -44,7 +46,9 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; /** * The TabContentManager is responsible for serving tab contents to the UI components. Contents @@ -61,10 +65,15 @@ int GOT_JPEG = 0; int GOT_ETC1 = 1; int GOT_NOTHING = 2; - int NUM_ENTRIES = 3; + int GOT_DIFFERENT_ASPECT_RATIO_JPEG = 3; + int NUM_ENTRIES = 4; } - private static final String UMA_THUMBNAIL_FETCHING_RESULT = + public static final double ASPECT_RATIO_PRECISION = 0.01; + + @VisibleForTesting + public static final String UMA_THUMBNAIL_FETCHING_RESULT = "GridTabSwitcher.ThumbnailFetchingResult"; + private Set<Integer> mRefectchedTabIds; private final float mThumbnailScale; private final int mFullResThumbnailsMaxSize; @@ -87,6 +96,7 @@ private int mOnTheFlyRequests; private int mRequests; private int mNumOfThumbnailsForLastThumbnail; + private float mExpectedThumbnailAspectRatio; /** * The Java interface for listening to thumbnail changes. @@ -173,6 +183,17 @@ mPriorityTabIds = new int[mFullResThumbnailsMaxSize]; + if (FeatureUtilities.isTabThumbnailAspectRatioNotOne() + || FeatureUtilities.isAllowToRefetchTabThumbnail()) { + mRefectchedTabIds = new HashSet<>(); + mExpectedThumbnailAspectRatio = + (float) ChromeFeatureList.getFieldTrialParamByFeatureAsDouble( + ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID, "thumbnail_aspect_ratio", + 1.0); + mExpectedThumbnailAspectRatio = + MathUtils.clamp(mExpectedThumbnailAspectRatio, 0.5f, 2.0f); + } + mNativeTabContentManager = TabContentManagerJni.get().init(TabContentManager.this, defaultCacheSize, approximationCacheSize, compressionQueueMaxSize, writeQueueMaxSize, useApproximationThumbnails, saveJpegThumbnails); @@ -182,6 +203,7 @@ * Destroy the native component. */ public void destroy() { + if (mRefectchedTabIds != null) mRefectchedTabIds.clear(); if (mNativeTabContentManager != 0) { TabContentManagerJni.get().destroy(mNativeTabContentManager); mNativeTabContentManager = 0; @@ -379,6 +401,13 @@ } } + @VisibleForTesting + public static Bitmap getJpegForTab(Tab tab) { + File file = getTabThumbnailFileJpeg(tab); + if (!file.isFile()) return null; + return BitmapFactory.decodeFile(file.getPath()); + } + private void getTabThumbnailFromDisk(@NonNull Tab tab, @NonNull Callback<Bitmap> callback) { mOnTheFlyRequests++; mRequests++; @@ -388,9 +417,7 @@ new AsyncTask<Bitmap>() { @Override public Bitmap doInBackground() { - File file = getTabThumbnailFileJpeg(tab); - if (!file.isFile()) return null; - return BitmapFactory.decodeFile(file.getPath()); + return getJpegForTab(tab); } @Override @@ -403,8 +430,29 @@ notifyOnLastThumbnail(); } if (jpeg != null) { + if (FeatureUtilities.isAllowToRefetchTabThumbnail()) { + double jpegAspectRatio = jpeg.getHeight() == 0 + ? 0 + : 1.0 * jpeg.getWidth() / jpeg.getHeight(); + // Retry fetching thumbnail once for all tabs that are: + // * Thumbnail's aspect ratio is different from the expected ratio. + if (!mRefectchedTabIds.contains(tab.getId()) + && Math.abs(jpegAspectRatio - mExpectedThumbnailAspectRatio) + >= ASPECT_RATIO_PRECISION) { + RecordHistogram.recordEnumeratedHistogram(UMA_THUMBNAIL_FETCHING_RESULT, + ThumbnailFetchingResult.GOT_DIFFERENT_ASPECT_RATIO_JPEG, + ThumbnailFetchingResult.NUM_ENTRIES); + mRefectchedTabIds.add(tab.getId()); + if (mNativeTabContentManager == 0 || !mSnapshotsEnabled) return; + TabContentManagerJni.get().getEtc1TabThumbnail(mNativeTabContentManager, + TabContentManager.this, tab.getId(), + (etc1) -> callback.onResult(etc1)); + return; + } + } RecordHistogram.recordEnumeratedHistogram(UMA_THUMBNAIL_FETCHING_RESULT, ThumbnailFetchingResult.GOT_JPEG, ThumbnailFetchingResult.NUM_ENTRIES); + callback.onResult(jpeg); return; } @@ -480,7 +528,11 @@ Matrix matrix = new Matrix(); matrix.setScale(downsamplingScale, downsamplingScale); Bitmap resized = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), - min(bitmap.getWidth(), bitmap.getHeight()), matrix, true); + FeatureUtilities.isTabThumbnailAspectRatioNotOne() + ? Math.min(bitmap.getHeight(), + (int) (bitmap.getWidth() * 1.0 / mExpectedThumbnailAspectRatio)) + : min(bitmap.getWidth(), bitmap.getHeight()), + matrix, true); callback.onResult(resized); } else { if (tab.getWebContents() == null) return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java index 00e8b9e..e24c377 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java
@@ -133,6 +133,9 @@ private final @Item int mItem; + // If set to true, adds a "New" superscript label to the menu string. + private boolean mShowNewLabel; + public ChromeContextMenuItem(@Item int item) { mItem = item; } @@ -143,6 +146,11 @@ return MENU_IDS[mItem]; } + @Override + public void setShowInProductHelp() { + mShowNewLabel = true; + } + /** * Get string ID from the ID of the item. * @param item #Item Item ID. @@ -194,10 +202,7 @@ */ private CharSequence addOrRemoveNewLabel(Context context, String prefKey) { String menuTitle = context.getString(getStringId(mItem)); - - // TODO(jinsukkim): Consider removing the preference keys and hooking this up to - // the feature engagement system. - if (SharedPreferencesManager.getInstance().readBoolean(prefKey, false)) { + if (!mShowNewLabel || SharedPreferencesManager.getInstance().readBoolean(prefKey, false)) { return SpanApplier.removeSpanText(menuTitle, new SpanInfo("<new>", "</new>")); } return SpanApplier.applySpans(menuTitle,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java index cfbd687..0163ba4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
@@ -13,6 +13,7 @@ import android.webkit.URLUtil; import androidx.annotation.IntDef; +import androidx.annotation.VisibleForTesting; import org.chromium.base.library_loader.LibraryProcessType; import org.chromium.base.metrics.RecordHistogram; @@ -20,15 +21,19 @@ import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.compositor.bottombar.ephemeraltab.EphemeralTabPanel; import org.chromium.chrome.browser.contextmenu.ChromeContextMenuItem.Item; +import org.chromium.chrome.browser.feature_engagement.TrackerFactory; import org.chromium.chrome.browser.firstrun.FirstRunStatus; import org.chromium.chrome.browser.locale.LocaleManager; import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory; import org.chromium.chrome.browser.share.LensUtils; import org.chromium.chrome.browser.share.ShareDelegate; import org.chromium.chrome.browser.share.ShareParams; import org.chromium.chrome.browser.util.UrlUtilities; +import org.chromium.components.feature_engagement.FeatureConstants; +import org.chromium.components.feature_engagement.Tracker; import org.chromium.components.search_engines.TemplateUrlService; import org.chromium.components.url_formatter.UrlFormatter; import org.chromium.content_public.browser.BrowserStartupController; @@ -51,6 +56,9 @@ private final ShareDelegate mShareDelegate; private boolean mEnableLensWithSearchByImageText; + // True when the tracker indicates IPH in the form of "new" label needs to be shown. + private Boolean mShowEphemeralTabNewLabel; + /** * Defines the Groups of each Context Menu Item */ @@ -297,6 +305,7 @@ public List<Pair<Integer, List<ContextMenuItem>>> buildContextMenu( ContextMenu menu, Context context, ContextMenuParams params) { boolean hasSaveImage = false; + mShowEphemeralTabNewLabel = null; // clang-format off List<Pair<Integer, List<ContextMenuItem>>> groupedItems = new ArrayList<>(); @@ -315,7 +324,10 @@ linkTab.add(new ChromeContextMenuItem(Item.OPEN_IN_OTHER_WINDOW)); } if (EphemeralTabPanel.isSupported()) { - linkTab.add(new ChromeContextMenuItem(Item.OPEN_IN_EPHEMERAL_TAB)); + ContextMenuItem item = new ChromeContextMenuItem(Item.OPEN_IN_EPHEMERAL_TAB); + mShowEphemeralTabNewLabel = shouldTriggerEphemeralTabHelpUi(); + if (mShowEphemeralTabNewLabel) item.setShowInProductHelp(); + linkTab.add(item); } } if (!MailTo.isMailTo(params.getLinkUrl()) @@ -375,7 +387,13 @@ imageTab.add(new ChromeContextMenuItem(Item.OPEN_IMAGE_IN_NEW_TAB)); } if (EphemeralTabPanel.isSupported()) { - imageTab.add(new ChromeContextMenuItem(Item.OPEN_IMAGE_IN_EPHEMERAL_TAB)); + ContextMenuItem item = + new ChromeContextMenuItem(Item.OPEN_IMAGE_IN_EPHEMERAL_TAB); + if (mShowEphemeralTabNewLabel == null) { + mShowEphemeralTabNewLabel = shouldTriggerEphemeralTabHelpUi(); + } + if (mShowEphemeralTabNewLabel) item.setShowInProductHelp(); + imageTab.add(item); } if (isSrcDownloadableScheme) { imageTab.add(new ChromeContextMenuItem(Item.SAVE_IMAGE)); @@ -398,8 +416,10 @@ mEnableLensWithSearchByImageText = true; imageTab.add(new ChromeContextMenuItem(Item.SEARCH_BY_IMAGE)); } else { - imageTab.add( - new ChromeContextMenuItem(Item.SEARCH_WITH_GOOGLE_LENS)); + ContextMenuItem item = + new ChromeContextMenuItem(Item.SEARCH_WITH_GOOGLE_LENS); + item.setShowInProductHelp(); + imageTab.add(item); } } else { imageTab.add(new ChromeContextMenuItem(Item.SEARCH_BY_IMAGE)); @@ -472,6 +492,13 @@ return groupedItems; } + @VisibleForTesting + boolean shouldTriggerEphemeralTabHelpUi() { + Tracker tracker = TrackerFactory.getTrackerForProfile(Profile.getLastUsedProfile()); + return tracker.isInitialized() + && tracker.shouldTriggerHelpUI(FeatureConstants.EPHEMERAL_TAB_FEATURE); + } + @Override public boolean onItemSelected(ContextMenuHelper helper, ContextMenuParams params, int itemId) { if (itemId == R.id.contextmenu_open_in_new_tab) { @@ -486,9 +513,6 @@ } else if (itemId == R.id.contextmenu_open_in_ephemeral_tab) { ContextMenuUma.record(params, ContextMenuUma.Action.OPEN_IN_EPHEMERAL_TAB); mDelegate.onOpenInEphemeralTab(params.getUrl(), params.getLinkText()); - SharedPreferencesManager prefManager = SharedPreferencesManager.getInstance(); - prefManager.writeBoolean( - ChromePreferenceKeys.CONTEXT_MENU_OPEN_IN_EPHEMERAL_TAB_CLICKED, true); } else if (itemId == R.id.contextmenu_open_image) { ContextMenuUma.record(params, ContextMenuUma.Action.OPEN_IMAGE); mDelegate.onOpenImageUrl(params.getSrcUrl(), params.getReferrer()); @@ -502,9 +526,6 @@ title = URLUtil.guessFileName(params.getSrcUrl(), null, null); } mDelegate.onOpenInEphemeralTab(params.getSrcUrl(), title); - SharedPreferencesManager prefManager = SharedPreferencesManager.getInstance(); - prefManager.writeBoolean( - ChromePreferenceKeys.CONTEXT_MENU_OPEN_IMAGE_IN_EPHEMERAL_TAB_CLICKED, true); } else if (itemId == R.id.contextmenu_copy_link_address) { ContextMenuUma.record(params, ContextMenuUma.Action.COPY_LINK_ADDRESS); mDelegate.onSaveToClipboard( @@ -599,6 +620,14 @@ return true; } + @Override + public void onMenuClosed() { + if (!mShowEphemeralTabNewLabel) return; + Tracker tracker = TrackerFactory.getTrackerForProfile(Profile.getLastUsedProfile()); + if (!tracker.isInitialized()) return; + tracker.dismissed(FeatureConstants.EPHEMERAL_TAB_FEATURE); + } + /** * @return The service that handles TemplateUrls. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java index 46b54e0..d20aacdb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java
@@ -145,6 +145,7 @@ }; mOnMenuClosed = (notAbandoned) -> { recordTimeToTakeActionHistogram(mSelectedItemBeforeDismiss || notAbandoned); + mPopulator.onMenuClosed(); if (mNativeContextMenuHelper == 0) return; ContextMenuHelperJni.get().onContextMenuClosed( mNativeContextMenuHelper, ContextMenuHelper.this);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItem.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItem.java index 987ad65..21e18c5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItem.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItem.java
@@ -24,4 +24,9 @@ * @return The title of the menu item. */ CharSequence getTitle(Context context); + + /** + * Turn on a flag indicating the menu item should show an in-product help label. + */ + default void setShowInProductHelp() {} }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuPopulator.java index 9e328c3..acaf6688 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuPopulator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuPopulator.java
@@ -42,4 +42,9 @@ * @return Whether or not the selection was handled. */ public boolean onItemSelected(ContextMenuHelper helper, ContextMenuParams params, int itemId); -} \ No newline at end of file + + /** + * Called when the context menu is closed. + */ + public void onMenuClosed(); +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/flags/FeatureUtilities.java b/chrome/android/java/src/org/chromium/chrome/browser/flags/FeatureUtilities.java index a6df8c4..105a229a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/flags/FeatureUtilities.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/flags/FeatureUtilities.java
@@ -64,6 +64,7 @@ private static Map<String, Boolean> sFlags = new HashMap<>(); private static Boolean sHasRecognitionIntentHandler; private static String sReachedCodeProfilerTrialGroup; + private static Boolean sEnabledTabThumbnailApsectRatioForTesting; /** * Determines whether or not the {@link RecognizerIntent#ACTION_WEB_SEARCH} {@link Intent} @@ -713,6 +714,31 @@ } /** + * @return Whether the thumbnail_aspect_ratio field trail is set. + */ + public static boolean isTabThumbnailAspectRatioNotOne() { + if (sEnabledTabThumbnailApsectRatioForTesting != null) { + return sEnabledTabThumbnailApsectRatioForTesting; + } + + double expectedAspectRatio = ChromeFeatureList.getFieldTrialParamByFeatureAsDouble( + ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID, "thumbnail_aspect_ratio", 1.0); + return Double.compare(1.0, expectedAspectRatio) != 0; + } + + /** + * @return Whether to allow to refetch tab thumbnail if the aspect ratio is not matching. + */ + public static boolean isAllowToRefetchTabThumbnail() { + return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean( + ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID, "allow_to_refetch", false); + } + + public static void enableTabThumbnailAspectRatioForTesting(Boolean enabled) { + sEnabledTabThumbnailApsectRatioForTesting = enabled; + } + + /** * Expose an interface to set the homepage policy feature flag to be enabled during tests. */ @VisibleForTesting
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/TextAndButtonPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/TextAndButtonPreference.java deleted file mode 100644 index b59048b..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/settings/TextAndButtonPreference.java +++ /dev/null
@@ -1,45 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.settings; - -import android.content.Context; -import android.support.v7.preference.Preference; -import android.support.v7.preference.PreferenceViewHolder; -import android.util.AttributeSet; -import android.view.View; - -import org.chromium.chrome.R; - -/** - * A {@link Preference} that provides label text plus button functionality. - * - * Preference.getOnPreferenceClickListener().onPreferenceClick() is called when the button is - * clicked. The button is defined by the widgetLayout attribute. - */ -public class TextAndButtonPreference extends Preference { - /** - * Constructor for inflating from XML - */ - public TextAndButtonPreference(Context context, AttributeSet attrs) { - super(context, attrs); - setSelectable(false); - } - - @Override - public void onBindViewHolder(PreferenceViewHolder holder) { - super.onBindViewHolder(holder); - - View button = holder.findViewById(R.id.preference_click_target); - button.setClickable(true); - button.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (getOnPreferenceClickListener() != null) { - getOnPreferenceClickListener().onPreferenceClick(TextAndButtonPreference.this); - } - } - }); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/autofill/AutofillEditLinkPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/autofill/AutofillEditLinkPreference.java new file mode 100644 index 0000000..8a88773 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/autofill/AutofillEditLinkPreference.java
@@ -0,0 +1,43 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.settings.autofill; + +import android.content.Context; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceViewHolder; +import android.util.AttributeSet; +import android.view.View; + +import org.chromium.chrome.R; + +/** + * A {@link Preference} that provides a clickable edit link as a widget. + * + * {@link OnPreferenceClickListener} is called when the link is clicked. + */ +public class AutofillEditLinkPreference extends Preference { + /** + * Constructor for inflating from XML. + */ + public AutofillEditLinkPreference(Context context, AttributeSet attrs) { + super(context, attrs); + setSelectable(false); + setWidgetLayoutResource(R.layout.autofill_server_data_edit_link); + setTitle(R.string.autofill_from_google_account_long); + } + + @Override + public void onBindViewHolder(PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + + View button = holder.findViewById(R.id.preference_click_target); + button.setClickable(true); + button.setOnClickListener(v -> { + if (getOnPreferenceClickListener() != null) { + getOnPreferenceClickListener().onPreferenceClick(AutofillEditLinkPreference.this); + } + }); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncNotificationController.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncNotificationController.java index 33e001e8..d38a547e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncNotificationController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncNotificationController.java
@@ -9,6 +9,8 @@ import android.os.Build; import android.util.Log; +import androidx.annotation.StringRes; + import org.chromium.base.ContextUtils; import org.chromium.base.ThreadUtils; import org.chromium.chrome.R; @@ -89,14 +91,21 @@ CoreAccountInfo primaryAccountInfo = IdentityServicesProvider.get().getIdentityManager().getPrimaryAccountInfo(); if (primaryAccountInfo != null) { - Intent intent = - TrustedVaultClient.get().createKeyRetrievalIntent(primaryAccountInfo); - if (intent != null) { - showSyncNotification(mProfileSyncService.isEncryptEverythingEnabled() - ? R.string.sync_error_card_title - : R.string.sync_passwords_error_card_title, - intent); - } + int flags = Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP; + TrustedVaultClient.get() + .createKeyRetrievalIntent(primaryAccountInfo) + .then( + (pendingIntent) + -> { + showSyncNotificationForPendingIntent( + mProfileSyncService.isEncryptEverythingEnabled() + ? R.string.sync_error_card_title + : R.string.sync_passwords_error_card_title, + new PendingIntentProvider(pendingIntent, flags)); + }, + (exception) -> { + Log.w(TAG, "Error creating key retrieval intent: ", exception); + }); } } else { mNotificationManager.cancel(NotificationConstants.NOTIFICATION_ID_SYNC); @@ -108,9 +117,10 @@ * Builds and shows a notification for the |message|. * * @param message Resource id of the message to display in the notification. - * @param intent Intent to send when the user activates the notification. + * @param contentIntent represents intent to send when the user activates the notification. */ - private void showSyncNotification(int message, Intent intent) { + private void showSyncNotificationForPendingIntent( + @StringRes int message, PendingIntentProvider contentIntent) { Context applicationContext = ContextUtils.getApplicationContext(); String title = null; String text = null; @@ -125,9 +135,6 @@ + applicationContext.getString(message); } - PendingIntentProvider contentIntent = - PendingIntentProvider.getActivity(applicationContext, 0, intent, 0); - // There is no need to provide a group summary notification because the NOTIFICATION_ID_SYNC // notification id ensures there's only one sync notification at a time. ChromeNotificationBuilder builder = @@ -153,6 +160,19 @@ NotificationUmaTracker.SystemNotificationType.SYNC, notification.getNotification()); } + /** + * Builds and shows a notification for the |message|. + * + * @param message Resource id of the message to display in the notification. + * @param intent Intent to send when the user activates the notification. + */ + private void showSyncNotification(@StringRes int message, Intent intent) { + Context applicationContext = ContextUtils.getApplicationContext(); + PendingIntentProvider contentIntent = + PendingIntentProvider.getActivity(applicationContext, 0, intent, 0); + showSyncNotificationForPendingIntent(message, contentIntent); + } + private boolean shouldSyncAuthErrorBeShown() { switch (mProfileSyncService.getAuthError()) { case State.NONE:
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/TrustedVaultClient.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/TrustedVaultClient.java index 8fee1d4..e706aeb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/TrustedVaultClient.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/TrustedVaultClient.java
@@ -4,17 +4,16 @@ package org.chromium.chrome.browser.sync; -import android.content.Context; -import android.content.Intent; +import android.app.Activity; +import android.app.PendingIntent; -import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import org.chromium.base.Log; import org.chromium.base.Promise; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.NativeMethods; import org.chromium.chrome.browser.AppHooks; -import org.chromium.chrome.browser.util.IntentUtils; import org.chromium.components.signin.base.CoreAccountInfo; import java.util.Collections; @@ -39,14 +38,14 @@ Promise<List<byte[]>> fetchKeys(CoreAccountInfo accountInfo); /** - * Gets an Intent that can be used to display a UI that allows the user to reauthenticate - * and retrieve the sync encryption keys. + * Gets a PendingIntent that can be used to display a UI that allows the user to + * reauthenticate and retrieve the sync encryption keys. * * @param accountInfo Account representing the user. - * @return the Intent object or null is something went wrong. + * @return a promise for a PendingIntent object. The promise will be rejected if no + * retrieval is actually required. */ - @Nullable - Intent createKeyRetrievalIntent(CoreAccountInfo accountInfo); + Promise<PendingIntent> createKeyRetrievalIntent(CoreAccountInfo accountInfo); /** * Invoked when the result of fetchKeys() represents keys that cannot decrypt Nigori, which @@ -69,8 +68,8 @@ } @Override - public Intent createKeyRetrievalIntent(CoreAccountInfo accountInfo) { - return null; + public Promise<PendingIntent> createKeyRetrievalIntent(CoreAccountInfo accountInfo) { + return Promise.rejected(); } @Override @@ -79,6 +78,8 @@ } }; + private static final String TAG = "TrustedVaultClient"; + private static TrustedVaultClient sInstance; private final Backend mBackend; @@ -106,28 +107,35 @@ /** * Displays a UI that allows the user to reauthenticate and retrieve the sync encryption keys. * - * @param context Context to use when starting the dialog activity. + * @param activity Activity to use when starting the dialog. * @param accountInfo Account representing the user. */ - public void displayKeyRetrievalDialog(Context context, CoreAccountInfo accountInfo) { - Intent intent = createKeyRetrievalIntent(accountInfo); - if (intent == null) return; - - IntentUtils.safeStartActivity(context, intent); - - // TODO(crbug.com/1012659): Upon intent completion, the new keys should - // fetched. + public void displayKeyRetrievalDialog(Activity activity, CoreAccountInfo accountInfo) { + createKeyRetrievalIntent(accountInfo) + .then( + (pendingIntent) + -> { + try { + // TODO(crbug.com/1012659): Upon intent completion, the new keys + // should be fetched. + pendingIntent.send(activity, 0, null, null, null, null, null); + } catch (PendingIntent.CanceledException exception) { + Log.w(TAG, "Error sending key retrieval intent: ", exception); + } + }, + (exception) -> { + Log.e(TAG, "Error opening key retrieval dialog: ", exception); + }); } /** * Creates an intent that launches an activity that triggers the key retrieval UI. * * @param accountInfo Account representing the user. - * @return the intent for opening the key retrieval activity or null if none is actually - * required + * @return a promise with the intent for opening the key retrieval activity. The promise will be + * rejected if no retrieval is actually required. */ - @Nullable - public Intent createKeyRetrievalIntent(CoreAccountInfo accountInfo) { + public Promise<PendingIntent> createKeyRetrievalIntent(CoreAccountInfo accountInfo) { return mBackend.createKeyRetrievalIntent(accountInfo); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuPopulator.java index 0ea0a9e8a..541dde6d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuPopulator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuPopulator.java
@@ -60,4 +60,7 @@ public boolean onItemSelected(ContextMenuHelper helper, ContextMenuParams params, int itemId) { return mPopulator.onItemSelected(helper, params, itemId); } + + @Override + public void onMenuClosed() {} }
diff --git a/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java b/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java index aff68d71..65189449 100644 --- a/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java +++ b/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java
@@ -78,6 +78,7 @@ mPopulator = Mockito.spy(new ChromeContextMenuPopulator(mItemDelegate, mShareDelegate, mode)); doReturn(mTemplateUrlService).when(mPopulator).getTemplateUrlService(); + doReturn(false).when(mPopulator).shouldTriggerEphemeralTabHelpUi(); } private void checkMenuOptions(ContextMenuParams params, int[]... tabs) {
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index d005c70c..fb2eedd 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -1206,17 +1206,49 @@ }; const FeatureEntry::FeatureParam kTabGridLayoutAndroid_NewTabVariation[] = { - {"tab_grid_layout_android_new_tab", "NewTabVariation"}}; + {"tab_grid_layout_android_new_tab", "NewTabVariation"}, + {"allow_to_refetch", "true"}}; const FeatureEntry::FeatureParam kTabGridLayoutAndroid_NewTabTile[] = { {"tab_grid_layout_android_new_tab_tile", "NewTabTile"}}; +const FeatureEntry::FeatureParam + kTabGridLayoutAndroid_ThumbnailAspectRatio_2[] = { + {"thumbnail_aspect_ratio", "2.0"}, + {"allow_to_refetch", "true"}}; + +const FeatureEntry::FeatureParam + kTabGridLayoutAndroid_ThumbnailAspectRatio_three_quarter[] = { + {"thumbnail_aspect_ratio", "0.75"}, + {"allow_to_refetch", "true"}}; + +const FeatureEntry::FeatureParam + kTabGridLayoutAndroid_ThumbnailAspectRatio_half[] = { + {"thumbnail_aspect_ratio", "0.5"}, + {"allow_to_refetch", "true"}}; + +const FeatureEntry::FeatureParam kTabGridLayoutAndroid_DisableRefetch[] = { + {"allow_to_refetch", "false"}}; + const FeatureEntry::FeatureVariation kTabGridLayoutAndroidVariations[] = { {"New Tab Variation", kTabGridLayoutAndroid_NewTabVariation, base::size(kTabGridLayoutAndroid_NewTabVariation), nullptr}, {"New Tab Tile", kTabGridLayoutAndroid_NewTabTile, base::size(kTabGridLayoutAndroid_NewTabTile), nullptr}, + {"thumbnail aspect ratio - 2:1", + kTabGridLayoutAndroid_ThumbnailAspectRatio_2, + base::size(kTabGridLayoutAndroid_ThumbnailAspectRatio_2), nullptr}, + {"thumbnail aspect ratio - 1:2", + kTabGridLayoutAndroid_ThumbnailAspectRatio_half, + base::size(kTabGridLayoutAndroid_ThumbnailAspectRatio_half), nullptr}, + {"thumbnail aspect ratio - 3:4", + kTabGridLayoutAndroid_ThumbnailAspectRatio_three_quarter, + base::size(kTabGridLayoutAndroid_ThumbnailAspectRatio_three_quarter), + nullptr}, + {"Disable refetch", kTabGridLayoutAndroid_DisableRefetch, + base::size(kTabGridLayoutAndroid_DisableRefetch), nullptr}, }; + const FeatureEntry::FeatureParam kStartSurfaceAndroid_SingleSurface[] = { {"start_surface_variation", "single"}};
diff --git a/chrome/browser/android/compositor/tab_content_manager.cc b/chrome/browser/android/compositor/tab_content_manager.cc index 75ef317..878e6b3 100644 --- a/chrome/browser/android/compositor/tab_content_manager.cc +++ b/chrome/browser/android/compositor/tab_content_manager.cc
@@ -7,6 +7,7 @@ #include <android/bitmap.h> #include <stddef.h> +#include <algorithm> #include <memory> #include <utility> @@ -17,8 +18,10 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/macros.h" +#include "base/metrics/field_trial_params.h" #include "cc/layers/layer.h" #include "chrome/android/chrome_jni_headers/TabContentManager_jni.h" +#include "chrome/browser/android/chrome_feature_list.h" #include "chrome/browser/android/compositor/layer/thumbnail_layer.h" #include "chrome/browser/android/tab_android.h" #include "chrome/browser/android/thumbnail/thumbnail.h" @@ -51,7 +54,7 @@ public: TabReadbackRequest(content::RenderWidgetHostView* rwhv, float thumbnail_scale, - bool crop_to_square, + bool crop_to_match_aspect_ratio, TabReadbackCallback end_callback) : thumbnail_scale_(thumbnail_scale), end_callback_(std::move(end_callback)), @@ -67,9 +70,14 @@ std::move(result_callback).Run(SkBitmap()); return; } - if (crop_to_square) { - view_size_in_pixels.set_height( - std::min(view_size_in_pixels.height(), view_size_in_pixels.width())); + if (crop_to_match_aspect_ratio) { + double aspect_ratio = base::GetFieldTrialParamByFeatureAsDouble( + chrome::android::kTabGridLayoutAndroid, "thumbnail_aspect_ratio", + 1.0); + aspect_ratio = ThumbnailCache::clampAspectRatio(aspect_ratio, 0.5, 2.0); + int height = std::min(view_size_in_pixels.height(), + (int)(view_size_in_pixels.width() / aspect_ratio)); + view_size_in_pixels.set_height(height); } gfx::Rect source_rect = gfx::Rect(view_size_in_pixels); gfx::Size thumbnail_size( @@ -392,8 +400,13 @@ // It's fine to horizontally center-align thumbnail saved in landscape // mode. int scale = need_downsampling ? 2 : 1; - SkIRect dest_subset = {0, 0, bitmap.width() / scale, - std::min(bitmap.width(), bitmap.height()) / scale}; + double aspect_ratio = base::GetFieldTrialParamByFeatureAsDouble( + chrome::android::kTabGridLayoutAndroid, "thumbnail_aspect_ratio", 1.0); + aspect_ratio = ThumbnailCache::clampAspectRatio(aspect_ratio, 0.5, 2.0); + SkIRect dest_subset = { + 0, 0, bitmap.width() / scale, + std::min(bitmap.height() / scale, + (int)(bitmap.width() / aspect_ratio / scale))}; SkBitmap result_bitmap = skia::ImageOperations::Resize( bitmap, skia::ImageOperations::RESIZE_BETTER, bitmap.width() / scale, bitmap.height() / scale, dest_subset);
diff --git a/chrome/browser/android/headers_classifier.cc b/chrome/browser/android/headers_classifier.cc index e98c9bb..88e4bac 100644 --- a/chrome/browser/android/headers_classifier.cc +++ b/chrome/browser/android/headers_classifier.cc
@@ -3,8 +3,6 @@ // found in the LICENSE file. #include "base/android/jni_string.h" -#include "base/debug/crash_logging.h" -#include "base/debug/dump_without_crashing.h" #include "base/hash/hash.h" #include "base/metrics/histogram_functions.h" #include "base/strings/string_util.h" @@ -28,17 +26,9 @@ return true; if (is_first_party) { - int hash = base::PersistentHash(base::ToLowerASCII(header_name)); - base::UmaHistogramSparse("Android.IntentNonSafelistedHeaderNames", hash); - if (hash == -240302231) { - static base::debug::CrashKeyString* non_safelisted_header_name = - base::debug::AllocateCrashKeyString( - "intent_non_safelisted_header_name", - base::debug::CrashKeySize::Size256); - base::debug::ScopedCrashKeyString(non_safelisted_header_name, - header_name); - base::debug::DumpWithoutCrashing(); - } + base::UmaHistogramSparse( + "Android.IntentNonSafelistedHeaderNames", + base::PersistentHash(base::ToLowerASCII(header_name))); } return false;
diff --git a/chrome/browser/android/thumbnail/thumbnail_cache.cc b/chrome/browser/android/thumbnail/thumbnail_cache.cc index 683e93a..2c13982 100644 --- a/chrome/browser/android/thumbnail/thumbnail_cache.cc +++ b/chrome/browser/android/thumbnail/thumbnail_cache.cc
@@ -14,11 +14,13 @@ #include "base/files/file.h" #include "base/files/file_path.h" #include "base/files/file_util.h" +#include "base/metrics/field_trial_params.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/task/post_task.h" #include "base/time/time.h" #include "build/build_config.h" +#include "chrome/browser/android/chrome_feature_list.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "gpu/config/gpu_finch_features.h" @@ -268,6 +270,10 @@ return GetFilePath(tab_id).AddExtension(".jpeg"); } +double ThumbnailCache::clampAspectRatio(double value, double min, double max) { + return std::max(std::min(value, max), min); +} + bool ThumbnailCache::CheckAndUpdateThumbnailMetaData(TabId tab_id, const GURL& url) { base::Time current_time = base::Time::Now(); @@ -719,8 +725,13 @@ // It's fine to horizontally center-align thumbnail saved in landscape // mode. int scale = 2; - SkIRect dest_subset = {0, 0, bitmap.width() / scale, - std::min(bitmap.width(), bitmap.height()) / scale}; + double aspect_ratio = base::GetFieldTrialParamByFeatureAsDouble( + chrome::android::kTabGridLayoutAndroid, "thumbnail_aspect_ratio", 1.0); + aspect_ratio = clampAspectRatio(aspect_ratio, 0.5, 2.0); + SkIRect dest_subset = { + 0, 0, bitmap.width() / scale, + std::min(bitmap.height() / scale, + (int)(bitmap.width() / scale / aspect_ratio))}; SkBitmap result_bitmap = skia::ImageOperations::Resize( bitmap, skia::ImageOperations::RESIZE_BETTER, bitmap.width() / scale, bitmap.height() / scale, dest_subset);
diff --git a/chrome/browser/android/thumbnail/thumbnail_cache.h b/chrome/browser/android/thumbnail/thumbnail_cache.h index 5c12260..343c2d9 100644 --- a/chrome/browser/android/thumbnail/thumbnail_cache.h +++ b/chrome/browser/android/thumbnail/thumbnail_cache.h
@@ -81,6 +81,7 @@ static base::FilePath GetCacheDirectory(); static base::FilePath GetFilePath(TabId tab_id); static base::FilePath GetJpegFilePath(TabId tab_id); + static double clampAspectRatio(double value, double min, double max); private: class ThumbnailMetaData {
diff --git a/chrome/browser/android/vr/arcore_device/arcore.h b/chrome/browser/android/vr/arcore_device/arcore.h index 288897ba..d5f5221 100644 --- a/chrome/browser/android/vr/arcore_device/arcore.h +++ b/chrome/browser/android/vr/arcore_device/arcore.h
@@ -54,6 +54,9 @@ // Returns information about all anchors tracked in the current frame. virtual mojom::XRAnchorsDataPtr GetAnchorsData() = 0; + // Returns information about lighting estimation. + virtual mojom::XRLightEstimationDataPtr GetLightEstimationData() = 0; + virtual bool RequestHitTest( const mojom::XRRayPtr& ray, std::vector<mojom::XRHitResultPtr>* hit_results) = 0;
diff --git a/chrome/browser/android/vr/arcore_device/arcore_gl.cc b/chrome/browser/android/vr/arcore_device/arcore_gl.cc index e596d96..910555f2 100644 --- a/chrome/browser/android/vr/arcore_device/arcore_gl.cc +++ b/chrome/browser/android/vr/arcore_device/arcore_gl.cc
@@ -427,7 +427,8 @@ gl_thread_task_runner_->PostTask( FROM_HERE, base::BindOnce(&ArCoreGl::ProcessFrame, weak_ptr_factory_.GetWeakPtr(), - base::Passed(&frame_data), base::Passed(&callback))); + std::move(options), std::move(frame_data), + std::move(callback))); } bool ArCoreGl::IsSubmitFrameExpected(int16_t frame_index) { @@ -775,6 +776,7 @@ } void ArCoreGl::ProcessFrame( + mojom::XRFrameDataRequestOptionsPtr options, mojom::XRFrameDataPtr frame_data, mojom::XRFrameDataProvider::GetFrameDataCallback callback) { DVLOG(3) << __func__ << " frame=" << frame_data->frame_id; @@ -799,6 +801,11 @@ // Get anchors data, including anchors created this frame. frame_data->anchors_data = arcore_->GetAnchorsData(); + // Get lighting estimation data + if (options && options->include_lighting_estimation_data) { + frame_data->light_estimation_data = arcore_->GetLightEstimationData(); + } + // The timing requirements for hit-test are documented here: // https://github.com/immersive-web/hit-test/blob/master/explainer.md#timing // The current implementation of frame generation on the renderer side is
diff --git a/chrome/browser/android/vr/arcore_device/arcore_gl.h b/chrome/browser/android/vr/arcore_device/arcore_gl.h index 16615d95..714675f 100644 --- a/chrome/browser/android/vr/arcore_device/arcore_gl.h +++ b/chrome/browser/android/vr/arcore_device/arcore_gl.h
@@ -157,7 +157,8 @@ void Resume(); bool IsSubmitFrameExpected(int16_t frame_index); - void ProcessFrame(mojom::XRFrameDataPtr frame_data, + void ProcessFrame(mojom::XRFrameDataRequestOptionsPtr options, + mojom::XRFrameDataPtr frame_data, mojom::XRFrameDataProvider::GetFrameDataCallback callback); bool InitializeGl(gfx::AcceleratedWidget drawing_widget);
diff --git a/chrome/browser/android/vr/arcore_device/arcore_impl.cc b/chrome/browser/android/vr/arcore_device/arcore_impl.cc index d8888a2b..b474e10c 100644 --- a/chrome/browser/android/vr/arcore_device/arcore_impl.cc +++ b/chrome/browser/android/vr/arcore_device/arcore_impl.cc
@@ -118,6 +118,180 @@ return mojo_from_viewer * viewer_from_pointer; } +void ReleaseArCoreCubemap(ArImageCubemap* cube_map) { + for (auto* image : *cube_map) { + ArImage_release(image); + } + + memset(cube_map, 0, sizeof(*cube_map)); +} + +void CopyArCoreImage_RGBA16F(const ArSession* session, + const ArImage* image, + int32_t plane_index, + std::vector<device::RgbaTupleF16>* out_pixels, + uint32_t* out_width, + uint32_t* out_height) { + // Get source image information + int32_t width = 0, height = 0, src_row_stride = 0, src_pixel_stride = 0; + ArImage_getWidth(session, image, &width); + ArImage_getHeight(session, image, &height); + ArImage_getPlaneRowStride(session, image, plane_index, &src_row_stride); + ArImage_getPlanePixelStride(session, image, plane_index, &src_pixel_stride); + + uint8_t const* src_buffer = nullptr; + int32_t src_buffer_length = 0; + ArImage_getPlaneData(session, image, plane_index, &src_buffer, + &src_buffer_length); + + // Create destination + *out_width = width; + *out_height = height; + out_pixels->resize(width * height); + + // Fast path: Source and destination have the same layout + bool const fast_path = static_cast<size_t>(src_row_stride) == + width * sizeof(device::RgbaTupleF16); + TRACE_EVENT1("xr", "CopyArCoreImage_RGBA16F: memcpy", "fastPath", fast_path); + + // If they have the same layout, we can copy the entire buffer at once + if (fast_path) { + DCHECK_EQ(out_pixels->size() * sizeof(device::RgbaTupleF16), + static_cast<size_t>(src_buffer_length)); + memcpy(out_pixels->data(), src_buffer, src_buffer_length); + return; + } + + // Slow path: copy pixel by pixel, row by row + for (int32_t row = 0; row < height; ++row) { + auto* src = src_buffer + src_row_stride * row; + auto* dest = out_pixels->data() + width * row; + + // For each pixel + for (int32_t x = 0; x < width; ++x) { + memcpy(dest, src, sizeof(device::RgbaTupleF16)); + + src += src_pixel_stride; + dest += 1; + } + } +} + +device::mojom::XRLightProbePtr GetLightProbe( + ArSession* arcore_session, + ArLightEstimate* arcore_light_estimate) { + // ArCore hands out 9 sets of RGB spherical harmonics coefficients + // https://developers.google.com/ar/reference/c/group/light#arlightestimate_getenvironmentalhdrambientsphericalharmonics + constexpr size_t kNumShCoefficients = 9; + + auto light_probe = device::mojom::XRLightProbe::New(); + + light_probe->spherical_harmonics = device::mojom::XRSphericalHarmonics::New(); + light_probe->spherical_harmonics->coefficients = + std::vector<device::RgbTupleF32>(kNumShCoefficients, + device::RgbTupleF32{}); + + ArLightEstimate_getEnvironmentalHdrAmbientSphericalHarmonics( + arcore_session, arcore_light_estimate, + light_probe->spherical_harmonics->coefficients.data()->components); + + float main_light_direction[3] = {0}; + ArLightEstimate_getEnvironmentalHdrMainLightDirection( + arcore_session, arcore_light_estimate, main_light_direction); + light_probe->main_light_direction.set_x(main_light_direction[0]); + light_probe->main_light_direction.set_y(main_light_direction[1]); + light_probe->main_light_direction.set_z(main_light_direction[2]); + + ArLightEstimate_getEnvironmentalHdrMainLightIntensity( + arcore_session, arcore_light_estimate, + light_probe->main_light_intensity.components); + + return light_probe; +} + +device::mojom::XRReflectionProbePtr GetReflectionProbe( + ArSession* arcore_session, + ArLightEstimate* arcore_light_estimate) { + ArImageCubemap arcore_cube_map = {nullptr}; + ArLightEstimate_acquireEnvironmentalHdrCubemap( + arcore_session, arcore_light_estimate, arcore_cube_map); + + auto cube_map = device::mojom::XRCubeMap::New(); + std::vector<device::RgbaTupleF16>* const cube_map_faces[] = { + &cube_map->positive_x, &cube_map->negative_x, &cube_map->positive_y, + &cube_map->negative_y, &cube_map->positive_z, &cube_map->negative_z}; + + static_assert( + base::size(cube_map_faces) == base::size(arcore_cube_map), + "`ArImageCubemap` and `device::mojom::XRCubeMap` are expected to " + "have the same number of faces (6)."); + + static_assert(device::mojom::XRCubeMap::kNumComponentsPerPixel == 4, + "`device::mojom::XRCubeMap::kNumComponentsPerPixel` is " + "expected to be 4 (RGBA)`, as that's the format ArCore uses."); + + for (size_t i = 0; i < base::size(arcore_cube_map); ++i) { + auto* arcore_cube_map_face = arcore_cube_map[i]; + if (!arcore_cube_map_face) { + DVLOG(1) << "`ArLightEstimate_acquireEnvironmentalHdrCubemap` failed to " + "return all faces"; + ReleaseArCoreCubemap(&arcore_cube_map); + return nullptr; + } + + auto* cube_map_face = cube_map_faces[i]; + + // Make sure we only have a single image plane + int32_t num_planes = 0; + ArImage_getNumberOfPlanes(arcore_session, arcore_cube_map_face, + &num_planes); + if (num_planes != 1) { + DVLOG(1) << "ArCore cube map face " << i + << " does not have exactly 1 plane."; + ReleaseArCoreCubemap(&arcore_cube_map); + return nullptr; + } + + // Make sure the format for the image is in RGBA16F + ArImageFormat format = AR_IMAGE_FORMAT_INVALID; + ArImage_getFormat(arcore_session, arcore_cube_map_face, &format); + if (format != AR_IMAGE_FORMAT_RGBA_FP16) { + DVLOG(1) << "ArCore cube map face " << i + << " not in expected image format."; + ReleaseArCoreCubemap(&arcore_cube_map); + return nullptr; + } + + // Copy the cubemap + uint32_t face_width = 0, face_height = 0; + CopyArCoreImage_RGBA16F(arcore_session, arcore_cube_map_face, 0, + cube_map_face, &face_width, &face_height); + + // Make sure the cube map is square + if (face_width != face_height) { + DVLOG(1) << "ArCore cube map contains non-square image."; + ReleaseArCoreCubemap(&arcore_cube_map); + return nullptr; + } + + // Make sure all faces have the same dimensions + if (i == 0) { + cube_map->width_and_height = face_width; + } else if (face_width != cube_map->width_and_height || + face_height != cube_map->width_and_height) { + DVLOG(1) << "ArCore cube map faces not all of the same dimensions."; + ReleaseArCoreCubemap(&arcore_cube_map); + return nullptr; + } + } + + ReleaseArCoreCubemap(&arcore_cube_map); + + auto reflection_probe = device::mojom::XRReflectionProbe::New(); + reflection_probe->cube_map = std::move(cube_map); + return reflection_probe; +} + constexpr float kDefaultFloorHeightEstimation = 1.2; } // namespace @@ -194,6 +368,10 @@ return false; } + // Enable lighting estimation with spherical harmonics + ArConfig_setLightEstimationMode(session.get(), arcore_config.get(), + AR_LIGHT_ESTIMATION_MODE_ENVIRONMENTAL_HDR); + status = ArSession_configure(session.get(), arcore_config.get()); if (status != AR_SUCCESS) { DLOG(ERROR) << "ArSession_configure failed: " << status; @@ -208,9 +386,20 @@ return false; } + internal::ScopedArCoreObject<ArLightEstimate*> light_estimate; + ArLightEstimate_create( + session.get(), + internal::ScopedArCoreObject<ArLightEstimate*>::Receiver(light_estimate) + .get()); + if (!light_estimate.is_valid()) { + DVLOG(1) << "ArLightEstimate_create failed"; + return false; + } + // Success, we now have a valid session and a valid frame. arcore_frame_ = std::move(frame); arcore_session_ = std::move(session); + arcore_light_estimate_ = std::move(light_estimate); return true; } @@ -563,6 +752,39 @@ return mojom::XRAnchorsData::New(all_anchor_ids, std::move(updated_anchors)); } +mojom::XRLightEstimationDataPtr ArCoreImpl::GetLightEstimationData() { + TRACE_EVENT0("gpu", __FUNCTION__); + + ArFrame_getLightEstimate(arcore_session_.get(), arcore_frame_.get(), + arcore_light_estimate_.get()); + + ArLightEstimateState light_estimate_state = AR_LIGHT_ESTIMATE_STATE_NOT_VALID; + ArLightEstimate_getState(arcore_session_.get(), arcore_light_estimate_.get(), + &light_estimate_state); + + // The light estimate state is not guaranteed to be valid initially + if (light_estimate_state != AR_LIGHT_ESTIMATE_STATE_VALID) { + DVLOG(2) << "ArCore light estimation state invalid."; + return nullptr; + } + + auto light_estimation_data = mojom::XRLightEstimationData::New(); + light_estimation_data->light_probe = + GetLightProbe(arcore_session_.get(), arcore_light_estimate_.get()); + if (!light_estimation_data->light_probe) { + DVLOG(1) << "Failed to generate light probe."; + return nullptr; + } + light_estimation_data->reflection_probe = + GetReflectionProbe(arcore_session_.get(), arcore_light_estimate_.get()); + if (!light_estimation_data->reflection_probe) { + DVLOG(1) << "Failed to generate reflection probe."; + return nullptr; + } + + return light_estimation_data; +} + std::pair<PlaneId, bool> ArCoreImpl::CreateOrGetPlaneId(void* plane_address) { auto it = ar_plane_address_to_id_.find(plane_address); if (it != ar_plane_address_to_id_.end()) {
diff --git a/chrome/browser/android/vr/arcore_device/arcore_impl.h b/chrome/browser/android/vr/arcore_device/arcore_impl.h index 757832f..c2e6b86a 100644 --- a/chrome/browser/android/vr/arcore_device/arcore_impl.h +++ b/chrome/browser/android/vr/arcore_device/arcore_impl.h
@@ -140,6 +140,8 @@ mojom::XRAnchorsDataPtr GetAnchorsData() override; + mojom::XRLightEstimationDataPtr GetLightEstimationData() override; + void Pause() override; void Resume() override; @@ -205,6 +207,9 @@ // call to the ARCore SDK. internal::ScopedArCoreObject<ArAnchorList*> arcore_anchors_; + // ArCore light estimation data + internal::ScopedArCoreObject<ArLightEstimate*> arcore_light_estimate_; + // Initializes |arcore_planes_| list. void EnsureArCorePlanesList();
diff --git a/chrome/browser/android/vr/arcore_device/fake_arcore.cc b/chrome/browser/android/vr/arcore_device/fake_arcore.cc index ce8ea8d..658717e 100644 --- a/chrome/browser/android/vr/arcore_device/fake_arcore.cc +++ b/chrome/browser/android/vr/arcore_device/fake_arcore.cc
@@ -278,6 +278,32 @@ return mojom::XRAnchorsData::New(std::move(result_ids), std::move(result)); } +mojom::XRLightEstimationDataPtr FakeArCore::GetLightEstimationData() { + auto result = mojom::XRLightEstimationData::New(); + + // Initialize light probe with a top-down white light + result->light_probe = mojom::XRLightProbe::New(); + result->light_probe->main_light_direction = gfx::Vector3dF(0, -1, 0); + result->light_probe->main_light_intensity = device::RgbTupleF32(1, 1, 1); + + // Initialize spherical harmonics to zero-filled array + result->light_probe->spherical_harmonics = mojom::XRSphericalHarmonics::New(); + result->light_probe->spherical_harmonics->coefficients.resize(9); + + // Initialize reflection_probe to black + result->reflection_probe = mojom::XRReflectionProbe::New(); + result->reflection_probe->cube_map = mojom::XRCubeMap::New(); + result->reflection_probe->cube_map->width_and_height = 16; + result->reflection_probe->cube_map->positive_x.resize(16 * 16); + result->reflection_probe->cube_map->negative_x.resize(16 * 16); + result->reflection_probe->cube_map->positive_y.resize(16 * 16); + result->reflection_probe->cube_map->negative_y.resize(16 * 16); + result->reflection_probe->cube_map->positive_z.resize(16 * 16); + result->reflection_probe->cube_map->negative_z.resize(16 * 16); + + return result; +} + base::Optional<uint64_t> FakeArCore::CreateAnchor(const mojom::PosePtr& pose, uint64_t plane_id) { // TODO(992035): Fix this when implementing tests.
diff --git a/chrome/browser/android/vr/arcore_device/fake_arcore.h b/chrome/browser/android/vr/arcore_device/fake_arcore.h index a0f0f768..5ccbefc 100644 --- a/chrome/browser/android/vr/arcore_device/fake_arcore.h +++ b/chrome/browser/android/vr/arcore_device/fake_arcore.h
@@ -58,6 +58,7 @@ mojom::XRPlaneDetectionDataPtr GetDetectedPlanesData() override; mojom::XRAnchorsDataPtr GetAnchorsData() override; + mojom::XRLightEstimationDataPtr GetLightEstimationData() override; base::Optional<uint64_t> CreateAnchor( const device::mojom::PosePtr& pose) override;
diff --git a/chrome/browser/apps/app_service/arc_apps.cc b/chrome/browser/apps/app_service/arc_apps.cc index 7f5a2fe..ede3368 100644 --- a/chrome/browser/apps/app_service/arc_apps.cc +++ b/chrome/browser/apps/app_service/arc_apps.cc
@@ -7,6 +7,7 @@ #include <memory> #include <utility> +#include "ash/public/cpp/app_menu_constants.h" #include "base/bind.h" #include "base/callback.h" #include "base/containers/flat_map.h" @@ -18,6 +19,7 @@ #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/apps/app_service/arc_apps_factory.h" #include "chrome/browser/apps/app_service/dip_px_util.h" +#include "chrome/browser/apps/app_service/menu_util.h" #include "chrome/browser/chromeos/arc/arc_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/arc/arc_app_dialog.h" @@ -25,6 +27,7 @@ #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" #include "chrome/common/chrome_features.h" #include "chrome/grit/component_extension_resources.h" +#include "chrome/grit/generated_resources.h" #include "chrome/services/app_service/public/cpp/intent_filter_util.h" #include "components/arc/app_permissions/arc_app_permissions_bridge.h" #include "components/arc/arc_service_manager.h" @@ -490,7 +493,39 @@ void ArcApps::GetMenuModel(const std::string& app_id, apps::mojom::MenuType menu_type, GetMenuModelCallback callback) { - std::move(callback).Run(apps::mojom::MenuItems::New()); + ArcAppListPrefs* prefs = ArcAppListPrefs::Get(profile_); + if (!prefs) { + std::move(callback).Run(apps::mojom::MenuItems::New()); + return; + } + const std::unique_ptr<ArcAppListPrefs::AppInfo> app_info = + prefs->GetApp(app_id); + if (!app_info) { + std::move(callback).Run(apps::mojom::MenuItems::New()); + return; + } + + apps::mojom::MenuItemsPtr menu_items = apps::mojom::MenuItems::New(); + + // Add Open item if the app is not opened and not suspended. + if (!base::Contains(app_id_to_task_ids_, app_id) && !app_info->suspended) { + AddCommandItem(ash::LAUNCH_NEW, IDS_APP_CONTEXT_MENU_ACTIVATE_ARC, + &menu_items); + } + + if (app_info->shortcut) { + AddCommandItem(ash::UNINSTALL, IDS_APP_LIST_REMOVE_SHORTCUT, &menu_items); + } else if (app_info->ready && !app_info->sticky) { + AddCommandItem(ash::UNINSTALL, IDS_APP_LIST_UNINSTALL_ITEM, &menu_items); + } + + // App Info item. + if (app_info->ready) { + AddCommandItem(ash::SHOW_APP_INFO, IDS_APP_CONTEXT_MENU_SHOW_INFO, + &menu_items); + } + + std::move(callback).Run(std::move(menu_items)); } void ArcApps::OpenNativeSettings(const std::string& app_id) {
diff --git a/chrome/browser/apps/app_service/built_in_chromeos_apps.cc b/chrome/browser/apps/app_service/built_in_chromeos_apps.cc index c0dc2805..df6fea0d 100644 --- a/chrome/browser/apps/app_service/built_in_chromeos_apps.cc +++ b/chrome/browser/apps/app_service/built_in_chromeos_apps.cc
@@ -8,6 +8,7 @@ #include <vector> #include "ash/public/cpp/app_list/app_list_metrics.h" +#include "ash/public/cpp/app_menu_constants.h" #include "base/time/time.h" #include "chrome/browser/apps/app_service/app_icon_factory.h" #include "chrome/browser/apps/app_service/app_service_metrics.h"
diff --git a/chrome/browser/apps/app_service/crostini_apps.cc b/chrome/browser/apps/app_service/crostini_apps.cc index 62ff9927..ec27855 100644 --- a/chrome/browser/apps/app_service/crostini_apps.cc +++ b/chrome/browser/apps/app_service/crostini_apps.cc
@@ -6,7 +6,9 @@ #include <utility> +#include "ash/public/cpp/app_menu_constants.h" #include "chrome/browser/apps/app_service/dip_px_util.h" +#include "chrome/browser/apps/app_service/menu_util.h" #include "chrome/browser/chromeos/crostini/crostini_features.h" #include "chrome/browser/chromeos/crostini/crostini_package_service.h" #include "chrome/browser/chromeos/crostini/crostini_pref_names.h" @@ -14,6 +16,7 @@ #include "chrome/browser/chromeos/crostini/crostini_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/grit/chrome_unscaled_resources.h" +#include "chrome/grit/generated_resources.h" #include "components/prefs/pref_change_registrar.h" // TODO(crbug.com/826982): the equivalent of @@ -175,7 +178,18 @@ void CrostiniApps::GetMenuModel(const std::string& app_id, apps::mojom::MenuType menu_type, GetMenuModelCallback callback) { - std::move(callback).Run(apps::mojom::MenuItems::New()); + apps::mojom::MenuItemsPtr menu_items = apps::mojom::MenuItems::New(); + if (crostini::IsUninstallable(profile_, app_id)) { + AddCommandItem(ash::UNINSTALL, IDS_APP_LIST_UNINSTALL_ITEM, &menu_items); + } + + if (app_id == crostini::GetTerminalId() && + crostini::IsCrostiniRunning(profile_)) { + AddCommandItem(ash::STOP_APP, IDS_CROSTINI_SHUT_DOWN_LINUX_MENU_ITEM, + &menu_items); + } + + std::move(callback).Run(std::move(menu_items)); } void CrostiniApps::OpenNativeSettings(const std::string& app_id) {
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index 93deb037..2a64dab 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -15,8 +15,8 @@ <if expr="not is_android"> <!-- New Tab Page WebUI. --> <structure name="IDR_INCOGNITO_TAB_HTML" file="resources\ntp4\incognito_tab.html" compress="gzip" flattenhtml="true" type="chrome_html" /> + <structure name="IDR_INCOGNITO_TAB_THEME_CSS" file="resources\ntp4\incognito_tab_theme.css" compress="gzip" flattenhtml="true" type="chrome_html" /> <structure name="IDR_GUEST_TAB_HTML" file="resources\ntp4\guest_tab.html" compress="gzip" flattenhtml="true" type="chrome_html" /> - <structure name="IDR_NEW_INCOGNITO_TAB_THEME_CSS" file="resources\ntp4\new_incognito_tab_theme.css" compress="gzip" flattenhtml="true" type="chrome_html" /> <structure name="IDR_NEW_TAB_4_HTML" file="resources\ntp4\new_tab.html" compress="gzip" flattenhtml="true" type="chrome_html" /> <structure name="IDR_NEW_TAB_4_THEME_CSS" file="resources\ntp4\new_tab_theme.css" compress="gzip" flattenhtml="true" type="chrome_html" />
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index b471059..c776000 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -2408,6 +2408,8 @@ "//chrome/services/cups_proxy/public/mojom", ] sources += [ + "extensions/printing/print_job_controller.cc", + "extensions/printing/print_job_controller.h", "extensions/printing/printing_api.cc", "extensions/printing/printing_api.h", "extensions/printing/printing_api_handler.cc", @@ -2615,7 +2617,6 @@ "arc/bluetooth/arc_bluetooth_task_queue_unittest.cc", "arc/boot_phase_monitor/arc_boot_phase_monitor_bridge_unittest.cc", "arc/enterprise/cert_store/arc_cert_installer_unittest.cc", - "arc/enterprise/cert_store/arc_cert_installer_utils_unittest.cc", "arc/enterprise/cert_store/arc_smart_card_manager_bridge_unittest.cc", "arc/enterprise/cert_store/security_token_operation_bridge_unittest.cc", "arc/extensions/arc_support_message_host_unittest.cc",
diff --git a/chrome/browser/chromeos/apps/apk_web_app_installer.cc b/chrome/browser/chromeos/apps/apk_web_app_installer.cc index e8af2606..dd68e746 100644 --- a/chrome/browser/chromeos/apps/apk_web_app_installer.cc +++ b/chrome/browser/chromeos/apps/apk_web_app_installer.cc
@@ -114,8 +114,9 @@ // It is assumed that if |weak_owner_| is gone, |profile_| is gone too. The // web app will be automatically cleaned up by provider. if (!weak_owner_.get()) { - CompleteInstallation(web_app::AppId(), - web_app::InstallResultCode::kProfileDestroyed); + CompleteInstallation( + web_app::AppId(), + web_app::InstallResultCode::kCancelledOnWebAppProviderShuttingDown); return; } @@ -141,8 +142,9 @@ if (!weak_owner_.get()) { // Assume |profile_| is no longer valid - destroy this object and // terminate. - CompleteInstallation(web_app::AppId(), - web_app::InstallResultCode::kProfileDestroyed); + CompleteInstallation( + web_app::AppId(), + web_app::InstallResultCode::kCancelledOnWebAppProviderShuttingDown); return; } DoInstall();
diff --git a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer.cc b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer.cc index 9d6296b4..da8369e05 100644 --- a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer.cc +++ b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer.cc
@@ -7,6 +7,7 @@ #include <cert.h> #include <utility> +#include <vector> #include "base/base64.h" #include "base/bind.h" @@ -18,10 +19,27 @@ #include "chrome/browser/net/nss_context.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/net/x509_certificate_model_nss.h" +#include "crypto/rsa_private_key.h" #include "net/cert/x509_util_nss.h" namespace arc { +namespace { + +// Exports subject public key info and encodes it in base64. +std::string exportSpki(crypto::RSAPrivateKey* rsa) { + std::vector<uint8_t> spki; + if (!rsa->ExportPublicKey(&spki)) { + LOG(ERROR) << "Key export has failed."; + return ""; + } + std::string encoded_spki; + base::Base64Encode(std::string(spki.begin(), spki.end()), &encoded_spki); + return encoded_spki; +} + +} // namespace + ArcCertInstaller::ArcCertInstaller(content::BrowserContext* context) : ArcCertInstaller(Profile::FromBrowserContext(context), std::make_unique<policy::RemoteCommandsQueue>()) {} @@ -41,7 +59,7 @@ queue_->RemoveObserver(this); } -std::set<std::string> ArcCertInstaller::InstallArcCerts( +std::map<std::string, std::string> ArcCertInstaller::InstallArcCerts( const std::vector<net::ScopedCERTCertificate>& certificates, InstallArcCertsCallback callback) { VLOG(1) << "ArcCertInstaller::InstallArcCerts"; @@ -53,7 +71,8 @@ pending_status_ = true; } - std::set<std::string> required_cert_names; + // Map the certificate name to the dummy RSA SPKI. + std::map<std::string, std::string> required_cert_names; callback_ = std::move(callback); for (const auto& nss_cert : certificates) { @@ -65,9 +84,7 @@ std::string cert_name = x509_certificate_model::GetCertNameOrNickname(nss_cert.get()); - required_cert_names.insert(cert_name); - - InstallArcCert(cert_name, nss_cert); + required_cert_names[cert_name] = InstallArcCert(cert_name, nss_cert); } // Cleanup |known_cert_names_| according to |required_cert_names|. @@ -81,23 +98,24 @@ std::move(callback_).Run(pending_status_); pending_status_ = true; } - return required_cert_names; } -void ArcCertInstaller::InstallArcCert( +std::string ArcCertInstaller::InstallArcCert( const std::string& name, const net::ScopedCERTCertificate& nss_cert) { VLOG(1) << "ArcCertInstaller::InstallArcCert " << name; - // Do not install certificate if already exists. - if (known_cert_names_.count(name)) - return; + // Do not install certificate if it is already installed or pending. + if (known_cert_names_.count(name)) { + VLOG(1) << "Certificate " << name << " is already installed or pending"; + return ""; + } std::string der_cert; if (!net::x509_util::GetDEREncoded(nss_cert.get(), &der_cert)) { LOG(ERROR) << "Certificate encoding error: " << name; - return; + return ""; } known_cert_names_.insert(name); @@ -113,23 +131,31 @@ std::string der_cert64; base::Base64Encode(der_cert, &der_cert64); - command_proto.set_payload(base::StringPrintf( - "{\"type\":\"INSTALL_KEY_PAIR\"," - "\"payload\":\"{" - "\\\"key\\\"=\\\"%s\\\"," - "\\\"alias\\\":\\\"%s\\\"," - "\\\"certs\\\":[\\\"%s\\\"]}\"}", - CreatePkcs12FromBlob(name).c_str(), name.c_str(), der_cert64.c_str())); + + std::unique_ptr<crypto::RSAPrivateKey> rsa = + crypto::RSAPrivateKey::Create(2048); + std::string pkcs12 = CreatePkcs12ForKey(name, rsa->key()); + command_proto.set_payload( + base::StringPrintf("{\"type\":\"INSTALL_KEY_PAIR\"," + "\"payload\":\"{" + "\\\"key\\\"=\\\"%s\\\"," + "\\\"alias\\\":\\\"%s\\\"," + "\\\"certs\\\":[\\\"%s\\\"]}\"}", + pkcs12.c_str(), name.c_str(), der_cert64.c_str())); if (!job || !job->Init(queue_->GetNowTicks(), command_proto, nullptr /* signed_command */)) { LOG(ERROR) << "Initialization of remote command failed"; known_cert_names_.erase(name); + return ""; } else { pending_commands_[next_id_++] = name; queue_->AddJob(std::move(job)); + + return exportSpki(rsa.get()); } } void ArcCertInstaller::OnJobFinished(policy::RemoteCommandJob* command) { + VLOG(1) << "ArcCertInstaller::OnJobFinished"; if (!pending_commands_.count(command->unique_id())) { LOG(ERROR) << "Received invalid ARC remote command with unrecognized " << "unique_id = " << command->unique_id();
diff --git a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer.h b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer.h index b9891fd..e2ebfe4 100644 --- a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer.h +++ b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer.h
@@ -42,17 +42,23 @@ // Install missing certificates via ARC remote commands. // - // Return set of the names of certificates required being installed on ARC. + // Return map of certificate names required being installed on ARC to dummy + // SPKI. + // The dummy SPKI may be empty if the key is not installed during this call + // (either error or already installed key pair). // Return false via |callback| in case of any error, and true otherwise. // Made virtual for override in test. - virtual std::set<std::string> InstallArcCerts( + virtual std::map<std::string, std::string> InstallArcCerts( const std::vector<net::ScopedCERTCertificate>& certs, InstallArcCertsCallback callback); private: // Install ARC certificate if not installed yet. - void InstallArcCert(const std::string& name, - const net::ScopedCERTCertificate& nss_cert); + // Return RSA public key material for the NSS cert encoded in base 64 + // or an empty string if the key is not installed during this call + // (either error or already installed key pair). + std::string InstallArcCert(const std::string& name, + const net::ScopedCERTCertificate& nss_cert); // RemoteCommandsQueue::Observer overrides: void OnJobStarted(policy::RemoteCommandJob* command) override {}
diff --git a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer_utils.cc b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer_utils.cc index 80766dd..95e6870 100644 --- a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer_utils.cc +++ b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer_utils.cc
@@ -7,179 +7,38 @@ #include "base/base64.h" #include "base/logging.h" #include "base/strings/string_piece.h" -#include "third_party/boringssl/src/include/openssl/bn.h" #include "third_party/boringssl/src/include/openssl/evp.h" #include "third_party/boringssl/src/include/openssl/mem.h" #include "third_party/boringssl/src/include/openssl/pkcs8.h" namespace arc { -// Creates a fake, but recognized as valid, RSA private key: -// * q = |blob| + 3 + { 4, 3, 2 } so that q % 3 = 1 -// * p = 3 -// * n = p * q -// * e = 1 -// * d = (q - 1) * (p - 1) + 1 so that d % (p - 1) * (q - 1) = 1 -// * dmp1 = 1 -// * dmq1 = 1 -// * iqmp = 1 -RSA* CreateRsaPrivateKeyFromBlob(const std::string& blob) { - const uint8_t* ptr = (const uint8_t*)blob.data(); - BIGNUM* q = BN_bin2bn(ptr, blob.size(), nullptr); - int mod3; - if (!q || !BN_add_word(q, 3) || (mod3 = BN_mod_word(q, 3)) >= 3 || - !BN_add_word(q, 4 - mod3)) { - BN_free(q); - VLOG(1) << "Failed to create q for " << blob; - return nullptr; - } - - BIGNUM* p = BN_new(); - if (!p || !BN_set_word(p, 3)) { - BN_free(q); - BN_free(p); - VLOG(1) << "Failed to create p for " << blob; - return nullptr; - } - - BIGNUM* n = BN_new(); - bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new()); - if (!n || !BN_mul(n, p, q, ctx.get())) { - BN_free(q); - BN_free(p); - BN_free(n); - VLOG(1) << "Failed to create n for " << blob; - return nullptr; - } - - BIGNUM* e = BN_new(); - if (!e || !BN_one(e)) { - BN_free(q); - BN_free(p); - BN_free(n); - BN_free(e); - VLOG(1) << "Failed to create e for " << blob; - return nullptr; - } - - BIGNUM* d = BN_new(); - if (!d || !BN_sub(d, q, BN_value_one()) || !BN_mul_word(d, 2) || - !BN_add_word(d, 1)) { - BN_free(q); - BN_free(p); - BN_free(n); - BN_free(e); - BN_free(d); - VLOG(1) << "Failed to create d for " << blob; - return nullptr; - } - - BIGNUM* dmp1 = BN_new(); - BIGNUM* dmq1 = BN_new(); - BIGNUM* iqmp = BN_new(); - if (!dmp1 || !BN_one(dmp1) || !dmq1 || !BN_one(dmq1) || !iqmp || - !BN_one(iqmp)) { - BN_free(q); - BN_free(p); - BN_free(n); - BN_free(e); - BN_free(d); - BN_free(dmp1); - BN_free(dmq1); - BN_free(iqmp); - VLOG(1) << "Failed to create dmp1 or dmq1 or iqmp for " << blob; - return nullptr; - } - - RSA* rsa = RSA_new(); - if (!rsa) { - BN_free(q); - BN_free(p); - BN_free(n); - BN_free(e); - BN_free(d); - BN_free(dmp1); - BN_free(dmq1); - BN_free(iqmp); - VLOG(1) << "Failed to create RSA key."; - return nullptr; - } - - if (!RSA_set0_key(rsa, n, e, d)) { - BN_free(q); - BN_free(p); - BN_free(n); - BN_free(e); - BN_free(d); - BN_free(dmp1); - BN_free(dmq1); - BN_free(iqmp); - RSA_free(rsa); - VLOG(1) << "Failed to set n to RSA for " << blob; - return nullptr; - } - - if (!RSA_set0_factors(rsa, p, q)) { - BN_free(q); - BN_free(p); - BN_free(dmp1); - BN_free(dmq1); - BN_free(iqmp); - RSA_free(rsa); - VLOG(1) << "Failed to set factors to RSA for " << blob; - return nullptr; - } - - if (!RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp)) { - BN_free(dmp1); - BN_free(dmq1); - BN_free(iqmp); - RSA_free(rsa); - VLOG(1) << "Failed to set crt params for " << blob; - return nullptr; - } - return rsa; -} - -std::string CreatePkcs12FromBlob(const std::string& blob) { - bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new()); - - if (!pkey) { - VLOG(1) << "Failed to generate RSA for " << blob; - return ""; - } - - RSA* rsa = CreateRsaPrivateKeyFromBlob(blob); - if (!rsa) { - return ""; - } - - if (!EVP_PKEY_assign_RSA(pkey.get(), rsa)) { - RSA_free(rsa); - VLOG(1) << "Failed to assign RSA for " << blob; +std::string CreatePkcs12ForKey(const std::string& name, EVP_PKEY* key) { + if (!key) { + VLOG(1) << "Failed due to a nullptr key"; return ""; } // Make a PKCS#12 blob. bssl::UniquePtr<PKCS12> pkcs12(PKCS12_create( - nullptr, blob.c_str(), pkey.get(), nullptr, nullptr, 0, 0, 0, 0, 0)); + nullptr, name.c_str(), key, nullptr, nullptr, 0, 0, 0, 0, 0)); if (!pkcs12) { - VLOG(1) << "Failed to create PKCS12 object from pkey for " << blob; + VLOG(1) << "Failed to create PKCS12 object from |key| for " << name; return ""; } - uint8_t* key = nullptr; - int key_len; - if (!(key_len = i2d_PKCS12(pkcs12.get(), &key))) { - VLOG(1) << "Failed to translate PKCS12 to byte array for " << blob; + uint8_t* pkcs12_key = nullptr; + int pkcs12_key_len; + if (!(pkcs12_key_len = i2d_PKCS12(pkcs12.get(), &pkcs12_key))) { + VLOG(1) << "Failed to translate PKCS12 to byte array for " << name; return ""; } - bssl::UniquePtr<uint8_t> free_key(key); - - std::string encoded_key; - base::Base64Encode(base::StringPiece((char*)key, key_len), &encoded_key); - return encoded_key; + bssl::UniquePtr<uint8_t> free_pkcs12_key(pkcs12_key); + std::string encoded_pkcs12_key; + base::Base64Encode(base::StringPiece((char*)pkcs12_key, pkcs12_key_len), + &encoded_pkcs12_key); + return encoded_pkcs12_key; } } // namespace arc
diff --git a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer_utils.h b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer_utils.h index bd0c3f2..925d553 100644 --- a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer_utils.h +++ b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer_utils.h
@@ -7,20 +7,13 @@ #include <string> -#include "third_party/boringssl/src/include/openssl/rsa.h" +#include "third_party/boringssl/src/include/openssl/base.h" namespace arc { -// Creates a PKCS12 container with RSA private key, generated with p = |blob|, -// to be able to extract |blob| value from a private key material later. +// Creates a PKCS12 container named |name| with private key |key|. // Returns empty string in case of any error. -std::string CreatePkcs12FromBlob(const std::string& blob); - -// Helper function that creates the RSA private key with p = |blob| to -// be able to extract |blob| value from a private key material later. -// Returns nullptr in case of any error. -// Should be used only for testing. -RSA* CreateRsaPrivateKeyFromBlob(const std::string& blob); +std::string CreatePkcs12ForKey(const std::string& name, EVP_PKEY* key); } // namespace arc
diff --git a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer_utils_unittest.cc b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer_utils_unittest.cc deleted file mode 100644 index 126e8fc..0000000 --- a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer_utils_unittest.cc +++ /dev/null
@@ -1,155 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <string> - -#include "chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer_utils.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/boringssl/src/include/openssl/evp.h" -#include "third_party/boringssl/src/include/openssl/mem.h" -#include "third_party/boringssl/src/include/openssl/pkcs8.h" -#include "third_party/boringssl/src/include/openssl/rsa.h" - -namespace arc { - -namespace { - -// Keep in sync with external/boringssl/src/crypto/fipsmodule/rsa/rsa.c -int checkRsaKey(const RSA* key) { - BIGNUM n, pm1, qm1, lcm, gcd, de, dmp1, dmq1, iqmp_times_q; - BN_CTX* ctx; - int ok = 0, has_crt_values; - - if (RSA_is_opaque(key)) { - // Opaque keys can't be checked. - return 1; - } - - if ((key->p != nullptr) != (key->q != nullptr)) { - OPENSSL_PUT_ERROR(RSA, RSA_R_ONLY_ONE_OF_P_Q_GIVEN); - return 0; - } - - if (!key->n || !key->e) { - OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); - return 0; - } - - if (!key->d || !key->p) { - // For a public key, or without p and q, there's nothing that can be - // checked. - return 1; - } - - ctx = BN_CTX_new(); - if (ctx == nullptr) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); - return 0; - } - - BN_init(&n); - BN_init(&pm1); - BN_init(&qm1); - BN_init(&lcm); - BN_init(&gcd); - BN_init(&de); - BN_init(&dmp1); - BN_init(&dmq1); - BN_init(&iqmp_times_q); - - if (!BN_mul(&n, key->p, key->q, ctx) || - // lcm = lcm(p, q) - !BN_sub(&pm1, key->p, BN_value_one()) || - !BN_sub(&qm1, key->q, BN_value_one()) || !BN_mul(&lcm, &pm1, &qm1, ctx) || - !BN_gcd(&gcd, &pm1, &qm1, ctx)) { - OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); - goto out; - } - - if (!BN_div(&lcm, nullptr, &lcm, &gcd, ctx) || - !BN_gcd(&gcd, &pm1, &qm1, ctx) || - // de = d*e mod lcm(p, q). - !BN_mod_mul(&de, key->d, key->e, &lcm, ctx)) { - OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); - goto out; - } - - if (BN_cmp(&n, key->n) != 0) { - OPENSSL_PUT_ERROR(RSA, RSA_R_N_NOT_EQUAL_P_Q); - goto out; - } - - if (!BN_is_one(&de)) { - OPENSSL_PUT_ERROR(RSA, RSA_R_D_E_NOT_CONGRUENT_TO_1); - goto out; - } - - has_crt_values = key->dmp1 != nullptr; - - if (has_crt_values != (key->dmq1 != nullptr) || - has_crt_values != (key->iqmp != nullptr)) { - OPENSSL_PUT_ERROR(RSA, RSA_R_INCONSISTENT_SET_OF_CRT_VALUES); - goto out; - } - - if (has_crt_values) { - if ( // dmp1 = d mod (p-1) - !BN_mod(&dmp1, key->d, &pm1, ctx) || - // dmq1 = d mod (q-1) - !BN_mod(&dmq1, key->d, &qm1, ctx) || - // iqmp = q^-1 mod p - !BN_mod_mul(&iqmp_times_q, key->iqmp, key->q, key->p, ctx)) { - OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); - goto out; - } - - if (BN_cmp(&dmp1, key->dmp1) != 0 || BN_cmp(&dmq1, key->dmq1) != 0 || - BN_cmp(key->iqmp, key->p) >= 0 || !BN_is_one(&iqmp_times_q)) { - OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_VALUES_INCORRECT); - goto out; - } - } - - ok = 1; - -out: - BN_free(&n); - BN_free(&pm1); - BN_free(&qm1); - BN_free(&lcm); - BN_free(&gcd); - BN_free(&de); - BN_free(&dmp1); - BN_free(&dmq1); - BN_free(&iqmp_times_q); - BN_CTX_free(ctx); - - return ok; -} - -} // namespace - -class ArcCertInstallerUtilsTest - : public testing::Test, - public testing::WithParamInterface<std::string> {}; - -// Test that CreatePkcs12FromBlob returns non-empty PKCS12 blob with a valid -// RSA private key. -TEST_P(ArcCertInstallerUtilsTest, Pkcs12) { - const std::string name = GetParam(); - EXPECT_FALSE(CreatePkcs12FromBlob(name).empty()); - - RSA* rsa = CreateRsaPrivateKeyFromBlob(name); - ASSERT_TRUE(rsa); - EXPECT_TRUE(checkRsaKey(rsa)); - RSA_free(rsa); -} - -INSTANTIATE_TEST_SUITE_P(All, - ArcCertInstallerUtilsTest, - testing::Values("", - "name of the smart card", - std::string(2048, 'A'))); - -} // namespace arc
diff --git a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge.cc b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge.cc index 957d788..e1a6bfd 100644 --- a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge.cc +++ b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge.h" +#include <algorithm> +#include <iterator> #include <utility> #include "base/bind.h" @@ -13,9 +15,12 @@ #include "chrome/browser/chromeos/arc/policy/arc_policy_bridge.h" #include "chrome/browser/chromeos/certificate_provider/certificate_provider_service.h" #include "chrome/browser/chromeos/certificate_provider/certificate_provider_service_factory.h" +#include "chrome/browser/chromeos/platform_keys/platform_keys.h" +#include "chrome/common/net/x509_certificate_model_nss.h" #include "components/arc/arc_browser_context_keyed_service_factory_base.h" #include "components/policy/core/common/policy_map.h" #include "components/policy/core/common/policy_namespace.h" +#include "crypto/rsa_private_key.h" #include "net/cert/x509_util_nss.h" namespace arc { @@ -96,12 +101,46 @@ weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } +std::string ArcSmartCardManagerBridge::GetRealSpkiForDummySpki( + const std::string& dummy_spki) { + return certificate_cache_.GetRealSpkiForDummySpki(dummy_spki); +} + +ArcSmartCardManagerBridge::CertificateCache::CertificateCache() = default; +ArcSmartCardManagerBridge::CertificateCache::~CertificateCache() = default; + void ArcSmartCardManagerBridge::DidGetCerts( RefreshCallback callback, net::ClientCertIdentityList cert_identities) { VLOG(1) << "ArcSmartCardManagerBridge::DidGetCerts"; + certificate_cache_.clear_need_policy_update(); + std::vector<net::ScopedCERTCertificate> certificates = + certificate_cache_.Update(std::move(cert_identities)); + + // Maps cert name to dummy SPKI. + std::map<std::string, std::string> installed_keys = + installer_->InstallArcCerts(std::move(certificates), std::move(callback)); + + certificate_cache_.Update(installed_keys); + + if (certificate_cache_.need_policy_update()) { + ArcPolicyBridge* const policy_bridge = + ArcPolicyBridge::GetForBrowserContext(context_); + if (policy_bridge) { + policy_bridge->OnPolicyUpdated(policy::PolicyNamespace(), + policy::PolicyMap(), policy::PolicyMap()); + } + } +} + +std::vector<net::ScopedCERTCertificate> +ArcSmartCardManagerBridge::CertificateCache::Update( + net::ClientCertIdentityList cert_identities) { std::vector<net::ScopedCERTCertificate> certificates; + // Map cert name to real SPKI. + real_spki_by_name_cache_.clear(); + std::set<std::string> new_required_cert_names; for (const auto& identity : cert_identities) { net::ScopedCERTCertificate nss_cert( net::x509_util::CreateCERTCertificateFromX509Certificate( @@ -111,20 +150,56 @@ << "certificate."; continue; } + std::string cert_name = + x509_certificate_model::GetCertNameOrNickname(nss_cert.get()); + real_spki_by_name_cache_[cert_name] = + chromeos::platform_keys::GetSubjectPublicKeyInfo( + identity->certificate()); + new_required_cert_names.insert(cert_name); certificates.push_back(std::move(nss_cert)); } - std::set<std::string> new_required_cert_names = - installer_->InstallArcCerts(std::move(certificates), std::move(callback)); - if (required_cert_names_ != new_required_cert_names) { - required_cert_names_ = new_required_cert_names; - ArcPolicyBridge* const policy_bridge = - ArcPolicyBridge::GetForBrowserContext(context_); - if (policy_bridge) { - policy_bridge->OnPolicyUpdated(policy::PolicyNamespace(), - policy::PolicyMap(), policy::PolicyMap()); + need_policy_update_ = (required_cert_names_ != new_required_cert_names); + for (auto cert_name : required_cert_names_) { + if (!new_required_cert_names.count(cert_name)) { + real_spki_by_dummy_spki_cache_.erase( + dummy_spki_by_name_cache_[cert_name]); + dummy_spki_by_name_cache_.erase(cert_name); } } + required_cert_names_ = new_required_cert_names; + return certificates; +} + +void ArcSmartCardManagerBridge::CertificateCache::Update( + std::map<std::string, std::string> dummy_spki_by_name) { + if (required_cert_names_.size() != dummy_spki_by_name.size()) + return; + for (const auto& cert : dummy_spki_by_name) { + const std::string& name = cert.first; + if (!required_cert_names_.count(name)) { + VLOG(1) << "ArcSmartCardManagerBridge::CertificateCache::Update error: " + << "An attempt to add a non-required key " << name; + continue; + } + + std::string dummy_spki = cert.second; + if (dummy_spki.empty() && dummy_spki_by_name_cache_.count(name)) + dummy_spki = dummy_spki_by_name_cache_[name]; + if (!dummy_spki.empty()) { + dummy_spki_by_name_cache_[name] = dummy_spki; + real_spki_by_dummy_spki_cache_[dummy_spki] = + real_spki_by_name_cache_[name]; + } + } +} + +std::string +ArcSmartCardManagerBridge::CertificateCache::GetRealSpkiForDummySpki( + const std::string& dummy_spki) { + if (real_spki_by_dummy_spki_cache_.count(dummy_spki)) + return real_spki_by_dummy_spki_cache_[dummy_spki]; + return ""; } } // namespace arc
diff --git a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge.h b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge.h index 068f15e..01cf0b5 100644 --- a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge.h +++ b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge.h
@@ -55,18 +55,52 @@ // SmartCardManagerHost overrides. void Refresh(RefreshCallback callback) override; + // Returns a real SPKI for a dummy SPKI |dummy_spki|. + // Returns empty string if the key is unknown. + std::string GetRealSpkiForDummySpki(const std::string& dummy_spki); + std::vector<std::string> get_required_cert_names() const { - return std::vector<std::string>(required_cert_names_.begin(), - required_cert_names_.end()); + return certificate_cache_.get_required_cert_names(); } void set_required_cert_names_for_testing( const std::vector<std::string>& cert_names) { - required_cert_names_ = - std::set<std::string>(cert_names.begin(), cert_names.end()); + certificate_cache_.set_required_cert_names_for_testing( + std::set<std::string>(cert_names.begin(), cert_names.end())); } private: + class CertificateCache { + public: + CertificateCache(); + ~CertificateCache(); + + std::vector<net::ScopedCERTCertificate> Update( + net::ClientCertIdentityList cert_identities); + void Update(std::map<std::string, std::string> dummy_spki_by_name); + std::string GetRealSpkiForDummySpki(const std::string& dummy_spki); + + bool need_policy_update() { return need_policy_update_; } + void clear_need_policy_update() { need_policy_update_ = false; } + std::vector<std::string> get_required_cert_names() const { + return std::vector<std::string>(required_cert_names_.begin(), + required_cert_names_.end()); + } + void set_required_cert_names_for_testing(std::set<std::string> cert_names) { + required_cert_names_ = std::move(cert_names); + } + + private: + bool need_policy_update_ = false; + std::set<std::string> required_cert_names_; + // Map dummy SPKI to real SPKI. + std::map<std::string, std::string> real_spki_by_dummy_spki_cache_; + // Map cert name to dummy SPKI. + std::map<std::string, std::string> dummy_spki_by_name_cache_; + // Intermediate map name to real SPKI. + std::map<std::string, std::string> real_spki_by_name_cache_; + }; + void DidGetCerts(RefreshCallback callback, net::ClientCertIdentityList cert_identities); @@ -75,8 +109,7 @@ std::unique_ptr<chromeos::CertificateProvider> certificate_provider_; std::unique_ptr<ArcCertInstaller> installer_; - - std::set<std::string> required_cert_names_; + CertificateCache certificate_cache_; base::WeakPtrFactory<ArcSmartCardManagerBridge> weak_ptr_factory_;
diff --git a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge_unittest.cc b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge_unittest.cc index 90e1106b..25eaa0e75 100644 --- a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge_unittest.cc +++ b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge_unittest.cc
@@ -108,7 +108,7 @@ std::unique_ptr<policy::RemoteCommandsQueue> queue) : ArcCertInstaller(profile, std::move(queue)) {} MOCK_METHOD2(InstallArcCerts, - std::set<std::string>( + std::map<std::string, std::string>( const std::vector<net::ScopedCERTCertificate>& certs, InstallArcCertsCallback callback)); }; @@ -188,7 +188,7 @@ .WillOnce( WithArg<1>(Invoke([](base::OnceCallback<void(bool result)> callback) { std::move(callback).Run(true); - return std::set<std::string>(); + return std::map<std::string, std::string>(); }))); bridge()->Refresh(base::BindOnce([](bool result) { EXPECT_TRUE(result); })); } @@ -204,7 +204,12 @@ .WillOnce(WithArg<1>( Invoke([&cert_names](base::OnceCallback<void(bool result)> callback) { std::move(callback).Run(true); - return std::set<std::string>(cert_names.begin(), cert_names.end()); + std::map<std::string, std::string> cert_names_map; + std::transform( + cert_names.begin(), cert_names.end(), + std::inserter(cert_names_map, cert_names_map.end()), + [](const std::string& s) { return std::make_pair(s, ""); }); + return cert_names_map; }))); EXPECT_CALL(*policy_bridge(), OnPolicyUpdated(_, _, _)); bridge()->Refresh(base::BindOnce([](bool result) { EXPECT_TRUE(result); }));
diff --git a/chrome/browser/chromeos/extensions/printing/print_job_controller.cc b/chrome/browser/chromeos/extensions/printing/print_job_controller.cc new file mode 100644 index 0000000..aec7f612 --- /dev/null +++ b/chrome/browser/chromeos/extensions/printing/print_job_controller.cc
@@ -0,0 +1,132 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/extensions/printing/print_job_controller.h" + +#include "base/bind.h" +#include "base/callback.h" +#include "base/task/post_task.h" +#include "chrome/browser/printing/printer_query.h" +#include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/common/child_process_host.h" +#include "printing/metafile_skia.h" +#include "printing/print_settings.h" +#include "printing/printed_document.h" + +namespace extensions { + +namespace { + +using PrinterQueryCallback = + base::OnceCallback<void(std::unique_ptr<printing::PrinterQuery>)>; + +// Send initialized PrinterQuery to UI thread. +void OnSettingsSetOnIOThread(std::unique_ptr<printing::PrinterQuery> query, + PrinterQueryCallback callback) { + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, + base::BindOnce(std::move(callback), std::move(query))); +} + +void CreateQueryOnIOThread(std::unique_ptr<printing::PrintSettings> settings, + PrinterQueryCallback callback) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + + auto query = std::make_unique<printing::PrinterQuery>( + content::ChildProcessHost::kInvalidUniqueID, + content::ChildProcessHost::kInvalidUniqueID); + auto* query_ptr = query.get(); + query_ptr->SetSettingsFromPOD( + std::move(settings), + base::BindOnce(&OnSettingsSetOnIOThread, std::move(query), + std::move(callback))); +} + +} // namespace + +PrintJobController::JobState::JobState(scoped_refptr<printing::PrintJob> job, + StartPrintJobCallback callback) + : job(job), callback(std::move(callback)) {} + +PrintJobController::JobState::JobState(JobState&&) = default; + +PrintJobController::JobState& PrintJobController::JobState::operator=( + JobState&&) = default; + +PrintJobController::JobState::~JobState() = default; + +PrintJobController::PrintJobController() = default; + +PrintJobController::~PrintJobController() = default; + +void PrintJobController::StartPrintJob( + const std::string& extension_id, + std::unique_ptr<printing::MetafileSkia> metafile, + std::unique_ptr<printing::PrintSettings> settings, + StartPrintJobCallback callback) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + base::PostTask( + FROM_HERE, {content::BrowserThread::IO}, + base::BindOnce( + &CreateQueryOnIOThread, std::move(settings), + base::BindOnce(&PrintJobController::StartPrinting, + weak_ptr_factory_.GetWeakPtr(), extension_id, + std::move(metafile), std::move(callback)))); +} + +void PrintJobController::StartPrinting( + const std::string& extension_id, + std::unique_ptr<printing::MetafileSkia> metafile, + StartPrintJobCallback callback, + std::unique_ptr<printing::PrinterQuery> query) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + auto job = base::MakeRefCounted<printing::PrintJob>(); + // Save in separate variable because |query| is moved. + base::string16 title = query->settings().title(); + job->Initialize(std::move(query), title, /*page_count=*/1); + job->SetSource(printing::PrintJob::Source::EXTENSION, extension_id); + printing::PrintedDocument* document = job->document(); + // |paper_size| and |page_rect| are used only for OS_MACOSX, so just use + // default constructor values. + document->SetDocument(std::move(metafile), + /*paper_size=*/gfx::Size(), + /*page_rect=*/gfx::Rect()); + // Save PrintJob scoped refptr and callback to resolve when print job is + // created. + extension_pending_jobs_[extension_id].emplace(job, std::move(callback)); + job->StartPrinting(); +} + +void PrintJobController::OnPrintJobCreated(const std::string& extension_id, + const std::string& job_id) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + auto it = extension_pending_jobs_.find(extension_id); + if (it == extension_pending_jobs_.end()) + return; + auto& pending_jobs = it->second; + if (!pending_jobs.empty()) { + // We need to move corresponding scoped refptr of PrintJob from queue + // of pending pointers to global map. We can't drop it as the print job is + // not completed yet so we should not destruct it. + print_jobs_map_[job_id] = pending_jobs.front().job; + // The job is submitted to CUPS so we have to resolve the first callback + // in the corresponding queue. + auto callback = std::move(pending_jobs.front().callback); + pending_jobs.pop(); + if (pending_jobs.empty()) + extension_pending_jobs_.erase(it); + std::move(callback).Run(std::make_unique<std::string>(job_id)); + } +} + +void PrintJobController::OnPrintJobFinished(const std::string& job_id) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + print_jobs_map_.erase(job_id); +} + +} // namespace extensions
diff --git a/chrome/browser/chromeos/extensions/printing/print_job_controller.h b/chrome/browser/chromeos/extensions/printing/print_job_controller.h new file mode 100644 index 0000000..5e604ea --- /dev/null +++ b/chrome/browser/chromeos/extensions/printing/print_job_controller.h
@@ -0,0 +1,90 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_PRINTING_PRINT_JOB_CONTROLLER_H_ +#define CHROME_BROWSER_CHROMEOS_EXTENSIONS_PRINTING_PRINT_JOB_CONTROLLER_H_ + +#include <memory> +#include <string> + +#include "base/callback_forward.h" +#include "base/containers/flat_map.h" +#include "base/containers/queue.h" +#include "base/memory/scoped_refptr.h" +#include "base/memory/weak_ptr.h" +#include "chrome/browser/printing/print_job.h" + +namespace printing { +class MetafileSkia; +class PrinterQuery; +class PrintSettings; +} // namespace printing + +namespace extensions { + +// This class is responsible for sending print jobs in the printing pipeline and +// cancelling them. It should be used by API handler as the entry point of +// actual printing pipeline. +// This class lives on UI thread. +class PrintJobController { + public: + using StartPrintJobCallback = + base::OnceCallback<void(std::unique_ptr<std::string> job_id)>; + + PrintJobController(); + ~PrintJobController(); + + // Creates, initializes and adds print job to the queue of pending print jobs. + void StartPrintJob(const std::string& extension_id, + std::unique_ptr<printing::MetafileSkia> metafile, + std::unique_ptr<printing::PrintSettings> settings, + StartPrintJobCallback callback); + + // Moves print job pointer to |print_jobs_map_| and resolves corresponding + // callback. + // This should be called when CupsPrintJobManager created CupsPrintJob. + void OnPrintJobCreated(const std::string& extension_id, + const std::string& job_id); + + // Removes print job pointer from |print_jobs_map_| as the job is finished. + // This should be called when CupsPrintJob is finished (it could be either + // completed, failed or cancelled). + void OnPrintJobFinished(const std::string& job_id); + + private: + struct JobState { + scoped_refptr<printing::PrintJob> job; + StartPrintJobCallback callback; + JobState(scoped_refptr<printing::PrintJob> job, + StartPrintJobCallback callback); + JobState(JobState&&); + JobState& operator=(JobState&&); + ~JobState(); + }; + + void StartPrinting(const std::string& extension_id, + std::unique_ptr<printing::MetafileSkia> metafile, + StartPrintJobCallback callback, + std::unique_ptr<printing::PrinterQuery> query); + + // Stores mapping from extension id to queue of pending jobs to resolve. + // Placing a job state in the map means that we sent print job to the printing + // pipeline and have been waiting for the response with created job id. + // After that we could resolve a callback and move PrintJob to global map. + // We need to store job pointers to keep the current scheduled print jobs + // alive (as they're ref counted). + base::flat_map<std::string, base::queue<JobState>> extension_pending_jobs_; + + // Stores mapping from job id to printing::PrintJob. + // This is needed to hold PrintJob pointer and correct handle CancelJob() + // requests. + base::flat_map<std::string, scoped_refptr<printing::PrintJob>> + print_jobs_map_; + + base::WeakPtrFactory<PrintJobController> weak_ptr_factory_{this}; +}; + +} // namespace extensions + +#endif // CHROME_BROWSER_CHROMEOS_EXTENSIONS_PRINTING_PRINT_JOB_CONTROLLER_H_
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc index bcf6d871..dfcbd38 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -466,6 +466,8 @@ TestCase("openQuickViewMtp"), TestCase("openQuickViewTabIndexImage"), TestCase("openQuickViewTabIndexText"), + TestCase("openQuickViewTabIndexAudio"), + TestCase("openQuickViewTabIndexVideo"), TestCase("pressEnterOnInfoBoxToOpenClose"), TestCase("closeQuickView"), TestCase("openQuickViewFromDirectoryTree")));
diff --git a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc index 79458a5e..37e884f 100644 --- a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc +++ b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
@@ -35,6 +35,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/synchronization/lock.h" +#include "base/test/scoped_feature_list.h" #include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" #include "base/values.h" @@ -79,6 +80,8 @@ #include "chrome/browser/extensions/updater/extension_cache_impl.h" #include "chrome/browser/extensions/updater/local_extension_cache.h" #include "chrome/browser/lifetime/application_lifetime.h" +#include "chrome/browser/net/profile_network_context_service.h" +#include "chrome/browser/net/profile_network_context_service_test_utils.h" #include "chrome/browser/policy/profile_policy_connector.h" #include "chrome/browser/prefs/session_startup_pref.h" #include "chrome/browser/profiles/profile.h" @@ -96,6 +99,7 @@ #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/terms_of_service_screen_handler.h" #include "chrome/browser/web_applications/web_app_provider.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/common/pref_names.h" @@ -2919,3 +2923,74 @@ } } // namespace policy + +class AmbientAuthenticationManagedGuestSessionTest + : public policy::DeviceLocalAccountTest, + public testing::WithParamInterface<net::AmbientAuthAllowedProfileTypes> { + public: + AmbientAuthenticationManagedGuestSessionTest() { + // Switching off the feature flags to test policies in isolation. + AmbientAuthenticationTestHelper::CookTheFeatureList( + scoped_feature_list_, + AmbientAuthenticationFeatureState::GUEST_OFF_INCOGNITO_OFF); + } + + void SetAmbientAuthPolicy(net::AmbientAuthAllowedProfileTypes value) { + device_local_account_policy_.payload() + .mutable_ambientauthenticationinprivatemodesenabled() + ->set_value(static_cast<int>(value)); + UploadDeviceLocalAccountPolicy(); + } + + void IsAmbientAuthAllowedForProfilesTest() { + int policy_value = device_local_account_policy_.payload() + .ambientauthenticationinprivatemodesenabled() + .value(); + Profile* regular_profile = GetCurrentBrowser()->profile(); + Profile* incognito_profile = regular_profile->GetOffTheRecordProfile(); + + EXPECT_TRUE(AmbientAuthenticationTestHelper::IsAmbientAuthAllowedForProfile( + regular_profile)); + EXPECT_EQ(AmbientAuthenticationTestHelper::IsAmbientAuthAllowedForProfile( + incognito_profile), + AmbientAuthenticationTestHelper::IsIncognitoAllowedInPolicy( + policy_value)); + } + + Browser* GetCurrentBrowser() { + BrowserList* browser_list = BrowserList::GetInstance(); + EXPECT_EQ(1U, browser_list->size()); + Browser* browser = browser_list->get(0); + DCHECK(browser); + return browser; + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +IN_PROC_BROWSER_TEST_P(AmbientAuthenticationManagedGuestSessionTest, + AmbientAuthenticationInPrivateModesEnabledPolicy) { + SetManagedSessionsEnabled(true); + SetAmbientAuthPolicy(GetParam()); + + UploadAndInstallDeviceLocalAccountPolicy(); + AddPublicSessionToDevicePolicy(policy::kAccountId1); + EnableAutoLogin(); + + WaitForPolicy(); + + WaitForSessionStart(); + + CheckPublicSessionPresent(account_id_1_); + + IsAmbientAuthAllowedForProfilesTest(); +} + +INSTANTIATE_TEST_CASE_P( + AmbientAuthAllPolicyValuesTest, + AmbientAuthenticationManagedGuestSessionTest, + testing::Values(net::AmbientAuthAllowedProfileTypes::REGULAR_ONLY, + net::AmbientAuthAllowedProfileTypes::INCOGNITO_AND_REGULAR, + net::AmbientAuthAllowedProfileTypes::GUEST_AND_REGULAR, + net::AmbientAuthAllowedProfileTypes::ALL));
diff --git a/chrome/browser/navigation_predictor/navigation_predictor_preconnect_client.cc b/chrome/browser/navigation_predictor/navigation_predictor_preconnect_client.cc index 8a84365..7907507a 100644 --- a/chrome/browser/navigation_predictor/navigation_predictor_preconnect_client.cc +++ b/chrome/browser/navigation_predictor/navigation_predictor_preconnect_client.cc
@@ -23,7 +23,7 @@ #include "content/public/browser/web_contents.h" #include "net/base/features.h" -namespace features { +namespace { // A holdback that prevents the preconnect to measure benefit of the feature. const base::Feature kNavigationPredictorPreconnectHoldback { @@ -34,9 +34,6 @@ base::FEATURE_ENABLED_BY_DEFAULT #endif }; -} // namespace features - -namespace { // Experiment with which event triggers the preconnect after commit. const base::Feature kPreconnectOnDidFinishNavigation{ @@ -113,8 +110,7 @@ } void NavigationPredictorPreconnectClient::MaybePreconnectNow() { - if (base::FeatureList::IsEnabled( - features::kNavigationPredictorPreconnectHoldback)) + if (base::FeatureList::IsEnabled(kNavigationPredictorPreconnectHoldback)) return; if (browser_context_->IsOffTheRecord())
diff --git a/chrome/browser/navigation_predictor/navigation_predictor_preconnect_client.h b/chrome/browser/navigation_predictor/navigation_predictor_preconnect_client.h index 8f0908f..af155bd 100644 --- a/chrome/browser/navigation_predictor/navigation_predictor_preconnect_client.h +++ b/chrome/browser/navigation_predictor/navigation_predictor_preconnect_client.h
@@ -19,10 +19,6 @@ class RenderFrameHost; } // namespace content -namespace features { -extern const base::Feature kNavigationPredictorPreconnectHoldback; -} - class NavigationPredictorPreconnectClient : public content::WebContentsObserver, public content::WebContentsUserData<NavigationPredictorPreconnectClient> {
diff --git a/chrome/browser/net/profile_network_context_service.h b/chrome/browser/net/profile_network_context_service.h index f7e5a3b..3a74bf5 100644 --- a/chrome/browser/net/profile_network_context_service.h +++ b/chrome/browser/net/profile_network_context_service.h
@@ -104,7 +104,7 @@ ProfileNetworkContextServiceCertVerifierBuiltinFeaturePolicyTest, Test); - friend class AmbientAuthenticationTestWithPolicy; + friend class AmbientAuthenticationTestHelper; // Checks |quic_allowed_|, and disables QUIC if needed. void DisableQuicIfNotAllowed();
diff --git a/chrome/browser/net/profile_network_context_service_browsertest.cc b/chrome/browser/net/profile_network_context_service_browsertest.cc index 483c52a..f56a77c0 100644 --- a/chrome/browser/net/profile_network_context_service_browsertest.cc +++ b/chrome/browser/net/profile_network_context_service_browsertest.cc
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/net/profile_network_context_service.h" - #include <algorithm> #include <string> #include <vector> @@ -25,24 +23,19 @@ #include "chrome/browser/metrics/subprocess_metrics_provider.h" #include "chrome/browser/net/profile_network_context_service.h" #include "chrome/browser/net/profile_network_context_service_factory.h" +#include "chrome/browser/net/profile_network_context_service_test_utils.h" #include "chrome/browser/policy/policy_test_utils.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/profiles/profile_window.h" -#include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/browser_list.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_paths_internal.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/in_process_browser_test.h" -#include "chrome/test/base/search_test_utils.h" #include "chrome/test/base/ui_test_utils.h" #include "components/policy/policy_constants.h" #include "components/prefs/pref_service.h" -#include "components/search_engines/template_url_service.h" #include "content/public/browser/storage_partition.h" #include "content/public/common/content_features.h" #include "content/public/test/simple_url_loader_test_helper.h" @@ -62,7 +55,6 @@ #include "testing/gtest/include/gtest/gtest.h" #if defined(OS_CHROMEOS) -#include "base/test/scoped_feature_list.h" #include "chrome/browser/chromeos/policy/login_policy_test_base.h" #include "chrome/browser/chromeos/policy/user_policy_test_helper.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" @@ -247,28 +239,14 @@ CheckCacheReset(); } -enum class AmbientAuthProfileBit { - INCOGNITO = 1, - GUEST = 2, -}; - -// Indicates the state of the feature flags -// |kEnableAmbientAuthenticationInIncognito| and -// |kEnableAmbientAuthenticationInGuestSession| -enum class AmbientAuthenticationFeatureState { - GUEST_OFF_INCOGNITO_OFF = 0, // 00 - GUEST_OFF_INCOGNITO_ON = 1, // 01 - GUEST_ON_INCOGNITO_OFF = 2, // 10 - GUEST_ON_INCOGNITO_ON = 3, // 11 -}; - class AmbientAuthenticationTestWithPolicy : public policy::PolicyTest, public testing::WithParamInterface<AmbientAuthenticationFeatureState> { public: AmbientAuthenticationTestWithPolicy() { feature_state_ = GetParam(); - CookTheFeatureList(); + AmbientAuthenticationTestHelper::CookTheFeatureList(scoped_feature_list_, + feature_state_); policy::PolicyTest::SetUpInProcessBrowserTestFixture(); } @@ -277,115 +255,29 @@ int policy_value = service->GetInteger(prefs::kAmbientAuthenticationInPrivateModesEnabled); - EXPECT_TRUE(IsAmbientAuthAllowedForProfile(GetRegularProfile())); - EXPECT_EQ(IsAmbientAuthAllowedForProfile(GetIncognitoProfile()), - IsIncognitoAllowedInFeature() || - IsIncognitoAllowedInPolicy(policy_value)); + Profile* regular_profile = browser()->profile(); + Profile* incognito_profile = regular_profile->GetOffTheRecordProfile(); + + EXPECT_TRUE(AmbientAuthenticationTestHelper::IsAmbientAuthAllowedForProfile( + regular_profile)); + EXPECT_EQ(AmbientAuthenticationTestHelper::IsAmbientAuthAllowedForProfile( + incognito_profile), + AmbientAuthenticationTestHelper::IsIncognitoAllowedInFeature( + feature_state_) || + AmbientAuthenticationTestHelper::IsIncognitoAllowedInPolicy( + policy_value)); // ChromeOS guest sessions don't have the capability to // do ambient authentications. #if !defined(OS_CHROMEOS) - EXPECT_EQ( - IsAmbientAuthAllowedForProfile(GetGuestProfile()), - IsGuestAllowedInFeature() || IsGuestAllowedInPolicy(policy_value)); + EXPECT_EQ(AmbientAuthenticationTestHelper::IsAmbientAuthAllowedForProfile( + AmbientAuthenticationTestHelper::GetGuestProfile()), + AmbientAuthenticationTestHelper::IsGuestAllowedInFeature( + feature_state_) || + AmbientAuthenticationTestHelper::IsGuestAllowedInPolicy( + policy_value)); #endif } - protected: - inline bool IsIncognitoAllowedInFeature() const { - return static_cast<int>(feature_state_) & - static_cast<int>(AmbientAuthProfileBit::INCOGNITO); - } - - inline bool IsGuestAllowedInFeature() const { - return static_cast<int>(feature_state_) & - static_cast<int>(AmbientAuthProfileBit::GUEST); - } - - inline bool IsIncognitoAllowedInPolicy(int policy_value) const { - return policy_value & static_cast<int>(AmbientAuthProfileBit::INCOGNITO); - } - - inline bool IsGuestAllowedInPolicy(int policy_value) const { - return policy_value & static_cast<int>(AmbientAuthProfileBit::GUEST); - } - - void CookTheFeatureList() { - std::vector<base::Feature> enabled_feature_list; - std::vector<base::Feature> disabled_feature_list; - - if (IsIncognitoAllowedInFeature()) - enabled_feature_list.push_back( - features::kEnableAmbientAuthenticationInIncognito); - else - disabled_feature_list.push_back( - features::kEnableAmbientAuthenticationInIncognito); - - if (IsGuestAllowedInFeature()) - enabled_feature_list.push_back( - features::kEnableAmbientAuthenticationInGuestSession); - else - disabled_feature_list.push_back( - features::kEnableAmbientAuthenticationInGuestSession); - - scoped_feature_list_.InitWithFeatures(enabled_feature_list, - disabled_feature_list); - } - - Profile* GetIncognitoProfile() { - Profile* regular_profile = browser()->profile(); - Profile* off_the_record_profile = regular_profile->GetOffTheRecordProfile(); - EXPECT_TRUE(regular_profile->HasOffTheRecordProfile()); - return off_the_record_profile; - } - - Profile* GetGuestProfile() { - Profile* guest_profile = OpenGuestBrowser()->profile(); - return guest_profile; - } - - Profile* GetRegularProfile() { return browser()->profile(); } - - bool IsAmbientAuthAllowedForProfile(Profile* profile) { - ProfileNetworkContextService* profile_network_context_service = - ProfileNetworkContextServiceFactory::GetForContext(profile); - base::FilePath empty_relative_partition_path; - network::mojom::NetworkContextParamsPtr network_context_params_ptr = - profile_network_context_service->CreateNetworkContextParams( - /*in_memory=*/false, empty_relative_partition_path); - return network_context_params_ptr->http_auth_static_network_context_params - ->allow_default_credentials == - net::HttpAuthPreferences::ALLOW_DEFAULT_CREDENTIALS; - } - // OpenGuestBrowser method code borrowed from - // chrome/browser/profiles/profile_window_browsertest.cc - Browser* OpenGuestBrowser() { - size_t num_browsers = BrowserList::GetInstance()->size(); - - // Create a guest browser nicely. Using CreateProfile() and CreateBrowser() - // does incomplete initialization that would lead to - // SystemUrlRequestContextGetter being leaked. - profiles::SwitchToGuestProfile(ProfileManager::CreateCallback()); - ui_test_utils::WaitForBrowserToOpen(); - - DCHECK_NE(static_cast<Profile*>(nullptr), - g_browser_process->profile_manager()->GetProfileByPath( - ProfileManager::GetGuestProfilePath())); - EXPECT_EQ(num_browsers + 1, BrowserList::GetInstance()->size()); - - Profile* guest = g_browser_process->profile_manager()->GetProfileByPath( - ProfileManager::GetGuestProfilePath()); - Browser* browser = chrome::FindAnyBrowser(guest, true); - EXPECT_TRUE(browser); - - // When |browser| closes a BrowsingDataRemover will be created and executed. - // It needs a loaded TemplateUrlService or else it hangs on to a - // CallbackList::Subscription forever. - search_test_utils::WaitForTemplateURLServiceToLoad( - TemplateURLServiceFactory::GetForProfile(guest)); - - return browser; - } - void EnablePolicyWithValue(net::AmbientAuthAllowedProfileTypes value) { SetPolicy(&policies_, policy::key::kAmbientAuthenticationInPrivateModesEnabled, @@ -400,7 +292,7 @@ }; INSTANTIATE_TEST_CASE_P( - , + AmbientAuthAllFeatureValuesTest, AmbientAuthenticationTestWithPolicy, testing::Values(AmbientAuthenticationFeatureState::GUEST_OFF_INCOGNITO_OFF, AmbientAuthenticationFeatureState::GUEST_OFF_INCOGNITO_ON,
diff --git a/chrome/browser/net/profile_network_context_service_test_utils.cc b/chrome/browser/net/profile_network_context_service_test_utils.cc new file mode 100644 index 0000000..b768aac --- /dev/null +++ b/chrome/browser/net/profile_network_context_service_test_utils.cc
@@ -0,0 +1,119 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/net/profile_network_context_service_test_utils.h" + +#include "base/test/scoped_feature_list.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/net/profile_network_context_service.h" +#include "chrome/browser/net/profile_network_context_service_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_window.h" +#include "chrome/browser/search_engines/template_url_service_factory.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/browser_list.h" +#include "chrome/common/chrome_features.h" +#include "chrome/test/base/search_test_utils.h" +#include "chrome/test/base/ui_test_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +enum class AmbientAuthProfileBit { + INCOGNITO = 1 << 0, + GUEST = 1 << 1, +}; + +bool AmbientAuthenticationTestHelper::IsIncognitoAllowedInFeature( + const AmbientAuthenticationFeatureState& feature_state) { + return static_cast<int>(feature_state) & + static_cast<int>(AmbientAuthProfileBit::INCOGNITO); +} + +bool AmbientAuthenticationTestHelper::IsGuestAllowedInFeature( + const AmbientAuthenticationFeatureState& feature_state) { + return static_cast<int>(feature_state) & + static_cast<int>(AmbientAuthProfileBit::GUEST); +} + +bool AmbientAuthenticationTestHelper::IsIncognitoAllowedInPolicy( + int policy_value) { + return policy_value & static_cast<int>(AmbientAuthProfileBit::INCOGNITO); +} + +bool AmbientAuthenticationTestHelper::IsGuestAllowedInPolicy(int policy_value) { + return policy_value & static_cast<int>(AmbientAuthProfileBit::GUEST); +} + +void AmbientAuthenticationTestHelper::CookTheFeatureList( + base::test::ScopedFeatureList& scoped_feature_list, + const AmbientAuthenticationFeatureState& feature_state) { + std::vector<base::Feature> enabled_feature_list; + std::vector<base::Feature> disabled_feature_list; + + if (IsIncognitoAllowedInFeature(feature_state)) { + enabled_feature_list.push_back( + features::kEnableAmbientAuthenticationInIncognito); + } else { + disabled_feature_list.push_back( + features::kEnableAmbientAuthenticationInIncognito); + } + + if (IsGuestAllowedInFeature(feature_state)) { + enabled_feature_list.push_back( + features::kEnableAmbientAuthenticationInGuestSession); + } else { + disabled_feature_list.push_back( + features::kEnableAmbientAuthenticationInGuestSession); + } + scoped_feature_list.InitWithFeatures(enabled_feature_list, + disabled_feature_list); +} + +Profile* AmbientAuthenticationTestHelper::GetGuestProfile() { + Profile* guest_profile = OpenGuestBrowser()->profile(); + return guest_profile; +} + +bool AmbientAuthenticationTestHelper::IsAmbientAuthAllowedForProfile( + Profile* profile) { + ProfileNetworkContextService* profile_network_context_service = + ProfileNetworkContextServiceFactory::GetForContext(profile); + base::FilePath empty_relative_partition_path; + network::mojom::NetworkContextParamsPtr network_context_params_ptr = + profile_network_context_service->CreateNetworkContextParams( + /*in_memory=*/false, empty_relative_partition_path); + return network_context_params_ptr->http_auth_static_network_context_params + ->allow_default_credentials == + net::HttpAuthPreferences::ALLOW_DEFAULT_CREDENTIALS; +} + +// OpenGuestBrowser method code borrowed from +// chrome/browser/profiles/profile_window_browsertest.cc +Browser* AmbientAuthenticationTestHelper::OpenGuestBrowser() { + size_t num_browsers = BrowserList::GetInstance()->size(); + + // Create a guest browser nicely. Using CreateProfile() and CreateBrowser() + // does incomplete initialization that would lead to + // SystemUrlRequestContextGetter being leaked. + profiles::SwitchToGuestProfile(ProfileManager::CreateCallback()); + ui_test_utils::WaitForBrowserToOpen(); + + DCHECK_NE(static_cast<Profile*>(nullptr), + g_browser_process->profile_manager()->GetProfileByPath( + ProfileManager::GetGuestProfilePath())); + EXPECT_EQ(num_browsers + 1, BrowserList::GetInstance()->size()); + + Profile* guest = g_browser_process->profile_manager()->GetProfileByPath( + ProfileManager::GetGuestProfilePath()); + Browser* browser = chrome::FindAnyBrowser(guest, true); + EXPECT_TRUE(browser); + + // When |browser| closes a BrowsingDataRemover will be created and executed. + // It needs a loaded TemplateUrlService or else it hangs on to a + // CallbackList::Subscription forever. + search_test_utils::WaitForTemplateURLServiceToLoad( + TemplateURLServiceFactory::GetForProfile(guest)); + + return browser; +}
diff --git a/chrome/browser/net/profile_network_context_service_test_utils.h b/chrome/browser/net/profile_network_context_service_test_utils.h new file mode 100644 index 0000000..71cab96 --- /dev/null +++ b/chrome/browser/net/profile_network_context_service_test_utils.h
@@ -0,0 +1,45 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_NET_PROFILE_NETWORK_CONTEXT_SERVICE_TEST_UTILS_H_ +#define CHROME_BROWSER_NET_PROFILE_NETWORK_CONTEXT_SERVICE_TEST_UTILS_H_ + +#include "base/test/scoped_feature_list.h" +#include "chrome/browser/ui/browser.h" + +// Indicates the state of the feature flags +// |kEnableAmbientAuthenticationInIncognito| and +// |kEnableAmbientAuthenticationInGuestSession| +enum class AmbientAuthenticationFeatureState { + GUEST_OFF_INCOGNITO_OFF = 0, // 00 + GUEST_OFF_INCOGNITO_ON = 1, // 01 + GUEST_ON_INCOGNITO_OFF = 2, // 10 + GUEST_ON_INCOGNITO_ON = 3, // 11 +}; + +class AmbientAuthenticationTestHelper { + public: + AmbientAuthenticationTestHelper() = default; + + static bool IsAmbientAuthAllowedForProfile(Profile* profile); + + static bool IsIncognitoAllowedInFeature( + const AmbientAuthenticationFeatureState& feature_state); + static bool IsIncognitoAllowedInPolicy(int policy_value); + + static bool IsGuestAllowedInFeature( + const AmbientAuthenticationFeatureState& feature_state); + static bool IsGuestAllowedInPolicy(int policy_value); + + static Profile* GetGuestProfile(); + // OpenGuestBrowser method code borrowed from + // chrome/browser/profiles/profile_window_browsertest.cc + static Browser* OpenGuestBrowser(); + + static void CookTheFeatureList( + base::test::ScopedFeatureList& scoped_feature_list, + const AmbientAuthenticationFeatureState& feature_state); +}; + +#endif // CHROME_BROWSER_NET_PROFILE_NETWORK_CONTEXT_SERVICE_TEST_UTILS_H_
diff --git a/chrome/browser/predictors/loading_predictor_browsertest.cc b/chrome/browser/predictors/loading_predictor_browsertest.cc index 80f1763..bf69197 100644 --- a/chrome/browser/predictors/loading_predictor_browsertest.cc +++ b/chrome/browser/predictors/loading_predictor_browsertest.cc
@@ -19,7 +19,6 @@ #include "base/task/post_task.h" #include "base/test/scoped_feature_list.h" #include "chrome/browser/browser_features.h" -#include "chrome/browser/navigation_predictor/navigation_predictor_preconnect_client.h" #include "chrome/browser/predictors/loading_predictor.h" #include "chrome/browser/predictors/loading_predictor_factory.h" #include "chrome/browser/predictors/loading_test_util.h" @@ -931,8 +930,7 @@ case NetworkIsolationKeyMode::kNone: scoped_feature_list2_.InitWithFeatures( // enabled_features - {features::kLoadingPreconnectToRedirectTarget, - features::kNavigationPredictorPreconnectHoldback}, + {features::kLoadingPreconnectToRedirectTarget}, // disabled_features {net::features::kPartitionConnectionsByNetworkIsolationKey, net::features::kSplitCacheByNetworkIsolationKey, @@ -947,8 +945,7 @@ // unfortunate if splitting the cache by the key as well broke // them. net::features::kSplitCacheByNetworkIsolationKey, - features::kLoadingPreconnectToRedirectTarget, - features::kNavigationPredictorPreconnectHoldback}, + features::kLoadingPreconnectToRedirectTarget}, // disabled_features {net::features::kAppendFrameOriginToNetworkIsolationKey}); break; @@ -958,8 +955,7 @@ {net::features::kPartitionConnectionsByNetworkIsolationKey, net::features::kSplitCacheByNetworkIsolationKey, net::features::kAppendFrameOriginToNetworkIsolationKey, - features::kLoadingPreconnectToRedirectTarget, - features::kNavigationPredictorPreconnectHoldback}, + features::kLoadingPreconnectToRedirectTarget}, // disabled_features {}); break;
diff --git a/chrome/browser/profiles/profile_metrics.cc b/chrome/browser/profiles/profile_metrics.cc index 353f189..94127c80 100644 --- a/chrome/browser/profiles/profile_metrics.cc +++ b/chrome/browser/profiles/profile_metrics.cc
@@ -78,28 +78,6 @@ return metric; } -void LogLockedProfileInformation(ProfileManager* manager) { - base::Time now = base::Time::Now(); - const int kMinutesInProfileValidDuration = - base::TimeDelta::FromDays(28).InMinutes(); - std::vector<ProfileAttributesEntry*> entries = - manager->GetProfileAttributesStorage().GetAllProfilesAttributes(); - for (ProfileAttributesEntry* entry : entries) { - // Find when locked profiles were locked - if (entry->IsSigninRequired()) { - base::TimeDelta time_since_lock = now - entry->GetActiveTime(); - // Specifying 100 buckets for the histogram to get a higher level of - // granularity in the reported data, given the large number of possible - // values (kMinutesInProfileValidDuration > 40,000). - UMA_HISTOGRAM_CUSTOM_COUNTS("Profile.LockedProfilesDuration", - time_since_lock.InMinutes(), - 1, - kMinutesInProfileValidDuration, - 100); - } - } -} - bool HasProfileBeenActiveSince(const ProfileAttributesEntry* entry, const base::Time& active_limit) { #if !defined(OS_ANDROID) @@ -245,13 +223,8 @@ void ProfileMetrics::LogNumberOfProfiles(ProfileManager* manager) { profile_metrics::Counts counts; - bool success = CountProfileInformation(manager, &counts); - + CountProfileInformation(manager, &counts); profile_metrics::LogProfileMetricsCounts(counts); - - // Ignore other metrics if we have no profiles. - if (success) - LogLockedProfileInformation(manager); } void ProfileMetrics::LogProfileAddNewUser(ProfileAdd metric) {
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc index 1cd31474..e369057 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -2410,8 +2410,8 @@ GetBrowser(), password_manager::ManagePasswordsReferrer::kPasswordContextMenu); password_manager::metrics_util::LogContextOfShowAllSavedPasswordsAccepted( - password_manager::metrics_util:: - SHOW_ALL_SAVED_PASSWORDS_CONTEXT_CONTEXT_MENU); + password_manager::metrics_util::ShowAllSavedPasswordsContext:: + kContextMenu); break; case IDC_CONTENT_CONTEXT_PICTUREINPICTURE:
diff --git a/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc b/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc index 4336ec6..8147eb0 100644 --- a/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc +++ b/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc
@@ -163,11 +163,12 @@ bool available = false; switch (format) { case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT: { - bool plain = clipboard->IsFormatAvailable( + available = clipboard->IsFormatAvailable( ui::ClipboardFormatType::GetPlainTextType(), clipboard_buffer); - bool plainw = clipboard->IsFormatAvailable( - ui::ClipboardFormatType::GetPlainTextWType(), clipboard_buffer); - available = plain || plainw; +#if defined(OS_WIN) + available |= clipboard->IsFormatAvailable( + ui::ClipboardFormatType::GetPlainTextAType(), clipboard_buffer); +#endif break; } case PP_FLASH_CLIPBOARD_FORMAT_HTML: @@ -212,7 +213,7 @@ switch (format) { case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT: { if (clipboard->IsFormatAvailable( - ui::ClipboardFormatType::GetPlainTextWType(), clipboard_buffer)) { + ui::ClipboardFormatType::GetPlainTextType(), clipboard_buffer)) { base::string16 text; clipboard->ReadText(clipboard_buffer, &text); if (!text.empty()) { @@ -221,13 +222,15 @@ break; } } - // If the PlainTextW format isn't available or is empty, take the +#if defined(OS_WIN) + // If the PlainText format isn't available or is empty, take the // ASCII text format. if (clipboard->IsFormatAvailable( - ui::ClipboardFormatType::GetPlainTextType(), clipboard_buffer)) { + ui::ClipboardFormatType::GetPlainTextAType(), clipboard_buffer)) { result = PP_OK; clipboard->ReadAsciiText(clipboard_buffer, &clipboard_string); } +#endif break; } case PP_FLASH_CLIPBOARD_FORMAT_HTML: {
diff --git a/chrome/browser/resources/management/BUILD.gn b/chrome/browser/resources/management/BUILD.gn index 4e27e41..eac86d91 100644 --- a/chrome/browser/resources/management/BUILD.gn +++ b/chrome/browser/resources/management/BUILD.gn
@@ -23,9 +23,7 @@ } js_library("management_browser_proxy") { - deps = [ - "//ui/webui/resources/js:cr.m", - ] + deps = [ "//ui/webui/resources/js:cr.m" ] } polymer_modulizer("management_ui") {
diff --git a/chrome/browser/resources/ntp4/incognito_tab.html b/chrome/browser/resources/ntp4/incognito_tab.html index f690ec9..c4ca611 100644 --- a/chrome/browser/resources/ntp4/incognito_tab.html +++ b/chrome/browser/resources/ntp4/incognito_tab.html
@@ -13,7 +13,7 @@ <script> // Until themes can clear the cache, force-reload the theme stylesheet. document.write('<link id="incognitothemecss" rel="stylesheet" ' + - 'href="chrome://theme/css/incognito_new_tab_theme.css?' + + 'href="chrome://theme/css/incognito_tab_theme.css?' + Date.now() + '">'); </script> </head>
diff --git a/chrome/browser/resources/ntp4/incognito_tab.js b/chrome/browser/resources/ntp4/incognito_tab.js index 4af622a..845c7a5 100644 --- a/chrome/browser/resources/ntp4/incognito_tab.js +++ b/chrome/browser/resources/ntp4/incognito_tab.js
@@ -7,7 +7,7 @@ document.documentElement.setAttribute( 'hascustombackground', themeData.hasCustomBackground); $('incognitothemecss').href = - 'chrome://theme/css/incognito_new_tab_theme.css?' + Date.now(); + 'chrome://theme/css/incognito_tab_theme.css?' + Date.now(); }); chrome.send('observeThemeChanges');
diff --git a/chrome/browser/resources/ntp4/new_incognito_tab_theme.css b/chrome/browser/resources/ntp4/incognito_tab_theme.css similarity index 100% rename from chrome/browser/resources/ntp4/new_incognito_tab_theme.css rename to chrome/browser/resources/ntp4/incognito_tab_theme.css
diff --git a/chrome/browser/sharing/click_to_call/click_to_call_context_menu_observer_unittest.cc b/chrome/browser/sharing/click_to_call/click_to_call_context_menu_observer_unittest.cc index d29728f..a5bcfe7 100644 --- a/chrome/browser/sharing/click_to_call/click_to_call_context_menu_observer_unittest.cc +++ b/chrome/browser/sharing/click_to_call/click_to_call_context_menu_observer_unittest.cc
@@ -17,6 +17,7 @@ #include "chrome/browser/renderer_context_menu/mock_render_view_context_menu.h" #include "chrome/browser/sharing/click_to_call/click_to_call_utils.h" #include "chrome/browser/sharing/click_to_call/feature.h" +#include "chrome/browser/sharing/features.h" #include "chrome/browser/sharing/mock_sharing_service.h" #include "chrome/browser/sharing/sharing_constants.h" #include "chrome/browser/sharing/sharing_service_factory.h" @@ -135,10 +136,12 @@ item.command_id); // Emulate click on the device. - EXPECT_CALL(*service(), - SendMessageToDevice(Property(&syncer::DeviceInfo::guid, guid), - Eq(kSendMessageTimeout), - ProtoEquals(sharing_message), _)) + EXPECT_CALL( + *service(), + SendMessageToDevice( + Property(&syncer::DeviceInfo::guid, guid), + Eq(base::TimeDelta::FromSeconds(kSharingMessageTTLSeconds.Get())), + ProtoEquals(sharing_message), _)) .Times(1); menu_.ExecuteCommand(IDC_CONTENT_CONTEXT_SHARING_CLICK_TO_CALL_SINGLE_DEVICE, 0); @@ -172,10 +175,12 @@ // assigned. for (int i = 0; i < kMaxDevicesShown; i++) { if (i < device_count) { - EXPECT_CALL(*service(), - SendMessageToDevice( - Property(&syncer::DeviceInfo::guid, guids[i]), - Eq(kSendMessageTimeout), ProtoEquals(sharing_message), _)) + EXPECT_CALL( + *service(), + SendMessageToDevice( + Property(&syncer::DeviceInfo::guid, guids[i]), + Eq(base::TimeDelta::FromSeconds(kSharingMessageTTLSeconds.Get())), + ProtoEquals(sharing_message), _)) .Times(1); } else { EXPECT_CALL(*service(), SendMessageToDevice(_, _, _, _)).Times(0); @@ -214,10 +219,12 @@ // range too. for (int i = 0; i < device_count; i++) { if (i < kMaxDevicesShown) { - EXPECT_CALL(*service(), - SendMessageToDevice( - Property(&syncer::DeviceInfo::guid, guids[i]), - Eq(kSendMessageTimeout), ProtoEquals(sharing_message), _)) + EXPECT_CALL( + *service(), + SendMessageToDevice( + Property(&syncer::DeviceInfo::guid, guids[i]), + Eq(base::TimeDelta::FromSeconds(kSharingMessageTTLSeconds.Get())), + ProtoEquals(sharing_message), _)) .Times(1); } else { EXPECT_CALL(*service(), SendMessageToDevice(_, _, _, _)).Times(0);
diff --git a/chrome/browser/sharing/click_to_call/click_to_call_ui_controller_unittest.cc b/chrome/browser/sharing/click_to_call/click_to_call_ui_controller_unittest.cc index 5a9dff3e..99efbe1f 100644 --- a/chrome/browser/sharing/click_to_call/click_to_call_ui_controller_unittest.cc +++ b/chrome/browser/sharing/click_to_call/click_to_call_ui_controller_unittest.cc
@@ -11,6 +11,7 @@ #include "base/strings/strcat.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/sharing/fake_device_info.h" +#include "chrome/browser/sharing/features.h" #include "chrome/browser/sharing/mock_sharing_service.h" #include "chrome/browser/sharing/sharing_constants.h" #include "chrome/browser/sharing/sharing_service_factory.h" @@ -26,6 +27,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" +using ::testing::Eq; using ::testing::Property; namespace { @@ -84,15 +86,17 @@ kExpectedPhoneNumber); EXPECT_CALL( *service(), - SendMessageToDevice(Property(&syncer::DeviceInfo::guid, kReceiverGuid), - testing::Eq(kSendMessageTimeout), - ProtoEquals(sharing_message), testing::_)); + SendMessageToDevice( + Property(&syncer::DeviceInfo::guid, kReceiverGuid), + Eq(base::TimeDelta::FromSeconds(kSharingMessageTTLSeconds.Get())), + ProtoEquals(sharing_message), testing::_)); controller_->OnDeviceChosen(*device_info.get()); } // Check the call to sharing service to get all synced devices. TEST_F(ClickToCallUiControllerTest, GetSyncedDevices) { - EXPECT_CALL(*service(), GetDeviceCandidates(testing::Eq( - sync_pb::SharingSpecificFields::CLICK_TO_CALL))); + EXPECT_CALL( + *service(), + GetDeviceCandidates(Eq(sync_pb::SharingSpecificFields::CLICK_TO_CALL))); controller_->GetDevices(); }
diff --git a/chrome/browser/sharing/features.cc b/chrome/browser/sharing/features.cc index 38355f8..669c8a0 100644 --- a/chrome/browser/sharing/features.cc +++ b/chrome/browser/sharing/features.cc
@@ -18,3 +18,15 @@ const base::FeatureParam<int> kSharingDeviceExpirationHours = { &kSharingDeviceExpiration, "SharingDeviceExpirationHours", 48}; + +const base::Feature kSharingMessageTTL{"SharingMessageTTL", + base::FEATURE_DISABLED_BY_DEFAULT}; + +const base::FeatureParam<int> kSharingMessageTTLSeconds = { + &kSharingMessageTTL, "SharingMessageTTLSeconds", 16}; + +const base::Feature kSharingAckMessageTTL{"SharingAckMessageTTL", + base::FEATURE_DISABLED_BY_DEFAULT}; + +const base::FeatureParam<int> kSharingAckMessageTTLSeconds = { + &kSharingAckMessageTTL, "SharingAckMessageTTLSeconds", 8};
diff --git a/chrome/browser/sharing/features.h b/chrome/browser/sharing/features.h index 97b82ecc..8a13160 100644 --- a/chrome/browser/sharing/features.h +++ b/chrome/browser/sharing/features.h
@@ -24,4 +24,18 @@ // The number of hours after which a device is considered expired. extern const base::FeatureParam<int> kSharingDeviceExpirationHours; +// Feature flag for configuring the sharing message timeout. This sets both the +// FCM message TTL and the duration of the timer that waits for an ack. +extern const base::Feature kSharingMessageTTL; + +// The duration in seconds for both the FCM message TTL and the timer that waits +// for an ack. +extern const base::FeatureParam<int> kSharingMessageTTLSeconds; + +// Feature flag for configuring the FCM TTL for sharing ack messages. +extern const base::Feature kSharingAckMessageTTL; + +// The FCM TTL in seconds for sharing ack messages. +extern const base::FeatureParam<int> kSharingAckMessageTTLSeconds; + #endif // CHROME_BROWSER_SHARING_FEATURES_H_
diff --git a/chrome/browser/sharing/shared_clipboard/shared_clipboard_context_menu_observer_unittest.cc b/chrome/browser/sharing/shared_clipboard/shared_clipboard_context_menu_observer_unittest.cc index d1e8c7c..bf30e9a 100644 --- a/chrome/browser/sharing/shared_clipboard/shared_clipboard_context_menu_observer_unittest.cc +++ b/chrome/browser/sharing/shared_clipboard/shared_clipboard_context_menu_observer_unittest.cc
@@ -14,6 +14,7 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/renderer_context_menu/mock_render_view_context_menu.h" +#include "chrome/browser/sharing/features.h" #include "chrome/browser/sharing/mock_sharing_service.h" #include "chrome/browser/sharing/shared_clipboard/feature_flags.h" #include "chrome/browser/sharing/sharing_constants.h" @@ -134,10 +135,12 @@ item.command_id); // Emulate click on the device. - EXPECT_CALL(*service(), - SendMessageToDevice(Property(&syncer::DeviceInfo::guid, guid), - Eq(kSendMessageTimeout), - ProtoEquals(sharing_message), _)) + EXPECT_CALL( + *service(), + SendMessageToDevice( + Property(&syncer::DeviceInfo::guid, guid), + Eq(base::TimeDelta::FromSeconds(kSharingMessageTTLSeconds.Get())), + ProtoEquals(sharing_message), _)) .Times(1); menu_.ExecuteCommand( IDC_CONTENT_CONTEXT_SHARING_SHARED_CLIPBOARD_SINGLE_DEVICE, 0); @@ -171,10 +174,12 @@ // assigned. for (int i = 0; i < kMaxDevicesShown; i++) { if (i < device_count) { - EXPECT_CALL(*service(), - SendMessageToDevice( - Property(&syncer::DeviceInfo::guid, guids[i]), - Eq(kSendMessageTimeout), ProtoEquals(sharing_message), _)) + EXPECT_CALL( + *service(), + SendMessageToDevice( + Property(&syncer::DeviceInfo::guid, guids[i]), + Eq(base::TimeDelta::FromSeconds(kSharingMessageTTLSeconds.Get())), + ProtoEquals(sharing_message), _)) .Times(1); } else { EXPECT_CALL(*service(), SendMessageToDevice(_, _, _, _)).Times(0); @@ -213,10 +218,12 @@ // range too. for (int i = 0; i < device_count; i++) { if (i < kMaxDevicesShown) { - EXPECT_CALL(*service(), - SendMessageToDevice( - Property(&syncer::DeviceInfo::guid, guids[i]), - Eq(kSendMessageTimeout), ProtoEquals(sharing_message), _)) + EXPECT_CALL( + *service(), + SendMessageToDevice( + Property(&syncer::DeviceInfo::guid, guids[i]), + Eq(base::TimeDelta::FromSeconds(kSharingMessageTTLSeconds.Get())), + ProtoEquals(sharing_message), _)) .Times(1); } else { EXPECT_CALL(*service(), SendMessageToDevice(_, _, _, _)).Times(0);
diff --git a/chrome/browser/sharing/shared_clipboard/shared_clipboard_ui_controller_unittest.cc b/chrome/browser/sharing/shared_clipboard/shared_clipboard_ui_controller_unittest.cc index 98f0cfe..dbd00e8 100644 --- a/chrome/browser/sharing/shared_clipboard/shared_clipboard_ui_controller_unittest.cc +++ b/chrome/browser/sharing/shared_clipboard/shared_clipboard_ui_controller_unittest.cc
@@ -11,6 +11,7 @@ #include "base/strings/strcat.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/sharing/fake_device_info.h" +#include "chrome/browser/sharing/features.h" #include "chrome/browser/sharing/mock_sharing_service.h" #include "chrome/browser/sharing/sharing_constants.h" #include "chrome/browser/sharing/sharing_service_factory.h" @@ -26,6 +27,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" +using ::testing::Eq; using ::testing::Property; namespace { @@ -88,16 +90,17 @@ sharing_message.mutable_shared_clipboard_message()->set_text(kExpectedText); EXPECT_CALL( *service(), - SendMessageToDevice(Property(&syncer::DeviceInfo::guid, kReceiverGuid), - testing::Eq(kSendMessageTimeout), - ProtoEquals(sharing_message), testing::_)); + SendMessageToDevice( + Property(&syncer::DeviceInfo::guid, kReceiverGuid), + Eq(base::TimeDelta::FromSeconds(kSharingMessageTTLSeconds.Get())), + ProtoEquals(sharing_message), testing::_)); controller_->OnDeviceChosen(*device_info.get()); } // Check the call to sharing service to get all synced devices. TEST_F(SharedClipboardUiControllerTest, GetSyncedDevices) { EXPECT_CALL(*service(), - GetDeviceCandidates(testing::Eq( - sync_pb::SharingSpecificFields::SHARED_CLIPBOARD))); + GetDeviceCandidates( + Eq(sync_pb::SharingSpecificFields::SHARED_CLIPBOARD))); controller_->GetDevices(); }
diff --git a/chrome/browser/sharing/sharing_constants.cc b/chrome/browser/sharing/sharing_constants.cc index f72b0d3..4e3e41b 100644 --- a/chrome/browser/sharing/sharing_constants.cc +++ b/chrome/browser/sharing/sharing_constants.cc
@@ -8,15 +8,6 @@ const char kSharingSenderID[] = "379932496580"; -// Based on Stable + Beta metrics on 23-Oct-2019, 95th percentile of round trip -// time (Sharing.MessageAckTime) is ~16 seconds. Message timeout is set as round -// trip expected time, and ack TTL is set as half of the value. -const constexpr base::TimeDelta kSendMessageTimeout = - base::TimeDelta::FromSeconds(16); - -const constexpr base::TimeDelta kAckTimeToLive = - base::TimeDelta::FromSeconds(8); - const constexpr base::TimeDelta kRegistrationExpiration = base::TimeDelta::FromDays(1);
diff --git a/chrome/browser/sharing/sharing_constants.h b/chrome/browser/sharing/sharing_constants.h index f4a09c4..5cfade7 100644 --- a/chrome/browser/sharing/sharing_constants.h +++ b/chrome/browser/sharing/sharing_constants.h
@@ -14,12 +14,6 @@ // Sender ID for Sharing. extern const char kSharingSenderID[]; -// Amount of time before a message is considered timeout if no ack is received. -extern const base::TimeDelta kSendMessageTimeout; - -// Amount of time before an ack message is expired. -extern const base::TimeDelta kAckTimeToLive; - // Amount of time before FCM registration should happen again. extern const base::TimeDelta kRegistrationExpiration;
diff --git a/chrome/browser/sharing/sharing_fcm_handler.cc b/chrome/browser/sharing/sharing_fcm_handler.cc index 9f78d706..5a67379 100644 --- a/chrome/browser/sharing/sharing_fcm_handler.cc +++ b/chrome/browser/sharing/sharing_fcm_handler.cc
@@ -6,6 +6,8 @@ #include "base/no_destructor.h" #include "base/strings/strcat.h" +#include "base/time/time.h" +#include "chrome/browser/sharing/features.h" #include "chrome/browser/sharing/sharing_constants.h" #include "chrome/browser/sharing/sharing_fcm_sender.h" #include "chrome/browser/sharing/sharing_handler_registry.h" @@ -166,7 +168,9 @@ ack_message->set_allocated_response_message(response.release()); sharing_fcm_sender_->SendMessageToTargetInfo( - std::move(*target_info), kAckTimeToLive, std::move(sharing_message), + std::move(*target_info), + base::TimeDelta::FromSeconds(kSharingAckMessageTTLSeconds.Get()), + std::move(sharing_message), base::BindOnce(&SharingFCMHandler::OnAckMessageSent, weak_ptr_factory_.GetWeakPtr(), std::move(original_message_id), original_message_type,
diff --git a/chrome/browser/sharing/sharing_fcm_handler_unittest.cc b/chrome/browser/sharing/sharing_fcm_handler_unittest.cc index f2db507..075cbe3 100644 --- a/chrome/browser/sharing/sharing_fcm_handler_unittest.cc +++ b/chrome/browser/sharing/sharing_fcm_handler_unittest.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "chrome/browser/sharing/features.h" #include "chrome/browser/sharing/sharing_constants.h" #include "chrome/browser/sharing/sharing_fcm_sender.h" #include "chrome/browser/sharing/sharing_handler_registry.h" @@ -18,7 +19,8 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -using testing::_; +using ::testing::_; +using ::testing::Eq; using SharingMessage = chrome_browser_sharing::SharingMessage; namespace { @@ -195,8 +197,10 @@ EXPECT_CALL(mock_sharing_message_handler_, OnMessage(_, _)); EXPECT_CALL( mock_sharing_fcm_sender_, - SendMessageToTargetInfo(DeviceMatcher(), testing::Eq(kAckTimeToLive), - ProtoEquals(sharing_ack_message), _)); + SendMessageToTargetInfo( + DeviceMatcher(), + Eq(base::TimeDelta::FromSeconds(kSharingAckMessageTTLSeconds.Get())), + ProtoEquals(sharing_ack_message), _)); handler_registry_->SetSharingHandler(SharingMessage::kPingMessage, &mock_sharing_message_handler_); sharing_fcm_handler_->OnMessage(kTestAppId, incoming_message); @@ -237,8 +241,10 @@ EXPECT_CALL(mock_sharing_message_handler_, OnMessage(_, _)); EXPECT_CALL( mock_sharing_fcm_sender_, - SendMessageToTargetInfo(DeviceMatcher(), testing::Eq(kAckTimeToLive), - ProtoEquals(sharing_ack_message), _)); + SendMessageToTargetInfo( + DeviceMatcher(), + Eq(base::TimeDelta::FromSeconds(kSharingAckMessageTTLSeconds.Get())), + ProtoEquals(sharing_ack_message), _)); handler_registry_->SetSharingHandler(SharingMessage::kPingMessage, &mock_sharing_message_handler_); sharing_fcm_handler_->OnMessage(kTestAppId, incoming_message); @@ -270,8 +276,10 @@ })); EXPECT_CALL( mock_sharing_fcm_sender_, - SendMessageToTargetInfo(DeviceMatcher(), testing::Eq(kAckTimeToLive), - ProtoEquals(sharing_ack_message), _)); + SendMessageToTargetInfo( + DeviceMatcher(), + Eq(base::TimeDelta::FromSeconds(kSharingAckMessageTTLSeconds.Get())), + ProtoEquals(sharing_ack_message), _)); handler_registry_->SetSharingHandler(SharingMessage::kPingMessage, &mock_sharing_message_handler_); sharing_fcm_handler_->OnMessage(kTestAppId, incoming_message); @@ -304,8 +312,10 @@ })); EXPECT_CALL( mock_sharing_fcm_sender_, - SendMessageToTargetInfo(DeviceMatcher(), testing::Eq(kAckTimeToLive), - ProtoEquals(sharing_ack_message), _)); + SendMessageToTargetInfo( + DeviceMatcher(), + Eq(base::TimeDelta::FromSeconds(kSharingAckMessageTTLSeconds.Get())), + ProtoEquals(sharing_ack_message), _)); handler_registry_->SetSharingHandler(SharingMessage::kPingMessage, &mock_sharing_message_handler_); sharing_fcm_handler_->OnMessage(kTestAppId, incoming_message);
diff --git a/chrome/browser/sharing/sharing_message_sender.cc b/chrome/browser/sharing/sharing_message_sender.cc index 16eab0f..bf6ac8f 100644 --- a/chrome/browser/sharing/sharing_message_sender.cc +++ b/chrome/browser/sharing/sharing_message_sender.cc
@@ -29,7 +29,6 @@ chrome_browser_sharing::SharingMessage message, DelegateType delegate_type, ResponseCallback callback) { - DCHECK_GE(response_timeout, kAckTimeToLive); DCHECK(message.payload_case() != chrome_browser_sharing::SharingMessage::kAckMessage); @@ -86,7 +85,7 @@ send_tab_to_self::GetSharingDeviceNames(local_device_info).full_name); delegate->DoSendMessageToDevice( - device, response_timeout - kAckTimeToLive, std::move(message), + device, response_timeout, std::move(message), base::BindOnce(&SharingMessageSender::OnMessageSent, weak_ptr_factory_.GetWeakPtr(), message_guid)); }
diff --git a/chrome/browser/sharing/sharing_service_proxy_android.cc b/chrome/browser/sharing/sharing_service_proxy_android.cc index 32e6e9c..9563aa1 100644 --- a/chrome/browser/sharing/sharing_service_proxy_android.cc +++ b/chrome/browser/sharing/sharing_service_proxy_android.cc
@@ -6,10 +6,11 @@ #include "base/android/callback_android.h" #include "base/android/jni_string.h" +#include "base/time/time.h" #include "chrome/android/chrome_jni_headers/SharingServiceProxy_jni.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_android.h" -#include "chrome/browser/sharing/sharing_constants.h" +#include "chrome/browser/sharing/features.h" #include "chrome/browser/sharing/sharing_device_source.h" #include "chrome/browser/sharing/sharing_send_message_result.h" #include "chrome/browser/sharing/sharing_service.h" @@ -64,7 +65,8 @@ base::BindOnce(base::android::RunIntCallbackAndroid, base::android::ScopedJavaGlobalRef<jobject>(j_runnable)); sharing_service_->SendMessageToDevice( - device, kSendMessageTimeout, std::move(sharing_message), + device, base::TimeDelta::FromSeconds(kSharingMessageTTLSeconds.Get()), + std::move(sharing_message), base::BindOnce( [](base::OnceCallback<void(int)> callback, SharingSendMessageResult result,
diff --git a/chrome/browser/sharing/sharing_ui_controller.cc b/chrome/browser/sharing/sharing_ui_controller.cc index cb2419f6..32ba870 100644 --- a/chrome/browser/sharing/sharing_ui_controller.cc +++ b/chrome/browser/sharing/sharing_ui_controller.cc
@@ -6,7 +6,8 @@ #include <utility> -#include "chrome/browser/sharing/sharing_constants.h" +#include "base/time/time.h" +#include "chrome/browser/sharing/features.h" #include "chrome/browser/sharing/sharing_dialog.h" #include "chrome/browser/sharing/sharing_dialog_data.h" #include "chrome/browser/sharing/sharing_service_factory.h" @@ -177,7 +178,8 @@ UpdateIcon(); sharing_service_->SendMessageToDevice( - device, kSendMessageTimeout, std::move(sharing_message), + device, base::TimeDelta::FromSeconds(kSharingMessageTTLSeconds.Get()), + std::move(sharing_message), base::Bind(&SharingUiController::OnMessageSentToDevice, weak_ptr_factory_.GetWeakPtr(), last_dialog_id_)); }
diff --git a/chrome/browser/signin/signin_ui_util.cc b/chrome/browser/signin/signin_ui_util.cc index 2fcd67c2..0db4302 100644 --- a/chrome/browser/signin/signin_ui_util.cc +++ b/chrome/browser/signin/signin_ui_util.cc
@@ -251,46 +251,27 @@ } } // namespace internal -std::vector<AccountInfo> GetAccountsForDicePromos(Profile* profile) { - // Fetch account ids for accounts that have a token. +AccountInfo GetAccountForDicePromos(Profile* profile) { signin::IdentityManager* identity_manager = IdentityManagerFactory::GetForProfile(profile); - std::vector<AccountInfo> accounts_with_tokens = - identity_manager->GetExtendedAccountInfoForAccountsWithRefreshToken(); // Compute the default account. - CoreAccountId default_account_id; - if (identity_manager->HasPrimaryAccount()) { - default_account_id = identity_manager->GetPrimaryAccountId(); - } else { - // Fetch accounts in the Gaia cookies. - auto accounts_in_cookie_jar_info = - identity_manager->GetAccountsInCookieJar(); - std::vector<gaia::ListedAccount> signed_in_accounts = - accounts_in_cookie_jar_info.signed_in_accounts; - UMA_HISTOGRAM_BOOLEAN("Profile.DiceUI.GaiaAccountsStale", - !accounts_in_cookie_jar_info.accounts_are_fresh); + CoreAccountId default_account_id = + identity_manager->GetUnconsentedPrimaryAccountId(); + AccountInfo default_account_info = + identity_manager + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + default_account_id) + .value_or(AccountInfo()); - if (accounts_in_cookie_jar_info.accounts_are_fresh && - !signed_in_accounts.empty()) - default_account_id = signed_in_accounts[0].id; + if (default_account_info.IsEmpty()) { + return default_account_info; } - - // Fetch account information for each id and make sure that the first account - // in the list matches the first account in the Gaia cookies (if available). - std::vector<AccountInfo> accounts; - for (auto& account_info : accounts_with_tokens) { - DCHECK(!account_info.IsEmpty()); - if (!signin::IsUsernameAllowedByPatternFromPrefs( - g_browser_process->local_state(), account_info.email)) { - continue; - } - if (account_info.account_id == default_account_id) - accounts.insert(accounts.begin(), std::move(account_info)); - else - accounts.push_back(std::move(account_info)); + if (signin::IsUsernameAllowedByPatternFromPrefs( + g_browser_process->local_state(), default_account_info.email)) { + return default_account_info; } - return accounts; + return AccountInfo(); } #endif // BUILDFLAG(ENABLE_DICE_SUPPORT)
diff --git a/chrome/browser/signin/signin_ui_util.h b/chrome/browser/signin/signin_ui_util.h index cb4f2c1..f3270d8 100644 --- a/chrome/browser/signin/signin_ui_util.h +++ b/chrome/browser/signin/signin_ui_util.h
@@ -53,9 +53,8 @@ bool is_default_promo_account); #if BUILDFLAG(ENABLE_DICE_SUPPORT) -// Returns the list of all accounts that have a token. The default account in -// the Gaia cookies will be the first account in the list. -std::vector<AccountInfo> GetAccountsForDicePromos(Profile* profile); +// Returns the account to use in Dice promos. +AccountInfo GetAccountForDicePromos(Profile* profile); #endif
diff --git a/chrome/browser/signin/signin_ui_util_unittest.cc b/chrome/browser/signin/signin_ui_util_unittest.cc index d5477ab2..17c48dd 100644 --- a/chrome/browser/signin/signin_ui_util_unittest.cc +++ b/chrome/browser/signin/signin_ui_util_unittest.cc
@@ -473,14 +473,14 @@ // TODO(https://crbug.com/1014790): Timeout on Mac10.12 and Win7 x64. #if defined(OS_MACOSX) || defined(OS_WIN) -#define MAYBE_GetAccountsForDicePromos DISABLED_GetAccountsForDicePromos +#define MAYBE_GetAccountForDicePromos DISABLED_GetAccountForDicePromos #else -#define MAYBE_GetAccountsForDicePromos GetAccountsForDicePromos +#define MAYBE_GetAccountForDicePromos GetAccountForDicePromos #endif -TEST_F(DiceSigninUiUtilTest, MAYBE_GetAccountsForDicePromos) { - // Should start off with no accounts. - std::vector<AccountInfo> accounts = GetAccountsForDicePromos(profile()); - EXPECT_TRUE(accounts.empty()); +TEST_F(DiceSigninUiUtilTest, MAYBE_GetAccountForDicePromos) { + // Should start off with no account. + AccountInfo info_empty = GetAccountForDicePromos(profile()); + EXPECT_TRUE(info_empty.IsEmpty()); // TODO(tangltom): Flesh out this test. }
diff --git a/chrome/browser/sync/test/integration/bookmarks_helper.cc b/chrome/browser/sync/test/integration/bookmarks_helper.cc index 7ac015a78..e579ec3 100644 --- a/chrome/browser/sync/test/integration/bookmarks_helper.cc +++ b/chrome/browser/sync/test/integration/bookmarks_helper.cc
@@ -373,6 +373,11 @@ << node_b->parent()->GetIndexOf(node_b); return false; } + if (node_a->guid() != node_b->guid()) { + LOG(ERROR) << "GUID mismatch: " << node_a->guid() << " vs. " + << node_b->guid(); + return false; + } return true; } @@ -530,7 +535,8 @@ const BookmarkNode* v_parent = nullptr; FindNodeInVerifier(model, parent, &v_parent); const BookmarkNode* v_node = GetVerifierBookmarkModel()->AddURL( - v_parent, index, base::UTF8ToUTF16(title), url); + v_parent, index, base::UTF8ToUTF16(title), url, + /*meta_info=*/nullptr, result->date_added(), result->guid()); if (!v_node) { LOG(ERROR) << "Could not add bookmark " << title << " to the verifier"; return nullptr; @@ -573,7 +579,8 @@ const BookmarkNode* v_parent = nullptr; FindNodeInVerifier(model, parent, &v_parent); const BookmarkNode* v_node = GetVerifierBookmarkModel()->AddFolder( - v_parent, index, base::UTF8ToUTF16(title)); + v_parent, index, base::UTF8ToUTF16(title), + /*meta_info=*/nullptr, result->guid()); if (!v_node) { LOG(ERROR) << "Could not add folder " << title << " to the verifier"; return nullptr;
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc b/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc index db1b020..b376b837 100644 --- a/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc +++ b/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
@@ -161,6 +161,7 @@ DCHECK_EQ(suggestions_.size(), elided_values_.size()); DCHECK_EQ(suggestions_.size(), elided_labels_.size()); + selected_line_.reset(); // Remove all the old data list values, which should always be at the top of // the list if they are present. while (!suggestions_.empty() &&
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_interactive_uitest.cc b/chrome/browser/ui/autofill/autofill_popup_controller_interactive_uitest.cc index eaca9a07..20506d3 100644 --- a/chrome/browser/ui/autofill/autofill_popup_controller_interactive_uitest.cc +++ b/chrome/browser/ui/autofill/autofill_popup_controller_interactive_uitest.cc
@@ -6,7 +6,9 @@ #include "base/macros.h" #include "build/build_config.h" +#include "chrome/browser/ui/autofill/autofill_popup_controller_impl.h" #include "chrome/browser/ui/autofill/autofill_popup_view.h" +#include "chrome/browser/ui/autofill/chrome_autofill_client.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -110,4 +112,30 @@ autofill_external_delegate_.reset(); } +// crbug.com/965025 +IN_PROC_BROWSER_TEST_F(AutofillPopupControllerBrowserTest, ResetSelectedLine) { + test::GenerateTestAutofillPopup(autofill_external_delegate_.get()); + + auto* client = + autofill::ChromeAutofillClient::FromWebContents(web_contents()); + AutofillPopupController* controller = + client->popup_controller_for_testing().get(); + ASSERT_TRUE(controller); + + // Push some suggestions and select the line #3. + std::vector<base::string16> rows = { + base::ASCIIToUTF16("suggestion1"), base::ASCIIToUTF16("suggestion2"), + base::ASCIIToUTF16("suggestion3"), base::ASCIIToUTF16("suggestion4")}; + client->UpdateAutofillPopupDataListValues(rows, rows); + controller->SetSelectedLine(3); + + // Replace the list with the smaller one. + rows = {base::ASCIIToUTF16("suggestion1")}; + client->UpdateAutofillPopupDataListValues(rows, rows); + // Make sure that previously selected line #3 doesn't exist. + ASSERT_LT(controller->GetLineCount(), 4); + // Selecting a new line should not crash. + controller->SetSelectedLine(0); +} + } // namespace autofill
diff --git a/chrome/browser/ui/input_method/input_method_engine.cc b/chrome/browser/ui/input_method/input_method_engine.cc index af44b36..1958896 100644 --- a/chrome/browser/ui/input_method/input_method_engine.cc +++ b/chrome/browser/ui/input_method/input_method_engine.cc
@@ -79,7 +79,8 @@ if (composition_.ime_text_spans.empty()) { composition_.ime_text_spans.push_back(ui::ImeTextSpan( ui::ImeTextSpan::Type::kComposition, 0, composition_.text.length(), - ui::ImeTextSpan::Thickness::kThin, SK_ColorTRANSPARENT)); + ui::ImeTextSpan::Thickness::kThin, + ui::ImeTextSpan::UnderlineStyle::kSolid, SK_ColorTRANSPARENT)); } ui::IMEInputContextHandlerInterface* input_context =
diff --git a/chrome/browser/ui/libgtkui/gtk_util.cc b/chrome/browser/ui/libgtkui/gtk_util.cc index 4a7e10b..ad76fefa 100644 --- a/chrome/browser/ui/libgtkui/gtk_util.cc +++ b/chrome/browser/ui/libgtkui/gtk_util.cc
@@ -114,11 +114,12 @@ GetIbusFlags(key_event)); } -int GetKeyboardGroup(const ui::KeyEvent& key_event) { +int GetKeyEventProperty(const ui::KeyEvent& key_event, + const char* property_key) { auto* properties = key_event.properties(); if (!properties) return 0; - auto it = properties->find(ui::kPropertyKeyboardGroup); + auto it = properties->find(property_key); DCHECK(it == properties->end() || it->second.size() == 1); return (it != properties->end()) ? it->second[0] : 0; } @@ -608,16 +609,15 @@ } int BuildXkbStateFromGdkEvent(unsigned int state, unsigned char group) { - DCHECK_EQ(0u, ((state >> 13) & 0x3)); return state | ((group & 0x3) << 13); } GdkEvent* GdkEventFromKeyEvent(const ui::KeyEvent& key_event) { GdkEventType event_type = key_event.type() == ui::ET_KEY_PRESSED ? GDK_KEY_PRESS : GDK_KEY_RELEASE; - int hw_code = ui::KeycodeConverter::DomCodeToNativeKeycode(key_event.code()); auto event_time = key_event.time_stamp() - base::TimeTicks(); - int group = GetKeyboardGroup(key_event); + int hw_code = GetKeyEventProperty(key_event, ui::kPropertyKeyboardHwKeyCode); + int group = GetKeyEventProperty(key_event, ui::kPropertyKeyboardGroup); // Get GdkKeymap GdkKeymap* keymap = gdk_keymap_get_for_display(GetGdkDisplay());
diff --git a/chrome/browser/ui/omnibox/clipboard_utils.cc b/chrome/browser/ui/omnibox/clipboard_utils.cc index 9185f23..e21cccb 100644 --- a/chrome/browser/ui/omnibox/clipboard_utils.cc +++ b/chrome/browser/ui/omnibox/clipboard_utils.cc
@@ -14,7 +14,7 @@ base::string16 GetClipboardText() { // Try text format. ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); - if (clipboard->IsFormatAvailable(ui::ClipboardFormatType::GetPlainTextWType(), + if (clipboard->IsFormatAvailable(ui::ClipboardFormatType::GetPlainTextType(), ui::ClipboardBuffer::kCopyPaste)) { base::string16 text; clipboard->ReadText(ui::ClipboardBuffer::kCopyPaste, &text); @@ -29,7 +29,7 @@ // and pastes from the URL bar to itself, the text will get fixed up and // cannonicalized, which is not what the user expects. By pasting in this // order, we are sure to paste what the user copied. - if (clipboard->IsFormatAvailable(ui::ClipboardFormatType::GetUrlWType(), + if (clipboard->IsFormatAvailable(ui::ClipboardFormatType::GetUrlType(), ui::ClipboardBuffer::kCopyPaste)) { std::string url_str; clipboard->ReadBookmark(nullptr, &url_str);
diff --git a/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view.cc b/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view.cc index 04d2d979..be50dee 100644 --- a/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view.cc +++ b/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view.cc
@@ -135,10 +135,12 @@ anchor_view = container->GetViewForId(extension()->id()); } else if (browser_view && !base::FeatureList::IsEnabled(features::kExtensionsToolbarMenu)) { + BrowserActionsContainer* const browser_actions_container = + browser_view->toolbar_button_provider()->GetBrowserActionsContainer(); ToolbarActionView* const reference_view = - browser_view->toolbar_button_provider() - ->GetBrowserActionsContainer() - ->GetViewForId(extension()->id()); + browser_actions_container + ? browser_actions_container->GetViewForId(extension()->id()) + : nullptr; if (reference_view && reference_view->GetVisible()) anchor_view = reference_view; }
diff --git a/chrome/browser/ui/views/ime/input_ime_apitest_nonchromeos.cc b/chrome/browser/ui/views/ime/input_ime_apitest_nonchromeos.cc index 17e829c..4188fbd 100644 --- a/chrome/browser/ui/views/ime/input_ime_apitest_nonchromeos.cc +++ b/chrome/browser/ui/views/ime/input_ime_apitest_nonchromeos.cc
@@ -89,7 +89,8 @@ composition.text = base::UTF8ToUTF16("test_set_composition"); composition.ime_text_spans.push_back(ui::ImeTextSpan( ui::ImeTextSpan::Type::kComposition, 0, composition.text.length(), - ui::ImeTextSpan::Thickness::kThin, SK_ColorTRANSPARENT)); + ui::ImeTextSpan::Thickness::kThin, + ui::ImeTextSpan::UnderlineStyle::kSolid, SK_ColorTRANSPARENT)); composition.selection = gfx::Range(2, 2); const std::vector<ui::CompositionText>& composition_history = client->composition_history();
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view.h b/chrome/browser/ui/views/profiles/profile_menu_view.h index 7a8b565..9b9b428 100644 --- a/chrome/browser/ui/views/profiles/profile_menu_view.h +++ b/chrome/browser/ui/views/profiles/profile_menu_view.h
@@ -32,8 +32,8 @@ class ProfileMenuView : public ProfileMenuViewBase { public: ProfileMenuView(views::Button* anchor_button, - Browser* browser, - signin_metrics::AccessPoint access_point); + Browser* browser, + signin_metrics::AccessPoint access_point); ~ProfileMenuView() override; // ProfileMenuViewBase:
diff --git a/chrome/browser/ui/views/sync/dice_bubble_sync_promo_view.cc b/chrome/browser/ui/views/sync/dice_bubble_sync_promo_view.cc index eba555f..e1ecbc3 100644 --- a/chrome/browser/ui/views/sync/dice_bubble_sync_promo_view.cc +++ b/chrome/browser/ui/views/sync/dice_bubble_sync_promo_view.cc
@@ -27,12 +27,12 @@ int accounts_promo_message_resource_id, bool signin_button_prominent, int text_style) - : views::View(), delegate_(delegate) { + : delegate_(delegate) { DCHECK(!profile->IsGuestSession()); - std::vector<AccountInfo> accounts; + AccountInfo account; // Signin promos can be shown in incognito, they use an empty account list. if (profile->IsRegularProfile()) - accounts = signin_ui_util::GetAccountsForDicePromos(profile); + account = signin_ui_util::GetAccountForDicePromos(profile); // Always show the accounts promo message for now. const int title_resource_id = accounts_promo_message_resource_id; @@ -53,25 +53,22 @@ AddChildView(title); } - if (accounts.empty()) { + if (account.IsEmpty()) { signin_button_view_ = new DiceSigninButtonView(this, signin_button_prominent); } else { - gfx::Image account_icon = accounts[0].account_image; + gfx::Image account_icon = account.account_image; if (account_icon.IsEmpty()) { account_icon = ui::ResourceBundle::GetSharedInstance().GetImageNamed( profiles::GetPlaceholderAvatarIconResourceID()); } signin_button_view_ = - new DiceSigninButtonView(accounts[0], account_icon, this, + new DiceSigninButtonView(account, account_icon, this, /*use_account_name_as_title=*/true); - - // Store account information for submenu. - accounts_for_submenu_.assign(accounts.begin() + 1, accounts.end()); } signin_metrics::RecordSigninImpressionUserActionForAccessPoint(access_point); signin_metrics::RecordSigninImpressionWithAccountUserActionForAccessPoint( - access_point, !accounts.empty() /* with_account */); + access_point, !account.IsEmpty() /* with_account */); AddChildView(signin_button_view_); }
diff --git a/chrome/browser/ui/views/sync/dice_bubble_sync_promo_view.h b/chrome/browser/ui/views/sync/dice_bubble_sync_promo_view.h index 2e7c31bd..a9f2e2fd 100644 --- a/chrome/browser/ui/views/sync/dice_bubble_sync_promo_view.h +++ b/chrome/browser/ui/views/sync/dice_bubble_sync_promo_view.h
@@ -65,8 +65,6 @@ BubbleSyncPromoDelegate* delegate_; DiceSigninButtonView* signin_button_view_ = nullptr; - std::vector<AccountInfo> accounts_for_submenu_; - DISALLOW_COPY_AND_ASSIGN(DiceBubbleSyncPromoView); }; #endif // CHROME_BROWSER_UI_VIEWS_SYNC_DICE_BUBBLE_SYNC_PROMO_VIEW_H_
diff --git a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc index bcc202d..c8b8da8 100644 --- a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc +++ b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
@@ -552,7 +552,7 @@ static const base::NoDestructor<scoped_refptr<base::RefCountedMemory>> new_tab_theme_css( ui::ResourceBundle::GetSharedInstance().LoadDataResourceBytes( - IDR_NEW_INCOGNITO_TAB_THEME_CSS)); + IDR_INCOGNITO_TAB_THEME_CSS)); CHECK(*new_tab_theme_css); // Create the string from our template and the replacements.
diff --git a/chrome/browser/ui/webui/settings/people_handler.cc b/chrome/browser/ui/webui/settings/people_handler.cc index 04cccd8..dc81e5f 100644 --- a/chrome/browser/ui/webui/settings/people_handler.cc +++ b/chrome/browser/ui/webui/settings/people_handler.cc
@@ -533,9 +533,9 @@ base::Value accounts(base::Value::Type::LIST); #if BUILDFLAG(ENABLE_DICE_SUPPORT) if (AccountConsistencyModeManager::IsDiceEnabledForProfile(profile_)) { - // If dice is enabled, show all the accounts. - for (auto const& account : - signin_ui_util::GetAccountsForDicePromos(profile_)) { + // If dice is enabled, show the account. + AccountInfo account = signin_ui_util::GetAccountForDicePromos(profile_); + if (!account.IsEmpty()) { accounts.Append(GetAccountValue(account)); } return accounts;
diff --git a/chrome/browser/ui/webui/settings/people_handler_unittest.cc b/chrome/browser/ui/webui/settings/people_handler_unittest.cc index 4c9ee8a..d51ec36 100644 --- a/chrome/browser/ui/webui/settings/people_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/people_handler_unittest.cc
@@ -1218,11 +1218,9 @@ ASSERT_TRUE(accounts.is_list()); base::Value::ConstListView accounts_list = accounts.GetList(); - ASSERT_EQ(2u, accounts_list.size()); + ASSERT_EQ(1u, accounts_list.size()); ASSERT_TRUE(accounts_list[0].FindKey("email")); - ASSERT_TRUE(accounts_list[1].FindKey("email")); EXPECT_EQ("a@gmail.com", accounts_list[0].FindKey("email")->GetString()); - EXPECT_EQ("b@gmail.com", accounts_list[1].FindKey("email")->GetString()); } #endif // BUILDFLAG(ENABLE_DICE_SUPPORT)
diff --git a/chrome/browser/ui/webui/theme_source.cc b/chrome/browser/ui/webui/theme_source.cc index 536f075..2ace3bf2 100644 --- a/chrome/browser/ui/webui/theme_source.cc +++ b/chrome/browser/ui/webui/theme_source.cc
@@ -44,10 +44,9 @@ } bool IsNewTabCssPath(const std::string& path) { - static const char kNewTabCSSPath[] = "css/new_tab_theme.css"; - static const char kIncognitoNewTabCSSPath[] = - "css/incognito_new_tab_theme.css"; - return (path == kNewTabCSSPath) || (path == kIncognitoNewTabCSSPath); + static const char kNewTabThemeCssPath[] = "css/new_tab_theme.css"; + static const char kIncognitoTabThemeCssPath[] = "css/incognito_tab_theme.css"; + return path == kNewTabThemeCssPath || path == kIncognitoTabThemeCssPath; } void ProcessImageOnUiThread(const gfx::ImageSkia& image,
diff --git a/chrome/browser/web_applications/components/app_shortcut_manager.cc b/chrome/browser/web_applications/components/app_shortcut_manager.cc index 8173ff80..71c8f53 100644 --- a/chrome/browser/web_applications/components/app_shortcut_manager.cc +++ b/chrome/browser/web_applications/components/app_shortcut_manager.cc
@@ -22,6 +22,15 @@ registrar_ = registrar; } +void AppShortcutManager::Start() { + DCHECK(registrar_); + app_registrar_observer_.Add(registrar_); +} + +void AppShortcutManager::Shutdown() { + app_registrar_observer_.RemoveAll(); +} + void AppShortcutManager::AddObserver(AppShortcutObserver* observer) { observers_.AddObserver(observer); }
diff --git a/chrome/browser/web_applications/components/app_shortcut_manager.h b/chrome/browser/web_applications/components/app_shortcut_manager.h index 8514381..e4f041e 100644 --- a/chrome/browser/web_applications/components/app_shortcut_manager.h +++ b/chrome/browser/web_applications/components/app_shortcut_manager.h
@@ -11,6 +11,9 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" +#include "base/scoped_observer.h" +#include "chrome/browser/web_applications/components/app_registrar.h" +#include "chrome/browser/web_applications/components/app_registrar_observer.h" #include "chrome/browser/web_applications/components/web_app_helpers.h" #include "chrome/browser/web_applications/components/web_app_shortcut.h" @@ -18,22 +21,26 @@ namespace web_app { -class AppRegistrar; class AppShortcutObserver; struct ShortcutInfo; +// This class manages creation/update/deletion of OS shortcuts for web +// applications. +// // TODO(crbug.com/860581): Migrate functions from // web_app_extension_shortcut.(h|cc) and -// platform_apps/shortcut_manager.(h|cc) to the AppShortcutManager, so web app -// shortcuts can be managed in an extensions agnostic way. -// Manages OS shortcuts for web applications. -class AppShortcutManager { +// platform_apps/shortcut_manager.(h|cc) to web_app::AppShortcutManager and +// its subclasses. +class AppShortcutManager : public AppRegistrarObserver { public: explicit AppShortcutManager(Profile* profile); - virtual ~AppShortcutManager(); + ~AppShortcutManager() override; void SetSubsystems(AppRegistrar* registrar); + void Start(); + void Shutdown(); + void AddObserver(AppShortcutObserver* observer); void RemoveObserver(AppShortcutObserver* observer); @@ -70,13 +77,16 @@ CreateShortcutsCallback callback, std::unique_ptr<ShortcutInfo> info); + ScopedObserver<AppRegistrar, AppRegistrarObserver> app_registrar_observer_{ + this}; + + base::ObserverList<AppShortcutObserver, /*check_empty=*/true> observers_; + bool suppress_shortcuts_for_testing_ = false; AppRegistrar* registrar_ = nullptr; Profile* const profile_; - base::ObserverList<AppShortcutObserver, /*check_empty=*/true> observers_; - base::WeakPtrFactory<AppShortcutManager> weak_ptr_factory_{this}; DISALLOW_COPY_AND_ASSIGN(AppShortcutManager);
diff --git a/chrome/browser/web_applications/components/web_app_constants.h b/chrome/browser/web_applications/components/web_app_constants.h index dc1d0746..010e164 100644 --- a/chrome/browser/web_applications/components/web_app_constants.h +++ b/chrome/browser/web_applications/components/web_app_constants.h
@@ -55,8 +55,6 @@ kWriteDataFailed = 6, // A user rejected installation prompt. kUserInstallDeclined = 7, - // A whole user profile was destroyed during installation. - kProfileDestroyed = 8, // |require_manifest| was specified but the app had no valid manifest. kNotValidManifestForWebApp = 10, // We have terminated the installation pipeline and intented to the Play @@ -84,9 +82,9 @@ kApkWebAppInstallFailed = 20, // App managers are shutting down. For example, when user logs out immediately // after login. - kFailedShuttingDown = 21, + kCancelledOnWebAppProviderShuttingDown = 21, - kMaxValue = kFailedShuttingDown + kMaxValue = kCancelledOnWebAppProviderShuttingDown }; // Checks if InstallResultCode is not a failure.
diff --git a/chrome/browser/web_applications/extensions/system_web_app_manager_unittest.cc b/chrome/browser/web_applications/extensions/system_web_app_manager_unittest.cc index 9aebe661..077c89e6 100644 --- a/chrome/browser/web_applications/extensions/system_web_app_manager_unittest.cc +++ b/chrome/browser/web_applications/extensions/system_web_app_manager_unittest.cc
@@ -426,7 +426,7 @@ system_web_app_manager()->SetSystemAppsForTesting(system_apps); pending_app_manager()->SetInstallResultCode( - InstallResultCode::kProfileDestroyed); + InstallResultCode::kWebAppDisabled); system_web_app_manager()->Start(); base::RunLoop().RunUntilIdle(); @@ -435,12 +435,12 @@ SystemWebAppManager::kInstallResultHistogramName, 3); histograms.ExpectBucketCount( SystemWebAppManager::kInstallResultHistogramName, - InstallResultCode::kProfileDestroyed, 2); + InstallResultCode::kWebAppDisabled, 2); histograms.ExpectTotalCount(settings_app_install_result_histogram, 2); histograms.ExpectBucketCount(settings_app_install_result_histogram, - InstallResultCode::kProfileDestroyed, 1); + InstallResultCode::kWebAppDisabled, 1); histograms.ExpectBucketCount(discover_app_install_result_histogram, - InstallResultCode::kProfileDestroyed, 1); + InstallResultCode::kWebAppDisabled, 1); } { base::flat_map<SystemAppType, SystemAppInfo> system_apps; @@ -449,14 +449,16 @@ SystemAppInfo(kSettingsAppNameForLogging, GURL(kAppUrl1))); system_web_app_manager()->SetSystemAppsForTesting(system_apps); pending_app_manager()->SetInstallResultCode( - InstallResultCode::kProfileDestroyed); + InstallResultCode::kWebAppDisabled); histograms.ExpectTotalCount( SystemWebAppManager::kInstallDurationHistogramName, 2); - histograms.ExpectBucketCount(settings_app_install_result_histogram, - InstallResultCode::kFailedShuttingDown, 0); - histograms.ExpectBucketCount(profile_install_result_histogram, - InstallResultCode::kFailedShuttingDown, 0); + histograms.ExpectBucketCount( + settings_app_install_result_histogram, + InstallResultCode::kCancelledOnWebAppProviderShuttingDown, 0); + histograms.ExpectBucketCount( + profile_install_result_histogram, + InstallResultCode::kCancelledOnWebAppProviderShuttingDown, 0); system_web_app_manager()->Start(); system_web_app_manager()->Shutdown(); @@ -464,15 +466,17 @@ histograms.ExpectBucketCount( SystemWebAppManager::kInstallResultHistogramName, - InstallResultCode::kFailedShuttingDown, 1); + InstallResultCode::kCancelledOnWebAppProviderShuttingDown, 1); histograms.ExpectBucketCount( SystemWebAppManager::kInstallResultHistogramName, - InstallResultCode::kProfileDestroyed, 2); + InstallResultCode::kWebAppDisabled, 2); - histograms.ExpectBucketCount(settings_app_install_result_histogram, - InstallResultCode::kFailedShuttingDown, 1); - histograms.ExpectBucketCount(profile_install_result_histogram, - InstallResultCode::kFailedShuttingDown, 1); + histograms.ExpectBucketCount( + settings_app_install_result_histogram, + InstallResultCode::kCancelledOnWebAppProviderShuttingDown, 1); + histograms.ExpectBucketCount( + profile_install_result_histogram, + InstallResultCode::kCancelledOnWebAppProviderShuttingDown, 1); // If install was interrupted by shutdown, do not report duration. histograms.ExpectTotalCount( SystemWebAppManager::kInstallDurationHistogramName, 2);
diff --git a/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc b/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc index c3e798fa..c541ab38 100644 --- a/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc +++ b/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc
@@ -504,7 +504,7 @@ list.Append(GetTabbedItem()); list.Append(GetNoContainerItem()); pending_app_manager()->SetInstallResultCode( - InstallResultCode::kProfileDestroyed); + InstallResultCode::kCancelledOnWebAppProviderShuttingDown); profile()->GetPrefs()->Set(prefs::kWebAppInstallForceList, std::move(list)); @@ -513,7 +513,7 @@ WebAppPolicyManager::kInstallResultHistogramName, 3); histograms.ExpectBucketCount( WebAppPolicyManager::kInstallResultHistogramName, - InstallResultCode::kProfileDestroyed, 2); + InstallResultCode::kCancelledOnWebAppProviderShuttingDown, 2); } }
diff --git a/chrome/browser/web_applications/system_web_app_manager.cc b/chrome/browser/web_applications/system_web_app_manager.cc index 76d3d30..fd690fe 100644 --- a/chrome/browser/web_applications/system_web_app_manager.cc +++ b/chrome/browser/web_applications/system_web_app_manager.cc
@@ -307,10 +307,11 @@ // Record aggregate result. for (const auto& url_and_result : install_results) - base::UmaHistogramEnumeration(kInstallResultHistogramName, - shutting_down_ - ? InstallResultCode::kFailedShuttingDown - : url_and_result.second); + base::UmaHistogramEnumeration( + kInstallResultHistogramName, + shutting_down_ + ? InstallResultCode::kCancelledOnWebAppProviderShuttingDown + : url_and_result.second); // Record per-app result. for (const auto type_and_app_info : system_app_infos_) { @@ -320,19 +321,21 @@ const std::string app_histogram_name = std::string(kInstallResultHistogramName) + ".Apps." + type_and_app_info.second.name_for_logging; - base::UmaHistogramEnumeration(app_histogram_name, - shutting_down_ - ? InstallResultCode::kFailedShuttingDown - : url_and_result->second); + base::UmaHistogramEnumeration( + app_histogram_name, + shutting_down_ + ? InstallResultCode::kCancelledOnWebAppProviderShuttingDown + : url_and_result->second); } } // Record per-profile result. for (const auto url_and_result : install_results) { - base::UmaHistogramEnumeration(install_result_per_profile_histogram_name_, - shutting_down_ - ? InstallResultCode::kFailedShuttingDown - : url_and_result.second); + base::UmaHistogramEnumeration( + install_result_per_profile_histogram_name_, + shutting_down_ + ? InstallResultCode::kCancelledOnWebAppProviderShuttingDown + : url_and_result.second); } }
diff --git a/chrome/browser/web_applications/web_app_provider.cc b/chrome/browser/web_applications/web_app_provider.cc index de2cfa7..4bfa9e8 100644 --- a/chrome/browser/web_applications/web_app_provider.cc +++ b/chrome/browser/web_applications/web_app_provider.cc
@@ -147,6 +147,7 @@ } void WebAppProvider::Shutdown() { + shortcut_manager_->Shutdown(); pending_app_manager_->Shutdown(); install_manager_->Shutdown(); manifest_update_manager_->Shutdown(); @@ -247,6 +248,7 @@ external_web_app_manager_->Start(); web_app_policy_manager_->Start(); system_web_app_manager_->Start(); + shortcut_manager_->Start(); manifest_update_manager_->Start(); file_handler_manager_->Start();
diff --git a/chrome/browser/web_applications/web_app_shortcut_manager.cc b/chrome/browser/web_applications/web_app_shortcut_manager.cc index 32eddbf..c56e83a 100644 --- a/chrome/browser/web_applications/web_app_shortcut_manager.cc +++ b/chrome/browser/web_applications/web_app_shortcut_manager.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/callback.h" +#include "base/files/file_path.h" #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/profiles/profile.h" @@ -35,6 +36,19 @@ WebAppShortcutManager::~WebAppShortcutManager() = default; +void WebAppShortcutManager::OnWebAppWillBeUninstalled(const AppId& app_id) { + const WebApp* app = GetWebAppRegistrar().GetAppById(app_id); + DCHECK(app); + + std::unique_ptr<ShortcutInfo> shortcut_info = BuildShortcutInfoForWebApp(app); + base::FilePath shortcut_data_dir = + internals::GetShortcutDataDir(*shortcut_info); + + internals::PostShortcutIOTask( + base::BindOnce(&internals::DeletePlatformShortcuts, shortcut_data_dir), + std::move(shortcut_info)); +} + void WebAppShortcutManager::GetShortcutInfoForApp( const AppId& app_id, GetShortcutInfoCallback callback) {
diff --git a/chrome/browser/web_applications/web_app_shortcut_manager.h b/chrome/browser/web_applications/web_app_shortcut_manager.h index 701849ef..bc9cd85b 100644 --- a/chrome/browser/web_applications/web_app_shortcut_manager.h +++ b/chrome/browser/web_applications/web_app_shortcut_manager.h
@@ -32,6 +32,9 @@ FileHandlerManager* file_handler_manager); ~WebAppShortcutManager() override; + // AppRegistrarObserver: + void OnWebAppWillBeUninstalled(const AppId& app_id) override; + // AppShortcutManager: void GetShortcutInfoForApp(const AppId& app_id, GetShortcutInfoCallback callback) override;
diff --git a/chrome/renderer/resources/extensions/developer_private_custom_bindings.js b/chrome/renderer/resources/extensions/developer_private_custom_bindings.js index 3e60a45..79f2e0ae 100644 --- a/chrome/renderer/resources/extensions/developer_private_custom_bindings.js +++ b/chrome/renderer/resources/extensions/developer_private_custom_bindings.js
@@ -38,13 +38,13 @@ apiFunctions.setHandleRequest('inspect', function(options, callback) { var renderViewId = options.render_view_id; - if (typeof renderViewId == 'string') { + if (typeof renderViewId === 'string') { renderViewId = parseInt(renderViewId); if (isNaN(renderViewId)) throw new Error('Invalid value for render_view_id'); } var renderProcessId = options.render_process_id; - if (typeof renderProcessId == 'string') { + if (typeof renderProcessId === 'string') { renderProcessId = parseInt(renderProcessId); if (isNaN(renderProcessId)) throw new Error('Invalid value for render_process_id');
diff --git a/chrome/renderer/resources/extensions/downloads_custom_bindings.js b/chrome/renderer/resources/extensions/downloads_custom_bindings.js index 5bcb3a7..40af92b 100644 --- a/chrome/renderer/resources/extensions/downloads_custom_bindings.js +++ b/chrome/renderer/resources/extensions/downloads_custom_bindings.js
@@ -15,18 +15,20 @@ function isValidResult(result) { if (result === undefined) return false; - if (typeof(result) != 'object') { - console.error('Error: Invocation of form suggest(' + typeof(result) + - ') doesn\'t match definition suggest({filename: string, ' + - 'conflictAction: string})'); + if (typeof result !== 'object') { + console.error( + 'Error: Invocation of form suggest(' + typeof result + + ') doesn\'t match definition suggest({filename: string, ' + + 'conflictAction: string})'); return false; - } else if ((typeof(result.filename) != 'string') || - (result.filename.length == 0)) { + } else if ( + typeof result.filename !== 'string' || result.filename.length === 0) { console.error('Error: "filename" parameter to suggest() must be a ' + 'non-empty string'); return false; - } else if ([undefined, 'uniquify', 'overwrite', 'prompt'].indexOf( - result.conflictAction) < 0) { + } else if ([ + undefined, 'uniquify', 'overwrite', 'prompt' + ].indexOf(result.conflictAction) < 0) { console.error('Error: "conflictAction" parameter to suggest() must be ' + 'one of undefined, "uniquify", "overwrite", "prompt"'); return false; @@ -48,10 +50,9 @@ } try { var results = dispatch([downloadItem, suggestCallback]); - var async = (results && - results.results && - (results.results.length != 0) && - (results.results[0] === true)); + var async = + (results && results.results && (results.results.length !== 0) && + (results.results[0] === true)); if (suggestable && !async) suggestCallback(); } catch (e) {
diff --git a/chrome/renderer/resources/extensions/enterprise_platform_keys/subtle_crypto.js b/chrome/renderer/resources/extensions/enterprise_platform_keys/subtle_crypto.js index 52bca98..02712034 100644 --- a/chrome/renderer/resources/extensions/enterprise_platform_keys/subtle_crypto.js +++ b/chrome/renderer/resources/extensions/enterprise_platform_keys/subtle_crypto.js
@@ -44,7 +44,7 @@ // returns true. function catchInvalidTokenError(reject) { if (chrome.runtime.lastError && - chrome.runtime.lastError.message == errorInvalidToken) { + chrome.runtime.lastError.message === errorInvalidToken) { reject(chrome.runtime.lastError); return true; }
diff --git a/chrome/renderer/resources/extensions/file_system_provider_custom_bindings.js b/chrome/renderer/resources/extensions/file_system_provider_custom_bindings.js index 3410ad77..7bfd2d57 100644 --- a/chrome/renderer/resources/extensions/file_system_provider_custom_bindings.js +++ b/chrome/renderer/resources/extensions/file_system_provider_custom_bindings.js
@@ -41,7 +41,7 @@ */ function verifyImageURI(uri) { // The URI is specified by a user, so the type may be incorrect. - if (typeof uri != 'string' && !(uri instanceof String)) + if (typeof uri !== 'string' && !(uri instanceof String)) return false; return METADATA_THUMBNAIL_FORMAT.test(uri);
diff --git a/chrome/renderer/resources/extensions/gcm_custom_bindings.js b/chrome/renderer/resources/extensions/gcm_custom_bindings.js index 5d1f3be..9907fd8b 100644 --- a/chrome/renderer/resources/extensions/gcm_custom_bindings.js +++ b/chrome/renderer/resources/extensions/gcm_custom_bindings.js
@@ -15,7 +15,7 @@ // Validate message.data. var payloadSize = 0; forEach(message.data, function(property, value) { - if (property.length == 0) + if (property.length === 0) throw new Error("One of data keys is empty."); var lowerCasedProperty = property.toLowerCase(); @@ -33,7 +33,7 @@ throw new Error("Payload exceeded allowed size limit. Payload size is: " + payloadSize); - if (payloadSize == 0) + if (payloadSize === 0) throw new Error("No data to send."); return arguments;
diff --git a/chrome/renderer/resources/extensions/identity_custom_bindings.js b/chrome/renderer/resources/extensions/identity_custom_bindings.js index dcb6f75a..3ac344c 100644 --- a/chrome/renderer/resources/extensions/identity_custom_bindings.js +++ b/chrome/renderer/resources/extensions/identity_custom_bindings.js
@@ -12,7 +12,7 @@ path = '/'; else path = String(path); - if (path[0] != '/') + if (path[0] !== '/') path = '/' + path; return 'https://' + id + '.chromiumapp.org' + path; });
diff --git a/chrome/renderer/resources/extensions/media_router_bindings.js b/chrome/renderer/resources/extensions/media_router_bindings.js index 192aef93..d054276 100644 --- a/chrome/renderer/resources/extensions/media_router_bindings.js +++ b/chrome/renderer/resources/extensions/media_router_bindings.js
@@ -262,12 +262,12 @@ this.$data = null; this.$tag = undefined; - if (value == undefined) { + if (value === undefined) { return; } var keys = Object.keys(value); - if (keys.length == 0) { + if (keys.length === 0) { return; } @@ -295,7 +295,7 @@ Object.defineProperty(MediaSinkExtraDataAdapter.prototype, 'dial_media_sink', { get: function() { - if (this.$tag != MediaSinkExtraDataAdapter.Tags.dial_media_sink) { + if (this.$tag !== MediaSinkExtraDataAdapter.Tags.dial_media_sink) { throw new ReferenceError( 'MediaSinkExtraDataAdapter.dial_media_sink is not currently set.'); } @@ -310,7 +310,7 @@ Object.defineProperty(MediaSinkExtraDataAdapter.prototype, 'cast_media_sink', { get: function() { - if (this.$tag != MediaSinkExtraDataAdapter.Tags.cast_media_sink) { + if (this.$tag !== MediaSinkExtraDataAdapter.Tags.cast_media_sink) { throw new ReferenceError( 'MediaSinkExtraDataAdapter.cast_media_sink is not currently set.'); } @@ -324,7 +324,7 @@ }); MediaSinkExtraDataAdapter.fromNewVersion = function(other) { - if (other.$tag == mediaRouter.mojom.MediaSinkExtraData.Tags.dialMediaSink) { + if (other.$tag === mediaRouter.mojom.MediaSinkExtraData.Tags.dialMediaSink) { return new MediaSinkExtraDataAdapter({ 'dial_media_sink': DialMediaSinkAdapter.fromNewVersion(other.dialMediaSink), @@ -338,7 +338,7 @@ }; MediaSinkExtraDataAdapter.prototype.toNewVersion = function() { - if (this.$tag == MediaSinkExtraDataAdapter.Tags.dial_media_sink) { + if (this.$tag === MediaSinkExtraDataAdapter.Tags.dial_media_sink) { return new mediaRouter.mojom.MediaSinkExtraData({ 'dialMediaSink': this.dial_media_sink.toNewVersion(), }); @@ -550,7 +550,7 @@ * @return {!mediaRouter.mojom.RouteMessage} A Mojo RouteMessage object. */ function messageToMojo_(message) { - if ("string" == typeof message.message) { + if ('string' === typeof message.message) { return new mediaRouter.mojom.RouteMessage({ 'type': mediaRouter.mojom.RouteMessage.Type.TEXT, 'message': message.message,
diff --git a/chrome/renderer/resources/extensions/omnibox_custom_bindings.js b/chrome/renderer/resources/extensions/omnibox_custom_bindings.js index 762679b..a5a1857 100644 --- a/chrome/renderer/resources/extensions/omnibox_custom_bindings.js +++ b/chrome/renderer/resources/extensions/omnibox_custom_bindings.js
@@ -46,16 +46,16 @@ function walk(node) { for (var i = 0, child; child = node.childNodes[i]; i++) { // Append text nodes to our description. - if (child.nodeType == Node.TEXT_NODE) { - var shouldTrim = result.description.length == 0; + if (child.nodeType === Node.TEXT_NODE) { + var shouldTrim = result.description.length === 0; result.description += sanitizeString(child.nodeValue, shouldTrim); continue; } // Process and descend into a subset of recognized tags. - if (child.nodeType == Node.ELEMENT_NODE && - (child.nodeName == 'dim' || child.nodeName == 'match' || - child.nodeName == 'url')) { + if (child.nodeType === Node.ELEMENT_NODE && + (child.nodeName === 'dim' || child.nodeName === 'match' || + child.nodeName === 'url')) { var style = { 'type': child.nodeName, 'offset': result.description.length @@ -79,14 +79,14 @@ apiBridge.registerCustomHook(function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; - apiFunctions.setUpdateArgumentsPreValidate('setDefaultSuggestion', - function(suggestResult) { - if (suggestResult.content != undefined) { // null, etc. - throw new Error( - 'setDefaultSuggestion cannot contain the "content" field'); - } - return [suggestResult]; - }); + apiFunctions.setUpdateArgumentsPreValidate( + 'setDefaultSuggestion', function(suggestResult) { + if (suggestResult.content != null) { + throw new Error( + 'setDefaultSuggestion cannot contain the "content" field'); + } + return [suggestResult]; + }); apiFunctions.setHandleRequest('setDefaultSuggestion', function(details) { var parseResult = parseOmniboxDescription(details.description);
diff --git a/chrome/renderer/resources/extensions/platform_keys/get_public_key.js b/chrome/renderer/resources/extensions/platform_keys/get_public_key.js index 19025a3..5bf7255 100644 --- a/chrome/renderer/resources/extensions/platform_keys/get_public_key.js +++ b/chrome/renderer/resources/extensions/platform_keys/get_public_key.js
@@ -11,7 +11,7 @@ // Any unknown parameters will be ignored. function normalizeImportParams(importParams) { if (!importParams.name || - Object.prototype.toString.call(importParams.name) != '[object String]') { + Object.prototype.toString.call(importParams.name) !== '[object String]') { throw new Error('Algorithm: name: Missing or not a String'); }
diff --git a/chrome/renderer/resources/extensions/platform_keys/subtle_crypto.js b/chrome/renderer/resources/extensions/platform_keys/subtle_crypto.js index 91bf3a3..a8ab0e1 100644 --- a/chrome/renderer/resources/extensions/platform_keys/subtle_crypto.js +++ b/chrome/renderer/resources/extensions/platform_keys/subtle_crypto.js
@@ -42,7 +42,7 @@ // returns true. function catchInvalidTokenError(reject) { if (bindingUtil.hasLastError() && - chrome.runtime.lastError.message == errorInvalidToken) { + chrome.runtime.lastError.message === errorInvalidToken) { var error = chrome.runtime.lastError; bindingUtil.clearLastError(); reject(error); @@ -65,7 +65,7 @@ SubtleCryptoImpl.prototype.sign = function(algorithm, key, dataView) { var subtleCrypto = this; return new Promise(function(resolve, reject) { - if (key.type != 'private' || key.usages.indexOf(KeyUsage.sign) == -1) + if (key.type !== 'private' || key.usages.indexOf(KeyUsage.sign) === -1) throw CreateInvalidAccessError(); var normalizedAlgorithmParameters = @@ -99,12 +99,12 @@ SubtleCryptoImpl.prototype.exportKey = function(format, key) { return new Promise(function(resolve, reject) { - if (format == 'pkcs8') { + if (format === 'pkcs8') { // Either key.type is not 'private' or the key is not extractable. In both // cases the error is the same. throw CreateInvalidAccessError(); - } else if (format == 'spki') { - if (key.type != 'public') + } else if (format === 'spki') { + if (key.type !== 'public') throw CreateInvalidAccessError(); resolve(getSpki(key)); } else {
diff --git a/chrome/renderer/resources/extensions/sync_file_system_custom_bindings.js b/chrome/renderer/resources/extensions/sync_file_system_custom_bindings.js index 56dfe96..4c6339ec 100644 --- a/chrome/renderer/resources/extensions/sync_file_system_custom_bindings.js +++ b/chrome/renderer/resources/extensions/sync_file_system_custom_bindings.js
@@ -94,7 +94,7 @@ var fileInfo = new Object(); fileInfo.fileEntry = fileEntry; fileInfo.status = args[1]; - if (fileInfo.status == "synced") { + if (fileInfo.status === 'synced') { fileInfo.action = args[2]; fileInfo.direction = args[3]; }
diff --git a/chrome/renderer/resources/extensions/tab_capture_custom_bindings.js b/chrome/renderer/resources/extensions/tab_capture_custom_bindings.js index e3e93449..f7c691c6 100644 --- a/chrome/renderer/resources/extensions/tab_capture_custom_bindings.js +++ b/chrome/renderer/resources/extensions/tab_capture_custom_bindings.js
@@ -21,7 +21,7 @@ // Convenience function for processing webkitGetUserMedia() error objects to // provide runtime.lastError messages for the tab capture API. function getErrorMessage(error, fallbackMessage) { - if (!error || (typeof error.message != 'string')) + if (!error || (typeof error.message !== 'string')) return fallbackMessage; return error.message.replace(/(navigator\.)?(webkit)?GetUserMedia/gi, name);
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 22490bf9..3a08b9a 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1018,6 +1018,8 @@ "../browser/net/network_request_metrics_browsertest.cc", "../browser/net/nss_context_chromeos_browsertest.cc", "../browser/net/profile_network_context_service_browsertest.cc", + "../browser/net/profile_network_context_service_test_utils.cc", + "../browser/net/profile_network_context_service_test_utils.h", "../browser/net/proxy_browsertest.cc", "../browser/net/proxy_test_utils.cc", "../browser/net/proxy_test_utils.h",
diff --git a/chrome/test/data/webui/settings/chromeos/cups_printer_page_tests.js b/chrome/test/data/webui/settings/chromeos/cups_printer_page_tests.js index 9007f1f..2b8ff1b 100644 --- a/chrome/test/data/webui/settings/chromeos/cups_printer_page_tests.js +++ b/chrome/test/data/webui/settings/chromeos/cups_printer_page_tests.js
@@ -1281,7 +1281,7 @@ mojoApi_.addNetworksForTest([wifi1]); PolymerTest.clearBody(); - settings.navigateTo(settings.routes.CUPS_PRINTERS); + settings.Router.getInstance().navigateTo(settings.routes.CUPS_PRINTERS); page = document.createElement('settings-cups-printers'); document.body.appendChild(page);
diff --git a/components/about_ui/resources/about_credits.js b/components/about_ui/resources/about_credits.js index e987fd5..6674aaa 100644 --- a/components/about_ui/resources/about_credits.js +++ b/components/about_ui/resources/about_credits.js
@@ -23,7 +23,7 @@ document.addEventListener('keypress', function(e) { // Make the license show/hide toggle when the Enter is pressed. - if (e.keyCode == 0x0d && e.target.tagName == 'LABEL') { + if (e.keyCode === 0x0d && e.target.tagName === 'LABEL') { e.target.previousElementSibling.click(); } });
diff --git a/components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.cc b/components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.cc index 8e28e27..099b583 100644 --- a/components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.cc +++ b/components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.cc
@@ -10,7 +10,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "build/branding_buildflags.h" -#include "build/build_config.h" #include "components/autofill/core/browser/autofill_experiments.h" #include "components/autofill/core/browser/data_model/credit_card.h" #include "components/autofill/core/common/autofill_constants.h" @@ -68,7 +67,8 @@ AutofillSaveCardInfoBarDelegateMobile:: ~AutofillSaveCardInfoBarDelegateMobile() { if (!had_user_interaction_) { - RunSaveCardPromptCallbackWithUserDecision(AutofillClient::IGNORED); + RunSaveCardPromptCallback(AutofillClient::IGNORED, + /*user_provided_details=*/{}); LogUserAction(AutofillMetrics::INFOBAR_IGNORED); } } @@ -141,12 +141,14 @@ } void AutofillSaveCardInfoBarDelegateMobile::InfoBarDismissed() { - RunSaveCardPromptCallbackWithUserDecision(AutofillClient::DECLINED); + RunSaveCardPromptCallback(AutofillClient::DECLINED, + /*user_provided_details=*/{}); LogUserAction(AutofillMetrics::INFOBAR_DENIED); } bool AutofillSaveCardInfoBarDelegateMobile::Cancel() { - RunSaveCardPromptCallbackWithUserDecision(AutofillClient::DECLINED); + RunSaveCardPromptCallback(AutofillClient::DECLINED, + /*user_provided_details=*/{}); LogUserAction(AutofillMetrics::INFOBAR_DENIED); return true; } @@ -178,18 +180,36 @@ } bool AutofillSaveCardInfoBarDelegateMobile::Accept() { - RunSaveCardPromptCallbackWithUserDecision(AutofillClient::ACCEPTED); + RunSaveCardPromptCallback(AutofillClient::ACCEPTED, + /*user_provided_details=*/{}); LogUserAction(AutofillMetrics::INFOBAR_ACCEPTED); return true; } -void AutofillSaveCardInfoBarDelegateMobile:: - RunSaveCardPromptCallbackWithUserDecision( - AutofillClient::SaveCardOfferUserDecision user_decision) { - if (upload_) - std::move(upload_save_card_prompt_callback_).Run(user_decision, {}); - else +#if defined(OS_IOS) +bool AutofillSaveCardInfoBarDelegateMobile::UpdateAndAccept( + base::string16 cardholder_name, + base::string16 expiration_date_month, + base::string16 expiration_date_year) { + AutofillClient::UserProvidedCardDetails user_provided_details; + user_provided_details.cardholder_name = cardholder_name; + user_provided_details.expiration_date_month = expiration_date_month; + user_provided_details.expiration_date_year = expiration_date_year; + RunSaveCardPromptCallback(AutofillClient::ACCEPTED, user_provided_details); + LogUserAction(AutofillMetrics::INFOBAR_ACCEPTED); + return true; +} +#endif // defined(OS_IOS) + +void AutofillSaveCardInfoBarDelegateMobile::RunSaveCardPromptCallback( + AutofillClient::SaveCardOfferUserDecision user_decision, + AutofillClient::UserProvidedCardDetails user_provided_details) { + if (upload_) { + std::move(upload_save_card_prompt_callback_) + .Run(user_decision, user_provided_details); + } else { std::move(local_save_card_prompt_callback_).Run(user_decision); + } } void AutofillSaveCardInfoBarDelegateMobile::LogUserAction(
diff --git a/components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.h b/components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.h index 0dbeaaa5..abd7520c 100644 --- a/components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.h +++ b/components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.h
@@ -10,6 +10,7 @@ #include "base/callback.h" #include "base/macros.h" #include "base/strings/string16.h" +#include "build/build_config.h" #include "components/autofill/core/browser/autofill_client.h" #include "components/autofill/core/browser/autofill_metrics.h" #include "components/autofill/core/browser/payments/legal_message_line.h" @@ -78,11 +79,25 @@ bool Accept() override; bool Cancel() override; +#if defined(OS_IOS) + // Updates and then saves the card using |cardholder_name|, + // |expiration_date_month| and |expiration_date_year|, which were provided + // as part of the iOS save card Infobar dialog. + bool UpdateAndAccept(base::string16 cardholder_name, + base::string16 expiration_date_month, + base::string16 expiration_date_year); +#endif // defined(OS_IOS) + private: // Runs the appropriate local or upload save callback with the given - // |user_decision|. - void RunSaveCardPromptCallbackWithUserDecision( - AutofillClient::SaveCardOfferUserDecision user_decision); + // |user_decision|, using the |user_provided_details|. If + // |user_provided_details| is empty then the current Card values will be used. + // The cardholder name and expiration date portions of + // |user_provided_details| are handled separately, so if either of them are + // empty the current Card values will be used. + void RunSaveCardPromptCallback( + AutofillClient::SaveCardOfferUserDecision user_decision, + AutofillClient::UserProvidedCardDetails user_provided_details); void LogUserAction(AutofillMetrics::InfoBarMetric user_action);
diff --git a/components/autofill/core/browser/payments/credit_card_save_manager.cc b/components/autofill/core/browser/payments/credit_card_save_manager.cc index 5ef7d517..5b1c5e2 100644 --- a/components/autofill/core/browser/payments/credit_card_save_manager.cc +++ b/components/autofill/core/browser/payments/credit_card_save_manager.cc
@@ -43,6 +43,7 @@ #include "components/autofill/core/common/autofill_payments_features.h" #include "components/autofill/core/common/autofill_prefs.h" #include "components/autofill/core/common/autofill_util.h" +#include "components/infobars/core/infobar_feature.h" #include "components/prefs/pref_service.h" #include "components/signin/public/identity_manager/identity_manager.h" #include "url/gurl.h" @@ -218,6 +219,20 @@ should_request_expiration_date_from_user_ = true; } +#if defined(OS_IOS) + if ((base::FeatureList::IsEnabled( + features::kAutofillSaveCardInfobarEditSupport) && + base::FeatureList::IsEnabled(kIOSInfobarUIReboot))) { + // iOS's new credit card save dialog requires the user to enter both + // cardholder name and expiration date before saving. Regardless of what + // Chrome thought it needed to do before, disable both of the previous + // standalone fix flows, and let the new save dialog handle their combined + // case. + should_request_name_from_user_ = false; + should_request_expiration_date_from_user_ = false; + } +#endif // defined(OS_IOS) + // The cardholder name and expiration date fix flows cannot both be // active at the same time. If they are, abort offering upload. // If user is signed in and has Wallet Sync Transport enabled but we still @@ -766,6 +781,18 @@ detected_values |= DetectedValue::USER_PROVIDED_NAME; } +// On iOS if the new Infobar UI is enabled, it won't be possible to save the +// card unless the user provides both a valid cardholder name and expiration +// date. +#if defined(OS_IOS) + if ((base::FeatureList::IsEnabled( + features::kAutofillSaveCardInfobarEditSupport) && + base::FeatureList::IsEnabled(kIOSInfobarUIReboot))) { + detected_values |= DetectedValue::USER_PROVIDED_NAME; + detected_values |= DetectedValue::USER_PROVIDED_EXPIRATION_DATE; + } +#endif // defined(OS_IOS) + return detected_values; } @@ -829,7 +856,17 @@ // that it is possible a name already existed on the card if conflicting names // were found, which this intentionally overwrites.) if (!user_provided_card_details.cardholder_name.empty()) { +#if defined(OS_IOS) + // On iOS if the new Infobar UI is enabled, cardholder name was provided by + // the user, but not through the fix flow triggered via + // |should_request_name_from_user_|. + DCHECK(should_request_name_from_user_ || + (base::FeatureList::IsEnabled( + autofill::features::kAutofillSaveCardInfobarEditSupport) && + base::FeatureList::IsEnabled(kIOSInfobarUIReboot))); +#else DCHECK(should_request_name_from_user_); +#endif upload_request_.card.SetInfo(CREDIT_CARD_NAME_FULL, user_provided_card_details.cardholder_name, app_locale_); @@ -840,7 +877,17 @@ // the expiration date on |upload_request_.card| with the selected date. if (!user_provided_card_details.expiration_date_month.empty() && !user_provided_card_details.expiration_date_year.empty()) { +#if defined(OS_IOS) + // On iOS if the new Infobar UI is enabled, expiration date was provided by + // the user, but not through the fix flow triggered via + // |should_request_expiration_date_from_user_|. + DCHECK(should_request_expiration_date_from_user_ || + (base::FeatureList::IsEnabled( + autofill::features::kAutofillSaveCardInfobarEditSupport) && + base::FeatureList::IsEnabled(kIOSInfobarUIReboot))); +#else DCHECK(should_request_expiration_date_from_user_); +#endif upload_request_.card.SetInfo( CREDIT_CARD_EXP_MONTH, user_provided_card_details.expiration_date_month, app_locale_);
diff --git a/components/autofill/ios/browser/resources/autofill_controller.js b/components/autofill/ios/browser/resources/autofill_controller.js index 3a0deb6..9373ca8 100644 --- a/components/autofill/ios/browser/resources/autofill_controller.js +++ b/components/autofill/ios/browser/resources/autofill_controller.js
@@ -299,7 +299,7 @@ fieldIdentifier !== forceFillFieldIdentifier && !__gCrWeb.fill.isSelectElement(element) && !((element.hasAttribute('value') && - element.getAttribute('value') == element.value) || + element.getAttribute('value') === element.value) || (element.hasAttribute('placeholder') && element.getAttribute('placeholder').toLowerCase() == element.value.toLowerCase()))) { @@ -371,7 +371,7 @@ continue; } - if (formField && formField.autofillSection != element.autofillSection) { + if (formField && formField.autofillSection !== element.autofillSection) { continue; } @@ -592,7 +592,7 @@ } } - if (controlElementsWithAutocomplete.length == 0) { + if (controlElementsWithAutocomplete.length === 0) { return false; } return __gCrWeb.fill.formOrFieldsetsToFormData( @@ -726,7 +726,7 @@ // Some sites enter values such as ____-____-____-____ or (___)-___-____ in // their fields. Check if the field value is empty after the removal of the // formatting characters. - return __gCrWeb.common.trim(value.replace(/[-_()/|]/g, '')) == ''; + return __gCrWeb.common.trim(value.replace(/[-_()/|]/g, '')) === ''; }; }()); // End of anonymous object
diff --git a/components/autofill/ios/browser/resources/suggestion_controller.js b/components/autofill/ios/browser/resources/suggestion_controller.js index bf7002d1..666115a 100644 --- a/components/autofill/ios/browser/resources/suggestion_controller.js +++ b/components/autofill/ios/browser/resources/suggestion_controller.js
@@ -222,7 +222,7 @@ // It is proposed in W3C that if tabIndex is a negative integer, the user // agent should not allow the element to be reached using sequential focus // navigation. - if ((!tabIndex && tabIndex != 0) || tabIndex < 0) { + if ((!tabIndex && tabIndex !== 0) || tabIndex < 0) { return false; } if (element.type === 'hidden' || element.hasAttribute('disabled')) {
diff --git a/components/autofill/ios/form_util/resources/fill.js b/components/autofill/ios/form_util/resources/fill.js index ebb7074c..c45d65b3 100644 --- a/components/autofill/ios/form_util/resources/fill.js +++ b/components/autofill/ios/form_util/resources/fill.js
@@ -146,7 +146,8 @@ if (!element) { return false; } - if (__gCrWeb.common.getLowerCaseAttribute(element, 'autocomplete') == 'off') { + if (__gCrWeb.common.getLowerCaseAttribute(element, 'autocomplete') === + 'off') { return false; } if (__gCrWeb.common.getLowerCaseAttribute(element.form, 'autocomplete') == @@ -218,7 +219,7 @@ if (!input) return; const activeElement = document.activeElement; - if (input != activeElement) { + if (input !== activeElement) { __gCrWeb.fill.createAndDispatchHTMLEvent( activeElement, value, 'blur', true, false); __gCrWeb.fill.createAndDispatchHTMLEvent( @@ -228,7 +229,7 @@ setInputElementValue_(value, input); if (callback) callback(); - if (input != activeElement) { + if (input !== activeElement) { __gCrWeb.fill.createAndDispatchHTMLEvent(input, value, 'blur', true, false); __gCrWeb.fill.createAndDispatchHTMLEvent( activeElement, value, 'focus', true, false); @@ -255,7 +256,9 @@ } // Return early if the value hasn't changed. - if (input[propertyName] == value) return; + if (input[propertyName] === value) { + return; + } // When the user inputs a value in an HTMLInput field, the property setter is // not called. The different frameworks often call it explicitly when @@ -311,7 +314,7 @@ if (overrideProperty) { Object.defineProperty(input, propertyName, oldPropertyDescriptor); - if (!setterCalled && input[propertyName] != value) { + if (!setterCalled && input[propertyName] !== value) { // The setter was never called. This may be intentional (the framework // ignored the input event) or not (the event did not conform to what // framework expected). The whole function will likely fail, but try to @@ -387,7 +390,7 @@ // This logic is from method String limitLength() in TextFieldInputType.h for (let i = 0; i < newLength; ++i) { const current = valueWithLineBreakRemoved[i]; - if (current < ' ' && current != '\t') { + if (current < ' ' && current !== '\t') { newLength = i; break; } @@ -493,7 +496,7 @@ element, value, type, bubbles, cancelable) { const event = new Event(type, {bubbles: bubbles, cancelable: cancelable, data: value}); - if (type == 'input') { + if (type === 'input') { event.inputType = 'insertText'; } element.dispatchEvent(event); @@ -582,7 +585,9 @@ if (node.nodeType === Node.ELEMENT_NODE) { const style = window.getComputedStyle(/** @type {Element} */ (node)); - if (style.visibility == 'hidden' || style.display == 'none') return false; + if (style.visibility === 'hidden' || style.display === 'none') { + return false; + } } // Verify all ancestors are focusable. @@ -642,7 +647,7 @@ } } } else if ( - fieldElement.form != formElement || fieldElement.type === 'hidden') { + fieldElement.form !== formElement || fieldElement.type === 'hidden') { continue; } else { // Typical case: look up |fieldData| in |elementArray|. @@ -915,9 +920,9 @@ __gCrWeb.fill.combineAndCollapseWhitespace = function( prefix, suffix, forceWhitespace) { const prefixTrimmed = __gCrWeb.fill.trimWhitespaceTrailing(prefix); - const prefixTrailingWhitespace = prefixTrimmed != prefix; + const prefixTrailingWhitespace = prefixTrimmed !== prefix; const suffixTrimmed = __gCrWeb.fill.trimWhitespaceLeading(suffix); - const suffixLeadingWhitespace = suffixTrimmed != suffix; + const suffixLeadingWhitespace = suffixTrimmed !== suffix; if (prefixTrailingWhitespace || suffixLeadingWhitespace || forceWhitespace) { return prefixTrimmed + ' ' + suffixTrimmed; } else { @@ -1086,7 +1091,7 @@ } // Otherwise, only consider normal HTML elements and their contents. - if (nodeType != Node.TEXT_NODE && nodeType != Node.ELEMENT_NODE) { + if (nodeType !== Node.TEXT_NODE && nodeType !== Node.ELEMENT_NODE) { break; } @@ -1218,7 +1223,7 @@ */ __gCrWeb.fill.InferLabelFromValueAttr = function(element) { if (!element || !element.value || !element.hasAttribute('value') || - element.value != element.getAttribute('value')) { + element.value !== element.getAttribute('value')) { return ''; } @@ -1861,7 +1866,7 @@ __gCrWeb.fill.value = function(element) { let value = element.value; if (__gCrWeb.fill.isSelectElement(element)) { - if (element.options.length > 0 && element.selectedIndex == 0 && + if (element.options.length > 0 && element.selectedIndex === 0 && element.options[0].disabled && !element.options[0].hasAttribute('selected')) { for (let i = 0; i < element.options.length; i++) { @@ -1924,7 +1929,7 @@ } const roleAttribute = element.getAttribute('role'); - if (roleAttribute && roleAttribute.toLowerCase() == 'presentation') { + if (roleAttribute && roleAttribute.toLowerCase() === 'presentation') { field['role'] = __gCrWeb.fill.ROLE_ATTRIBUTE_PRESENTATION; } @@ -1947,7 +1952,7 @@ if (__gCrWeb.fill.isAutofillableInputElement(element)) { if (__gCrWeb.fill.isTextInput(element)) { field['max_length'] = element.maxLength; - if (field['max_length'] == -1) { + if (field['max_length'] === -1) { // Take default value as defined by W3C. field['max_length'] = 524288; }
diff --git a/components/autofill/ios/form_util/resources/form.js b/components/autofill/ios/form_util/resources/form.js index dcdc65b..898642a 100644 --- a/components/autofill/ios/form_util/resources/form.js +++ b/components/autofill/ios/form_util/resources/form.js
@@ -148,14 +148,14 @@ // check the index of the element in the descendants of the ancestors with // the same type. let ancestor = element.parentNode; - while (!!ancestor && ancestor.nodeType == Node.ELEMENT_NODE && + while (!!ancestor && ancestor.nodeType === Node.ELEMENT_NODE && (!ancestor.hasAttribute('id') || - __gCrWeb.common.trim(ancestor.id) == '')) { + __gCrWeb.common.trim(ancestor.id) === '')) { ancestor = ancestor.parentNode; } const query = element.tagName; let ancestorId = ''; - if (!ancestor || ancestor.nodeType != Node.ELEMENT_NODE) { + if (!ancestor || ancestor.nodeType !== Node.ELEMENT_NODE) { ancestor = document.body; } if (ancestor.hasAttribute('id')) { @@ -220,12 +220,12 @@ __gCrWeb.form.getFormIdentifier = function(form) { if (!form) return ''; let name = form.getAttribute('name'); - if (name && name.length != 0 && + if (name && name.length !== 0 && form.ownerDocument.forms.namedItem(name) === form) { return name; } name = form.getAttribute('id'); - if (name && name.length != 0 && + if (name && name.length !== 0 && form.ownerDocument.getElementById(name) === form) { return name; } @@ -233,8 +233,8 @@ // identified from the name. A last resort is to take the index number of // the form in document.forms. ids are not supposed to begin with digits (by // HTML 4 spec) so this is unlikely to match a true id. - for (let idx = 0; idx != document.forms.length; idx++) { - if (document.forms[idx] == form) { + for (let idx = 0; idx !== document.forms.length; idx++) { + if (document.forms[idx] === form) { return __gCrWeb.form.kNamelessFormIDPrefix + idx; } } @@ -259,10 +259,10 @@ } // Second attempt is from the prefixed index position of the form in // document.forms. - if (name.indexOf(__gCrWeb.form.kNamelessFormIDPrefix) == 0) { + if (name.indexOf(__gCrWeb.form.kNamelessFormIDPrefix) === 0) { const nameAsInteger = 0 | name.substring(__gCrWeb.form.kNamelessFormIDPrefix.length); - if (__gCrWeb.form.kNamelessFormIDPrefix + nameAsInteger == name && + if (__gCrWeb.form.kNamelessFormIDPrefix + nameAsInteger === name && nameAsInteger < document.forms.length) { return document.forms[nameAsInteger]; }
diff --git a/components/autofill/ios/form_util/resources/form_handlers.js b/components/autofill/ios/form_util/resources/form_handlers.js index 3f0d992..30ffe39 100644 --- a/components/autofill/ios/form_util/resources/form_handlers.js +++ b/components/autofill/ios/form_util/resources/form_handlers.js
@@ -107,7 +107,9 @@ __gCrWeb.form.wasEditedByUser !== null) { __gCrWeb.form.wasEditedByUser.set(target, evt.isTrusted); } - if (target != lastFocusedElement) return; + if (target !== lastFocusedElement) { + return; + } const msg = { 'command': 'form.activity', 'formName': __gCrWeb.form.getFormIdentifier(evt.target.form), @@ -222,12 +224,16 @@ for (let i = 0; i < mutations.length; i++) { const mutation = mutations[i]; // Only process mutations to the tree of nodes. - if (mutation.type != 'childList') continue; + if (mutation.type !== 'childList') { + continue; + } const addedElements = []; for (let j = 0; j < mutation.addedNodes.length; j++) { const node = mutation.addedNodes[j]; // Ignore non-element nodes. - if (node.nodeType != Node.ELEMENT_NODE) continue; + if (node.nodeType !== Node.ELEMENT_NODE) { + continue; + } addedElements.push(node); [].push.apply( addedElements, [].slice.call(node.getElementsByTagName('*')));
diff --git a/components/crash/core/browser/resources/crashes.js b/components/crash/core/browser/resources/crashes.js index e5d6a72..fb5d25b 100644 --- a/components/crash/core/browser/resources/crashes.js +++ b/components/crash/core/browser/resources/crashes.js
@@ -44,17 +44,17 @@ for (let i = 0; i < crashes.length; i++) { const crash = crashes[i]; - if (crash.local_id == '') { + if (crash.local_id === '') { crash.local_id = productName; } const crashBlock = document.createElement('div'); - if (crash.state != 'uploaded') { + if (crash.state !== 'uploaded') { crashBlock.className = 'notUploaded'; } const title = document.createElement('h3'); - const uploaded = crash.state == 'uploaded'; + const uploaded = crash.state === 'uploaded'; if (uploaded) { const crashHeaderText = loadTimeData.getString('crashHeaderFormat'); const pieces = loadTimeData @@ -133,11 +133,11 @@ crashBlock.appendChild(linkBlock); } else { let textContentKey; - if (crash.state == 'pending_user_requested') { + if (crash.state === 'pending_user_requested') { textContentKey = 'crashUserRequested'; - } else if (crash.state == 'pending') { + } else if (crash.state === 'pending') { textContentKey = 'crashPending'; - } else if (crash.state == 'not_uploaded') { + } else if (crash.state === 'not_uploaded') { textContentKey = 'crashNotUploaded'; } else { continue; @@ -148,7 +148,7 @@ crash.capture_time); crashBlock.appendChild(crashText); - if (crash.file_size != '') { + if (crash.file_size !== '') { const crashSizeText = document.createElement('p'); crashSizeText.textContent = loadTimeData.getStringF('crashSizeMessage', crash.file_size); @@ -156,7 +156,7 @@ } // Do not show "Send now" link for already requested crashes. - if (crash.state != 'pending_user_requested' && manualUploads) { + if (crash.state !== 'pending_user_requested' && manualUploads) { const uploadNowLinkBlock = document.createElement('p'); const link = document.createElement('a'); link.href = ''; @@ -174,7 +174,7 @@ // Reset the height, in order to accommodate for the new content. crashSection.style.height = ""; - $('noCrashes').hidden = crashes.length != 0; + $('noCrashes').hidden = crashes.length !== 0; } /**
diff --git a/components/dom_distiller/core/javascript/dom_distiller_viewer.js b/components/dom_distiller/core/javascript/dom_distiller_viewer.js index 1c911d89..7d4cd6e 100644 --- a/components/dom_distiller/core/javascript/dom_distiller_viewer.js +++ b/components/dom_distiller/core/javascript/dom_distiller_viewer.js
@@ -28,7 +28,7 @@ const placeholders = document.getElementsByClassName('embed-placeholder'); for (let i = 0; i < placeholders.length; i++) { if (!placeholders[i].hasAttribute('data-type') || - placeholders[i].getAttribute('data-type') != 'youtube' || + placeholders[i].getAttribute('data-type') !== 'youtube' || !placeholders[i].hasAttribute('data-id')) { continue; } @@ -69,14 +69,14 @@ function useFontFamily(fontFamily) { fontFamilyClasses.forEach( (element) => - document.body.classList.toggle(element, element == fontFamily)); + document.body.classList.toggle(element, element === fontFamily)); } // These classes must agree with the theme classes in distilledpage.css. const themeClasses = ['light', 'dark', 'sepia']; function useTheme(theme) { themeClasses.forEach( - (element) => document.body.classList.toggle(element, element == theme)); + (element) => document.body.classList.toggle(element, element === theme)); updateToolbarColor(theme); } @@ -92,9 +92,9 @@ function updateToolbarColor(theme) { let toolbarColor; - if (theme == 'sepia') { + if (theme === 'sepia') { toolbarColor = '#BF9A73'; - } else if (theme == 'dark') { + } else if (theme === 'dark') { toolbarColor = '#1A1A1A'; } else { toolbarColor = '#F5F5F5';
diff --git a/components/dom_distiller/core/javascript/domdistiller.js b/components/dom_distiller/core/javascript/domdistiller.js index 069684be..62050063f 100644 --- a/components/dom_distiller/core/javascript/domdistiller.js +++ b/components/dom_distiller/core/javascript/domdistiller.js
@@ -27,7 +27,7 @@ return res; } catch (e) { window.console.error('Error during distillation: ' + e); - if (e.stack != undefined) { + if (e.stack !== undefined) { window.console.error(e.stack); } }
diff --git a/components/dom_distiller/core/javascript/extract_features.js b/components/dom_distiller/core/javascript/extract_features.js index 6c166e3..11a4883 100644 --- a/components/dom_distiller/core/javascript/extract_features.js +++ b/components/dom_distiller/core/javascript/extract_features.js
@@ -7,7 +7,7 @@ const elems = document.head.querySelectorAll( 'meta[property="og:type"],meta[name="og:type"]'); for (const i in elems) { - if (elems[i].content && elems[i].content.toUpperCase() == 'ARTICLE') { + if (elems[i].content && elems[i].content.toUpperCase() === 'ARTICLE') { return true; } }
diff --git a/components/exo/data_offer.cc b/components/exo/data_offer.cc index eff37d39..a02dcd48 100644 --- a/components/exo/data_offer.cc +++ b/components/exo/data_offer.cc
@@ -304,7 +304,7 @@ void DataOffer::SetClipboardData(FileHelper* file_helper, const ui::Clipboard& data) { DCHECK_EQ(0u, data_.size()); - if (data.IsFormatAvailable(ui::ClipboardFormatType::GetPlainTextWType(), + if (data.IsFormatAvailable(ui::ClipboardFormatType::GetPlainTextType(), ui::ClipboardBuffer::kCopyPaste)) { auto utf8_callback = base::BindRepeating(&ReadTextFromClipboard, std::string(kUTF8));
diff --git a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/EventConstants.java b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/EventConstants.java index 9fa9efa3..66d950f 100644 --- a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/EventConstants.java +++ b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/EventConstants.java
@@ -157,6 +157,9 @@ /** User has tapped on Identity Disc. */ public static final String IDENTITY_DISC_USED = "identity_disc_used"; + /** User has used Ephemeral Tab i.e. opened and browsed the content. */ + public static final String EPHEMERAL_TAB_USED = "ephemeral_tab_used"; + /** * Do not instantiate. */
diff --git a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java index f14d4ca..71d57961 100644 --- a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java +++ b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java
@@ -21,7 +21,7 @@ FeatureConstants.CHROME_HOME_EXPAND_FEATURE, FeatureConstants.CHROME_HOME_PULL_TO_REFRESH_FEATURE, FeatureConstants.DATA_SAVER_PREVIEW_FEATURE, FeatureConstants.DATA_SAVER_DETAIL_FEATURE, - FeatureConstants.PREVIEWS_OMNIBOX_UI_FEATURE, + FeatureConstants.EPHEMERAL_TAB_FEATURE, FeatureConstants.PREVIEWS_OMNIBOX_UI_FEATURE, FeatureConstants.TRANSLATE_MENU_BUTTON_FEATURE, FeatureConstants.CONTEXTUAL_SEARCH_WEB_SEARCH_FEATURE, FeatureConstants.CONTEXTUAL_SEARCH_PROMOTE_TAP_FEATURE, @@ -52,6 +52,7 @@ String DATA_SAVER_PREVIEW_FEATURE = "IPH_DataSaverPreview"; String DATA_SAVER_DETAIL_FEATURE = "IPH_DataSaverDetail"; String DATA_SAVER_MILESTONE_PROMO_FEATURE = "IPH_DataSaverMilestonePromo"; + String EPHEMERAL_TAB_FEATURE = "IPH_EphemeralTab"; String KEYBOARD_ACCESSORY_ADDRESS_FILL_FEATURE = "IPH_KeyboardAccessoryAddressFilling"; String KEYBOARD_ACCESSORY_PASSWORD_FILLING_FEATURE = "IPH_KeyboardAccessoryPasswordFilling"; String KEYBOARD_ACCESSORY_PAYMENT_FILLING_FEATURE = "IPH_KeyboardAccessoryPaymentFilling";
diff --git a/components/feature_engagement/public/feature_constants.cc b/components/feature_engagement/public/feature_constants.cc index 520aa28..50b4b5b 100644 --- a/components/feature_engagement/public/feature_constants.cc +++ b/components/feature_engagement/public/feature_constants.cc
@@ -75,6 +75,8 @@ "IPH_DownloadInfoBarDownloadsAreFaster", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kIPHQuietNotificationPromptsFeature{ "IPH_QuietNotificationPrompts", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kIPHEphemeralTabFeature{"IPH_EphemeralTab", + base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kIPHFeedCardMenuFeature{"IPH_FeedCardMenu", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kIPHIdentityDiscFeature{"IPH_IdentityDisc",
diff --git a/components/feature_engagement/public/feature_constants.h b/components/feature_engagement/public/feature_constants.h index de4b4117..d062cfc 100644 --- a/components/feature_engagement/public/feature_constants.h +++ b/components/feature_engagement/public/feature_constants.h
@@ -54,6 +54,7 @@ extern const base::Feature kIPHDownloadSettingsFeature; extern const base::Feature kIPHDownloadInfoBarDownloadContinuingFeature; extern const base::Feature kIPHDownloadInfoBarDownloadsAreFasterFeature; +extern const base::Feature kIPHEphemeralTabFeature; extern const base::Feature kIPHFeedCardMenuFeature; extern const base::Feature kIPHHomePageButtonFeature; extern const base::Feature kIPHHomepageTileFeature;
diff --git a/components/feature_engagement/public/feature_list.cc b/components/feature_engagement/public/feature_list.cc index 8367202..4843659 100644 --- a/components/feature_engagement/public/feature_list.cc +++ b/components/feature_engagement/public/feature_list.cc
@@ -35,6 +35,7 @@ &kIPHDownloadSettingsFeature, &kIPHDownloadInfoBarDownloadContinuingFeature, &kIPHDownloadInfoBarDownloadsAreFasterFeature, + &kIPHEphemeralTabFeature, &kIPHFeedCardMenuFeature, &kIPHIdentityDiscFeature, &kIPHKeyboardAccessoryAddressFillingFeature,
diff --git a/components/feature_engagement/public/feature_list.h b/components/feature_engagement/public/feature_list.h index ed5fe83a..16866bb 100644 --- a/components/feature_engagement/public/feature_list.h +++ b/components/feature_engagement/public/feature_list.h
@@ -76,6 +76,7 @@ "IPH_DownloadInfoBarDownloadContinuing"); DEFINE_VARIATION_PARAM(kIPHDownloadInfoBarDownloadsAreFasterFeature, "IPH_DownloadInfoBarDownloadsAreFaster"); +DEFINE_VARIATION_PARAM(kIPHEphemeralTabFeature, "IPH_EphemeralTab"); DEFINE_VARIATION_PARAM(kIPHFeedCardMenuFeature, "IPH_FeedCardMenu"); DEFINE_VARIATION_PARAM(kIPHIdentityDiscFeature, "IPH_IdentityDisc"); DEFINE_VARIATION_PARAM(kIPHKeyboardAccessoryAddressFillingFeature, @@ -150,6 +151,7 @@ VARIATION_ENTRY(kIPHDownloadSettingsFeature), VARIATION_ENTRY(kIPHDownloadInfoBarDownloadContinuingFeature), VARIATION_ENTRY(kIPHDownloadInfoBarDownloadsAreFasterFeature), + VARIATION_ENTRY(kIPHEphemeralTabFeature), VARIATION_ENTRY(kIPHFeedCardMenuFeature), VARIATION_ENTRY(kIPHIdentityDiscFeature), VARIATION_ENTRY(kIPHKeyboardAccessoryAddressFillingFeature),
diff --git a/components/flags_ui/resources/flags.js b/components/flags_ui/resources/flags.js index fcca6b3..880dff21 100644 --- a/components/flags_ui/resources/flags.js +++ b/components/flags_ui/resources/flags.js
@@ -95,8 +95,8 @@ tabEls[i].addEventListener('click', function(e) { e.preventDefault(); for (let j = 0; j < tabEls.length; ++j) { - tabEls[j].parentNode.classList.toggle('selected', tabEls[j] == this); - tabEls[j].setAttribute('aria-selected', tabEls[j] == this); + tabEls[j].parentNode.classList.toggle('selected', tabEls[j] === this); + tabEls[j].setAttribute('aria-selected', tabEls[j] === this); } FlagSearch.getInstance().announceSearchResults(); }); @@ -126,7 +126,7 @@ */ function registerFocusEvents(el) { el.addEventListener('keydown', function(e) { - if (lastChanged && e.key == 'Tab' && !e.shiftKey) { + if (lastChanged && e.key === 'Tab' && !e.shiftKey) { lastFocused = lastChanged; e.preventDefault(); restartButton.focus(); @@ -313,8 +313,8 @@ /** @suppress {missingProperties} */ const experimentContainerEl = $(node.internal_name).firstElementChild; const isDefault = - ("default" in selected.dataset && selected.dataset.default == "1") || - (!("default" in selected.dataset) && index === 0); + ('default' in selected.dataset && selected.dataset.default === '1') || + (!('default' in selected.dataset) && index === 0); experimentContainerEl.classList.toggle('experiment-default', isDefault); experimentContainerEl.classList.toggle('experiment-switched', !isDefault); @@ -452,18 +452,18 @@ this.clearSearch.bind(this)); window.addEventListener('keyup', function(e) { - if (document.activeElement.nodeName == "TEXTAREA") { - return; - } - switch(e.key) { - case '/': - this.searchBox_.focus(); - break; - case 'Escape': - case 'Enter': - this.searchBox_.blur(); - break; - } + if (document.activeElement.nodeName === 'TEXTAREA') { + return; + } + switch (e.key) { + case '/': + this.searchBox_.focus(); + break; + case 'Escape': + case 'Enter': + this.searchBox_.blur(); + break; + } }.bind(this)); this.searchBox_.focus(); this.initialized = true; @@ -501,14 +501,14 @@ const text = el.textContent; const match = text.toLowerCase().indexOf(searchTerm); - parentEl.classList.toggle('hidden', match == -1); + parentEl.classList.toggle('hidden', match === -1); - if (match == -1) { + if (match === -1) { this.resetHighlights(el, text); return false; } - if (searchTerm != '') { + if (searchTerm !== '') { // Clear all nodes. el.textContent = ''; @@ -583,7 +583,7 @@ doSearch() { const searchTerm = this.searchBox_.value.trim().toLowerCase(); - if (searchTerm || searchTerm == '') { + if (searchTerm || searchTerm === '') { document.body.classList.toggle('searching', searchTerm); // Available experiments this.noMatchMsg_[0].classList.toggle( @@ -610,7 +610,7 @@ const tabEls = document.getElementsByClassName('tab'); for (let i = 0; i < tabEls.length; ++i) { if (tabEls[i].parentNode.classList.contains('selected')) { - tabAvailable = tabEls[i].id == 'tab-available'; + tabAvailable = tabEls[i].id === 'tab-available'; } } const seletedTabId = @@ -618,9 +618,11 @@ const queryString = seletedTabId + ' .experiment:not(.hidden)'; const total = document.querySelectorAll(queryString).length; if (total) { - announceStatus((total == 1) ? - loadTimeData.getStringF("searchResultsSingular", searchTerm) : - loadTimeData.getStringF("searchResultsPlural", total, searchTerm)); + announceStatus( + total === 1 ? + loadTimeData.getStringF('searchResultsSingular', searchTerm) : + loadTimeData.getStringF( + 'searchResultsPlural', total, searchTerm)); } }, @@ -643,7 +645,7 @@ */ function setupRestartButton() { restartButton.addEventListener('keydown', function(e) { - if (e.shiftKey && e.key == 'Tab' && lastFocused) { + if (e.shiftKey && e.key === 'Tab' && lastFocused) { e.preventDefault(); lastFocused.focus(); }
diff --git a/components/invalidation/impl/per_user_topic_subscription_manager.cc b/components/invalidation/impl/per_user_topic_subscription_manager.cc index 5c3ba07..e301856 100644 --- a/components/invalidation/impl/per_user_topic_subscription_manager.cc +++ b/components/invalidation/impl/per_user_topic_subscription_manager.cc
@@ -411,7 +411,7 @@ pending_subscriptions_[topic]->request_retry_timer_.Start( FROM_HERE, pending_subscriptions_[topic]->request_backoff_.GetTimeUntilRelease(), - base::BindRepeating( + base::BindOnce( &PerUserTopicSubscriptionManager::StartPendingSubscriptionRequest, base::Unretained(this), topic)); } @@ -426,6 +426,15 @@ } else { auto it = pending_subscriptions_.find(topic); if (code.IsAuthFailure()) { + // Invalidate previous token, otherwise the identity provider will return + // the same token again. + // TODO(crbug.com/1020117): Don't invalidate multiple access tokens in a + // row - just retry once, then give up. (Or at least use backoff!) + if (!access_token_.empty()) { + identity_provider_->InvalidateAccessToken({kFCMOAuthScope}, + access_token_); + access_token_.clear(); + } // Re-request access token and try subscription requests again. RequestAccessToken(); } else { @@ -440,6 +449,10 @@ pending_subscriptions_.erase(it); return; } + // TODO(crbug.com/1020117): This should probably go through + // RequestAccessToken() to make sure we have a fresh one. (The identity + // code will only actually request a new one from the network if the + // existing one has expired.) ScheduleRequestForRepetition(topic); } } @@ -462,12 +475,6 @@ } void PerUserTopicSubscriptionManager::RequestAccessToken() { - // TODO(crbug.com/1020117): Implement traffic optimisation. - // * Before sending request to server ask for access token from identity - // provider (don't invalidate previous token). - // Identity provider will take care of retrieving/caching. - // * Only invalidate access token when server didn't accept it. - // Only one active request at a time. if (access_token_fetcher_ != nullptr) return; @@ -475,13 +482,9 @@ // should probably early-out instead of starting a request immediately. As it // is, this might bypass the exponential backoff. request_access_token_retry_timer_.Stop(); - OAuth2AccessTokenManager::ScopeSet oauth2_scopes = {kFCMOAuthScope}; - // Invalidate previous token, otherwise the identity provider will return the - // same token again. - identity_provider_->InvalidateAccessToken(oauth2_scopes, access_token_); access_token_.clear(); access_token_fetcher_ = identity_provider_->FetchAccessToken( - "fcm_invalidation", oauth2_scopes, + "fcm_invalidation", {kFCMOAuthScope}, base::BindOnce( &PerUserTopicSubscriptionManager::OnAccessTokenRequestCompleted, base::Unretained(this))); @@ -519,8 +522,8 @@ request_access_token_backoff_.InformOfRequest(false); request_access_token_retry_timer_.Start( FROM_HERE, request_access_token_backoff_.GetTimeUntilRelease(), - base::BindRepeating(&PerUserTopicSubscriptionManager::RequestAccessToken, - base::Unretained(this))); + base::BindOnce(&PerUserTopicSubscriptionManager::RequestAccessToken, + base::Unretained(this))); } void PerUserTopicSubscriptionManager::DropAllSavedSubscriptionsOnTokenChange() {
diff --git a/components/net_log/resources/net_export.js b/components/net_log/resources/net_export.js index 19b7d43..5d4ca98 100644 --- a/components/net_log/resources/net_export.js +++ b/components/net_log/resources/net_export.js
@@ -284,7 +284,7 @@ ]; for (const curDivId of kAllDivIds) { - $(curDivId).hidden = divId != curDivId; + $(curDivId).hidden = divId !== curDivId; } }, };
diff --git a/components/neterror/resources/neterror.js b/components/neterror/resources/neterror.js index cbe8d85..fb7fd6d 100644 --- a/components/neterror/resources/neterror.js +++ b/components/neterror/resources/neterror.js
@@ -73,7 +73,7 @@ // Subframes use a different layout but the same html file. This is to make it // easier to support platforms that load the error page via different // mechanisms (Currently just iOS). -if (window.top.location != window.location) { +if (window.top.location !== window.location) { document.documentElement.setAttribute('subframe', ''); } @@ -92,7 +92,7 @@ if (classList.hasOwnProperty('last_icon_class')) { oldClass = classList['last_icon_class']; - if (oldClass == newClass) { + if (oldClass === newClass) { return; } } @@ -104,7 +104,7 @@ classList['last_icon_class'] = newClass; - if (newClass == 'icon-offline') { + if (newClass === 'icon-offline') { document.firstElementChild.classList.add('offline'); new Runner('.interstitial-wrapper'); } else { @@ -358,7 +358,7 @@ } const contentListElement = document.getElementById('offline-content-list'); - if (document.dir == 'rtl') { + if (document.dir === 'rtl') { contentListElement.classList.add('is-rtl'); } contentListElement.hidden = false; @@ -420,8 +420,8 @@ const reloadButton = document.getElementById('reload-button'); const downloadButton = document.getElementById('download-button'); - if (reloadButton.style.display == 'none' && - downloadButton.style.display == 'none') { + if (reloadButton.style.display === 'none' && + downloadButton.style.display === 'none') { detailsButton.classList.add('singular'); }
diff --git a/components/neterror/resources/offline.js b/components/neterror/resources/offline.js index 629c873..9fafe9d 100644 --- a/components/neterror/resources/offline.js +++ b/components/neterror/resources/offline.js
@@ -272,7 +272,7 @@ * @param {number|string} value */ updateConfigSetting(setting, value) { - if (setting in this.config && value != undefined) { + if (setting in this.config && value !== undefined) { this.config[setting] = value; switch (setting) { @@ -569,7 +569,7 @@ const hasObstacles = this.runningTime > this.config.CLEAR_TIME; // First jump triggers the intro. - if (this.tRex.jumpCount == 1 && !this.playingIntro) { + if (this.tRex.jumpCount === 1 && !this.playingIntro) { this.playIntro(); } @@ -711,12 +711,12 @@ if (this.isCanvasInView()) { if (!this.crashed && !this.paused) { if (Runner.keycodes.JUMP[e.keyCode] || - e.type == Runner.events.TOUCHSTART) { + e.type === Runner.events.TOUCHSTART) { e.preventDefault(); // Starting the game for the first time. if (!this.playing) { // Started by touch so create a touch controller. - if (!this.touchController && e.type == Runner.events.TOUCHSTART) { + if (!this.touchController && e.type === Runner.events.TOUCHSTART) { this.createTouchController(); } this.loadSounds(); @@ -742,8 +742,9 @@ } } // iOS only triggers touchstart and no pointer events. - } else if (IS_IOS && this.crashed && e.type == Runner.events.TOUCHSTART && - e.currentTarget == this.containerEl) { + } else if ( + IS_IOS && this.crashed && e.type === Runner.events.TOUCHSTART && + e.currentTarget === this.containerEl) { this.handleGameOverClicks(e); } } @@ -756,8 +757,7 @@ onKeyUp(e) { const keyCode = String(e.keyCode); const isjumpKey = Runner.keycodes.JUMP[keyCode] || - e.type == Runner.events.TOUCHEND || - e.type == Runner.events.POINTERUP; + e.type === Runner.events.TOUCHEND || e.type === Runner.events.POINTERUP; if (this.isRunning() && isjumpKey) { this.tRex.endJump(); @@ -862,7 +862,7 @@ previousState = this.previousGamepad.buttons[buttonIndex].pressed; } // Generate key events on the rising and falling edge of a button press. - if (state != previousState) { + if (state !== previousState) { const e = new KeyboardEvent(state ? Runner.events.KEYDOWN : Runner.events.KEYUP, { keyCode: keyCode }); @@ -900,7 +900,7 @@ */ isLeftClickOnCanvas(e) { return e.button != null && e.button < 2 && - e.type == Runner.events.POINTERUP && e.target == this.canvas; + e.type === Runner.events.POINTERUP && e.target === this.canvas; }, /** @@ -1041,7 +1041,7 @@ * @return {boolean} */ isArcadeMode() { - return document.title == ARCADE_MODE_URL; + return document.title === ARCADE_MODE_URL; }, /** @@ -1075,8 +1075,8 @@ * Pause the game if the tab is not in focus. */ onVisibilityChange(e) { - if (document.hidden || document.webkitHidden || e.type == 'blur' || - document.visibilityState != 'visible') { + if (document.hidden || document.webkitHidden || e.type === 'blur' || + document.visibilityState !== 'visible') { this.stop(); } else if (!this.crashed) { this.tRex.reset(); @@ -1156,7 +1156,7 @@ // our canvas element. context.scale(ratio, ratio); return true; - } else if (devicePixelRatio == 1) { + } else if (devicePixelRatio === 1) { // Reset the canvas width / height. Fixes scaling bug when the page is // zoomed and the devicePixelRatio changes accordingly. canvas.style.width = canvas.width + 'px'; @@ -1613,7 +1613,7 @@ this.timer += deltaTime; if (this.timer >= this.typeConfig.frameRate) { this.currentFrame = - this.currentFrame == this.typeConfig.numFrames - 1 ? + this.currentFrame === this.typeConfig.numFrames - 1 ? 0 : this.currentFrame + 1; this.timer = 0; @@ -1902,7 +1902,7 @@ this.msPerFrame = Trex.animFrames[opt_status].msPerFrame; this.currentAnimFrames = Trex.animFrames[opt_status].frames; - if (opt_status == Trex.status.WAITING) { + if (opt_status === Trex.status.WAITING) { this.animStartTime = getTimeStamp(); this.setBlinkDelay(); } @@ -1915,7 +1915,7 @@ this.xInitialPos = this.xPos; } - if (this.status == Trex.status.WAITING) { + if (this.status === Trex.status.WAITING) { this.blink(getTimeStamp()); } else { this.draw(this.currentAnimFrames[this.currentFrame], 0); @@ -1929,7 +1929,7 @@ } // Speed drop becomes duck if the down key is still being pressed. - if (this.speedDrop && this.yPos == this.groundYPos) { + if (this.speedDrop && this.yPos === this.groundYPos) { this.speedDrop = false; this.setDuck(true); } @@ -1943,8 +1943,9 @@ draw(x, y) { let sourceX = x; let sourceY = y; - let sourceWidth = this.ducking && this.status != Trex.status.CRASHED ? - this.config.WIDTH_DUCK : this.config.WIDTH; + let sourceWidth = this.ducking && this.status !== Trex.status.CRASHED ? + this.config.WIDTH_DUCK : + this.config.WIDTH; let sourceHeight = this.config.HEIGHT; const outputHeight = sourceHeight; @@ -1960,14 +1961,14 @@ sourceY += this.spritePos.y; // Ducking. - if (this.ducking && this.status != Trex.status.CRASHED) { + if (this.ducking && this.status !== Trex.status.CRASHED) { this.canvasCtx.drawImage(Runner.imageSprite, sourceX, sourceY, sourceWidth, sourceHeight, this.xPos, this.yPos, this.config.WIDTH_DUCK, outputHeight); } else { // Crashed whilst ducking. Trex is standing up so needs adjustment. - if (this.ducking && this.status == Trex.status.CRASHED) { + if (this.ducking && this.status === Trex.status.CRASHED) { this.xPos++; } // Standing / running @@ -1996,7 +1997,7 @@ if (deltaTime >= this.blinkDelay) { this.draw(this.currentAnimFrames[this.currentFrame], 0); - if (this.currentFrame == 1) { + if (this.currentFrame === 1) { // Set new random delay to blink. this.setBlinkDelay(); this.animStartTime = time; @@ -2077,10 +2078,10 @@ * @param {boolean} isDucking */ setDuck(isDucking) { - if (isDucking && this.status != Trex.status.DUCKING) { + if (isDucking && this.status !== Trex.status.DUCKING) { this.update(0, Trex.status.DUCKING); this.ducking = true; - } else if (this.status == Trex.status.DUCKING) { + } else if (this.status === Trex.status.DUCKING) { this.update(0, Trex.status.RUNNING); this.ducking = false; } @@ -2291,8 +2292,8 @@ } if (distance > 0) { - // Acheivement unlocked - if (distance % this.config.ACHIEVEMENT_DISTANCE == 0) { + // Achievement unlocked. + if (distance % this.config.ACHIEVEMENT_DISTANCE === 0) { // Flash score and play sound. this.achievement = true; this.flashTimer = 0; @@ -2646,7 +2647,7 @@ */ update(activated) { // Moon phase. - if (activated && this.opacity == 0) { + if (activated && this.opacity === 0) { this.currentPhase++; if (this.currentPhase >= NightMode.phases.length) { @@ -2655,7 +2656,7 @@ } // Fade in / out. - if (activated && (this.opacity < 1 || this.opacity == 0)) { + if (activated && (this.opacity < 1 || this.opacity === 0)) { this.opacity += NightMode.config.FADE_SPEED; } else if (this.opacity > 0) { this.opacity -= NightMode.config.FADE_SPEED; @@ -2690,8 +2691,8 @@ }, draw() { - let moonSourceWidth = this.currentPhase == 3 ? NightMode.config.WIDTH * 2 : - NightMode.config.WIDTH; + let moonSourceWidth = this.currentPhase === 3 ? NightMode.config.WIDTH * 2 : + NightMode.config.WIDTH; let moonSourceHeight = NightMode.config.HEIGHT; let moonSourceX = this.spritePos.x + NightMode.phases[this.currentPhase]; const moonOutputWidth = moonSourceWidth; @@ -2804,7 +2805,7 @@ setSourceDimensions() { for (const dimension in HorizonLine.dimensions) { if (IS_HIDPI) { - if (dimension != 'YPOS') { + if (dimension !== 'YPOS') { this.sourceDimensions[dimension] = HorizonLine.dimensions[dimension] * 2; } @@ -2850,7 +2851,7 @@ */ updateXPos(pos, increment) { const line1 = pos; - const line2 = pos == 0 ? 1 : 0; + const line2 = pos === 0 ? 1 : 0; this.xPos[line1] -= increment; this.xPos[line2] = this.xPos[line1] + this.dimensions.WIDTH; @@ -3074,8 +3075,8 @@ let duplicateCount = 0; for (let i = 0; i < this.obstacleHistory.length; i++) { - duplicateCount = this.obstacleHistory[i] == nextObstacleType ? - duplicateCount + 1 : 0; + duplicateCount = + this.obstacleHistory[i] === nextObstacleType ? duplicateCount + 1 : 0; } return duplicateCount >= Runner.config.MAX_OBSTACLE_DUPLICATION; },
diff --git a/components/password_manager/core/browser/password_autofill_manager.cc b/components/password_manager/core/browser/password_autofill_manager.cc index 06bd330..204894c 100644 --- a/components/password_manager/core/browser/password_autofill_manager.cc +++ b/components/password_manager/core/browser/password_autofill_manager.cc
@@ -231,7 +231,7 @@ password_client_->NavigateToManagePasswordsPage( ManagePasswordsReferrer::kPasswordDropdown); metrics_util::LogContextOfShowAllSavedPasswordsAccepted( - metrics_util::SHOW_ALL_SAVED_PASSWORDS_CONTEXT_PASSWORD); + metrics_util::ShowAllSavedPasswordsContext::kPassword); metrics_util::LogPasswordDropdownItemSelected( PasswordDropdownSelectedOption::kShowAll, password_client_->IsIncognito()); @@ -345,7 +345,7 @@ suggestions.push_back(suggestion); metrics_util::LogContextOfShowAllSavedPasswordsShown( - metrics_util::SHOW_ALL_SAVED_PASSWORDS_CONTEXT_PASSWORD); + metrics_util::ShowAllSavedPasswordsContext::kPassword); } if (show_account_storage_optin) { @@ -408,7 +408,7 @@ suggestions.push_back(suggestion); metrics_util::LogContextOfShowAllSavedPasswordsShown( - metrics_util::SHOW_ALL_SAVED_PASSWORDS_CONTEXT_PASSWORD); + metrics_util::ShowAllSavedPasswordsContext::kPassword); } if (!password_manager_driver_->CanShowAutofillUi())
diff --git a/components/password_manager/core/browser/password_autofill_manager_unittest.cc b/components/password_manager/core/browser/password_autofill_manager_unittest.cc index 097c3b2..ff3588c0 100644 --- a/components/password_manager/core/browser/password_autofill_manager_unittest.cc +++ b/components/password_manager/core/browser/password_autofill_manager_unittest.cc
@@ -657,7 +657,7 @@ // Expect a sample only in the shown histogram. histograms.ExpectUniqueSample( kShownContextHistogram, - metrics_util::SHOW_ALL_SAVED_PASSWORDS_CONTEXT_PASSWORD, 1); + metrics_util::ShowAllSavedPasswordsContext::kPassword, 1); // Clicking at the "Show all passwords row" should trigger a call to open // the Password Manager settings page and hide the popup. EXPECT_CALL( @@ -670,10 +670,10 @@ // Expect a sample in both the shown and accepted histogram. histograms.ExpectUniqueSample( kShownContextHistogram, - metrics_util::SHOW_ALL_SAVED_PASSWORDS_CONTEXT_PASSWORD, 1); + metrics_util::ShowAllSavedPasswordsContext::kPassword, 1); histograms.ExpectUniqueSample( kAcceptedContextHistogram, - metrics_util::SHOW_ALL_SAVED_PASSWORDS_CONTEXT_PASSWORD, 1); + metrics_util::ShowAllSavedPasswordsContext::kPassword, 1); histograms.ExpectUniqueSample( kDropdownSelectedHistogram, metrics_util::PasswordDropdownSelectedOption::kShowAll, 1);
diff --git a/components/password_manager/core/browser/password_manager_metrics_util.cc b/components/password_manager/core/browser/password_manager_metrics_util.cc index 263c61d1..5a0e798 100644 --- a/components/password_manager/core/browser/password_manager_metrics_util.cc +++ b/components/password_manager/core/browser/password_manager_metrics_util.cc
@@ -190,15 +190,13 @@ void LogContextOfShowAllSavedPasswordsShown( ShowAllSavedPasswordsContext context) { base::UmaHistogramEnumeration( - "PasswordManager.ShowAllSavedPasswordsShownContext", context, - SHOW_ALL_SAVED_PASSWORDS_CONTEXT_COUNT); + "PasswordManager.ShowAllSavedPasswordsShownContext", context); } void LogContextOfShowAllSavedPasswordsAccepted( ShowAllSavedPasswordsContext context) { base::UmaHistogramEnumeration( - "PasswordManager.ShowAllSavedPasswordsAcceptedContext", context, - SHOW_ALL_SAVED_PASSWORDS_CONTEXT_COUNT); + "PasswordManager.ShowAllSavedPasswordsAcceptedContext", context); } void LogPasswordDropdownShown(PasswordDropdownState state,
diff --git a/components/password_manager/core/browser/password_manager_metrics_util.h b/components/password_manager/core/browser/password_manager_metrics_util.h index 816c56c..e6bfcdf 100644 --- a/components/password_manager/core/browser/password_manager_metrics_util.h +++ b/components/password_manager/core/browser/password_manager_metrics_util.h
@@ -330,16 +330,19 @@ // Metrics: // - PasswordManager.ShowAllSavedPasswordsAcceptedContext // - PasswordManager.ShowAllSavedPasswordsShownContext -enum ShowAllSavedPasswordsContext { - SHOW_ALL_SAVED_PASSWORDS_CONTEXT_NONE, +// +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class ShowAllSavedPasswordsContext { + kNone = 0, // The "Show all saved passwords..." fallback is shown below a list of // available passwords. - SHOW_ALL_SAVED_PASSWORDS_CONTEXT_PASSWORD, + kPassword = 1, // Obsolete. - SHOW_ALL_SAVED_PASSWORDS_CONTEXT_MANUAL_FALLBACK_DEPRECATED, + kManualFallbackDeprecated = 2, // The "Show all saved passwords..." fallback is shown in context menu. - SHOW_ALL_SAVED_PASSWORDS_CONTEXT_CONTEXT_MENU, - SHOW_ALL_SAVED_PASSWORDS_CONTEXT_COUNT + kContextMenu = 3, + kMaxValue = kContextMenu, }; // Metrics: "PasswordManager.CertificateErrorsWhileSeeingForms"
diff --git a/components/password_manager/core/browser/password_manager_util.cc b/components/password_manager/core/browser/password_manager_util.cc index d0fc224..7931cda 100644 --- a/components/password_manager/core/browser/password_manager_util.cc +++ b/components/password_manager/core/browser/password_manager_util.cc
@@ -146,8 +146,8 @@ return false; LogContextOfShowAllSavedPasswordsShown( - password_manager::metrics_util:: - SHOW_ALL_SAVED_PASSWORDS_CONTEXT_CONTEXT_MENU); + password_manager::metrics_util::ShowAllSavedPasswordsContext:: + kContextMenu); return true; }
diff --git a/components/password_manager/ios/resources/password_controller.js b/components/password_manager/ios/resources/password_controller.js index 2595fcc..cd7c02d 100644 --- a/components/password_manager/ios/resources/password_controller.js +++ b/components/password_manager/ios/resources/password_controller.js
@@ -90,11 +90,11 @@ } // Try to find buttons of type submit at first. let buttons = form.querySelectorAll('button[type="submit"]'); - if (buttons.length == 0) { + if (buttons.length === 0) { // Try to check all buttons. If there is only one button, assume that this // is the submit button. buttons = form.querySelectorAll('button'); - if (buttons.length != 1) { + if (buttons.length !== 1) { return; } } @@ -126,7 +126,7 @@ */ const findInputByFieldIdentifier = function(inputs, identifier) { for (let i = 0; i < inputs.length; ++i) { - if (identifier == __gCrWeb.form.getFieldIdentifier(inputs[i])) { + if (identifier === __gCrWeb.form.getFieldIdentifier(inputs[i])) { return inputs[i]; } } @@ -233,12 +233,12 @@ return false; } // Avoid resetting if same value, as it moves cursor to the end. - if (newPasswordField.value != password) { + if (newPasswordField.value !== password) { __gCrWeb.fill.setInputElementValue(password, newPasswordField); } const confirmPasswordField = findInputByFieldIdentifier(inputs, confirmPasswordIdentifier); - if (confirmPasswordField && confirmPasswordField.value != password) { + if (confirmPasswordField && confirmPasswordField.value !== password) { __gCrWeb.fill.setInputElementValue(password, confirmPasswordField); } return true; @@ -266,13 +266,13 @@ const form = forms[i]; const normalizedFormAction = opt_normalizedOrigin || __gCrWeb.fill.getCanonicalActionForForm(form); - if (formData.action != normalizedFormAction) { + if (formData.action !== normalizedFormAction) { continue; } const inputs = getFormInputElements(form); const usernameIdentifier = formData.fields[0].name; let usernameInput = null; - if (usernameIdentifier != '') { + if (usernameIdentifier !== '') { usernameInput = findInputByFieldIdentifier(inputs, usernameIdentifier); if (!usernameInput || !__gCrWeb.common.isTextField(usernameInput) || usernameInput.disabled) { @@ -282,7 +282,7 @@ const passwordInput = findInputByFieldIdentifier(inputs, formData.fields[1].name); - if (!passwordInput || passwordInput.type != 'password' || + if (!passwordInput || passwordInput.type !== 'password' || passwordInput.readOnly || passwordInput.disabled) { continue; } @@ -290,7 +290,7 @@ // If username was provided on a read-only field and it matches the // requested username, fill the form. if (usernameInput && usernameInput.readOnly) { - if (usernameInput.value == username) { + if (usernameInput.value === username) { __gCrWeb.fill.setInputElementValue(password, passwordInput); filled = true; }
diff --git a/components/policy/resources/webui/policy_base.js b/components/policy/resources/webui/policy_base.js index ecb5e84..4133121 100644 --- a/components/policy/resources/webui/policy_base.js +++ b/components/policy/resources/webui/policy_base.js
@@ -100,7 +100,7 @@ */ initialize(scope, status) { const notSpecifiedString = loadTimeData.getString('notSpecified'); - if (scope == 'device') { + if (scope === 'device') { // For device policy, set the appropriate title and populate the topmost // status item with the domain the device is enrolled into. this.querySelector('.legend').textContent = @@ -131,7 +131,7 @@ status.isOffHoursActive ? 'offHoursActive' : 'offHoursNotActive')); } - } else if (scope == 'machine') { + } else if (scope === 'machine') { // For machine policy, set the appropriate title and populate // machine enrollment status with the information that applies // to this machine. @@ -191,10 +191,10 @@ /** @param {Conflict} conflict */ initialize(conflict) { this.querySelector('.scope').textContent = loadTimeData.getString( - conflict.scope == 'user' ? 'scopeUser' : 'scopeDevice'); + conflict.scope === 'user' ? 'scopeUser' : 'scopeDevice'); this.querySelector('.level').textContent = loadTimeData.getString( - conflict.level == 'recommended' ? 'levelRecommended' : - 'levelMandatory'); + conflict.level === 'recommended' ? 'levelRecommended' : + 'levelMandatory'); this.querySelector('.source').textContent = loadTimeData.getString(conflict.source); this.querySelector('.value.row .value').textContent = conflict.value; @@ -260,12 +260,12 @@ if (!this.unset_) { const scopeDisplay = this.querySelector('.scope'); scopeDisplay.textContent = loadTimeData.getString( - policy.scope == 'user' ? 'scopeUser' : 'scopeDevice'); + policy.scope === 'user' ? 'scopeUser' : 'scopeDevice'); const levelDisplay = this.querySelector('.level'); levelDisplay.textContent = loadTimeData.getString( - policy.level == 'recommended' ? 'levelRecommended' : - 'levelMandatory'); + policy.level === 'recommended' ? 'levelRecommended' : + 'levelMandatory'); const sourceDisplay = this.querySelector('.source'); sourceDisplay.textContent = loadTimeData.getString(policy.source);
diff --git a/components/safe_browsing/content/web_ui/resources/safe_browsing.js b/components/safe_browsing/content/web_ui/resources/safe_browsing.js index 919bf9d..90adee2c 100644 --- a/components/safe_browsing/content/web_ui/resources/safe_browsing.js +++ b/components/safe_browsing/content/web_ui/resources/safe_browsing.js
@@ -248,7 +248,7 @@ const token = result[0]; const request = result[1]; - if ($(tableId + '-' + token) == undefined) { + if ($(tableId + '-' + token) === undefined) { insertTokenToTable(tableId, token); }
diff --git a/components/security_interstitials/core/browser/resources/extended_reporting.js b/components/security_interstitials/core/browser/resources/extended_reporting.js index 86f4460..20d9add6 100644 --- a/components/security_interstitials/core/browser/resources/extended_reporting.js +++ b/components/security_interstitials/core/browser/resources/extended_reporting.js
@@ -13,8 +13,8 @@ // interstitial type is not SAFEBROWSING or SSL or CAPTIVE_PORTAL. function setupExtendedReportingCheckbox() { const interstitialType = loadTimeData.getString('type'); - if (interstitialType != 'SAFEBROWSING' && interstitialType != 'SSL' && - interstitialType != 'CAPTIVE_PORTAL') { + if (interstitialType !== 'SAFEBROWSING' && interstitialType !== 'SSL' && + interstitialType !== 'CAPTIVE_PORTAL') { return; } @@ -26,11 +26,11 @@ $('opt-in-checkbox').checked = loadTimeData.getBoolean(SB_BOX_CHECKED); $('extended-reporting-opt-in').classList.remove('hidden'); - const billing = interstitialType == 'SAFEBROWSING' && - loadTimeData.getBoolean('billing'); + const billing = + interstitialType === 'SAFEBROWSING' && loadTimeData.getBoolean('billing'); let className = 'ssl-opt-in'; - if (interstitialType == 'SAFEBROWSING' && !billing) { + if (interstitialType === 'SAFEBROWSING' && !billing) { className = 'safe-browsing-opt-in'; }
diff --git a/components/security_interstitials/core/browser/resources/interstitial_large.js b/components/security_interstitials/core/browser/resources/interstitial_large.js index daaa94a..5b2196d 100644 --- a/components/security_interstitials/core/browser/resources/interstitial_large.js +++ b/components/security_interstitials/core/browser/resources/interstitial_large.js
@@ -17,9 +17,9 @@ // other approaches are both safer and have fewer side-effects. // See https://goo.gl/ZcZixP for more details. const BYPASS_SEQUENCE = window.atob('dGhpc2lzdW5zYWZl'); - if (BYPASS_SEQUENCE.charCodeAt(keyPressState) == e.keyCode) { + if (BYPASS_SEQUENCE.charCodeAt(keyPressState) === e.keyCode) { keyPressState++; - if (keyPressState == BYPASS_SEQUENCE.length) { + if (keyPressState === BYPASS_SEQUENCE.length) { sendCommand(SecurityInterstitialCommandId.CMD_PROCEED); keyPressState = 0; } @@ -65,14 +65,14 @@ function setupEvents() { const overridable = loadTimeData.getBoolean('overridable'); const interstitialType = loadTimeData.getString('type'); - const ssl = interstitialType == 'SSL'; - const captivePortal = interstitialType == 'CAPTIVE_PORTAL'; + const ssl = interstitialType === 'SSL'; + const captivePortal = interstitialType === 'CAPTIVE_PORTAL'; const badClock = ssl && loadTimeData.getBoolean('bad_clock'); - const lookalike = interstitialType == 'LOOKALIKE'; - const billing = interstitialType == 'SAFEBROWSING' && - loadTimeData.getBoolean('billing'); - const originPolicy = interstitialType == "ORIGIN_POLICY"; - const blockedInterception = interstitialType == "BLOCKED_INTERCEPTION"; + const lookalike = interstitialType === 'LOOKALIKE'; + const billing = + interstitialType === 'SAFEBROWSING' && loadTimeData.getBoolean('billing'); + const originPolicy = interstitialType === 'ORIGIN_POLICY'; + const blockedInterception = interstitialType === 'BLOCKED_INTERCEPTION'; const hidePrimaryButton = loadTimeData.getBoolean('hide_primary_button'); const showRecurrentErrorParagraph = loadTimeData.getBoolean( 'show_recurrent_error_paragraph');
diff --git a/components/security_interstitials/core/browser/resources/interstitial_webview_quiet.js b/components/security_interstitials/core/browser/resources/interstitial_webview_quiet.js index 236b6fc..40609a0 100644 --- a/components/security_interstitials/core/browser/resources/interstitial_webview_quiet.js +++ b/components/security_interstitials/core/browser/resources/interstitial_webview_quiet.js
@@ -22,8 +22,8 @@ const isGiantWebView = loadTimeData.getBoolean('is_giant'); const darkModeAvailable = loadTimeData.getBoolean('darkModeAvailable'); const interstitialType = loadTimeData.getString('type'); - const safebrowsing = interstitialType == "SAFEBROWSING"; - const heavyAd = interstitialType == "HEAVYAD"; + const safebrowsing = interstitialType === 'SAFEBROWSING'; + const heavyAd = interstitialType === 'HEAVYAD'; document.body.className = isGiantWebView ? 'giant' : '';
diff --git a/components/security_interstitials/core/browser/resources/ssl.js b/components/security_interstitials/core/browser/resources/ssl.js index 5930e2a1..e43c68e 100644 --- a/components/security_interstitials/core/browser/resources/ssl.js +++ b/components/security_interstitials/core/browser/resources/ssl.js
@@ -3,7 +3,7 @@ // found in the LICENSE file. function setupSSLDebuggingInfo() { - if (loadTimeData.getString('type') != 'SSL') { + if (loadTimeData.getString('type') !== 'SSL') { return; }
diff --git a/components/security_interstitials/core/common/resources/interstitial_common.js b/components/security_interstitials/core/common/resources/interstitial_common.js index 11f087d..27c543f 100644 --- a/components/security_interstitials/core/common/resources/interstitial_common.js +++ b/components/security_interstitials/core/common/resources/interstitial_common.js
@@ -126,10 +126,10 @@ function preventDefaultOnPoundLinkClicks() { document.addEventListener('click', function(e) { const anchor = findAncestor(/** @type {Node} */ (e.target), function(el) { - return el.tagName == 'A'; + return el.tagName === 'A'; }); // Use getAttribute() to prevent URL normalization. - if (anchor && anchor.getAttribute('href') == '#') { + if (anchor && anchor.getAttribute('href') === '#') { e.preventDefault(); } });
diff --git a/components/security_interstitials/core/common/resources/interstitial_mobile_nav.js b/components/security_interstitials/core/common/resources/interstitial_mobile_nav.js index bf13bbe2..5787630 100644 --- a/components/security_interstitials/core/common/resources/interstitial_mobile_nav.js +++ b/components/security_interstitials/core/common/resources/interstitial_mobile_nav.js
@@ -20,7 +20,7 @@ const runnerContainer = document.querySelector('.runner-container'); // Check for change in nav status. - if (mobileNav != window.matchMedia(mediaQuery).matches) { + if (mobileNav !== window.matchMedia(mediaQuery).matches) { mobileNav = !mobileNav; // Handle showing the top content / details sections according to state.
diff --git a/components/signin/core/browser/resources/signin_internals.js b/components/signin/core/browser/resources/signin_internals.js index 3f0e7297..c5bcefd 100644 --- a/components/signin/core/browser/resources/signin_internals.js +++ b/components/signin/core/browser/resources/signin_internals.js
@@ -16,11 +16,11 @@ // TODO(vishwath): This function is identical to the one in sync_internals.js // Merge both if possible. -// Accepts a DOM node and sets its highlighted attribute oldVal != newVal +// Accepts a DOM node and sets its highlighted attribute oldVal !== newVal function highlightIfChanged(node, oldVal, newVal) { const oldStr = oldVal.toString(); const newStr = newVal.toString(); - if (oldStr != '' && oldStr != newStr) { + if (oldStr !== '' && oldStr !== newStr) { // Note the addListener function does not end up creating duplicate // listeners. There can be only one listener per event at a time. // Reference: https://developer.mozilla.org/en/DOM/element.addEventListener @@ -39,10 +39,10 @@ } function setClassFromValue(value) { - if (value == 0) { + if (value === 0) { return 'zero'; } - if (value == 'Successful') { + if (value === 'Successful') { return 'ok'; } @@ -68,7 +68,7 @@ // Remove a listener from the list. Event.prototype.removeListener = function(listener) { const i = this.findListener_(listener); - if (i == -1) { + if (i === -1) { return; } this.listeners_.splice(i, 1); @@ -88,7 +88,7 @@ // Returns the index of the given listener, or -1 if not found. Event.prototype.findListener_ = function(listener) { for (let i = 0; i < this.listeners_.length; i++) { - if (this.listeners_[i] == listener) { + if (this.listeners_[i] === listener) { return i; } }
diff --git a/components/sync/driver/resources/about.js b/components/sync/driver/resources/about.js index f1377d83..20cf9c0 100644 --- a/components/sync/driver/resources/about.js +++ b/components/sync/driver/resources/about.js
@@ -13,7 +13,7 @@ const oldStr = oldVal.toString(); const newStr = newVal.toString(); - if (oldStr != '' && oldStr != newStr) { + if (oldStr !== '' && oldStr !== newStr) { // Note the addListener function does not end up creating duplicate // listeners. There can be only one listener per event at a time. // Reference: https://developer.mozilla.org/en/DOM/element.addEventListener @@ -40,7 +40,7 @@ const typeStatusArray = chrome.sync.aboutInfo.type_status; typeStatusArray.forEach(function(row) { - if (row.name == modelType) { + if (row.name === modelType) { // There are three types of counters, only "status" counters have these // fields. Keep the old values if updated fields are not present. if (counters.numEntriesAndTombstones !== undefined) { @@ -61,7 +61,7 @@ * @return {boolean} true if the element is scrolled to the bottom */ function isScrolledToBottom(elem) { - return elem.scrollHeight - elem.scrollTop == elem.clientHeight; + return elem.scrollHeight - elem.scrollTop === elem.clientHeight; } /** @@ -157,7 +157,7 @@ const importStatusButton = $('import-status'); importStatusButton.addEventListener('click', function(event) { $('status-data').hidden = false; - if ($('status-text').value.length == 0) { + if ($('status-text').value.length === 0) { $('status-text').value = 'Paste sync status dump here then click import.'; return; @@ -197,7 +197,7 @@ } let trafficEventDiv = e.target; // Click might be on div's child. - if (trafficEventDiv.nodeName != 'DIV') { + if (trafficEventDiv.nodeName !== 'DIV') { trafficEventDiv = trafficEventDiv.parentNode; } trafficEventDiv.classList.toggle('traffic-event-entry-expanded');
diff --git a/components/sync/driver/resources/data.js b/components/sync/driver/resources/data.js index 595d5126..d2b65014 100644 --- a/components/sync/driver/resources/data.js +++ b/components/sync/driver/resources/data.js
@@ -64,23 +64,23 @@ function serializeNode(node) { return allFields.map(function(field) { let fieldVal; - if (field == 'SERVER_VERSION_TIME') { + if (field === 'SERVER_VERSION_TIME') { const version = node['SERVER_VERSION']; if (version != null) { fieldVal = versionToDateString(version); } } - if (field == 'BASE_VERSION_TIME') { + if (field === 'BASE_VERSION_TIME') { const version = node['BASE_VERSION']; if (version != null) { fieldVal = versionToDateString(version); } } else if ( - (field == 'SERVER_SPECIFICS' || field == 'SPECIFICS') && + (field === 'SERVER_SPECIFICS' || field === 'SPECIFICS') && (!$('include-specifics').checked)) { fieldVal = 'REDACTED'; } else if ( - (field == 'SERVER_SPECIFICS' || field == 'SPECIFICS') && + (field === 'SERVER_SPECIFICS' || field === 'SPECIFICS') && $('include-specifics').checked) { fieldVal = JSON.stringify(node[field]); } else {
diff --git a/components/sync/driver/resources/events.js b/components/sync/driver/resources/events.js index 98d1d87..3471e85 100644 --- a/components/sync/driver/resources/events.js +++ b/components/sync/driver/resources/events.js
@@ -7,7 +7,7 @@ function toggleDisplay(event) { const originatingButton = event.target; - if (originatingButton.className != 'toggle-button') { + if (originatingButton.className !== 'toggle-button') { return; } const detailsNode =
diff --git a/components/sync/driver/resources/sync_node_browser.js b/components/sync/driver/resources/sync_node_browser.js index 14d0097..f551f7d 100644 --- a/components/sync/driver/resources/sync_node_browser.js +++ b/components/sync/driver/resources/sync_node_browser.js
@@ -13,7 +13,7 @@ * @param {!Object} node The node to check. */ function isTypeRootNode(node) { - return node.PARENT_ID == 'r' && node.UNIQUE_SERVER_TAG != ''; + return node.PARENT_ID === 'r' && node.UNIQUE_SERVER_TAG !== ''; } /** @@ -23,10 +23,10 @@ * @param {!Object} node The node to check. */ function isChildOf(parentNode, node) { - if (node.PARENT_ID != '') { - return node.PARENT_ID == parentNode.ID; + if (node.PARENT_ID !== '') { + return node.PARENT_ID === parentNode.ID; } else { - return node.modelType == parentNode.modelType; + return node.modelType === parentNode.modelType; } } @@ -43,7 +43,7 @@ if (nodeA.hasOwnProperty('positionIndex') && nodeB.hasOwnProperty('positionIndex')) { return nodeA.positionIndex - nodeB.positionIndex; - } else if (nodeA.NON_UNIQUE_NAME != nodeB.NON_UNIQUE_NAME) { + } else if (nodeA.NON_UNIQUE_NAME !== nodeB.NON_UNIQUE_NAME) { return nodeA.NON_UNIQUE_NAME.localeCompare(nodeB.NON_UNIQUE_NAME); } else { return nodeA.METAHANDLE - nodeB.METAHANDLE;
diff --git a/components/sync/driver/resources/sync_search.js b/components/sync/driver/resources/sync_search.js index 226e49c..2ea9aa5 100644 --- a/components/sync/driver/resources/sync_search.js +++ b/components/sync/driver/resources/sync_search.js
@@ -58,7 +58,7 @@ return a.concat(b); }); - if (currSearchId != searchId) { + if (currSearchId !== searchId) { return; } callback(nodes.filter(function(elem) {
diff --git a/components/sync/driver/resources/traffic_log.js b/components/sync/driver/resources/traffic_log.js index 4a9818f3..dd6972a 100644 --- a/components/sync/driver/resources/traffic_log.js +++ b/components/sync/driver/resources/traffic_log.js
@@ -67,7 +67,7 @@ } let trafficEventDiv = e.target; // Click might be on div's child. - if (trafficEventDiv.nodeName != 'DIV') { + if (trafficEventDiv.nodeName !== 'DIV') { trafficEventDiv = trafficEventDiv.parentNode; } trafficEventDiv.classList.toggle(
diff --git a/components/sync_bookmarks/bookmark_local_changes_builder.cc b/components/sync_bookmarks/bookmark_local_changes_builder.cc index e5ffb17d..a6727a7 100644 --- a/components/sync_bookmarks/bookmark_local_changes_builder.cc +++ b/components/sync_bookmarks/bookmark_local_changes_builder.cc
@@ -64,7 +64,8 @@ // Assign specifics only for the non-deletion case. In case of deletion, // EntityData should contain empty specifics to indicate deletion. data->specifics = CreateSpecificsFromBookmarkNode( - node, bookmark_model_, /*force_favicon_load=*/true); + node, bookmark_model_, /*force_favicon_load=*/true, + entity->has_final_guid()); data->name = data->specifics.bookmark().title(); } auto request = std::make_unique<syncer::CommitRequestData>();
diff --git a/components/sync_bookmarks/bookmark_model_merger.cc b/components/sync_bookmarks/bookmark_model_merger.cc index 4979bb57c..7df7d3d2 100644 --- a/components/sync_bookmarks/bookmark_model_merger.cc +++ b/components/sync_bookmarks/bookmark_model_merger.cc
@@ -614,8 +614,10 @@ predecessor_entity->metadata()->unique_position()), suffix); } + const sync_pb::EntitySpecifics specifics = CreateSpecificsFromBookmarkNode( - node, bookmark_model_, /*force_favicon_load=*/true); + node, bookmark_model_, /*force_favicon_load=*/true, + /*include_guid=*/true); bookmark_tracker_->Add(sync_id, node, server_version, creation_time, pos.ToProto(), specifics); // Mark the entity that it needs to be committed.
diff --git a/components/sync_bookmarks/bookmark_model_observer_impl.cc b/components/sync_bookmarks/bookmark_model_observer_impl.cc index aa6e3a4..bee1c498 100644 --- a/components/sync_bookmarks/bookmark_model_observer_impl.cc +++ b/components/sync_bookmarks/bookmark_model_observer_impl.cc
@@ -66,8 +66,8 @@ const sync_pb::UniquePosition unique_position = ComputePosition(*new_parent, new_index, sync_id).ToProto(); - sync_pb::EntitySpecifics specifics = - CreateSpecificsFromBookmarkNode(node, model, /*force_favicon_load=*/true); + sync_pb::EntitySpecifics specifics = CreateSpecificsFromBookmarkNode( + node, model, /*force_favicon_load=*/true, entity->has_final_guid()); bookmark_tracker_->Update(sync_id, entity->metadata()->server_version(), modification_time, unique_position, specifics); @@ -106,8 +106,8 @@ ComputePosition(*parent, index, sync_id).ToProto(); sync_pb::EntitySpecifics specifics = - CreateSpecificsFromBookmarkNode(node, model, /*force_favicon_load=*/true); - + CreateSpecificsFromBookmarkNode(node, model, /*force_favicon_load=*/true, + /*include_guid=*/true); bookmark_tracker_->Add(sync_id, node, server_version, creation_time, unique_position, specifics); // Mark the entity that it needs to be committed. @@ -184,9 +184,11 @@ // start tracking the node. return; } + const base::Time modification_time = base::Time::Now(); - sync_pb::EntitySpecifics specifics = - CreateSpecificsFromBookmarkNode(node, model, /*force_favicon_load=*/true); + sync_pb::EntitySpecifics specifics = CreateSpecificsFromBookmarkNode( + node, model, /*force_favicon_load=*/true, entity->has_final_guid()); + // TODO(crbug.com/516866): The below CHECKs are added to debug some crashes. // Should be removed after figuring out the reason for the crash. CHECK_EQ(entity, bookmark_tracker_->GetEntityForBookmarkNode(node)); @@ -266,7 +268,8 @@ : syncer::UniquePosition::After(position, suffix); const sync_pb::EntitySpecifics specifics = CreateSpecificsFromBookmarkNode( - child.get(), model, /*force_favicon_load=*/true); + child.get(), model, /*force_favicon_load=*/true, + entity->has_final_guid()); bookmark_tracker_->Update(sync_id, entity->metadata()->server_version(), modification_time, position.ToProto(), specifics);
diff --git a/components/sync_bookmarks/bookmark_model_type_processor.cc b/components/sync_bookmarks/bookmark_model_type_processor.cc index 676106b..34ae62b 100644 --- a/components/sync_bookmarks/bookmark_model_type_processor.cc +++ b/components/sync_bookmarks/bookmark_model_type_processor.cc
@@ -17,6 +17,7 @@ #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/browser/bookmark_node.h" #include "components/bookmarks/browser/bookmark_utils.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/base/data_type_histogram.h" #include "components/sync/base/model_type.h" #include "components/sync/base/time.h" @@ -593,8 +594,10 @@ data.name = base::UTF16ToUTF8(node->GetTitle()); data.is_folder = node->is_folder(); data.unique_position = metadata->unique_position(); - data.specifics = CreateSpecificsFromBookmarkNode( - node, bookmark_model_, /*force_favicon_load=*/false); + data.specifics = CreateSpecificsFromBookmarkNode(node, bookmark_model_, + /*force_favicon_load=*/false, + entity->has_final_guid()); + if (node->is_permanent_node()) { data.server_defined_unique_tag = ComputeServerDefinedUniqueTagForDebugging(node, bookmark_model_);
diff --git a/components/sync_bookmarks/bookmark_remote_updates_handler.cc b/components/sync_bookmarks/bookmark_remote_updates_handler.cc index 0d38def1..f70e67f1 100644 --- a/components/sync_bookmarks/bookmark_remote_updates_handler.cc +++ b/components/sync_bookmarks/bookmark_remote_updates_handler.cc
@@ -131,16 +131,16 @@ return; } - // If there is a different GUID in the specifics and it is valid, we must - // replace the entire node in order to use it, as GUIDs are immutable. Further - // updates are then applied to the new node instead. - if (update_entity.specifics.bookmark().guid() != node->guid() && - base::IsValidGUID(update_entity.specifics.bookmark().guid())) { - const bookmarks::BookmarkNode* old_node = node; - node = ReplaceBookmarkNodeGUID( - node, update_entity.specifics.bookmark().guid(), model); - tracker->UpdateBookmarkNodePointer(old_node, node); + // The GUID is immutable and cannot change. This check is somewhat redundant + // here because there is a similar one also accounted to kUnexpectedGuid, but + // in theory a misbehaving server could trigger this codepath. + // TODO(crbug.com/1032052): If the tracker becomes client-tag-centric, this + // shouldn't be necessary. + if (update_entity.specifics.bookmark().guid() != node->guid()) { + LogProblematicBookmark(RemoteBookmarkUpdateError::kUnexpectedGuid); + return; } + UpdateBookmarkNodeFromSpecifics(update_entity.specifics.bookmark(), node, model, favicon_service); // Compute index information before updating the |tracker|. @@ -222,6 +222,19 @@ const SyncedBookmarkTracker::Entity* tracked_entity = bookmark_tracker_->GetEntityForSyncId(update_entity.id); + + // This may be a good chance to populate the client tag for the first time. + // TODO(crbug.com/1032052): Remove this code once all local sync metadata + // is required to populate the client tag (and be considered invalid + // otherwise). + if (tracked_entity && !tracked_entity->has_final_guid() && + !update_entity.is_deleted() && + update_entity.server_defined_unique_tag.empty()) { + DCHECK(base::IsValidGUID(update_entity.specifics.bookmark().guid())); + bookmark_tracker_->PopulateFinalGuid( + update_entity.id, update_entity.specifics.bookmark().guid()); + } + if (tracked_entity && tracked_entity->metadata()->server_version() >= update->response_version) { // Seen this update before; just ignore it. @@ -237,9 +250,7 @@ // |original_client_item_id|. If we have a entry by that description, we // should update the |sync_id| in |bookmark_tracker_|. The rest of code will // handle this a conflict and adjust the model if needed. - if (update_entity.originator_cache_guid == - bookmark_tracker_->model_type_state().cache_guid() && - bookmark_tracker_->GetEntityForSyncId( + if (bookmark_tracker_->GetEntityForSyncId( update_entity.originator_client_item_id) != nullptr) { if (tracked_entity) { // We generally shouldn't have an entry for both the old ID and the new
diff --git a/components/sync_bookmarks/bookmark_remote_updates_handler_unittest.cc b/components/sync_bookmarks/bookmark_remote_updates_handler_unittest.cc index b765aa4..75005bf 100644 --- a/components/sync_bookmarks/bookmark_remote_updates_handler_unittest.cc +++ b/components/sync_bookmarks/bookmark_remote_updates_handler_unittest.cc
@@ -436,7 +436,7 @@ } TEST_F(BookmarkRemoteUpdatesHandlerWithInitialMergeTest, - ShouldUpdateGUIDValueUponRemoteUpdate) { + ShouldLogGuidMismatchUponInvalidRemoteUpdate) { const std::string kId = "id"; const std::string kTitle = "title"; const std::string kOldGuid = base::GenerateGUID(); @@ -474,14 +474,20 @@ syncer::UniquePosition::InitialPosition( syncer::UniquePosition::RandomSuffix()))); + base::HistogramTester histogram_tester; updates_handler()->Process(updates, /*got_new_encryption_requirements=*/false); - // The GUID should have been updated. + // The GUID should not have been updated. const bookmarks::BookmarkNode* bookmark_bar_node = bookmark_model()->bookmark_bar_node(); ASSERT_THAT(bookmark_bar_node->children().size(), Eq(1u)); - EXPECT_THAT(bookmark_bar_node->children().front()->guid(), Eq(kNewGuid)); + EXPECT_THAT(bookmark_bar_node->children().front()->guid(), Eq(kOldGuid)); + + histogram_tester.ExpectBucketCount( + "Sync.ProblematicServerSideBookmarks", + /*sample=*/ExpectedRemoteBookmarkUpdateError::kUnexpectedGuid, + /*count=*/1); } TEST_F(BookmarkRemoteUpdatesHandlerWithInitialMergeTest, @@ -592,6 +598,7 @@ // |- node4 std::vector<std::string> ids; + std::vector<std::string> guids; std::vector<syncer::UniquePosition> positions; syncer::UniquePosition position = syncer::UniquePosition::InitialPosition( @@ -599,11 +606,13 @@ syncer::UpdateResponseDataList updates; for (int i = 0; i < 5; i++) { ids.push_back("node" + base::NumberToString(i)); + guids.push_back(base::GenerateGUID()); position = syncer::UniquePosition::After( position, syncer::UniquePosition::RandomSuffix()); positions.push_back(position); updates.push_back(CreateUpdateResponseData( - /*server_id=*/ids[i], /*parent_id=*/kBookmarkBarId, /*title=*/ids[i], + /*server_id=*/ids[i], /*parent_id=*/kBookmarkBarId, /*guid=*/guids[i], + /*title=*/ids[i], /*is_deletion=*/false, /*version=*/0, /*unique_position=*/positions[i])); } @@ -626,6 +635,7 @@ updates.push_back(CreateUpdateResponseData( /*server_id=*/ids[3], /*parent_id=*/kBookmarkBarId, + /*guid=*/guids[3], /*title=*/ids[3], /*is_deletion=*/false, /*version=*/1, @@ -652,6 +662,7 @@ // |- node4 std::vector<std::string> ids; + std::vector<std::string> guids; std::vector<syncer::UniquePosition> positions; syncer::UniquePosition position = syncer::UniquePosition::InitialPosition( @@ -659,11 +670,13 @@ syncer::UpdateResponseDataList updates; for (int i = 0; i < 5; i++) { ids.push_back("node" + base::NumberToString(i)); + guids.push_back(base::GenerateGUID()); position = syncer::UniquePosition::After( position, syncer::UniquePosition::RandomSuffix()); positions.push_back(position); updates.push_back(CreateUpdateResponseData( - /*server_id=*/ids[i], /*parent_id=*/kBookmarkBarId, /*title=*/ids[i], + /*server_id=*/ids[i], /*parent_id=*/kBookmarkBarId, /*guid=*/guids[i], + /*title=*/ids[i], /*is_deletion=*/false, /*version=*/0, /*unique_position=*/positions[i])); } @@ -686,6 +699,7 @@ updates.push_back(CreateUpdateResponseData( /*server_id=*/ids[1], /*parent_id=*/kBookmarkBarId, + /*guid=*/guids[1], /*title=*/ids[1], /*is_deletion=*/false, /*version=*/1, @@ -712,6 +726,7 @@ // |- node4 std::vector<std::string> ids; + std::vector<std::string> guids; std::vector<syncer::UniquePosition> positions; syncer::UniquePosition position = syncer::UniquePosition::InitialPosition( @@ -719,11 +734,13 @@ syncer::UpdateResponseDataList updates; for (int i = 0; i < 5; i++) { ids.push_back("node" + base::NumberToString(i)); + guids.push_back(base::GenerateGUID()); position = syncer::UniquePosition::After( position, syncer::UniquePosition::RandomSuffix()); positions.push_back(position); updates.push_back(CreateUpdateResponseData( - /*server_id=*/ids[i], /*parent_id=*/kBookmarkBarId, /*title=*/ids[i], + /*server_id=*/ids[i], /*parent_id=*/kBookmarkBarId, /*guid=*/guids[i], + /*title=*/ids[i], /*is_deletion=*/false, /*version=*/0, /*unique_position=*/positions[i])); } @@ -746,6 +763,7 @@ updates.push_back(CreateUpdateResponseData( /*server_id=*/ids[4], /*parent_id=*/ids[1], + /*guid=*/guids[4], /*title=*/ids[4], /*is_deletion=*/false, /*version=*/1, @@ -1300,6 +1318,7 @@ TEST_F(BookmarkRemoteUpdatesHandlerWithInitialMergeTest, ShouldResolveConflictBetweenLocalAndRemoteUpdatesWithRemote) { const std::string kId = "id"; + const std::string kGuid = base::GenerateGUID(); const std::string kTitle = "title"; const std::string kNewRemoteTitle = "remote title"; @@ -1308,6 +1327,7 @@ updates.push_back(CreateUpdateResponseData( /*server_id=*/kId, /*parent_id=*/kBookmarkBarId, + /*guid=*/kGuid, /*title=*/kTitle, /*is_deletion=*/false, /*version=*/0, @@ -1330,6 +1350,7 @@ updates.push_back(CreateUpdateResponseData( /*server_id=*/kId, /*parent_id=*/kBookmarkBarId, + /*guid=*/kGuid, /*title=*/kNewRemoteTitle, /*is_deletion=*/false, /*version=*/1,
diff --git a/components/sync_bookmarks/bookmark_specifics_conversions.cc b/components/sync_bookmarks/bookmark_specifics_conversions.cc index 8ca57fb2..8ceba43 100644 --- a/components/sync_bookmarks/bookmark_specifics_conversions.cc +++ b/components/sync_bookmarks/bookmark_specifics_conversions.cc
@@ -184,7 +184,8 @@ sync_pb::EntitySpecifics CreateSpecificsFromBookmarkNode( const bookmarks::BookmarkNode* node, bookmarks::BookmarkModel* model, - bool force_favicon_load) { + bool force_favicon_load, + bool include_guid) { sync_pb::EntitySpecifics specifics; sync_pb::BookmarkSpecifics* bm_specifics = specifics.mutable_bookmark(); if (!node->is_folder()) { @@ -194,8 +195,9 @@ DCHECK(!node->guid().empty()); DCHECK(base::IsValidGUID(node->guid())) << "Actual: " << node->guid(); - // TODO(crbug.com/978430): populate the GUID, as long as it's known to be - // consistent with the originator client item ID. + if (include_guid) { + bm_specifics->set_guid(node->guid()); + } bm_specifics->set_title(SpecificsTitleFromNodeTitle(node->GetTitle())); bm_specifics->set_creation_time_us(
diff --git a/components/sync_bookmarks/bookmark_specifics_conversions.h b/components/sync_bookmarks/bookmark_specifics_conversions.h index 71e46a7..377d2fc 100644 --- a/components/sync_bookmarks/bookmark_specifics_conversions.h +++ b/components/sync_bookmarks/bookmark_specifics_conversions.h
@@ -24,10 +24,14 @@ namespace sync_bookmarks { +// TODO(crbug.com/978430): Remove argument |include_guid| once the client tag +// hash is required to be populated during sync metadata validation upon +// startup in SyncedBookmarkTracker::BookmarkModelMatchesMetadata(). sync_pb::EntitySpecifics CreateSpecificsFromBookmarkNode( const bookmarks::BookmarkNode* node, bookmarks::BookmarkModel* model, - bool force_favicon_load); + bool force_favicon_load, + bool include_guid); // Creates a bookmark node under the given parent node from the given specifics. // Returns the newly created node. Callers must verify that
diff --git a/components/sync_bookmarks/bookmark_specifics_conversions_unittest.cc b/components/sync_bookmarks/bookmark_specifics_conversions_unittest.cc index 7300db69..cc5a34e 100644 --- a/components/sync_bookmarks/bookmark_specifics_conversions_unittest.cc +++ b/components/sync_bookmarks/bookmark_specifics_conversions_unittest.cc
@@ -76,10 +76,9 @@ model->SetNodeMetaInfo(node, kKey2, kValue2); sync_pb::EntitySpecifics specifics = CreateSpecificsFromBookmarkNode( - node, model.get(), /*force_favicon_load=*/false); + node, model.get(), /*force_favicon_load=*/false, /*include_guid=*/true); const sync_pb::BookmarkSpecifics& bm_specifics = specifics.bookmark(); - // TODO(crbug.com/978430): Update expectation once the GUID is populated. - EXPECT_FALSE(bm_specifics.has_guid()); + EXPECT_THAT(bm_specifics.guid(), Eq(node->guid())); EXPECT_THAT(bm_specifics.title(), Eq(kTitle)); EXPECT_THAT(GURL(bm_specifics.url()), Eq(kUrl)); EXPECT_THAT( @@ -94,6 +93,28 @@ } TEST(BookmarkSpecificsConversionsTest, + ShouldCreateSpecificsFromBookmarkNodeWithoutGuid) { + const GURL kUrl("http://www.url.com"); + const std::string kTitle = "Title"; + + std::unique_ptr<bookmarks::BookmarkModel> model = + bookmarks::TestBookmarkClient::CreateModel(); + + const bookmarks::BookmarkNode* bookmark_bar_node = model->bookmark_bar_node(); + const bookmarks::BookmarkNode* node = model->AddURL( + /*parent=*/bookmark_bar_node, /*index=*/0, base::UTF8ToUTF16(kTitle), + kUrl); + ASSERT_THAT(node, NotNull()); + + sync_pb::EntitySpecifics specifics = CreateSpecificsFromBookmarkNode( + node, model.get(), /*force_favicon_load=*/false, /*include_guid=*/false); + const sync_pb::BookmarkSpecifics& bm_specifics = specifics.bookmark(); + ASSERT_THAT(bm_specifics.title(), Eq(kTitle)); + ASSERT_THAT(GURL(bm_specifics.url()), Eq(kUrl)); + EXPECT_FALSE(bm_specifics.has_guid()); +} + +TEST(BookmarkSpecificsConversionsTest, ShouldCreateSpecificsFromBookmarkNodeWithIllegalTitle) { std::unique_ptr<bookmarks::BookmarkModel> model = bookmarks::TestBookmarkClient::CreateModel(); @@ -107,7 +128,7 @@ GURL("http://www.url.com")); ASSERT_THAT(node, NotNull()); sync_pb::EntitySpecifics specifics = CreateSpecificsFromBookmarkNode( - node, model.get(), /*force_favicon_load=*/false); + node, model.get(), /*force_favicon_load=*/false, /*include_guid=*/true); // Legacy clients append a space to illegal titles. EXPECT_THAT(specifics.bookmark().title(), Eq(illegal_title + " ")); } @@ -123,7 +144,7 @@ ASSERT_THAT(node, NotNull()); sync_pb::EntitySpecifics specifics = CreateSpecificsFromBookmarkNode( - node, model.get(), /*force_favicon_load=*/false); + node, model.get(), /*force_favicon_load=*/false, /*include_guid=*/true); const sync_pb::BookmarkSpecifics& bm_specifics = specifics.bookmark(); EXPECT_FALSE(bm_specifics.has_url()); } @@ -145,7 +166,7 @@ ASSERT_FALSE(node->is_favicon_loaded()); ASSERT_THAT(client_ptr->GetLoadFaviconRequestsForTest(), Eq(0)); sync_pb::EntitySpecifics specifics = CreateSpecificsFromBookmarkNode( - node, model.get(), /*force_favicon_load=*/true); + node, model.get(), /*force_favicon_load=*/true, /*include_guid=*/true); EXPECT_THAT(client_ptr->GetLoadFaviconRequestsForTest(), Eq(1)); } @@ -166,7 +187,7 @@ ASSERT_FALSE(node->is_favicon_loaded()); ASSERT_THAT(client_ptr->GetLoadFaviconRequestsForTest(), Eq(0)); sync_pb::EntitySpecifics specifics = CreateSpecificsFromBookmarkNode( - node, model.get(), /*force_favicon_load=*/false); + node, model.get(), /*force_favicon_load=*/false, /*include_guid=*/true); EXPECT_THAT(client_ptr->GetLoadFaviconRequestsForTest(), Eq(0)); }
diff --git a/components/sync_bookmarks/synced_bookmark_tracker.cc b/components/sync_bookmarks/synced_bookmark_tracker.cc index 6e855a0b..215e3a65 100644 --- a/components/sync_bookmarks/synced_bookmark_tracker.cc +++ b/components/sync_bookmarks/synced_bookmark_tracker.cc
@@ -15,6 +15,7 @@ #include "base/trace_event/memory_usage_estimator.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/browser/bookmark_node.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/base/time.h" #include "components/sync/base/unique_position.h" #include "components/sync/model/entity_data.h" @@ -43,11 +44,7 @@ void HashSpecifics(const sync_pb::EntitySpecifics& specifics, std::string* hash) { DCHECK_GT(specifics.ByteSize(), 0); - // TODO(crbug.com/978430): Include GUID in hash when committing is supported. - sync_pb::EntitySpecifics specifics_without_guid = specifics; - specifics_without_guid.mutable_bookmark()->clear_guid(); - base::Base64Encode( - base::SHA1HashString(specifics_without_guid.SerializeAsString()), hash); + base::Base64Encode(base::SHA1HashString(specifics.SerializeAsString()), hash); } } // namespace @@ -94,6 +91,16 @@ return hash == metadata_->specifics_hash(); } +bool SyncedBookmarkTracker::Entity::has_final_guid() const { + return metadata_->has_client_tag_hash(); +} + +void SyncedBookmarkTracker::Entity::set_final_guid(const std::string& guid) { + DCHECK(!has_final_guid()); + metadata_->set_client_tag_hash( + syncer::ClientTagHash::FromUnhashed(syncer::BOOKMARKS, guid).value()); +} + size_t SyncedBookmarkTracker::Entity::EstimateMemoryUsage() const { using base::trace_event::EstimateMemoryUsage; size_t memory_usage = 0; @@ -169,6 +176,14 @@ // The entry is valid. If it's not a tombstone, collect its node id to // compare it later with the ids in the bookmark model. if (!bookmark_metadata.metadata().is_deleted()) { + // TODO(crbug.com/1032052): If the client-tag is known, verify that it + // matches the bookmark's GUID. + + // TODO(crbug.com/1032052): Eventually empty client-tag-hashes should be + // disallowed and treated as invalid sync metadata. This requires a grace + // period for most clients to receive at least one update per bookmark. + // When that's achieved, has_final_guid() and set_final_guid() could be + // removed. metadata_node_ids.push_back(bookmark_metadata.id()); } } @@ -242,6 +257,11 @@ metadata->set_sequence_number(0); metadata->set_acked_sequence_number(0); metadata->mutable_unique_position()->CopyFrom(unique_position); + // For any newly added bookmark, be it a local creation or a remote one, the + // authoritative final GUID is known from start. + metadata->set_client_tag_hash(syncer::ClientTagHash::FromUnhashed( + syncer::BOOKMARKS, bookmark_node->guid()) + .value()); HashSpecifics(specifics, metadata->mutable_specifics_hash()); auto entity = std::make_unique<Entity>(bookmark_node, std::move(metadata)); bookmark_node_to_entities_map_[bookmark_node] = entity.get(); @@ -261,6 +281,7 @@ Entity* entity = GetMutableEntityForSyncId(sync_id); DCHECK(entity); DCHECK_EQ(entity->metadata()->server_id(), sync_id); + entity->metadata()->set_server_version(server_version); entity->metadata()->set_modification_time( syncer::TimeToProtoTime(modification_time)); @@ -277,6 +298,14 @@ entity->metadata()->set_server_version(server_version); } +void SyncedBookmarkTracker::PopulateFinalGuid(const std::string& sync_id, + const std::string& guid) { + Entity* entity = GetMutableEntityForSyncId(sync_id); + DCHECK(entity); + DCHECK(!entity->has_final_guid()); + entity->set_final_guid(guid); +} + void SyncedBookmarkTracker::MarkCommitMayHaveStarted( const std::string& sync_id) { Entity* entity = GetMutableEntityForSyncId(sync_id); @@ -510,18 +539,6 @@ sync_id_to_entities_map_.erase(old_id); } -void SyncedBookmarkTracker::UpdateBookmarkNodePointer( - const bookmarks::BookmarkNode* old_node, - const bookmarks::BookmarkNode* new_node) { - if (old_node == new_node) { - return; - } - bookmark_node_to_entities_map_[new_node] = - bookmark_node_to_entities_map_[old_node]; - bookmark_node_to_entities_map_[new_node]->set_bookmark_node(new_node); - bookmark_node_to_entities_map_.erase(old_node); -} - void SyncedBookmarkTracker::AckSequenceNumber(const std::string& sync_id) { Entity* entity = GetMutableEntityForSyncId(sync_id); DCHECK(entity);
diff --git a/components/sync_bookmarks/synced_bookmark_tracker.h b/components/sync_bookmarks/synced_bookmark_tracker.h index 9be8db4..ee9e8b4 100644 --- a/components/sync_bookmarks/synced_bookmark_tracker.h +++ b/components/sync_bookmarks/synced_bookmark_tracker.h
@@ -87,6 +87,20 @@ commit_may_have_started_ = value; } + // Returns whether the bookmark's GUID is known to match the server-side + // originator client item ID (or for pre-2015 bookmarks, the equivalent + // inferred GUID). This function may return false negatives since the + // required local metadata got populated with M81. + // TODO(crbug.com/1032052): Remove this code once all local sync metadata + // is required to populate the client tag (and be considered invalid + // otherwise). + bool has_final_guid() const; + + // TODO(crbug.com/1032052): Remove this code once all local sync metadata + // is required to populate the client tag (and be considered invalid + // otherwise). + void set_final_guid(const std::string& guid); + // Returns the estimate of dynamically allocated memory in bytes. size_t EstimateMemoryUsage() const; @@ -149,6 +163,9 @@ // Updates the server version of an existing entry for the |sync_id|. void UpdateServerVersion(const std::string& sync_id, int64_t server_version); + // Populates a bookmark's final GUID. + void PopulateFinalGuid(const std::string& sync_id, const std::string& guid); + // Marks an existing entry for |sync_id| that a commit request might have been // sent to the server. void MarkCommitMayHaveStarted(const std::string& sync_id); @@ -200,11 +217,6 @@ void UpdateSyncForLocalCreationIfNeeded(const std::string& old_id, const std::string& new_id); - // Informs the tracker that a BookmarkNode has been replaced. It updates - // the internal state of the tracker accordingly. - void UpdateBookmarkNodePointer(const bookmarks::BookmarkNode* old_node, - const bookmarks::BookmarkNode* new_node); - // Set the value of |EntityMetadata.acked_sequence_number| in the entity with // |sync_id| to be equal to |EntityMetadata.sequence_number| such that it is // not returned in GetEntitiesWithLocalChanges().
diff --git a/components/translate/core/browser/resources/translate.js b/components/translate/core/browser/resources/translate.js index 5dd9c5a..877d090 100644 --- a/components/translate/core/browser/resources/translate.js +++ b/components/translate/core/browser/resources/translate.js
@@ -146,13 +146,13 @@ function onTranslateProgress(progress, opt_finished, opt_error) { finished = opt_finished; // opt_error can be 'undefined'. - if (typeof opt_error == 'boolean' && opt_error) { + if (typeof opt_error === 'boolean' && opt_error) { // TODO(toyoshim): Remove boolean case once a server is updated. errorCode = ERROR['TRANSLATION_ERROR']; // We failed to translate, restore so the page is in a consistent state. lib.restore(); invokeResultCallback(); - } else if (typeof opt_error == 'number' && opt_error != 0) { + } else if (typeof opt_error === 'number' && opt_error !== 0) { errorCode = TRANSLATE_ERROR_TO_ERROR_CODE_MAP[opt_error]; lib.restore(); invokeResultCallback(); @@ -241,7 +241,7 @@ * @type {boolean} */ get error() { - return errorCode != ERROR['NONE']; + return errorCode !== ERROR['NONE']; }, /** @@ -261,7 +261,7 @@ * @type {boolean} */ get sourceLang() { - if (!libReady || !finished || errorCode != ERROR['NONE']) { + if (!libReady || !finished || errorCode !== ERROR['NONE']) { return ''; } if (!lib.getDetectedLanguage) { @@ -276,7 +276,7 @@ * @type {number} */ get loadTime() { - if (loadedTime == 0) { + if (loadedTime === 0) { return 0; } return loadedTime - injectedTime; @@ -414,10 +414,10 @@ const xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.onreadystatechange = function() { - if (this.readyState != this.DONE) { + if (this.readyState !== this.DONE) { return; } - if (this.status != 200) { + if (this.status !== 200) { errorCode = ERROR['SCRIPT_LOAD_ERROR']; return; }
diff --git a/components/translate/ios/browser/resources/language_detection.js b/components/translate/ios/browser/resources/language_detection.js index 54c2585..743f87d 100644 --- a/components/translate/ios/browser/resources/language_detection.js +++ b/components/translate/ios/browser/resources/language_detection.js
@@ -167,7 +167,7 @@ __gCrWeb.languageDetection['retrieveBufferedTextContent'] = function() { const textContent = __gCrWeb.languageDetection.bufferedTextContent; __gCrWeb.languageDetection.activeRequests -= 1; - if (__gCrWeb.languageDetection.activeRequests == 0) { + if (__gCrWeb.languageDetection.activeRequests === 0) { __gCrWeb.languageDetection.bufferedTextContent = null; } return textContent;
diff --git a/components/translate/ios/browser/resources/translate_ios.js b/components/translate/ios/browser/resources/translate_ios.js index 06deddf..12abf816 100644 --- a/components/translate/ios/browser/resources/translate_ios.js +++ b/components/translate/ios/browser/resources/translate_ios.js
@@ -66,7 +66,7 @@ * Redefine XMLHttpRequest's open to capture request configurations. * Only redefines once because this script may be injected multiple times. */ -if (typeof(XMLHttpRequest.prototype.realOpen) == 'undefined') { +if (typeof XMLHttpRequest.prototype.realOpen === 'undefined') { XMLHttpRequest.prototype.realOpen = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function(method, url, async, user, password) { this.savedMethod = method; @@ -89,7 +89,7 @@ * predefined translate security origin. * Only redefines once because this script may be injected multiple times. */ -if (typeof(XMLHttpRequest.prototype.realSend) == 'undefined') { +if (typeof XMLHttpRequest.prototype.realSend === 'undefined') { XMLHttpRequest.prototype.realSend = XMLHttpRequest.prototype.send; XMLHttpRequest.prototype.send = function(body) { // If this is a translate request, save this xhr and proxy the request to
diff --git a/components/translate/translate_internals/translate_internals.js b/components/translate/translate_internals/translate_internals.js index 88854e88..ef3fc85 100644 --- a/components/translate/translate_internals/translate_internals.js +++ b/components/translate/translate_internals/translate_internals.js
@@ -43,7 +43,7 @@ hash = hash.substring(1); const id = 'tabpanel-' + hash; - if (tabpanelIds.indexOf(id) == -1) { + if (tabpanelIds.indexOf(id) === -1) { return; }
diff --git a/components/ukm/debug/ukm_internals.js b/components/ukm/debug/ukm_internals.js index 92aebee..151b6c3 100644 --- a/components/ukm/debug/ukm_internals.js +++ b/components/ukm/debug/ukm_internals.js
@@ -71,7 +71,7 @@ * value is smaller than 32bit. */ function as64Bit(num) { - if (num.length != 2) { + if (num.length !== 2) { return '0'; } if (!num[0]) { @@ -249,7 +249,7 @@ const toggleExpand = $('toggle_expand'); toggleExpand.textContent = 'Expand'; toggleExpand.addEventListener('click', () => { - if (toggleExpand.textContent == 'Expand') { + if (toggleExpand.textContent === 'Expand') { toggleExpand.textContent = 'Collapse'; setDisplayStyle(document.getElementsByClassName('entries'), 'block'); } else {
diff --git a/components/ukm/test_ukm_recorder.cc b/components/ukm/test_ukm_recorder.cc index 9286bdc0..279c905 100644 --- a/components/ukm/test_ukm_recorder.cc +++ b/components/ukm/test_ukm_recorder.cc
@@ -164,4 +164,48 @@ DelegatingUkmRecorder::Get()->RemoveDelegate(this); } +std::vector<TestUkmRecorder::HumanReadableUkmMetrics> +TestUkmRecorder::GetMetrics(std::string entry_name, + const std::vector<std::string>& metric_names) { + std::vector<TestUkmRecorder::HumanReadableUkmMetrics> result; + for (const auto& entry : GetEntries(entry_name, metric_names)) { + result.push_back(entry.metrics); + } + return result; +} + +std::vector<TestUkmRecorder::HumanReadableUkmEntry> TestUkmRecorder::GetEntries( + std::string entry_name, + const std::vector<std::string>& metric_names) { + std::vector<TestUkmRecorder::HumanReadableUkmEntry> results; + for (const ukm::mojom::UkmEntry* entry : GetEntriesByName(entry_name)) { + HumanReadableUkmEntry result; + result.source_id = entry->source_id; + for (const std::string& metric_name : metric_names) { + const int64_t* metric_value = + ukm::TestUkmRecorder::GetEntryMetric(entry, metric_name); + if (metric_value) + result.metrics[metric_name] = *metric_value; + } + results.push_back(std::move(result)); + } + return results; +} + +TestUkmRecorder::HumanReadableUkmEntry::HumanReadableUkmEntry() = default; + +TestUkmRecorder::HumanReadableUkmEntry::HumanReadableUkmEntry( + ukm::SourceId source_id, + TestUkmRecorder::HumanReadableUkmMetrics ukm_metrics) + : source_id(source_id), metrics(std::move(ukm_metrics)) {} + +TestUkmRecorder::HumanReadableUkmEntry::HumanReadableUkmEntry( + const HumanReadableUkmEntry&) = default; +TestUkmRecorder::HumanReadableUkmEntry::~HumanReadableUkmEntry() = default; + +bool TestUkmRecorder::HumanReadableUkmEntry::operator==( + const HumanReadableUkmEntry& other) const { + return source_id == other.source_id && metrics == other.metrics; +} + } // namespace ukm
diff --git a/components/ukm/test_ukm_recorder.h b/components/ukm/test_ukm_recorder.h index 1ddb5e3..b9008c1 100644 --- a/components/ukm/test_ukm_recorder.h +++ b/components/ukm/test_ukm_recorder.h
@@ -26,6 +26,21 @@ // Wraps an UkmRecorder with additional accessors used for testing. class TestUkmRecorder : public UkmRecorderImpl { public: + using HumanReadableUkmMetrics = std::map<std::string, int64_t>; + + struct HumanReadableUkmEntry { + HumanReadableUkmEntry(); + HumanReadableUkmEntry(ukm::SourceId source_id, + HumanReadableUkmMetrics ukm_metrics); + ~HumanReadableUkmEntry(); + HumanReadableUkmEntry(const HumanReadableUkmEntry&); + + bool operator==(const HumanReadableUkmEntry& other) const; + + ukm::SourceId source_id = kInvalidSourceId; + HumanReadableUkmMetrics metrics; + }; + TestUkmRecorder(); ~TestUkmRecorder() override; @@ -85,6 +100,18 @@ static const int64_t* GetEntryMetric(const mojom::UkmEntry* entry, base::StringPiece metric_name); + // A test helper returning all metrics for all entries with a given name in a + // human-readable form, allowing to write clearer test expectations. + std::vector<HumanReadableUkmMetrics> GetMetrics( + std::string entry_name, + const std::vector<std::string>& metric_names); + + // A test helper returning all entries for a given name in a human-readable + // form, allowing to write clearer test expectations. + std::vector<HumanReadableUkmEntry> GetEntries( + std::string entry_name, + const std::vector<std::string>& metric_names); + private: uint64_t entry_hash_to_wait_for_ = 0; base::OnceClosure on_add_entry_;
diff --git a/components/version_ui/resources/about_version.js b/components/version_ui/resources/about_version.js index d2f61cf..b7ed628 100644 --- a/components/version_ui/resources/about_version.js +++ b/components/version_ui/resources/about_version.js
@@ -89,7 +89,7 @@ $('arc_holder').hidden = true; chrome.chromeosInfoPrivate.get(['customizationId'], returnCustomizationId); } - if ($('sanitizer').textContent != '') { + if ($('sanitizer').textContent !== '') { $('sanitizer-section').hidden = false; } }
diff --git a/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm b/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm index 9f97200..4df726e 100644 --- a/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm +++ b/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm
@@ -141,9 +141,10 @@ ui::ImeTextSpan::Thickness thickness = [style intValue] > 1 ? ui::ImeTextSpan::Thickness::kThick : ui::ImeTextSpan::Thickness::kThin; - ui::ImeTextSpan ui_ime_text_span = - ui::ImeTextSpan(ui::ImeTextSpan::Type::kComposition, range.location, - NSMaxRange(range), thickness, SK_ColorTRANSPARENT); + ui::ImeTextSpan ui_ime_text_span = ui::ImeTextSpan( + ui::ImeTextSpan::Type::kComposition, range.location, + NSMaxRange(range), thickness, ui::ImeTextSpan::UnderlineStyle::kSolid, + SK_ColorTRANSPARENT); ui_ime_text_span.underline_color = color; ime_text_spans->push_back(ui_ime_text_span); } @@ -1958,7 +1959,8 @@ // Use a thin black underline by default. _ime_text_spans.push_back(ui::ImeTextSpan( ui::ImeTextSpan::Type::kComposition, 0, length, - ui::ImeTextSpan::Thickness::kThin, SK_ColorTRANSPARENT)); + ui::ImeTextSpan::Thickness::kThin, + ui::ImeTextSpan::UnderlineStyle::kSolid, SK_ColorTRANSPARENT)); } // If we are handling a key down event, then SetComposition() will be
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc index 17c6a95f..ed57bd6 100644 --- a/content/browser/accessibility/browser_accessibility_manager.cc +++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -462,10 +462,16 @@ // Some screen readers need a focus event in order to work properly. FireFocusEventsIfNeeded(); - // Also, perform the initial run of language detection. - // TODO(chrishall): we will want to run this more often for dynamic pages. - tree_->language_detection_manager->DetectLanguages(tree_->root()); - tree_->language_detection_manager->LabelLanguages(tree_->root()); + // Perform the initial run of language detection. + tree_->language_detection_manager->DetectLanguages(); + tree_->language_detection_manager->LabelLanguages(); + + // After initial language detection, enable language detection for future + // content updates in order to support dynamic content changes. + // + // If the LanguageDetectionDynamic feature flag is not enabled then this + // is a no-op. + tree_->language_detection_manager->RegisterLanguageDetectionObserver(); } // Allow derived classes to do event post-processing.
diff --git a/content/browser/android/ime_adapter_android.cc b/content/browser/android/ime_adapter_android.cc index 95ae1e6..7ee9cc5 100644 --- a/content/browser/android/ime_adapter_android.cc +++ b/content/browser/android/ime_adapter_android.cc
@@ -87,6 +87,7 @@ ime_text_spans->push_back(ui::ImeTextSpan( ui::ImeTextSpan::Type::kComposition, static_cast<unsigned>(start), static_cast<unsigned>(end), ui::ImeTextSpan::Thickness::kNone, + ui::ImeTextSpan::UnderlineStyle::kNone, static_cast<unsigned>(background_color), SK_ColorTRANSPARENT, std::vector<std::string>())); } @@ -116,7 +117,8 @@ AppendJavaStringArrayToStringVector(env, suggestions, &suggestions_vec); ui::ImeTextSpan ime_text_span = ui::ImeTextSpan( type, static_cast<unsigned>(start), static_cast<unsigned>(end), - ui::ImeTextSpan::Thickness::kThick, SK_ColorTRANSPARENT, + ui::ImeTextSpan::Thickness::kThick, + ui::ImeTextSpan::UnderlineStyle::kSolid, SK_ColorTRANSPARENT, static_cast<unsigned>(suggestion_highlight_color), suggestions_vec); ime_text_span.remove_on_finish_composing = remove_on_finish_composing; ime_text_span.underline_color = static_cast<unsigned>(underline_color); @@ -136,7 +138,8 @@ ime_text_spans->push_back(ui::ImeTextSpan( ui::ImeTextSpan::Type::kComposition, static_cast<unsigned>(start), static_cast<unsigned>(end), ui::ImeTextSpan::Thickness::kThin, - SK_ColorTRANSPARENT, SK_ColorTRANSPARENT, std::vector<std::string>())); + ui::ImeTextSpan::UnderlineStyle::kSolid, SK_ColorTRANSPARENT, + SK_ColorTRANSPARENT, std::vector<std::string>())); } ImeAdapterAndroid::ImeAdapterAndroid(JNIEnv* env, @@ -279,10 +282,11 @@ // Default to plain underline if we didn't find any span that we care about. if (ime_text_spans.empty()) { - ime_text_spans.push_back( - ui::ImeTextSpan(ui::ImeTextSpan::Type::kComposition, 0, text16.length(), - ui::ImeTextSpan::Thickness::kThin, SK_ColorTRANSPARENT, - SK_ColorTRANSPARENT, std::vector<std::string>())); + ime_text_spans.push_back(ui::ImeTextSpan( + ui::ImeTextSpan::Type::kComposition, 0, text16.length(), + ui::ImeTextSpan::Thickness::kThin, + ui::ImeTextSpan::UnderlineStyle::kSolid, SK_ColorTRANSPARENT, + SK_ColorTRANSPARENT, std::vector<std::string>())); } // relative_cursor_pos is as described in the Android API for @@ -401,10 +405,11 @@ return; std::vector<ui::ImeTextSpan> ime_text_spans; - ime_text_spans.push_back( - ui::ImeTextSpan(ui::ImeTextSpan::Type::kComposition, 0, end - start, - ui::ImeTextSpan::Thickness::kThin, SK_ColorTRANSPARENT, - SK_ColorTRANSPARENT, std::vector<std::string>())); + ime_text_spans.push_back(ui::ImeTextSpan( + ui::ImeTextSpan::Type::kComposition, 0, end - start, + ui::ImeTextSpan::Thickness::kThin, + ui::ImeTextSpan::UnderlineStyle::kSolid, SK_ColorTRANSPARENT, + SK_ColorTRANSPARENT, std::vector<std::string>())); input_handler->SetCompositionFromExistingText(start, end, ime_text_spans); }
diff --git a/content/browser/blob_storage/blob_registry_wrapper.cc b/content/browser/blob_storage/blob_registry_wrapper.cc index 5cf53de..314b05d0e 100644 --- a/content/browser/blob_storage/blob_registry_wrapper.cc +++ b/content/browser/blob_storage/blob_registry_wrapper.cc
@@ -20,32 +20,22 @@ class BindingDelegate : public storage::BlobRegistryImpl::Delegate { public: - explicit BindingDelegate(int process_id) : process_id_(process_id) {} + explicit BindingDelegate( + ChildProcessSecurityPolicyImpl::Handle security_policy_handle) + : security_policy_handle_(std::move(security_policy_handle)) {} ~BindingDelegate() override {} bool CanReadFile(const base::FilePath& file) override { - ChildProcessSecurityPolicyImpl* security_policy = - ChildProcessSecurityPolicyImpl::GetInstance(); - return security_policy->CanReadFile(process_id_, file); + return security_policy_handle_.CanReadFile(file); } bool CanReadFileSystemFile(const storage::FileSystemURL& url) override { - ChildProcessSecurityPolicyImpl* security_policy = - ChildProcessSecurityPolicyImpl::GetInstance(); - return security_policy->CanReadFileSystemFile(process_id_, url); + return security_policy_handle_.CanReadFileSystemFile(url); } bool CanCommitURL(const GURL& url) override { - ChildProcessSecurityPolicyImpl* security_policy = - ChildProcessSecurityPolicyImpl::GetInstance(); - return security_policy->CanCommitURL(process_id_, url); + return security_policy_handle_.CanCommitURL(url); } - bool IsProcessValid() override { - ChildProcessSecurityPolicyImpl* security_policy = - ChildProcessSecurityPolicyImpl::GetInstance(); - return security_policy->HasSecurityState(process_id_); - } - private: - const int process_id_; + ChildProcessSecurityPolicyImpl::Handle security_policy_handle_; }; } // namespace @@ -69,8 +59,11 @@ int process_id, mojo::PendingReceiver<blink::mojom::BlobRegistry> receiver) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - blob_registry_->Bind(std::move(receiver), - std::make_unique<BindingDelegate>(process_id)); + blob_registry_->Bind( + std::move(receiver), + std::make_unique<BindingDelegate>( + ChildProcessSecurityPolicyImpl::GetInstance()->CreateHandle( + process_id))); } BlobRegistryWrapper::~BlobRegistryWrapper() {}
diff --git a/content/browser/browser_context.cc b/content/browser/browser_context.cc index 36f2408..44e6a96 100644 --- a/content/browser/browser_context.cc +++ b/content/browser/browser_context.cc
@@ -456,13 +456,13 @@ } } - // Clean up any isolated origins associated with this BrowserContext. This - // should be safe now that all RenderProcessHosts are destroyed, since future - // navigations or security decisions shouldn't ever need to consult these - // isolated origins. + // Clean up any isolated origins and other security state associated with this + // BrowserContext. This should be safe now that all RenderProcessHosts are + // destroyed, since future navigations or security decisions shouldn't ever + // need to consult these isolated origins and other security state. ChildProcessSecurityPolicyImpl* policy = ChildProcessSecurityPolicyImpl::GetInstance(); - policy->RemoveIsolatedOriginsForBrowserContext(*browser_context); + policy->RemoveStateForBrowserContext(*browser_context); } void BrowserContext::EnsureResourceContextInitialized(BrowserContext* context) {
diff --git a/content/browser/child_process_security_policy_impl.cc b/content/browser/child_process_security_policy_impl.cc index 7f328241..d22e4211 100644 --- a/content/browser/child_process_security_policy_impl.cc +++ b/content/browser/child_process_security_policy_impl.cc
@@ -33,6 +33,7 @@ #include "content/public/browser/site_isolation_policy.h" #include "content/public/browser/storage_partition.h" #include "content/public/common/bindings_policy.h" +#include "content/public/common/child_process_host.h" #include "content/public/common/content_client.h" #include "content/public/common/url_constants.h" #include "net/base/filename_util.h" @@ -159,6 +160,88 @@ } // namespace +ChildProcessSecurityPolicyImpl::Handle::Handle() + : child_id_(ChildProcessHost::kInvalidUniqueID) {} + +ChildProcessSecurityPolicyImpl::Handle::Handle(int child_id) + : child_id_(child_id) { + auto* policy = ChildProcessSecurityPolicyImpl::GetInstance(); + if (!policy->AddProcessReference(child_id_)) + child_id_ = ChildProcessHost::kInvalidUniqueID; +} + +ChildProcessSecurityPolicyImpl::Handle::Handle(Handle&& rhs) + : child_id_(rhs.child_id_) { + rhs.child_id_ = ChildProcessHost::kInvalidUniqueID; +} + +ChildProcessSecurityPolicyImpl::Handle::~Handle() { + if (child_id_ != ChildProcessHost::kInvalidUniqueID) { + auto* policy = ChildProcessSecurityPolicyImpl::GetInstance(); + policy->RemoveProcessReference(child_id_); + } +} + +ChildProcessSecurityPolicyImpl::Handle& ChildProcessSecurityPolicyImpl::Handle:: +operator=(Handle&& rhs) { + if (child_id_ != ChildProcessHost::kInvalidUniqueID && + child_id_ != rhs.child_id_) { + auto* policy = ChildProcessSecurityPolicyImpl::GetInstance(); + policy->RemoveProcessReference(child_id_); + } + child_id_ = rhs.child_id_; + rhs.child_id_ = ChildProcessHost::kInvalidUniqueID; + return *this; +} + +bool ChildProcessSecurityPolicyImpl::Handle::is_valid() const { + return child_id_ != ChildProcessHost::kInvalidUniqueID; +} + +bool ChildProcessSecurityPolicyImpl::Handle::CanCommitURL(const GURL& url) { + if (child_id_ == ChildProcessHost::kInvalidUniqueID) + return false; + + auto* policy = ChildProcessSecurityPolicyImpl::GetInstance(); + return policy->CanCommitURL(child_id_, url); +} + +bool ChildProcessSecurityPolicyImpl::Handle::CanReadFile( + const base::FilePath& file) { + if (child_id_ == ChildProcessHost::kInvalidUniqueID) + return false; + + auto* policy = ChildProcessSecurityPolicyImpl::GetInstance(); + return policy->CanReadFile(child_id_, file); +} + +bool ChildProcessSecurityPolicyImpl::Handle::CanReadFileSystemFile( + const storage::FileSystemURL& url) { + if (child_id_ == ChildProcessHost::kInvalidUniqueID) + return false; + + auto* policy = ChildProcessSecurityPolicyImpl::GetInstance(); + return policy->CanReadFileSystemFile(child_id_, url); +} + +bool ChildProcessSecurityPolicyImpl::Handle::CanAccessDataForOrigin( + const GURL& url) { + if (child_id_ == ChildProcessHost::kInvalidUniqueID) + return false; + + auto* policy = ChildProcessSecurityPolicyImpl::GetInstance(); + return policy->CanAccessDataForOrigin(child_id_, url); +} + +bool ChildProcessSecurityPolicyImpl::Handle::CanAccessDataForOrigin( + const url::Origin& origin) { + if (child_id_ == ChildProcessHost::kInvalidUniqueID) + return false; + + auto* policy = ChildProcessSecurityPolicyImpl::GetInstance(); + return policy->CanAccessDataForOrigin(child_id_, origin); +} + // The SecurityState class is used to maintain per-child process security state // information. class ChildProcessSecurityPolicyImpl::SecurityState { @@ -389,7 +472,10 @@ return BrowserOrResourceContext(); } - void ClearBrowserContext() { browser_context_ = nullptr; } + void ClearBrowserContextIfMatches(const BrowserContext* browser_context) { + if (browser_context == browser_context_) + browser_context_ = nullptr; + } private: enum class CommitRequestPolicy { @@ -563,12 +649,13 @@ DCHECK(browser_context); DCHECK_CURRENTLY_ON(BrowserThread::UI); base::AutoLock lock(lock_); - if (security_state_.count(child_id) != 0) { + if (security_state_.find(child_id) != security_state_.end()) { NOTREACHED() << "Add child process at most once."; return; } security_state_[child_id] = std::make_unique<SecurityState>(browser_context); + CHECK(AddProcessReferenceLocked(child_id)); } void ChildProcessSecurityPolicyImpl::Remove(int child_id) { @@ -579,27 +666,13 @@ if (state == security_state_.end()) return; - state->second->ClearBrowserContext(); - // Moving the existing SecurityState object into a pending map so // that we can preserve permission state and avoid mutations to this // state after Remove() has been called. pending_remove_state_[child_id] = std::move(state->second); security_state_.erase(child_id); - // |child_id| could be inside tasks that are on the IO thread task queues. We - // need to keep the |pending_remove_state_| entry around until we have - // successfully executed a task on the IO thread. This should ensure that any - // pending tasks on the IO thread will have completed before we remove the - // entry. - base::PostTask(FROM_HERE, {BrowserThread::IO}, - base::BindOnce( - [](ChildProcessSecurityPolicyImpl* policy, int child_id) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - base::AutoLock lock(policy->lock_); - policy->pending_remove_state_.erase(child_id); - }, - base::Unretained(this), child_id)); + RemoveProcessReferenceLocked(child_id); } void ChildProcessSecurityPolicyImpl::RegisterWebSafeScheme( @@ -1005,13 +1078,13 @@ if (base::Contains(schemes_okay_to_commit_in_any_process_, scheme)) return true; - auto state = security_state_.find(child_id); - if (state == security_state_.end()) + auto* state = GetSecurityState(child_id); + if (!state) return false; // Otherwise, we consult the child process's security state to see if it is // allowed to commit the URL. - return state->second->CanCommitURL(url); + return state->CanCommitURL(url); } } @@ -1239,10 +1312,10 @@ bool ChildProcessSecurityPolicyImpl::ChildProcessHasPermissionsForFile( int child_id, const base::FilePath& file, int permissions) { - auto state = security_state_.find(child_id); - if (state == security_state_.end()) + auto* state = GetSecurityState(child_id); + if (!state) return false; - return state->second->HasPermissionsForFile(file, permissions); + return state->HasPermissionsForFile(file, permissions); } CanCommitStatus ChildProcessSecurityPolicyImpl::CanCommitOriginAndUrl( @@ -1510,10 +1583,10 @@ int permission) { base::AutoLock lock(lock_); - auto state = security_state_.find(child_id); - if (state == security_state_.end()) + auto* state = GetSecurityState(child_id); + if (!state) return false; - return state->second->HasPermissionsForFileSystem(filesystem_id, permission); + return state->HasPermissionsForFileSystem(filesystem_id, permission); } void ChildProcessSecurityPolicyImpl::RegisterFileSystemPermissionPolicy( @@ -1635,22 +1708,33 @@ } } -void ChildProcessSecurityPolicyImpl::RemoveIsolatedOriginsForBrowserContext( +void ChildProcessSecurityPolicyImpl::RemoveStateForBrowserContext( const BrowserContext& browser_context) { - base::AutoLock isolated_origins_lock(isolated_origins_lock_); + { + base::AutoLock isolated_origins_lock(isolated_origins_lock_); - for (auto& iter : isolated_origins_) { - base::EraseIf(iter.second, - [&browser_context](const IsolatedOriginEntry& entry) { - // Remove if BrowserContext matches. - return (entry.browser_context() == &browser_context); - }); + for (auto& iter : isolated_origins_) { + base::EraseIf(iter.second, + [&browser_context](const IsolatedOriginEntry& entry) { + // Remove if BrowserContext matches. + return (entry.browser_context() == &browser_context); + }); + } + + // Also remove map entries for site URLs which no longer have any + // IsolatedOriginEntries remaining. + base::EraseIf(isolated_origins_, + [](const auto& pair) { return pair.second.empty(); }); } - // Also remove map entries for site URLs which no longer have any - // IsolatedOriginEntries remaining. - base::EraseIf(isolated_origins_, - [](const auto& pair) { return pair.second.empty(); }); + { + base::AutoLock lock(lock_); + for (auto& pair : security_state_) + pair.second->ClearBrowserContextIfMatches(&browser_context); + + for (auto& pair : pending_remove_state_) + pair.second->ClearBrowserContextIfMatches(&browser_context); + } } bool ChildProcessSecurityPolicyImpl::IsIsolatedOrigin( @@ -1823,15 +1907,29 @@ if (itr != security_state_.end()) return itr->second.get(); - // Check to see if |child_id| is in the pending removal map since this - // may be a call that was already on the IO thread's task queue when the - // Remove() call occurred. - if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { - itr = pending_remove_state_.find(child_id); - if (itr != pending_remove_state_.end()) - return itr->second.get(); + auto pending_itr = pending_remove_state_.find(child_id); + if (pending_itr == pending_remove_state_.end()) + return nullptr; + + // At this point the SecurityState in the map is being kept alive + // by a Handle object or we are waiting for the deletion task to be run on + // the IO thread. + SecurityState* pending_security_state = pending_itr->second.get(); + + auto count_itr = process_reference_counts_.find(child_id); + if (count_itr != process_reference_counts_.end()) { + // There must be a Handle that still holds a reference to this + // pending state so it is safe to return. The assumption is that the + // owner of this Handle is making a security check. + return pending_security_state; } + // Since we don't have an entry in |process_reference_counts_| it means + // that we are waiting for the deletion task posted to the IO thread to run. + // Only allow the state to be accessed by the IO thread in this situation. + if (BrowserThread::CurrentlyOn(BrowserThread::IO)) + return pending_security_state; + return nullptr; } @@ -1876,4 +1974,59 @@ GetKilledProcessOriginLock(security_state)); } +ChildProcessSecurityPolicyImpl::Handle +ChildProcessSecurityPolicyImpl::CreateHandle(int child_id) { + return Handle(child_id); +} + +bool ChildProcessSecurityPolicyImpl::AddProcessReference(int child_id) { + base::AutoLock lock(lock_); + return AddProcessReferenceLocked(child_id); +} + +bool ChildProcessSecurityPolicyImpl::AddProcessReferenceLocked(int child_id) { + // Make sure that we aren't trying to add references after the process has + // been destroyed. + if (security_state_.find(child_id) == security_state_.end()) + return false; + + ++process_reference_counts_[child_id]; + return true; +} + +void ChildProcessSecurityPolicyImpl::RemoveProcessReference(int child_id) { + base::AutoLock lock(lock_); + RemoveProcessReferenceLocked(child_id); +} + +void ChildProcessSecurityPolicyImpl::RemoveProcessReferenceLocked( + int child_id) { + auto itr = process_reference_counts_.find(child_id); + CHECK(itr != process_reference_counts_.end()); + + if (itr->second > 1) { + itr->second--; + return; + } + + DCHECK_EQ(itr->second, 1); + process_reference_counts_.erase(itr); + + // |child_id| could be inside tasks that are on the IO thread task queues. We + // need to keep the |pending_remove_state_| entry around until we have + // successfully executed a task on the IO thread. This should ensure that any + // pending tasks on the IO thread will have completed before we remove the + // entry. + // TODO(acolwell): Remove this call once all objects on the IO thread have + // been converted to use Handles. + base::PostTask(FROM_HERE, {BrowserThread::IO}, + base::BindOnce( + [](ChildProcessSecurityPolicyImpl* policy, int child_id) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + base::AutoLock lock(policy->lock_); + policy->pending_remove_state_.erase(child_id); + }, + base::Unretained(this), child_id)); +} + } // namespace content
diff --git a/content/browser/child_process_security_policy_impl.h b/content/browser/child_process_security_policy_impl.h index 73c7d42..e5ef843 100644 --- a/content/browser/child_process_security_policy_impl.h +++ b/content/browser/child_process_security_policy_impl.h
@@ -53,6 +53,68 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl : public ChildProcessSecurityPolicy { public: + // Handle used to access the security state for a specific process. + // + // Objects that require the security state to be preserved beyond the + // lifetime of the RenderProcessHostImpl should hold an instance of this + // object and use it to answer security policy questions. (e.g. Mojo services + // created by RPHI that can receive calls after RPHI destruction). This + // object should only be called on the UI and IO threads. + // + // Note: Some security methods, like CanAccessDataForOrigin(), require + // information from the BrowserContext to make its decisions. These methods + // will fall back to failsafe values if called after BrowserContext + // destruction. Callers should be prepared to gracefully handle this or + // ensure that they don't make any calls after BrowserContext destruction. + class CONTENT_EXPORT Handle { + public: + Handle(); + Handle(Handle&&); + Handle(const Handle&) = delete; + ~Handle(); + + Handle& operator=(const Handle&) = delete; + Handle& operator=(Handle&&); + + // Returns true if this object has a valid process ID. + // Returns false if this object was created with the default constructor, + // the contents of this object was transferred to another Handle via + // std::move(), or ChildProcessSecurityPolicyImpl::CreateHandle() + // created this object after the process has already been destructed. + bool is_valid() const; + + // Whether the process is allowed to commit a document from the given URL. + bool CanCommitURL(const GURL& url); + + // Before servicing a child process's request to upload a file to the web, + // the browser should call this method to determine whether the process has + // the capability to upload the requested file. + bool CanReadFile(const base::FilePath& file); + + // Explicit read permissions check for FileSystemURL specified files. + bool CanReadFileSystemFile(const storage::FileSystemURL& url); + + // Returns true if the process is permitted to read and modify the data for + // the origin of |url|. This is currently used to protect data such as + // cookies, passwords, and local storage. Does not affect cookies attached + // to or set by network requests. + // + // This can only return false for processes locked to a particular origin, + // which can happen for any origin when the --site-per-process flag is used, + // or for isolated origins that require a dedicated process (see + // AddIsolatedOrigins). + bool CanAccessDataForOrigin(const GURL& url); + bool CanAccessDataForOrigin(const url::Origin& origin); + + private: + friend class ChildProcessSecurityPolicyImpl; + explicit Handle(int child_id); + + // The ID of the child process that this handle is associated with or + // ChildProcessHost::kInvalidUniqueID if the handle is no longer valid. + int child_id_; + }; + // Object can only be created through GetInstance() so the constructor is // private. ~ChildProcessSecurityPolicyImpl() override; @@ -281,14 +343,14 @@ // Returns true if sending system exclusive messages is allowed. bool CanSendMidiSysExMessage(int child_id); - // Remove all isolated origins associated with |browser_context|. This is + // Remove all isolated origins associated with |browser_context| and clear any + // pointers that may reference |browser_context|. This is // typically used when |browser_context| is being destroyed and assumes that // no processes are running or will run for that profile; this makes the // isolated origin removal safe. Note that |browser_context| cannot be null; // i.e., isolated origins that apply globally to all profiles cannot // currently be removed, since that is not safe to do at runtime. - void RemoveIsolatedOriginsForBrowserContext( - const BrowserContext& browser_context); + void RemoveStateForBrowserContext(const BrowserContext& browser_context); // Check whether |origin| requires origin-wide process isolation within // |isolation_context|. @@ -332,9 +394,23 @@ // process associated with |child_id|. void LogKilledProcessOriginLock(int child_id); + // Creates a Handle object for a specific child process ID. + // + // This handle can be used to extend the lifetime of policy state beyond + // the Remove() call for |child_id|. This should be used by objects that can + // outlive the RenderProcessHostImpl object associated with |child_id| and + // need to be able to make policy decisions after RPHI destruction. (e.g. + // Mojo services created by RPHI) + // + // Returns a valid Handle for any |child_id| that is present in + // |security_state_|. Otherwise it returns a Handle that returns false for + // all policy checks. + Handle CreateHandle(int child_id); + private: friend class ChildProcessSecurityPolicyInProcessBrowserTest; friend class ChildProcessSecurityPolicyTest; + friend class ChildProcessSecurityPolicyImpl::Handle; FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyInProcessBrowserTest, NoLeak); FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest, FilePermissions); @@ -502,6 +578,12 @@ IsolatedOriginSource source, BrowserContext* browser_context = nullptr); + bool AddProcessReference(int child_id); + bool AddProcessReferenceLocked(int child_id) EXCLUSIVE_LOCKS_REQUIRED(lock_); + void RemoveProcessReference(int child_id); + void RemoveProcessReferenceLocked(int child_id) + EXCLUSIVE_LOCKS_REQUIRED(lock_); + // Creates the value to place in the "killed_process_origin_lock" crash key // based on the contents of |security_state|. static std::string GetKilledProcessOriginLock( @@ -539,6 +621,13 @@ FileSystemPermissionPolicyMap file_system_policy_map_ GUARDED_BY(lock_); + // Contains a mapping between child process ID and the number of outstanding + // references that want to keep the SecurityState for each process alive. + // This object and Handles created by this object increment/decrement + // the counts in this map and only destroy a SecurityState object for a + // process when its count goes to zero. + std::map<int, int> process_reference_counts_ GUARDED_BY(lock_); + // You must acquire this lock before reading or writing isolated_origins_. // You must not block while holding this lock. //
diff --git a/content/browser/child_process_security_policy_unittest.cc b/content/browser/child_process_security_policy_unittest.cc index a7afbf8..e8cacf49 100644 --- a/content/browser/child_process_security_policy_unittest.cc +++ b/content/browser/child_process_security_policy_unittest.cc
@@ -240,6 +240,10 @@ EXPECT_FALSE(p->CanCreateReadWriteFileSystemFile(kRendererID, url)); EXPECT_FALSE(p->CanCopyIntoFileSystemFile(kRendererID, url)); EXPECT_FALSE(p->CanDeleteFileSystemFile(kRendererID, url)); + + auto handle = p->CreateHandle(kRendererID); + EXPECT_FALSE(handle.CanReadFile(file)); + EXPECT_FALSE(handle.CanReadFileSystemFile(url)); } BrowserContext* browser_context() { return &browser_context_; } @@ -293,6 +297,8 @@ p->Add(kRendererID, browser_context()); + auto handle = p->CreateHandle(kRendererID); + // Safe to request, redirect or commit. EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("http://www.google.com/"))); EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("https://www.paypal.com/"))); @@ -306,23 +312,25 @@ EXPECT_TRUE(p->CanRedirectToURL(GURL("data:text/html,<b>Hi</b>"))); EXPECT_TRUE( p->CanRedirectToURL(GURL("filesystem:http://localhost/temporary/a.gif"))); - if (AreAllSitesIsolatedForTesting() && IsCitadelProtectionEnabled()) { - // A non-locked process cannot access URLs below (because with - // site-per-process all the URLs need to be isolated). - EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("http://www.google.com/"))); - EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("https://www.paypal.com/"))); - EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("ftp://ftp.gnu.org/"))); - EXPECT_FALSE( - p->CanCommitURL(kRendererID, GURL("data:text/html,<b>Hi</b>"))); - EXPECT_FALSE(p->CanCommitURL( - kRendererID, GURL("filesystem:http://localhost/temporary/a.gif"))); - } else { - EXPECT_TRUE(p->CanCommitURL(kRendererID, GURL("http://www.google.com/"))); - EXPECT_TRUE(p->CanCommitURL(kRendererID, GURL("https://www.paypal.com/"))); - EXPECT_TRUE(p->CanCommitURL(kRendererID, GURL("ftp://ftp.gnu.org/"))); - EXPECT_TRUE(p->CanCommitURL(kRendererID, GURL("data:text/html,<b>Hi</b>"))); - EXPECT_TRUE(p->CanCommitURL( - kRendererID, GURL("filesystem:http://localhost/temporary/a.gif"))); + + const std::vector<std::string> kCommitURLs({ + "http://www.google.com/", + "https://www.paypal.com/", + "ftp://ftp.gnu.org/", + "data:text/html,<b>Hi</b>", + "filesystem:http://localhost/temporary/a.gif", + }); + for (const auto url_string : kCommitURLs) { + const GURL commit_url(url_string); + if (AreAllSitesIsolatedForTesting() && IsCitadelProtectionEnabled()) { + // A non-locked process cannot access URL (because with + // site-per-process all the URLs need to be isolated). + EXPECT_FALSE(p->CanCommitURL(kRendererID, commit_url)) << commit_url; + EXPECT_FALSE(handle.CanCommitURL(commit_url)) << commit_url; + } else { + EXPECT_TRUE(p->CanCommitURL(kRendererID, commit_url)) << commit_url; + EXPECT_TRUE(handle.CanCommitURL(commit_url)) << commit_url; + } } // Dangerous to request, commit, or set as origin header. @@ -334,13 +342,16 @@ EXPECT_TRUE(p->CanRedirectToURL(GURL("file:///etc/passwd"))); EXPECT_TRUE(p->CanRedirectToURL(GetWebUIURL("foo/bar"))); EXPECT_FALSE(p->CanRedirectToURL(GURL("view-source:http://www.google.com/"))); - EXPECT_FALSE(p->CanCommitURL(kRendererID, - GURL("file:///etc/passwd"))); - EXPECT_FALSE(p->CanCommitURL(kRendererID, GetWebUIURL("foo/bar"))); - EXPECT_FALSE( - p->CanCommitURL(kRendererID, GURL("view-source:http://www.google.com/"))); EXPECT_FALSE(p->CanRedirectToURL(GURL(kUnreachableWebDataURL))); - EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL(kUnreachableWebDataURL))); + + const std::vector<std::string> kFailedCommitURLs( + {"file:///etc/passwd", "view-source:http://www.google.com/", + kUnreachableWebDataURL, GetWebUIURL("foo/bar").spec()}); + for (const auto url_string : kFailedCommitURLs) { + const GURL commit_url(url_string); + EXPECT_FALSE(p->CanCommitURL(kRendererID, commit_url)) << commit_url; + EXPECT_FALSE(handle.CanCommitURL(commit_url)) << commit_url; + } p->Remove(kRendererID); } @@ -1228,6 +1239,102 @@ EXPECT_FALSE(io_after_remove_complete); } +// This test is similar to the one above that verifies CanAccessDataForOrigin() +// behavior during process shutdown. This particular test verifies that a +// ChildProcessSecurityPolicyImpl::Handle extends the lifetime of the security +// state beyond the Remove() call. This represents the case where a Mojo service +// on the IO thread still receives calls after the RPHI that created it has +// been destroyed. +// +// We use a combination of waitable events and extra tasks posted to the +// threads to capture permission state from the UI & IO threads during the +// removal process. It is intended to simulate pending tasks that could be +// run on each thread during removal. +TEST_F(ChildProcessSecurityPolicyTest, HandleExtendsSecurityStateLifetime) { + ChildProcessSecurityPolicyImpl* p = + ChildProcessSecurityPolicyImpl::GetInstance(); + + GURL url("file:///etc/passwd"); + + p->Add(kRendererID, browser_context()); + + auto handle = p->CreateHandle(kRendererID); + + base::WaitableEvent ready_for_remove_event; + base::WaitableEvent remove_called_event; + base::WaitableEvent ready_for_handle_invalidation_event; + + // Keep track of the return value for CanAccessDataForOrigin at various + // points in time during the test. + bool io_before_remove = false; + bool io_after_remove = false; + bool ui_before_remove = false; + bool ui_after_remove = false; + + // Post a task that will run on the IO thread before the task that + // Remove() will post to the IO thread. + base::PostTask(FROM_HERE, {BrowserThread::IO}, + base::BindLambdaForTesting([&]() { + // Capture state on the IO thread before Remove() is called. + io_before_remove = handle.CanAccessDataForOrigin(url); + + // Tell the UI thread we are ready for Remove() to be called. + ready_for_remove_event.Signal(); + })); + + ready_for_remove_event.Wait(); + + ui_before_remove = handle.CanAccessDataForOrigin(url); + + p->Remove(kRendererID); + + ui_after_remove = handle.CanAccessDataForOrigin(url); + + // Post a task to verify post-Remove() state on the IO thread. + base::PostTask(FROM_HERE, {BrowserThread::IO}, + base::BindLambdaForTesting([&]() { + io_after_remove = handle.CanAccessDataForOrigin(url); + + // Tell the UI thread that we are ready to invalidate the + // handle. + ready_for_handle_invalidation_event.Signal(); + })); + + ready_for_handle_invalidation_event.Wait(); + + // Invalidate the handle so it triggers destruction of the security state. + handle = ChildProcessSecurityPolicyImpl::Handle(); + + bool ui_after_handle_invalidation = handle.CanAccessDataForOrigin(url); + bool io_after_handle_invalidation = false; + base::WaitableEvent after_invalidation_complete_event; + + base::PostTask( + FROM_HERE, {BrowserThread::IO}, base::BindLambdaForTesting([&]() { + io_after_handle_invalidation = handle.CanAccessDataForOrigin(url); + + // Tell the UI thread that this task has + // has completed on the IO thread. + after_invalidation_complete_event.Signal(); + })); + + // Wait for the task we just posted to the IO thread to complete. + after_invalidation_complete_event.Wait(); + + // Verify expected states at various parts of the removal. + // Note: IO thread is expected to keep pre-Remove() permissions until + // |handle| is invalidated and the task RemoveProcessReferenceLocked() posted + // runs on the IO thread. + EXPECT_TRUE(io_before_remove); + EXPECT_TRUE(ui_before_remove); + + EXPECT_TRUE(io_after_remove); + EXPECT_TRUE(ui_after_remove); + + EXPECT_FALSE(io_after_handle_invalidation); + EXPECT_FALSE(ui_after_handle_invalidation); +} + TEST_F(ChildProcessSecurityPolicyTest, CanAccessDataForOrigin_URL) { ChildProcessSecurityPolicyImpl* p = ChildProcessSecurityPolicyImpl::GetInstance(); @@ -1238,31 +1345,33 @@ GURL foo_filesystem_url("filesystem:http://foo.com/temporary/test.html"); GURL bar_http_url("http://bar.com/index.html"); - // Test invalid ID case. - EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID, file_url)); - EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID, foo_http_url)); - EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID, foo_blob_url)); - EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID, foo_filesystem_url)); - EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID, bar_http_url)); + const std::vector<GURL> kAllTestUrls = {file_url, foo_http_url, foo_blob_url, + foo_filesystem_url, bar_http_url}; + + // Test invalid ID and invalid Handle cases. + auto handle = p->CreateHandle(kRendererID); + for (auto url : kAllTestUrls) { + EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID, url)) << url; + EXPECT_FALSE(handle.CanAccessDataForOrigin(bar_http_url)) << url; + } TestBrowserContext browser_context; p->Add(kRendererID, &browser_context); + // Replace the old invalid handle with a new valid handle. + handle = p->CreateHandle(kRendererID); + // Verify unlocked origin permissions. - if (AreAllSitesIsolatedForTesting() && IsCitadelProtectionEnabled()) { - // A non-locked process cannot access URLs below (because with - // site-per-process all the URLs need to be isolated). - EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID, file_url)); - EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID, foo_http_url)); - EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID, foo_blob_url)); - EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID, foo_filesystem_url)); - EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID, bar_http_url)); - } else { - EXPECT_TRUE(p->CanAccessDataForOrigin(kRendererID, file_url)); - EXPECT_TRUE(p->CanAccessDataForOrigin(kRendererID, foo_http_url)); - EXPECT_TRUE(p->CanAccessDataForOrigin(kRendererID, foo_blob_url)); - EXPECT_TRUE(p->CanAccessDataForOrigin(kRendererID, foo_filesystem_url)); - EXPECT_TRUE(p->CanAccessDataForOrigin(kRendererID, bar_http_url)); + for (auto url : kAllTestUrls) { + if (AreAllSitesIsolatedForTesting() && IsCitadelProtectionEnabled()) { + // A non-locked process cannot access URLs below (because with + // site-per-process all the URLs need to be isolated). + EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID, url)) << url; + EXPECT_FALSE(handle.CanAccessDataForOrigin(url)) << url; + } else { + EXPECT_TRUE(p->CanAccessDataForOrigin(kRendererID, url)) << url; + EXPECT_TRUE(handle.CanAccessDataForOrigin(url)) << url; + } } // Isolate |http_url| so we can't get a default SiteInstance. @@ -1281,6 +1390,14 @@ EXPECT_TRUE(p->CanAccessDataForOrigin(kRendererID, foo_blob_url)); EXPECT_TRUE(p->CanAccessDataForOrigin(kRendererID, foo_filesystem_url)); EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID, bar_http_url)); + EXPECT_FALSE(handle.CanAccessDataForOrigin(file_url)); + EXPECT_TRUE(handle.CanAccessDataForOrigin(foo_http_url)); + EXPECT_TRUE(handle.CanAccessDataForOrigin(foo_blob_url)); + EXPECT_TRUE(handle.CanAccessDataForOrigin(foo_filesystem_url)); + EXPECT_FALSE(handle.CanAccessDataForOrigin(bar_http_url)); + + // Invalidate handle so it does not preserve security state beyond Remove(). + handle = ChildProcessSecurityPolicyImpl::Handle(); p->Remove(kRendererID); @@ -1292,11 +1409,10 @@ run_loop.Run(); // Verify invalid ID is rejected now that Remove() has completed. - EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID, file_url)); - EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID, foo_http_url)); - EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID, foo_blob_url)); - EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID, foo_filesystem_url)); - EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID, bar_http_url)); + for (auto url : kAllTestUrls) { + EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID, url)) << url; + EXPECT_FALSE(handle.CanAccessDataForOrigin(url)) << url; + } } TEST_F(ChildProcessSecurityPolicyTest, CanAccessDataForOrigin_Origin) {
diff --git a/content/browser/frame_host/back_forward_cache_metrics_browsertest.cc b/content/browser/frame_host/back_forward_cache_metrics_browsertest.cc index 6d83f51..6c66e83 100644 --- a/content/browser/frame_host/back_forward_cache_metrics_browsertest.cc +++ b/content/browser/frame_host/back_forward_cache_metrics_browsertest.cc
@@ -48,38 +48,8 @@ 1 << static_cast<size_t>(blink::scheduler::WebSchedulerTrackedFeature:: kOutstandingNetworkRequest); -using UkmMetrics = std::map<std::string, int64_t>; -using UkmEntry = std::pair<ukm::SourceId, UkmMetrics>; - -std::vector<UkmEntry> GetEntries(ukm::TestUkmRecorder* recorder, - std::string entry_name, - const std::vector<std::string>& metrics) { - std::vector<UkmEntry> results; - for (const ukm::mojom::UkmEntry* entry : - recorder->GetEntriesByName(entry_name)) { - UkmEntry result; - result.first = entry->source_id; - for (const std::string& metric_name : metrics) { - const int64_t* metric_value = - ukm::TestUkmRecorder::GetEntryMetric(entry, metric_name); - EXPECT_TRUE(metric_value) << "Metric " << metric_name - << " is not found in entry " << entry_name; - result.second[metric_name] = *metric_value; - } - results.push_back(std::move(result)); - } - return results; -} - -std::vector<UkmMetrics> GetMetrics(ukm::TestUkmRecorder* recorder, - std::string entry_name, - const std::vector<std::string>& metrics) { - std::vector<UkmMetrics> result; - for (const auto& entry : GetEntries(recorder, entry_name, metrics)) { - result.push_back(entry.second); - } - return result; -} +using UkmMetrics = ukm::TestUkmRecorder::HumanReadableUkmMetrics; +using UkmEntry = ukm::TestUkmRecorder::HumanReadableUkmEntry; } // namespace @@ -181,7 +151,7 @@ // Second back-forward navigation (#8) navigates back to navigation #2, // but it is subframe navigation and not reflected here. Third back-forward // navigation (#9) navigates back to navigation #1. - EXPECT_THAT(GetEntries(&recorder, "HistoryNavigation", {last_navigation_id}), + EXPECT_THAT(recorder.GetEntries("HistoryNavigation", {last_navigation_id}), testing::ElementsAre(UkmEntry{id6, {{last_navigation_id, id2}}}, UkmEntry{id9, {{last_navigation_id, id1}}})); } @@ -229,7 +199,7 @@ // The second back/forward navigation is a subframe one and should be ignored. // The last one navigates to the actual entry. EXPECT_THAT( - GetMetrics(&recorder, "HistoryNavigation", {navigated_to_last_entry}), + recorder.GetMetrics("HistoryNavigation", {navigated_to_last_entry}), testing::ElementsAre(UkmMetrics{{navigated_to_last_entry, false}}, UkmMetrics{{navigated_to_last_entry, true}})); } @@ -287,7 +257,7 @@ // The fourth goes back, but the metrics are not recorded due to it being // cloned and the metrics objects missing. // The last two navigations, however, should have metrics. - EXPECT_THAT(GetEntries(&recorder, "HistoryNavigation", {last_navigation_id}), + EXPECT_THAT(recorder.GetEntries("HistoryNavigation", {last_navigation_id}), testing::ElementsAre(UkmEntry{id5, {{last_navigation_id, id3}}}, UkmEntry{id6, {{last_navigation_id, id4}}})); } @@ -322,17 +292,18 @@ ukm::TestAutoSetUkmRecorder* recorder) { std::vector<FeatureUsage> result; for (const auto& entry : - GetEntries(recorder, "HistoryNavigation", - {"MainFrameFeatures", "SameOriginSubframesFeatures", - "CrossOriginSubframesFeatures"})) { + recorder->GetEntries("HistoryNavigation", + {"MainFrameFeatures", "SameOriginSubframesFeatures", + "CrossOriginSubframesFeatures"})) { FeatureUsage feature_usage; - feature_usage.source_id = entry.first; + feature_usage.source_id = entry.source_id; feature_usage.main_frame_features = - entry.second.at("MainFrameFeatures") & ~kFeaturesToIgnoreMask; + entry.metrics.at("MainFrameFeatures") & ~kFeaturesToIgnoreMask; feature_usage.same_origin_subframes_features = - entry.second.at("SameOriginSubframesFeatures") & ~kFeaturesToIgnoreMask; + entry.metrics.at("SameOriginSubframesFeatures") & + ~kFeaturesToIgnoreMask; feature_usage.cross_origin_subframes_features = - entry.second.at("CrossOriginSubframesFeatures") & + entry.metrics.at("CrossOriginSubframesFeatures") & ~kFeaturesToIgnoreMask; result.push_back(feature_usage); }
diff --git a/content/browser/frame_host/back_forward_cache_metrics_unittest.cc b/content/browser/frame_host/back_forward_cache_metrics_unittest.cc index 7c229b9..29b2b87b 100644 --- a/content/browser/frame_host/back_forward_cache_metrics_unittest.cc +++ b/content/browser/frame_host/back_forward_cache_metrics_unittest.cc
@@ -47,27 +47,7 @@ std::vector<int64_t> navigation_ids_; }; -using UkmEntry = std::pair<ukm::SourceId, std::map<std::string, int64_t>>; - -std::vector<UkmEntry> GetMetrics(ukm::TestUkmRecorder* recorder, - std::string entry_name, - std::vector<std::string> metrics) { - std::vector<UkmEntry> results; - for (const ukm::mojom::UkmEntry* entry : - recorder->GetEntriesByName(entry_name)) { - UkmEntry result; - result.first = entry->source_id; - for (const std::string& metric_name : metrics) { - const int64_t* metric_value = - ukm::TestUkmRecorder::GetEntryMetric(entry, metric_name); - EXPECT_TRUE(metric_value) << "Metric " << metric_name - << " is not found in entry " << entry_name; - result.second[metric_name] = *metric_value; - } - results.push_back(std::move(result)); - } - return results; -} +using UkmEntry = ukm::TestUkmRecorder::HumanReadableUkmEntry; ukm::SourceId ToSourceId(int64_t navigation_id) { return ukm::ConvertToSourceId(navigation_id, @@ -108,8 +88,8 @@ std::string time_away = "TimeSinceNavigatedAwayFromDocument"; EXPECT_THAT( - GetMetrics(&recorder_, "HistoryNavigation", - {last_navigation_id, time_away}), + recorder_.GetEntries("HistoryNavigation", + {last_navigation_id, time_away}), testing::ElementsAre( UkmEntry{id4, {{last_navigation_id, id2}, {time_away, 0b100}}}, UkmEntry{id5, {{last_navigation_id, id1}, {time_away, 0b1110}}}, @@ -133,7 +113,7 @@ // The original interval of 5h + 50ms is clamped to just 5h. EXPECT_THAT( - GetMetrics(&recorder_, "HistoryNavigation", {time_away}), + recorder_.GetEntries("HistoryNavigation", {time_away}), testing::ElementsAre(UkmEntry{ id3, {{time_away, base::TimeDelta::FromHours(5).InMilliseconds()}}})); } @@ -178,7 +158,7 @@ std::string time_away = "TimeSinceNavigatedAwayFromDocument"; - EXPECT_THAT(GetMetrics(&recorder_, "HistoryNavigation", {time_away}), + EXPECT_THAT(recorder_.GetEntries("HistoryNavigation", {time_away}), testing::ElementsAre(UkmEntry{id3, {{time_away, 0b1000}}})); }
diff --git a/content/browser/frame_host/frame_tree_browsertest.cc b/content/browser/frame_host/frame_tree_browsertest.cc index 3feccf79..ec69e552 100644 --- a/content/browser/frame_host/frame_tree_browsertest.cc +++ b/content/browser/frame_host/frame_tree_browsertest.cc
@@ -30,6 +30,7 @@ #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "third_party/blink/public/common/frame/sandbox_flags.h" +#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h" #include "url/url_constants.h" namespace content { @@ -768,7 +769,7 @@ // Set the user activation bits. root->UpdateUserActivationState( - blink::UserActivationUpdateType::kNotifyActivation); + blink::mojom::UserActivationUpdateType::kNotifyActivation); EXPECT_TRUE(root->HasStickyUserActivation()); EXPECT_TRUE(root->HasTransientUserActivation()); @@ -1199,7 +1200,7 @@ // Set the user activation bits. root->UpdateUserActivationState( - blink::UserActivationUpdateType::kNotifyActivation); + blink::mojom::UserActivationUpdateType::kNotifyActivation); EXPECT_TRUE(root->HasStickyUserActivation()); EXPECT_TRUE(root->HasTransientUserActivation());
diff --git a/content/browser/frame_host/frame_tree_node.cc b/content/browser/frame_host/frame_tree_node.cc index 7f8ef70..330efb1 100644 --- a/content/browser/frame_host/frame_tree_node.cc +++ b/content/browser/frame_host/frame_tree_node.cc
@@ -30,7 +30,7 @@ #include "content/public/common/content_features.h" #include "content/public/common/navigation_policy.h" #include "third_party/blink/public/common/frame/sandbox_flags.h" -#include "third_party/blink/public/common/frame/user_activation_update_type.h" +#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h" namespace content { @@ -231,7 +231,8 @@ // This frame has had its user activation bits cleared in the renderer // before arriving here. We just need to clear them here and in the other // renderer processes that may have a reference to this frame. - UpdateUserActivationState(blink::UserActivationUpdateType::kClearActivation); + UpdateUserActivationState( + blink::mojom::UserActivationUpdateType::kClearActivation); } size_t FrameTreeNode::GetFrameTreeSize() const { @@ -620,20 +621,20 @@ } bool FrameTreeNode::UpdateUserActivationState( - blink::UserActivationUpdateType update_type) { + blink::mojom::UserActivationUpdateType update_type) { bool update_result = false; switch (update_type) { - case blink::UserActivationUpdateType::kConsumeTransientActivation: + case blink::mojom::UserActivationUpdateType::kConsumeTransientActivation: update_result = ConsumeTransientUserActivation(); break; - case blink::UserActivationUpdateType::kNotifyActivation: + case blink::mojom::UserActivationUpdateType::kNotifyActivation: update_result = NotifyUserActivation(); break; - case blink::UserActivationUpdateType:: + case blink::mojom::UserActivationUpdateType:: kNotifyActivationPendingBrowserVerification: if (VerifyUserActivation()) { update_result = NotifyUserActivation(); - update_type = blink::UserActivationUpdateType::kNotifyActivation; + update_type = blink::mojom::UserActivationUpdateType::kNotifyActivation; } else { // TODO(crbug.com/848778): We need to decide what to do when user // activation verification failed. NOTREACHED here will make all @@ -641,7 +642,7 @@ return false; } break; - case blink::UserActivationUpdateType::kClearActivation: + case blink::mojom::UserActivationUpdateType::kClearActivation: update_result = ClearUserActivation(); break; }
diff --git a/content/browser/frame_host/frame_tree_node.h b/content/browser/frame_host/frame_tree_node.h index 240d6e73..7d8054d7 100644 --- a/content/browser/frame_host/frame_tree_node.h +++ b/content/browser/frame_host/frame_tree_node.h
@@ -24,7 +24,7 @@ #include "third_party/blink/public/common/frame/frame_owner_element_type.h" #include "third_party/blink/public/common/frame/frame_policy.h" #include "third_party/blink/public/common/frame/user_activation_state.h" -#include "third_party/blink/public/common/frame/user_activation_update_type.h" +#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h" #include "third_party/blink/public/platform/web_insecure_request_policy.h" #include "url/gurl.h" #include "url/origin.h" @@ -328,7 +328,8 @@ // (which initiated the update). Returns |false| if the update tries to // consume an already consumed/expired transient state, |true| otherwise. See // the comment on user_activation_state_ below. - bool UpdateUserActivationState(blink::UserActivationUpdateType update_type); + bool UpdateUserActivationState( + blink::mojom::UserActivationUpdateType update_type); void OnSetHadStickyUserActivationBeforeNavigation(bool value);
diff --git a/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/content/browser/frame_host/navigation_controller_impl_browsertest.cc index 197ed434..44d3b89 100644 --- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc +++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
@@ -72,6 +72,7 @@ #include "net/test/embedded_test_server/http_request.h" #include "net/test/url_request/url_request_failed_job.h" #include "testing/gmock/include/gmock/gmock.h" +#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h" #include "third_party/blink/public/mojom/renderer_preferences.mojom.h" namespace content { @@ -9247,7 +9248,7 @@ // Simulate a user gesture. root->UpdateUserActivationState( - blink::UserActivationUpdateType::kNotifyActivation); + blink::mojom::UserActivationUpdateType::kNotifyActivation); // Since the last navigations refer to a different document, a user gesture // here should not reset the skippable bit in the previous entries. @@ -9613,7 +9614,7 @@ // A user gesture in the main frame now will lead to all same document // entries to be marked as non-skippable. root->UpdateUserActivationState( - blink::UserActivationUpdateType::kNotifyActivation); + blink::mojom::UserActivationUpdateType::kNotifyActivation); EXPECT_TRUE(root->HasStickyUserActivation()); EXPECT_TRUE(root->HasTransientUserActivation()); EXPECT_FALSE(controller.GetEntryAtIndex(0)->should_skip_on_back_forward_ui()); @@ -9648,7 +9649,7 @@ // user gesture will not lead to the last committed entry being marked as // skippable. root->UpdateUserActivationState( - blink::UserActivationUpdateType::kNotifyActivation); + blink::mojom::UserActivationUpdateType::kNotifyActivation); EXPECT_TRUE(root->HasStickyUserActivation()); EXPECT_TRUE(root->HasTransientUserActivation());
diff --git a/content/browser/frame_host/navigation_controller_impl_unittest.cc b/content/browser/frame_host/navigation_controller_impl_unittest.cc index da2431b..f9c41d03 100644 --- a/content/browser/frame_host/navigation_controller_impl_unittest.cc +++ b/content/browser/frame_host/navigation_controller_impl_unittest.cc
@@ -53,6 +53,7 @@ #include "skia/ext/platform_canvas.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/frame/frame_policy.h" +#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h" using base::Time; @@ -440,7 +441,7 @@ // Simulate a user gesture so that the above entry is not marked to be skipped // on back. main_test_rfh()->frame_tree_node()->UpdateUserActivationState( - blink::UserActivationUpdateType::kNotifyActivation); + blink::mojom::UserActivationUpdateType::kNotifyActivation); // Load another... controller.LoadURL(url2, Referrer(), ui::PAGE_TRANSITION_TYPED, @@ -869,7 +870,7 @@ // Simulate a user gesture so that the above entry is not marked to be skipped // on back. main_test_rfh()->frame_tree_node()->UpdateUserActivationState( - blink::UserActivationUpdateType::kNotifyActivation); + blink::mojom::UserActivationUpdateType::kNotifyActivation); const GURL kExistingURL2("http://foo/bee"); NavigationSimulator::NavigateAndCommitFromBrowser(contents(), kExistingURL2); @@ -924,7 +925,7 @@ // Simulate a user gesture so that the above entry is not marked to be skipped // on back. main_test_rfh()->frame_tree_node()->UpdateUserActivationState( - blink::UserActivationUpdateType::kNotifyActivation); + blink::mojom::UserActivationUpdateType::kNotifyActivation); // Navigate cross-process to a second URL. const GURL kExistingURL2("http://foo/eh"); @@ -1613,7 +1614,7 @@ // Simulate a user gesture so that the above entry is not marked to be skipped // on back. main_test_rfh()->frame_tree_node()->UpdateUserActivationState( - blink::UserActivationUpdateType::kNotifyActivation); + blink::mojom::UserActivationUpdateType::kNotifyActivation); // controller.LoadURL(kUrl2, ui::PAGE_TRANSITION_TYPED); NavigationSimulator::NavigateAndCommitFromDocument(kUrl2, main_test_rfh()); @@ -2211,7 +2212,7 @@ // Simulate a user gesture. main_test_rfh()->frame_tree_node()->UpdateUserActivationState( - blink::UserActivationUpdateType::kNotifyActivation); + blink::mojom::UserActivationUpdateType::kNotifyActivation); NavigationSimulator::NavigateAndCommitFromDocument(url2, main_test_rfh()); EXPECT_EQ(1U, navigation_entry_committed_counter_);
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 3d39aba..40a5113f 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -200,6 +200,7 @@ #include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom.h" #include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h" #include "third_party/blink/public/mojom/frame/fullscreen.mojom.h" +#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h" #include "third_party/blink/public/mojom/geolocation/geolocation_service.mojom.h" #include "third_party/blink/public/mojom/loader/pause_subresource_loading_handle.mojom.h" #include "third_party/blink/public/mojom/loader/url_loader_factory_bundle.mojom.h" @@ -1560,7 +1561,7 @@ // JavaScriptExecuteRequestsForTests call is redundant with this update. We // should determine if the redundancy can be removed. frame_tree_node()->UpdateUserActivationState( - blink::UserActivationUpdateType::kNotifyActivation); + blink::mojom::UserActivationUpdateType::kNotifyActivation); const bool has_user_gesture = true; GetNavigationControl()->JavaScriptExecuteRequestForTests( @@ -3540,8 +3541,7 @@ return; } - proxy->Send(new FrameMsg_SetNeedsOcclusionTracking(proxy->GetRoutingID(), - needs_tracking)); + proxy->GetAssociatedRemoteFrame()->SetNeedsOcclusionTracking(needs_tracking); } void RenderFrameHostImpl::LifecycleStateChanged( @@ -4083,7 +4083,7 @@ } void RenderFrameHostImpl::OnUpdateUserActivationState( - blink::UserActivationUpdateType update_type) { + blink::mojom::UserActivationUpdateType update_type) { if (!is_active()) return; frame_tree_node_->UpdateUserActivationState(update_type); @@ -4377,7 +4377,7 @@ // Consume activation even w/o User Activation v2, to sync other renderers // with calling renderer. was_consumed = frame_tree_node_->UpdateUserActivationState( - blink::UserActivationUpdateType::kConsumeTransientActivation); + blink::mojom::UserActivationUpdateType::kConsumeTransientActivation); } else { std::move(callback).Run(mojom::CreateNewWindowStatus::kIgnore, nullptr); return;
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index 71d0c1c7..e7148e9 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -82,7 +82,6 @@ #include "services/viz/public/mojom/hit_test/input_target_client.mojom.h" #include "third_party/blink/public/common/feature_policy/feature_policy.h" #include "third_party/blink/public/common/frame/frame_owner_element_type.h" -#include "third_party/blink/public/common/frame/user_activation_update_type.h" #include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom.h" #include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h" #include "third_party/blink/public/mojom/commit_result/commit_result.mojom.h" @@ -92,6 +91,7 @@ #include "third_party/blink/public/mojom/frame/find_in_page.mojom.h" #include "third_party/blink/public/mojom/frame/frame.mojom.h" #include "third_party/blink/public/mojom/frame/navigation_initiator.mojom.h" +#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h" #include "third_party/blink/public/mojom/idle/idle_manager.mojom.h" #include "third_party/blink/public/mojom/image_downloader/image_downloader.mojom.h" #include "third_party/blink/public/mojom/installedapp/installed_app_provider.mojom.h" @@ -1495,7 +1495,8 @@ const gfx::Range& range); void OnFocusedNodeChanged(bool is_editable_element, const gfx::Rect& bounds_in_frame_widget); - void OnUpdateUserActivationState(blink::UserActivationUpdateType update_type); + void OnUpdateUserActivationState( + blink::mojom::UserActivationUpdateType update_type); void OnSetNeedsOcclusionTracking(bool needs_tracking); void OnScrollRectToVisibleInParentFrame( const gfx::Rect& rect_to_scroll,
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc index e02f5ed..c898d24 100644 --- a/content/browser/frame_host/render_frame_host_manager.cc +++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -58,6 +58,7 @@ #include "content/public/common/referrer.h" #include "content/public/common/url_constants.h" #include "content/public/common/url_utils.h" +#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h" #if defined(OS_MACOSX) #include "ui/gfx/mac/scoped_cocoa_disable_screen_updates.h" @@ -1022,7 +1023,7 @@ } void RenderFrameHostManager::UpdateUserActivationState( - blink::UserActivationUpdateType update_type) { + blink::mojom::UserActivationUpdateType update_type) { for (const auto& pair : proxy_hosts_) { pair.second->Send(new FrameMsg_UpdateUserActivationState( pair.second->GetRoutingID(), update_type)); @@ -1040,7 +1041,8 @@ ->render_manager() ->GetProxyToOuterDelegate(); if (outer_delegate_proxy && - update_type == blink::UserActivationUpdateType::kNotifyActivation) { + update_type == + blink::mojom::UserActivationUpdateType::kNotifyActivation) { outer_delegate_proxy->Send(new FrameMsg_UpdateUserActivationState( outer_delegate_proxy->GetRoutingID(), update_type)); GetOuterDelegateNode()->UpdateUserActivationState(update_type);
diff --git a/content/browser/frame_host/render_frame_host_manager.h b/content/browser/frame_host/render_frame_host_manager.h index a077627..5debc67 100644 --- a/content/browser/frame_host/render_frame_host_manager.h +++ b/content/browser/frame_host/render_frame_host_manager.h
@@ -24,7 +24,7 @@ #include "content/public/browser/global_request_id.h" #include "content/public/common/referrer.h" #include "services/network/public/mojom/content_security_policy.mojom-forward.h" -#include "third_party/blink/public/common/frame/user_activation_update_type.h" +#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h" #include "ui/base/page_transition_types.h" #include "url/origin.h" @@ -454,7 +454,8 @@ // Updates the user activation state in all proxies of this frame. For // more details, see the comment on FrameTreeNode::user_activation_state_. - void UpdateUserActivationState(blink::UserActivationUpdateType update_type); + void UpdateUserActivationState( + blink::mojom::UserActivationUpdateType update_type); // When a frame transfers user activation to another frame via postMessage, // this is used to inform proxies of the target frame (via IPC) about the
diff --git a/content/browser/initiator_csp_context.cc b/content/browser/initiator_csp_context.cc index 4e3b56a..adc9b7bb 100644 --- a/content/browser/initiator_csp_context.cc +++ b/content/browser/initiator_csp_context.cc
@@ -33,9 +33,7 @@ violation_params.directive, violation_params.effective_directive, violation_params.console_message, violation_params.blocked_url.spec(), violation_params.report_endpoints, violation_params.use_reporting_api, - violation_params.header, - (blink::mojom::WebContentSecurityPolicyType) - violation_params.disposition, + violation_params.header, violation_params.disposition, violation_params.after_redirect, blink::mojom::SourceLocation::New( violation_params.source_location.url,
diff --git a/content/browser/renderer_host/clipboard_host_impl.cc b/content/browser/renderer_host/clipboard_host_impl.cc index 33b88796..93411f5 100644 --- a/content/browser/renderer_host/clipboard_host_impl.cc +++ b/content/browser/renderer_host/clipboard_host_impl.cc
@@ -69,11 +69,12 @@ bool result = false; switch (format) { case blink::mojom::ClipboardFormat::kPlaintext: - result = - clipboard_->IsFormatAvailable( - ui::ClipboardFormatType::GetPlainTextWType(), clipboard_buffer) || - clipboard_->IsFormatAvailable( - ui::ClipboardFormatType::GetPlainTextType(), clipboard_buffer); + result = clipboard_->IsFormatAvailable( + ui::ClipboardFormatType::GetPlainTextType(), clipboard_buffer); +#if defined(OS_WIN) + result |= clipboard_->IsFormatAvailable( + ui::ClipboardFormatType::GetPlainTextAType(), clipboard_buffer); +#endif break; case blink::mojom::ClipboardFormat::kHtml: result = clipboard_->IsFormatAvailable( @@ -86,7 +87,7 @@ case blink::mojom::ClipboardFormat::kBookmark: #if defined(OS_WIN) || defined(OS_MACOSX) result = clipboard_->IsFormatAvailable( - ui::ClipboardFormatType::GetUrlWType(), clipboard_buffer); + ui::ClipboardFormatType::GetUrlType(), clipboard_buffer); #else result = false; #endif @@ -98,15 +99,18 @@ void ClipboardHostImpl::ReadText(ui::ClipboardBuffer clipboard_buffer, ReadTextCallback callback) { base::string16 result; - if (clipboard_->IsFormatAvailable( - ui::ClipboardFormatType::GetPlainTextWType(), clipboard_buffer)) { + if (clipboard_->IsFormatAvailable(ui::ClipboardFormatType::GetPlainTextType(), + clipboard_buffer)) { clipboard_->ReadText(clipboard_buffer, &result); - } else if (clipboard_->IsFormatAvailable( - ui::ClipboardFormatType::GetPlainTextType(), - clipboard_buffer)) { - std::string ascii; - clipboard_->ReadAsciiText(clipboard_buffer, &ascii); - result = base::ASCIIToUTF16(ascii); + } else { +#if defined(OS_WIN) + if (clipboard_->IsFormatAvailable( + ui::ClipboardFormatType::GetPlainTextAType(), clipboard_buffer)) { + std::string ascii; + clipboard_->ReadAsciiText(clipboard_buffer, &ascii); + result = base::ASCIIToUTF16(ascii); + } +#endif } std::move(callback).Run(result); }
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc index a98630e..eb66b1ac 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -1243,12 +1243,14 @@ // Focused segment composition_text.ime_text_spans.push_back( ui::ImeTextSpan(ui::ImeTextSpan::Type::kComposition, 0, 3, - ui::ImeTextSpan::Thickness::kThick, 0x78563412)); + ui::ImeTextSpan::Thickness::kThick, + ui::ImeTextSpan::UnderlineStyle::kSolid, 0x78563412)); // Non-focused segment, with different background color. composition_text.ime_text_spans.push_back( ui::ImeTextSpan(ui::ImeTextSpan::Type::kComposition, 3, 4, - ui::ImeTextSpan::Thickness::kThin, 0xefcdab90)); + ui::ImeTextSpan::Thickness::kThin, + ui::ImeTextSpan::UnderlineStyle::kSolid, 0xefcdab90)); const ui::ImeTextSpans& ime_text_spans = composition_text.ime_text_spans; @@ -1301,12 +1303,14 @@ // Focused segment composition_text.ime_text_spans.push_back( ui::ImeTextSpan(ui::ImeTextSpan::Type::kComposition, 0, 3, - ui::ImeTextSpan::Thickness::kThick, 0x78563412)); + ui::ImeTextSpan::Thickness::kThick, + ui::ImeTextSpan::UnderlineStyle::kSolid, 0x78563412)); // Non-focused segment, with different background color. composition_text.ime_text_spans.push_back( ui::ImeTextSpan(ui::ImeTextSpan::Type::kComposition, 3, 4, - ui::ImeTextSpan::Thickness::kThin, 0xefcdab90)); + ui::ImeTextSpan::Thickness::kThin, + ui::ImeTextSpan::UnderlineStyle::kSolid, 0xefcdab90)); // Caret is at the end. (This emulates Japanese MSIME 2007 and later) composition_text.selection = gfx::Range(4);
diff --git a/content/browser/resources/appcache/appcache_internals.js b/content/browser/resources/appcache/appcache_internals.js index 66a81e7a..4933f5b 100644 --- a/content/browser/resources/appcache/appcache_internals.js +++ b/content/browser/resources/appcache/appcache_internals.js
@@ -43,7 +43,7 @@ function getItemByProperties(list, properties, values) { return list.find(function(candidate) { return properties.every(function(key, i) { - return candidate[key] == values[i]; + return candidate[key] === values[i]; }); }) || null; @@ -54,7 +54,7 @@ while (pos < list.length) { const candidate = list[pos]; if (properties.every(function(key) { - return candidate[key] == item[key]; + return candidate[key] === item[key]; })) { list.splice(pos, 1); } else {
diff --git a/content/browser/resources/gpu/browser_bridge.js b/content/browser/resources/gpu/browser_bridge.js index 6b01029..4fe53ca 100644 --- a/content/browser/resources/gpu/browser_bridge.js +++ b/content/browser/resources/gpu/browser_bridge.js
@@ -124,7 +124,7 @@ this.callAsync( 'requestLogMessages', undefined, (function(messages) { - if (messages.length != this.logMessages_.length) { + if (messages.length !== this.logMessages_.length) { this.logMessages_ = messages; cr.dispatchSimpleEvent(this, 'logMessagesChange'); } @@ -146,7 +146,7 @@ isSandboxedForTesting() { for (i = 0; i < this.gpuInfo_.basicInfo.length; ++i) { const info = this.gpuInfo_.basicInfo[i]; - if (info.description == 'Sandboxed') { + if (info.description === 'Sandboxed') { return info.value; } }
diff --git a/content/browser/resources/gpu/info_view.js b/content/browser/resources/gpu/info_view.js index 53a968f5..43a41ab 100644 --- a/content/browser/resources/gpu/info_view.js +++ b/content/browser/resources/gpu/info_view.js
@@ -390,9 +390,9 @@ problemEl.appendChild(iNode); const headNode = document.createElement('span'); - if (problem.tag == 'disabledFeatures') { + if (problem.tag === 'disabledFeatures') { headNode.textContent = 'Disabled Features: '; - } else { // problem.tag == 'workarounds' + } else { // problem.tag === 'workarounds' headNode.textContent = 'Applied Workarounds: '; } iNode.appendChild(headNode); @@ -403,9 +403,9 @@ iNode.appendChild(separateNode); } const nameNode = document.createElement('span'); - if (problem.tag == 'disabledFeatures') { + if (problem.tag === 'disabledFeatures') { nameNode.classList.add('feature-red'); - } else { // problem.tag == 'workarounds' + } else { // problem.tag === 'workarounds' nameNode.classList.add('feature-yellow'); } nameNode.textContent = problem.affectedGpuSettings[j]; @@ -459,7 +459,7 @@ ANGLEFeatureEl.appendChild(separator); const status = document.createElement('span'); - if (ANGLEFeature.status == 'enabled') { + if (ANGLEFeature.status === 'enabled') { status.textContent = 'Enabled'; status.classList.add('feature-green'); } else {
diff --git a/content/browser/resources/indexed_db/indexeddb_internals.js b/content/browser/resources/indexed_db/indexeddb_internals.js index 6fcf000..8e63c36 100644 --- a/content/browser/resources/indexed_db/indexeddb_internals.js +++ b/content/browser/resources/indexed_db/indexeddb_internals.js
@@ -32,8 +32,8 @@ const links = document.querySelectorAll(selector); for (let i = 0; i < links.length; ++i) { const link = links[i]; - if (partition_path == link.idb_partition_path && - origin_url == link.idb_origin_url) { + if (partition_path === link.idb_partition_path && + origin_url === link.idb_origin_url) { callback(link); } }
diff --git a/content/browser/resources/media/client_renderer.js b/content/browser/resources/media/client_renderer.js index dad0ef4..369cc625 100644 --- a/content/browser/resources/media/client_renderer.js +++ b/content/browser/resources/media/client_renderer.js
@@ -148,7 +148,7 @@ this.redrawAudioComponentList_(componentType, components); // Redraw the component if it's currently selected. - if (this.selectedAudioComponentType == componentType && + if (this.selectedAudioComponentType === componentType && this.selectedAudioComponentId && this.selectedAudioComponentId in components) { // TODO(chcunningham): This path is used both for adding and updating @@ -232,7 +232,7 @@ }, createVideoCaptureFormatTable: function(formats) { - if (!formats || formats.length == 0) { + if (!formats || formats.length === 0) { return document.createTextNode('No formats'); } @@ -277,11 +277,11 @@ var value = device[keys[i]]; var tableCell = document.createElement('td'); var cellElement; - if ((typeof value) == (typeof[])) { + if ((typeof value) === (typeof[])) { cellElement = this.createVideoCaptureFormatTable(value); } else { cellElement = document.createTextNode( - ((typeof value) == 'undefined') ? 'n/a' : value); + ((typeof value) === 'undefined') ? 'n/a' : value); } tableCell.appendChild(cellElement); tableRow.appendChild(tableCell); @@ -356,7 +356,7 @@ listElement.appendChild(fragment); if (this.selectedAudioComponentType && - this.selectedAudioComponentType == componentType && + this.selectedAudioComponentType === componentType && this.selectedAudioComponentId in components) { // Re-select the selected component since the button was just recreated. selectSelectableButton(this.selectedAudioComponentId); @@ -563,7 +563,7 @@ this.filterFunction = function(text) { text = text.toLowerCase(); return parts.length === 0 || parts.some(function(part) { - return text.indexOf(part) != -1; + return text.indexOf(part) !== -1; }); };
diff --git a/content/browser/resources/media/data_series.js b/content/browser/resources/media/data_series.js index 83e714b..dd0da7a 100644 --- a/content/browser/resources/media/data_series.js +++ b/content/browser/resources/media/data_series.js
@@ -88,9 +88,9 @@ */ getValues: function(startTime, stepSize, count) { // Use cached values, if we can. - if (this.cacheStartTime_ == startTime && - this.cacheStepSize_ == stepSize && - this.cacheValues_.length == count) { + if (this.cacheStartTime_ === startTime && + this.cacheStepSize_ === stepSize && + this.cacheValues_.length === count) { return this.cacheValues_; }
diff --git a/content/browser/resources/media/manager.js b/content/browser/resources/media/manager.js index 5d9e38c..c83409d 100644 --- a/content/browser/resources/media/manager.js +++ b/content/browser/resources/media/manager.js
@@ -177,8 +177,8 @@ var formatDict = {}; for (var i in parts) { var kv = parts[i].split(': '); - if (kv.length == 2) { - if (kv[0] == 'pixel format') { + if (kv.length === 2) { + if (kv[0] === 'pixel format') { // The camera does not actually output I420, // so this info is misleading. continue; @@ -186,7 +186,7 @@ formatDict[kv[0]] = kv[1]; } else { kv = parts[i].split('@'); - if (kv.length == 2) { + if (kv.length === 2) { formatDict['resolution'] = kv[0].replace(/[)(]/g, ''); // Round down the FPS to 2 decimals. formatDict['fps'] =
diff --git a/content/browser/resources/media/peer_connection_update_table.js b/content/browser/resources/media/peer_connection_update_table.js index 7f9804a..ec30a97 100644 --- a/content/browser/resources/media/peer_connection_update_table.js +++ b/content/browser/resources/media/peer_connection_update_table.js
@@ -97,7 +97,7 @@ }[update.type] || update.type; - if (update.value.length == 0) { + if (update.value.length === 0) { row.innerHTML += '<td>' + type + '</td>'; return; }
diff --git a/content/browser/resources/media/ssrc_info_manager.js b/content/browser/resources/media/ssrc_info_manager.js index a3038de..39a05d68 100644 --- a/content/browser/resources/media/ssrc_info_manager.js +++ b/content/browser/resources/media/ssrc_info_manager.js
@@ -14,7 +14,7 @@ * @return {?string} The ssrc. */ function GetSsrcFromReport(report) { - if (report.type != 'ssrc') { + if (report.type !== 'ssrc') { console.warn('Trying to get ssrc from non-ssrc report.'); return null; } @@ -28,7 +28,7 @@ // to Chrome. if (report.stats && report.stats.values) { for (var i = 0; i < report.stats.values.length - 1; i += 2) { - if (report.stats.values[i] == 'ssrc') { + if (report.stats.values[i] === 'ssrc') { return report.stats.values[i + 1]; } } @@ -98,13 +98,13 @@ var attributes = sdp.split(this.ATTRIBUTE_SEPARATOR_); for (var i = 0; i < attributes.length; ++i) { // Check if this is a ssrc attribute. - if (attributes[i].indexOf(this.SSRC_ATTRIBUTE_PREFIX_) != 0) { + if (attributes[i].indexOf(this.SSRC_ATTRIBUTE_PREFIX_) !== 0) { continue; } var nextFieldIndex = attributes[i].search(this.FIELD_SEPARATOR_REGEX_); - if (nextFieldIndex == -1) { + if (nextFieldIndex === -1) { continue; } @@ -119,7 +119,7 @@ var name, value; while (rest.length > 0) { nextFieldIndex = rest.search(this.FIELD_SEPARATOR_REGEX_); - if (nextFieldIndex == -1) { + if (nextFieldIndex === -1) { nextFieldIndex = rest.length; }
diff --git a/content/browser/resources/media/stats_graph_helper.js b/content/browser/resources/media/stats_graph_helper.js index 46271ff3..ac31f4a49 100644 --- a/content/browser/resources/media/stats_graph_helper.js +++ b/content/browser/resources/media/stats_graph_helper.js
@@ -100,23 +100,23 @@ function isStandardReportBlacklisted(report) { // Codec stats reflect what has been negotiated. There are LOTS of them and // they don't change over time on their own. - if (report.type == 'codec') { + if (report.type === 'codec') { return true; } // Unused data channels can stay in "connecting" indefinitely and their // counters stay zero. - if (report.type == 'data-channel' && - readReportStat(report, 'state') == 'connecting') { + if (report.type === 'data-channel' && + readReportStat(report, 'state') === 'connecting') { return true; } // The same is true for transports and "new". - if (report.type == 'transport' && - readReportStat(report, 'dtlsState') == 'new') { + if (report.type === 'transport' && + readReportStat(report, 'dtlsState') === 'new') { return true; } // Local and remote candidates don't change over time and there are several of // them. - if (report.type == 'local-candidate' || report.type == 'remote-candidate') { + if (report.type === 'local-candidate' || report.type === 'remote-candidate') { return true; } return false; @@ -125,7 +125,7 @@ function readReportStat(report, stat) { let values = report.stats.values; for (let i = 0; i < values.length; i += 2) { - if (values[i] == stat) { + if (values[i] === stat) { return values[i + 1]; } } @@ -135,11 +135,11 @@ function isStandardStatBlacklisted(report, statName) { // The datachannelid is an identifier, but because it is a number it shows up // as a graph if we don't blacklist it. - if (report.type == 'data-channel' && statName == 'datachannelid') { + if (report.type === 'data-channel' && statName === 'datachannelid') { return true; } // The priority does not change over time on its own; plotting uninteresting. - if (report.type == 'candidate-pair' && statName == 'priority') { + if (report.type === 'candidate-pair' && statName === 'priority') { return true; } return false; @@ -176,7 +176,7 @@ for (var i = 0; i < stats.values.length - 1; i = i + 2) { var rawLabel = stats.values[i]; // Propagation deltas are handled separately. - if (rawLabel == RECEIVED_PROPAGATION_DELTA_LABEL) { + if (rawLabel === RECEIVED_PROPAGATION_DELTA_LABEL) { drawReceivedPropagationDelta( peerConnectionElement, report, stats.values[i + 1]); continue; @@ -310,7 +310,7 @@ var times = null; // Find the packet group arrival times. for (var i = 0; i < stats.values.length - 1; i = i + 2) { - if (stats.values[i] == RECEIVED_PACKET_GROUP_ARRIVAL_TIME_LABEL) { + if (stats.values[i] === RECEIVED_PACKET_GROUP_ARRIVAL_TIME_LABEL) { times = stats.values[i + 1]; break; } @@ -355,20 +355,20 @@ // can be deduced from existing stats labels. Otherwise empty string for // non-SSRC reports or where type (audio/video) can't be deduced. function getSsrcReportType(report) { - if (report.type != 'ssrc') { + if (report.type !== 'ssrc') { return ''; } if (report.stats && report.stats.values) { // Known stats keys for audio send/receive streams. - if (report.stats.values.indexOf('audioOutputLevel') != -1 || - report.stats.values.indexOf('audioInputLevel') != -1) { + if (report.stats.values.indexOf('audioOutputLevel') !== -1 || + report.stats.values.indexOf('audioInputLevel') !== -1) { return 'audio'; } // Known stats keys for video send/receive streams. // TODO(pbos): Change to use some non-goog-prefixed stats when available for // video. - if (report.stats.values.indexOf('googFrameRateReceived') != -1 || - report.stats.values.indexOf('googFrameRateSent') != -1) { + if (report.stats.values.indexOf('googFrameRateReceived') !== -1 || + report.stats.values.indexOf('googFrameRateSent') !== -1) { return 'video'; } } @@ -393,11 +393,11 @@ container.firstChild.firstChild.textContent = 'Stats graphs for ' + report.id + ' (' + report.type + ')'; var statsType = getSsrcReportType(report); - if (statsType != '') { + if (statsType !== '') { container.firstChild.firstChild.textContent += ' (' + statsType + ')'; } - if (report.type == 'ssrc') { + if (report.type === 'ssrc') { var ssrcInfoElement = document.createElement('div'); container.firstChild.appendChild(ssrcInfoElement); ssrcInfoManager.populateSsrcInfo( @@ -423,7 +423,7 @@ topContainer.appendChild(container); container.innerHTML = '<div>' + statsName + '</div>' + '<div id=' + divId + '><canvas id=' + canvasId + '></canvas></div>'; - if (statsName == 'bweCompound') { + if (statsName === 'bweCompound') { container.insertBefore( createBweCompoundLegend(peerConnectionElement, report.id), $(divId)); }
diff --git a/content/browser/resources/media/stats_rates_calculator.js b/content/browser/resources/media/stats_rates_calculator.js index 8bb19f1..def2444a 100644 --- a/content/browser/resources/media/stats_rates_calculator.js +++ b/content/browser/resources/media/stats_rates_calculator.js
@@ -135,8 +135,8 @@ } }; Object.keys(stats).forEach(metricName => { - if (metricName == 'id' || metricName == 'type' || - metricName == 'timestamp') { + if (metricName === 'id' || metricName === 'type' || + metricName === 'timestamp') { return; // continue; } internalReport.stats.values.push(metricName); @@ -159,14 +159,14 @@ toString() { let str = ''; for (let stats of this.statsById.values()) { - if (str != '') { + if (str !== '') { str += ','; } str += JSON.stringify(stats); } let str2 = ''; for (let stats of this.calculatedStatsById.values()) { - if (str2 != '') { + if (str2 !== '') { str2 += ','; } str2 += stats.toString(); @@ -181,7 +181,7 @@ getByType(type) { const result = []; for (let stats of this.statsById.values()) { - if (stats.type == type) { + if (stats.type === type) { result.push(stats); } } @@ -221,7 +221,7 @@ const accumulativeMetric = this.modifier.bitrate ? this.accumulativeMetric + '_in_bits' : this.accumulativeMetric; - if (this.samplesMetric == 'timestamp') { + if (this.samplesMetric === 'timestamp') { return '[' + accumulativeMetric + '/s]'; } return '[' + accumulativeMetric + '/' + this.samplesMetric + @@ -254,13 +254,13 @@ // int64, uint64 and double) are passed as strings. const previousValue = Number(previousStats[accumulativeMetric]); const currentValue = Number(currentStats[accumulativeMetric]); - if (typeof previousValue != 'number' || typeof currentValue != 'number') { + if (typeof previousValue !== 'number' || typeof currentValue !== 'number') { return undefined; } const previousSamples = Number(previousStats[samplesMetric]); const currentSamples = Number(currentStats[samplesMetric]); - if (typeof previousSamples != 'number' || - typeof currentSamples != 'number') { + if (typeof previousSamples !== 'number' || + typeof currentSamples !== 'number') { return undefined; } const deltaValue = currentValue - previousValue; @@ -365,14 +365,14 @@ const previousSquaredSumValue = Number(previousStats[totalSquaredSumMetric]); const currentSquaredSumValue = Number(currentStats[totalSquaredSumMetric]); - if (typeof previousSquaredSumValue != 'number' || - typeof currentSquaredSumValue != 'number') { + if (typeof previousSquaredSumValue !== 'number' || + typeof currentSquaredSumValue !== 'number') { return undefined; } const previousSumValue = Number(previousStats[totalSumMetric]); const currentSumValue = Number(currentStats[totalSumMetric]); - if (typeof previousSumValue != 'number' || - typeof currentSumValue != 'number') { + if (typeof previousSumValue !== 'number' || + typeof currentSumValue !== 'number') { return undefined; }
diff --git a/content/browser/resources/media/stats_table.js b/content/browser/resources/media/stats_table.js index ee1e22c21..4bf82af 100644 --- a/content/browser/resources/media/stats_table.js +++ b/content/browser/resources/media/stats_table.js
@@ -33,7 +33,7 @@ * the value. */ addStatsReport: function(peerConnectionElement, report) { - if (report.type == 'codec') { + if (report.type === 'codec') { return; } var statsTable = this.ensureStatsTable_(peerConnectionElement, report); @@ -107,7 +107,7 @@ table.innerHTML = '<tr><th colspan=2></th></tr>'; table.rows[0].cells[0].textContent = 'Statistics ' + report.id; - if (report.type == 'ssrc') { + if (report.type === 'ssrc') { table.insertRow(1); table.rows[1].innerHTML = '<td colspan=2></td>'; this.ssrcInfoManager_.populateSsrcInfo( @@ -155,7 +155,7 @@ trElement.cells[1].textContent = value; // Highlights the table for the active connection. - if (rowName == 'googActiveConnection') { + if (rowName === 'googActiveConnection') { if (value === true) { statsTable.parentElement.classList.add(activeConnectionClass); } else {
diff --git a/content/browser/resources/media/tab_view.js b/content/browser/resources/media/tab_view.js index b68b8f2..9b20ae9 100644 --- a/content/browser/resources/media/tab_view.js +++ b/content/browser/resources/media/tab_view.js
@@ -82,7 +82,7 @@ this.tabElements_[id].body); delete this.tabElements_[id]; - if (this.activeTabId_ == id) { + if (this.activeTabId_ === id) { this.switchTab_(Object.keys(this.tabElements_)[0]); } },
diff --git a/content/browser/resources/media/timeline_graph_view.js b/content/browser/resources/media/timeline_graph_view.js index 186957c..3e16c9c 100644 --- a/content/browser/resources/media/timeline_graph_view.js +++ b/content/browser/resources/media/timeline_graph_view.js
@@ -72,7 +72,7 @@ * Returns true if the graph is scrolled all the way to the right. */ graphScrolledToRightEdge_: function() { - return this.scrollbar_.position_ == this.scrollbar_.range_; + return this.scrollbar_.position_ === this.scrollbar_.range_; }, /** @@ -176,7 +176,7 @@ var fontHeight = parseInt(fontHeightString); // Safety check, to avoid drawing anything too ugly. - if (fontHeightString.length == 0 || fontHeight <= 0 || + if (fontHeightString.length === 0 || fontHeight <= 0 || fontHeight * 4 > height || width < 50) { return; } @@ -193,7 +193,7 @@ var position = this.scrollbar_.position_; // If the entire time range is being displayed, align the right edge of // the graph to the end of the time range. - if (this.scrollbar_.range_ == 0) { + if (this.scrollbar_.range_ === 0) { position = this.getLength_() - this.canvas_.width; } var visibleStartTime = this.startTime_ + position * this.scale_; @@ -318,7 +318,7 @@ hasDataSeries: function(dataSeries) { for (var i = 0; i < this.dataSeries_.length; ++i) { - if (this.dataSeries_[i] == dataSeries) { + if (this.dataSeries_[i] === dataSeries) { return true; } } @@ -414,7 +414,7 @@ this.labels_ = []; var range = maxValue - minValue; // No labels if the range is 0. - if (range == 0) { + if (range === 0) { this.min_ = this.max_ = maxValue; return; } @@ -533,7 +533,7 @@ * Draw labels in |labels_|. */ drawLabels: function(context) { - if (this.labels_.length == 0) { + if (this.labels_.length === 0) { return; } var x = this.width_ - LABEL_HORIZONTAL_SPACING;
diff --git a/content/browser/resources/process/process_internals.js b/content/browser/resources/process/process_internals.js index ab50e60..9a669c3 100644 --- a/content/browser/resources/process/process_internals.js +++ b/content/browser/resources/process/process_internals.js
@@ -22,7 +22,7 @@ for (let i = 0; i < tabContents.length; i++) { const tabContent = tabContents[i]; const tabHeader = tabHeaders[i]; - const isTargetTab = tabContent.id == id; + const isTargetTab = tabContent.id === id; found = found || isTargetTab; tabContent.classList.toggle('selected', isTargetTab);
diff --git a/content/browser/resources/service_worker/serviceworker_internals.js b/content/browser/resources/service_worker/serviceworker_internals.js index 626f37f..47a54ef 100644 --- a/content/browser/resources/service_worker/serviceworker_internals.js +++ b/content/browser/resources/service_worker/serviceworker_internals.js
@@ -96,8 +96,8 @@ const logAreas = container.querySelectorAll('textarea.serviceworker-log'); for (let i = 0; i < logAreas.length; ++i) { const logArea = logAreas[i]; - if (logArea.partition_id == partition_id && - logArea.version_id == version.version_id) { + if (logArea.partition_id === partition_id && + logArea.version_id === version.version_id) { logArea.value = version.log; } } @@ -154,7 +154,7 @@ // the UI to be updated in-place rather than refreshing the // whole page. for (let i = 0; i < container.childNodes.length; ++i) { - if (container.childNodes[i].partition_id == partition_id) { + if (container.childNodes[i].partition_id === partition_id) { template = container.childNodes[i]; } } @@ -233,8 +233,8 @@ const logAreas = document.querySelectorAll('textarea.serviceworker-log'); for (let i = 0; i < logAreas.length; ++i) { const logArea = logAreas[i]; - if (logArea.partition_id == partition_id && - logArea.version_id == version_id) { + if (logArea.partition_id === partition_id && + logArea.version_id === version_id) { logArea.value += message; } }
diff --git a/content/browser/service_worker/service_worker_job_unittest.cc b/content/browser/service_worker/service_worker_job_unittest.cc index 9c98474..07afe433 100644 --- a/content/browser/service_worker/service_worker_job_unittest.cc +++ b/content/browser/service_worker/service_worker_job_unittest.cc
@@ -43,6 +43,7 @@ #include "net/base/net_errors.h" #include "net/base/test_completion_callback.h" #include "net/http/http_response_headers.h" +#include "services/network/public/cpp/features.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h" @@ -1970,6 +1971,109 @@ runner->RunUntilIdle(); } +class ServiceWorkerUpdateJobTestWithCrossOriginIsolation + : public ServiceWorkerUpdateJobTest { + public: + ServiceWorkerUpdateJobTestWithCrossOriginIsolation() { + feature_list_.InitAndEnableFeature( + ::network::features::kCrossOriginIsolation); + } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +// Update job should handle the COEP header appropriately. +TEST_F(ServiceWorkerUpdateJobTestWithCrossOriginIsolation, + Update_CrossOriginEmbedderPolicy) { + const char kHeadersWithRequireCorp[] = R"(HTTP/1.1 200 OK +Content-Type: application/javascript +Cross-Origin-Embedder-Policy: require-corp + +)"; + const char kHeadersWithNone[] = R"(HTTP/1.1 200 OK +Content-Type: application/javascript +Cross-Origin-Embedder-Policy: none + +)"; + + const base::Time kToday = base::Time::Now(); + const base::Time kYesterday = + kToday - base::TimeDelta::FromDays(1) - base::TimeDelta::FromHours(1); + + scoped_refptr<ServiceWorkerRegistration> registration = + update_helper_->SetupInitialRegistration(kNewVersionOrigin); + ASSERT_TRUE(registration.get()); + EXPECT_EQ(network::mojom::CrossOriginEmbedderPolicy::kNone, + registration->active_version()->cross_origin_embedder_policy()); + + registration->AddListener(update_helper_); + + // Run an update where the response header is updated but the script did not + // change. No update is found but the last update check time is updated. + update_helper_->fake_network_.SetResponse(kNewVersionOrigin.Resolve(kScript), + kHeadersWithRequireCorp, kBody, + /*network_accessed=*/true, net::OK); + + { + base::HistogramTester histogram_tester; + registration->set_last_update_check(kYesterday); + registration->active_version()->StartUpdate(); + base::RunLoop().RunUntilIdle(); + EXPECT_LT(kYesterday, registration->last_update_check()); + EXPECT_FALSE(update_helper_->update_found_); + + // Update check succeeds but no update is found. + histogram_tester.ExpectBucketCount("ServiceWorker.UpdateCheck.Result", + blink::ServiceWorkerStatusCode::kOk, 1); + histogram_tester.ExpectBucketCount("ServiceWorker.UpdateCheck.UpdateFound", + false, 1); + } + + // Run an update where the COEP value and the script changed. + update_helper_->fake_network_.SetResponse(kNewVersionOrigin.Resolve(kScript), + kHeadersWithRequireCorp, kNewBody, + /*network_accessed=*/true, net::OK); + { + base::HistogramTester histogram_tester; + registration->set_last_update_check(kYesterday); + registration->active_version()->StartUpdate(); + base::RunLoop().RunUntilIdle(); + EXPECT_LT(kYesterday, registration->last_update_check()); + EXPECT_TRUE(update_helper_->update_found_); + // Update check succeeds and update is found. + histogram_tester.ExpectBucketCount("ServiceWorker.UpdateCheck.Result", + blink::ServiceWorkerStatusCode::kOk, 1); + histogram_tester.ExpectBucketCount("ServiceWorker.UpdateCheck.UpdateFound", + true, 1); + ASSERT_NE(nullptr, registration->waiting_version()); + EXPECT_EQ(network::mojom::CrossOriginEmbedderPolicy::kRequireCorp, + registration->waiting_version()->cross_origin_embedder_policy()); + } + + // Run an update again where the COEP value and the body has been updated. The + // COEP value should be updated appropriately. + update_helper_->fake_network_.SetResponse(kNewVersionOrigin.Resolve(kScript), + kHeadersWithNone, kBody, + /*network_accessed=*/true, net::OK); + { + base::HistogramTester histogram_tester; + registration->set_last_update_check(kYesterday); + registration->active_version()->StartUpdate(); + base::RunLoop().RunUntilIdle(); + EXPECT_LT(kYesterday, registration->last_update_check()); + EXPECT_TRUE(update_helper_->update_found_); + // Update check succeeds and update is found. + histogram_tester.ExpectBucketCount("ServiceWorker.UpdateCheck.Result", + blink::ServiceWorkerStatusCode::kOk, 1); + histogram_tester.ExpectBucketCount("ServiceWorker.UpdateCheck.UpdateFound", + true, 1); + ASSERT_NE(nullptr, registration->waiting_version()); + EXPECT_EQ(network::mojom::CrossOriginEmbedderPolicy::kNone, + registration->waiting_version()->cross_origin_embedder_policy()); + } +} + class WaitForeverInstallWorker : public FakeServiceWorker { public: WaitForeverInstallWorker(EmbeddedWorkerTestHelper* helper)
diff --git a/content/browser/service_worker/service_worker_new_script_loader.cc b/content/browser/service_worker/service_worker_new_script_loader.cc index 2e09c770..74cc5e0 100644 --- a/content/browser/service_worker/service_worker_new_script_loader.cc +++ b/content/browser/service_worker/service_worker_new_script_loader.cc
@@ -225,6 +225,9 @@ return; } + version_->set_cross_origin_embedder_policy( + response_head->cross_origin_embedder_policy); + if (response_head->network_accessed) version_->embedded_worker()->OnNetworkAccessedForScriptLoad();
diff --git a/content/browser/service_worker/service_worker_register_job.cc b/content/browser/service_worker/service_worker_register_job.cc index a6add92..706a8beb 100644 --- a/content/browser/service_worker/service_worker_register_job.cc +++ b/content/browser/service_worker/service_worker_register_job.cc
@@ -513,8 +513,10 @@ if (update_checker_) { DCHECK(blink::ServiceWorkerUtils::IsImportedScriptUpdateCheckEnabled()); - new_version()->PrepareForUpdate(update_checker_->TakeComparedResults(), - update_checker_->updated_script_url()); + new_version()->PrepareForUpdate( + update_checker_->TakeComparedResults(), + update_checker_->updated_script_url(), + update_checker_->cross_origin_embedder_policy()); update_checker_.reset(); }
diff --git a/content/browser/service_worker/service_worker_registry.cc b/content/browser/service_worker/service_worker_registry.cc index 40449c4c..e17abe7 100644 --- a/content/browser/service_worker/service_worker_registry.cc +++ b/content/browser/service_worker/service_worker_registry.cc
@@ -5,44 +5,83 @@ #include "content/browser/service_worker/service_worker_registry.h" #include "base/memory/ptr_util.h" +#include "base/memory/weak_ptr.h" +#include "base/trace_event/trace_event.h" +#include "content/browser/service_worker/service_worker_context_core.h" #include "content/browser/service_worker/service_worker_registration.h" #include "content/browser/service_worker/service_worker_version.h" #include "content/common/service_worker/service_worker_utils.h" namespace content { +namespace { + +void CompleteFindNow(scoped_refptr<ServiceWorkerRegistration> registration, + blink::ServiceWorkerStatusCode status, + ServiceWorkerRegistry::FindRegistrationCallback callback) { + if (registration && registration->is_deleted()) { + // It's past the point of no return and no longer findable. + std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorNotFound, + nullptr); + return; + } + std::move(callback).Run(status, std::move(registration)); +} + +} // namespace + ServiceWorkerRegistry::ServiceWorkerRegistry( const base::FilePath& user_data_directory, ServiceWorkerContextCore* context, scoped_refptr<base::SequencedTaskRunner> database_task_runner, storage::QuotaManagerProxy* quota_manager_proxy, storage::SpecialStoragePolicy* special_storage_policy) - : storage_(ServiceWorkerStorage::Create(user_data_directory, + : context_(context), + storage_(ServiceWorkerStorage::Create(user_data_directory, context, std::move(database_task_runner), quota_manager_proxy, special_storage_policy, - this)) {} + this)) { + DCHECK(context_); +} ServiceWorkerRegistry::ServiceWorkerRegistry( ServiceWorkerContextCore* context, ServiceWorkerRegistry* old_registry) - : storage_(ServiceWorkerStorage::Create(context, + : context_(context), + storage_(ServiceWorkerStorage::Create(context, old_registry->storage(), - this)) {} + this)) { + DCHECK(context_); +} ServiceWorkerRegistry::~ServiceWorkerRegistry() = default; void ServiceWorkerRegistry::FindRegistrationForClientUrl( const GURL& client_url, FindRegistrationCallback callback) { - storage()->FindRegistrationForClientUrl(client_url, std::move(callback)); + // To connect this TRACE_EVENT with the callback, Time::Now() is used as a + // trace event id. + int64_t trace_event_id = + base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds(); + TRACE_EVENT_ASYNC_BEGIN1( + "ServiceWorker", "ServiceWorkerRegistry::FindRegistrationForClientUrl", + trace_event_id, "URL", client_url.spec()); + storage()->FindRegistrationForClientUrl( + client_url, + base::BindOnce(&ServiceWorkerRegistry::DidFindRegistrationForClientUrl, + weak_factory_.GetWeakPtr(), client_url, trace_event_id, + std::move(callback))); } void ServiceWorkerRegistry::FindRegistrationForScope( const GURL& scope, FindRegistrationCallback callback) { - storage()->FindRegistrationForScope(scope, std::move(callback)); + storage()->FindRegistrationForScope( + scope, + base::BindOnce(&ServiceWorkerRegistry::DidFindRegistrationForScope, + weak_factory_.GetWeakPtr(), scope, std::move(callback))); } void ServiceWorkerRegistry::FindRegistrationForId( @@ -135,4 +174,110 @@ return found->second.get(); } +scoped_refptr<ServiceWorkerRegistration> +ServiceWorkerRegistry::GetOrCreateRegistration( + const ServiceWorkerDatabase::RegistrationData& data, + const ResourceList& resources) { + scoped_refptr<ServiceWorkerRegistration> registration = + context_->GetLiveRegistration(data.registration_id); + if (registration) + return registration; + + blink::mojom::ServiceWorkerRegistrationOptions options( + data.scope, data.script_type, data.update_via_cache); + registration = base::MakeRefCounted<ServiceWorkerRegistration>( + options, data.registration_id, context_->AsWeakPtr()); + registration->set_resources_total_size_bytes(data.resources_total_size_bytes); + registration->set_last_update_check(data.last_update_check); + DCHECK(uninstalling_registrations().find(data.registration_id) == + uninstalling_registrations().end()); + + scoped_refptr<ServiceWorkerVersion> version = + context_->GetLiveVersion(data.version_id); + if (!version) { + version = base::MakeRefCounted<ServiceWorkerVersion>( + registration.get(), data.script, data.script_type, data.version_id, + context_->AsWeakPtr()); + version->set_fetch_handler_existence( + data.has_fetch_handler + ? ServiceWorkerVersion::FetchHandlerExistence::EXISTS + : ServiceWorkerVersion::FetchHandlerExistence::DOES_NOT_EXIST); + version->SetStatus(data.is_active ? ServiceWorkerVersion::ACTIVATED + : ServiceWorkerVersion::INSTALLED); + version->script_cache_map()->SetResources(resources); + if (data.origin_trial_tokens) + version->SetValidOriginTrialTokens(*data.origin_trial_tokens); + + version->set_used_features(data.used_features); + version->set_cross_origin_embedder_policy( + data.cross_origin_embedder_policy); + } + version->set_script_response_time_for_devtools(data.script_response_time); + + if (version->status() == ServiceWorkerVersion::ACTIVATED) + registration->SetActiveVersion(version); + else if (version->status() == ServiceWorkerVersion::INSTALLED) + registration->SetWaitingVersion(version); + else + NOTREACHED(); + + registration->EnableNavigationPreload(data.navigation_preload_state.enabled); + registration->SetNavigationPreloadHeader( + data.navigation_preload_state.header); + return registration; +} + +void ServiceWorkerRegistry::DidFindRegistrationForClientUrl( + const GURL& client_url, + int64_t trace_event_id, + FindRegistrationCallback callback, + blink::ServiceWorkerStatusCode status, + scoped_refptr<ServiceWorkerRegistration> registration) { + if (status == blink::ServiceWorkerStatusCode::kErrorNotFound) { + // Look for something currently being installed. + scoped_refptr<ServiceWorkerRegistration> installing_registration = + FindInstallingRegistrationForClientUrl(client_url); + if (installing_registration) { + blink::ServiceWorkerStatusCode installing_status = + installing_registration->is_deleted() + ? blink::ServiceWorkerStatusCode::kErrorNotFound + : blink::ServiceWorkerStatusCode::kOk; + TRACE_EVENT_ASYNC_END2( + "ServiceWorker", + "ServiceWorkerRegistry::FindRegistrationForClientUrl", trace_event_id, + "Status", blink::ServiceWorkerStatusToString(status), "Info", + (installing_status == blink::ServiceWorkerStatusCode::kOk) + ? "Installing registration is found" + : "Any registrations are not found"); + CompleteFindNow(std::move(installing_registration), installing_status, + std::move(callback)); + return; + } + } + + TRACE_EVENT_ASYNC_END1( + "ServiceWorker", "ServiceWorkerRegistry::FindRegistrationForClientUrl", + trace_event_id, "Status", blink::ServiceWorkerStatusToString(status)); + CompleteFindNow(std::move(registration), status, std::move(callback)); +} + +void ServiceWorkerRegistry::DidFindRegistrationForScope( + const GURL& scope, + FindRegistrationCallback callback, + blink::ServiceWorkerStatusCode status, + scoped_refptr<ServiceWorkerRegistration> registration) { + if (status == blink::ServiceWorkerStatusCode::kErrorNotFound) { + // Look for something currently being installed. + scoped_refptr<ServiceWorkerRegistration> installing_registration = + FindInstallingRegistrationForScope(scope); + if (installing_registration) { + CompleteFindNow(std::move(installing_registration), + blink::ServiceWorkerStatusCode::kOk, std::move(callback)); + return; + } + } + + CompleteFindNow(std::move(registration), status, std::move(callback)); +} + } // namespace content
diff --git a/content/browser/service_worker/service_worker_registry.h b/content/browser/service_worker/service_worker_registry.h index d10c8e9d..682955bd 100644 --- a/content/browser/service_worker/service_worker_registry.h +++ b/content/browser/service_worker/service_worker_registry.h
@@ -9,6 +9,7 @@ #include "base/files/file_path.h" #include "base/memory/scoped_refptr.h" +#include "content/browser/service_worker/service_worker_database.h" #include "content/browser/service_worker/service_worker_storage.h" #include "content/common/content_export.h" @@ -92,6 +93,13 @@ ServiceWorkerRegistration* FindInstallingRegistrationForId( int64_t registration_id); + // TODO(crbug.com/1039200): Make this private once methods/fields related to + // ServiceWorkerRegistration in ServiceWorkerStorage are moved into this + // class. + scoped_refptr<ServiceWorkerRegistration> GetOrCreateRegistration( + const ServiceWorkerDatabase::RegistrationData& data, + const ResourceList& resources); + using RegistrationRefsById = std::map<int64_t, scoped_refptr<ServiceWorkerRegistration>>; // TODO(crbug.com/1039200): Remove these accessors. These are tentatively @@ -105,11 +113,28 @@ } private: + void DidFindRegistrationForClientUrl( + const GURL& client_url, + int64_t trace_event_id, + FindRegistrationCallback callback, + blink::ServiceWorkerStatusCode status, + scoped_refptr<ServiceWorkerRegistration> registration); + void DidFindRegistrationForScope( + const GURL& scope, + FindRegistrationCallback callback, + blink::ServiceWorkerStatusCode status, + scoped_refptr<ServiceWorkerRegistration> registration); + + // The ServiceWorkerContextCore object must outlive this. + ServiceWorkerContextCore* const context_; + std::unique_ptr<ServiceWorkerStorage> storage_; // For finding registrations being installed or uninstalled. RegistrationRefsById installing_registrations_; RegistrationRefsById uninstalling_registrations_; + + base::WeakPtrFactory<ServiceWorkerRegistry> weak_factory_{this}; }; } // namespace content
diff --git a/content/browser/service_worker/service_worker_single_script_update_checker.cc b/content/browser/service_worker/service_worker_single_script_update_checker.cc index 4c84e2c..8876ed4 100644 --- a/content/browser/service_worker/service_worker_single_script_update_checker.cc +++ b/content/browser/service_worker/service_worker_single_script_update_checker.cc
@@ -286,6 +286,7 @@ network::URLLoaderCompletionStatus(net::ERR_INSECURE_RESPONSE)); return; } + cross_origin_embedder_policy_ = response_head->cross_origin_embedder_policy; } network_loader_state_ =
diff --git a/content/browser/service_worker/service_worker_single_script_update_checker.h b/content/browser/service_worker/service_worker_single_script_update_checker.h index 614627d6..8155ab7b 100644 --- a/content/browser/service_worker/service_worker_single_script_update_checker.h +++ b/content/browser/service_worker/service_worker_single_script_update_checker.h
@@ -10,6 +10,7 @@ #include "content/common/content_export.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h" +#include "services/network/public/cpp/cross_origin_resource_policy.h" #include "services/network/public/mojom/url_loader.mojom.h" #include "third_party/blink/public/common/service_worker/service_worker_status_code.h" #include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h" @@ -144,6 +145,10 @@ void OnComplete(const network::URLLoaderCompletionStatus& status) override; bool network_accessed() const { return network_accessed_; } + network::mojom::CrossOriginEmbedderPolicy cross_origin_embedder_policy() + const { + return cross_origin_embedder_policy_; + } static const char* ResultToString(Result result); @@ -183,6 +188,8 @@ const blink::mojom::ServiceWorkerUpdateViaCache update_via_cache_; const base::TimeDelta time_since_last_check_; bool network_accessed_ = false; + network::mojom::CrossOriginEmbedderPolicy cross_origin_embedder_policy_ = + network::mojom::CrossOriginEmbedderPolicy::kNone; std::unique_ptr< ServiceWorkerUpdatedScriptLoader::ThrottlingURLLoaderCoreWrapper>
diff --git a/content/browser/service_worker/service_worker_storage.cc b/content/browser/service_worker/service_worker_storage.cc index 2fe159d..f95530b27 100644 --- a/content/browser/service_worker/service_worker_storage.cc +++ b/content/browser/service_worker/service_worker_storage.cc
@@ -44,6 +44,7 @@ base::ThreadTaskRunnerHandle::Get()->PostTask(from_here, std::move(closure)); } +// TODO(crbug.com/1039200): Remove; this depends on ServiceWorkerRegistration. void CompleteFindNow(scoped_refptr<ServiceWorkerRegistration> registration, blink::ServiceWorkerStatusCode status, ServiceWorkerStorage::FindRegistrationCallback callback) { @@ -56,14 +57,6 @@ std::move(callback).Run(status, std::move(registration)); } -void CompleteFindSoon(const base::Location& from_here, - scoped_refptr<ServiceWorkerRegistration> registration, - blink::ServiceWorkerStatusCode status, - ServiceWorkerStorage::FindRegistrationCallback callback) { - RunSoon(from_here, base::BindOnce(&CompleteFindNow, std::move(registration), - status, std::move(callback))); -} - const base::FilePath::CharType kDatabaseName[] = FILE_PATH_LITERAL("Database"); const base::FilePath::CharType kDiskCacheName[] = @@ -148,9 +141,8 @@ DCHECK(!client_url.has_ref()); switch (state_) { case STORAGE_STATE_DISABLED: - CompleteFindNow(scoped_refptr<ServiceWorkerRegistration>(), - blink::ServiceWorkerStatusCode::kErrorAbort, - std::move(callback)); + std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorAbort, + nullptr); return; case STORAGE_STATE_INITIALIZING: // Fall-through. case STORAGE_STATE_UNINITIALIZED: @@ -166,40 +158,20 @@ break; } - // See if there are any stored registrations for the origin. + // Bypass database lookup when there is no stored registration. if (!base::Contains(registered_origins_, client_url.GetOrigin())) { - // Look for something currently being installed. - scoped_refptr<ServiceWorkerRegistration> installing_registration = - registry_->FindInstallingRegistrationForClientUrl(client_url); - blink::ServiceWorkerStatusCode status = - installing_registration - ? blink::ServiceWorkerStatusCode::kOk - : blink::ServiceWorkerStatusCode::kErrorNotFound; - TRACE_EVENT_INSTANT2( - "ServiceWorker", - "ServiceWorkerStorage::FindRegistrationForClientUrl:CheckInstalling", - TRACE_EVENT_SCOPE_THREAD, "URL", client_url.spec(), "Status", - blink::ServiceWorkerStatusToString(status)); - CompleteFindNow(std::move(installing_registration), status, - std::move(callback)); + std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorNotFound, + nullptr); return; } - // To connect this TRACE_EVENT with the callback, Time is used for - // callback id. - int64_t callback_id = - base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds(); - TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker", - "ServiceWorkerStorage::FindRegistrationForClientUrl", - callback_id, "URL", client_url.spec()); database_task_runner_->PostTask( FROM_HERE, base::BindOnce( &FindForClientUrlInDB, database_.get(), base::ThreadTaskRunnerHandle::Get(), client_url, - base::BindOnce(&ServiceWorkerStorage::DidFindRegistrationForClientUrl, - weak_factory_.GetWeakPtr(), client_url, - std::move(callback), callback_id))); + base::BindOnce(&ServiceWorkerStorage::DidFindRegistration, + weak_factory_.GetWeakPtr(), std::move(callback)))); } void ServiceWorkerStorage::FindRegistrationForScope( @@ -207,9 +179,10 @@ FindRegistrationCallback callback) { switch (state_) { case STORAGE_STATE_DISABLED: - CompleteFindSoon(FROM_HERE, scoped_refptr<ServiceWorkerRegistration>(), - blink::ServiceWorkerStatusCode::kErrorAbort, - std::move(callback)); + RunSoon( + FROM_HERE, + base::BindOnce(std::move(callback), + blink::ServiceWorkerStatusCode::kErrorAbort, nullptr)); return; case STORAGE_STATE_INITIALIZING: // Fall-through. case STORAGE_STATE_UNINITIALIZED: @@ -221,17 +194,12 @@ break; } - // See if there are any stored registrations for the origin. + // Bypass database lookup when there is no stored registration. if (!base::Contains(registered_origins_, scope.GetOrigin())) { - // Look for something currently being installed. - scoped_refptr<ServiceWorkerRegistration> installing_registration = - registry_->FindInstallingRegistrationForScope(scope); - blink::ServiceWorkerStatusCode installing_status = - installing_registration - ? blink::ServiceWorkerStatusCode::kOk - : blink::ServiceWorkerStatusCode::kErrorNotFound; - CompleteFindSoon(FROM_HERE, std::move(installing_registration), - installing_status, std::move(callback)); + RunSoon(FROM_HERE, + base::BindOnce(std::move(callback), + blink::ServiceWorkerStatusCode::kErrorNotFound, + nullptr)); return; } @@ -240,9 +208,8 @@ base::BindOnce( &FindForScopeInDB, database_.get(), base::ThreadTaskRunnerHandle::Get(), scope, - base::BindOnce(&ServiceWorkerStorage::DidFindRegistrationForScope, - weak_factory_.GetWeakPtr(), scope, - std::move(callback)))); + base::BindOnce(&ServiceWorkerStorage::DidFindRegistration, + weak_factory_.GetWeakPtr(), std::move(callback)))); } void ServiceWorkerStorage::FindRegistrationForId( @@ -1205,51 +1172,7 @@ pending_tasks_.clear(); } -void ServiceWorkerStorage::DidFindRegistrationForClientUrl( - const GURL& client_url, - FindRegistrationCallback callback, - int64_t callback_id, - const ServiceWorkerDatabase::RegistrationData& data, - const ResourceList& resources, - ServiceWorkerDatabase::Status status) { - if (status == ServiceWorkerDatabase::STATUS_OK) { - ReturnFoundRegistration(std::move(callback), data, resources); - TRACE_EVENT_ASYNC_END1( - "ServiceWorker", "ServiceWorkerStorage::FindRegistrationForClientUrl", - callback_id, "Status", ServiceWorkerDatabase::StatusToString(status)); - return; - } - - if (status == ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND) { - // Look for something currently being installed. - scoped_refptr<ServiceWorkerRegistration> installing_registration = - registry_->FindInstallingRegistrationForClientUrl(client_url); - blink::ServiceWorkerStatusCode installing_status = - installing_registration - ? blink::ServiceWorkerStatusCode::kOk - : blink::ServiceWorkerStatusCode::kErrorNotFound; - std::move(callback).Run(installing_status, - std::move(installing_registration)); - TRACE_EVENT_ASYNC_END2( - "ServiceWorker", "ServiceWorkerStorage::FindRegistrationForClientUrl", - callback_id, "Status", ServiceWorkerDatabase::StatusToString(status), - "Info", - (installing_status == blink::ServiceWorkerStatusCode::kOk) - ? "Installing registration is found" - : "Any registrations are not found"); - return; - } - - ScheduleDeleteAndStartOver(); - std::move(callback).Run(DatabaseStatusToStatusCode(status), - scoped_refptr<ServiceWorkerRegistration>()); - TRACE_EVENT_ASYNC_END1( - "ServiceWorker", "ServiceWorkerStorage::FindRegistrationForClientUrl", - callback_id, "Status", ServiceWorkerDatabase::StatusToString(status)); -} - -void ServiceWorkerStorage::DidFindRegistrationForScope( - const GURL& scope, +void ServiceWorkerStorage::DidFindRegistration( FindRegistrationCallback callback, const ServiceWorkerDatabase::RegistrationData& data, const ResourceList& resources, @@ -1259,19 +1182,9 @@ return; } - if (status == ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND) { - scoped_refptr<ServiceWorkerRegistration> installing_registration = - registry_->FindInstallingRegistrationForScope(scope); - blink::ServiceWorkerStatusCode installing_status = - installing_registration - ? blink::ServiceWorkerStatusCode::kOk - : blink::ServiceWorkerStatusCode::kErrorNotFound; - std::move(callback).Run(installing_status, - std::move(installing_registration)); - return; - } + if (status != ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND) + ScheduleDeleteAndStartOver(); - ScheduleDeleteAndStartOver(); std::move(callback).Run(DatabaseStatusToStatusCode(status), scoped_refptr<ServiceWorkerRegistration>()); } @@ -1304,7 +1217,7 @@ const ResourceList& resources) { DCHECK(!resources.empty()); scoped_refptr<ServiceWorkerRegistration> registration = - GetOrCreateRegistration(data, resources); + registry_->GetOrCreateRegistration(data, resources); CompleteFindNow(std::move(registration), blink::ServiceWorkerStatusCode::kOk, std::move(callback)); } @@ -1334,7 +1247,7 @@ size_t index = 0; for (const auto& registration_data : *registration_data_list) { registration_ids.insert(registration_data.registration_id); - registrations.push_back(GetOrCreateRegistration( + registrations.push_back(registry_->GetOrCreateRegistration( registration_data, resources_list->at(index++))); } @@ -1592,59 +1505,6 @@ std::move(callback).Run(user_data, DatabaseStatusToStatusCode(status)); } -scoped_refptr<ServiceWorkerRegistration> -ServiceWorkerStorage::GetOrCreateRegistration( - const ServiceWorkerDatabase::RegistrationData& data, - const ResourceList& resources) { - scoped_refptr<ServiceWorkerRegistration> registration = - context_->GetLiveRegistration(data.registration_id); - if (registration) - return registration; - - blink::mojom::ServiceWorkerRegistrationOptions options( - data.scope, data.script_type, data.update_via_cache); - registration = new ServiceWorkerRegistration(options, data.registration_id, - context_->AsWeakPtr()); - registration->set_resources_total_size_bytes(data.resources_total_size_bytes); - registration->set_last_update_check(data.last_update_check); - DCHECK(registry_->uninstalling_registrations().find(data.registration_id) == - registry_->uninstalling_registrations().end()); - - scoped_refptr<ServiceWorkerVersion> version = - context_->GetLiveVersion(data.version_id); - if (!version) { - version = base::MakeRefCounted<ServiceWorkerVersion>( - registration.get(), data.script, data.script_type, data.version_id, - context_->AsWeakPtr()); - version->set_fetch_handler_existence( - data.has_fetch_handler - ? ServiceWorkerVersion::FetchHandlerExistence::EXISTS - : ServiceWorkerVersion::FetchHandlerExistence::DOES_NOT_EXIST); - version->SetStatus(data.is_active ? - ServiceWorkerVersion::ACTIVATED : ServiceWorkerVersion::INSTALLED); - version->script_cache_map()->SetResources(resources); - if (data.origin_trial_tokens) - version->SetValidOriginTrialTokens(*data.origin_trial_tokens); - - version->set_used_features(data.used_features); - version->set_cross_origin_embedder_policy( - data.cross_origin_embedder_policy); - } - version->set_script_response_time_for_devtools(data.script_response_time); - - if (version->status() == ServiceWorkerVersion::ACTIVATED) - registration->SetActiveVersion(version); - else if (version->status() == ServiceWorkerVersion::INSTALLED) - registration->SetWaitingVersion(version); - else - NOTREACHED(); - - registration->EnableNavigationPreload(data.navigation_preload_state.enabled); - registration->SetNavigationPreloadHeader( - data.navigation_preload_state.header); - return registration; -} - ServiceWorkerDiskCache* ServiceWorkerStorage::disk_cache() { DCHECK(STORAGE_STATE_INITIALIZED == state_ || STORAGE_STATE_DISABLED == state_)
diff --git a/content/browser/service_worker/service_worker_storage.h b/content/browser/service_worker/service_worker_storage.h index db12378..21f214e5 100644 --- a/content/browser/service_worker/service_worker_storage.h +++ b/content/browser/service_worker/service_worker_storage.h
@@ -385,19 +385,10 @@ void LazyInitialize(base::OnceClosure callback); void DidReadInitialData(std::unique_ptr<InitialData> data, ServiceWorkerDatabase::Status status); - void DidFindRegistrationForClientUrl( - const GURL& client_url, - FindRegistrationCallback callback, - int64_t callback_id, - const ServiceWorkerDatabase::RegistrationData& data, - const ResourceList& resources, - ServiceWorkerDatabase::Status status); - void DidFindRegistrationForScope( - const GURL& scope, - FindRegistrationCallback callback, - const ServiceWorkerDatabase::RegistrationData& data, - const ResourceList& resources, - ServiceWorkerDatabase::Status status); + void DidFindRegistration(FindRegistrationCallback callback, + const ServiceWorkerDatabase::RegistrationData& data, + const ResourceList& resources, + ServiceWorkerDatabase::Status status); void DidFindRegistrationForId( FindRegistrationCallback callback, const ServiceWorkerDatabase::RegistrationData& data, @@ -449,10 +440,6 @@ const ServiceWorkerDatabase::RegistrationData& data, const ResourceList& resources); - scoped_refptr<ServiceWorkerRegistration> GetOrCreateRegistration( - const ServiceWorkerDatabase::RegistrationData& data, - const ResourceList& resources); - // Lazy disk_cache getter. ServiceWorkerDiskCache* disk_cache(); void InitializeDiskCache();
diff --git a/content/browser/service_worker/service_worker_storage_unittest.cc b/content/browser/service_worker/service_worker_storage_unittest.cc index 10bd4730..11a126ff 100644 --- a/content/browser/service_worker/service_worker_storage_unittest.cc +++ b/content/browser/service_worker/service_worker_storage_unittest.cc
@@ -1259,7 +1259,7 @@ ResourceRecord(resource_id1_, script_, resource_id1_size_)); resources.push_back( ResourceRecord(resource_id2_, import_, resource_id2_size_)); - registration_ = storage()->GetOrCreateRegistration(data, resources); + registration_ = registry()->GetOrCreateRegistration(data, resources); registration_->waiting_version()->SetStatus(ServiceWorkerVersion::NEW); // Add the resources ids to the uncommitted list.
diff --git a/content/browser/service_worker/service_worker_test_utils.cc b/content/browser/service_worker/service_worker_test_utils.cc index 390b766b..52ef915 100644 --- a/content/browser/service_worker/service_worker_test_utils.cc +++ b/content/browser/service_worker/service_worker_test_utils.cc
@@ -690,7 +690,8 @@ (compare_result == ServiceWorkerSingleScriptUpdateChecker::Result::kDifferent) ? script_url - : GURL()); + : GURL(), + network::mojom::CrossOriginEmbedderPolicy::kNone); } void ServiceWorkerUpdateCheckTestUtils::
diff --git a/content/browser/service_worker/service_worker_update_checker.cc b/content/browser/service_worker/service_worker_update_checker.cc index a922ca4..8a0a029 100644 --- a/content/browser/service_worker/service_worker_update_checker.cc +++ b/content/browser/service_worker/service_worker_update_checker.cc
@@ -170,6 +170,11 @@ if (running_checker_->network_accessed()) network_accessed_ = true; + if (is_main_script) { + cross_origin_embedder_policy_ = + running_checker_->cross_origin_embedder_policy(); + } + if (ServiceWorkerSingleScriptUpdateChecker::Result::kDifferent == result) { TRACE_EVENT_WITH_FLOW0( "ServiceWorker",
diff --git a/content/browser/service_worker/service_worker_update_checker.h b/content/browser/service_worker/service_worker_update_checker.h index 0d25de87..74aac2d8 100644 --- a/content/browser/service_worker/service_worker_update_checker.h +++ b/content/browser/service_worker/service_worker_update_checker.h
@@ -110,6 +110,10 @@ const GURL& updated_script_url() const { return updated_script_url_; } bool network_accessed() const { return network_accessed_; } + network::mojom::CrossOriginEmbedderPolicy cross_origin_embedder_policy() + const { + return cross_origin_embedder_policy_; + } private: void CheckOneScript(const GURL& url, const int64_t resource_id); @@ -150,6 +154,10 @@ // True if any at least one of the scripts is fetched by network. bool network_accessed_ = false; + // The value of Cross-Origin-Embedder-Policy header for the updated main + // script. + network::mojom::CrossOriginEmbedderPolicy cross_origin_embedder_policy_; + // |context_| outlives |this| because it owns |this| through // ServiceWorkerJobCoordinator and ServiceWorkerRegisterJob. ServiceWorkerContextCore* const context_;
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc index 01aa37c..c2f5d76c 100644 --- a/content/browser/service_worker/service_worker_version.cc +++ b/content/browser/service_worker/service_worker_version.cc
@@ -2185,9 +2185,11 @@ void ServiceWorkerVersion::PrepareForUpdate( std::map<GURL, ServiceWorkerUpdateChecker::ComparedScriptInfo> compared_script_info_map, - const GURL& updated_script_url) { + const GURL& updated_script_url, + network::mojom::CrossOriginEmbedderPolicy cross_origin_embedder_policy) { compared_script_info_map_ = std::move(compared_script_info_map); updated_script_url_ = updated_script_url; + cross_origin_embedder_policy_ = cross_origin_embedder_policy; } const std::map<GURL, ServiceWorkerUpdateChecker::ComparedScriptInfo>&
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h index 0272aff..8cea3712 100644 --- a/content/browser/service_worker/service_worker_version.h +++ b/content/browser/service_worker/service_worker_version.h
@@ -555,7 +555,8 @@ void PrepareForUpdate( std::map<GURL, ServiceWorkerUpdateChecker::ComparedScriptInfo> compared_script_info_map, - const GURL& updated_script_url); + const GURL& updated_script_url, + network::mojom::CrossOriginEmbedderPolicy cross_origin_embedder_policy); const std::map<GURL, ServiceWorkerUpdateChecker::ComparedScriptInfo>& compared_script_info_map() const; ServiceWorkerUpdateChecker::ComparedScriptInfo TakeComparedScriptInfo(
diff --git a/content/browser/service_worker/service_worker_version_browsertest.cc b/content/browser/service_worker/service_worker_version_browsertest.cc index fce2677..69b62f3c 100644 --- a/content/browser/service_worker/service_worker_version_browsertest.cc +++ b/content/browser/service_worker/service_worker_version_browsertest.cc
@@ -59,6 +59,7 @@ #include "net/http/http_response_info.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" +#include "services/network/public/cpp/features.h" #include "storage/browser/test/blob_test_utils.h" #include "third_party/blink/public/common/service_worker/service_worker_status_code.h" #include "third_party/blink/public/common/service_worker/service_worker_type_converters.h" @@ -1568,6 +1569,79 @@ base::Unretained(version_.get()), &observer)); } +// This tests whether the ServiceWorkerVersion can have the correct value of +// Cross-Origin-Embedder-Policy and checks if it works either of when +// CrossOriginIsolation is enabled and disabled. +class ServiceWorkerVersionCoepTest : public ServiceWorkerVersionBrowserTest, + public testing::WithParamInterface<bool> { + public: + ServiceWorkerVersionCoepTest() { + if (IsCrossOriginIsolationEnabled()) { + feature_list_.InitAndEnableFeature( + network::features::kCrossOriginIsolation); + } else { + feature_list_.InitAndDisableFeature( + network::features::kCrossOriginIsolation); + } + } + + static bool IsCrossOriginIsolationEnabled() { return GetParam(); } + + // Returns a response with Cross-Origin-Embedder-Policy header matching with + // |coep|. + static std::unique_ptr<net::test_server::HttpResponse> + RequestHandlerForWorkerScriptWithCoep( + base::Optional<network::mojom::CrossOriginEmbedderPolicy> coep, + const net::test_server::HttpRequest& request) { + static int counter = 0; + if (request.relative_url != "/service_worker/generated") + return nullptr; + auto response = std::make_unique<net::test_server::BasicHttpResponse>(); + response->set_code(net::HTTP_OK); + response->set_content( + base::StringPrintf("// empty. counter = %d\n", counter++)); + response->set_content_type("text/javascript"); + if (coep.has_value()) { + std::string header_value = + coep.value() == network::mojom::CrossOriginEmbedderPolicy::kNone + ? "none" + : "require-corp"; + response->AddCustomHeader("Cross-Origin-Embedder-Policy", header_value); + } + return response; + } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +INSTANTIATE_TEST_SUITE_P(All, ServiceWorkerVersionCoepTest, testing::Bool()); + +// Checks if ServiceWorkerVersion has the correct value of COEP when a new +// worker is installed. +IN_PROC_BROWSER_TEST_P(ServiceWorkerVersionCoepTest, + CrossOriginEmbedderPolicy_Install) { + embedded_test_server()->RegisterRequestHandler(base::BindRepeating( + &ServiceWorkerVersionCoepTest::RequestHandlerForWorkerScriptWithCoep, + network::mojom::CrossOriginEmbedderPolicy::kRequireCorp)); + StartServerAndNavigateToSetup(); + + // The version cannot get the proper COEP value until the worker is started. + RunOnCoreThread(base::BindOnce( + &ServiceWorkerVersionBrowserTest::SetUpRegistrationOnCoreThread, + base::Unretained(this), "/service_worker/generated")); + EXPECT_EQ(network::mojom::CrossOriginEmbedderPolicy::kNone, + version_->cross_origin_embedder_policy()); + + // Once it's started, the worker script is read from the network and the COEP + // value is set to the version. + StartWorker(blink::ServiceWorkerStatusCode::kOk); + EXPECT_EQ(IsCrossOriginIsolationEnabled() + ? network::mojom::CrossOriginEmbedderPolicy::kRequireCorp + : network::mojom::CrossOriginEmbedderPolicy::kNone, + version_->cross_origin_embedder_policy()); +} + class ServiceWorkerVersionBrowserV8FullCodeCacheTest : public ServiceWorkerVersionBrowserTest, public ServiceWorkerVersion::Observer {
diff --git a/content/browser/site_instance_impl_unittest.cc b/content/browser/site_instance_impl_unittest.cc index 1e50d54..b9e1ed0b 100644 --- a/content/browser/site_instance_impl_unittest.cc +++ b/content/browser/site_instance_impl_unittest.cc
@@ -1371,7 +1371,7 @@ EXPECT_FALSE(IsIsolatedOrigin(blank_url)); // Cleanup. - policy->RemoveIsolatedOriginsForBrowserContext(*context()); + policy->RemoveStateForBrowserContext(*context()); } TEST_F(SiteInstanceTest, CreateForURL) {
diff --git a/content/browser/site_per_process_hit_test_browsertest.cc b/content/browser/site_per_process_hit_test_browsertest.cc index 5402a26..0102a6da 100644 --- a/content/browser/site_per_process_hit_test_browsertest.cc +++ b/content/browser/site_per_process_hit_test_browsertest.cc
@@ -42,6 +42,7 @@ #include "content/shell/common/shell_switches.h" #include "content/test/mock_overscroll_observer.h" #include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h" #include "ui/display/display_switches.h" #include "ui/events/base_event_utils.h" #include "ui/events/gesture_detection/gesture_configuration.h" @@ -6665,7 +6666,7 @@ // Clear the activation state. root->UpdateUserActivationState( - blink::UserActivationUpdateType::kClearActivation); + blink::mojom::UserActivationUpdateType::kClearActivation); // Send a mouse down to child frame. mouse_event.SetType(blink::WebInputEvent::kMouseDown);
diff --git a/content/browser/webrtc/webrtc_media_recorder_browsertest.cc b/content/browser/webrtc/webrtc_media_recorder_browsertest.cc index 5f5cdb9..8c5792c 100644 --- a/content/browser/webrtc/webrtc_media_recorder_browsertest.cc +++ b/content/browser/webrtc/webrtc_media_recorder_browsertest.cc
@@ -22,10 +22,13 @@ } const kEncodingParameters[] = { {true, "video/webm;codecs=VP8"}, {true, "video/webm;codecs=VP9"}, - {true, "video/x-matroska;codecs=AVC1"}, {false, ""}, // Instructs the platform to choose any accelerated codec. {false, "video/webm;codecs=VP8"}, {false, "video/webm;codecs=VP9"}, +}; + +static const EncodingParameters kProprietaryEncodingParameters[] = { + {true, "video/x-matroska;codecs=AVC1"}, {false, "video/x-matroska;codecs=AVC1"}, }; @@ -233,8 +236,16 @@ kMediaRecorderHtmlFile); } -INSTANTIATE_TEST_SUITE_P(All, +INSTANTIATE_TEST_SUITE_P(OpenCodec, MAYBE_WebRtcMediaRecorderTest, testing::ValuesIn(kEncodingParameters)); +#if BUILDFLAG(USE_PROPRIETARY_CODECS) + +INSTANTIATE_TEST_SUITE_P(ProprietaryCodec, + MAYBE_WebRtcMediaRecorderTest, + testing::ValuesIn(kProprietaryEncodingParameters)); + +#endif // BUILDFLAG(USE_PROPRIETARY_CODECS) + } // namespace content
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index 061462a0..bbff880 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -52,7 +52,6 @@ #include "third_party/blink/public/common/feature_policy/feature_policy.h" #include "third_party/blink/public/common/frame/frame_owner_element_type.h" #include "third_party/blink/public/common/frame/frame_policy.h" -#include "third_party/blink/public/common/frame/user_activation_update_type.h" #include "third_party/blink/public/common/media/media_player_action.h" #include "third_party/blink/public/common/messaging/message_port_channel.h" #include "third_party/blink/public/common/messaging/transferable_message.h" @@ -63,6 +62,7 @@ #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h" #include "third_party/blink/public/mojom/frame/blocked_navigation_types.mojom.h" #include "third_party/blink/public/mojom/frame/lifecycle.mojom.h" +#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h" #include "third_party/blink/public/mojom/web_feature/web_feature.mojom.h" #include "third_party/blink/public/platform/viewport_intersection_state.h" #include "third_party/blink/public/platform/web_focus_type.h" @@ -136,8 +136,8 @@ content::CSPDisposition::LAST) IPC_ENUM_TRAITS_MAX_VALUE(blink::TriggeringEventInfo, blink::TriggeringEventInfo::kMaxValue) -IPC_ENUM_TRAITS_MAX_VALUE(blink::UserActivationUpdateType, - blink::UserActivationUpdateType::kMaxValue) +IPC_ENUM_TRAITS_MAX_VALUE(blink::mojom::UserActivationUpdateType, + blink::mojom::UserActivationUpdateType::kMaxValue) IPC_ENUM_TRAITS_MAX_VALUE(blink::MediaPlayerAction::Type, blink::MediaPlayerAction::Type::kMaxValue) IPC_ENUM_TRAITS_MAX_VALUE(blink::mojom::FeaturePolicyDisposition, @@ -838,16 +838,12 @@ double /* volume */) #endif // BUILDFLAG(ENABLE_PLUGINS) -// Notifies a parent frame that the child frame requires information about -// whether it is occluded or has visual effects applied. -IPC_MESSAGE_ROUTED1(FrameMsg_SetNeedsOcclusionTracking, - bool /* needs_tracking */) - // Tells the frame to update the user activation state in appropriate part of // the frame tree (ancestors for activation notification and all nodes for // consumption). -IPC_MESSAGE_ROUTED1(FrameMsg_UpdateUserActivationState, - blink::UserActivationUpdateType /* type of state update */) +IPC_MESSAGE_ROUTED1( + FrameMsg_UpdateUserActivationState, + blink::mojom::UserActivationUpdateType /* type of state update */) // Updates the renderer with a list of unique WebFeature values representing // Blink features used, performed or encountered by the browser during the @@ -1150,8 +1146,9 @@ // Indicates that the user activation state in the current frame has been // updated, so the replicated states need to be synced (in the browser process // as well as in all other renderer processes). -IPC_MESSAGE_ROUTED1(FrameHostMsg_UpdateUserActivationState, - blink::UserActivationUpdateType /* type of state update */) +IPC_MESSAGE_ROUTED1( + FrameHostMsg_UpdateUserActivationState, + blink::mojom::UserActivationUpdateType /* type of state update */) // Transfers user activation state from the source frame to the current frame. IPC_MESSAGE_ROUTED1(FrameMsg_TransferUserActivationFrom,
diff --git a/content/common/input/ime_text_span_conversions.cc b/content/common/input/ime_text_span_conversions.cc index be91d760..3b2be1f 100644 --- a/content/common/input/ime_text_span_conversions.cc +++ b/content/common/input/ime_text_span_conversions.cc
@@ -68,15 +68,54 @@ return ui::ImeTextSpan::Thickness::kThin; } +ui::mojom::ImeTextSpanUnderlineStyle +ConvertUiUnderlineStyleToUiImeTextSpanUnderlineStyle( + ui::ImeTextSpan::UnderlineStyle underline_style) { + switch (underline_style) { + case ui::ImeTextSpan::UnderlineStyle::kNone: + return ui::mojom::ImeTextSpanUnderlineStyle::kNone; + case ui::ImeTextSpan::UnderlineStyle::kSolid: + return ui::mojom::ImeTextSpanUnderlineStyle::kSolid; + case ui::ImeTextSpan::UnderlineStyle::kDot: + return ui::mojom::ImeTextSpanUnderlineStyle::kDot; + case ui::ImeTextSpan::UnderlineStyle::kDash: + return ui::mojom::ImeTextSpanUnderlineStyle::kDash; + } + + NOTREACHED(); + return ui::mojom::ImeTextSpanUnderlineStyle::kSolid; +} + +ui::ImeTextSpan::UnderlineStyle +ConvertUiImeTextSpanUnderlineStyleToUiUnderlineStyle( + ui::mojom::ImeTextSpanUnderlineStyle underline_style) { + switch (underline_style) { + case ui::mojom::ImeTextSpanUnderlineStyle::kNone: + return ui::ImeTextSpan::UnderlineStyle::kNone; + case ui::mojom::ImeTextSpanUnderlineStyle::kSolid: + return ui::ImeTextSpan::UnderlineStyle::kSolid; + case ui::mojom::ImeTextSpanUnderlineStyle::kDot: + return ui::ImeTextSpan::UnderlineStyle::kDot; + case ui::mojom::ImeTextSpanUnderlineStyle::kDash: + return ui::ImeTextSpan::UnderlineStyle::kDash; + } + + NOTREACHED(); + return ui::ImeTextSpan::UnderlineStyle::kSolid; +} + blink::WebImeTextSpan ConvertUiImeTextSpanToBlinkImeTextSpan( const ui::ImeTextSpan& ui_ime_text_span) { blink::WebImeTextSpan blink_ime_text_span = blink::WebImeTextSpan( ConvertUiImeTextSpanTypeToWebType(ui_ime_text_span.type), ui_ime_text_span.start_offset, ui_ime_text_span.end_offset, ConvertUiThicknessToUiImeTextSpanThickness(ui_ime_text_span.thickness), + ConvertUiUnderlineStyleToUiImeTextSpanUnderlineStyle( + ui_ime_text_span.underline_style), ui_ime_text_span.background_color, ui_ime_text_span.suggestion_highlight_color, ui_ime_text_span.suggestions); + blink_ime_text_span.text_color = ui_ime_text_span.text_color; blink_ime_text_span.underline_color = ui_ime_text_span.underline_color; blink_ime_text_span.remove_on_finish_composing = ui_ime_text_span.remove_on_finish_composing; @@ -99,9 +138,12 @@ ConvertWebImeTextSpanTypeToUiType(blink_ime_text_span.type), blink_ime_text_span.start_offset, blink_ime_text_span.end_offset, ConvertUiImeTextSpanThicknessToUiThickness(blink_ime_text_span.thickness), + ConvertUiImeTextSpanUnderlineStyleToUiUnderlineStyle( + blink_ime_text_span.underline_style), blink_ime_text_span.background_color, blink_ime_text_span.suggestion_highlight_color, blink_ime_text_span.suggestions); + ui_ime_text_span.text_color = blink_ime_text_span.text_color; ui_ime_text_span.underline_color = blink_ime_text_span.underline_color; ui_ime_text_span.remove_on_finish_composing = blink_ime_text_span.remove_on_finish_composing;
diff --git a/content/common/input/ime_text_span_conversions.h b/content/common/input/ime_text_span_conversions.h index 18353d30..e7dd4fbf 100644 --- a/content/common/input/ime_text_span_conversions.h +++ b/content/common/input/ime_text_span_conversions.h
@@ -18,6 +18,12 @@ ui::ImeTextSpan::Thickness thickness); ui::ImeTextSpan::Thickness ConvertUiImeTextSpanThicknessToUiThickness( ui::mojom::ImeTextSpanThickness thickness); +ui::mojom::ImeTextSpanUnderlineStyle +ConvertUiUnderlineStyleToUiImeTextSpanUnderlineStyle( + ui::ImeTextSpan::UnderlineStyle underline_style); +ui::ImeTextSpan::UnderlineStyle +ConvertUiImeTextSpanUnderlineStyleToUiUnderlineStyle( + ui::mojom::ImeTextSpanUnderlineStyle underline_style); blink::WebImeTextSpan ConvertUiImeTextSpanToBlinkImeTextSpan( const ui::ImeTextSpan&); ui::ImeTextSpan ConvertBlinkImeTextSpanToUiImeTextSpan(
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index 22852534..da8e2dc 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc
@@ -3302,7 +3302,7 @@ } void UpdateUserActivationStateMsgWaiter::OnUpdateUserActivationState( - blink::UserActivationUpdateType) { + blink::mojom::UserActivationUpdateType) { received_ = true; run_loop_.Quit(); }
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h index dbdb0f2..d4b40fa 100644 --- a/content/public/test/browser_test_utils.h +++ b/content/public/test/browser_test_utils.h
@@ -41,10 +41,10 @@ #include "services/network/public/mojom/network_service.mojom.h" #include "storage/common/file_system/file_system_types.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/common/frame/user_activation_update_type.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "third_party/blink/public/common/input/web_mouse_event.h" #include "third_party/blink/public/common/input/web_mouse_wheel_event.h" +#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h" #include "ui/accessibility/ax_node_data.h" #include "ui/accessibility/ax_tree_update.h" #include "ui/events/keycodes/dom/dom_code.h" @@ -1711,7 +1711,7 @@ private: ~UpdateUserActivationStateMsgWaiter() override = default; - void OnUpdateUserActivationState(blink::UserActivationUpdateType); + void OnUpdateUserActivationState(blink::mojom::UserActivationUpdateType); bool received_ = false; base::RunLoop run_loop_;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 098d530..7ca4113 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -162,7 +162,6 @@ #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/frame/sandbox_flags.h" -#include "third_party/blink/public/common/frame/user_activation_update_type.h" #include "third_party/blink/public/common/input/web_keyboard_event.h" #include "third_party/blink/public/common/loader/url_loader_throttle.h" #include "third_party/blink/public/common/logging/logging_utils.h" @@ -171,6 +170,7 @@ #include "third_party/blink/public/mojom/blob/blob.mojom.h" #include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h" +#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h" #include "third_party/blink/public/mojom/loader/request_context_frame_type.mojom.h" #include "third_party/blink/public/mojom/permissions/permission.mojom.h" #include "third_party/blink/public/mojom/referrer.mojom.h" @@ -4276,7 +4276,7 @@ } void RenderFrameImpl::UpdateUserActivationState( - blink::UserActivationUpdateType update_type) { + blink::mojom::UserActivationUpdateType update_type) { Send(new FrameHostMsg_UpdateUserActivationState(routing_id_, update_type)); }
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 683a0d2..45ce9bd 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -88,6 +88,7 @@ #include "third_party/blink/public/mojom/commit_result/commit_result.mojom.h" #include "third_party/blink/public/mojom/devtools/console_message.mojom.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h" +#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h" #include "third_party/blink/public/mojom/renderer_preferences.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h" #include "third_party/blink/public/mojom/use_counter/css_property_id.mojom.h" @@ -694,7 +695,7 @@ const blink::WebVector<blink::WebString>& stopped_matching_selectors) override; void UpdateUserActivationState( - blink::UserActivationUpdateType update_type) override; + blink::mojom::UserActivationUpdateType update_type) override; void SetMouseCapture(bool capture) override; bool ShouldReportDetailedMessageForSource( const blink::WebString& source) override;
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc index 67e5bf3..3284c7c 100644 --- a/content/renderer/render_frame_proxy.cc +++ b/content/renderer/render_frame_proxy.cc
@@ -349,7 +349,7 @@ state.feature_policy_header, state.opener_feature_state); if (state.has_received_user_gesture) { web_frame_->UpdateUserActivationState( - blink::UserActivationUpdateType::kNotifyActivation); + blink::mojom::UserActivationUpdateType::kNotifyActivation); } web_frame_->SetHadStickyUserActivationBeforeNavigation( state.has_received_user_gesture_before_nav); @@ -423,8 +423,6 @@ OnDidSetFramePolicyHeaders) IPC_MESSAGE_HANDLER(FrameMsg_ForwardResourceTimingToParent, OnForwardResourceTimingToParent) - IPC_MESSAGE_HANDLER(FrameMsg_SetNeedsOcclusionTracking, - OnSetNeedsOcclusionTracking) IPC_MESSAGE_HANDLER(FrameMsg_DidUpdateName, OnDidUpdateName) IPC_MESSAGE_HANDLER(FrameMsg_EnforceInsecureRequestPolicy, OnEnforceInsecureRequestPolicy) @@ -499,10 +497,6 @@ ResourceTimingInfoToWebResourceTimingInfo(info)); } -void RenderFrameProxy::OnSetNeedsOcclusionTracking(bool needs_tracking) { - web_frame_->SetNeedsOcclusionTracking(needs_tracking); -} - void RenderFrameProxy::OnDidUpdateName(const std::string& name, const std::string& unique_name) { web_frame_->SetReplicatedName(blink::WebString::FromUTF8(name)); @@ -525,7 +519,7 @@ } void RenderFrameProxy::OnUpdateUserActivationState( - blink::UserActivationUpdateType update_type) { + blink::mojom::UserActivationUpdateType update_type) { web_frame_->UpdateUserActivationState(update_type); }
diff --git a/content/renderer/render_frame_proxy.h b/content/renderer/render_frame_proxy.h index 55ecbc3..6690b51 100644 --- a/content/renderer/render_frame_proxy.h +++ b/content/renderer/render_frame_proxy.h
@@ -22,7 +22,7 @@ #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" #include "third_party/blink/public/common/feature_policy/feature_policy.h" -#include "third_party/blink/public/common/frame/user_activation_update_type.h" +#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h" #include "third_party/blink/public/platform/web_focus_type.h" #include "third_party/blink/public/platform/web_insecure_request_policy.h" #include "third_party/blink/public/web/web_remote_frame.h" @@ -238,12 +238,12 @@ blink::ParsedFeaturePolicy parsed_feature_policy); void OnForwardResourceTimingToParent( const ResourceTimingInfo& resource_timing); - void OnSetNeedsOcclusionTracking(bool); void OnDidUpdateName(const std::string& name, const std::string& unique_name); void OnEnforceInsecureRequestPolicy(blink::WebInsecureRequestPolicy policy); void OnSetFrameOwnerProperties(const FrameOwnerProperties& properties); void OnSetPageFocus(bool is_focused); - void OnUpdateUserActivationState(blink::UserActivationUpdateType update_type); + void OnUpdateUserActivationState( + blink::mojom::UserActivationUpdateType update_type); void OnTransferUserActivationFrom(int32_t source_routing_id); void OnScrollRectToVisible(const gfx::Rect& rect_to_scroll, const blink::WebScrollIntoViewParams& params);
diff --git a/content/shell/browser/web_test/blink_test_controller.cc b/content/shell/browser/web_test/blink_test_controller.cc index 439331c..d07d6fd 100644 --- a/content/shell/browser/web_test/blink_test_controller.cc +++ b/content/shell/browser/web_test/blink_test_controller.cc
@@ -578,10 +578,9 @@ } void BlinkTestController::OnTestFinishedInSecondaryRenderer() { - RenderViewHost* main_render_view_host = - main_window_->web_contents()->GetRenderViewHost(); - main_render_view_host->Send(new BlinkTestMsg_TestFinishedInSecondaryRenderer( - main_render_view_host->GetRoutingID())); + GetWebTestControlRemote( + main_window_->web_contents()->GetRenderViewHost()->GetMainFrame()) + ->TestFinishedInSecondaryRenderer(); } void BlinkTestController::OnInitiateCaptureDump(bool capture_navigation_history, @@ -1041,14 +1040,15 @@ void BlinkTestController::OnCleanupFinished() { if (main_window_) { main_window_->web_contents()->Stop(); - RenderViewHost* rvh = main_window_->web_contents()->GetRenderViewHost(); - rvh->Send(new BlinkTestMsg_Reset(rvh->GetRoutingID())); + GetWebTestControlRemote( + main_window_->web_contents()->GetRenderViewHost()->GetMainFrame()) + ->Reset(); } if (secondary_window_) { secondary_window_->web_contents()->Stop(); - RenderViewHost* rvh = - secondary_window_->web_contents()->GetRenderViewHost(); - rvh->Send(new BlinkTestMsg_Reset(rvh->GetRoutingID())); + GetWebTestControlRemote( + secondary_window_->web_contents()->GetRenderViewHost()->GetMainFrame()) + ->Reset(); } } @@ -1223,10 +1223,9 @@ } // Continue finishing the test. - RenderViewHost* render_view_host = - main_window_->web_contents()->GetRenderViewHost(); - render_view_host->Send(new BlinkTestMsg_LayoutDumpCompleted( - render_view_host->GetRoutingID(), stitched_layout_dump)); + GetWebTestControlRemote( + main_window_->web_contents()->GetRenderViewHost()->GetMainFrame()) + ->LayoutDumpCompleted(stitched_layout_dump); } void BlinkTestController::OnPrintMessage(const std::string& message) { @@ -1404,9 +1403,10 @@ "getBluetoothManualChooserEvents."); return; } - RenderViewHost* rvh = main_window_->web_contents()->GetRenderViewHost(); - rvh->Send(new BlinkTestMsg_ReplyBluetoothManualChooserEvents( - rvh->GetRoutingID(), bluetooth_chooser_factory_->GetAndResetEvents())); + GetWebTestControlRemote( + main_window_->web_contents()->GetRenderViewHost()->GetMainFrame()) + ->ReplyBluetoothManualChooserEvents( + bluetooth_chooser_factory_->GetAndResetEvents()); } void BlinkTestController::OnSendBluetoothManualChooserEvent(
diff --git a/content/shell/common/web_test.mojom b/content/shell/common/web_test.mojom index 6e08214..bab5d6f 100644 --- a/content/shell/common/web_test.mojom +++ b/content/shell/common/web_test.mojom
@@ -68,4 +68,20 @@ // Sets up a secondary renderer (renderer that doesn't [yet] host parts of the // main test window) for a web test. SetupSecondaryRenderer(); + + // Tells the renderer to reset all test runners. + Reset(); + + // Tells the main window that a secondary renderer in a different process + // asked to finish the test. + TestFinishedInSecondaryRenderer(); + + // Notifies BlinkTestRunner that the layout dump has completed (and that it + // can proceed with finishing up the test). + // TODO(crbug.com/1039247): This message should be removed and the callback + // should happen part of LayoutDump call on the host interface. + LayoutDumpCompleted(string completed_layout_dump); + + // Reply Bluetooth manual events to BlinkTestRunner. + ReplyBluetoothManualChooserEvents(array<string> events); };
diff --git a/content/shell/common/web_test/blink_test_messages.h b/content/shell/common/web_test/blink_test_messages.h index 296c8f7fc..3bccc2b 100644 --- a/content/shell/common/web_test/blink_test_messages.h +++ b/content/shell/common/web_test/blink_test_messages.h
@@ -15,25 +15,12 @@ #define IPC_MESSAGE_START BlinkTestMsgStart -// Tells the renderer to reset all test runners. -IPC_MESSAGE_ROUTED0(BlinkTestMsg_Reset) - -// Tells the main window that a secondary renderer in a different process asked -// to finish the test. -IPC_MESSAGE_ROUTED0(BlinkTestMsg_TestFinishedInSecondaryRenderer) - -// Notifies BlinkTestRunner that the layout dump has completed -// (and that it can proceed with finishing up the test). -IPC_MESSAGE_ROUTED1(BlinkTestMsg_LayoutDumpCompleted, - std::string /* completed/stitched layout dump */) - -IPC_MESSAGE_ROUTED1(BlinkTestMsg_ReplyBluetoothManualChooserEvents, - std::vector<std::string> /* events */) - // Asks the browser process to perform a layout dump spanning all the // (potentially cross-process) frames. This goes through multiple // WebTestControl.DumpFrameLayout calls and ends with sending of -// BlinkTestMsg_LayoutDumpCompleted. +// LayoutDumpCompleted. +// TODO(crbug.com/1039247): LayoutDumpCompleted call should be removed and the +// callback should happen part of LayoutDump call on the host interface. IPC_MESSAGE_ROUTED0(BlinkTestHostMsg_InitiateLayoutDump) IPC_MESSAGE_ROUTED0(BlinkTestHostMsg_ResetDone)
diff --git a/content/shell/renderer/web_test/blink_test_runner.cc b/content/shell/renderer/web_test/blink_test_runner.cc index 3c92f87..82772ec4 100644 --- a/content/shell/renderer/web_test/blink_test_runner.cc +++ b/content/shell/renderer/web_test/blink_test_runner.cc
@@ -683,21 +683,6 @@ WebTestingSupport::InjectInternalsObject(frame); } -bool BlinkTestRunner::OnMessageReceived(const IPC::Message& message) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(BlinkTestRunner, message) - IPC_MESSAGE_HANDLER(BlinkTestMsg_Reset, OnReset) - IPC_MESSAGE_HANDLER(BlinkTestMsg_TestFinishedInSecondaryRenderer, - OnTestFinishedInSecondaryRenderer) - IPC_MESSAGE_HANDLER(BlinkTestMsg_ReplyBluetoothManualChooserEvents, - OnReplyBluetoothManualChooserEvents) - IPC_MESSAGE_HANDLER(BlinkTestMsg_LayoutDumpCompleted, OnLayoutDumpCompleted) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - - return handled; -} - // Public methods - ----------------------------------------------------------- void BlinkTestRunner::Reset(bool for_new_test) {
diff --git a/content/shell/renderer/web_test/blink_test_runner.h b/content/shell/renderer/web_test/blink_test_runner.h index 0a53e0a..abf4eba 100644 --- a/content/shell/renderer/web_test/blink_test_runner.h +++ b/content/shell/renderer/web_test/blink_test_runner.h
@@ -51,7 +51,6 @@ ~BlinkTestRunner() override; // RenderViewObserver implementation. - bool OnMessageReceived(const IPC::Message& message) override; void DidClearWindowObject(blink::WebLocalFrame* frame) override; // WebTestDelegate implementation. @@ -154,14 +153,13 @@ void OnSetupSecondaryRenderer(); void CaptureDump(mojom::WebTestControl::CaptureDumpCallback callback); void DidCommitNavigationInMainFrame(); - - private: - // Message handlers. void OnReset(); void OnTestFinishedInSecondaryRenderer(); + void OnLayoutDumpCompleted(std::string completed_layout_dump); void OnReplyBluetoothManualChooserEvents( const std::vector<std::string>& events); + private: // RenderViewObserver implementation. void OnDestruct() override; @@ -170,7 +168,6 @@ // After finishing the test, retrieves the audio, text, and pixel dumps from // the TestRunner library and sends them to the browser process. - void OnLayoutDumpCompleted(std::string completed_layout_dump); void OnPixelsDumpCompleted(const SkBitmap& snapshot); void CaptureDumpComplete(); void CaptureLocalAudioDump();
diff --git a/content/shell/renderer/web_test/web_test_render_frame_observer.cc b/content/shell/renderer/web_test/web_test_render_frame_observer.cc index 370f37b..9a2583f 100644 --- a/content/shell/renderer/web_test/web_test_render_frame_observer.cc +++ b/content/shell/renderer/web_test/web_test_render_frame_observer.cc
@@ -116,4 +116,25 @@ ->OnSetupSecondaryRenderer(); } +void WebTestRenderFrameObserver::Reset() { + BlinkTestRunner::Get(render_frame()->GetRenderView())->OnReset(); +} + +void WebTestRenderFrameObserver::TestFinishedInSecondaryRenderer() { + BlinkTestRunner::Get(render_frame()->GetRenderView()) + ->OnTestFinishedInSecondaryRenderer(); +} + +void WebTestRenderFrameObserver::LayoutDumpCompleted( + const std::string& completed_layout_dump) { + BlinkTestRunner::Get(render_frame()->GetRenderView()) + ->OnLayoutDumpCompleted(completed_layout_dump); +} + +void WebTestRenderFrameObserver::ReplyBluetoothManualChooserEvents( + const std::vector<std::string>& events) { + BlinkTestRunner::Get(render_frame()->GetRenderView()) + ->OnReplyBluetoothManualChooserEvents(events); +} + } // namespace content
diff --git a/content/shell/renderer/web_test/web_test_render_frame_observer.h b/content/shell/renderer/web_test/web_test_render_frame_observer.h index 4954ec35..799696e4 100644 --- a/content/shell/renderer/web_test/web_test_render_frame_observer.h +++ b/content/shell/renderer/web_test/web_test_render_frame_observer.h
@@ -36,6 +36,12 @@ void ReplicateTestConfiguration( mojom::ShellTestConfigurationPtr config) override; void SetupSecondaryRenderer() override; + void Reset() override; + void TestFinishedInSecondaryRenderer() override; + void LayoutDumpCompleted(const std::string& completed_layout_dump) override; + void ReplyBluetoothManualChooserEvents( + const std::vector<std::string>& events) override; + void BindReceiver( mojo::PendingAssociatedReceiver<mojom::WebTestControl> receiver);
diff --git a/content/shell/test_runner/text_input_controller.cc b/content/shell/test_runner/text_input_controller.cc index f62630aa..5a7cbc0 100644 --- a/content/shell/test_runner/text_input_controller.cc +++ b/content/shell/test_runner/text_input_controller.cc
@@ -274,11 +274,14 @@ ime_text_span.end_offset = start + length; } ime_text_span.thickness = ui::mojom::ImeTextSpanThickness::kThick; + ime_text_span.underline_style = ui::mojom::ImeTextSpanUnderlineStyle::kSolid; ime_text_spans.push_back(ime_text_span); if (start + length < static_cast<int>(web_text.length())) { ime_text_span.start_offset = ime_text_span.end_offset; ime_text_span.end_offset = web_text.length(); ime_text_span.thickness = ui::mojom::ImeTextSpanThickness::kThin; + ime_text_span.underline_style = + ui::mojom::ImeTextSpanUnderlineStyle::kSolid; ime_text_spans.push_back(ime_text_span); } @@ -385,7 +388,8 @@ std::vector<blink::WebImeTextSpan> ime_text_spans; ime_text_spans.push_back(blink::WebImeTextSpan( blink::WebImeTextSpan::Type::kComposition, 0, textLength, - ui::mojom::ImeTextSpanThickness::kThin, SK_ColorTRANSPARENT)); + ui::mojom::ImeTextSpanThickness::kThin, + ui::mojom::ImeTextSpanUnderlineStyle::kSolid, SK_ColorTRANSPARENT)); if (auto* controller = GetInputMethodController()) { controller->SetComposition( newText, blink::WebVector<blink::WebImeTextSpan>(ime_text_spans),
diff --git a/content/test/fake_network.cc b/content/test/fake_network.cc index af2a48f..b9cd7d1 100644 --- a/content/test/fake_network.cc +++ b/content/test/fake_network.cc
@@ -4,8 +4,10 @@ #include "content/test/fake_network.h" +#include "base/feature_list.h" #include "base/strings/string_util.h" #include "net/http/http_util.h" +#include "services/network/public/cpp/features.h" #include "services/network/public/mojom/url_loader.mojom.h" #include "services/network/public/mojom/url_response_head.mojom.h" @@ -98,6 +100,13 @@ response->headers->GetMimeType(&response->mime_type); response->network_accessed = response_info.network_accessed; + if (base::FeatureList::IsEnabled(network::features::kCrossOriginIsolation) && + info.headers->HasHeaderValue("Cross-Origin-Embedder-Policy", + "require-corp")) { + response->cross_origin_embedder_policy = + network::mojom::CrossOriginEmbedderPolicy::kRequireCorp; + } + mojo::Remote<network::mojom::URLLoaderClient>& client = params->client; client->OnReceiveResponse(std::move(response));
diff --git a/device/vr/public/mojom/OWNERS b/device/vr/public/mojom/OWNERS index fd66a0a..b8aabfd 100644 --- a/device/vr/public/mojom/OWNERS +++ b/device/vr/public/mojom/OWNERS
@@ -1,5 +1,9 @@ per-file *.mojom=set noparent per-file *.mojom=file://ipc/SECURITY_OWNERS +per-file *_mojom_traits*.*=set noparent +per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS +per-file *.typemap=set noparent +per-file *.typemap=file://ipc/SECURITY_OWNERS # TEAM: xr-dev@chromium.org # COMPONENT: Internals>XR
diff --git a/device/vr/public/mojom/blink_typemaps.gni b/device/vr/public/mojom/blink_typemaps.gni new file mode 100644 index 0000000..4cdfadb --- /dev/null +++ b/device/vr/public/mojom/blink_typemaps.gni
@@ -0,0 +1 @@ +typemaps = [ "//device/vr/public/mojom/vr_service.typemap" ]
diff --git a/device/vr/public/mojom/rgb_tuple_f32.h b/device/vr/public/mojom/rgb_tuple_f32.h new file mode 100644 index 0000000..e07d678 --- /dev/null +++ b/device/vr/public/mojom/rgb_tuple_f32.h
@@ -0,0 +1,36 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef DEVICE_VR_PUBLIC_MOJOM_RGB_TUPLE_F32_H_ +#define DEVICE_VR_PUBLIC_MOJOM_RGB_TUPLE_F32_H_ + +#include <stddef.h> + +namespace device { + +struct RgbTupleF32 { + using Component = float; + static constexpr size_t kNumComponents = 3; + + RgbTupleF32() : RgbTupleF32(0, 0, 0) {} + RgbTupleF32(float red, float green, float blue) + : components{red, green, blue} {} + + float red() const { return components[0]; } + void set_red(float red) { components[0] = red; } + float green() const { return components[1]; } + void set_green(float green) { components[1] = green; } + float blue() const { return components[2]; } + void set_blue(float blue) { components[2] = blue; } + + float components[kNumComponents]; +}; + +static_assert(sizeof(RgbTupleF32) == + sizeof(RgbTupleF32::Component) * RgbTupleF32::kNumComponents, + "RgbTupleF32 must be contiguous"); + +} // namespace device + +#endif // DEVICE_VR_PUBLIC_MOJOM_RGB_TUPLE_F32_H_
diff --git a/device/vr/public/mojom/rgba_tuple_f16.h b/device/vr/public/mojom/rgba_tuple_f16.h new file mode 100644 index 0000000..e57017d9 --- /dev/null +++ b/device/vr/public/mojom/rgba_tuple_f16.h
@@ -0,0 +1,41 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef DEVICE_VR_PUBLIC_MOJOM_RGBA_TUPLE_F16_H_ +#define DEVICE_VR_PUBLIC_MOJOM_RGBA_TUPLE_F16_H_ + +#include <stddef.h> +#include <stdint.h> + +namespace device { + +struct RgbaTupleF16 { + // Because C++ does not have a native 16-bit floating point type, + // the components are stored as |uint16_t|s. + using Component = uint16_t; + static constexpr size_t kNumComponents = 4; + + RgbaTupleF16() : RgbaTupleF16(0, 0, 0, 0) {} + RgbaTupleF16(uint16_t red, uint16_t green, uint16_t blue, uint16_t alpha) + : components{red, green, blue, alpha} {} + + uint16_t red() const { return components[0]; } + void set_red(uint16_t red) { components[0] = red; } + uint16_t green() const { return components[1]; } + void set_green(uint16_t green) { components[1] = green; } + uint16_t blue() const { return components[2]; } + void set_blue(uint16_t blue) { components[2] = blue; } + uint16_t alpha() const { return components[3]; } + void set_alpha(uint16_t alpha) { components[3] = alpha; } + + uint16_t components[kNumComponents]; +}; + +static_assert(sizeof(RgbaTupleF16) == sizeof(RgbaTupleF16::Component) * + RgbaTupleF16::kNumComponents, + "RgbaTupleF16 must be contiguous"); + +} // namespace device + +#endif // DEVICE_VR_PUBLIC_MOJOM_RGBA_TUPLE_F16_H_
diff --git a/device/vr/public/mojom/typemaps.gni b/device/vr/public/mojom/typemaps.gni new file mode 100644 index 0000000..4cdfadb --- /dev/null +++ b/device/vr/public/mojom/typemaps.gni
@@ -0,0 +1 @@ +typemaps = [ "//device/vr/public/mojom/vr_service.typemap" ]
diff --git a/device/vr/public/mojom/vr_service.mojom b/device/vr/public/mojom/vr_service.mojom index 2ba0869e..42631ba 100644 --- a/device/vr/public/mojom/vr_service.mojom +++ b/device/vr/public/mojom/vr_service.mojom
@@ -420,6 +420,82 @@ array<XRHitTestTransientInputSubscriptionResultData> transient_input_results; }; +// Tuple of single-precision floating point RGB data. +// This is the format used by ArCore for spherical harmonics coefficients +// and main light intensity. +struct RgbTupleF32 { + float red; + float green; + float blue; +}; + +// Contains the coefficient data for L2 spherical harmonics generated by ArCore. +struct XRSphericalHarmonics { + // L2 (3rd order) spherical harmonics coefficients. + // This array has 9 RGB vector elements, representing the 27 coefficients + // given by ArCore. + // Units are expressed in nits: + // https://github.com/immersive-web/lighting-estimation/blob/master/lighting-estimation-explainer.md#physically-based-units + array<RgbTupleF32, 9> coefficients; +}; + +// Tuple of half-precision floating point RGBA data. +// Since there isn't a native way to represent half-precision floats, they are +// stored a uint16s. +// This is the pixel format used by ArCore for cubemap textures. +struct RgbaTupleF16 { + uint16 red; + uint16 green; + uint16 blue; + uint16 alpha; +}; + +// Contains the pixel data for all six faces of an HDR cubemap generated by +// ArCore. Pixel data is stored in RGBA16F format. +struct XRCubeMap { + // Each pixel has four components (RGBA) + const uint64 kNumComponentsPerPixel = 4; + + // The width and height (in pixels) of each cube map face. + // Since each face is equal and square, this is only given as a single value. + // Additionally, the dimensions of each face will be a power of two. + // Note that each pixel is a contiguous RGBA16F vector, so the length of each + // array will be this times |kNumComponentsPerPixel|. + uint32 width_and_height; + + // Each cube map face, stored in RGBA row-major order. Units are in nits. + // Each array will be |width_and_height ** 2| in length. + // https://github.com/immersive-web/lighting-estimation/blob/master/lighting-estimation-explainer.md#physically-based-units + array<RgbaTupleF16> positive_x; + array<RgbaTupleF16> negative_x; + array<RgbaTupleF16> positive_y; + array<RgbaTupleF16> negative_y; + array<RgbaTupleF16> positive_z; + array<RgbaTupleF16> negative_z; +}; + +// Contains lighting information generated from ArCore for use in diffuse +// lighting calculations. +struct XRLightProbe { + XRSphericalHarmonics spherical_harmonics; + gfx.mojom.Vector3dF main_light_direction; + + // RGB vector, units in nits. + RgbTupleF32 main_light_intensity; +}; + +// Contains lighting information generated from ArCore for use in specular +// lighting calculations. +struct XRReflectionProbe { + XRCubeMap cube_map; +}; + +// Contains all lighting information generated from ArCore. +struct XRLightEstimationData { + XRLightProbe? light_probe; + XRReflectionProbe? reflection_probe; +}; + // The data needed for each animation frame of an XRSession. struct XRFrameData { // General XRSession value @@ -487,6 +563,9 @@ // Tracked anchors information. XRAnchorsData? anchors_data; + // Lighting estimation data. Only present if lighting estimation is enabled. + XRLightEstimationData? light_estimation_data; + // Hit test subscription results. Only present if the session supports // environment integration. XRHitTestSubscriptionResultsData? hit_test_subscription_results; @@ -667,9 +746,13 @@ }; struct XRFrameDataRequestOptions { - // Controls whether XRFrameData.detected_planes should be populated by the - // request to XRFrameDataProvider.GetFrameData(). + // Controls whether |XRFrameData.detected_planes| should be populated by the + // request to |XRFrameDataProvider.GetFrameData()|. bool include_plane_data; + + // Controls whether |XRFrameData.light_estimation_data| should be populated + // by the request to |XRFrameDataProvider.GetFrameData()|. + bool include_lighting_estimation_data; }; // Provides the necessary functionality for a WebXR session to get data for
diff --git a/device/vr/public/mojom/vr_service.typemap b/device/vr/public/mojom/vr_service.typemap new file mode 100644 index 0000000..15aa149 --- /dev/null +++ b/device/vr/public/mojom/vr_service.typemap
@@ -0,0 +1,11 @@ +mojom = "//device/vr/public/mojom/vr_service.mojom" +public_headers = [ + "//device/vr/public/mojom/rgba_tuple_f16.h", + "//device/vr/public/mojom/rgb_tuple_f32.h", +] +traits_headers = [ "//device/vr/public/mojom/vr_service_mojom_traits.h" ] +public_deps = [ "//mojo/public/cpp/bindings" ] +type_mappings = [ + "device.mojom.RgbaTupleF16=::device::RgbaTupleF16", + "device.mojom.RgbTupleF32=::device::RgbTupleF32", +]
diff --git a/device/vr/public/mojom/vr_service_mojom_traits.h b/device/vr/public/mojom/vr_service_mojom_traits.h new file mode 100644 index 0000000..c196791 --- /dev/null +++ b/device/vr/public/mojom/vr_service_mojom_traits.h
@@ -0,0 +1,51 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef DEVICE_VR_PUBLIC_MOJOM_VR_SERVICE_MOJOM_TRAITS_H_ +#define DEVICE_VR_PUBLIC_MOJOM_VR_SERVICE_MOJOM_TRAITS_H_ + +#include "device/vr/public/mojom/rgb_tuple_f32.h" +#include "device/vr/public/mojom/rgba_tuple_f16.h" +#include "device/vr/public/mojom/vr_service.mojom-shared.h" +#include "mojo/public/cpp/bindings/struct_traits.h" + +namespace mojo { + +template <> +struct StructTraits<device::mojom::RgbaTupleF16DataView, device::RgbaTupleF16> { + static uint16_t red(const device::RgbaTupleF16& rgba) { return rgba.red(); } + static uint16_t green(const device::RgbaTupleF16& rgba) { + return rgba.green(); + } + static uint16_t blue(const device::RgbaTupleF16& rgba) { return rgba.blue(); } + static uint16_t alpha(const device::RgbaTupleF16& rgba) { + return rgba.alpha(); + } + static bool Read(device::mojom::RgbaTupleF16DataView data, + device::RgbaTupleF16* out) { + out->set_red(data.red()); + out->set_green(data.green()); + out->set_blue(data.blue()); + out->set_alpha(data.alpha()); + return true; + } +}; + +template <> +struct StructTraits<device::mojom::RgbTupleF32DataView, device::RgbTupleF32> { + static float red(const device::RgbTupleF32& rgba) { return rgba.red(); } + static float green(const device::RgbTupleF32& rgba) { return rgba.green(); } + static float blue(const device::RgbTupleF32& rgba) { return rgba.blue(); } + static bool Read(device::mojom::RgbTupleF32DataView data, + device::RgbTupleF32* out) { + out->set_red(data.red()); + out->set_green(data.green()); + out->set_blue(data.blue()); + return true; + } +}; + +} // namespace mojo + +#endif // DEVICE_VR_PUBLIC_MOJOM_VR_SERVICE_MOJOM_TRAITS_H_
diff --git a/extensions/renderer/api/automation/automation_ax_tree_wrapper.cc b/extensions/renderer/api/automation/automation_ax_tree_wrapper.cc index 8d2d948..01fc7eb 100644 --- a/extensions/renderer/api/automation/automation_ax_tree_wrapper.cc +++ b/extensions/renderer/api/automation/automation_ax_tree_wrapper.cc
@@ -323,13 +323,19 @@ // Currently language detection only runs once for initial load complete, any // content loaded after this will not have language detection performed for // it. - // - // TODO(chrishall): We may want to run this more often for dynamic content. for (const auto& targeted_event : event_generator_) { if (targeted_event.event_params.event == ui::AXEventGenerator::Event::LOAD_COMPLETE) { - tree_.language_detection_manager->DetectLanguages(tree_.root()); - tree_.language_detection_manager->LabelLanguages(tree_.root()); + tree_.language_detection_manager->DetectLanguages(); + tree_.language_detection_manager->LabelLanguages(); + + // After initial language detection, enable language detection for future + // content updates in order to support dynamic content changes. + // + // If the LanguageDetectionDynamic feature flag is not enabled then this + // is a no-op. + tree_.language_detection_manager->RegisterLanguageDetectionObserver(); + break; } }
diff --git a/gpu/command_buffer/service/gl_context_virtual_unittest.cc b/gpu/command_buffer/service/gl_context_virtual_unittest.cc index 67975fb..d8defe0 100644 --- a/gpu/command_buffer/service/gl_context_virtual_unittest.cc +++ b/gpu/command_buffer/service/gl_context_virtual_unittest.cc
@@ -49,7 +49,7 @@ { auto base_context = base::MakeRefCounted<gl::GLContextStub>(); gl::GLShareGroup* share_group = base_context->share_group(); - share_group->SetSharedContext(GetGLSurface(), base_context.get()); + share_group->SetSharedContext(base_context.get()); auto context = base::MakeRefCounted<GLContextVirtual>( share_group, base_context.get(), decoder_->AsWeakPtr()); EXPECT_TRUE(context->Initialize(GetGLSurface(), gl::GLContextAttribs())); @@ -58,7 +58,7 @@ { auto base_context = base::MakeRefCounted<gl::GLContextStub>(); gl::GLShareGroup* share_group = base_context->share_group(); - share_group->SetSharedContext(GetGLSurface(), base_context.get()); + share_group->SetSharedContext(base_context.get()); auto context = base::MakeRefCounted<GLContextVirtual>( share_group, base_context.get(), decoder_->AsWeakPtr()); EXPECT_TRUE(context->Initialize(GetGLSurface(), gl::GLContextAttribs())); @@ -77,7 +77,7 @@ base_context->SetExtensionsString(gl_extensions); gl::GLShareGroup* share_group = base_context->share_group(); - share_group->SetSharedContext(GetGLSurface(), base_context.get()); + share_group->SetSharedContext(base_context.get()); auto context = base::MakeRefCounted<GLContextVirtual>( share_group, base_context.get(), decoder_->AsWeakPtr()); EXPECT_TRUE(context->Initialize(GetGLSurface(), gl::GLContextAttribs()));
diff --git a/gpu/ipc/in_process_command_buffer.cc b/gpu/ipc/in_process_command_buffer.cc index 1009345..180ef010 100644 --- a/gpu/ipc/in_process_command_buffer.cc +++ b/gpu/ipc/in_process_command_buffer.cc
@@ -659,9 +659,8 @@ // TODO(khushalsagar): A lot of this initialization code is duplicated in // GpuChannelManager. Pull it into a common util method. scoped_refptr<gl::GLContext> real_context = - use_virtualized_gl_context_ - ? gl_share_group_->GetSharedContext(surface_.get()) - : nullptr; + use_virtualized_gl_context_ ? gl_share_group_->shared_context() + : nullptr; if (real_context && (!real_context->MakeCurrent(surface_.get()) || real_context->CheckStickyGraphicsResetStatus() != GL_NO_ERROR)) { @@ -686,7 +685,7 @@ task_executor_->gpu_feature_info().ApplyToGLContext(real_context.get()); if (use_virtualized_gl_context_) - gl_share_group_->SetSharedContext(surface_.get(), real_context.get()); + gl_share_group_->SetSharedContext(real_context.get()); } if (!real_context->MakeCurrent(surface_.get())) {
diff --git a/gpu/ipc/service/gles2_command_buffer_stub.cc b/gpu/ipc/service/gles2_command_buffer_stub.cc index 28a7a9d..ec99e708 100644 --- a/gpu/ipc/service/gles2_command_buffer_stub.cc +++ b/gpu/ipc/service/gles2_command_buffer_stub.cc
@@ -261,7 +261,7 @@ scoped_refptr<gl::GLContext> context; if (use_virtualized_gl_context_ && share_group_) { - context = share_group_->GetSharedContext(surface_.get()); + context = share_group_->shared_context(); if (context && (!context->MakeCurrent(surface_.get()) || context->CheckStickyGraphicsResetStatus() != GL_NO_ERROR)) { context = nullptr; @@ -281,7 +281,7 @@ // Ensure that context creation did not lose track of the intended share // group. DCHECK(context->share_group() == share_group_.get()); - share_group_->SetSharedContext(surface_.get(), context.get()); + share_group_->SetSharedContext(context.get()); // This needs to be called against the real shared context, not the // virtual context created below.
diff --git a/gpu/ipc/service/gpu_channel_manager.cc b/gpu/ipc/service/gpu_channel_manager.cc index f05e29f9..e80ff895 100644 --- a/gpu/ipc/service/gpu_channel_manager.cc +++ b/gpu/ipc/service/gpu_channel_manager.cc
@@ -461,8 +461,7 @@ } scoped_refptr<gl::GLContext> context = - use_virtualized_gl_contexts ? share_group->GetSharedContext(surface.get()) - : nullptr; + use_virtualized_gl_contexts ? share_group->shared_context() : nullptr; if (context && (!context->MakeCurrent(surface.get()) || context->CheckStickyGraphicsResetStatus() != GL_NO_ERROR)) { context = nullptr; @@ -487,7 +486,7 @@ gpu_feature_info_.ApplyToGLContext(context.get()); if (use_virtualized_gl_contexts) - share_group->SetSharedContext(surface.get(), context.get()); + share_group->SetSharedContext(context.get()); } // This should be either:
diff --git a/headless/lib/browser/headless_clipboard.cc b/headless/lib/browser/headless_clipboard.cc index aa09cbe..4814081a 100644 --- a/headless/lib/browser/headless_clipboard.cc +++ b/headless/lib/browser/headless_clipboard.cc
@@ -102,7 +102,7 @@ void HeadlessClipboard::ReadBookmark(base::string16* title, std::string* url) const { const DataStore& store = GetDefaultStore(); - auto it = store.data.find(ui::ClipboardFormatType::GetUrlWType()); + auto it = store.data.find(ui::ClipboardFormatType::GetUrlType()); if (it != store.data.end()) *url = it->second; *title = base::UTF8ToUTF16(store.url_title); @@ -138,8 +138,6 @@ void HeadlessClipboard::WriteText(const char* text_data, size_t text_len) { std::string text(text_data, text_len); GetDefaultStore().data[ui::ClipboardFormatType::GetPlainTextType()] = text; - // Create a dummy entry. - GetDefaultStore().data[ui::ClipboardFormatType::GetPlainTextType()]; if (IsSupportedClipboardBuffer(ui::ClipboardBuffer::kSelection)) { GetStore(ui::ClipboardBuffer::kSelection) .data[ui::ClipboardFormatType::GetPlainTextType()] = text; @@ -166,7 +164,7 @@ size_t title_len, const char* url_data, size_t url_len) { - GetDefaultStore().data[ui::ClipboardFormatType::GetUrlWType()] = + GetDefaultStore().data[ui::ClipboardFormatType::GetUrlType()] = std::string(url_data, url_len); GetDefaultStore().url_title = std::string(title_data, title_len); }
diff --git a/infra/config/buckets/ci.star b/infra/config/buckets/ci.star index 6283ffe6..344cf59 100644 --- a/infra/config/buckets/ci.star +++ b/infra/config/buckets/ci.star
@@ -408,28 +408,24 @@ chromium_builder( name = 'win-archive-dbg', cores = 32, - goma_enable_ats = True, os = os.WINDOWS_DEFAULT, ) chromium_builder( name = 'win-archive-rel', cores = 32, - goma_enable_ats = True, os = os.WINDOWS_DEFAULT, ) chromium_builder( name = 'win32-archive-dbg', cores = 32, - goma_enable_ats = True, os = os.WINDOWS_DEFAULT, ) chromium_builder( name = 'win32-archive-rel', cores = 32, - goma_enable_ats = True, os = os.WINDOWS_DEFAULT, ) @@ -763,13 +759,11 @@ dawn_builder( name = 'Dawn Win10 x86 Builder', - goma_enable_ats = True, os = os.WINDOWS_ANY, ) dawn_builder( name = 'Dawn Win10 x64 Builder', - goma_enable_ats = True, os = os.WINDOWS_ANY, ) @@ -801,13 +795,11 @@ dawn_builder( name = 'Dawn Win10 x86 DEPS Builder', - goma_enable_ats = True, os = os.WINDOWS_ANY, ) dawn_builder( name = 'Dawn Win10 x64 DEPS Builder', - goma_enable_ats = True, os = os.WINDOWS_ANY, ) @@ -919,14 +911,12 @@ fuzz_builder( name = 'Win ASan Release', builderless = False, - goma_enable_ats = True, os = os.WINDOWS_DEFAULT, ) fuzz_builder( name = 'Win ASan Release Media', builderless = False, - goma_enable_ats = True, os = os.WINDOWS_DEFAULT ) @@ -993,7 +983,6 @@ fuzz_libfuzzer_builder( name = 'Libfuzzer Upload Windows ASan', - goma_enable_ats = True, os = os.WINDOWS_DEFAULT, ) @@ -1122,8 +1111,7 @@ fyi_builder( name = 'win-pixel-builder-rel', - goma_enable_ats = True, - os = None, + os = os.WINDOWS_10, ) fyi_builder( @@ -1150,7 +1138,6 @@ fyi_celab_builder( name = 'win-celab-builder-rel', - goma_enable_ats = True, ) fyi_celab_builder( @@ -1218,7 +1205,6 @@ fyi_coverage_builder( name = 'win10-code-coverage', builderless = True, - goma_enable_ats = True, os = os.WINDOWS_DEFAULT, use_clang_coverage = True, ) @@ -1324,7 +1310,6 @@ return fyi_builder( name = name, goma_backend = goma.backend.RBE_PROD, - goma_enable_ats = True, os = os, **kwargs ) @@ -1700,7 +1685,6 @@ name = name, builderless = True, goma_backend = goma.backend.RBE_PROD, - goma_enable_ats = True, os = os.WINDOWS_ANY, **kwargs ) @@ -1763,7 +1747,6 @@ gpu_builder( name = 'GPU Win x64 Builder (dbg)', builderless = True, - goma_enable_ats = True, os = os.WINDOWS_ANY, ) @@ -2070,7 +2053,6 @@ memory_builder( name = 'win-asan', cores = 32, - goma_enable_ats = True, builderless = True, os = os.WINDOWS_DEFAULT, ) @@ -2126,7 +2108,6 @@ return swangle_builder( name = name, goma_backend = goma.backend.RBE_PROD, - goma_enable_ats = True, os = os.WINDOWS_DEFAULT, **kwargs ) @@ -2160,7 +2141,6 @@ return builder( name = name, goma_backend = goma.backend.RBE_PROD, - goma_enable_ats = True, mastername = 'chromium.win', os = os, **kwargs
diff --git a/infra/config/buckets/try.star b/infra/config/buckets/try.star index 0a4d72f..03f6b6c2 100644 --- a/infra/config/buckets/try.star +++ b/infra/config/buckets/try.star
@@ -365,25 +365,21 @@ angle_builder( name = 'win-angle-deqp-rel-32', - goma_enable_ats = True, os = os.WINDOWS_ANY, ) angle_builder( name = 'win-angle-deqp-rel-64', - goma_enable_ats = True, os = os.WINDOWS_ANY, ) angle_builder( name = 'win-angle-rel-32', - goma_enable_ats = True, os = os.WINDOWS_ANY, ) angle_builder( name = 'win-angle-rel-64', - goma_enable_ats = True, os = os.WINDOWS_ANY, ) @@ -412,7 +408,6 @@ blink_builder( name = 'win10-blink-rel', goma_backend = goma.backend.RBE_PROD, - goma_enable_ats = True, os = os.WINDOWS_ANY, builderless = True, ) @@ -420,7 +415,6 @@ blink_builder( name = 'win7-blink-rel', goma_backend = goma.backend.RBE_PROD, - goma_enable_ats = True, os = os.WINDOWS_ANY, builderless = True, ) @@ -601,7 +595,6 @@ dawn_builder( name = 'dawn-win10-x64-deps-rel', - goma_enable_ats = True, os = os.WINDOWS_ANY, tryjob = tryjob( location_regexp = [ @@ -618,7 +611,6 @@ dawn_builder( name = 'dawn-win10-x86-deps-rel', - goma_enable_ats = True, os = os.WINDOWS_ANY, tryjob = tryjob( location_regexp = [ @@ -644,7 +636,6 @@ dawn_builder( name = 'win-dawn-rel', - goma_enable_ats = True, os = os.WINDOWS_ANY, ) @@ -864,7 +855,6 @@ return gpu_builder( name = name, goma_backend = goma.backend.RBE_PROD, - goma_enable_ats = True, mastername = 'tryserver.chromium.win', os = os, **kwargs @@ -1494,7 +1484,6 @@ name = name, os = os.WINDOWS_DEFAULT, goma_backend = goma.backend.RBE_PROD, - goma_enable_ats = True, **kwargs ) @@ -1528,14 +1517,12 @@ name, builderless=True, goma_backend=goma.backend.RBE_PROD, - goma_enable_ats=True, os=os.WINDOWS_DEFAULT, **kwargs): return try_builder( name = name, builderless = builderless, goma_backend = goma_backend, - goma_enable_ats = goma_enable_ats, mastername = 'tryserver.chromium.win', os = os, **kwargs @@ -1626,7 +1613,6 @@ cores = 32, executable = luci.recipe(name = 'chromium_upload_clang'), goma_backend = None, - goma_enable_ats = False, os = os.WINDOWS_ANY, )
diff --git a/infra/config/buckets/webrtc.fyi.star b/infra/config/buckets/webrtc.fyi.star index 2b22bef..5d01e34 100644 --- a/infra/config/buckets/webrtc.fyi.star +++ b/infra/config/buckets/webrtc.fyi.star
@@ -123,14 +123,12 @@ builder( name = 'WebRTC Chromium FYI Win Builder', goma_backend = goma.backend.RBE_PROD, - goma_enable_ats = True, os = os.WINDOWS_DEFAULT, ) builder( name = 'WebRTC Chromium FYI Win Builder (dbg)', goma_backend = goma.backend.RBE_PROD, - goma_enable_ats = True, os = os.WINDOWS_DEFAULT, )
diff --git a/infra/config/buckets/webrtc.star b/infra/config/buckets/webrtc.star index 8620f7f5..06c095d 100644 --- a/infra/config/buckets/webrtc.star +++ b/infra/config/buckets/webrtc.star
@@ -73,7 +73,6 @@ builder( name = 'WebRTC Chromium Win Builder', goma_backend = goma.backend.RBE_PROD, - goma_enable_ats = True, os = os.WINDOWS_ANY, )
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg index d450e79..b29eab6 100644 --- a/infra/config/generated/cr-buildbucket.cfg +++ b/infra/config/generated/cr-buildbucket.cfg
@@ -7640,7 +7640,6 @@ cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" - properties_j: "$build/goma:{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"chromium.fyi\"" > @@ -7766,7 +7765,7 @@ name: "celab" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/goma:{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" + properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "exclude:\"chrome_only\"" properties_j: "mastername:\"chromium.fyi\"" @@ -7785,6 +7784,7 @@ dimensions: "builder:win-pixel-builder-rel" dimensions: "cores:8" dimensions: "cpu:x86-64" + dimensions: "os:Windows-10" recipe: < name: "chromium" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -8612,7 +8612,6 @@ cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" - properties_j: "$build/goma:{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"chromium.fyi\"" > @@ -9208,7 +9207,6 @@ cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" - properties_j: "$build/goma:{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"chromium.fyi\"" >
diff --git a/infra/config/lib/builders.star b/infra/config/lib/builders.star index 4a570f0eb..858fa3b 100644 --- a/infra/config/lib/builders.star +++ b/infra/config/lib/builders.star
@@ -144,26 +144,30 @@ return chromium_tests or None -def _goma_property(*, goma_backend, goma_debug, goma_enable_ats, goma_jobs): - goma = {} +def _goma_property(*, goma_backend, goma_debug, goma_enable_ats, goma_jobs, os): + goma_properties = {} goma_backend = _default('goma_backend', goma_backend) if goma_backend != None: - goma.update(goma_backend) + goma_properties.update(goma_backend) goma_debug = _default('goma_debug', goma_debug) if goma_debug: - goma['debug'] = True + goma_properties['debug'] = True goma_enable_ats = _default('goma_enable_ats', goma_enable_ats) - if goma_enable_ats: - goma['enable_ats'] = True + if goma_enable_ats: # TODO(crbug.com/1040754): Remove this flag. + goma_properties['enable_ats'] = True + elif (goma_backend in (goma.backend.RBE_TOT, goma.backend.RBE_STAGING, + goma.backend.RBE_PROD) and + (os and os.category == os_category.WINDOWS)): + goma_properties['enable_ats'] = True goma_jobs = _default('goma_jobs', goma_jobs) if goma_jobs != None: - goma['jobs'] = goma_jobs + goma_properties['jobs'] = goma_jobs - return goma or None + return goma_properties or None def _code_coverage_property(*, use_clang_coverage, use_java_coverage): @@ -385,6 +389,7 @@ goma_debug = goma_debug, goma_enable_ats = goma_enable_ats, goma_jobs = goma_jobs, + os = os, ) if goma != None: properties['$build/goma'] = goma
diff --git a/infra/config/versioned/milestones/m79/buckets/ci.star b/infra/config/versioned/milestones/m79/buckets/ci.star index 854efcce..3cc3f3d 100644 --- a/infra/config/versioned/milestones/m79/buckets/ci.star +++ b/infra/config/versioned/milestones/m79/buckets/ci.star
@@ -100,7 +100,6 @@ # OS shouldn't matter. fyi_builder( name = 'mac-osxbeta-rel', - goma_backend = goma.backend.RBE_PROD, ) @@ -142,7 +141,6 @@ gpu_builder( name = 'GPU Win x64 Builder', builderless = True, - goma_enable_ats = True, os = os.WINDOWS_ANY, ) @@ -257,7 +255,6 @@ return builder( name = name, goma_backend = goma.backend.RBE_PROD, - goma_enable_ats = True, mastername = 'chromium.win', os = os, **kwargs
diff --git a/infra/config/versioned/milestones/m79/buckets/try.star b/infra/config/versioned/milestones/m79/buckets/try.star index 1ee6f14..70b58a0 100644 --- a/infra/config/versioned/milestones/m79/buckets/try.star +++ b/infra/config/versioned/milestones/m79/buckets/try.star
@@ -262,7 +262,6 @@ name = name, builderless = builderless, goma_backend = goma.backend.RBE_PROD, - goma_enable_ats = True, mastername = 'tryserver.chromium.win', os = os, **kwargs
diff --git a/infra/config/versioned/milestones/m80/buckets/ci.star b/infra/config/versioned/milestones/m80/buckets/ci.star index 854efcce..3cc3f3d 100644 --- a/infra/config/versioned/milestones/m80/buckets/ci.star +++ b/infra/config/versioned/milestones/m80/buckets/ci.star
@@ -100,7 +100,6 @@ # OS shouldn't matter. fyi_builder( name = 'mac-osxbeta-rel', - goma_backend = goma.backend.RBE_PROD, ) @@ -142,7 +141,6 @@ gpu_builder( name = 'GPU Win x64 Builder', builderless = True, - goma_enable_ats = True, os = os.WINDOWS_ANY, ) @@ -257,7 +255,6 @@ return builder( name = name, goma_backend = goma.backend.RBE_PROD, - goma_enable_ats = True, mastername = 'chromium.win', os = os, **kwargs
diff --git a/infra/config/versioned/milestones/m80/buckets/try.star b/infra/config/versioned/milestones/m80/buckets/try.star index b196cab..70cf4fd8 100644 --- a/infra/config/versioned/milestones/m80/buckets/try.star +++ b/infra/config/versioned/milestones/m80/buckets/try.star
@@ -239,7 +239,6 @@ name = name, builderless = builderless, goma_backend = goma.backend.RBE_PROD, - goma_enable_ats = True, mastername = 'tryserver.chromium.win', os = os, **kwargs
diff --git a/infra/config/versioned/trunk/buckets/ci.star b/infra/config/versioned/trunk/buckets/ci.star index 854efcce..3cc3f3d 100644 --- a/infra/config/versioned/trunk/buckets/ci.star +++ b/infra/config/versioned/trunk/buckets/ci.star
@@ -100,7 +100,6 @@ # OS shouldn't matter. fyi_builder( name = 'mac-osxbeta-rel', - goma_backend = goma.backend.RBE_PROD, ) @@ -142,7 +141,6 @@ gpu_builder( name = 'GPU Win x64 Builder', builderless = True, - goma_enable_ats = True, os = os.WINDOWS_ANY, ) @@ -257,7 +255,6 @@ return builder( name = name, goma_backend = goma.backend.RBE_PROD, - goma_enable_ats = True, mastername = 'chromium.win', os = os, **kwargs
diff --git a/infra/config/versioned/trunk/buckets/try.star b/infra/config/versioned/trunk/buckets/try.star index b196cab..70cf4fd8 100644 --- a/infra/config/versioned/trunk/buckets/try.star +++ b/infra/config/versioned/trunk/buckets/try.star
@@ -239,7 +239,6 @@ name = name, builderless = builderless, goma_backend = goma.backend.RBE_PROD, - goma_enable_ats = True, mastername = 'tryserver.chromium.win', os = os, **kwargs
diff --git a/ios/chrome/app/BUILD.gn b/ios/chrome/app/BUILD.gn index 56c752be..d9481f3 100644 --- a/ios/chrome/app/BUILD.gn +++ b/ios/chrome/app/BUILD.gn
@@ -59,6 +59,7 @@ "//ios/chrome/browser", "//ios/chrome/browser/browser_state:test_support", "//ios/chrome/browser/tabs", + "//ios/chrome/browser/ui/main:scene", "//ios/chrome/common/app_group", "//ios/chrome/test:test_support", "//ios/public/provider/chrome/browser:browser",
diff --git a/ios/chrome/app/main_application_delegate.mm b/ios/chrome/app/main_application_delegate.mm index ae39e43..a7e1cb0 100644 --- a/ios/chrome/app/main_application_delegate.mm +++ b/ios/chrome/app/main_application_delegate.mm
@@ -71,7 +71,6 @@ [_mainController setMetricsMediator:_metricsMediator]; _browserLauncher = _mainController; _startupInformation = _mainController; - _tabOpener = _mainController; _appState = [[AppState alloc] initWithBrowserLauncher:_browserLauncher startupInformation:_startupInformation applicationDelegate:self]; @@ -91,6 +90,7 @@ _sceneController.mainController = (id<MainControllerGuts>)_mainController; _mainController.sceneController = _sceneController; _tabSwitcherProtocol = _sceneController; + _tabOpener = _sceneController; } } return self;
diff --git a/ios/chrome/app/main_controller.h b/ios/chrome/app/main_controller.h index 8062d27..0d22ea1 100644 --- a/ios/chrome/app/main_controller.h +++ b/ios/chrome/app/main_controller.h
@@ -10,7 +10,6 @@ #import "ios/chrome/app/application_delegate/app_navigation.h" #import "ios/chrome/app/application_delegate/browser_launcher.h" #import "ios/chrome/app/application_delegate/startup_information.h" -#import "ios/chrome/app/application_delegate/tab_opening.h" #import "ios/chrome/app/main_controller_guts.h" #import "ios/chrome/browser/ui/commands/application_commands.h" #import "ios/chrome/browser/ui/commands/browsing_data_commands.h" @@ -20,6 +19,7 @@ @protocol AppURLLoadingServiceDelegate; @protocol BrowsingDataCommands; @protocol SceneControllerGuts; +@protocol TabOpening; @protocol TabSwitcherDelegate; // The main controller of the application, owned by the MainWindow nib. Also @@ -32,7 +32,6 @@ BrowserLauncher, MainControllerGuts, StartupInformation, - TabOpening, BrowsingDataCommands> // The application window. @@ -50,7 +49,8 @@ @property(nonatomic, weak) id<ApplicationCommands, TabSwitcherDelegate, AppURLLoadingServiceDelegate, - SceneControllerGuts> + SceneControllerGuts, + TabOpening> sceneController; @end
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm index 68617985..fda5b19 100644 --- a/ios/chrome/app/main_controller.mm +++ b/ios/chrome/app/main_controller.mm
@@ -675,9 +675,9 @@ [_browserViewWrangler updateDeviceSharingManager]; - [self openTabFromLaunchOptions:_launchOptions - startupInformation:self - appState:self.appState]; + [self.sceneController openTabFromLaunchOptions:_launchOptions + startupInformation:self + appState:self.appState]; _launchOptions = nil; if (!self.startupParameters) { @@ -718,13 +718,14 @@ if (self.startupParameters) { UrlLoadParams params = UrlLoadParams::InNewTab(self.startupParameters.externalURL); - [self dismissModalsAndOpenSelectedTabInMode:ApplicationModeForTabOpening:: - NORMAL - withUrlLoadParams:params - dismissOmnibox:YES - completion:^{ - [self setStartupParameters:nil]; - }]; + [self.sceneController + dismissModalsAndOpenSelectedTabInMode:ApplicationModeForTabOpening:: + NORMAL + withUrlLoadParams:params + dismissOmnibox:YES + completion:^{ + [self setStartupParameters:nil]; + }]; } } @@ -1285,7 +1286,8 @@ focusOmnibox:NO]; [self finishDismissingTabSwitcher]; } - if (firstRun || [self shouldOpenNTPTabOnActivationOfTabModel:tabModel]) { + if (firstRun || + [self.sceneController shouldOpenNTPTabOnActivationOfTabModel:tabModel]) { OpenNewTabCommand* command = [OpenNewTabCommand commandWithIncognito:(self.currentBVC == self.otrBVC)]; command.userInitiated = NO; @@ -1544,33 +1546,6 @@ [self.mainCoordinator showTabSwitcher:_tabSwitcher]; } -- (BOOL)shouldOpenNTPTabOnActivationOfTabModel:(TabModel*)tabModel { - if (self.tabSwitcherIsActive) { - // Only attempt to dismiss the tab switcher and open a new tab if: - // - there are no tabs open in either tab model, and - // - the tab switcher controller is not directly or indirectly presenting - // another view controller. - if (![self.mainTabModel isEmpty] || ![self.otrTabModel isEmpty]) - return NO; - - // If the tabSwitcher is contained, check if the parent container is - // presenting another view controller. - if ([[_tabSwitcher viewController] - .parentViewController presentedViewController]) { - return NO; - } - - // Check if the tabSwitcher is directly presenting another view controller. - if ([_tabSwitcher viewController].presentedViewController) { - return NO; - } - - return YES; - } - return ![tabModel count] && [tabModel browserState] && - ![tabModel browserState]->IsOffTheRecord(); -} - #pragma mark - TabSwitcherDelegate helper methods - (void)beginDismissingTabSwitcherWithCurrentModel:(TabModel*)tabModel @@ -1732,51 +1707,6 @@ prefs->CommitPendingWrite(); } -#pragma mark - TabOpening implementation. - -- (void)dismissModalsAndOpenSelectedTabInMode: - (ApplicationModeForTabOpening)targetMode - withUrlLoadParams: - (const UrlLoadParams&)urlLoadParams - dismissOmnibox:(BOOL)dismissOmnibox - completion:(ProceduralBlock)completion { - UrlLoadParams copyOfUrlLoadParams = urlLoadParams; - [self.sceneController - dismissModalDialogsWithCompletion:^{ - [self.sceneController openSelectedTabInMode:targetMode - withUrlLoadParams:copyOfUrlLoadParams - completion:completion]; - } - dismissOmnibox:dismissOmnibox]; -} - -- (void)openTabFromLaunchOptions:(NSDictionary*)launchOptions - startupInformation:(id<StartupInformation>)startupInformation - appState:(AppState*)appState { - if (launchOptions) { - BOOL applicationIsActive = - [[UIApplication sharedApplication] applicationState] == - UIApplicationStateActive; - - [URLOpener handleLaunchOptions:launchOptions - applicationActive:applicationIsActive - tabOpener:self - startupInformation:startupInformation - appState:appState]; - } -} - -// TODO(crbug.com/1021752): Remove this stub. -- (BOOL)shouldCompletePaymentRequestOnCurrentTab: - (id<StartupInformation>)startupInformation { - return NO; -} - -- (BOOL)URLIsOpenedInRegularMode:(const GURL&)URL { - WebStateList* webStateList = self.mainTabModel.webStateList; - return webStateList && webStateList->GetIndexOfWebStateWithURL(URL) != - WebStateList::kInvalidIndex; -} #pragma mark - ApplicationCommands helpers
diff --git a/ios/chrome/app/main_controller_guts.h b/ios/chrome/app/main_controller_guts.h index e9169a8c..6972747 100644 --- a/ios/chrome/app/main_controller_guts.h +++ b/ios/chrome/app/main_controller_guts.h
@@ -7,6 +7,7 @@ #import <UIKit/UIKit.h> +#include "ios/chrome/app/startup/chrome_app_startup_parameters.h" #import "ios/chrome/browser/crash_report/crash_restore_helper.h" #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h" #import "ios/public/provider/chrome/browser/user_feedback/user_feedback_provider.h" @@ -64,8 +65,7 @@ BOOL tabSwitcherIsActive; // YES while animating the dismissal of tab switcher. -@property(nonatomic, assign, getter=dismissingTabSwitcher) - BOOL dismissingTabSwitcher; +@property(nonatomic, assign) BOOL dismissingTabSwitcher; // Returns YES if the settings are presented, either from // self.settingsNavigationController or from SigninInteractionCoordinator. @@ -104,13 +104,6 @@ - (TabGridCoordinator*)mainCoordinator; - (id<BrowserInterfaceProvider>)interfaceProvider; - (void)startVoiceSearchInCurrentBVC; - -- (void)dismissModalsAndOpenSelectedTabInMode: - (ApplicationModeForTabOpening)targetMode - withUrlLoadParams: - (const UrlLoadParams&)urlLoadParams - dismissOmnibox:(BOOL)dismissOmnibox - completion:(ProceduralBlock)completion; - (void)showTabSwitcher; // TabSwitcherDelegate helpers
diff --git a/ios/chrome/app/tab_opener_unittest.mm b/ios/chrome/app/tab_opener_unittest.mm index 8df077c..84ed59e 100644 --- a/ios/chrome/app/tab_opener_unittest.mm +++ b/ios/chrome/app/tab_opener_unittest.mm
@@ -6,9 +6,12 @@ #include "base/threading/thread.h" #import "ios/chrome/app/application_delegate/app_state.h" +#import "ios/chrome/app/application_delegate/tab_opening.h" #import "ios/chrome/app/application_delegate/url_opener.h" #include "ios/chrome/app/main_controller_private.h" #import "ios/chrome/browser/tabs/tab_model.h" +#import "ios/chrome/browser/ui/main/scene_controller.h" +#import "ios/chrome/browser/ui/main/scene_state.h" #import "ios/testing/scoped_block_swizzler.h" #include "testing/platform_test.h" #import "third_party/ocmock/OCMock/OCMock.h" @@ -50,7 +53,7 @@ swizzle_block_executed_ = YES; EXPECT_EQ(expectedLaunchOptions, options); EXPECT_EQ(expectedStartupInformation, startupInformation); - EXPECT_EQ(main_controller_, tabOpener); + EXPECT_EQ(main_controller_.sceneController, tabOpener); EXPECT_EQ(expectedAppState, appState); } copy]; URL_opening_handle_launch_swizzler_.reset(new ScopedBlockSwizzler( @@ -62,13 +65,21 @@ MainController* GetMainController() { if (!main_controller_) { + scene_state_ = [[SceneState alloc] init]; main_controller_ = [[MainController alloc] init]; + scene_controller_ = + [[SceneController alloc] initWithSceneState:scene_state_]; + main_controller_.sceneController = scene_controller_; + scene_controller_.mainController = main_controller_; } return main_controller_; } private: MainController* main_controller_; + SceneController* scene_controller_; + SceneState* scene_state_; + __block BOOL swizzle_block_executed_; HandleLaunchOptions swizzle_block_; std::unique_ptr<ScopedBlockSwizzler> URL_opening_handle_launch_swizzler_; @@ -91,7 +102,7 @@ swizzleHandleLaunchOptions(launchOptions, startupInformationMock, appStateMock); - id<TabOpening> tabOpener = GetMainController(); + id<TabOpening> tabOpener = GetMainController().sceneController; // Action. [tabOpener openTabFromLaunchOptions:launchOptions @@ -111,7 +122,7 @@ swizzleHandleLaunchOptions(nil, startupInformationMock, appStateMock); - id<TabOpening> tabOpener = GetMainController(); + id<TabOpening> tabOpener = GetMainController().sceneController; // Action. [tabOpener openTabFromLaunchOptions:nil
diff --git a/ios/chrome/browser/payments/BUILD.gn b/ios/chrome/browser/payments/BUILD.gn index f695168..ea205d3 100644 --- a/ios/chrome/browser/payments/BUILD.gn +++ b/ios/chrome/browser/payments/BUILD.gn
@@ -54,6 +54,7 @@ "//ui/base", "//url", ] + public_deps = [ "//components/autofill/core/browser" ] libs = [ "UIKit.framework" ] }
diff --git a/ios/chrome/browser/ui/infobars/coordinators/infobar_save_card_coordinator.mm b/ios/chrome/browser/ui/infobars/coordinators/infobar_save_card_coordinator.mm index 312a24f..81c53aba 100644 --- a/ios/chrome/browser/ui/infobars/coordinators/infobar_save_card_coordinator.mm +++ b/ios/chrome/browser/ui/infobars/coordinators/infobar_save_card_coordinator.mm
@@ -38,6 +38,16 @@ autofill::AutofillSaveCardInfoBarDelegateMobile* saveCardInfoBarDelegate; // YES if the Infobar has been Accepted. @property(nonatomic, assign) BOOL infobarAccepted; + +// TODO(crbug.com/1014652): Move these to future Mediator since these properties +// don't belong in the Coordinator. Cardholder Name to be saved by +// |saveCardInfoBarDelegate|. +@property(nonatomic, copy) NSString* cardholderName; +// Card Expiration month to be saved by |saveCardInfoBarDelegate|. +@property(nonatomic, copy) NSString* expirationMonth; +// Card Expiration year to be saved by |saveCardInfoBarDelegate|. +@property(nonatomic, copy) NSString* expirationYear; + @end @implementation InfobarSaveCardCoordinator @@ -67,6 +77,7 @@ initWithDelegate:self presentsModal:self.hasBadge type:InfobarType::kInfobarTypeSaveCard]; + [self.bannerViewController setButtonText:self.saveCardInfoBarDelegate->upload() ? l10n_util::GetNSString( @@ -82,6 +93,13 @@ self.saveCardInfoBarDelegate->card_label())]; self.bannerViewController.iconImage = [UIImage imageNamed:@"infobar_save_card_icon"]; + + self.cardholderName = base::SysUTF16ToNSString( + self.saveCardInfoBarDelegate->cardholder_name()); + self.expirationMonth = base::SysUTF16ToNSString( + self.saveCardInfoBarDelegate->expiration_date_month()); + self.expirationYear = base::SysUTF16ToNSString( + self.saveCardInfoBarDelegate->expiration_date_year()); } } @@ -115,7 +133,13 @@ return; } // Ignore the Accept() return value since it always returns YES. - self.saveCardInfoBarDelegate->Accept(); + DCHECK(self.cardholderName); + DCHECK(self.expirationMonth); + DCHECK(self.expirationYear); + self.saveCardInfoBarDelegate->UpdateAndAccept( + base::SysNSStringToUTF16(self.cardholderName), + base::SysNSStringToUTF16(self.expirationMonth), + base::SysNSStringToUTF16(self.expirationYear)); self.infobarAccepted = YES; } @@ -164,12 +188,9 @@ stringWithFormat:@"•••• %@", base::SysUTF16ToNSString(self.saveCardInfoBarDelegate ->card_last_four_digits())]; - self.modalViewController.cardholderName = - base::SysUTF16ToNSString(self.saveCardInfoBarDelegate->cardholder_name()); - self.modalViewController.expirationMonth = base::SysUTF16ToNSString( - self.saveCardInfoBarDelegate->expiration_date_month()); - self.modalViewController.expirationYear = base::SysUTF16ToNSString( - self.saveCardInfoBarDelegate->expiration_date_year()); + self.modalViewController.cardholderName = self.cardholderName; + self.modalViewController.expirationMonth = self.expirationMonth; + self.modalViewController.expirationYear = self.expirationYear; self.modalViewController.currentCardSaved = !self.infobarAccepted; self.modalViewController.legalMessages = [self legalMessagesForModal]; if ((base::FeatureList::IsEnabled( @@ -210,8 +231,9 @@ - (void)saveCardWithCardholderName:(NSString*)cardholderName expirationMonth:(NSString*)month expirationYear:(NSString*)year { - // TODO(crbug.com/1014652): Once editing is supported send these parameters to - // the Delegate for saving. + self.cardholderName = cardholderName; + self.expirationMonth = month; + self.expirationYear = year; [self modalInfobarButtonWasAccepted:self]; }
diff --git a/ios/chrome/browser/ui/main/BUILD.gn b/ios/chrome/browser/ui/main/BUILD.gn index 28323ef..491921d7 100644 --- a/ios/chrome/browser/ui/main/BUILD.gn +++ b/ios/chrome/browser/ui/main/BUILD.gn
@@ -30,6 +30,7 @@ ":main", ":scene_guts", "//base", + "//components/payments/core", "//components/signin/public/identity_manager", "//components/url_formatter", "//ios/chrome/app:app", @@ -40,6 +41,8 @@ "//ios/chrome/browser/browsing_data", "//ios/chrome/browser/main", "//ios/chrome/browser/ntp:features", + "//ios/chrome/browser/payments", + "//ios/chrome/browser/payments:constants", "//ios/chrome/browser/signin", "//ios/chrome/browser/snapshots", "//ios/chrome/browser/tabs:tabs",
diff --git a/ios/chrome/browser/ui/main/scene_controller.h b/ios/chrome/browser/ui/main/scene_controller.h index 39d23a2..6a37fb2 100644 --- a/ios/chrome/browser/ui/main/scene_controller.h +++ b/ios/chrome/browser/ui/main/scene_controller.h
@@ -7,6 +7,7 @@ #import <UIKit/UIKit.h> +#import "ios/chrome/app/application_delegate/tab_opening.h" #import "ios/chrome/app/application_delegate/tab_switching.h" #import "ios/chrome/browser/ui/commands/application_commands.h" #import "ios/chrome/browser/ui/main/scene_controller_guts.h" @@ -22,7 +23,8 @@ ApplicationCommands, TabSwitcherDelegate, TabSwitching, - SceneControllerGuts> + SceneControllerGuts, + TabOpening> - (instancetype)init NS_UNAVAILABLE; - (instancetype)initWithSceneState:(SceneState*)sceneState
diff --git a/ios/chrome/browser/ui/main/scene_controller.mm b/ios/chrome/browser/ui/main/scene_controller.mm index 78440be..6220189 100644 --- a/ios/chrome/browser/ui/main/scene_controller.mm +++ b/ios/chrome/browser/ui/main/scene_controller.mm
@@ -8,9 +8,12 @@ #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/strings/sys_string_conversions.h" +#include "components/payments/core/features.h" #include "components/signin/public/identity_manager/identity_manager.h" #include "components/url_formatter/url_formatter.h" +#import "ios/chrome/app/application_delegate/app_state.h" #include "ios/chrome/app/application_delegate/tab_opening.h" +#import "ios/chrome/app/application_delegate/url_opener.h" #import "ios/chrome/app/chrome_overlay_window.h" #import "ios/chrome/app/deferred_initialization_runner.h" #import "ios/chrome/app/main_controller_guts.h" @@ -22,6 +25,9 @@ #import "ios/chrome/browser/chrome_url_util.h" #include "ios/chrome/browser/main/browser.h" #include "ios/chrome/browser/ntp/features.h" +#include "ios/chrome/browser/payments/ios_payment_instrument_launcher.h" +#include "ios/chrome/browser/payments/ios_payment_instrument_launcher_factory.h" +#include "ios/chrome/browser/payments/payment_request_constants.h" #include "ios/chrome/browser/signin/identity_manager_factory.h" #import "ios/chrome/browser/snapshots/snapshot_tab_helper.h" #import "ios/chrome/browser/tabs/tab_model.h" @@ -517,11 +523,11 @@ UrlLoadParams params = UrlLoadParams::InNewTab([command URL]); params.web_params.transition_type = ui::PAGE_TRANSITION_TYPED; ProceduralBlock completion = ^{ - [self.mainController dismissModalsAndOpenSelectedTabInMode: - ApplicationModeForTabOpening::NORMAL - withUrlLoadParams:params - dismissOmnibox:YES - completion:nil]; + [self dismissModalsAndOpenSelectedTabInMode:ApplicationModeForTabOpening:: + NORMAL + withUrlLoadParams:params + dismissOmnibox:YES + completion:nil]; }; [self closeSettingsAnimated:YES completion:completion]; } @@ -616,6 +622,118 @@ return YES; } +#pragma mark - TabOpening implementation. + +- (void)dismissModalsAndOpenSelectedTabInMode: + (ApplicationModeForTabOpening)targetMode + withUrlLoadParams: + (const UrlLoadParams&)urlLoadParams + dismissOmnibox:(BOOL)dismissOmnibox + completion:(ProceduralBlock)completion { + UrlLoadParams copyOfUrlLoadParams = urlLoadParams; + [self + dismissModalDialogsWithCompletion:^{ + [self openSelectedTabInMode:targetMode + withUrlLoadParams:copyOfUrlLoadParams + completion:completion]; + } + dismissOmnibox:dismissOmnibox]; +} + +- (void)openTabFromLaunchOptions:(NSDictionary*)launchOptions + startupInformation:(id<StartupInformation>)startupInformation + appState:(AppState*)appState { + if (launchOptions) { + BOOL applicationIsActive = + [[UIApplication sharedApplication] applicationState] == + UIApplicationStateActive; + + [URLOpener handleLaunchOptions:launchOptions + applicationActive:applicationIsActive + tabOpener:self + startupInformation:startupInformation + appState:appState]; + } +} + +- (BOOL)shouldCompletePaymentRequestOnCurrentTab: + (id<StartupInformation>)startupInformation { + if (!startupInformation.startupParameters) + return NO; + + if (!startupInformation.startupParameters.completePaymentRequest) + return NO; + + if (!base::FeatureList::IsEnabled(payments::features::kWebPaymentsNativeApps)) + return NO; + + payments::IOSPaymentInstrumentLauncher* paymentAppLauncher = + payments::IOSPaymentInstrumentLauncherFactory::GetInstance() + ->GetForBrowserState(self.mainController.mainBrowserState); + + if (!paymentAppLauncher->delegate()) + return NO; + + std::string payment_id = + startupInformation.startupParameters.externalURLParams + .find(payments::kPaymentRequestIDExternal) + ->second; + if (paymentAppLauncher->payment_request_id() != payment_id) + return NO; + + std::string payment_response = + startupInformation.startupParameters.externalURLParams + .find(payments::kPaymentRequestDataExternal) + ->second; + paymentAppLauncher->ReceiveResponseFromIOSPaymentInstrument(payment_response); + [startupInformation setStartupParameters:nil]; + return YES; +} + +- (BOOL)URLIsOpenedInRegularMode:(const GURL&)URL { + WebStateList* webStateList = + self.mainController.interfaceProvider.mainInterface.tabModel.webStateList; + return webStateList && webStateList->GetIndexOfWebStateWithURL(URL) != + WebStateList::kInvalidIndex; +} + +- (ProceduralBlock)completionBlockForTriggeringAction: + (NTPTabOpeningPostOpeningAction)action { + return [self.mainController completionBlockForTriggeringAction:action]; +} + +- (BOOL)shouldOpenNTPTabOnActivationOfTabModel:(TabModel*)tabModel { + if (self.mainController.tabSwitcherIsActive) { + TabModel* mainTabModel = + self.mainController.interfaceProvider.mainInterface.tabModel; + TabModel* otrTabModel = + self.mainController.interfaceProvider.incognitoInterface.tabModel; + // Only attempt to dismiss the tab switcher and open a new tab if: + // - there are no tabs open in either tab model, and + // - the tab switcher controller is not directly or indirectly presenting + // another view controller. + if (![mainTabModel isEmpty] || ![otrTabModel isEmpty]) + return NO; + + // If the tabSwitcher is contained, check if the parent container is + // presenting another view controller. + if ([[self.mainController.tabSwitcher viewController] + .parentViewController presentedViewController]) { + return NO; + } + + // Check if the tabSwitcher is directly presenting another view controller. + if ([self.mainController.tabSwitcher viewController] + .presentedViewController) { + return NO; + } + + return YES; + } + return ![tabModel count] && [tabModel browserState] && + ![tabModel browserState] -> IsOffTheRecord(); +} + #pragma mark - AppURLLoadingServiceDelegate // Note that the current tab of |browserCoordinator|'s BVC will normally be
diff --git a/ios/chrome/browser/ui/main/scene_controller_guts.h b/ios/chrome/browser/ui/main/scene_controller_guts.h index 8f6791f..785abcc 100644 --- a/ios/chrome/browser/ui/main/scene_controller_guts.h +++ b/ios/chrome/browser/ui/main/scene_controller_guts.h
@@ -7,10 +7,13 @@ #import <UIKit/UIKit.h> +#include "ios/chrome/app/application_delegate/startup_information.h" #import "ios/chrome/app/application_delegate/tab_opening.h" #import "ios/chrome/browser/procedural_block_types.h" #import "ios/chrome/browser/url_loading/url_loading_params.h" +@class TabModel; + @protocol SceneControllerGuts - (void)closeSettingsAnimated:(BOOL)animated @@ -23,6 +26,18 @@ withUrlLoadParams:(const UrlLoadParams&)urlLoadParams completion:(ProceduralBlock)completion; +- (void)openTabFromLaunchOptions:(NSDictionary*)launchOptions + startupInformation:(id<StartupInformation>)startupInformation + appState:(AppState*)appState; + +- (void)dismissModalsAndOpenSelectedTabInMode: + (ApplicationModeForTabOpening)targetMode + withUrlLoadParams: + (const UrlLoadParams&)urlLoadParams + dismissOmnibox:(BOOL)dismissOmnibox + completion:(ProceduralBlock)completion; + +- (BOOL)shouldOpenNTPTabOnActivationOfTabModel:(TabModel*)tabModel; @end #endif // IOS_CHROME_BROWSER_UI_MAIN_SCENE_CONTROLLER_GUTS_H_
diff --git a/ios/chrome/browser/ui/settings/BUILD.gn b/ios/chrome/browser/ui/settings/BUILD.gn index 4e3c54b..38dc8c5 100644 --- a/ios/chrome/browser/ui/settings/BUILD.gn +++ b/ios/chrome/browser/ui/settings/BUILD.gn
@@ -37,9 +37,7 @@ "settings_root_table_constants.h", "settings_root_table_constants.mm", ] - deps = [ - "//base", - ] + deps = [ "//base" ] } source_set("settings") { @@ -363,6 +361,7 @@ testonly = true sources = [ "block_popups_egtest.mm", + "search_engine_settings_egtest.mm", "settings_accessibility_egtest.mm", "settings_egtest.mm", "signin_settings_egtest.mm", @@ -413,6 +412,7 @@ "//ios/web:earl_grey_test_support", "//ios/web/public/test/http_server", "//net", + "//net:test_support", "//ui/base", "//url", ] @@ -444,9 +444,7 @@ "//ios/chrome/test/app:test_support", "//third_party/breakpad:client", ] - public_deps = [ - "//components/content_settings/core/common", - ] + public_deps = [ "//components/content_settings/core/common" ] } source_set("eg_test_support+eg2") { @@ -458,12 +456,8 @@ "settings_app_interface.h", "signin_settings_app_interface.h", ] - public_deps = [ - "//components/content_settings/core/common", - ] - deps = [ - "//base", - ] + public_deps = [ "//components/content_settings/core/common" ] + deps = [ "//base" ] } source_set("eg2_tests") { @@ -475,6 +469,7 @@ testonly = true sources = [ "block_popups_egtest.mm", + "search_engine_settings_egtest.mm", "settings_accessibility_egtest.mm", "settings_egtest.mm", "signin_settings_egtest.mm", @@ -495,6 +490,7 @@ "//ios/testing/earl_grey:eg_test_support+eg2", "//ios/third_party/earl_grey2:test_lib", "//ios/web/public/test/http_server", + "//net:test_support", "//ui/base", "//url", ]
diff --git a/ios/chrome/browser/ui/settings/search_engine_settings_egtest.mm b/ios/chrome/browser/ui/settings/search_engine_settings_egtest.mm new file mode 100644 index 0000000..7207780 --- /dev/null +++ b/ios/chrome/browser/ui/settings/search_engine_settings_egtest.mm
@@ -0,0 +1,188 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/strings/sys_string_conversions.h" +#import "base/test/ios/wait_util.h" +#include "ios/chrome/grit/ios_strings.h" +#import "ios/chrome/test/earl_grey/chrome_earl_grey.h" +#import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" +#import "ios/chrome/test/earl_grey/chrome_matchers.h" +#import "ios/chrome/test/earl_grey/chrome_test_case.h" +#include "ios/testing/earl_grey/disabled_test_macros.h" +#import "ios/testing/earl_grey/earl_grey_test.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/test/embedded_test_server/http_request.h" +#include "net/test/embedded_test_server/http_response.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { + +const char kPageURL[] = "/"; +const char kOpenSearch[] = "/opensearch.xml"; +const char kSearchURL[] = "/search?q="; +const char kCustomSearchEngineName[] = "Custom Search Engine"; + +NSString* GetCustomeSearchEngineLabel() { + return [NSString stringWithFormat:@"%s, 127.0.0.1", kCustomSearchEngineName]; +} + +std::string GetSearchExample() { + return std::string(kSearchURL) + "example"; +} + +// Responses for the test http server. |server_url| is the URL of the server, +// used for absolute URL in the response. |open_search_queried| is set to true +// when the OpenSearchDescription is queried. +std::unique_ptr<net::test_server::HttpResponse> StandardResponse( + std::string* server_url, + bool* open_search_queried, + const net::test_server::HttpRequest& request) { + std::unique_ptr<net::test_server::BasicHttpResponse> http_response = + std::make_unique<net::test_server::BasicHttpResponse>(); + http_response->set_code(net::HTTP_OK); + + if (request.relative_url == kPageURL) { + http_response->set_content("<head><link rel=\"search\" " + "type=\"application/opensearchdescription+xml\" " + "title=\"Custom Search Engine\" href=\"" + + std::string(kOpenSearch) + + "\"></head><body>Test Search</body>"); + } else if (request.relative_url == kOpenSearch) { + *open_search_queried = true; + http_response->set_content( + "<OpenSearchDescription xmlns=\"http://a9.com/-/spec/opensearch/1.1/\">" + "<ShortName>" + + std::string(kCustomSearchEngineName) + + "</ShortName>" + "<Description>Description</Description>" + "<Url type=\"text/html\" method=\"get\" template=\"" + + *server_url + kSearchURL + + "{searchTerms}\"/>" + "</OpenSearchDescription>"); + } else if (request.relative_url == GetSearchExample()) { + http_response->set_content("<head><body>Search Result</body>"); + + } else { + return nullptr; + } + return std::move(http_response); +} + +} // namespace + +@interface SearchEngineSettingsTestCase : ChromeTestCase { + std::string _serverURL; + bool _openSearchCalled; +} + +@end + +@implementation SearchEngineSettingsTestCase + +// Deletes a custom search engine by swiping and tapping on the "Delete" button. +- (void)testDeleteCustomSearchEngineSwipeAndTap { + if (@available(iOS 13, *)) { + } else { + EARL_GREY_TEST_SKIPPED( + @"Test disabled on iOS 12 as this feature isn't present."); + } + [self enterSettingsWithCustomSearchEngine]; + + id<GREYMatcher> customSearchEngineCell = + grey_accessibilityLabel(GetCustomeSearchEngineLabel()); + + [[EarlGrey selectElementWithMatcher:customSearchEngineCell] + assertWithMatcher:grey_sufficientlyVisible()]; + + [[EarlGrey selectElementWithMatcher:customSearchEngineCell] + performAction:grey_swipeSlowInDirectionWithStartPoint(kGREYDirectionLeft, + 0.3, 0.5)]; + + [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(@"Delete")] + performAction:grey_tap()]; + + [[EarlGrey selectElementWithMatcher:customSearchEngineCell] + assertWithMatcher:grey_nil()]; +} + +// Deletes a custom engine by swiping it. +- (void)testDeleteCustomSearchEngineSwipe { + [self enterSettingsWithCustomSearchEngine]; + + id<GREYMatcher> customSearchEngineCell = + grey_accessibilityLabel(GetCustomeSearchEngineLabel()); + + [[EarlGrey selectElementWithMatcher:customSearchEngineCell] + performAction:grey_swipeSlowInDirectionWithStartPoint(kGREYDirectionLeft, + 0.9, 0.5)]; + + [[EarlGrey selectElementWithMatcher:customSearchEngineCell] + assertWithMatcher:grey_nil()]; +} + +// Deletes a custom search engine by entering edit mode. +- (void)testDeleteCustomSearchEngineEdit { + [self enterSettingsWithCustomSearchEngine]; + + id<GREYMatcher> editButton = grey_allOf( + chrome_test_util::ButtonWithAccessibilityLabelId( + IDS_IOS_NAVIGATION_BAR_EDIT_BUTTON), + grey_not(grey_accessibilityTrait(UIAccessibilityTraitNotEnabled)), nil); + [[EarlGrey selectElementWithMatcher:editButton] performAction:grey_tap()]; + + id<GREYMatcher> customSearchEngineCell = + grey_accessibilityLabel(GetCustomeSearchEngineLabel()); + [[EarlGrey selectElementWithMatcher:customSearchEngineCell] + assertWithMatcher:grey_sufficientlyVisible()]; + [[EarlGrey selectElementWithMatcher:customSearchEngineCell] + performAction:grey_tap()]; + + id<GREYMatcher> deleteButton = grey_allOf( + grey_accessibilityLabel(@"Delete"), + grey_accessibilityTrait(UIAccessibilityTraitButton), + grey_not(grey_accessibilityTrait(UIAccessibilityTraitNotEnabled)), nil); + [[EarlGrey selectElementWithMatcher:deleteButton] performAction:grey_tap()]; + + [[EarlGrey selectElementWithMatcher:customSearchEngineCell] + assertWithMatcher:grey_nil()]; +} + +#pragma mark - helpers + +// Adds a custom search engine by navigating to a fake search engine page, then +// enters the search engine screen in Settings. +- (void)enterSettingsWithCustomSearchEngine { + _openSearchCalled = false; + self.testServer->RegisterRequestHandler( + base::Bind(&StandardResponse, &(_serverURL), &(_openSearchCalled))); + GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); + const GURL pageURL = self.testServer->GetURL(kPageURL); + _serverURL = pageURL.spec(); + // Remove trailing "/". + _serverURL.pop_back(); + + [ChromeEarlGrey loadURL:pageURL]; + + GREYCondition* openSearchQuery = + [GREYCondition conditionWithName:@"Wait for Open Search query" + block:^BOOL { + return _openSearchCalled; + }]; + // Wait for the + GREYAssertTrue([openSearchQuery + waitWithTimeout:base::test::ios::kWaitForPageLoadTimeout], + @"The open search XML hasn't been queried."); + + [ChromeEarlGrey loadURL:self.testServer->GetURL(GetSearchExample())]; + + [ChromeEarlGreyUI openSettingsMenu]; + [[EarlGrey + selectElementWithMatcher:chrome_test_util::SettingsSearchEngineButton()] + performAction:grey_tap()]; +} + +@end
diff --git a/ios/chrome/test/earl_grey/chrome_matchers.h b/ios/chrome/test/earl_grey/chrome_matchers.h index 9be4827e..85e9d94 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers.h +++ b/ios/chrome/test/earl_grey/chrome_matchers.h
@@ -394,6 +394,9 @@ // views. id<GREYMatcher> SettingsBottomToolbarDeleteButton(); +// Returns a matcher for the search engine button in the main settings view. +id<GREYMatcher> SettingsSearchEngineButton(); + // Returns a matcher for an autofill suggestion view. id<GREYMatcher> AutofillSuggestionViewMatcher();
diff --git a/ios/chrome/test/earl_grey/chrome_matchers.mm b/ios/chrome/test/earl_grey/chrome_matchers.mm index dd91aea..c853e90 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers.mm +++ b/ios/chrome/test/earl_grey/chrome_matchers.mm
@@ -491,6 +491,10 @@ return [ChromeMatchersAppInterface settingsBottomToolbarDeleteButton]; } +id<GREYMatcher> SettingsSearchEngineButton() { + return [ChromeMatchersAppInterface settingsSearchEngineButton]; +} + id<GREYMatcher> AutofillSuggestionViewMatcher() { return [ChromeMatchersAppInterface autofillSuggestionViewMatcher]; }
diff --git a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h index abe608f..270034af 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h +++ b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h
@@ -399,6 +399,9 @@ // views. + (id<GREYMatcher>)settingsBottomToolbarDeleteButton; +// Returns a matcher for the search engine button in the main settings view. ++ (id<GREYMatcher>)settingsSearchEngineButton; + // Returns a matcher for an autofill suggestion view. + (id<GREYMatcher>)autofillSuggestionViewMatcher;
diff --git a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm index aae1d6d3..1dedb1ed 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm +++ b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm
@@ -795,6 +795,10 @@ return grey_accessibilityID(kSettingsToolbarDeleteButtonId); } ++ (id<GREYMatcher>)settingsSearchEngineButton { + return grey_accessibilityID(kSettingsSearchEngineCellId); +} + + (id<GREYMatcher>)contentViewSmallerThanScrollView { GREYMatchesBlock matches = ^BOOL(UIView* view) { UIScrollView* scrollView = base::mac::ObjCCast<UIScrollView>(view);
diff --git a/ios/web/net/cookies/wk_http_system_cookie_store_unittest.mm b/ios/web/net/cookies/wk_http_system_cookie_store_unittest.mm index 5e299a6..be40730 100644 --- a/ios/web/net/cookies/wk_http_system_cookie_store_unittest.mm +++ b/ios/web/net/cookies/wk_http_system_cookie_store_unittest.mm
@@ -25,7 +25,7 @@ // Test class that conforms to net::SystemCookieStoreTestDelegate to exercise // WKHTTPSystemCookieStore. -class WKHTTPSystemCookieStoreTestDelegate { +class API_AVAILABLE(ios(11.0)) WKHTTPSystemCookieStoreTestDelegate { public: WKHTTPSystemCookieStoreTestDelegate() { // Using off the record browser state so it will use non-persistent @@ -104,9 +104,10 @@ std::unique_ptr<web::WKHTTPSystemCookieStore> store_; }; -API_AVAILABLE(ios(11.0)) +#if defined(__IPHONE_11_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0) INSTANTIATE_TYPED_TEST_SUITE_P(WKHTTPSystemCookieStore, SystemCookieStoreTest, WKHTTPSystemCookieStoreTestDelegate); +#endif } // namespace net
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index 8d4515de..76f0748 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -652,6 +652,11 @@ const base::Feature kUseFakeDeviceForMediaStream{ "use-fake-device-for-media-stream", base::FEATURE_DISABLED_BY_DEFAULT}; +// Makes VideoCadenceEstimator use Bresenham-like algorithm for frame cadence +// estimations. +const base::Feature kBresenhamCadence{"BresenhamCadence", + base::FEATURE_DISABLED_BY_DEFAULT}; + bool IsVideoCaptureAcceleratedJpegDecodingEnabled() { if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableAcceleratedMjpegDecode)) {
diff --git a/media/base/media_switches.h b/media/base/media_switches.h index e49fcc5..b3ef729 100644 --- a/media/base/media_switches.h +++ b/media/base/media_switches.h
@@ -105,6 +105,7 @@ MEDIA_EXPORT extern const base::Feature kAutoplayDisableSettings; MEDIA_EXPORT extern const base::Feature kAutoplayWhitelistSettings; MEDIA_EXPORT extern const base::Feature kBackgroundVideoPauseOptimization; +MEDIA_EXPORT extern const base::Feature kBresenhamCadence; MEDIA_EXPORT extern const base::Feature kD3D11LimitTo11_0; MEDIA_EXPORT extern const base::Feature kD3D11PrintCodecOnCrash; MEDIA_EXPORT extern const base::Feature kD3D11VideoDecoder;
diff --git a/media/filters/video_cadence_estimator.cc b/media/filters/video_cadence_estimator.cc index 550db73..005cb57 100644 --- a/media/filters/video_cadence_estimator.cc +++ b/media/filters/video_cadence_estimator.cc
@@ -8,9 +8,11 @@ #include <cmath> #include <iterator> #include <limits> +#include <numeric> #include <string> #include "base/metrics/histogram_macros.h" +#include "media/base/media_switches.h" namespace media { @@ -87,6 +89,11 @@ pending_cadence_.clear(); cadence_changes_ = render_intervals_cadence_held_ = 0; first_update_call_ = true; + + bm_.use_bresenham_cadence_ = + base::FeatureList::IsEnabled(media::kBresenhamCadence); + bm_.perfect_cadence_.reset(); + bm_.frame_index_shift_ = 0; } bool VideoCadenceEstimator::UpdateCadenceEstimate( @@ -103,6 +110,9 @@ is_variable_frame_rate_ = false; } + if (bm_.use_bresenham_cadence_) + return UpdateBresenhamCadenceEstimate(render_interval, frame_duration); + // Variable FPS detected, turn off Cadence by force. if (is_variable_frame_rate_) { render_intervals_cadence_held_ = 0; @@ -171,9 +181,91 @@ int VideoCadenceEstimator::GetCadenceForFrame(uint64_t frame_number) const { DCHECK(has_cadence()); + if (bm_.use_bresenham_cadence_) { + double cadence = *bm_.perfect_cadence_; + auto index = frame_number + bm_.frame_index_shift_; + auto result = static_cast<uint64_t>(cadence * (index + 1)) - + static_cast<uint64_t>(cadence * index); + DCHECK(frame_number > 0 || result > 0); + return result; + } return cadence_[frame_number % cadence_.size()]; } +/* List of tests that are expected to fail when media::kBresenhamCadence + is enabled. + - VideoRendererAlgorithmTest.BestFrameByCadenceOverdisplayedForDrift + Reason: Bresenham cadence does not exhibit innate drift. + - VideoRendererAlgorithmTest.CadenceCalculations + Reason: The test inspects an internal data structures of the current alg. + - VideoRendererAlgorithmTest.VariablePlaybackRateCadence + Reason: The test assumes that cadence algorithm should fail for playback + rate of 3.15. Bresenham alg works fine. + + - VideoCadenceEstimatorTest.CadenceCalculationWithLargeDeviation + - VideoCadenceEstimatorTest.CadenceCalculationWithLargeDrift + - VideoCadenceEstimatorTest.CadenceCalculations + - VideoCadenceEstimatorTest.CadenceHystersisPreventsOscillation + - VideoCadenceEstimatorTest.CadenceVariesWithAcceptableDrift + - VideoCadenceEstimatorTest.CadenceVariesWithAcceptableGlitchTime + Reason: These tests inspects an internal data structures of the current + algorithm. +*/ +bool VideoCadenceEstimator::UpdateBresenhamCadenceEstimate( + base::TimeDelta render_interval, + base::TimeDelta frame_duration) { + if (is_variable_frame_rate_) { + if (bm_.perfect_cadence_.has_value()) { + bm_.perfect_cadence_.reset(); + return true; + } + return false; + } + + if (++render_intervals_cadence_held_ * render_interval < + cadence_hysteresis_threshold_) { + return false; + } + + double current_cadence = bm_.perfect_cadence_.value_or(0.0); + double new_cadence = + frame_duration.InMicrosecondsF() / render_interval.InMicrosecondsF(); + DCHECK(new_cadence >= 0.0); + + double cadence_relative_diff = std::abs(current_cadence - new_cadence) / + std::max(current_cadence, new_cadence); + + // Ignore tiny changes in cadence, as they are most likely just noise. + // Let's use a threshold of 0.08%, which is slightly less than NTSC frame + // rate adjustment coefficient. + constexpr double kCadenceRoundingError = 0.0008; + if (cadence_relative_diff <= kCadenceRoundingError) + return false; + + bm_.perfect_cadence_ = new_cadence; + if (render_interval > frame_duration) { + // When display refresh rate is lower than the video frame rate, + // not all frames can be shown. But we want to make sure that the very + // first frame is shown. That's why frame indexes are shifted by this + // much to make sure that the cadence sequence always has 1 in the + // beginning. + bm_.frame_index_shift_ = (render_interval.InMicroseconds() - 1) / + frame_duration.InMicroseconds(); + } else { + // It can be 0 (or anything), but it makes the output look more like + // an output of the current cadence algorithm. + bm_.frame_index_shift_ = 1; + } + + DVLOG(1) << "Cadence switch" + << " perfect_cadence: " << new_cadence + << " frame_index_shift: " << bm_.frame_index_shift_ + << " cadence_relative_diff: " << cadence_relative_diff + << " cadence_held: " << render_intervals_cadence_held_; + render_intervals_cadence_held_ = 0; + return true; +} + VideoCadenceEstimator::Cadence VideoCadenceEstimator::CalculateCadence( base::TimeDelta render_interval, base::TimeDelta frame_duration, @@ -259,4 +351,14 @@ return os.str(); } +double VideoCadenceEstimator::avg_cadence_for_testing() const { + if (!has_cadence()) + return 0.0; + if (bm_.use_bresenham_cadence_) + return bm_.perfect_cadence_.value(); + + int sum = std::accumulate(begin(cadence_), end(cadence_), 0); + return static_cast<double>(sum) / cadence_.size(); +} + } // namespace media
diff --git a/media/filters/video_cadence_estimator.h b/media/filters/video_cadence_estimator.h index c0bc0da..71cfeed6 100644 --- a/media/filters/video_cadence_estimator.h +++ b/media/filters/video_cadence_estimator.h
@@ -11,6 +11,7 @@ #include <vector> #include "base/macros.h" +#include "base/optional.h" #include "base/time/time.h" #include "media/base/media_export.h" @@ -96,7 +97,10 @@ base::TimeDelta max_acceptable_drift); // Returns true if a useful cadence was found. - bool has_cadence() const { return !cadence_.empty(); } + bool has_cadence() const { + return bm_.use_bresenham_cadence_ ? bm_.perfect_cadence_.has_value() + : !cadence_.empty(); + } // Given a |frame_number|, where zero is the most recently rendered frame, // returns the ideal cadence for that frame. @@ -113,6 +117,7 @@ cadence_hysteresis_threshold_ = threshold; } + double avg_cadence_for_testing() const; size_t cadence_size_for_testing() const { return cadence_.size(); } std::string GetCadenceForTesting() const { return CadenceToString(cadence_); } @@ -131,6 +136,9 @@ // "[a: b: ...: z]". std::string CadenceToString(const Cadence& cadence) const; + bool UpdateBresenhamCadenceEstimate(base::TimeDelta render_interval, + base::TimeDelta frame_duration); + // The approximate best N-frame cadence for all frames seen thus far; updated // by UpdateCadenceEstimate(). Empty when no cadence has been detected. Cadence cadence_; @@ -160,6 +168,20 @@ bool is_variable_frame_rate_; + // Data members related to Bresenham cadence algorithm. + // No technical reason to have this struct except for grouping related fields. + struct { + bool use_bresenham_cadence_ = false; + + // By how much to shift frame index before calculating Bresenham cadence. + int frame_index_shift_ = 0; + + // In an ideal world, each video frame would be shown for this many display + // intervals. It equals (display frequency) divided by (video frame rate). + // Absent when a video has variable frame rate. + base::Optional<double> perfect_cadence_; + } bm_; + DISALLOW_COPY_AND_ASSIGN(VideoCadenceEstimator); };
diff --git a/media/filters/video_cadence_estimator_unittest.cc b/media/filters/video_cadence_estimator_unittest.cc index 406ef620..186cba9 100644 --- a/media/filters/video_cadence_estimator_unittest.cc +++ b/media/filters/video_cadence_estimator_unittest.cc
@@ -11,6 +11,8 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "base/strings/stringprintf.h" +#include "base/test/scoped_feature_list.h" +#include "media/base/media_switches.h" #include "testing/gtest/include/gtest/gtest.h" namespace media { @@ -296,4 +298,86 @@ EXPECT_FALSE(estimator->has_cadence()); } +void VerifyCadenceSequence(VideoCadenceEstimator* estimator, + double frame_rate, + double display_rate, + std::vector<int> expected_cadence) { + SCOPED_TRACE(base::StringPrintf("Checking %.03f fps into %0.03f", frame_rate, + display_rate)); + + const base::TimeDelta render_interval = Interval(display_rate); + const base::TimeDelta frame_interval = Interval(frame_rate); + const base::TimeDelta acceptable_drift = + frame_interval < render_interval ? render_interval : frame_interval; + const base::TimeDelta test_runtime = base::TimeDelta::FromSeconds(10 * 60); + const int test_frames = test_runtime / frame_interval; + + estimator->Reset(); + EXPECT_TRUE(estimator->UpdateCadenceEstimate( + render_interval, frame_interval, base::TimeDelta(), acceptable_drift)); + EXPECT_TRUE(estimator->has_cadence()); + for (auto i = 0u; i < expected_cadence.size(); i++) { + ASSERT_EQ(expected_cadence[i], estimator->GetCadenceForFrame(i)) + << " i=" << i; + } + + int total_display_cycles = 0; + for (int i = 0; i < test_frames; i++) { + total_display_cycles += estimator->GetCadenceForFrame(i); + base::TimeDelta drift = + (total_display_cycles * render_interval) - ((i + 1) * frame_interval); + EXPECT_LE(drift.magnitude(), acceptable_drift) + << " i=" << i << " time=" << (total_display_cycles * render_interval); + if (drift.magnitude() > acceptable_drift) + break; + } +} + +TEST(VideoCadenceEstimatorTest, BresenhamTest) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(media::kBresenhamCadence); + VideoCadenceEstimator estimator(base::TimeDelta::FromSeconds(1)); + estimator.set_cadence_hysteresis_threshold_for_testing(base::TimeDelta()); + + VerifyCadenceSequence(&estimator, 30, 60, + {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}); + VerifyCadenceSequence(&estimator, NTSC(30), 60, + {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}); + VerifyCadenceSequence(&estimator, 30, NTSC(60), + {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}); + + VerifyCadenceSequence(&estimator, 25, 60, {2, 3, 2, 3, 2, 2, 3, 2}); + + VerifyCadenceSequence(&estimator, 24, 60, {3, 2, 3, 2, 3, 2, 3, 2}); + VerifyCadenceSequence(&estimator, NTSC(24), 60, {3, 2, 3, 2, 3, 2, 3, 2}); + VerifyCadenceSequence(&estimator, 24, NTSC(60), {2, 3, 2, 3, 2, 3, 2, 3, 2}); + + VerifyCadenceSequence(&estimator, 24, 50, + {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2}); + VerifyCadenceSequence(&estimator, NTSC(24), 50, + {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2}); + + VerifyCadenceSequence(&estimator, 30, 50, {2, 1, 2, 2, 1, 2, 2}); + VerifyCadenceSequence(&estimator, NTSC(30), 50, {2, 2, 1, 2, 2}); + VerifyCadenceSequence(&estimator, 120, 24, {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}); + VerifyCadenceSequence(&estimator, 60, 50, {1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0}); + VerifyCadenceSequence(&estimator, 25, 50, {2, 2, 2, 2, 2, 2, 2, 2, 2}); + + VerifyCadenceSequence(&estimator, 50, 25, {1, 0, 1, 0, 1, 0, 1, 0}); + VerifyCadenceSequence(&estimator, 120, 60, {1, 0, 1, 0, 1, 0, 1, 0}); + + // Frame rate deviation is too high, refuse to provide cadence. + EXPECT_TRUE(estimator.UpdateCadenceEstimate( + Interval(60), Interval(30), base::TimeDelta::FromMilliseconds(20), + base::TimeDelta::FromSeconds(100))); + EXPECT_FALSE(estimator.has_cadence()); + + // No cadence change for neglegable rate changes + EXPECT_TRUE(estimator.UpdateCadenceEstimate( + Interval(60), Interval(30), base::TimeDelta(), base::TimeDelta())); + EXPECT_FALSE(estimator.UpdateCadenceEstimate(Interval(60 * 1.0001), + Interval(30), base::TimeDelta(), + base::TimeDelta())); +} + } // namespace media
diff --git a/media/filters/video_renderer_algorithm_unittest.cc b/media/filters/video_renderer_algorithm_unittest.cc index 40f4f85..4da03072 100644 --- a/media/filters/video_renderer_algorithm_unittest.cc +++ b/media/filters/video_renderer_algorithm_unittest.cc
@@ -116,24 +116,11 @@ if (!is_using_cadence()) return false; - size_t size = algorithm_.cadence_estimator_.cadence_size_for_testing(); - for (size_t i = 0; i < size; ++i) { - if (!algorithm_.cadence_estimator_.GetCadenceForFrame(i)) - return true; - } - - return false; + return algorithm_.cadence_estimator_.avg_cadence_for_testing() < 1.0; } double CadenceValue() const { - int num_render_intervals = 0; - size_t size = algorithm_.cadence_estimator_.cadence_size_for_testing(); - for (size_t i = 0; i < size; ++i) { - num_render_intervals += - algorithm_.cadence_estimator_.GetCadenceForFrame(i); - } - - return (num_render_intervals + 0.0) / size; + return algorithm_.cadence_estimator_.avg_cadence_for_testing(); } size_t frames_queued() const { return algorithm_.frame_queue_.size(); }
diff --git a/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc index 2999c6f..84fa266 100644 --- a/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc
@@ -577,6 +577,14 @@ ? ImageProcessor::OutputMode::ALLOCATE : ImageProcessor::OutputMode::IMPORT); + // Start with a brand new image processor device, since the old one was + // already opened and attempting to open it again is not supported. + image_processor_device_ = V4L2Device::Create(); + if (!image_processor_device_) { + VLOGF(1) << "Could not create a V4L2Device for image processor"; + return false; + } + image_processor_ = v4l2_vda_helpers::CreateImageProcessor( *output_format_fourcc_, *gl_image_format_fourcc_, coded_size_, gl_image_size_, decoder_->GetVisibleRect().size(),
diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc index 9f32eee3..f3dbbf0 100644 --- a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
@@ -2405,6 +2405,14 @@ ? ImageProcessor::OutputMode::ALLOCATE : ImageProcessor::OutputMode::IMPORT); + // Start with a brand new image processor device, since the old one was + // already opened and attempting to open it again is not supported. + image_processor_device_ = V4L2Device::Create(); + if (!image_processor_device_) { + VLOGF(1) << "Could not create a V4L2Device for image processor"; + return false; + } + image_processor_ = v4l2_vda_helpers::CreateImageProcessor( *output_format_fourcc_, *egl_image_format_fourcc_, coded_size_, egl_image_size_, visible_size_, output_buffer_map_.size(),
diff --git a/mojo/public/tools/bindings/blink_bindings_configuration.gni b/mojo/public/tools/bindings/blink_bindings_configuration.gni index b8c0abb..5f67d5d 100644 --- a/mojo/public/tools/bindings/blink_bindings_configuration.gni +++ b/mojo/public/tools/bindings/blink_bindings_configuration.gni
@@ -9,6 +9,7 @@ _typemap_imports = [ "//cc/typemaps.gni", "//device/gamepad/public/cpp/typemaps.gni", + "//device/vr/public/mojom/blink_typemaps.gni", "//mojo/public/cpp/bindings/tests/blink_typemaps.gni", "//skia/public/mojom/typemaps.gni", "//third_party/blink/renderer/platform/mojo/blink_typemaps.gni",
diff --git a/mojo/public/tools/bindings/chromium_bindings_configuration.gni b/mojo/public/tools/bindings/chromium_bindings_configuration.gni index eae907f..a406026 100644 --- a/mojo/public/tools/bindings/chromium_bindings_configuration.gni +++ b/mojo/public/tools/bindings/chromium_bindings_configuration.gni
@@ -25,6 +25,7 @@ "//device/bluetooth/public/mojom/typemaps.gni", "//device/bluetooth/public/mojom/test/typemaps.gni", "//device/gamepad/public/cpp/typemaps.gni", + "//device/vr/public/mojom/typemaps.gni", "//fuchsia/mojom/test_typemaps.gni", "//gpu/ipc/common/typemaps.gni", "//ipc/typemaps.gni",
diff --git a/mojo/public/tools/bindings/mojom_bindings_generator.py b/mojo/public/tools/bindings/mojom_bindings_generator.py index e1d27a8..65f8e3b 100755 --- a/mojo/public/tools/bindings/mojom_bindings_generator.py +++ b/mojo/public/tools/bindings/mojom_bindings_generator.py
@@ -207,7 +207,7 @@ module = translate.OrderedModule(tree, module_path, imports) if args.scrambled_message_id_salt_paths: - salt = ''.join( + salt = b''.join( map(ReadFileContents, args.scrambled_message_id_salt_paths)) ScrambleMethodOrdinals(module.interfaces, salt)
diff --git a/services/network/public/mojom/quic_transport.mojom b/services/network/public/mojom/quic_transport.mojom index 925377d..d00ab56 100644 --- a/services/network/public/mojom/quic_transport.mojom +++ b/services/network/public/mojom/quic_transport.mojom
@@ -39,6 +39,9 @@ // A mojo interface for the client of QuicTransport. interface QuicTransportClient { + // A datagram message is sent from the server. + OnDatagramReceived(mojo_base.mojom.ReadOnlyBuffer data); + // Notifies that the server will not write data to the Stream for |stream_id|. // |fin_received| is true when FIN is received from the server. // Note that OnIncomingStreamClosed and OnOutgoingStreamClosed can both be
diff --git a/services/network/quic_transport.cc b/services/network/quic_transport.cc index 5a1a6dd..b6505aa 100644 --- a/services/network/quic_transport.cc +++ b/services/network/quic_transport.cc
@@ -513,7 +513,15 @@ } void QuicTransport::OnIncomingDatagramAvailable() { - // TODO(yhirano): Implement this. + if (torn_down_) { + return; + } + + base::Optional<std::string> datagram = transport_->session()->ReadDatagram(); + DCHECK(datagram); + + client_->OnDatagramReceived(base::make_span( + reinterpret_cast<const uint8_t*>(datagram->data()), datagram->size())); } void QuicTransport::OnCanCreateNewOutgoingBidirectionalStream() {
diff --git a/services/network/quic_transport_unittest.cc b/services/network/quic_transport_unittest.cc index 9bfcc01..dbad0ee 100644 --- a/services/network/quic_transport_unittest.cc +++ b/services/network/quic_transport_unittest.cc
@@ -115,6 +115,7 @@ } // mojom::QuicTransportClient implementation. + void OnDatagramReceived(base::span<const uint8_t> data) override {} void OnIncomingStreamClosed(uint32_t stream_id, bool fin_received) override { closed_incoming_streams_.insert(std::make_pair(stream_id, fin_received)); if (quit_closure_for_incoming_stream_closure_) { @@ -311,6 +312,9 @@ EXPECT_TRUE(result); } +// TODO(yhirano): Add a test for OnDatagramReceived. It would be difficult due +// to the flaky nature of datagrams. + TEST_F(QuicTransportTest, SendToolargeDatagram) { base::RunLoop run_loop_for_handshake; mojo::PendingRemote<mojom::QuicTransportHandshakeClient> handshake_client;
diff --git a/storage/browser/blob/blob_registry_impl.h b/storage/browser/blob/blob_registry_impl.h index c85bf665..f60fd11a 100644 --- a/storage/browser/blob/blob_registry_impl.h +++ b/storage/browser/blob/blob_registry_impl.h
@@ -32,7 +32,6 @@ virtual bool CanReadFile(const base::FilePath& file) = 0; virtual bool CanReadFileSystemFile(const FileSystemURL& url) = 0; virtual bool CanCommitURL(const GURL& url) = 0; - virtual bool IsProcessValid() = 0; }; BlobRegistryImpl(base::WeakPtr<BlobStorageContext> context,
diff --git a/storage/browser/blob/blob_url_store_impl.cc b/storage/browser/blob/blob_url_store_impl.cc index a79f0b0..0be7cc13 100644 --- a/storage/browser/blob/blob_url_store_impl.cc +++ b/storage/browser/blob/blob_url_store_impl.cc
@@ -78,12 +78,7 @@ std::move(callback).Run(); return; } - // Only report errors when we don't have permission to commit and - // the process is valid. The process check is a temporary solution to - // handle cases where this method is run after the - // process associated with |delegate_| has been destroyed. - // See https://crbug.com/933089 for details. - if (!delegate_->CanCommitURL(url) && delegate_->IsProcessValid()) { + if (!delegate_->CanCommitURL(url)) { mojo::ReportBadMessage( "Non committable URL passed to BlobURLStore::Register"); std::move(callback).Run(); @@ -107,12 +102,7 @@ mojo::ReportBadMessage("Invalid scheme passed to BlobURLStore::Revoke"); return; } - // Only report errors when we don't have permission to commit and - // the process is valid. The process check is a temporary solution to - // handle cases where this method is run after the - // process associated with |delegate_| has been destroyed. - // See https://crbug.com/933089 for details. - if (!delegate_->CanCommitURL(url) && delegate_->IsProcessValid()) { + if (!delegate_->CanCommitURL(url)) { mojo::ReportBadMessage( "Non committable URL passed to BlobURLStore::Revoke"); return;
diff --git a/storage/browser/blob/blob_url_store_impl_unittest.cc b/storage/browser/blob/blob_url_store_impl_unittest.cc index 532fff0..979e675f 100644 --- a/storage/browser/blob/blob_url_store_impl_unittest.cc +++ b/storage/browser/blob/blob_url_store_impl_unittest.cc
@@ -216,17 +216,6 @@ EXPECT_EQ(1u, bad_messages_.size()); } -TEST_F(BlobURLStoreImplTest, RevokeCantCommit_ProcessNotValid) { - delegate_.can_commit_url_result = false; - delegate_.is_process_valid_result = false; - - mojo::Remote<BlobURLStore> url_store(CreateURLStore()); - url_store->Revoke(kValidUrl); - url_store.FlushForTesting(); - EXPECT_TRUE(bad_messages_.empty()); - EXPECT_FALSE(context_->GetBlobFromPublicURL(kValidUrl)); -} - TEST_F(BlobURLStoreImplTest, RevokeURLWithFragment) { mojo::Remote<BlobURLStore> url_store(CreateURLStore()); url_store->Revoke(kFragmentUrl);
diff --git a/storage/browser/test/mock_blob_registry_delegate.cc b/storage/browser/test/mock_blob_registry_delegate.cc index f8e14fd..54489261 100644 --- a/storage/browser/test/mock_blob_registry_delegate.cc +++ b/storage/browser/test/mock_blob_registry_delegate.cc
@@ -15,8 +15,5 @@ bool MockBlobRegistryDelegate::CanCommitURL(const GURL& url) { return can_commit_url_result; } -bool MockBlobRegistryDelegate::IsProcessValid() { - return is_process_valid_result; -} } // namespace storage
diff --git a/storage/browser/test/mock_blob_registry_delegate.h b/storage/browser/test/mock_blob_registry_delegate.h index 734ebde..db68558fe 100644 --- a/storage/browser/test/mock_blob_registry_delegate.h +++ b/storage/browser/test/mock_blob_registry_delegate.h
@@ -17,12 +17,10 @@ bool CanReadFile(const base::FilePath& file) override; bool CanReadFileSystemFile(const FileSystemURL& url) override; bool CanCommitURL(const GURL& url) override; - bool IsProcessValid() override; bool can_read_file_result = true; bool can_read_file_system_file_result = true; bool can_commit_url_result = true; - bool is_process_valid_result = true; }; } // namespace storage
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index d03513b..9ffa27c 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -20349,40 +20349,6 @@ "test_target": "//content/shell:content_shell_crash_test" }, { - "isolate_name": "devtools_lint_check", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "devtools_lint_check", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test_target": "//third_party/devtools-frontend/src:devtools_lint_check" - }, - { - "isolate_name": "devtools_type_check", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "devtools_type_check", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test_target": "//third_party/devtools-frontend/src:devtools_type_check" - }, - { "isolate_name": "flatbuffers_unittests", "merge": { "args": [], @@ -22230,42 +22196,6 @@ }, { "isolate_coverage_data": true, - "isolate_name": "devtools_lint_check", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "devtools_lint_check", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test_target": "//third_party/devtools-frontend/src:devtools_lint_check" - }, - { - "isolate_coverage_data": true, - "isolate_name": "devtools_type_check", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "devtools_type_check", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test_target": "//third_party/devtools-frontend/src:devtools_type_check" - }, - { - "isolate_coverage_data": true, "isolate_name": "flatbuffers_unittests", "merge": { "args": [],
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json index 8b37f12..6f0f22a5 100644 --- a/testing/buildbot/chromium.linux.json +++ b/testing/buildbot/chromium.linux.json
@@ -4022,42 +4022,6 @@ }, { "isolate_coverage_data": true, - "isolate_name": "devtools_lint_check", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "devtools_lint_check", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test_target": "//third_party/devtools-frontend/src:devtools_lint_check" - }, - { - "isolate_coverage_data": true, - "isolate_name": "devtools_type_check", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "devtools_type_check", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test_target": "//third_party/devtools-frontend/src:devtools_type_check" - }, - { - "isolate_coverage_data": true, "isolate_name": "flatbuffers_unittests", "merge": { "args": [], @@ -5816,40 +5780,6 @@ "test_target": "//content/shell:content_shell_crash_test" }, { - "isolate_name": "devtools_lint_check", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "devtools_lint_check", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test_target": "//third_party/devtools-frontend/src:devtools_lint_check" - }, - { - "isolate_name": "devtools_type_check", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "devtools_type_check", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test_target": "//third_party/devtools-frontend/src:devtools_type_check" - }, - { "isolate_name": "flatbuffers_unittests", "merge": { "args": [], @@ -7686,40 +7616,6 @@ "test_target": "//content/shell:content_shell_crash_test" }, { - "isolate_name": "devtools_lint_check", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "devtools_lint_check", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04" - } - ] - }, - "test_target": "//third_party/devtools-frontend/src:devtools_lint_check" - }, - { - "isolate_name": "devtools_type_check", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "devtools_type_check", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04" - } - ] - }, - "test_target": "//third_party/devtools-frontend/src:devtools_type_check" - }, - { "isolate_name": "flatbuffers_unittests", "merge": { "args": [],
diff --git a/testing/buildbot/client.v8.chromium.json b/testing/buildbot/client.v8.chromium.json index 1ac0ebd..f40ff2b 100644 --- a/testing/buildbot/client.v8.chromium.json +++ b/testing/buildbot/client.v8.chromium.json
@@ -488,40 +488,6 @@ "test_target": "//content/shell:content_shell_crash_test" }, { - "isolate_name": "devtools_lint_check", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "devtools_lint_check", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test_target": "//third_party/devtools-frontend/src:devtools_lint_check" - }, - { - "isolate_name": "devtools_type_check", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "devtools_type_check", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test_target": "//third_party/devtools-frontend/src:devtools_type_check" - }, - { "isolate_name": "telemetry_gpu_unittests", "merge": { "args": [], @@ -1074,40 +1040,6 @@ "test_target": "//content/shell:content_shell_crash_test" }, { - "isolate_name": "devtools_lint_check", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "devtools_lint_check", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test_target": "//third_party/devtools-frontend/src:devtools_lint_check" - }, - { - "isolate_name": "devtools_type_check", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "devtools_type_check", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test_target": "//third_party/devtools-frontend/src:devtools_type_check" - }, - { "isolate_name": "telemetry_gpu_unittests", "merge": { "args": [],
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index ef5792b..c006b8b 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -754,22 +754,6 @@ "label": "//device:device_unittests", "type": "console_test_launcher", }, - "devtools_type_check": { - "args": [ - "../../third_party/devtools-frontend/src/scripts/test/run_type_check.py", - ], - "label": "//third_party/devtools-frontend/src:devtools_type_check", - "script": "//testing/scripts/run_devtools_check.py", - "type": "script", - }, - "devtools_lint_check": { - "args": [ - "../../third_party/devtools-frontend/src/scripts/test/run_lint_check.py", - ], - "label": "//third_party/devtools-frontend/src:devtools_lint_check", - "script": "//testing/scripts/run_devtools_check.py", - "type": "script", - }, "display_unittests": { "label": "//ui/display:display_unittests", "type": "console_test_launcher",
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 56578c2..05d64c0 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -1010,8 +1010,6 @@ 'client_v8_chromium_isolated_scripts': { 'content_shell_crash_test': {}, - 'devtools_lint_check': {}, - 'devtools_type_check': {}, 'telemetry_gpu_unittests': { 'swarming': { 'idempotent': False, # https://crbug.com/549140 @@ -2664,8 +2662,6 @@ }, 'linux_specific_chromium_isolated_scripts': { - 'devtools_lint_check': {}, - 'devtools_type_check': {}, 'not_site_per_process_webkit_layout_tests': { # not_site_per_process_webkit_layout_tests provides coverage for # running Layout Tests without site-per-process. This is the mode used
diff --git a/testing/variations/OWNERS b/testing/variations/OWNERS index dcfea59..03a77ec22 100644 --- a/testing/variations/OWNERS +++ b/testing/variations/OWNERS
@@ -1,8 +1,3 @@ file://base/metrics/OWNERS -# Use the following owners only if: -# - You work in the same area as them. -# - They are already aware of the field trial being modified. -per-file fieldtrial_testing_config.json=tbansal@chromium.org - # COMPONENT: Internals>Metrics>Variations
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 429b533..d1fdad0e 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -2641,9 +2641,16 @@ "experiments": [ { "name": "Enabled", + "params": { + "availability": "any", + "event_trigger": "name:ephemeral_tab_triggered;comparator:<2;window:90;storage:90", + "event_used": "name:ephemeral_tab_used;comparator:==0;window:90;storage:90", + "session_rate": "any" + }, "enable_features": [ "EphemeralTab", - "EphemeralTabUsingBottomSheet" + "EphemeralTabUsingBottomSheet", + "IPH_EphemeralTab" ] } ] @@ -4951,30 +4958,6 @@ ] } ], - "PreconnectSameOriginDesktop": [ - { - "platforms": [ - "windows", - "chromeos", - "mac", - "linux" - ], - "experiments": [ - { - "name": "EnabledWithExtendedSocket", - "params": { - "unused_idle_socket_timeout_seconds": "60" - }, - "enable_features": [ - "NetUnusedIdleSocketTimeout" - ], - "disable_features": [ - "NavigationPredictorPreconnectHoldback" - ] - } - ] - } - ], "PrefetchSRPAndroid": [ { "platforms": [
diff --git a/third_party/blink/public/common/BUILD.gn b/third_party/blink/public/common/BUILD.gn index 11b861d..21f938b76 100644 --- a/third_party/blink/public/common/BUILD.gn +++ b/third_party/blink/public/common/BUILD.gn
@@ -73,7 +73,6 @@ "frame/sandbox_flags.h", "frame/user_activation_state.h", "frame/user_activation_update_source.h", - "frame/user_activation_update_type.h", "http/structured_header.h", "indexeddb/indexed_db_default_mojom_traits.h", "indexeddb/indexeddb_key.h",
diff --git a/third_party/blink/public/common/frame/user_activation_update_type.h b/third_party/blink/public/common/frame/user_activation_update_type.h deleted file mode 100644 index 127f0db..0000000 --- a/third_party/blink/public/common/frame/user_activation_update_type.h +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_FRAME_USER_ACTIVATION_UPDATE_TYPE_H_ -#define THIRD_PARTY_BLINK_PUBLIC_COMMON_FRAME_USER_ACTIVATION_UPDATE_TYPE_H_ - -namespace blink { - -// Types of UserActivationV2 state updates sent between the browser and the -// renderer processes. -enum class UserActivationUpdateType { - kNotifyActivation, - kNotifyActivationPendingBrowserVerification, - kConsumeTransientActivation, - kClearActivation, - kMaxValue = kClearActivation -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_FRAME_USER_ACTIVATION_UPDATE_TYPE_H_
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn index 3704ae08..4b59f07 100644 --- a/third_party/blink/public/mojom/BUILD.gn +++ b/third_party/blink/public/mojom/BUILD.gn
@@ -56,6 +56,7 @@ "frame/lifecycle.mojom", "frame/navigation_initiator.mojom", "frame/sudden_termination_disabler_type.mojom", + "frame/user_activation_update_types.mojom", "geolocation/geolocation_service.mojom", "hid/hid.mojom", "hyphenation/hyphenation.mojom",
diff --git a/third_party/blink/public/mojom/frame/frame.mojom b/third_party/blink/public/mojom/frame/frame.mojom index d655f00..64c1648 100644 --- a/third_party/blink/public/mojom/frame/frame.mojom +++ b/third_party/blink/public/mojom/frame/frame.mojom
@@ -255,6 +255,11 @@ // (eg. the iframe, portal, or object element). DispatchLoadEventForFrameOwner(); + // Sent to the remote frame placeholder in the parent process to indicate the + // associated frame in the child process requires information about + // whether it is occluded or has visual effects applied. + SetNeedsOcclusionTracking(bool needs_tracking); + // Sent to the process that owns this frame's HTMLFrameOwnerElement to // control whether the element is collapsed or not. If the element is // collapsed, it will be removed from the layout tree of its parent
diff --git a/third_party/blink/public/mojom/frame/navigation_initiator.mojom b/third_party/blink/public/mojom/frame/navigation_initiator.mojom index 293a1c8d..9a9a58a 100644 --- a/third_party/blink/public/mojom/frame/navigation_initiator.mojom +++ b/third_party/blink/public/mojom/frame/navigation_initiator.mojom
@@ -4,12 +4,7 @@ module blink.mojom; -// Represents the disposition of a CSP violation's policy as defined in: -// https://w3c.github.io/webappsec-csp/#policy-disposition -enum WebContentSecurityPolicyType { - WebContentSecurityPolicyTypeReport, - WebContentSecurityPolicyTypeEnforce -}; +import "services/network/public/mojom/content_security_policy.mojom"; // Represents the source location of a CSP violation which contains the // three fields in: @@ -52,7 +47,7 @@ string header; // The associated disposition, which is either "enforce" or "report". - WebContentSecurityPolicyType disposition; + network.mojom.ContentSecurityPolicyType disposition; // Whether or not the violation happened after a redirect. bool after_redirect;
diff --git a/third_party/blink/public/mojom/frame/user_activation_update_types.mojom b/third_party/blink/public/mojom/frame/user_activation_update_types.mojom new file mode 100644 index 0000000..2915a58b --- /dev/null +++ b/third_party/blink/public/mojom/frame/user_activation_update_types.mojom
@@ -0,0 +1,14 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module blink.mojom; + +// Types of UserActivationV2 state updates sent between the browser and the +// renderer processes. +enum UserActivationUpdateType { + kNotifyActivation, + kNotifyActivationPendingBrowserVerification, + kConsumeTransientActivation, + kClearActivation +};
diff --git a/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h b/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h index 01dec0a4..0e26269 100644 --- a/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h +++ b/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h
@@ -234,6 +234,8 @@ void OnDisplayTypeChanged(WebMediaPlayer::DisplayType) override; + void RequestAnimationFrame() override; + private: friend class WebMediaPlayerMSTest; @@ -266,6 +268,17 @@ void SetGpuMemoryBufferVideoForTesting( media::GpuMemoryBufferVideoFramePool* gpu_memory_buffer_pool); + // Returns |compositor_|'s current frame, or |current_frame_override_| if we + // are in the middle of a rAF callback. + scoped_refptr<media::VideoFrame> GetCurrentFrame() const; + + // Callback used to fulfill video.requestAnimationFrame() requests. + void OnNewFramePresentedCallback( + scoped_refptr<media::VideoFrame> presented_frame, + base::TimeTicks presentation_time, + base::TimeTicks expected_presentation_time, + uint32_t presentation_counter); + std::unique_ptr<MediaStreamInternalFrameWrapper> internal_frame_; WebMediaPlayer::NetworkState network_state_; @@ -301,6 +314,15 @@ scoped_refptr<WebMediaStreamAudioRenderer> audio_renderer_; // Weak media::PaintCanvasVideoRenderer video_renderer_; + // Indicated whether an outstanding rAF request needs to be forwarded to + // |compositor_|. Set when RequestAnimationFrame() is called before Load(). + bool pending_raf_request_ = false; + + // Takes precedence over the compositor's current frame when painting or + // copying frames. Only set when we are in the middle of executing a + // video.requestAnimationFrame() callback. + scoped_refptr<media::VideoFrame> current_frame_override_; + bool paused_; media::VideoTransformation video_transformation_;
diff --git a/third_party/blink/public/web/web_ime_text_span.h b/third_party/blink/public/web/web_ime_text_span.h index d74342e..bf1db07 100644 --- a/third_party/blink/public/web/web_ime_text_span.h +++ b/third_party/blink/public/web/web_ime_text_span.h
@@ -59,6 +59,7 @@ start_offset(0), end_offset(0), thickness(ui::mojom::ImeTextSpanThickness::kThin), + underline_style(ui::mojom::ImeTextSpanUnderlineStyle::kSolid), background_color(0), suggestion_highlight_color(0), suggestions(std::vector<std::string>()) {} @@ -68,6 +69,7 @@ unsigned s, unsigned e, ui::mojom::ImeTextSpanThickness th, + ui::mojom::ImeTextSpanUnderlineStyle us, SkColor bc, SkColor shc = 0, const std::vector<std::string>& su = std::vector<std::string>()) @@ -75,6 +77,7 @@ start_offset(s), end_offset(e), thickness(th), + underline_style(us), background_color(bc), suggestion_highlight_color(shc), suggestions(su) {} @@ -92,6 +95,8 @@ unsigned end_offset; SkColor underline_color = SK_ColorTRANSPARENT; ui::mojom::ImeTextSpanThickness thickness; + ui::mojom::ImeTextSpanUnderlineStyle underline_style; + SkColor text_color = SK_ColorTRANSPARENT; SkColor background_color; SkColor suggestion_highlight_color; bool remove_on_finish_composing;
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h index 37169d9..f73f9a3 100644 --- a/third_party/blink/public/web/web_local_frame_client.h +++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -38,12 +38,12 @@ #include "third_party/blink/public/common/feature_policy/feature_policy.h" #include "third_party/blink/public/common/frame/frame_owner_element_type.h" #include "third_party/blink/public/common/frame/sandbox_flags.h" -#include "third_party/blink/public/common/frame/user_activation_update_type.h" #include "third_party/blink/public/common/loader/loading_behavior_flag.h" #include "third_party/blink/public/common/loader/url_loader_factory_bundle.h" #include "third_party/blink/public/common/navigation/triggering_event_info.h" #include "third_party/blink/public/mojom/frame/blocked_navigation_types.mojom-shared.h" #include "third_party/blink/public/mojom/frame/lifecycle.mojom-shared.h" +#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom-shared.h" #include "third_party/blink/public/mojom/use_counter/css_property_id.mojom-shared.h" #include "third_party/blink/public/platform/blame_context.h" #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider.h" @@ -298,8 +298,8 @@ const WebVector<WebString>& stopped_matching_selectors) {} // Replicate user activation state updates for this frame to the embedder. - virtual void UpdateUserActivationState(UserActivationUpdateType update_type) { - } + virtual void UpdateUserActivationState( + mojom::UserActivationUpdateType update_type) {} // Called when a frame is capturing mouse input, such as when a scrollbar // is being dragged.
diff --git a/third_party/blink/public/web/web_remote_frame.h b/third_party/blink/public/web/web_remote_frame.h index e57d848..7d559ef 100644 --- a/third_party/blink/public/web/web_remote_frame.h +++ b/third_party/blink/public/web/web_remote_frame.h
@@ -9,7 +9,7 @@ #include "third_party/blink/public/common/feature_policy/feature_policy.h" #include "third_party/blink/public/common/frame/frame_owner_element_type.h" #include "third_party/blink/public/common/frame/sandbox_flags.h" -#include "third_party/blink/public/common/frame/user_activation_update_type.h" +#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom-shared.h" #include "third_party/blink/public/platform/web_content_security_policy.h" #include "third_party/blink/public/platform/web_insecure_request_policy.h" #include "third_party/blink/public/web/web_frame.h" @@ -128,8 +128,6 @@ // Reports resource timing info for a navigation in this frame. virtual void ForwardResourceTimingToParent(const WebResourceTimingInfo&) = 0; - virtual void SetNeedsOcclusionTracking(bool) = 0; - virtual void DidStartLoading() = 0; virtual void DidStopLoading() = 0; @@ -138,7 +136,7 @@ // Update the user activation state in appropriate part of this frame's // "local" frame tree (ancestors-only vs all-nodes). - virtual void UpdateUserActivationState(UserActivationUpdateType) = 0; + virtual void UpdateUserActivationState(mojom::UserActivationUpdateType) = 0; // Transfers user activation state from |source_frame| to this frame, which // must be in the same frame tree as |source_frame|.
diff --git a/third_party/blink/renderer/bindings/core/v8/idl_types.h b/third_party/blink/renderer/bindings/core/v8/idl_types.h index d2c6ddd..b4e19de 100644 --- a/third_party/blink/renderer/bindings/core/v8/idl_types.h +++ b/third_party/blink/renderer/bindings/core/v8/idl_types.h
@@ -8,12 +8,13 @@ #include <type_traits> #include "base/optional.h" +#include "base/template_util.h" #include "base/time/time.h" #include "third_party/blink/renderer/bindings/core/v8/idl_types_base.h" #include "third_party/blink/renderer/bindings/core/v8/native_value_traits.h" #include "third_party/blink/renderer/bindings/core/v8/v8_string_resource.h" #include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "third_party/blink/renderer/platform/wtf/forward.h" #include "third_party/blink/renderer/platform/wtf/vector.h" namespace blink { @@ -22,6 +23,9 @@ class ScriptPromise; class ScriptValue; +// The type names below are named as "IDL" prefix + Web IDL type name. +// https://heycam.github.io/webidl/#dfn-type-name + // Boolean struct IDLBoolean final : public IDLBaseHelper<bool> {}; @@ -144,6 +148,10 @@ using ImplType = VectorOf<typename NativeValueTraits<T>::ImplType>; }; +// Frozen array types +template <typename T> +using IDLArray = IDLSequence<T>; + // Record template <typename Key, typename Value> struct IDLRecord final : public IDLBase { @@ -156,45 +164,25 @@ VectorOfPairs<String, typename NativeValueTraits<Value>::ImplType>; }; -// Nullable (T?). -// https://heycam.github.io/webidl/#idl-nullable-type -// Types without a built-in notion of nullability are mapped to -// base::Optional<T>. -template <typename InnerType, typename = void> +// Nullable +template <typename InnerType, typename SFINAEHelper = void> struct IDLNullable final : public IDLBase { - private: - using InnerTraits = NativeValueTraits<InnerType>; - using InnerResultType = - decltype(InnerTraits::NativeValue(std::declval<v8::Isolate*>(), - v8::Local<v8::Value>(), - std::declval<ExceptionState&>())); - - public: - using ResultType = base::Optional<std::decay_t<InnerResultType>>; - using ImplType = ResultType; - static inline ResultType NullValue() { return base::nullopt; } + using ImplType = + base::Optional<typename NativeValueTraits<InnerType>::ImplType>; }; template <typename InnerType> -struct IDLNullable<InnerType, - decltype(void(NativeValueTraits<InnerType>::NullValue()))> +struct IDLNullable< + InnerType, + base::void_t<decltype(NativeValueTraits<InnerType>::NullValue)>> final : public IDLBase { - private: - using InnerTraits = NativeValueTraits<InnerType>; - using InnerResultType = - decltype(InnerTraits::NativeValue(std::declval<v8::Isolate*>(), - v8::Local<v8::Value>(), - std::declval<ExceptionState&>())); - - public: - using ResultType = InnerResultType; - using ImplType = typename InnerTraits::ImplType; - static inline ResultType NullValue() { return InnerTraits::NullValue(); } + using ImplType = typename NativeValueTraits<InnerType>::ImplType; }; // EventHandler types -struct IDLEventHandler : public IDLBaseHelper<EventListener*> {}; -struct IDLOnBeforeUnloadEventHandler : public IDLBaseHelper<EventListener*> {}; -struct IDLOnErrorEventHandler : public IDLBaseHelper<EventListener*> {}; +struct IDLEventHandler final : public IDLBaseHelper<EventListener> {}; +struct IDLOnBeforeUnloadEventHandler final + : public IDLBaseHelper<EventListener> {}; +struct IDLOnErrorEventHandler final : public IDLBaseHelper<EventListener> {}; } // namespace blink
diff --git a/third_party/blink/renderer/bindings/core/v8/idl_types_base.h b/third_party/blink/renderer/bindings/core/v8/idl_types_base.h index 6f37b584..86ea6d5 100644 --- a/third_party/blink/renderer/bindings/core/v8/idl_types_base.h +++ b/third_party/blink/renderer/bindings/core/v8/idl_types_base.h
@@ -7,7 +7,7 @@ namespace blink { -// This is the base type for all WebIDL types, such as the ones defined in +// This is the base type for all Web IDL types, such as the ones defined in // idl_types.h. It is defined in a separate location to avoid circular header // inclusions when one only needs to check if a type inherits from IDLBase. struct IDLBase { @@ -18,7 +18,7 @@ // can inherit from IDLBaseHelper to avoid having to set ImplType on its own. // // Example: -// struct MyType<double> final : public IDLBaseHelper<double> {}; +// struct IDLDouble final : public IDLBaseHelper<double> {}; template <typename T> struct IDLBaseHelper : public IDLBase { using ImplType = T;
diff --git a/third_party/blink/renderer/bindings/core/v8/idl_types_test.cc b/third_party/blink/renderer/bindings/core/v8/idl_types_test.cc index 2e4af55..f898976 100644 --- a/third_party/blink/renderer/bindings/core/v8/idl_types_test.cc +++ b/third_party/blink/renderer/bindings/core/v8/idl_types_test.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/bindings/core/v8/idl_types.h" #include <type_traits> + #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h" #include "third_party/blink/renderer/bindings/core/v8/string_or_string_sequence.h" #include "third_party/blink/renderer/bindings/core/v8/v8_element.h" @@ -142,14 +143,14 @@ static_assert(std::is_base_of<IDLBase, IDLNullable<IDLDouble>>::value, "IDLNullable should have IDLBase as a base class"); -static_assert(std::is_same<IDLNullable<IDLDouble>::ResultType, +static_assert(std::is_same<IDLNullable<IDLDouble>::ImplType, base::Optional<double>>::value, "double? corresponds to base::Optional<double>"); -static_assert(std::is_same<IDLNullable<Element>::ResultType, Element*>::value, +static_assert(std::is_same<IDLNullable<Element>::ImplType, Element>::value, "Element? doesn't require a base::Optional<> wrapper"); -static_assert(std::is_same<IDLNullable<IDLString>::ResultType, String>::value, +static_assert(std::is_same<IDLNullable<IDLString>::ImplType, String>::value, "DOMString? doesn't require a base::Optional<> wrapper"); -static_assert(std::is_same<IDLNullable<StringOrStringSequence>::ResultType, +static_assert(std::is_same<IDLNullable<StringOrStringSequence>::ImplType, StringOrStringSequence>::value, "(union type)? doesn't require a base::Optional<> wrapper");
diff --git a/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc b/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc index efa7fbc..0bce9e7 100644 --- a/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc +++ b/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc
@@ -184,9 +184,9 @@ csp->BindToDelegate(*delegate); if (apply_policy) { - csp->AddPolicyFromHeaderValue(policy, - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + csp->AddPolicyFromHeaderValue( + policy, network::mojom::ContentSecurityPolicyType::kEnforce, + network::mojom::ContentSecurityPolicySource::kHTTP); } return csp;
diff --git a/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h b/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h index 12289df2..fe0a76f 100644 --- a/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h +++ b/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h
@@ -893,6 +893,8 @@ << "is not yet implemented."; return nullptr; } + + static constexpr T* NullValue() { return nullptr; } }; // Dictionary @@ -907,6 +909,8 @@ ExceptionState& exception_state) { return T::Create(isolate, value, exception_state); } + + static constexpr T* NullValue() { return nullptr; } }; // Interface @@ -937,24 +941,49 @@ }; // Nullable +// +// Types without a built-in notion of nullability are mapped to +// base::Optional<T>. template <typename InnerType> struct NativeValueTraits<IDLNullable<InnerType>> : public NativeValueTraitsBase<IDLNullable<InnerType>> { // https://heycam.github.io/webidl/#es-nullable-type - static typename IDLNullable<InnerType>::ResultType NativeValue( - v8::Isolate* isolate, - v8::Local<v8::Value> v8_value, - ExceptionState& exception_state) { - if (v8_value->IsNullOrUndefined()) - return IDLNullable<InnerType>::NullValue(); - return NativeValueTraits<InnerType>::NativeValue(isolate, v8_value, + using ImplType = + base::Optional<typename NativeValueTraits<InnerType>::ImplType>; + + static ImplType NativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exception_state) { + if (value->IsNullOrUndefined()) + return base::nullopt; + return NativeValueTraits<InnerType>::NativeValue(isolate, value, exception_state); } }; +template <typename InnerType> +struct NativeValueTraits< + IDLNullable<InnerType>, + base::void_t<decltype(NativeValueTraits<InnerType>::NullValue)>> + : public NativeValueTraitsBase<IDLNullable<InnerType>> { + // https://heycam.github.io/webidl/#es-nullable-type + using ImplType = typename NativeValueTraits<InnerType>::ImplType; + + static decltype(auto) NativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exception_state) { + if (value->IsNullOrUndefined()) + return NativeValueTraits<InnerType>::NullValue(); + return NativeValueTraits<InnerType>::NativeValue(isolate, value, + exception_state); + } +}; +// IDLNullable<IDLNullable<T>> must not be used. +template <typename T> +struct NativeValueTraits<IDLNullable<IDLNullable<T>>>; // EventHandler template <> -struct NativeValueTraits<IDLEventHandler> +struct CORE_EXPORT NativeValueTraits<IDLEventHandler> : public NativeValueTraitsBase<IDLEventHandler> { static EventListener* NativeValue(v8::Isolate* isolate, v8::Local<v8::Value> value, @@ -962,7 +991,7 @@ }; template <> -struct NativeValueTraits<IDLOnBeforeUnloadEventHandler> +struct CORE_EXPORT NativeValueTraits<IDLOnBeforeUnloadEventHandler> : public NativeValueTraitsBase<IDLOnBeforeUnloadEventHandler> { static EventListener* NativeValue(v8::Isolate* isolate, v8::Local<v8::Value> value, @@ -970,13 +999,22 @@ }; template <> -struct NativeValueTraits<IDLOnErrorEventHandler> +struct CORE_EXPORT NativeValueTraits<IDLOnErrorEventHandler> : public NativeValueTraitsBase<IDLOnErrorEventHandler> { static EventListener* NativeValue(v8::Isolate* isolate, v8::Local<v8::Value> value, ExceptionState& exception_state); }; +// EventHandler and its family are nullable, so IDLNullable<IDLEventHandler> +// must not be used. +template <> +struct NativeValueTraits<IDLNullable<IDLEventHandler>>; +template <> +struct NativeValueTraits<IDLNullable<IDLOnBeforeUnloadEventHandler>>; +template <> +struct NativeValueTraits<IDLNullable<IDLOnErrorEventHandler>>; + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_NATIVE_VALUE_TRAITS_IMPL_H_
diff --git a/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py b/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py index ad75793..c39edfa 100644 --- a/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py +++ b/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py
@@ -50,8 +50,8 @@ const_ref_t: A const-qualified reference type. value_t: The type of a variable that behaves as a value. E.g. String => String - is_nullable: True if the Blink implementation type can represent IDL null - value by itself. + has_null_value: True if the Blink implementation type can represent IDL + null value by itself without use of base::Optional<T>. """ assert isinstance(idl_type, web_idl.IdlType) @@ -62,13 +62,13 @@ ref_fmt="{}", const_ref_fmt="{}", value_fmt="{}", - is_nullable=False): + has_null_value=False): self.member_t = member_fmt.format(typename) self.ref_t = ref_fmt.format(typename) self.const_ref_t = const_ref_fmt.format(typename) self.value_t = value_fmt.format(typename) # Whether Blink impl type can represent IDL null or not. - self.is_nullable = is_nullable + self.has_null_value = has_null_value real_type = idl_type.unwrap(typedef=True) @@ -95,7 +95,7 @@ "String", ref_fmt="{}&", const_ref_fmt="const {}&", - is_nullable=True) + has_null_value=True) if real_type.is_buffer_source_type: return TypeInfo( @@ -104,7 +104,7 @@ ref_fmt="{}*", const_ref_fmt="const {}*", value_fmt="{}*", - is_nullable=True) + has_null_value=True) if real_type.is_symbol: assert False, "Blink does not support/accept IDL symbol type." @@ -114,7 +114,7 @@ "ScriptValue", ref_fmt="{}&", const_ref_fmt="const {}&", - is_nullable=True) + has_null_value=True) if real_type.is_void: assert False, "Blink does not support/accept IDL void type." @@ -127,7 +127,7 @@ ref_fmt="{}*", const_ref_fmt="const {}*", value_fmt="{}*", - is_nullable=True) + has_null_value=True) if (real_type.is_sequence or real_type.is_frozen_array or real_type.is_variadic): @@ -156,11 +156,11 @@ blink_impl_type, ref_fmt="{}&", const_ref_fmt="const {}&", - is_nullable=True) + has_null_value=True) if real_type.is_nullable: inner_type = blink_type_info(real_type.inner_type) - if inner_type.is_nullable: + if inner_type.has_null_value: return inner_type return TypeInfo( "base::Optional<{}>".format(inner_type.value_t), @@ -261,7 +261,7 @@ initializer = None # <union_type>::IsNull() by default assignment_value = "{}()".format(type_info.value_t) else: - assert not type_info.is_nullable + assert not type_info.has_null_value initializer = None # !base::Optional::has_value() by default assignment_value = "base::nullopt" elif default_value.idl_type.is_sequence:
diff --git a/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_utils.py b/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_utils.py index 5ecd708..14d2b82 100644 --- a/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_utils.py +++ b/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_utils.py
@@ -5,6 +5,7 @@ import web_idl from . import name_style +from .blink_v8_bridge import blink_type_info from .clang_format import clang_format from .code_node import CodeNode from .code_node import EmptyNode @@ -160,6 +161,61 @@ return header_paths +def collect_include_headers_of_idl_types(idl_types): + """ + Returns a set of header paths that are required by |idl_types|. + """ + header_paths = set() + + def add_header_path(idl_type): + assert isinstance(idl_type, web_idl.IdlType) + + if idl_type.is_numeric or idl_type.is_boolean or idl_type.is_typedef: + pass + elif idl_type.is_string or idl_type.is_enumeration: + header_paths.add("third_party/blink/renderer/" + "platform/wtf/text/wtf_string.h") + elif idl_type.is_buffer_source_type: + basename = name_style.file("DOM", idl_type.type_name) + header_paths.add("third_party/blink/renderer/core/typed_arrays/" + "{}.h".format(basename)) + header_paths.add( + "third_party/blink/renderer/platform/heap/handle.h") + elif idl_type.is_object or idl_type.is_any: + header_paths.add("third_party/blink/renderer/" + "bindings/core/v8/script_value.h") + elif idl_type.type_definition_object: + header_paths.add( + "third_party/blink/renderer/platform/heap/handle.h") + type_def_obj = idl_type.type_definition_object + # TODO(crbug.com/1034398): Remove this hack + if idl_type.is_dictionary: + header_paths.add(PathManager(type_def_obj).dict_path(ext="h")) + header_paths.add(PathManager(type_def_obj).api_path(ext="h")) + elif (idl_type.is_sequence or idl_type.is_frozen_array + or idl_type.is_variadic or idl_type.is_record): + header_paths.add("third_party/blink/renderer/" + "platform/wtf/vector.h") + header_paths.add("third_party/blink/renderer/" + "platform/heap/heap_allocator.h") + elif idl_type.is_promise: + header_paths.add("third_party/blink/renderer/" + "bindings/core/v8/script_promise.h") + elif idl_type.is_union: + type_def_obj = idl_type.union_definition_object + header_paths.add(PathManager(type_def_obj).api_path(ext="h")) + elif idl_type.is_nullable: + if not blink_type_info(idl_type.inner_type).has_null_value: + header_paths.add("base/optional.h") + else: + assert False, "Unknown type: {}".format(idl_type.syntactic_form) + + for idl_type in idl_types: + idl_type.apply_to_all_composing_elements(add_header_path) + + return header_paths + + def write_code_node_to_file(code_node, filepath): """Renders |code_node| and then write the result to |filepath|.""" assert isinstance(code_node, CodeNode)
diff --git a/third_party/blink/renderer/bindings/scripts/bind_gen/dictionary.py b/third_party/blink/renderer/bindings/scripts/bind_gen/dictionary.py index 3153717f..33517319 100644 --- a/third_party/blink/renderer/bindings/scripts/bind_gen/dictionary.py +++ b/third_party/blink/renderer/bindings/scripts/bind_gen/dictionary.py
@@ -27,7 +27,7 @@ from .codegen_context import CodeGenContext from .codegen_expr import expr_from_exposure from .codegen_format import format_template as _format -from .codegen_utils import collect_include_headers +from .codegen_utils import collect_include_headers_of_idl_types from .codegen_utils import component_export from .codegen_utils import enclose_with_header_guard from .codegen_utils import enclose_with_namespace @@ -642,7 +642,8 @@ base_class_header = ( "third_party/blink/renderer/platform/bindings/dictionary_base.h") header_node.accumulator.add_include_headers( - collect_include_headers(dictionary)) + collect_include_headers_of_idl_types( + [member.idl_type for member in dictionary.own_members])) header_node.accumulator.add_include_headers([ base_class_header, "v8/include/v8.h", @@ -685,8 +686,6 @@ make_forward_declarations(source_node.accumulator), TextNode(""), ]) - source_node.accumulator.add_include_headers( - collect_include_headers(dictionary)) # Assemble the parts. header_blink_ns.body.append(class_def)
diff --git a/third_party/blink/renderer/bindings/scripts/bind_gen/path_manager.py b/third_party/blink/renderer/bindings/scripts/bind_gen/path_manager.py index a5e2c54..4459b89 100644 --- a/third_party/blink/renderer/bindings/scripts/bind_gen/path_manager.py +++ b/third_party/blink/renderer/bindings/scripts/bind_gen/path_manager.py
@@ -87,6 +87,14 @@ components = sorted(idl_definition.components) # "core" < "modules" + if len(components) == 0: + assert isinstance(idl_definition, web_idl.Union) + # Unions of built-in types, e.g. DoubleOrString, do not have a + # component. + self._is_cross_components = False + default_component = web_idl.Component("core") + self._api_component = default_component + self._impl_component = default_component if len(components) == 1: component = components[0] self._is_cross_components = False
diff --git a/third_party/blink/renderer/core/dom/document_test.cc b/third_party/blink/renderer/core/dom/document_test.cc index 119ec16..6960087c 100644 --- a/third_party/blink/renderer/core/dom/document_test.cc +++ b/third_party/blink/renderer/core/dom/document_test.cc
@@ -75,6 +75,9 @@ namespace blink { +using network::mojom::ContentSecurityPolicySource; +using network::mojom::ContentSecurityPolicyType; + class DocumentTest : public PageTestBase { protected: void TearDown() override { @@ -997,8 +1000,8 @@ // Set a CSP for the main world. const char* kMainWorldCSP = "connect-src https://google.com;"; GetDocument().GetContentSecurityPolicy()->DidReceiveHeader( - kMainWorldCSP, kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + kMainWorldCSP, ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); LocalFrame* frame = GetDocument().GetFrame(); ScriptState* main_world_script_state = ToScriptStateForMainWorld(frame); @@ -1032,7 +1035,7 @@ ScriptState::Scope scope(main_world_script_state); EXPECT_THAT(get_csp_headers(), ElementsAre(CSPHeaderAndType( - {kMainWorldCSP, kContentSecurityPolicyHeaderTypeEnforce}))); + {kMainWorldCSP, ContentSecurityPolicyType::kEnforce}))); } { @@ -1043,7 +1046,7 @@ // CSP. EXPECT_THAT(get_csp_headers(), ElementsAre(CSPHeaderAndType( - {kMainWorldCSP, kContentSecurityPolicyHeaderTypeEnforce}))); + {kMainWorldCSP, ContentSecurityPolicyType::kEnforce}))); } { @@ -1063,7 +1066,7 @@ EXPECT_THAT( get_csp_headers(), ElementsAre(CSPHeaderAndType( - {kIsolatedWorldCSP, kContentSecurityPolicyHeaderTypeEnforce}))); + {kIsolatedWorldCSP, ContentSecurityPolicyType::kEnforce}))); } } }
diff --git a/third_party/blink/renderer/core/dom/live_node_list_base.cc b/third_party/blink/renderer/core/dom/live_node_list_base.cc index 3b946a5..d60ec265 100644 --- a/third_party/blink/renderer/core/dom/live_node_list_base.cc +++ b/third_party/blink/renderer/core/dom/live_node_list_base.cc
@@ -33,7 +33,7 @@ if (IsLiveNodeListType(GetType())) To<LiveNodeList>(this)->InvalidateCacheForAttribute(attr_name); else - ToHTMLCollection(this)->InvalidateCacheForAttribute(attr_name); + To<HTMLCollection>(this)->InvalidateCacheForAttribute(attr_name); } ContainerNode& LiveNodeListBase::RootNode() const {
diff --git a/third_party/blink/renderer/core/editing/ime/ime_text_span.cc b/third_party/blink/renderer/core/editing/ime/ime_text_span.cc index 6a40e770..359a0725 100644 --- a/third_party/blink/renderer/core/editing/ime/ime_text_span.cc +++ b/third_party/blink/renderer/core/editing/ime/ime_text_span.cc
@@ -14,6 +14,8 @@ unsigned end_offset, const Color& underline_color, ui::mojom::ImeTextSpanThickness thickness, + ui::mojom::ImeTextSpanUnderlineStyle underline_style, + const Color& text_color, const Color& background_color, const Color& suggestion_highlight_color, bool remove_on_finish_composing, @@ -21,6 +23,8 @@ : type_(type), underline_color_(underline_color), thickness_(thickness), + underline_style_(underline_style), + text_color_(text_color), background_color_(background_color), suggestion_highlight_color_(suggestion_highlight_color), remove_on_finish_composing_(remove_on_finish_composing), @@ -67,6 +71,8 @@ ime_text_span.end_offset, Color(ime_text_span.underline_color), ime_text_span.thickness, + ime_text_span.underline_style, + Color(ime_text_span.text_color), Color(ime_text_span.background_color), Color(ime_text_span.suggestion_highlight_color), ime_text_span.remove_on_finish_composing,
diff --git a/third_party/blink/renderer/core/editing/ime/ime_text_span.h b/third_party/blink/renderer/core/editing/ime/ime_text_span.h index 40fcf98a..5e8f42e 100644 --- a/third_party/blink/renderer/core/editing/ime/ime_text_span.h +++ b/third_party/blink/renderer/core/editing/ime/ime_text_span.h
@@ -48,6 +48,8 @@ unsigned end_offset, const Color& underline_color, ui::mojom::ImeTextSpanThickness, + ui::mojom::ImeTextSpanUnderlineStyle, + const Color& text_color, const Color& background_color, const Color& suggestion_highlight_color = Color::kTransparent, bool remove_on_finish_composing = false, @@ -60,6 +62,10 @@ unsigned EndOffset() const { return end_offset_; } const Color& UnderlineColor() const { return underline_color_; } ui::mojom::ImeTextSpanThickness Thickness() const { return thickness_; } + ui::mojom::ImeTextSpanUnderlineStyle UnderlineStyle() const { + return underline_style_; + } + const Color& TextColor() const { return text_color_; } const Color& BackgroundColor() const { return background_color_; } const Color& SuggestionHighlightColor() const { return suggestion_highlight_color_; @@ -75,6 +81,8 @@ unsigned end_offset_; Color underline_color_; ui::mojom::ImeTextSpanThickness thickness_; + ui::mojom::ImeTextSpanUnderlineStyle underline_style_; + Color text_color_; Color background_color_; Color suggestion_highlight_color_; bool remove_on_finish_composing_;
diff --git a/third_party/blink/renderer/core/editing/ime/ime_text_span_test.cc b/third_party/blink/renderer/core/editing/ime/ime_text_span_test.cc index 23131ca..5b0c502d 100644 --- a/third_party/blink/renderer/core/editing/ime/ime_text_span_test.cc +++ b/third_party/blink/renderer/core/editing/ime/ime_text_span_test.cc
@@ -14,7 +14,8 @@ return ImeTextSpan(ImeTextSpan::Type::kComposition, start_offset, end_offset, Color::kTransparent, ui::mojom::ImeTextSpanThickness::kNone, - Color::kTransparent); + ui::mojom::ImeTextSpanUnderlineStyle::kNone, + Color::kTransparent, Color::kTransparent); } TEST(ImeTextSpanTest, OneChar) {
diff --git a/third_party/blink/renderer/core/editing/ime/input_method_controller.cc b/third_party/blink/renderer/core/editing/ime/input_method_controller.cc index 6de4f3a..6235a23 100644 --- a/third_party/blink/renderer/core/editing/ime/input_method_controller.cc +++ b/third_party/blink/renderer/core/editing/ime/input_method_controller.cc
@@ -630,7 +630,8 @@ case ImeTextSpan::Type::kComposition: GetDocument().Markers().AddCompositionMarker( ephemeral_line_range, ime_text_span.UnderlineColor(), - ime_text_span.Thickness(), ime_text_span.BackgroundColor()); + ime_text_span.Thickness(), ime_text_span.UnderlineStyle(), + ime_text_span.TextColor(), ime_text_span.BackgroundColor()); break; case ImeTextSpan::Type::kSuggestion: case ImeTextSpan::Type::kMisspellingSuggestion: @@ -656,6 +657,8 @@ .SetHighlightColor(ime_text_span.SuggestionHighlightColor()) .SetUnderlineColor(ime_text_span.UnderlineColor()) .SetThickness(ime_text_span.Thickness()) + .SetUnderlineStyle(ime_text_span.UnderlineStyle()) + .SetTextColor(ime_text_span.TextColor()) .SetBackgroundColor(ime_text_span.BackgroundColor()) .SetRemoveOnFinishComposing( ime_text_span.NeedsRemovalOnFinishComposing()) @@ -948,6 +951,7 @@ GetDocument().Markers().AddCompositionMarker( CompositionEphemeralRange(), Color::kTransparent, ui::mojom::ImeTextSpanThickness::kThin, + ui::mojom::ImeTextSpanUnderlineStyle::kSolid, Color::kTransparent, LayoutTheme::GetTheme().PlatformDefaultCompositionBackgroundColor()); return; }
diff --git a/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc b/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc index 59db51c..23aec7b 100644 --- a/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc +++ b/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc
@@ -24,6 +24,7 @@ #include "third_party/blink/renderer/core/html/forms/html_text_area_element.h" using ui::mojom::ImeTextSpanThickness; +using ui::mojom::ImeTextSpanUnderlineStyle; namespace blink { @@ -169,9 +170,9 @@ "<div id='sample' contenteditable>hello world</div>", "sample"); Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); Controller().SetCompositionFromExistingText(ime_text_spans, 0, 5); Range* range = GetCompositionRange(); @@ -189,9 +190,9 @@ "<div id='sample' contenteditable>🏆</div>", "sample"); Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 2, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 2, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); GetDocument().UpdateStyleAndLayout(); Controller().SetEditableSelectionOffsets(PlainTextRange(2, 2)); @@ -217,9 +218,9 @@ InsertHTMLElement("<div id='sample' contenteditable></div>", "sample"); Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 6, 6, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 6, 6, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); GetDocument().UpdateStyleAndLayout(); // UTF16 = 0x0939 0x0947 0x0932 0x0932. Note that 0x0932 0x0932 is a grapheme @@ -245,9 +246,9 @@ InsertHTMLElement("<div id='sample' contenteditable></div>", "sample"); Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 12, 12, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 12, 12, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); GetDocument().UpdateStyleAndLayout(); // UTF16 = 0x0939 0x0947 0x0932 0x094D 0x0932 0x094B. 0x0939 0x0947 0x0932 is @@ -281,9 +282,9 @@ "sample"); Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 3, 12, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 3, 12, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); Controller().SetCompositionFromExistingText(ime_text_spans, 3, 12); // Subtract a character. @@ -312,9 +313,9 @@ "<div id='sample' contenteditable><b>🏠</b></div>", "sample"); Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 2, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 2, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); Controller().SetCompositionFromExistingText(ime_text_spans, 0, 2); @@ -338,9 +339,9 @@ "<div id='sample' contenteditable><b>ః</b></div>", "sample"); Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 2, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 2, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); Controller().SetCompositionFromExistingText(ime_text_spans, 0, 1); // 0xE0 0xB0 0x83 0xE0 0xB0 0x83, a telugu character with 2 code points in @@ -361,9 +362,9 @@ "sample"); Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 3, 12, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 3, 12, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); Controller().SetCompositionFromExistingText(ime_text_spans, 3, 12); Controller().SetComposition(String("123hello789"), ime_text_spans, 11, 11); @@ -380,9 +381,9 @@ "sample"); Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 3, 12, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 3, 12, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); Controller().SetCompositionFromExistingText(ime_text_spans, 3, 12); Controller().CommitText(String("123789"), ime_text_spans, 0); @@ -393,9 +394,9 @@ Element* div = InsertHTMLElement("<div id='sample' contenteditable></div>", "sample"); Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 11, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 11, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); Controller().CommitText(String("hello\nworld"), ime_text_spans, 0); EXPECT_EQ("hello<div>world</div>", div->InnerHTMLAsString()); @@ -419,9 +420,9 @@ "sample"); Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); Controller().SetCompositionFromExistingText(ime_text_spans, 0, 5); Controller().FinishComposingText(InputMethodController::kKeepSelection); @@ -456,9 +457,9 @@ EXPECT_EQ("foo", input->value()); Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 3, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 3, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); Controller().SetCompositionFromExistingText(ime_text_spans, 0, 3); Controller().SetComposition(String(""), ime_text_spans, 0, 3); @@ -474,9 +475,9 @@ "<div id='sample' contenteditable>\nhello world</div>", "sample"); Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); Controller().SetCompositionFromExistingText(ime_text_spans, 0, 5); Range* range = GetCompositionRange(); @@ -493,9 +494,9 @@ InsertHTMLElement("<div id='sample' contenteditable>test</div>", "sample"); Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 7, 8, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 7, 8, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); Controller().SetCompositionFromExistingText(ime_text_spans, 7, 8); EXPECT_FALSE(GetCompositionRange()); @@ -506,9 +507,9 @@ "<input id='sample' type='password' size='24'>", "sample")); Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); Controller().SetComposition("foo", ime_text_spans, 0, 3); Controller().FinishComposingText(InputMethodController::kKeepSelection); @@ -947,9 +948,9 @@ EXPECT_EQ(2u, Controller().GetSelectionOffsets().End()); Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 2, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 2, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); // The caret exceeds left boundary. // "*heABllo", where * stands for caret. @@ -1013,9 +1014,9 @@ EXPECT_EQ(17u, Controller().GetSelectionOffsets().End()); Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 2, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 2, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); // The caret exceeds left boundary. // "*hello\nworld\n\n01234AB56789", where * stands for caret. @@ -1105,13 +1106,13 @@ EXPECT_EQ(2u, Controller().GetSelectionOffsets().End()); Vector<ImeTextSpan> ime_text_spans0; - ime_text_spans0.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 0, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans0.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 0, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); Vector<ImeTextSpan> ime_text_spans2; - ime_text_spans2.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 2, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans2.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 2, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); Controller().SetComposition("AB", ime_text_spans2, 2, 2); // With previous composition. @@ -1132,9 +1133,9 @@ InsertHTMLElement("<div id='sample' contenteditable></div>", "sample"); Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); Controller().SetComposition("hello", ime_text_spans, 5, 5); EXPECT_EQ("hello", div->innerText()); EXPECT_EQ(5u, Controller().GetSelectionOffsets().Start()); @@ -1151,9 +1152,9 @@ InsertHTMLElement("<div id='sample' contenteditable></div>", "sample"); Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 2, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 2, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); Controller().CommitText("hello", ime_text_spans, 0); EXPECT_EQ("hello", div->innerText()); @@ -1184,9 +1185,9 @@ // Simulate composition in the |contentEditable|. Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); editable->focus(); GetDocument().setTitle(g_empty_string); @@ -1206,9 +1207,9 @@ // Simulate composition in the |contentEditable|. Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); GetDocument().setTitle(g_empty_string); Controller().SetComposition("hell", ime_text_spans, 4, 4); @@ -1225,9 +1226,9 @@ // Simulate composition in the |contentEditable|. Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); GetDocument().setTitle(g_empty_string); Controller().SetComposition("hello", ime_text_spans, 5, 5); @@ -1244,9 +1245,9 @@ // Simulate composition in the |contentEditable|. Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); GetDocument().setTitle(g_empty_string); Controller().SetComposition("hello", ime_text_spans, 5, 5); @@ -1264,9 +1265,9 @@ // Simulate composition in the |contentEditable|. Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); // Insert new text without previous composition. GetDocument().setTitle(g_empty_string); @@ -1292,9 +1293,9 @@ // Simulate composition in the |contentEditable|. Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); // Insert empty text without previous composition. GetDocument().setTitle(g_empty_string); @@ -1319,9 +1320,9 @@ // Simulate composition in the |contentEditable|. Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); Controller().SetComposition("hello", ime_text_spans, 1, 1); GetDocument().UpdateStyleAndLayout(); @@ -1374,9 +1375,9 @@ InsertHTMLElement("<div id='sample' contenteditable></div>", "sample"); Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 1, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 1, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); Controller().SetComposition(" ", ime_text_spans, 1, 1); @@ -1394,9 +1395,9 @@ Controller().SetEditableSelectionOffsets(PlainTextRange(8, 8)); - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 1, 11, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 1, 11, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); Controller().CommitText(String("ime_text_spand"), ime_text_spans, 0); @@ -1414,9 +1415,9 @@ Controller().SetCompositionFromExistingText(ime_text_spans, 8, 12); - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 1, 11, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 1, 11, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); Controller().CommitText(String("string"), ime_text_spans, 0); @@ -1437,9 +1438,9 @@ Controller().SetCompositionFromExistingText(ime_text_spans, 8, 8); - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); Controller().SetComposition(String("world"), ime_text_spans, 0, 0); ASSERT_EQ(1u, GetDocument().Markers().Markers().size()); @@ -1473,9 +1474,9 @@ // Simulate composition in the |contentEditable|. Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); Controller().SetComposition("foo", ime_text_spans, 3, 3); EXPECT_TRUE(Controller().HasComposition()); @@ -1520,9 +1521,9 @@ Controller().SetEditableSelectionOffsets(PlainTextRange(4, 4)); Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 3, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 3, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); Controller().SetComposition(String("def"), ime_text_spans, 0, 3); Controller().SetComposition(String(""), ime_text_spans, 0, 3); Controller().CommitText(String("def"), ime_text_spans, 0); @@ -1585,7 +1586,8 @@ // persist across editing operations) EphemeralRange marker_range = PlainTextRange(8, 12).CreateRange(*div); GetDocument().Markers().AddActiveSuggestionMarker( - marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack); + marker_range, Color::kBlack, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack); // Delete "Initial" Vector<ImeTextSpan> empty_ime_text_spans; Controller().SetCompositionFromExistingText(empty_ime_text_spans, 0, 7); @@ -1613,7 +1615,8 @@ // persist across editing operations) EphemeralRange marker_range = PlainTextRange(7, 12).CreateRange(*div); GetDocument().Markers().AddActiveSuggestionMarker( - marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack); + marker_range, Color::kBlack, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack); // Delete "Initial" Vector<ImeTextSpan> empty_ime_text_spans; Controller().SetCompositionFromExistingText(empty_ime_text_spans, 0, 7); @@ -1640,7 +1643,8 @@ // persist across editing operations) EphemeralRange marker_range = PlainTextRange(8, 13).CreateRange(*div); GetDocument().Markers().AddActiveSuggestionMarker( - marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack); + marker_range, Color::kBlack, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack); // Delete "Initial" Vector<ImeTextSpan> empty_ime_text_spans; Controller().SetCompositionFromExistingText(empty_ime_text_spans, 0, 7); @@ -1668,7 +1672,8 @@ // persist across editing operations) EphemeralRange marker_range = PlainTextRange(7, 13).CreateRange(*div); GetDocument().Markers().AddActiveSuggestionMarker( - marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack); + marker_range, Color::kBlack, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack); // Delete "Initial" Vector<ImeTextSpan> empty_ime_text_spans; @@ -1713,7 +1718,8 @@ // Add marker under "Initial text" EphemeralRange marker_range = PlainTextRange(0, 12).CreateRange(*div); GetDocument().Markers().AddActiveSuggestionMarker( - marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack); + marker_range, Color::kBlack, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack); // Replace "Initial" with "Original" Vector<ImeTextSpan> empty_ime_text_spans; @@ -1756,7 +1762,8 @@ // Add marker under "initial text" EphemeralRange marker_range = PlainTextRange(13, 25).CreateRange(*div); GetDocument().Markers().AddActiveSuggestionMarker( - marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack); + marker_range, Color::kBlack, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack); // Replace "some initial" with "boring" Vector<ImeTextSpan> empty_ime_text_spans; @@ -1794,7 +1801,8 @@ // Add marker under "Initial text" EphemeralRange marker_range = PlainTextRange(0, 12).CreateRange(*div); GetDocument().Markers().AddActiveSuggestionMarker( - marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack); + marker_range, Color::kBlack, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack); // Replace "text" with "string" Vector<ImeTextSpan> empty_ime_text_spans; @@ -1839,7 +1847,8 @@ // Add marker under "some initial" EphemeralRange marker_range = PlainTextRange(8, 20).CreateRange(*div); GetDocument().Markers().AddActiveSuggestionMarker( - marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack); + marker_range, Color::kBlack, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack); // Replace "initial text" with "content" Vector<ImeTextSpan> empty_ime_text_spans; @@ -1880,7 +1889,8 @@ // Add marker under "text" EphemeralRange marker_range = PlainTextRange(8, 12).CreateRange(*div); GetDocument().Markers().AddActiveSuggestionMarker( - marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack); + marker_range, Color::kBlack, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack); // Replace "text" with "string" Vector<ImeTextSpan> empty_ime_text_spans; @@ -1923,7 +1933,8 @@ // Add marker under "Initial" EphemeralRange marker_range = PlainTextRange(0, 7).CreateRange(*div); GetDocument().Markers().AddActiveSuggestionMarker( - marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack); + marker_range, Color::kBlack, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack); EXPECT_EQ(1u, GetDocument().Markers().Markers().size()); @@ -1965,7 +1976,8 @@ // Add marker under "text" EphemeralRange marker_range = PlainTextRange(8, 12).CreateRange(*div); GetDocument().Markers().AddActiveSuggestionMarker( - marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack); + marker_range, Color::kBlack, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack); EXPECT_EQ(1u, GetDocument().Markers().Markers().size()); @@ -2027,23 +2039,28 @@ EphemeralRange marker_range = PlainTextRange(0, 5).CreateRange(*div); GetDocument().Markers().AddActiveSuggestionMarker( - marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack); + marker_range, Color::kBlack, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack); marker_range = PlainTextRange(5, 10).CreateRange(*div); GetDocument().Markers().AddActiveSuggestionMarker( - marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack); + marker_range, Color::kBlack, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack); marker_range = PlainTextRange(10, 15).CreateRange(*div); GetDocument().Markers().AddActiveSuggestionMarker( - marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack); + marker_range, Color::kBlack, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack); marker_range = PlainTextRange(15, 20).CreateRange(*div); GetDocument().Markers().AddActiveSuggestionMarker( - marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack); + marker_range, Color::kBlack, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack); marker_range = PlainTextRange(20, 25).CreateRange(*div); GetDocument().Markers().AddActiveSuggestionMarker( - marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack); + marker_range, Color::kBlack, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack); EXPECT_EQ(5u, GetDocument().Markers().Markers().size()); @@ -2095,7 +2112,8 @@ EphemeralRange marker_range = PlainTextRange(5, 10).CreateRange(*div); GetDocument().Markers().AddActiveSuggestionMarker( - marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack); + marker_range, Color::kBlack, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, 0, Color::kBlack); EXPECT_EQ(1u, GetDocument().Markers().Markers().size()); @@ -2132,7 +2150,8 @@ EphemeralRange marker_range = PlainTextRange(5, 10).CreateRange(*div); GetDocument().Markers().AddActiveSuggestionMarker( - marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack); + marker_range, Color::kBlack, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, 0, Color::kBlack); // Delete middle of marker Vector<ImeTextSpan> empty_ime_text_spans; @@ -2187,15 +2206,18 @@ EphemeralRange marker_range = PlainTextRange(0, 5).CreateRange(*div); GetDocument().Markers().AddActiveSuggestionMarker( - marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack); + marker_range, Color::kBlack, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, 0, Color::kBlack); marker_range = PlainTextRange(5, 10).CreateRange(*div); GetDocument().Markers().AddActiveSuggestionMarker( - marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack); + marker_range, Color::kBlack, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, 0, Color::kBlack); marker_range = PlainTextRange(10, 15).CreateRange(*div); GetDocument().Markers().AddActiveSuggestionMarker( - marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack); + marker_range, Color::kBlack, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, 0, Color::kBlack); EXPECT_EQ(3u, GetDocument().Markers().Markers().size()); @@ -2259,15 +2281,18 @@ EphemeralRange marker_range = PlainTextRange(0, 5).CreateRange(*div); GetDocument().Markers().AddActiveSuggestionMarker( - marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack); + marker_range, Color::kBlack, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, 0, Color::kBlack); marker_range = PlainTextRange(5, 15).CreateRange(*div); GetDocument().Markers().AddActiveSuggestionMarker( - marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack); + marker_range, Color::kBlack, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, 0, Color::kBlack); marker_range = PlainTextRange(15, 20).CreateRange(*div); GetDocument().Markers().AddActiveSuggestionMarker( - marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack); + marker_range, Color::kBlack, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, 0, Color::kBlack); EXPECT_EQ(3u, GetDocument().Markers().Markers().size()); @@ -2297,7 +2322,8 @@ // Try to commit a non-misspelling suggestion marker. ime_text_spans.push_back( ImeTextSpan(ImeTextSpan::Type::kSuggestion, 0, 5, Color::kTransparent, - ImeTextSpanThickness::kNone, Color::kTransparent)); + ImeTextSpanThickness::kNone, ImeTextSpanUnderlineStyle::kNone, + Color::kTransparent, Color::kTransparent)); Controller().CommitText("hello", ime_text_spans, 1); // The marker should have been added. @@ -2314,7 +2340,8 @@ // Try to commit a non-misspelling suggestion marker. ime_text_spans.push_back(ImeTextSpan( ImeTextSpan::Type::kMisspellingSuggestion, 0, 5, Color::kTransparent, - ImeTextSpanThickness::kNone, Color::kTransparent)); + ImeTextSpanThickness::kNone, ImeTextSpanUnderlineStyle::kNone, + Color::kTransparent, Color::kTransparent)); Controller().CommitText("hello", ime_text_spans, 1); // The marker should not have been added since the div has spell checking @@ -2330,7 +2357,8 @@ Vector<ImeTextSpan> ime_text_spans; ime_text_spans.push_back(ImeTextSpan( ImeTextSpan::Type::kMisspellingSuggestion, 0, 5, Color::kTransparent, - ImeTextSpanThickness::kNone, Color::kTransparent, Color ::kTransparent, + ImeTextSpanThickness::kNone, ImeTextSpanUnderlineStyle::kNone, + Color::kTransparent, Color::kTransparent, Color ::kTransparent, /* remove_on_finish_composing */ true)); // Case 1: SetComposition() -> FinishComposingText() removes the suggestion @@ -2402,9 +2430,9 @@ Element* div = InsertHTMLElement( "<div id='sample' contenteditable><b>t</b>est</div>", "sample"); Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 4, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 4, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); Controller().SetCompositionFromExistingText(Vector<ImeTextSpan>(), 0, 4); Controller().SetComposition("test", ime_text_spans, 0, 4); @@ -2483,9 +2511,9 @@ InsertHTMLElement("<div id='sample' contenteditable></div>", "sample"); Vector<ImeTextSpan> ime_text_spans; - ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 1, - Color(255, 0, 0), - ImeTextSpanThickness::kThin, 0)); + ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, 1, Color(255, 0, 0), + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0)); Controller().CommitText(" ", ime_text_spans, 0); // Add character U+094D: 'DEVANAGARI SIGN VIRAMA' Controller().SetComposition(String::FromUTF8("\xE0\xA5\x8D"), ime_text_spans,
diff --git a/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.cc b/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.cc index 926d2c85..21fef20 100644 --- a/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.cc +++ b/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.cc
@@ -11,11 +11,15 @@ unsigned end_offset, Color underline_color, ui::mojom::ImeTextSpanThickness thickness, + ui::mojom::ImeTextSpanUnderlineStyle underline_style, + Color text_color, Color background_color) : StyleableMarker(start_offset, end_offset, underline_color, thickness, + underline_style, + text_color, background_color) {} DocumentMarker::MarkerType ActiveSuggestionMarker::GetType() const {
diff --git a/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.h b/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.h index 62a99d9b..645e49e 100644 --- a/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.h +++ b/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.h
@@ -18,6 +18,8 @@ unsigned end_offset, Color underline_color, ui::mojom::ImeTextSpanThickness, + ui::mojom::ImeTextSpanUnderlineStyle underline_style, + Color text_color, Color background_color); // DocumentMarker implementations
diff --git a/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_list_impl_test.cc b/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_list_impl_test.cc index 3278806..8ccff83 100644 --- a/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_list_impl_test.cc +++ b/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_list_impl_test.cc
@@ -17,7 +17,9 @@ DocumentMarker* CreateMarker(unsigned start_offset, unsigned end_offset) { return MakeGarbageCollected<ActiveSuggestionMarker>( start_offset, end_offset, Color::kTransparent, - ui::mojom::ImeTextSpanThickness::kThin, Color::kBlack); + ui::mojom::ImeTextSpanThickness::kThin, + ui::mojom::ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, + Color::kBlack); } Persistent<ActiveSuggestionMarkerListImpl> marker_list_;
diff --git a/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_test.cc b/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_test.cc index 1e3872b..2c47828 100644 --- a/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_test.cc +++ b/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_test.cc
@@ -7,6 +7,7 @@ #include "testing/gtest/include/gtest/gtest.h" using ui::mojom::ImeTextSpanThickness; +using ui::mojom::ImeTextSpanUnderlineStyle; namespace blink { @@ -15,6 +16,7 @@ TEST_F(ActiveSuggestionMarkerTest, MarkerType) { DocumentMarker* marker = MakeGarbageCollected<ActiveSuggestionMarker>( 0, 1, Color::kTransparent, ImeTextSpanThickness::kNone, + ImeTextSpanUnderlineStyle::kNone, Color::kTransparent, Color::kTransparent); EXPECT_EQ(DocumentMarker::kActiveSuggestion, marker->GetType()); } @@ -22,21 +24,28 @@ TEST_F(ActiveSuggestionMarkerTest, IsStyleableMarker) { DocumentMarker* marker = MakeGarbageCollected<ActiveSuggestionMarker>( 0, 1, Color::kTransparent, ImeTextSpanThickness::kNone, + ImeTextSpanUnderlineStyle::kNone, Color::kTransparent, Color::kTransparent); EXPECT_TRUE(IsStyleableMarker(*marker)); } TEST_F(ActiveSuggestionMarkerTest, ConstructorAndGetters) { ActiveSuggestionMarker* marker = MakeGarbageCollected<ActiveSuggestionMarker>( - 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThin, Color::kGray); + 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, Color::kTransparent, Color::kGray); EXPECT_EQ(Color::kDarkGray, marker->UnderlineColor()); EXPECT_FALSE(marker->HasThicknessThick()); + EXPECT_EQ(ImeTextSpanUnderlineStyle::kSolid, marker->UnderlineStyle()); + EXPECT_EQ(Color::kTransparent, marker->TextColor()); EXPECT_EQ(Color::kGray, marker->BackgroundColor()); ActiveSuggestionMarker* thick_marker = MakeGarbageCollected<ActiveSuggestionMarker>( - 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThick, Color::kGray); + 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThick, + ImeTextSpanUnderlineStyle::kSolid, Color::kTransparent, Color::kGray); EXPECT_EQ(true, thick_marker->HasThicknessThick()); + EXPECT_EQ(ImeTextSpanUnderlineStyle::kSolid, marker->UnderlineStyle()); + EXPECT_EQ(Color::kTransparent, marker->TextColor()); } } // namespace blink
diff --git a/third_party/blink/renderer/core/editing/markers/composition_marker.cc b/third_party/blink/renderer/core/editing/markers/composition_marker.cc index 954fa2a..d35e034 100644 --- a/third_party/blink/renderer/core/editing/markers/composition_marker.cc +++ b/third_party/blink/renderer/core/editing/markers/composition_marker.cc
@@ -6,15 +6,20 @@ namespace blink { -CompositionMarker::CompositionMarker(unsigned start_offset, - unsigned end_offset, - Color underline_color, - ui::mojom::ImeTextSpanThickness thickness, - Color background_color) +CompositionMarker::CompositionMarker( + unsigned start_offset, + unsigned end_offset, + Color underline_color, + ui::mojom::ImeTextSpanThickness thickness, + ui::mojom::ImeTextSpanUnderlineStyle underline_style, + Color text_color, + Color background_color) : StyleableMarker(start_offset, end_offset, underline_color, thickness, + underline_style, + text_color, background_color) {} DocumentMarker::MarkerType CompositionMarker::GetType() const {
diff --git a/third_party/blink/renderer/core/editing/markers/composition_marker.h b/third_party/blink/renderer/core/editing/markers/composition_marker.h index 81f853f8..994bb4fc 100644 --- a/third_party/blink/renderer/core/editing/markers/composition_marker.h +++ b/third_party/blink/renderer/core/editing/markers/composition_marker.h
@@ -20,6 +20,8 @@ unsigned end_offset, Color underline_color, ui::mojom::ImeTextSpanThickness, + ui::mojom::ImeTextSpanUnderlineStyle, + Color text_color, Color background_color); // DocumentMarker implementations
diff --git a/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl_test.cc b/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl_test.cc index d1d3b40..5760908bd 100644 --- a/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl_test.cc +++ b/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl_test.cc
@@ -18,7 +18,9 @@ DocumentMarker* CreateMarker(unsigned start_offset, unsigned end_offset) { return MakeGarbageCollected<CompositionMarker>( start_offset, end_offset, Color::kTransparent, - ui::mojom::ImeTextSpanThickness::kThin, Color::kBlack); + ui::mojom::ImeTextSpanThickness::kThin, + ui::mojom::ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, + Color::kBlack); } Persistent<CompositionMarkerListImpl> marker_list_;
diff --git a/third_party/blink/renderer/core/editing/markers/composition_marker_test.cc b/third_party/blink/renderer/core/editing/markers/composition_marker_test.cc index 5bf0d80..324c7e20 100644 --- a/third_party/blink/renderer/core/editing/markers/composition_marker_test.cc +++ b/third_party/blink/renderer/core/editing/markers/composition_marker_test.cc
@@ -7,6 +7,7 @@ #include "testing/gtest/include/gtest/gtest.h" using ui::mojom::ImeTextSpanThickness; +using ui::mojom::ImeTextSpanUnderlineStyle; namespace blink { @@ -15,6 +16,7 @@ TEST_F(CompositionMarkerTest, MarkerType) { DocumentMarker* marker = MakeGarbageCollected<CompositionMarker>( 0, 1, Color::kTransparent, ImeTextSpanThickness::kNone, + ImeTextSpanUnderlineStyle::kNone, Color::kTransparent, Color::kTransparent); EXPECT_EQ(DocumentMarker::kComposition, marker->GetType()); } @@ -22,20 +24,63 @@ TEST_F(CompositionMarkerTest, IsStyleableMarker) { DocumentMarker* marker = MakeGarbageCollected<CompositionMarker>( 0, 1, Color::kTransparent, ImeTextSpanThickness::kNone, + ImeTextSpanUnderlineStyle::kNone, Color::kTransparent, Color::kTransparent); EXPECT_TRUE(IsStyleableMarker(*marker)); } TEST_F(CompositionMarkerTest, ConstructorAndGetters) { CompositionMarker* marker = MakeGarbageCollected<CompositionMarker>( - 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThin, Color::kGray); + 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, Color::kTransparent, Color::kGray); EXPECT_EQ(Color::kDarkGray, marker->UnderlineColor()); EXPECT_TRUE(marker->HasThicknessThin()); + EXPECT_EQ(ImeTextSpanUnderlineStyle::kSolid, marker->UnderlineStyle()); + EXPECT_EQ(Color::kTransparent, marker->TextColor()); EXPECT_EQ(Color::kGray, marker->BackgroundColor()); CompositionMarker* thick_marker = MakeGarbageCollected<CompositionMarker>( - 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThick, Color::kGray); + 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThick, + ImeTextSpanUnderlineStyle::kSolid, Color::kTransparent, Color::kGray); EXPECT_TRUE(thick_marker->HasThicknessThick()); + EXPECT_EQ(ImeTextSpanUnderlineStyle::kSolid, marker->UnderlineStyle()); + EXPECT_EQ(Color::kTransparent, marker->TextColor()); +} + +TEST_F(CompositionMarkerTest, UnderlineStyleDottedAndGrayText) { + CompositionMarker* marker = MakeGarbageCollected<CompositionMarker>( + 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kDot, Color::kGray, Color::kGray); + EXPECT_EQ(Color::kDarkGray, marker->UnderlineColor()); + EXPECT_TRUE(marker->HasThicknessThin()); + EXPECT_EQ(ImeTextSpanUnderlineStyle::kDot, marker->UnderlineStyle()); + EXPECT_EQ(Color::kGray, marker->TextColor()); + EXPECT_EQ(Color::kGray, marker->BackgroundColor()); + + CompositionMarker* thick_marker = MakeGarbageCollected<CompositionMarker>( + 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThick, + ImeTextSpanUnderlineStyle::kDot, Color::kGray, Color::kGray); + EXPECT_TRUE(thick_marker->HasThicknessThick()); + EXPECT_EQ(ImeTextSpanUnderlineStyle::kDot, marker->UnderlineStyle()); + EXPECT_EQ(Color::kGray, marker->TextColor()); +} + +TEST_F(CompositionMarkerTest, UnderlineStyleDashed) { + CompositionMarker* marker = MakeGarbageCollected<CompositionMarker>( + 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kDash, Color::kTransparent, Color::kGray); + EXPECT_EQ(Color::kDarkGray, marker->UnderlineColor()); + EXPECT_TRUE(marker->HasThicknessThin()); + EXPECT_EQ(ImeTextSpanUnderlineStyle::kDash, marker->UnderlineStyle()); + EXPECT_EQ(Color::kTransparent, marker->TextColor()); + EXPECT_EQ(Color::kGray, marker->BackgroundColor()); + + CompositionMarker* thick_marker = MakeGarbageCollected<CompositionMarker>( + 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThick, + ImeTextSpanUnderlineStyle::kDash, Color::kTransparent, Color::kGray); + EXPECT_TRUE(thick_marker->HasThicknessThick()); + EXPECT_EQ(ImeTextSpanUnderlineStyle::kDash, marker->UnderlineStyle()); + EXPECT_EQ(Color::kTransparent, marker->TextColor()); } } // namespace blink
diff --git a/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc b/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc index 46a5bcb84..b694290f 100644 --- a/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc +++ b/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc
@@ -191,26 +191,34 @@ const EphemeralRange& range, Color underline_color, ui::mojom::ImeTextSpanThickness thickness, + ui::mojom::ImeTextSpanUnderlineStyle underline_style, + Color text_color, Color background_color) { DCHECK(!document_->NeedsLayoutTreeUpdate()); - AddMarkerInternal(range, [underline_color, thickness, background_color]( - int start_offset, int end_offset) { - return MakeGarbageCollected<CompositionMarker>( - start_offset, end_offset, underline_color, thickness, background_color); - }); + AddMarkerInternal(range, + [underline_color, thickness, underline_style, text_color, + background_color](int start_offset, int end_offset) { + return MakeGarbageCollected<CompositionMarker>( + start_offset, end_offset, underline_color, thickness, + underline_style, text_color, background_color); + }); } void DocumentMarkerController::AddActiveSuggestionMarker( const EphemeralRange& range, Color underline_color, ui::mojom::ImeTextSpanThickness thickness, + ui::mojom::ImeTextSpanUnderlineStyle underline_style, + Color text_color, Color background_color) { DCHECK(!document_->NeedsLayoutTreeUpdate()); - AddMarkerInternal(range, [underline_color, thickness, background_color]( - int start_offset, int end_offset) { - return MakeGarbageCollected<ActiveSuggestionMarker>( - start_offset, end_offset, underline_color, thickness, background_color); - }); + AddMarkerInternal(range, + [underline_color, thickness, underline_style, text_color, + background_color](int start_offset, int end_offset) { + return MakeGarbageCollected<ActiveSuggestionMarker>( + start_offset, end_offset, underline_color, thickness, + underline_style, text_color, background_color); + }); } void DocumentMarkerController::AddSuggestionMarker(
diff --git a/third_party/blink/renderer/core/editing/markers/document_marker_controller.h b/third_party/blink/renderer/core/editing/markers/document_marker_controller.h index bb13c084..a5d7b85 100644 --- a/third_party/blink/renderer/core/editing/markers/document_marker_controller.h +++ b/third_party/blink/renderer/core/editing/markers/document_marker_controller.h
@@ -67,10 +67,14 @@ void AddCompositionMarker(const EphemeralRange&, Color underline_color, ui::mojom::ImeTextSpanThickness, + ui::mojom::ImeTextSpanUnderlineStyle, + Color text_color, Color background_color); void AddActiveSuggestionMarker(const EphemeralRange&, Color underline_color, ui::mojom::ImeTextSpanThickness, + ui::mojom::ImeTextSpanUnderlineStyle, + Color text_color, Color background_color); void AddSuggestionMarker(const EphemeralRange&, const SuggestionMarkerProperties&);
diff --git a/third_party/blink/renderer/core/editing/markers/document_marker_controller_test.cc b/third_party/blink/renderer/core/editing/markers/document_marker_controller_test.cc index 5453ea9..641e2ac 100644 --- a/third_party/blink/renderer/core/editing/markers/document_marker_controller_test.cc +++ b/third_party/blink/renderer/core/editing/markers/document_marker_controller_test.cc
@@ -240,10 +240,14 @@ Node* text = GetDocument().body()->firstChild()->firstChild(); MarkerController().AddCompositionMarker( EphemeralRange(Position(text, 0), Position(text, 1)), Color::kTransparent, - ui::mojom::ImeTextSpanThickness::kThin, Color::kBlack); + ui::mojom::ImeTextSpanThickness::kThin, + ui::mojom::ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, + Color::kBlack); MarkerController().AddCompositionMarker( EphemeralRange(Position(text, 1), Position(text, 3)), Color::kTransparent, - ui::mojom::ImeTextSpanThickness::kThick, Color::kBlack); + ui::mojom::ImeTextSpanThickness::kThick, + ui::mojom::ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, + Color::kBlack); EXPECT_EQ(2u, MarkerController().Markers().size()); }
diff --git a/third_party/blink/renderer/core/editing/markers/styleable_marker.cc b/third_party/blink/renderer/core/editing/markers/styleable_marker.cc index 51691b29..e4bb6533 100644 --- a/third_party/blink/renderer/core/editing/markers/styleable_marker.cc +++ b/third_party/blink/renderer/core/editing/markers/styleable_marker.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/editing/markers/styleable_marker.h" using ui::mojom::ImeTextSpanThickness; +using ui::mojom::ImeTextSpanUnderlineStyle; namespace blink { @@ -12,11 +13,15 @@ unsigned end_offset, Color underline_color, ImeTextSpanThickness thickness, + ImeTextSpanUnderlineStyle underline_style, + Color text_color, Color background_color) : DocumentMarker(start_offset, end_offset), underline_color_(underline_color), background_color_(background_color), - thickness_(thickness) {} + thickness_(thickness), + underline_style_(underline_style), + text_color_(text_color) {} Color StyleableMarker::UnderlineColor() const { return underline_color_; @@ -34,6 +39,14 @@ return thickness_ == ImeTextSpanThickness::kThick; } +ui::mojom::ImeTextSpanUnderlineStyle StyleableMarker::UnderlineStyle() const { + return underline_style_; +} + +Color StyleableMarker::TextColor() const { + return text_color_; +} + bool StyleableMarker::UseTextColor() const { return thickness_ != ImeTextSpanThickness::kNone && underline_color_ == Color::kTransparent;
diff --git a/third_party/blink/renderer/core/editing/markers/styleable_marker.h b/third_party/blink/renderer/core/editing/markers/styleable_marker.h index 801afb1..13994f2 100644 --- a/third_party/blink/renderer/core/editing/markers/styleable_marker.h +++ b/third_party/blink/renderer/core/editing/markers/styleable_marker.h
@@ -19,6 +19,8 @@ unsigned end_offset, Color underline_color, ui::mojom::ImeTextSpanThickness, + ui::mojom::ImeTextSpanUnderlineStyle, + Color text_color, Color background_color); // StyleableMarker-specific @@ -26,13 +28,17 @@ bool HasThicknessNone() const; bool HasThicknessThin() const; bool HasThicknessThick() const; + ui::mojom::ImeTextSpanUnderlineStyle UnderlineStyle() const; bool UseTextColor() const; Color BackgroundColor() const; + Color TextColor() const; private: const Color underline_color_; const Color background_color_; const ui::mojom::ImeTextSpanThickness thickness_; + const ui::mojom::ImeTextSpanUnderlineStyle underline_style_; + const Color text_color_; DISALLOW_COPY_AND_ASSIGN(StyleableMarker); };
diff --git a/third_party/blink/renderer/core/editing/markers/suggestion_marker.cc b/third_party/blink/renderer/core/editing/markers/suggestion_marker.cc index 57b2533..8d4ce28 100644 --- a/third_party/blink/renderer/core/editing/markers/suggestion_marker.cc +++ b/third_party/blink/renderer/core/editing/markers/suggestion_marker.cc
@@ -17,6 +17,8 @@ end_offset, properties.UnderlineColor(), properties.Thickness(), + properties.UnderlineStyle(), + properties.TextColor(), properties.BackgroundColor()), tag_(NextTag()), suggestions_(properties.Suggestions()),
diff --git a/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.cc b/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.cc index 4e446603..95e2fff7 100644 --- a/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.cc +++ b/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.cc
@@ -70,4 +70,17 @@ return *this; } +SuggestionMarkerProperties::Builder& +SuggestionMarkerProperties::Builder::SetUnderlineStyle( + ui::mojom::ImeTextSpanUnderlineStyle underline_style) { + data_.underline_style_ = underline_style; + return *this; +} + +SuggestionMarkerProperties::Builder& +SuggestionMarkerProperties::Builder::SetTextColor(Color text_color) { + data_.text_color_ = text_color; + return *this; +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.h b/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.h index a69b47a..e6d9d22 100644 --- a/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.h +++ b/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.h
@@ -10,6 +10,7 @@ #include "third_party/blink/renderer/core/editing/markers/suggestion_marker.h" using ui::mojom::ImeTextSpanThickness; +using ui::mojom::ImeTextSpanUnderlineStyle; namespace blink { @@ -33,6 +34,8 @@ Color UnderlineColor() const { return underline_color_; } Color BackgroundColor() const { return background_color_; } ImeTextSpanThickness Thickness() const { return thickness_; } + ImeTextSpanUnderlineStyle UnderlineStyle() const { return underline_style_; } + Color TextColor() const { return text_color_; } private: SuggestionMarker::SuggestionType type_ = @@ -44,6 +47,9 @@ Color underline_color_ = Color::kTransparent; Color background_color_ = Color::kTransparent; ImeTextSpanThickness thickness_ = ImeTextSpanThickness::kThin; + ImeTextSpanUnderlineStyle underline_style_ = + ImeTextSpanUnderlineStyle::kSolid; + Color text_color_ = Color::kTransparent; }; // This class is used for building SuggestionMarkerProperties objects. @@ -63,6 +69,8 @@ Builder& SetUnderlineColor(Color); Builder& SetBackgroundColor(Color); Builder& SetThickness(ImeTextSpanThickness); + Builder& SetUnderlineStyle(ImeTextSpanUnderlineStyle); + Builder& SetTextColor(Color); private: SuggestionMarkerProperties data_;
diff --git a/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.cc b/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.cc index 75b21990..e5ef3f11 100644 --- a/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.cc +++ b/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.cc
@@ -420,6 +420,7 @@ GetDocument().Markers().AddActiveSuggestionMarker( active_suggestion_range, SK_ColorTRANSPARENT, ui::mojom::ImeTextSpanThickness::kNone, + ui::mojom::ImeTextSpanUnderlineStyle::kSolid, SK_ColorTRANSPARENT, LayoutTheme::GetTheme().PlatformActiveSpellingMarkerHighlightColor()); Vector<String> suggestions; @@ -485,6 +486,7 @@ GetDocument().Markers().AddActiveSuggestionMarker( marker_range, SK_ColorTRANSPARENT, ui::mojom::ImeTextSpanThickness::kThin, + ui::mojom::ImeTextSpanUnderlineStyle::kSolid, SK_ColorTRANSPARENT, suggestion_infos_with_node_and_highlight_color.highlight_color); is_suggestion_menu_open_ = true;
diff --git a/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller_test.cc b/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller_test.cc index 65ca6e7..d6d51da 100644 --- a/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller_test.cc +++ b/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller_test.cc
@@ -14,6 +14,7 @@ #include "third_party/blink/renderer/core/editing/visible_selection.h" using ui::mojom::ImeTextSpanThickness; +using ui::mojom::ImeTextSpanUnderlineStyle; namespace blink { @@ -56,7 +57,8 @@ GetDocument().Markers().AddActiveSuggestionMarker( EphemeralRange(Position(text, 0), Position(text, 8)), Color::kBlack, - ImeTextSpanThickness::kThin, Color::kBlack); + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, + Color::kBlack, Color::kBlack); // Select immediately before misspelling GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping( SelectionInDOMTree::Builder() @@ -237,7 +239,8 @@ // Mark "word2" as the active suggestion range GetDocument().Markers().AddActiveSuggestionMarker( EphemeralRange(Position(text, 6), Position(text, 11)), - Color::kTransparent, ImeTextSpanThickness::kThin, Color::kBlack); + Color::kTransparent, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack); // Select immediately before word2 GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping( SelectionInDOMTree::Builder() @@ -263,7 +266,8 @@ // Mark "word2" as the active suggestion range GetDocument().Markers().AddActiveSuggestionMarker( EphemeralRange(Position(text, 6), Position(text, 11)), - Color::kTransparent, ImeTextSpanThickness::kThin, Color::kBlack); + Color::kTransparent, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack); // Select immediately before word2 GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping( SelectionInDOMTree::Builder() @@ -290,7 +294,8 @@ // Mark "word1" as the active suggestion range GetDocument().Markers().AddActiveSuggestionMarker( EphemeralRange(Position(text, 0), Position(text, 5)), Color::kTransparent, - ImeTextSpanThickness::kThin, Color::kBlack); + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, + Color::kBlack, Color::kBlack); // Select immediately before word1 GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping( SelectionInDOMTree::Builder() @@ -318,7 +323,8 @@ // Mark "word1" as the active suggestion range GetDocument().Markers().AddActiveSuggestionMarker( EphemeralRange(Position(text, 0), Position(text, 5)), Color::kTransparent, - ImeTextSpanThickness::kThin, Color::kBlack); + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, + Color::kBlack, Color::kBlack); // Select immediately before word1 GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping( SelectionInDOMTree::Builder() @@ -349,7 +355,8 @@ // Mark "word2" as the active suggestion range GetDocument().Markers().AddActiveSuggestionMarker( EphemeralRange(Position(text, 5), Position(text, 10)), - Color::kTransparent, ImeTextSpanThickness::kThin, Color::kBlack); + Color::kTransparent, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack); // Select immediately before word2 GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping( SelectionInDOMTree::Builder() @@ -375,7 +382,8 @@ // Mark "word2" as the active suggestion range GetDocument().Markers().AddActiveSuggestionMarker( EphemeralRange(Position(text, 6), Position(text, 11)), - Color::kTransparent, ImeTextSpanThickness::kThin, Color::kBlack); + Color::kTransparent, ImeTextSpanThickness::kThin, + ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack); // Select immediately before word2 GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping( SelectionInDOMTree::Builder() @@ -401,7 +409,8 @@ // Mark "word1" as the active suggestion range GetDocument().Markers().AddActiveSuggestionMarker( EphemeralRange(Position(text, 0), Position(text, 5)), Color::kTransparent, - ImeTextSpanThickness::kThin, Color::kBlack); + ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, + Color::kBlack, Color::kBlack); // Select immediately before word1 GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping( SelectionInDOMTree::Builder()
diff --git a/third_party/blink/renderer/core/events/security_policy_violation_event.cc b/third_party/blink/renderer/core/events/security_policy_violation_event.cc index 2893d3b4..06e8169 100644 --- a/third_party/blink/renderer/core/events/security_policy_violation_event.cc +++ b/third_party/blink/renderer/core/events/security_policy_violation_event.cc
@@ -37,11 +37,7 @@ SecurityPolicyViolationEvent::SecurityPolicyViolationEvent( const AtomicString& type) - : Event(type, Bubbles::kYes, Cancelable::kNo, ComposedMode::kComposed), - disposition_(kContentSecurityPolicyHeaderTypeEnforce), - line_number_(0), - column_number_(0), - status_code_(0) {} + : Event(type, Bubbles::kYes, Cancelable::kNo, ComposedMode::kComposed) {} SecurityPolicyViolationEvent::SecurityPolicyViolationEvent( const AtomicString& type, @@ -60,8 +56,8 @@ if (initializer->hasOriginalPolicy()) original_policy_ = initializer->originalPolicy(); disposition_ = initializer->disposition() == kReport - ? kContentSecurityPolicyHeaderTypeReport - : kContentSecurityPolicyHeaderTypeEnforce; + ? network::mojom::ContentSecurityPolicyType::kReport + : network::mojom::ContentSecurityPolicyType::kEnforce; if (initializer->hasSourceFile()) source_file_ = initializer->sourceFile(); if (initializer->hasLineNumber()) @@ -78,9 +74,9 @@ DEFINE_STATIC_LOCAL(const String, enforce, (kEnforce)); DEFINE_STATIC_LOCAL(const String, report, (kReport)); - if (disposition_ == kContentSecurityPolicyHeaderTypeReport) - return report; - return enforce; + return disposition_ == network::mojom::ContentSecurityPolicyType::kReport + ? report + : enforce; } } // namespace blink
diff --git a/third_party/blink/renderer/core/events/security_policy_violation_event.h b/third_party/blink/renderer/core/events/security_policy_violation_event.h index 8aad17c..badacf3 100644 --- a/third_party/blink/renderer/core/events/security_policy_violation_event.h +++ b/third_party/blink/renderer/core/events/security_policy_violation_event.h
@@ -26,6 +26,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_SECURITY_POLICY_VIOLATION_EVENT_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_SECURITY_POLICY_VIOLATION_EVENT_H_ +#include "services/network/public/mojom/content_security_policy.mojom-shared.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/event_interface_names.h" #include "third_party/blink/renderer/core/events/security_policy_violation_event_init.h" @@ -79,12 +80,13 @@ String violated_directive_; String effective_directive_; String original_policy_; - ContentSecurityPolicyHeaderType disposition_; + network::mojom::ContentSecurityPolicyType disposition_ = + network::mojom::ContentSecurityPolicyType::kEnforce; String source_file_; String sample_; - int line_number_; - int column_number_; - uint16_t status_code_; + int line_number_ = 0; + int column_number_ = 0; + uint16_t status_code_ = 0; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc index b58bbdf..8266ea07 100644 --- a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc +++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
@@ -38,7 +38,7 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "third_party/blink/public/common/blob/blob_utils.h" #include "third_party/blink/public/common/feature_policy/feature_policy.h" -#include "third_party/blink/public/common/frame/user_activation_update_type.h" +#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom-blink-forward.h" #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider.h" #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider_client.h" #include "third_party/blink/public/platform/platform.h" @@ -951,11 +951,11 @@ void LocalFrameClientImpl::NotifyUserActivation( bool need_browser_verification) { DCHECK(web_frame_->Client()); - UserActivationUpdateType update_type = + mojom::blink::UserActivationUpdateType update_type = need_browser_verification - ? UserActivationUpdateType:: + ? mojom::blink::UserActivationUpdateType:: kNotifyActivationPendingBrowserVerification - : UserActivationUpdateType::kNotifyActivation; + : mojom::blink::UserActivationUpdateType::kNotifyActivation; web_frame_->Client()->UpdateUserActivationState(update_type); if (WebAutofillClient* autofill_client = web_frame_->AutofillClient()) autofill_client->UserGestureObserved(); @@ -964,7 +964,7 @@ void LocalFrameClientImpl::ConsumeTransientUserActivation() { DCHECK(web_frame_->Client()); web_frame_->Client()->UpdateUserActivationState( - UserActivationUpdateType::kConsumeTransientActivation); + mojom::blink::UserActivationUpdateType::kConsumeTransientActivation); } void LocalFrameClientImpl::AbortClientNavigation() {
diff --git a/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc b/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc index 5acc4339..702575d5 100644 --- a/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc +++ b/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc
@@ -285,9 +285,7 @@ GetFrame() ->GetSecurityContext() ->GetContentSecurityPolicy() - ->AddPolicyFromHeaderValue( - header_value, static_cast<ContentSecurityPolicyHeaderType>(type), - static_cast<ContentSecurityPolicyHeaderSource>(source)); + ->AddPolicyFromHeaderValue(header_value, type, source); } void WebRemoteFrameImpl::ResetReplicatedContentSecurityPolicy() { @@ -319,10 +317,6 @@ mojo::NullReceiver() /* worker_timing_receiver */); } -void WebRemoteFrameImpl::SetNeedsOcclusionTracking(bool needs_tracking) { - GetFrame()->View()->SetNeedsOcclusionTracking(needs_tracking); -} - void WebRemoteFrameImpl::DidStartLoading() { GetFrame()->SetIsLoading(true); } @@ -344,18 +338,19 @@ } void WebRemoteFrameImpl::UpdateUserActivationState( - UserActivationUpdateType update_type) { + mojom::blink::UserActivationUpdateType update_type) { switch (update_type) { - case UserActivationUpdateType::kNotifyActivation: + case mojom::blink::UserActivationUpdateType::kNotifyActivation: GetFrame()->NotifyUserActivationInLocalTree(); break; - case UserActivationUpdateType::kConsumeTransientActivation: + case mojom::blink::UserActivationUpdateType::kConsumeTransientActivation: GetFrame()->ConsumeTransientUserActivationInLocalTree(); break; - case UserActivationUpdateType::kClearActivation: + case mojom::blink::UserActivationUpdateType::kClearActivation: GetFrame()->ClearUserActivationInLocalTree(); break; - case UserActivationUpdateType::kNotifyActivationPendingBrowserVerification: + case mojom::blink::UserActivationUpdateType:: + kNotifyActivationPendingBrowserVerification: NOTREACHED() << "Unexpected UserActivationUpdateType from browser"; break; }
diff --git a/third_party/blink/renderer/core/exported/web_remote_frame_impl.h b/third_party/blink/renderer/core/exported/web_remote_frame_impl.h index a922c86..580cb4f1 100644 --- a/third_party/blink/renderer/core/exported/web_remote_frame_impl.h +++ b/third_party/blink/renderer/core/exported/web_remote_frame_impl.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_REMOTE_FRAME_IMPL_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_REMOTE_FRAME_IMPL_H_ +#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom-blink-forward.h" #include "third_party/blink/public/platform/web_insecure_request_policy.h" #include "third_party/blink/public/web/web_remote_frame.h" #include "third_party/blink/public/web/web_remote_frame_client.h" @@ -91,11 +92,11 @@ void SetReplicatedInsecureRequestPolicy(WebInsecureRequestPolicy) override; void SetReplicatedInsecureNavigationsSet(const WebVector<unsigned>&) override; void ForwardResourceTimingToParent(const WebResourceTimingInfo&) override; - void SetNeedsOcclusionTracking(bool) override; void DidStartLoading() override; void DidStopLoading() override; bool IsIgnoredForHitTest() const override; - void UpdateUserActivationState(UserActivationUpdateType) override; + void UpdateUserActivationState( + mojom::blink::UserActivationUpdateType) override; void TransferUserActivationFrom(blink::WebRemoteFrame* source_frame) override; void ScrollRectToVisible(const WebRect&, const WebScrollIntoViewParams&) override;
diff --git a/third_party/blink/renderer/core/exported/web_view_test.cc b/third_party/blink/renderer/core/exported/web_view_test.cc index a18cb9052..2c3edf4 100644 --- a/third_party/blink/renderer/core/exported/web_view_test.cc +++ b/third_party/blink/renderer/core/exported/web_view_test.cc
@@ -1646,8 +1646,10 @@ base_url_ + "input_field_populated.html"); web_view->SetInitialFocus(false); WebVector<WebImeTextSpan> ime_text_spans(static_cast<size_t>(1)); - ime_text_spans[0] = WebImeTextSpan(WebImeTextSpan::Type::kComposition, 0, 4, - ui::mojom::ImeTextSpanThickness::kThin, 0); + ime_text_spans[0] = + WebImeTextSpan(WebImeTextSpan::Type::kComposition, 0, 4, + ui::mojom::ImeTextSpanThickness::kThin, + ui::mojom::ImeTextSpanUnderlineStyle::kSolid, 0, 0); WebLocalFrameImpl* frame = web_view->MainFrameImpl(); WebInputMethodController* active_input_method_controller = frame->GetInputMethodController(); @@ -1673,8 +1675,10 @@ base_url_ + "text_area_populated.html"); web_view->SetInitialFocus(false); WebVector<WebImeTextSpan> ime_text_spans(static_cast<size_t>(1)); - ime_text_spans[0] = WebImeTextSpan(WebImeTextSpan::Type::kComposition, 0, 4, - ui::mojom::ImeTextSpanThickness::kThin, 0); + ime_text_spans[0] = + WebImeTextSpan(WebImeTextSpan::Type::kComposition, 0, 4, + ui::mojom::ImeTextSpanThickness::kThin, + ui::mojom::ImeTextSpanUnderlineStyle::kSolid, 0, 0); WebLocalFrameImpl* frame = web_view->MainFrameImpl(); WebInputMethodController* active_input_method_controller = frame->FrameWidget()->GetActiveWebInputMethodController(); @@ -1714,8 +1718,10 @@ base_url_ + "content_editable_rich_text.html"); web_view->SetInitialFocus(false); WebVector<WebImeTextSpan> ime_text_spans(static_cast<size_t>(1)); - ime_text_spans[0] = WebImeTextSpan(WebImeTextSpan::Type::kComposition, 0, 4, - ui::mojom::ImeTextSpanThickness::kThin, 0); + ime_text_spans[0] = + WebImeTextSpan(WebImeTextSpan::Type::kComposition, 0, 4, + ui::mojom::ImeTextSpanThickness::kThin, + ui::mojom::ImeTextSpanUnderlineStyle::kSolid, 0, 0); WebLocalFrameImpl* frame = web_view->MainFrameImpl(); frame->SetEditableSelectionOffsets(1, 1); WebDocument document = web_view->MainFrameImpl()->GetDocument();
diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy.cc b/third_party/blink/renderer/core/frame/csp/content_security_policy.cc index ead321f6..52dbbf05 100644 --- a/third_party/blink/renderer/core/frame/csp/content_security_policy.cc +++ b/third_party/blink/renderer/core/frame/csp/content_security_policy.cc
@@ -73,20 +73,23 @@ namespace blink { +using network::mojom::ContentSecurityPolicySource; +using network::mojom::ContentSecurityPolicyType; + namespace { // Helper function that returns true if the given |header_type| should be // checked when the CheckHeaderType is |check_header_type|. bool CheckHeaderTypeMatches( ContentSecurityPolicy::CheckHeaderType check_header_type, - ContentSecurityPolicyHeaderType header_type) { + ContentSecurityPolicyType header_type) { switch (check_header_type) { case ContentSecurityPolicy::CheckHeaderType::kCheckAll: return true; case ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly: - return header_type == kContentSecurityPolicyHeaderTypeReport; + return header_type == ContentSecurityPolicyType::kReport; case ContentSecurityPolicy::CheckHeaderType::kCheckEnforce: - return header_type == kContentSecurityPolicyHeaderTypeEnforce; + return header_type == ContentSecurityPolicyType::kEnforce; } NOTREACHED(); return false; @@ -135,12 +138,11 @@ return nonceable; } -static WebFeature GetUseCounterHelperType( - ContentSecurityPolicyHeaderType type) { +static WebFeature GetUseCounterHelperType(ContentSecurityPolicyType type) { switch (type) { - case kContentSecurityPolicyHeaderTypeEnforce: + case ContentSecurityPolicyType::kEnforce: return WebFeature::kContentSecurityPolicy; - case kContentSecurityPolicyHeaderTypeReport: + case ContentSecurityPolicyType::kReport: return WebFeature::kContentSecurityPolicyReportOnly; } NOTREACHED(); @@ -261,23 +263,24 @@ void ContentSecurityPolicy::DidReceiveHeaders( const ContentSecurityPolicyResponseHeaders& headers) { - if (headers.ShouldParseWasmEval()) { + if (headers.ShouldParseWasmEval()) supports_wasm_eval_ = true; - } - if (!headers.ContentSecurityPolicy().IsEmpty()) + if (!headers.ContentSecurityPolicy().IsEmpty()) { AddAndReportPolicyFromHeaderValue(headers.ContentSecurityPolicy(), - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); - if (!headers.ContentSecurityPolicyReportOnly().IsEmpty()) + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); + } + if (!headers.ContentSecurityPolicyReportOnly().IsEmpty()) { AddAndReportPolicyFromHeaderValue(headers.ContentSecurityPolicyReportOnly(), - kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kReport, + ContentSecurityPolicySource::kHTTP); + } } void ContentSecurityPolicy::DidReceiveHeader( const String& header, - ContentSecurityPolicyHeaderType type, - ContentSecurityPolicyHeaderSource source) { + ContentSecurityPolicyType type, + ContentSecurityPolicySource source) { AddAndReportPolicyFromHeaderValue(header, type, source); // This might be called after we've been bound to a delegate. For example, a @@ -315,16 +318,16 @@ void ContentSecurityPolicy::AddPolicyFromHeaderValue( const String& header, - ContentSecurityPolicyHeaderType type, - ContentSecurityPolicyHeaderSource source) { + ContentSecurityPolicyType type, + ContentSecurityPolicySource source) { // If this is a report-only header inside a <meta> element, bail out. - if (source == kContentSecurityPolicyHeaderSourceMeta && - type == kContentSecurityPolicyHeaderTypeReport) { + if (source == ContentSecurityPolicySource::kMeta && + type == ContentSecurityPolicyType::kReport) { ReportReportOnlyInMeta(header); return; } - if (source == kContentSecurityPolicyHeaderSourceHTTP) + if (source == ContentSecurityPolicySource::kHTTP) header_delivered_ = true; Vector<UChar> characters; @@ -372,8 +375,8 @@ void ContentSecurityPolicy::AddAndReportPolicyFromHeaderValue( const String& header, - ContentSecurityPolicyHeaderType type, - ContentSecurityPolicyHeaderSource source) { + ContentSecurityPolicyType type, + ContentSecurityPolicySource source) { wtf_size_t previous_policy_count = policies_.size(); AddPolicyFromHeaderValue(header, type, source); // Notify about the new header, so that it can be reported back to the @@ -931,7 +934,7 @@ const KURL& blocked_url, const String& header, RedirectStatus redirect_status, - ContentSecurityPolicyHeaderType header_type, + ContentSecurityPolicyType header_type, ContentSecurityPolicy::ViolationType violation_type, std::unique_ptr<SourceLocation> source_location, const String& script_source) { @@ -976,7 +979,7 @@ init->setViolatedDirective(effective_directive); init->setEffectiveDirective(effective_directive); init->setOriginalPolicy(header); - init->setDisposition(header_type == kContentSecurityPolicyHeaderTypeEnforce + init->setDisposition(header_type == ContentSecurityPolicyType::kEnforce ? "enforce" : "report"); init->setStatusCode(0); @@ -1029,7 +1032,7 @@ const Vector<String>& report_endpoints, bool use_reporting_api, const String& header, - ContentSecurityPolicyHeaderType header_type, + ContentSecurityPolicyType header_type, ViolationType violation_type, std::unique_ptr<SourceLocation> source_location, LocalFrame* context_frame, @@ -1587,8 +1590,8 @@ auto* attr_policy = MakeGarbageCollected<ContentSecurityPolicy>(); attr_policy->AddPolicyFromHeaderValue(attr, - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); if (!attr_policy->console_messages_.IsEmpty() || attr_policy->policies_.size() != 1) { return false; @@ -1605,9 +1608,9 @@ } auto* context_policy = MakeGarbageCollected<ContentSecurityPolicy>(); - context_policy->AddPolicyFromHeaderValue( - context_required_csp, kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + context_policy->AddPolicyFromHeaderValue(context_required_csp, + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); DCHECK(context_policy->console_messages_.IsEmpty() && context_policy->policies_.size() == 1); @@ -1629,7 +1632,7 @@ } bool ContentSecurityPolicy::HasPolicyFromSource( - ContentSecurityPolicyHeaderSource source) const { + ContentSecurityPolicySource source) const { for (const auto& policy : policies_) { if (policy->HeaderSource() == source) return true;
diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy.h b/third_party/blink/renderer/core/frame/csp/content_security_policy.h index f2a82f85..70a74896 100644 --- a/third_party/blink/renderer/core/frame/csp/content_security_policy.h +++ b/third_party/blink/renderer/core/frame/csp/content_security_policy.h
@@ -29,6 +29,7 @@ #include <memory> #include <utility> +#include "services/network/public/mojom/content_security_policy.mojom-shared.h" #include "third_party/blink/public/mojom/devtools/console_message.mojom-blink.h" #include "third_party/blink/public/platform/web_content_security_policy_struct.h" #include "third_party/blink/public/platform/web_insecure_request_policy.h" @@ -76,7 +77,8 @@ using SandboxFlags = WebSandboxFlags; typedef HeapVector<Member<CSPDirectiveList>> CSPDirectiveListVector; typedef HeapVector<Member<ConsoleMessage>> ConsoleMessageVector; -typedef std::pair<String, ContentSecurityPolicyHeaderType> CSPHeaderAndType; +typedef std::pair<String, network::mojom::ContentSecurityPolicyType> + CSPHeaderAndType; using RedirectStatus = ResourceRequest::RedirectStatus; // A delegate interface to implement violation reporting, support for some @@ -222,11 +224,11 @@ void DidReceiveHeaders(const ContentSecurityPolicyResponseHeaders&); void DidReceiveHeader(const String&, - ContentSecurityPolicyHeaderType, - ContentSecurityPolicyHeaderSource); + network::mojom::ContentSecurityPolicyType, + network::mojom::ContentSecurityPolicySource); void AddPolicyFromHeaderValue(const String&, - ContentSecurityPolicyHeaderType, - ContentSecurityPolicyHeaderSource); + network::mojom::ContentSecurityPolicyType, + network::mojom::ContentSecurityPolicySource); void ReportAccumulatedHeaders(LocalFrameClient*) const; Vector<CSPHeaderAndType> Headers() const; @@ -400,7 +402,7 @@ const Vector<String>& report_endpoints, bool use_reporting_api, const String& header, - ContentSecurityPolicyHeaderType, + network::mojom::ContentSecurityPolicyType, ViolationType, std::unique_ptr<SourceLocation>, LocalFrame* = nullptr, @@ -481,7 +483,7 @@ // there is no execution context to enforce the sandbox flags. SandboxFlags GetSandboxMask() const { return sandbox_mask_; } - bool HasPolicyFromSource(ContentSecurityPolicyHeaderSource) const; + bool HasPolicyFromSource(network::mojom::ContentSecurityPolicySource) const; static bool IsScriptDirective( ContentSecurityPolicy::DirectiveType directive_type) { @@ -520,9 +522,10 @@ const String& message, mojom::ConsoleMessageLevel = mojom::ConsoleMessageLevel::kError); - void AddAndReportPolicyFromHeaderValue(const String&, - ContentSecurityPolicyHeaderType, - ContentSecurityPolicyHeaderSource); + void AddAndReportPolicyFromHeaderValue( + const String&, + network::mojom::ContentSecurityPolicyType, + network::mojom::ContentSecurityPolicySource); bool ShouldSendViolationReport(const String&) const; void DidSendViolationReport(const String&);
diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy_fuzzer.cc b/third_party/blink/renderer/core/frame/csp/content_security_policy_fuzzer.cc index c3e310e..c27f4e13 100644 --- a/third_party/blink/renderer/core/frame/csp/content_security_policy_fuzzer.cc +++ b/third_party/blink/renderer/core/frame/csp/content_security_policy_fuzzer.cc
@@ -43,15 +43,16 @@ // 1st bit: header type. // 2nd bit: header source: HTTP (or other) // 3rd bit: header source: Meta or OriginPolicy (if not HTTP) - ContentSecurityPolicyHeaderType header_type = - hash & 0x01 ? kContentSecurityPolicyHeaderTypeEnforce - : kContentSecurityPolicyHeaderTypeReport; - ContentSecurityPolicyHeaderSource header_source = - kContentSecurityPolicyHeaderSourceHTTP; + network::mojom::ContentSecurityPolicyType header_type = + hash & 0x01 ? network::mojom::ContentSecurityPolicyType::kEnforce + : network::mojom::ContentSecurityPolicyType::kReport; + network::mojom::ContentSecurityPolicySource header_source = + network::mojom::ContentSecurityPolicySource::kHTTP; if (hash & 0x02) { - header_source = (hash & 0x04) - ? kContentSecurityPolicyHeaderSourceMeta - : kContentSecurityPolicyHeaderSourceOriginPolicy; + header_source = + (hash & 0x04) + ? network::mojom::ContentSecurityPolicySource::kMeta + : network::mojom::ContentSecurityPolicySource::kOriginPolicy; } // Construct and initialize a policy from the string.
diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc b/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc index 0773e01c..c38e000 100644 --- a/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc +++ b/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc
@@ -24,6 +24,9 @@ namespace blink { +using network::mojom::ContentSecurityPolicySource; +using network::mojom::ContentSecurityPolicyType; + class ContentSecurityPolicyTest : public testing::Test { public: ContentSecurityPolicyTest() @@ -65,8 +68,8 @@ SCOPED_TRACE(testing::Message() << "[Enforce] Header: `" << test.header << "`"); csp = MakeGarbageCollected<ContentSecurityPolicy>(); - csp->DidReceiveHeader(test.header, kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + csp->DidReceiveHeader(test.header, ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_EQ(test.expected_policy, csp->GetInsecureRequestPolicy()); DocumentInit init = DocumentInit::Create() @@ -88,8 +91,8 @@ SCOPED_TRACE(testing::Message() << "[Report-Only] Header: `" << test.header << "`"); csp = MakeGarbageCollected<ContentSecurityPolicy>(); - csp->DidReceiveHeader(test.header, kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceHTTP); + csp->DidReceiveHeader(test.header, ContentSecurityPolicyType::kReport, + ContentSecurityPolicySource::kHTTP); EXPECT_EQ(kLeaveInsecureRequestsAlone, csp->GetInsecureRequestPolicy()); execution_context = CreateExecutionContext(); @@ -106,11 +109,11 @@ TEST_F(ContentSecurityPolicyTest, CopyStateFrom) { csp->DidReceiveHeader("script-src 'none'; plugin-types application/x-type-1", - kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kReport, + ContentSecurityPolicySource::kHTTP); csp->DidReceiveHeader("img-src http://example.com", - kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kReport, + ContentSecurityPolicySource::kHTTP); const KURL example_url("http://example.com"); const KURL not_example_url("http://not-example.com"); @@ -140,11 +143,11 @@ TEST_F(ContentSecurityPolicyTest, CopyPluginTypesFrom) { csp->DidReceiveHeader("script-src 'none'; plugin-types application/x-type-1", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); csp->DidReceiveHeader("img-src http://example.com", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); const KURL example_url("http://example.com"); const KURL not_example_url("http://not-example.com"); @@ -171,34 +174,34 @@ TEST_F(ContentSecurityPolicyTest, IsFrameAncestorsEnforced) { csp->DidReceiveHeader("script-src 'none';", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_FALSE(csp->IsFrameAncestorsEnforced()); csp->DidReceiveHeader("frame-ancestors 'self'", - kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kReport, + ContentSecurityPolicySource::kHTTP); EXPECT_FALSE(csp->IsFrameAncestorsEnforced()); csp->DidReceiveHeader("frame-ancestors 'self'", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(csp->IsFrameAncestorsEnforced()); } TEST_F(ContentSecurityPolicyTest, IsActiveForConnectionsWithConnectSrc) { EXPECT_FALSE(csp->IsActiveForConnections()); csp->DidReceiveHeader("connect-src 'none';", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(csp->IsActiveForConnections()); } TEST_F(ContentSecurityPolicyTest, IsActiveForConnectionsWithDefaultSrc) { EXPECT_FALSE(csp->IsActiveForConnections()); csp->DidReceiveHeader("default-src 'none';", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(csp->IsActiveForConnections()); } @@ -207,12 +210,12 @@ TEST_F(ContentSecurityPolicyTest, FrameAncestorsInMeta) { csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); csp->DidReceiveHeader("frame-ancestors 'none';", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceMeta); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kMeta); EXPECT_FALSE(csp->IsFrameAncestorsEnforced()); csp->DidReceiveHeader("frame-ancestors 'none';", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(csp->IsFrameAncestorsEnforced()); } @@ -221,13 +224,13 @@ TEST_F(ContentSecurityPolicyTest, SandboxInMeta) { csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); EXPECT_EQ(WebSandboxFlags::kNone, csp->GetSandboxMask()); - csp->DidReceiveHeader("sandbox;", kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceMeta); + csp->DidReceiveHeader("sandbox;", ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kMeta); EXPECT_EQ(WebSandboxFlags::kNone, csp->GetSandboxMask()); execution_context->GetSecurityContext().ApplySandboxFlags( WebSandboxFlags::kAll); - csp->DidReceiveHeader("sandbox;", kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + csp->DidReceiveHeader("sandbox;", ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_EQ(WebSandboxFlags::kAll, csp->GetSandboxMask()); } @@ -240,12 +243,12 @@ const UChar* begin = characters.data(); const UChar* end = begin + characters.size(); CSPDirectiveList* directive_list(CSPDirectiveList::Create( - csp, begin, end, kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceMeta)); + csp, begin, end, ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kMeta)); EXPECT_TRUE(directive_list->ReportEndpoints().IsEmpty()); - directive_list = CSPDirectiveList::Create( - csp, begin, end, kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + directive_list = CSPDirectiveList::Create(csp, begin, end, + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_FALSE(directive_list->ReportEndpoints().IsEmpty()); } @@ -256,8 +259,8 @@ const KURL url("https://example.test"); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); csp->DidReceiveHeader("object-src 'none';", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceMeta); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kMeta); EXPECT_FALSE(csp->AllowRequest( mojom::RequestContextType::OBJECT, url, String(), IntegrityMetadataSet(), kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect, @@ -276,8 +279,8 @@ const KURL url("https://example.test"); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); csp->DidReceiveHeader("connect-src 'none';", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceMeta); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kMeta); EXPECT_FALSE( csp->AllowRequest(mojom::RequestContextType::SUBRESOURCE, url, String(), IntegrityMetadataSet(), kParserInserted, @@ -310,8 +313,8 @@ MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); policy->DidReceiveHeader("require-sri-for script style", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_FALSE(policy->AllowRequest( mojom::RequestContextType::SCRIPT, url, String(), IntegrityMetadataSet(), kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect, @@ -346,8 +349,8 @@ policy = MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); policy->DidReceiveHeader("require-sri-for script style", - kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kReport, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(policy->AllowRequest( mojom::RequestContextType::SCRIPT, url, String(), IntegrityMetadataSet(), kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect, @@ -393,8 +396,8 @@ MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); policy->DidReceiveHeader("require-sri-for script style", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(policy->AllowRequest( mojom::RequestContextType::SCRIPT, url, String(), integrity_metadata, kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect, @@ -430,8 +433,8 @@ policy = MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); policy->DidReceiveHeader("require-sri-for script style", - kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kReport, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(policy->AllowRequest( mojom::RequestContextType::SCRIPT, url, String(), integrity_metadata, kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect, @@ -473,8 +476,8 @@ MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); policy->DidReceiveHeader("require-sri-for script style", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceMeta); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kMeta); EXPECT_FALSE(policy->AllowRequest( mojom::RequestContextType::SCRIPT, url, String(), IntegrityMetadataSet(), kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect, @@ -510,8 +513,8 @@ policy = MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); policy->DidReceiveHeader("require-sri-for script style", - kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceMeta); + ContentSecurityPolicyType::kReport, + ContentSecurityPolicySource::kMeta); EXPECT_TRUE(policy->AllowRequest( mojom::RequestContextType::SCRIPT, url, String(), IntegrityMetadataSet(), kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect, @@ -557,8 +560,8 @@ MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); policy->DidReceiveHeader("require-sri-for script style", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceMeta); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kMeta); EXPECT_TRUE(policy->AllowRequest( mojom::RequestContextType::SCRIPT, url, String(), integrity_metadata, kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect, @@ -594,8 +597,8 @@ policy = MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); policy->DidReceiveHeader("require-sri-for script style", - kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceMeta); + ContentSecurityPolicyType::kReport, + ContentSecurityPolicySource::kMeta); EXPECT_TRUE(policy->AllowRequest( mojom::RequestContextType::SCRIPT, url, String(), integrity_metadata, kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect, @@ -658,9 +661,8 @@ MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate( execution_context->GetContentSecurityPolicyDelegate()); - policy->DidReceiveHeader(test.policy, - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + policy->DidReceiveHeader(test.policy, ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_EQ(test.allowed, policy->AllowScriptFromSource( resource, String(test.nonce), IntegrityMetadataSet(), kParserInserted)); @@ -672,9 +674,8 @@ policy = MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate( execution_context->GetContentSecurityPolicyDelegate()); - policy->DidReceiveHeader(test.policy, - kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceHTTP); + policy->DidReceiveHeader(test.policy, ContentSecurityPolicyType::kReport, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(policy->AllowScriptFromSource( resource, String(test.nonce), IntegrityMetadataSet(), kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect, @@ -721,8 +722,8 @@ MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate(document->GetContentSecurityPolicyDelegate()); policy->DidReceiveHeader(String("script-src ") + test.policy, - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_EQ(test.allowed, policy->AllowInline(ContentSecurityPolicy::InlineType::kScript, element, content, String(test.nonce), @@ -733,8 +734,8 @@ policy = MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate(document->GetContentSecurityPolicyDelegate()); policy->DidReceiveHeader(String("style-src ") + test.policy, - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_EQ(test.allowed, policy->AllowInline(ContentSecurityPolicy::InlineType::kStyle, element, content, String(test.nonce), @@ -745,8 +746,8 @@ policy = MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate(document->GetContentSecurityPolicyDelegate()); policy->DidReceiveHeader(String("script-src ") + test.policy, - kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kReport, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(policy->AllowInline(ContentSecurityPolicy::InlineType::kScript, element, content, String(test.nonce), context_url, context_line)); @@ -756,8 +757,8 @@ policy = MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate(document->GetContentSecurityPolicyDelegate()); policy->DidReceiveHeader(String("style-src ") + test.policy, - kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kReport, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(policy->AllowInline(ContentSecurityPolicy::InlineType::kStyle, element, content, String(test.nonce), context_url, context_line)); @@ -827,12 +828,10 @@ MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate( execution_context->GetContentSecurityPolicyDelegate()); - policy->DidReceiveHeader(test.policy1, - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); - policy->DidReceiveHeader(test.policy2, - kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceHTTP); + policy->DidReceiveHeader(test.policy1, ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); + policy->DidReceiveHeader(test.policy2, ContentSecurityPolicyType::kReport, + ContentSecurityPolicySource::kHTTP); EXPECT_EQ(test.allowed1, policy->AllowScriptFromSource( resource, String(test.nonce), IntegrityMetadataSet(), @@ -850,12 +849,10 @@ policy = MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate( execution_context->GetContentSecurityPolicyDelegate()); - policy->DidReceiveHeader(test.policy1, - kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceHTTP); - policy->DidReceiveHeader(test.policy2, - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + policy->DidReceiveHeader(test.policy1, ContentSecurityPolicyType::kReport, + ContentSecurityPolicySource::kHTTP); + policy->DidReceiveHeader(test.policy2, ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(policy->AllowScriptFromSource( resource, String(test.nonce), IntegrityMetadataSet(), kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect, @@ -873,12 +870,10 @@ policy = MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate( execution_context->GetContentSecurityPolicyDelegate()); - policy->DidReceiveHeader(test.policy1, - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); - policy->DidReceiveHeader(test.policy2, - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + policy->DidReceiveHeader(test.policy1, ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); + policy->DidReceiveHeader(test.policy2, ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_EQ(test.allowed1 && test.allowed2, policy->AllowScriptFromSource( resource, String(test.nonce), IntegrityMetadataSet(), @@ -891,12 +886,10 @@ policy = MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate( execution_context->GetContentSecurityPolicyDelegate()); - policy->DidReceiveHeader(test.policy1, - kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceHTTP); - policy->DidReceiveHeader(test.policy2, - kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceHTTP); + policy->DidReceiveHeader(test.policy1, ContentSecurityPolicyType::kReport, + ContentSecurityPolicySource::kHTTP); + policy->DidReceiveHeader(test.policy2, ContentSecurityPolicyType::kReport, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(policy->AllowScriptFromSource( resource, String(test.nonce), IntegrityMetadataSet(), kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect, @@ -1016,28 +1009,28 @@ EXPECT_TRUE(other->Subsumes(*csp)); csp->DidReceiveHeader("default-src http://example.com;", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); // If this CSP is not empty, the other must not be empty either. EXPECT_FALSE(csp->Subsumes(*other)); EXPECT_TRUE(other->Subsumes(*csp)); // Report-only policies do not impact subsumption. other->DidReceiveHeader("default-src http://example.com;", - kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kReport, + ContentSecurityPolicySource::kHTTP); EXPECT_FALSE(csp->Subsumes(*other)); // CSPDirectiveLists have to subsume. other->DidReceiveHeader("default-src http://example.com https://another.com;", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_FALSE(csp->Subsumes(*other)); // `other` is stricter than `this`. other->DidReceiveHeader("default-src https://example.com;", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(csp->Subsumes(*other)); } @@ -1045,12 +1038,12 @@ const KURL base; execution_context = CreateExecutionContext(); execution_context->GetSecurityContext().SetSecurityOrigin( - secure_origin); // https://example.com - execution_context->SetURL(secure_url); // https://example.com + secure_origin); // https://example.com + execution_context->SetURL(secure_url); // https://example.com csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); csp->DidReceiveHeader("default-src https://example.com", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(csp->AllowRequest( mojom::RequestContextType::OBJECT, KURL(base, "https://example.com/"), @@ -1086,12 +1079,12 @@ const KURL base; execution_context = CreateExecutionContext(); execution_context->GetSecurityContext().SetSecurityOrigin( - secure_origin); // https://example.com - execution_context->SetURL(secure_url); // https://example.com + secure_origin); // https://example.com + execution_context->SetURL(secure_url); // https://example.com csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); csp->DidReceiveHeader("default-src https://example.com", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_FALSE( csp->AllowRequest(mojom::RequestContextType::OBJECT, @@ -1132,12 +1125,12 @@ const KURL base; execution_context = CreateExecutionContext(); execution_context->GetSecurityContext().SetSecurityOrigin( - secure_origin); // https://example.com - execution_context->SetURL(secure_url); // https://example.com + secure_origin); // https://example.com + execution_context->SetURL(secure_url); // https://example.com csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); csp->DidReceiveHeader("default-src https://example.com", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_FALSE(csp->AllowRequest( mojom::RequestContextType::OBJECT, @@ -1179,8 +1172,8 @@ execution_context->SetURL(BlankURL()); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); csp->DidReceiveHeader("script-src http://example.com", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); const KURL allowed_url("http://example.com/script.js"); const KURL http_url("http://not-example.com/script.js"); @@ -1359,8 +1352,8 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypesNoDirective) { execution_context->GetSecurityContext().SetRequireTrustedTypesForTesting(); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("", kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + csp->DidReceiveHeader("", ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", false)); EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", true)); } @@ -1369,16 +1362,16 @@ execution_context->GetSecurityContext().SetRequireTrustedTypesForTesting(); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); csp->DidReceiveHeader("trusted-types one two three", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); } TEST_F(ContentSecurityPolicyTest, TrustedTypesWhitespace) { execution_context->GetSecurityContext().SetRequireTrustedTypesForTesting(); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); csp->DidReceiveHeader("trusted-types one\ntwo\rthree", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(csp->AllowTrustedTypePolicy("one", false)); EXPECT_TRUE(csp->AllowTrustedTypePolicy("two", false)); EXPECT_TRUE(csp->AllowTrustedTypePolicy("three", false)); @@ -1390,9 +1383,8 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypesEmpty) { execution_context->GetSecurityContext().SetRequireTrustedTypesForTesting(); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("trusted-types", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + csp->DidReceiveHeader("trusted-types", ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_FALSE(csp->AllowTrustedTypePolicy("somepolicy", false)); EXPECT_FALSE(csp->AllowTrustedTypePolicy("somepolicy", true)); } @@ -1400,9 +1392,8 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypesStar) { execution_context->GetSecurityContext().SetRequireTrustedTypesForTesting(); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("trusted-types *", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + csp->DidReceiveHeader("trusted-types *", ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", false)); EXPECT_FALSE(csp->AllowTrustedTypePolicy("somepolicy", true)); } @@ -1411,8 +1402,8 @@ execution_context->GetSecurityContext().SetRequireTrustedTypesForTesting(); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); csp->DidReceiveHeader("trusted-types * 'allow-duplicates'", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", false)); EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", true)); } @@ -1421,8 +1412,8 @@ execution_context->GetSecurityContext().SetRequireTrustedTypesForTesting(); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); csp->DidReceiveHeader("trusted-types one \"two\" 'three'", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(csp->AllowTrustedTypePolicy("one", false)); EXPECT_TRUE(csp->AllowTrustedTypePolicy("one", false)); @@ -1440,9 +1431,8 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypesReportingStar) { execution_context->GetSecurityContext().SetRequireTrustedTypesForTesting(); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("trusted-types *", - kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceHTTP); + csp->DidReceiveHeader("trusted-types *", ContentSecurityPolicyType::kReport, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", false)); EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", true)); } @@ -1451,8 +1441,8 @@ execution_context->GetSecurityContext().SetRequireTrustedTypesForTesting(); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); csp->DidReceiveHeader("trusted-types a b c", - kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kReport, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(csp->AllowTrustedTypePolicy("a", false)); EXPECT_TRUE(csp->AllowTrustedTypePolicy("a", true)); } @@ -1461,8 +1451,8 @@ execution_context->GetSecurityContext().SetRequireTrustedTypesForTesting(); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); csp->DidReceiveHeader("trusted-types one\ntwo\rthree", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(csp->IsRequireTrustedTypes()); EXPECT_FALSE(csp->AllowTrustedTypeAssignmentFailure("blabla")); } @@ -1471,8 +1461,8 @@ execution_context->GetSecurityContext().SetRequireTrustedTypesForTesting(); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); csp->DidReceiveHeader("trusted-types one\ntwo\rthree", - kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kReport, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(csp->IsRequireTrustedTypes()); EXPECT_TRUE(csp->AllowTrustedTypeAssignmentFailure("blabla")); } @@ -1480,12 +1470,11 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypeReportAndEnforce) { execution_context->GetSecurityContext().SetRequireTrustedTypesForTesting(); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("trusted-types one", - kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceHTTP); + csp->DidReceiveHeader("trusted-types one", ContentSecurityPolicyType::kReport, + ContentSecurityPolicySource::kHTTP); csp->DidReceiveHeader("trusted-types two", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(csp->IsRequireTrustedTypes()); EXPECT_FALSE(csp->AllowTrustedTypeAssignmentFailure("blabla")); } @@ -1493,12 +1482,10 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypeReportAndNonTTEnforce) { execution_context->GetSecurityContext().SetRequireTrustedTypesForTesting(); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("trusted-types one", - kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceHTTP); - csp->DidReceiveHeader("script-src none", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + csp->DidReceiveHeader("trusted-types one", ContentSecurityPolicyType::kReport, + ContentSecurityPolicySource::kHTTP); + csp->DidReceiveHeader("script-src none", ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(csp->IsRequireTrustedTypes()); EXPECT_TRUE(csp->AllowTrustedTypeAssignmentFailure("blabla")); } @@ -1506,9 +1493,8 @@ TEST_F(ContentSecurityPolicyTest, DefaultPolicy) { execution_context->GetSecurityContext().SetRequireTrustedTypesForTesting(); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("trusted-types *", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + csp->DidReceiveHeader("trusted-types *", ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(csp->AllowTrustedTypePolicy("default", false)); EXPECT_FALSE(csp->AllowTrustedTypePolicy("default", true)); } @@ -1520,8 +1506,8 @@ // Directive name is case insensitive. csp = MakeGarbageCollected<ContentSecurityPolicy>(); csp->DidReceiveHeader("sCrIpt-sRc http://example.com", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); EXPECT_TRUE(csp->AllowScriptFromSource( @@ -1534,8 +1520,7 @@ csp = MakeGarbageCollected<ContentSecurityPolicy>(); csp->DidReceiveHeader( "SCRipt-SRC http://example.com; script-src http://not-example.com;", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); EXPECT_TRUE(csp->AllowScriptFromSource( @@ -1628,8 +1613,7 @@ EXPECT_FALSE(csp->HasHeaderDeliveredPolicy()); EXPECT_FALSE(csp->SupportsWasmEval()); EXPECT_EQ(WebSandboxFlags::kNone, csp->GetSandboxMask()); - EXPECT_FALSE( - csp->HasPolicyFromSource(kContentSecurityPolicyHeaderSourceHTTP)); + EXPECT_FALSE(csp->HasPolicyFromSource(ContentSecurityPolicySource::kHTTP)); } TEST_F(ContentSecurityPolicyTest, OpaqueOriginBeforeBind) { @@ -1642,8 +1626,8 @@ execution_context = CreateExecutionContext(); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); csp->DidReceiveHeader("default-src 'self';", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceMeta); + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kMeta); EXPECT_TRUE( csp->AllowRequest(mojom::RequestContextType::SUBRESOURCE, url, String(), IntegrityMetadataSet(), kParserInserted,
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc b/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc index 1e697f8..e5d60997 100644 --- a/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc +++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
@@ -8,6 +8,7 @@ #include <utility> #include "services/network/public/cpp/features.h" +#include "services/network/public/mojom/content_security_policy.mojom-shared.h" #include "third_party/blink/renderer/bindings/core/v8/source_location.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/space_split_string.h" @@ -124,9 +125,12 @@ } // namespace +using network::mojom::ContentSecurityPolicySource; +using network::mojom::ContentSecurityPolicyType; + CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy, - ContentSecurityPolicyHeaderType type, - ContentSecurityPolicyHeaderSource source) + ContentSecurityPolicyType type, + ContentSecurityPolicySource source) : policy_(policy), header_type_(type), header_source_(source), @@ -136,13 +140,12 @@ require_sri_for_(RequireSRIForToken::kNone), use_reporting_api_(false) {} -CSPDirectiveList* CSPDirectiveList::Create( - ContentSecurityPolicy* policy, - const UChar* begin, - const UChar* end, - ContentSecurityPolicyHeaderType type, - ContentSecurityPolicyHeaderSource source, - bool should_parse_wasm_eval) { +CSPDirectiveList* CSPDirectiveList::Create(ContentSecurityPolicy* policy, + const UChar* begin, + const UChar* end, + ContentSecurityPolicyType type, + ContentSecurityPolicySource source, + bool should_parse_wasm_eval) { CSPDirectiveList* directives = MakeGarbageCollected<CSPDirectiveList>(policy, type, source); directives->Parse(begin, end, should_parse_wasm_eval); @@ -167,7 +170,7 @@ } if (directives->IsReportOnly() && - source != kContentSecurityPolicyHeaderSourceMeta && + source != ContentSecurityPolicySource::kMeta && directives->ReportEndpoints().IsEmpty()) { policy->ReportMissingReportURI( String(begin, static_cast<wtf_size_t>(end - begin))); @@ -1125,7 +1128,7 @@ // Remove report-uri in meta policies, per // https://html.spec.whatwg.org/C/#attr-meta-http-equiv-content-security-policy. - if (header_source_ == kContentSecurityPolicyHeaderSourceMeta) { + if (header_source_ == ContentSecurityPolicySource::kMeta) { policy_->ReportInvalidDirectiveInMeta(name); return; } @@ -1197,7 +1200,7 @@ // Remove frame-ancestors directives in meta policies, per // https://www.w3.org/TR/CSP2/#delivery-html-meta-element. - if (header_source_ == kContentSecurityPolicyHeaderSourceMeta && + if (header_source_ == ContentSecurityPolicySource::kMeta && ContentSecurityPolicy::GetDirectiveType(name) == ContentSecurityPolicy::DirectiveType::kFrameAncestors) { policy_->ReportInvalidDirectiveInMeta(name); @@ -1211,7 +1214,7 @@ const String& sandbox_policy) { // Remove sandbox directives in meta policies, per // https://www.w3.org/TR/CSP2/#delivery-html-meta-element. - if (header_source_ == kContentSecurityPolicyHeaderSourceMeta) { + if (header_source_ == ContentSecurityPolicySource::kMeta) { policy_->ReportInvalidDirectiveInMeta(name); return; } @@ -1571,10 +1574,8 @@ WebContentSecurityPolicy CSPDirectiveList::ExposeForNavigationalChecks() const { WebContentSecurityPolicy policy; - policy.disposition = - static_cast<network::mojom::ContentSecurityPolicyType>(header_type_); - policy.source = - static_cast<network::mojom::ContentSecurityPolicySource>(header_source_); + policy.disposition = header_type_; + policy.source = header_source_; for (const auto& directive : {child_src_, default_src_, form_action_, frame_src_, navigate_to_}) { if (directive) {
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list.h b/third_party/blink/renderer/core/frame/csp/csp_directive_list.h index 8855e320..4dc796f 100644 --- a/third_party/blink/renderer/core/frame/csp/csp_directive_list.h +++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list.h
@@ -34,21 +34,23 @@ static CSPDirectiveList* Create(ContentSecurityPolicy*, const UChar* begin, const UChar* end, - ContentSecurityPolicyHeaderType, - ContentSecurityPolicyHeaderSource, + network::mojom::ContentSecurityPolicyType, + network::mojom::ContentSecurityPolicySource, bool should_parse_wasm_eval = false); CSPDirectiveList(ContentSecurityPolicy*, - ContentSecurityPolicyHeaderType, - ContentSecurityPolicyHeaderSource); + network::mojom::ContentSecurityPolicyType, + network::mojom::ContentSecurityPolicySource); void Parse(const UChar* begin, const UChar* end, bool should_parse_wasm_eval = false); const String& Header() const { return header_; } - ContentSecurityPolicyHeaderType HeaderType() const { return header_type_; } - ContentSecurityPolicyHeaderSource HeaderSource() const { + network::mojom::ContentSecurityPolicyType HeaderType() const { + return header_type_; + } + network::mojom::ContentSecurityPolicySource HeaderSource() const { return header_source_; } @@ -122,7 +124,7 @@ return eval_disabled_error_message_; } bool IsReportOnly() const { - return header_type_ == kContentSecurityPolicyHeaderTypeReport; + return header_type_ == network::mojom::ContentSecurityPolicyType::kReport; } bool IsActiveForConnections() const { return OperativeDirective( @@ -299,8 +301,8 @@ Member<ContentSecurityPolicy> policy_; String header_; - ContentSecurityPolicyHeaderType header_type_; - ContentSecurityPolicyHeaderSource header_source_; + network::mojom::ContentSecurityPolicyType header_type_; + network::mojom::ContentSecurityPolicySource header_source_; bool has_sandbox_policy_;
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc b/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc index 2cc39ba..3b56ddd 100644 --- a/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc +++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc
@@ -22,6 +22,9 @@ namespace blink { +using network::mojom::ContentSecurityPolicySource; +using network::mojom::ContentSecurityPolicyType; + class CSPDirectiveListTest : public testing::Test { public: CSPDirectiveListTest() : csp(MakeGarbageCollected<ContentSecurityPolicy>()) {} @@ -31,10 +34,10 @@ *SecurityOrigin::CreateFromString("https://example.test/image.png")); } - CSPDirectiveList* CreateList(const String& list, - ContentSecurityPolicyHeaderType type, - ContentSecurityPolicyHeaderSource source = - kContentSecurityPolicyHeaderSourceHTTP) { + CSPDirectiveList* CreateList( + const String& list, + ContentSecurityPolicyType type, + ContentSecurityPolicySource source = ContentSecurityPolicySource::kHTTP) { Vector<UChar> characters; list.AppendTo(characters); const UChar* begin = characters.data(); @@ -59,10 +62,9 @@ for (const auto& test : cases) { Member<CSPDirectiveList> directive_list = - CreateList(test.list, kContentSecurityPolicyHeaderTypeReport); + CreateList(test.list, ContentSecurityPolicyType::kReport); EXPECT_EQ(test.expected, directive_list->Header()); - directive_list = - CreateList(test.list, kContentSecurityPolicyHeaderTypeEnforce); + directive_list = CreateList(test.list, ContentSecurityPolicyType::kEnforce); EXPECT_EQ(test.expected, directive_list->Header()); } } @@ -134,7 +136,7 @@ for (const auto& test : cases) { // Report-only Member<CSPDirectiveList> directive_list = - CreateList(test.list, kContentSecurityPolicyHeaderTypeReport); + CreateList(test.list, ContentSecurityPolicyType::kReport); Member<SourceListDirective> directive = directive_list->OperativeDirective(test.type); EXPECT_EQ(test.expected, @@ -144,8 +146,7 @@ EXPECT_FALSE(directive_list->IsMatchingNoncePresent(directive, String())); // Enforce - directive_list = - CreateList(test.list, kContentSecurityPolicyHeaderTypeEnforce); + directive_list = CreateList(test.list, ContentSecurityPolicyType::kEnforce); directive = directive_list->OperativeDirective(test.type); EXPECT_EQ(test.expected, directive_list->IsMatchingNoncePresent(directive, test.nonce)); @@ -211,7 +212,7 @@ // Report-only Member<CSPDirectiveList> directive_list = - CreateList(test.list, kContentSecurityPolicyHeaderTypeReport); + CreateList(test.list, ContentSecurityPolicyType::kReport); EXPECT_EQ(test.expected, directive_list->AllowFromSource( ContentSecurityPolicy::DirectiveType::kScriptSrcElem, @@ -220,8 +221,7 @@ String(), IntegrityMetadataSet(), kParserInserted)); // Enforce - directive_list = - CreateList(test.list, kContentSecurityPolicyHeaderTypeEnforce); + directive_list = CreateList(test.list, ContentSecurityPolicyType::kEnforce); EXPECT_EQ(test.expected, directive_list->AllowFromSource( ContentSecurityPolicy::DirectiveType::kScriptSrcElem, @@ -268,9 +268,8 @@ const KURL resource(test.url); // Report-only 'script-src' - Member<CSPDirectiveList> directive_list = - CreateList(String("script-src ") + test.list, - kContentSecurityPolicyHeaderTypeReport); + Member<CSPDirectiveList> directive_list = CreateList( + String("script-src ") + test.list, ContentSecurityPolicyType::kReport); EXPECT_EQ(test.expected, directive_list->AllowFromSource( ContentSecurityPolicy::DirectiveType::kScriptSrcElem, @@ -280,7 +279,7 @@ // Enforce 'script-src' directive_list = CreateList(String("script-src ") + test.list, - kContentSecurityPolicyHeaderTypeEnforce); + ContentSecurityPolicyType::kEnforce); EXPECT_EQ(test.expected, directive_list->AllowFromSource( ContentSecurityPolicy::DirectiveType::kScriptSrcElem, @@ -290,7 +289,7 @@ // Report-only 'style-src' directive_list = CreateList(String("style-src ") + test.list, - kContentSecurityPolicyHeaderTypeReport); + ContentSecurityPolicyType::kReport); EXPECT_EQ(test.expected, directive_list->AllowFromSource( ContentSecurityPolicy::DirectiveType::kStyleSrcElem, resource, @@ -300,7 +299,7 @@ // Enforce 'style-src' directive_list = CreateList(String("style-src ") + test.list, - kContentSecurityPolicyHeaderTypeEnforce); + ContentSecurityPolicyType::kEnforce); EXPECT_EQ(test.expected, directive_list->AllowFromSource( ContentSecurityPolicy::DirectiveType::kStyleSrcElem, resource, @@ -310,7 +309,7 @@ // Report-only 'style-src' directive_list = CreateList(String("default-src ") + test.list, - kContentSecurityPolicyHeaderTypeReport); + ContentSecurityPolicyType::kReport); EXPECT_EQ(test.expected, directive_list->AllowFromSource( ContentSecurityPolicy::DirectiveType::kScriptSrcElem, @@ -326,7 +325,7 @@ // Enforce 'style-src' directive_list = CreateList(String("default-src ") + test.list, - kContentSecurityPolicyHeaderTypeEnforce); + ContentSecurityPolicyType::kEnforce); EXPECT_EQ(test.expected, directive_list->AllowFromSource( ContentSecurityPolicy::DirectiveType::kScriptSrcElem, @@ -421,9 +420,8 @@ integrity_metadata)); // Report-only 'script-src' - Member<CSPDirectiveList> directive_list = - CreateList(String("script-src ") + test.list, - kContentSecurityPolicyHeaderTypeReport); + Member<CSPDirectiveList> directive_list = CreateList( + String("script-src ") + test.list, ContentSecurityPolicyType::kReport); EXPECT_EQ(test.expected, directive_list->AllowFromSource( ContentSecurityPolicy::DirectiveType::kScriptSrcElem, @@ -433,7 +431,7 @@ // Enforce 'script-src' directive_list = CreateList(String("script-src ") + test.list, - kContentSecurityPolicyHeaderTypeEnforce); + ContentSecurityPolicyType::kEnforce); EXPECT_EQ(test.expected, directive_list->AllowFromSource( ContentSecurityPolicy::DirectiveType::kScriptSrcElem, @@ -549,15 +547,14 @@ const KURL resource(test.url); // Report-only Member<CSPDirectiveList> directive_list = - CreateList(test.list, kContentSecurityPolicyHeaderTypeReport); + CreateList(test.list, ContentSecurityPolicyType::kReport); EXPECT_EQ(true, directive_list->AllowRequestWithoutIntegrity( test.context, resource, ResourceRequest::RedirectStatus::kNoRedirect, SecurityViolationReportingPolicy::kSuppressReporting)); // Enforce - directive_list = - CreateList(test.list, kContentSecurityPolicyHeaderTypeEnforce); + directive_list = CreateList(test.list, ContentSecurityPolicyType::kEnforce); EXPECT_EQ(test.expected, directive_list->AllowRequestWithoutIntegrity( test.context, resource, @@ -603,7 +600,7 @@ SCOPED_TRACE(test.list); const KURL resource("https://example.test/worker.js"); Member<CSPDirectiveList> directive_list = - CreateList(test.list, kContentSecurityPolicyHeaderTypeEnforce); + CreateList(test.list, ContentSecurityPolicyType::kEnforce); EXPECT_EQ(test.allowed, directive_list->AllowFromSource( ContentSecurityPolicy::DirectiveType::kWorkerSrc, resource, @@ -649,7 +646,7 @@ SCOPED_TRACE(test.list); const KURL resource("https://example.test/worker.js"); Member<CSPDirectiveList> directive_list = - CreateList(test.list, kContentSecurityPolicyHeaderTypeEnforce); + CreateList(test.list, ContentSecurityPolicyType::kEnforce); EXPECT_EQ(test.allowed, directive_list->AllowFromSource( ContentSecurityPolicy::DirectiveType::kWorkerSrc, resource, @@ -662,7 +659,7 @@ CSPDirectiveList* a = CreateList( "script-src http://*.one.com; img-src https://one.com " "http://two.com/imgs/", - kContentSecurityPolicyHeaderTypeEnforce); + ContentSecurityPolicyType::kEnforce); struct TestCase { const Vector<const char*> policies; @@ -722,13 +719,12 @@ }; CSPDirectiveList* empty_a = - CreateList("", kContentSecurityPolicyHeaderTypeEnforce); + CreateList("", ContentSecurityPolicyType::kEnforce); for (const auto& test : cases) { HeapVector<Member<CSPDirectiveList>> list_b; for (auto* const policy : test.policies) { - list_b.push_back( - CreateList(policy, kContentSecurityPolicyHeaderTypeEnforce)); + list_b.push_back(CreateList(policy, ContentSecurityPolicyType::kEnforce)); } EXPECT_EQ(test.expected, a->Subsumes(list_b)); @@ -830,12 +826,13 @@ for (const auto& test : cases) { CSPDirectiveList* a = - CreateList(test.policy_a, kContentSecurityPolicyHeaderTypeEnforce); + CreateList(test.policy_a, ContentSecurityPolicyType::kEnforce); HeapVector<Member<CSPDirectiveList>> list_b; - for (auto* const policy_b : test.policies_b) + for (auto* const policy_b : test.policies_b) { list_b.push_back( - CreateList(policy_b, kContentSecurityPolicyHeaderTypeEnforce)); + CreateList(policy_b, ContentSecurityPolicyType::kEnforce)); + } EXPECT_EQ(test.expected, a->Subsumes(list_b)); } @@ -912,12 +909,13 @@ for (const auto& test : cases) { CSPDirectiveList* a = - CreateList(test.policy_a, kContentSecurityPolicyHeaderTypeEnforce); + CreateList(test.policy_a, ContentSecurityPolicyType::kEnforce); HeapVector<Member<CSPDirectiveList>> list_b; - for (auto* const policy_b : test.policies_b) + for (auto* const policy_b : test.policies_b) { list_b.push_back( - CreateList(policy_b, kContentSecurityPolicyHeaderTypeEnforce)); + CreateList(policy_b, ContentSecurityPolicyType::kEnforce)); + } EXPECT_EQ(test.expected, a->Subsumes(list_b)); } @@ -974,8 +972,7 @@ all_directives << name << " http://" << name << ".com; "; } - CSPDirectiveList* empty = - CreateList("", kContentSecurityPolicyHeaderTypeEnforce); + CSPDirectiveList* empty = CreateList("", ContentSecurityPolicyType::kEnforce); std::string directive_string; CSPDirectiveList* directive_list; @@ -993,7 +990,7 @@ while (!test.fallback_list.IsEmpty()) { directive_list = CreateList(directive_string.c_str(), - kContentSecurityPolicyHeaderTypeEnforce); + ContentSecurityPolicyType::kEnforce); CSPDirective* operative_directive = directive_list->OperativeDirective(test.directive); @@ -1026,7 +1023,7 @@ // chain we should ensure that there is no unexpected directive outside of // the fallback chain that is returned. directive_list = CreateList(directive_string.c_str(), - kContentSecurityPolicyHeaderTypeEnforce); + ContentSecurityPolicyType::kEnforce); EXPECT_FALSE(directive_list->OperativeDirective(test.directive)); } } @@ -1048,7 +1045,7 @@ HeapVector<Member<CSPDirectiveList>> policy_vector; for (auto* const policy : policies) { policy_vector.push_back( - CreateList(policy, kContentSecurityPolicyHeaderTypeEnforce)); + CreateList(policy, ContentSecurityPolicyType::kEnforce)); } HeapVector<Member<SourceListDirective>> result = CSPDirectiveList::GetSourceVector( @@ -1102,15 +1099,14 @@ HeapVector<Member<CSPDirectiveList>> policy_vector; for (auto* const policy : policies) { policy_vector.push_back( - CreateList(policy, kContentSecurityPolicyHeaderTypeEnforce)); + CreateList(policy, ContentSecurityPolicyType::kEnforce)); } // Append current test's policy. std::stringstream current_directive; const char* name = ContentSecurityPolicy::GetDirectiveName(test.directive); current_directive << name << " http://" << name << ".com;"; - policy_vector.push_back( - CreateList(current_directive.str().c_str(), - kContentSecurityPolicyHeaderTypeEnforce)); + policy_vector.push_back(CreateList(current_directive.str().c_str(), + ContentSecurityPolicyType::kEnforce)); HeapVector<Member<SourceListDirective>> result = CSPDirectiveList::GetSourceVector(test.directive, policy_vector); @@ -1136,9 +1132,8 @@ EXPECT_EQ(actual_child, test.expected_child_src); // If another default-src is added that should only impact Fetch Directives - policy_vector.push_back( - CreateList("default-src https://default-src.com;", - kContentSecurityPolicyHeaderTypeEnforce)); + policy_vector.push_back(CreateList("default-src https://default-src.com;", + ContentSecurityPolicyType::kEnforce)); size_t udpated_total = test.type != kNoDefault ? test.expected_total + 1 : test.expected_total; EXPECT_EQ( @@ -1155,9 +1150,8 @@ // If another child-src is added that should only impact frame-src and // child-src - policy_vector.push_back( - CreateList("child-src http://child-src.com;", - kContentSecurityPolicyHeaderTypeEnforce)); + policy_vector.push_back(CreateList("child-src http://child-src.com;", + ContentSecurityPolicyType::kEnforce)); udpated_total = test.type == kChildAndDefault || test.directive == ContentSecurityPolicy::DirectiveType::kChildSrc @@ -1175,9 +1169,8 @@ // If we add sandbox, nothing should change since it is currenly not // considered. - policy_vector.push_back( - CreateList("sandbox http://sandbox.com;", - kContentSecurityPolicyHeaderTypeEnforce)); + policy_vector.push_back(CreateList("sandbox http://sandbox.com;", + ContentSecurityPolicyType::kEnforce)); EXPECT_EQ( CSPDirectiveList::GetSourceVector(test.directive, policy_vector).size(), udpated_total); @@ -1192,67 +1185,67 @@ TEST_F(CSPDirectiveListTest, ReportEndpointsProperlyParsed) { struct TestCase { const char* policy; - ContentSecurityPolicyHeaderSource header_source; + ContentSecurityPolicySource header_source; Vector<String> expected_endpoints; bool expected_use_reporting_api; } cases[] = { - {"script-src 'self';", kContentSecurityPolicyHeaderSourceHTTP, {}, false}, + {"script-src 'self';", ContentSecurityPolicySource::kHTTP, {}, false}, {"script-src 'self'; report-uri https://example.com", - kContentSecurityPolicyHeaderSourceHTTP, + ContentSecurityPolicySource::kHTTP, {"https://example.com"}, false}, {"script-src 'self'; report-uri https://example.com " "https://example2.com", - kContentSecurityPolicyHeaderSourceHTTP, + ContentSecurityPolicySource::kHTTP, {"https://example.com", "https://example2.com"}, false}, {"script-src 'self'; report-uri https://example.com", - kContentSecurityPolicyHeaderSourceMeta, + ContentSecurityPolicySource::kMeta, {}, false}, {"script-src 'self'; report-to group", - kContentSecurityPolicyHeaderSourceHTTP, + ContentSecurityPolicySource::kHTTP, {"group"}, true}, // report-to supersedes report-uri {"script-src 'self'; report-to group; report-uri https://example.com", - kContentSecurityPolicyHeaderSourceHTTP, + ContentSecurityPolicySource::kHTTP, {"group"}, true}, {"script-src 'self'; report-to group", - kContentSecurityPolicyHeaderSourceMeta, + ContentSecurityPolicySource::kMeta, {"group"}, true}, {"script-src 'self'; report-to group; report-to group2;", - kContentSecurityPolicyHeaderSourceHTTP, + ContentSecurityPolicySource::kHTTP, {"group"}, true}, {"script-src 'self'; report-to group; report-uri https://example.com; " "report-to group2", - kContentSecurityPolicyHeaderSourceHTTP, + ContentSecurityPolicySource::kHTTP, {"group"}, true}, {"script-src 'self'; report-uri https://example.com; report-to group; " "report-to group2", - kContentSecurityPolicyHeaderSourceHTTP, + ContentSecurityPolicySource::kHTTP, {"group"}, true}, {"script-src 'self'; report-uri https://example.com " "https://example2.com; report-to group", - kContentSecurityPolicyHeaderSourceHTTP, + ContentSecurityPolicySource::kHTTP, {"group"}, true}, {"script-src 'self'; report-uri https://example.com; report-to group; " "report-uri https://example.com", - kContentSecurityPolicyHeaderSourceHTTP, + ContentSecurityPolicySource::kHTTP, {"group"}, true}, }; for (const auto& test : cases) { // Test both enforce and report, there should not be a difference - for (const auto& header_type : {kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderTypeReport}) { + for (const auto& header_type : {ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicyType::kReport}) { Member<CSPDirectiveList> directive_list = CreateList(test.policy, header_type, test.header_source);
diff --git a/third_party/blink/renderer/core/frame/csp/navigation_initiator_impl.cc b/third_party/blink/renderer/core/frame/csp/navigation_initiator_impl.cc index 00317ab..f5d47acd 100644 --- a/third_party/blink/renderer/core/frame/csp/navigation_initiator_impl.cc +++ b/third_party/blink/renderer/core/frame/csp/navigation_initiator_impl.cc
@@ -39,9 +39,7 @@ violation_params->effective_directive), violation_params->console_message, KURL(violation_params->blocked_url), report_endpoints, violation_params->use_reporting_api, - violation_params->header, - static_cast<ContentSecurityPolicyHeaderType>( - violation_params->disposition), + violation_params->header, violation_params->disposition, ContentSecurityPolicy::ViolationType::kURLViolation, std::move(source_location), nullptr /* LocalFrame */, violation_params->after_redirect ? RedirectStatus::kFollowedRedirect
diff --git a/third_party/blink/renderer/core/frame/deprecation.cc b/third_party/blink/renderer/core/frame/deprecation.cc index 44fe75a..189d3bb 100644 --- a/third_party/blink/renderer/core/frame/deprecation.cc +++ b/third_party/blink/renderer/core/frame/deprecation.cc
@@ -480,13 +480,13 @@ MilestoneString(kM72).Ascii().c_str())}; case WebFeature::kNoSysexWebMIDIWithoutPermission: - return {"NoSysexWebMIDIWithoutPermission", kM77, + return {"NoSysexWebMIDIWithoutPermission", kM82, String::Format( "Web MIDI will ask a permission to use even if the sysex is " - "not specified in the MIDIOptions since %s. See " + "not specified in the MIDIOptions since around %s. See " "https://www.chromestatus.com/feature/5138066234671104 for " "more details.", - MilestoneString(kM77).Ascii().c_str())}; + MilestoneString(kM82).Ascii().c_str())}; case WebFeature::kCustomCursorIntersectsViewport: return {
diff --git a/third_party/blink/renderer/core/frame/remote_frame.cc b/third_party/blink/renderer/core/frame/remote_frame.cc index 354c81a..9c5ad6a 100644 --- a/third_party/blink/renderer/core/frame/remote_frame.cc +++ b/third_party/blink/renderer/core/frame/remote_frame.cc
@@ -304,9 +304,7 @@ headers) { for (auto& header : headers) { GetSecurityContext()->GetContentSecurityPolicy()->AddPolicyFromHeaderValue( - header->header_value, - static_cast<ContentSecurityPolicyHeaderType>(header->type), - static_cast<ContentSecurityPolicyHeaderSource>(header->source)); + header->header_value, header->type, header->source); } } @@ -361,6 +359,10 @@ Frame::SetHadStickyUserActivationBeforeNavigation(value); } +void RemoteFrame::SetNeedsOcclusionTracking(bool needs_tracking) { + View()->SetNeedsOcclusionTracking(needs_tracking); +} + void RemoteFrame::BubbleLogicalScroll( mojom::blink::ScrollDirection direction, ui::input_types::ScrollGranularity granularity) {
diff --git a/third_party/blink/renderer/core/frame/remote_frame.h b/third_party/blink/renderer/core/frame/remote_frame.h index 072a473..2019de9 100644 --- a/third_party/blink/renderer/core/frame/remote_frame.h +++ b/third_party/blink/renderer/core/frame/remote_frame.h
@@ -103,6 +103,7 @@ void Collapse(bool collapsed) final; void Focus() override; void SetHadStickyUserActivationBeforeNavigation(bool value) override; + void SetNeedsOcclusionTracking(bool needs_tracking) override; void BubbleLogicalScroll( mojom::blink::ScrollDirection direction, ui::input_types::ScrollGranularity granularity) override;
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc index a9588c9..3de275c6 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -2206,8 +2206,7 @@ document->GetContentSecurityPolicy()->ReportViolation( violation.directive, directive_type, violation.console_message, violation.blocked_url, report_endpoints, violation.use_reporting_api, - violation.header, - static_cast<ContentSecurityPolicyHeaderType>(violation.disposition), + violation.header, violation.disposition, ContentSecurityPolicy::ViolationType::kURLViolation, std::move(source_location), context_frame, violation.after_redirect ? RedirectStatus::kFollowedRedirect
diff --git a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc index 71465066..c8a6482 100644 --- a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc +++ b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
@@ -1106,11 +1106,15 @@ canvas2d_bridge_ = CreateUnaccelerated2dBuffer(); } - if (canvas2d_bridge_) - canvas2d_bridge_->SetCanvasResourceHost(this); - else + if (!canvas2d_bridge_) return; + canvas2d_bridge_->SetCanvasResourceHost(this); + bool is_being_displayed = + GetLayoutObject() && GetComputedStyle() && + GetComputedStyle()->Visibility() == EVisibility::kVisible; + canvas2d_bridge_->SetIsBeingDisplayed(is_being_displayed); + did_fail_to_create_resource_provider_ = false; UpdateMemoryUsage();
diff --git a/third_party/blink/renderer/core/html/forms/form_controller.cc b/third_party/blink/renderer/core/html/forms/form_controller.cc index b9b161e..befd317b 100644 --- a/third_party/blink/renderer/core/html/forms/form_controller.cc +++ b/third_party/blink/renderer/core/html/forms/form_controller.cc
@@ -62,8 +62,9 @@ } bool IsDirtyControl(const ListedElement& control) { - if (control.IsFormControlElementWithState()) - return ToHTMLFormControlElementWithState(control).UserHasEditedTheField(); + if (auto* form_control_element = + DynamicTo<HTMLFormControlElementWithState>(control)) + return form_control_element->UserHasEditedTheField(); if (control.IsElementInternals()) { // We have no ways to know the dirtiness of a form-associated custom // element. Assume it is dirty if it has focus.
diff --git a/third_party/blink/renderer/core/html/forms/html_data_list_options_collection.h b/third_party/blink/renderer/core/html/forms/html_data_list_options_collection.h index 4b68f90..94d5f68 100644 --- a/third_party/blink/renderer/core/html/forms/html_data_list_options_collection.h +++ b/third_party/blink/renderer/core/html/forms/html_data_list_options_collection.h
@@ -7,6 +7,7 @@ #include "third_party/blink/renderer/core/html/forms/html_option_element.h" #include "third_party/blink/renderer/core/html/html_collection.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" namespace blink { @@ -28,11 +29,12 @@ bool ElementMatches(const HTMLElement&) const; }; -DEFINE_TYPE_CASTS(HTMLDataListOptionsCollection, - LiveNodeListBase, - collection, - collection->GetType() == kDataListOptions, - collection.GetType() == kDataListOptions); +template <> +struct DowncastTraits<HTMLDataListOptionsCollection> { + static bool AllowFrom(const LiveNodeListBase& collection) { + return collection.GetType() == kDataListOptions; + } +}; inline bool HTMLDataListOptionsCollection::ElementMatches( const HTMLElement& element) const {
diff --git a/third_party/blink/renderer/core/html/forms/html_form_control_element.cc b/third_party/blink/renderer/core/html/forms/html_form_control_element.cc index faca1baab..cb63b742 100644 --- a/third_party/blink/renderer/core/html/forms/html_form_control_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_form_control_element.cc
@@ -205,13 +205,15 @@ void HTMLFormControlElement::AttachLayoutTree(AttachContext& context) { HTMLElement::AttachLayoutTree(context); - if (!GetLayoutObject()) - return; - - // The call to updateFromElement() needs to go after the call through + // The call to UpdateFromElement() needs to go after the call through // to the base class's attachLayoutTree() because that can sometimes do a - // close on the layoutObject. - GetLayoutObject()->UpdateFromElement(); + // close on the LayoutObject. + UpdateFromElement(); +} + +void HTMLFormControlElement::UpdateFromElement() { + if (auto* layout_object = GetLayoutObject()) + layout_object->UpdateFromElement(); } void HTMLFormControlElement::DidMoveToNewDocument(Document& old_document) {
diff --git a/third_party/blink/renderer/core/html/forms/html_form_control_element.h b/third_party/blink/renderer/core/html/forms/html_form_control_element.h index 859d6e9f..86d721d 100644 --- a/third_party/blink/renderer/core/html/forms/html_form_control_element.h +++ b/third_party/blink/renderer/core/html/forms/html_form_control_element.h
@@ -150,6 +150,10 @@ virtual void ResetImpl() {} + // This is called just after attaching a LayoutObject. However, + // GetLayoutObject() can be nullptr. + virtual void UpdateFromElement(); + private: bool IsFormControlElement() const final { return true; } bool AlwaysCreateUserAgentShadowRoot() const override { return true; }
diff --git a/third_party/blink/renderer/core/html/forms/html_form_control_element_with_state.h b/third_party/blink/renderer/core/html/forms/html_form_control_element_with_state.h index f5e11249c..e3e9799 100644 --- a/third_party/blink/renderer/core/html/forms/html_form_control_element_with_state.h +++ b/third_party/blink/renderer/core/html/forms/html_form_control_element_with_state.h
@@ -27,6 +27,7 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/html/forms/html_form_control_element.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" namespace blink { @@ -68,11 +69,12 @@ bool IsWearingAutofillAnchorMantle() const; }; -DEFINE_TYPE_CASTS(HTMLFormControlElementWithState, - ListedElement, - control, - control->IsFormControlElementWithState(), - control.IsFormControlElementWithState()); +template <> +struct DowncastTraits<HTMLFormControlElementWithState> { + static bool AllowFrom(const ListedElement& control) { + return control.IsFormControlElementWithState(); + } +}; } // namespace blink
diff --git a/third_party/blink/renderer/core/html/forms/html_options_collection.h b/third_party/blink/renderer/core/html/forms/html_options_collection.h index 2f371ef..30411954 100644 --- a/third_party/blink/renderer/core/html/forms/html_options_collection.h +++ b/third_party/blink/renderer/core/html/forms/html_options_collection.h
@@ -26,6 +26,7 @@ #include "third_party/blink/renderer/core/html/forms/html_option_element.h" #include "third_party/blink/renderer/core/html/html_collection.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" namespace blink { @@ -61,11 +62,12 @@ void SupportedPropertyNames(Vector<String>& names) override; }; -DEFINE_TYPE_CASTS(HTMLOptionsCollection, - LiveNodeListBase, - collection, - collection->GetType() == kSelectOptions, - collection.GetType() == kSelectOptions); +template <> +struct DowncastTraits<HTMLOptionsCollection> { + static bool AllowFrom(const LiveNodeListBase& collection) { + return collection.GetType() == kSelectOptions; + } +}; inline bool HTMLOptionsCollection::ElementMatches( const HTMLElement& element) const {
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.cc b/third_party/blink/renderer/core/html/forms/html_select_element.cc index 01ad655..2e149ba 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_select_element.cc
@@ -357,7 +357,7 @@ if (GetLayoutObject()) { if (option.Selected() && UsesMenuList()) - GetLayoutObject()->UpdateFromElement(); + UpdateFromElement(); if (AXObjectCache* cache = GetLayoutObject()->GetDocument().ExistingAXObjectCache()) cache->ChildrenChanged(this); @@ -903,8 +903,8 @@ return; suggested_option_ = option; - if (LayoutObject* layout_object = GetLayoutObject()) { - layout_object->UpdateFromElement(); + if (GetLayoutObject()) { + UpdateFromElement(); ScrollToOption(option); } if (PopupIsVisible()) @@ -1078,8 +1078,7 @@ } // For the menu list case, this is what makes the selected element appear. - if (LayoutObject* layout_object = GetLayoutObject()) - layout_object->UpdateFromElement(); + UpdateFromElement(); // PopupMenu::UpdateFromElement() posts an O(N) task. if (PopupIsVisible() && should_update_popup) popup_->UpdateFromElement(PopupMenu::kBySelectionChange); @@ -1096,8 +1095,9 @@ // Need to check UsesMenuList() again because event handlers might // change the status. if (UsesMenuList()) { - // DidSelectOption() is O(N) because of HTMLOptionElement::index(). - ToLayoutMenuList(layout_object)->DidSelectOption(element); + // DidUpdateMenuListActiveOption() is O(N) because of + // HTMLOptionElement::index(). + DidUpdateMenuListActiveOption(element); } } } @@ -1510,6 +1510,27 @@ UpdateListBoxSelection(!multi_select); } +void HTMLSelectElement::DidUpdateMenuListActiveOption( + HTMLOptionElement* option) { + if (!GetDocument().ExistingAXObjectCache()) + return; + + int option_index = option ? option->index() : -1; + if (ax_menulist_last_active_index_ == option_index) + return; + ax_menulist_last_active_index_ = option_index; + + // We skip sending accessiblity notifications for the very first option, + // otherwise we get extra focus and select events that are undesired. + if (!has_updated_menulist_active_option_) { + has_updated_menulist_active_option_ = true; + return; + } + + GetDocument().ExistingAXObjectCache()->HandleUpdateActiveMenuOption( + ToLayoutMenuList(GetLayoutObject()), option_index); +} + HTMLOptionElement* HTMLSelectElement::EventTargetOption(const Event& event) { return DynamicTo<HTMLOptionElement>(event.target()->ToNode()); } @@ -2002,8 +2023,7 @@ void HTMLSelectElement::SetIndexToSelectOnCancel(int list_index) { index_to_select_on_cancel_ = list_index; - if (GetLayoutObject()) - GetLayoutObject()->UpdateFromElement(); + UpdateFromElement(); } HTMLOptionElement* HTMLSelectElement::OptionToBeShown() const { @@ -2203,6 +2223,20 @@ DetachLayoutTree(); SetNeedsStyleRecalc(kLocalStyleChange, StyleChangeReasonForTracing::Create( style_change_reason::kControl)); + + if (UsesMenuList()) { + ax_menulist_last_active_index_ = -1; + has_updated_menulist_active_option_ = false; + } +} + +void HTMLSelectElement::UpdateFromElement() { + auto* layout_object = GetLayoutObject(); + if (!layout_object) + return; + layout_object->UpdateFromElement(); + if (UsesMenuList()) + DidUpdateMenuListActiveOption(OptionToBeShown()); } } // namespace blink
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.h b/third_party/blink/renderer/core/html/forms/html_select_element.h index 4e4258d..64fd37e 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_element.h +++ b/third_party/blink/renderer/core/html/forms/html_select_element.h
@@ -179,6 +179,7 @@ private: const AtomicString& FormControlType() const override; + void UpdateFromElement() override; bool MayTriggerVirtualKeyboard() const override; @@ -242,6 +243,7 @@ void ParseMultipleAttribute(const AtomicString&); HTMLOptionElement* LastSelectedOption() const; void UpdateSelectedState(HTMLOptionElement*, bool multi, bool shift); + void DidUpdateMenuListActiveOption(HTMLOptionElement*); void MenuListDefaultEventHandler(Event&); void HandlePopupOpenKeyboardEvent(Event&); bool ShouldOpenPopupForKeyDownEvent(const KeyboardEvent&); @@ -303,6 +305,8 @@ Member<HTMLOptionElement> active_selection_end_; Member<HTMLOptionElement> option_to_scroll_to_; Member<HTMLOptionElement> suggested_option_; + int ax_menulist_last_active_index_ = -1; + bool has_updated_menulist_active_option_ = false; bool is_multiple_; bool is_in_non_contiguous_selection_; bool active_selection_state_;
diff --git a/third_party/blink/renderer/core/html/html_collection.cc b/third_party/blink/renderer/core/html/html_collection.cc index f2645f8..f641dc4 100644 --- a/third_party/blink/renderer/core/html/html_collection.cc +++ b/third_party/blink/renderer/core/html/html_collection.cc
@@ -225,13 +225,13 @@ case kTSectionRows: return element.HasTagName(html_names::kTrTag); case kSelectOptions: - return ToHTMLOptionsCollection(html_collection).ElementMatches(element); + return To<HTMLOptionsCollection>(html_collection).ElementMatches(element); case kSelectedOptions: { auto* option_element = DynamicTo<HTMLOptionElement>(element); return option_element && option_element->Selected(); } case kDataListOptions: - return ToHTMLDataListOptionsCollection(html_collection) + return To<HTMLDataListOptionsCollection>(html_collection) .ElementMatches(element); case kMapAreas: return element.HasTagName(html_names::kAreaTag); @@ -281,7 +281,7 @@ case kTagCollectionType: return To<TagCollection>(*this).ElementMatches(element); case kHTMLTagCollectionType: - return ToHTMLTagCollection(*this).ElementMatches(element); + return To<HTMLTagCollection>(*this).ElementMatches(element); case kTagCollectionNSType: return To<TagCollectionNS>(*this).ElementMatches(element); case kWindowNamedItems: @@ -352,7 +352,7 @@ switch (GetType()) { case kHTMLTagCollectionType: return ElementTraversal::FirstWithin( - RootNode(), MakeIsMatch(ToHTMLTagCollection(*this))); + RootNode(), MakeIsMatch(To<HTMLTagCollection>(*this))); case kClassCollectionType: return ElementTraversal::FirstWithin( RootNode(), MakeIsMatch(To<ClassCollection>(*this))); @@ -381,7 +381,7 @@ case kHTMLTagCollectionType: return TraverseMatchingElementsForwardToOffset( current_element, &RootNode(), offset, current_offset, - MakeIsMatch(ToHTMLTagCollection(*this))); + MakeIsMatch(To<HTMLTagCollection>(*this))); case kClassCollectionType: return TraverseMatchingElementsForwardToOffset( current_element, &RootNode(), offset, current_offset,
diff --git a/third_party/blink/renderer/core/html/html_collection.h b/third_party/blink/renderer/core/html/html_collection.h index d1388a8..a864646 100644 --- a/third_party/blink/renderer/core/html/html_collection.h +++ b/third_party/blink/renderer/core/html/html_collection.h
@@ -29,6 +29,7 @@ #include "third_party/blink/renderer/core/dom/live_node_list_base.h" #include "third_party/blink/renderer/core/html/collection_items_cache.h" #include "third_party/blink/renderer/core/html/collection_type.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" #include "third_party/blink/renderer/platform/wtf/forward.h" namespace blink { @@ -212,11 +213,12 @@ mutable CollectionItemsCache<HTMLCollection, Element> collection_items_cache_; }; -DEFINE_TYPE_CASTS(HTMLCollection, - LiveNodeListBase, - collection, - IsHTMLCollectionType(collection->GetType()), - IsHTMLCollectionType(collection.GetType())); +template <> +struct DowncastTraits<HTMLCollection> { + static bool AllowFrom(const LiveNodeListBase& collection) { + return IsHTMLCollectionType(collection.GetType()); + } +}; DISABLE_CFI_PERF inline void HTMLCollection::InvalidateCacheForAttribute(
diff --git a/third_party/blink/renderer/core/html/html_tag_collection.h b/third_party/blink/renderer/core/html/html_tag_collection.h index acdfe63..10f2b4e 100644 --- a/third_party/blink/renderer/core/html/html_tag_collection.h +++ b/third_party/blink/renderer/core/html/html_tag_collection.h
@@ -27,6 +27,7 @@ #include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/dom/tag_collection.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" namespace blink { @@ -46,11 +47,12 @@ AtomicString lowered_qualified_name_; }; -DEFINE_TYPE_CASTS(HTMLTagCollection, - LiveNodeListBase, - collection, - collection->GetType() == kHTMLTagCollectionType, - collection.GetType() == kHTMLTagCollectionType); +template <> +struct DowncastTraits<HTMLTagCollection> { + static bool AllowFrom(const LiveNodeListBase& collection) { + return collection.GetType() == kHTMLTagCollectionType; + } +}; inline bool HTMLTagCollection::ElementMatches( const Element& test_element) const {
diff --git a/third_party/blink/renderer/core/html/imports/html_import_child.cc b/third_party/blink/renderer/core/html/imports/html_import_child.cc index 7ebf653..301cb4a5 100644 --- a/third_party/blink/renderer/core/html/imports/html_import_child.cc +++ b/third_party/blink/renderer/core/html/imports/html_import_child.cc
@@ -108,7 +108,7 @@ } void HTMLImportChild::StateWillChange() { - ToHTMLImportTreeRoot(Root())->ScheduleRecalcState(); + To<HTMLImportTreeRoot>(Root())->ScheduleRecalcState(); } void HTMLImportChild::StateDidChange() {
diff --git a/third_party/blink/renderer/core/html/imports/html_import_tree_root.h b/third_party/blink/renderer/core/html/imports/html_import_tree_root.h index a97a05e2..5bfb3fe 100644 --- a/third_party/blink/renderer/core/html/imports/html_import_tree_root.h +++ b/third_party/blink/renderer/core/html/imports/html_import_tree_root.h
@@ -9,6 +9,7 @@ #include "third_party/blink/renderer/core/html/imports/html_import.h" #include "third_party/blink/renderer/platform/bindings/name_client.h" #include "third_party/blink/renderer/platform/timer.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" namespace blink { @@ -48,11 +49,10 @@ ImportList imports_; }; -DEFINE_TYPE_CASTS(HTMLImportTreeRoot, - HTMLImport, - import, - import->IsRoot(), - import.IsRoot()); +template <> +struct DowncastTraits<HTMLImportTreeRoot> { + static bool AllowFrom(const HTMLImport& import) { return import.IsRoot(); } +}; } // namespace blink
diff --git a/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc b/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc index 9244171f..eccc234f 100644 --- a/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc +++ b/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc
@@ -93,11 +93,13 @@ } // namespace struct LazyLoadFrameObserver::LazyLoadRequestInfo { - LazyLoadRequestInfo(const ResourceRequest& resource_request, + LazyLoadRequestInfo(const ResourceRequest& passed_resource_request, WebFrameLoadType frame_load_type) - : resource_request(resource_request), frame_load_type(frame_load_type) {} + : frame_load_type(frame_load_type) { + resource_request.CopyFrom(passed_resource_request); + } - const ResourceRequest resource_request; + ResourceRequest resource_request; const WebFrameLoadType frame_load_type; };
diff --git a/third_party/blink/renderer/core/layout/layout_file_upload_control.cc b/third_party/blink/renderer/core/layout/layout_file_upload_control.cc index bf2b1e4..ffa31dd 100644 --- a/third_party/blink/renderer/core/layout/layout_file_upload_control.cc +++ b/third_party/blink/renderer/core/layout/layout_file_upload_control.cc
@@ -23,7 +23,6 @@ #include <math.h> #include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/core/dom/shadow_root.h" -#include "third_party/blink/renderer/core/editing/position_with_affinity.h" #include "third_party/blink/renderer/core/fileapi/file_list.h" #include "third_party/blink/renderer/core/html/forms/html_input_element.h" #include "third_party/blink/renderer/core/input_type_names.h" @@ -144,11 +143,6 @@ ClearPreferredLogicalWidthsDirty(); } -PositionWithAffinity LayoutFileUploadControl::PositionForPoint( - const PhysicalOffset&) const { - return PositionWithAffinity(); -} - HTMLInputElement* LayoutFileUploadControl::UploadButton() const { return To<HTMLInputElement>(GetNode())->UploadButton(); }
diff --git a/third_party/blink/renderer/core/layout/layout_file_upload_control.h b/third_party/blink/renderer/core/layout/layout_file_upload_control.h index d649472..fac63c2a 100644 --- a/third_party/blink/renderer/core/layout/layout_file_upload_control.h +++ b/third_party/blink/renderer/core/layout/layout_file_upload_control.h
@@ -71,8 +71,6 @@ const PhysicalOffset& paint_offset) const override; int MaxFilenameWidth() const; - - PositionWithAffinity PositionForPoint(const PhysicalOffset&) const override; }; DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutFileUploadControl, IsFileUploadControl());
diff --git a/third_party/blink/renderer/core/layout/layout_menu_list.cc b/third_party/blink/renderer/core/layout/layout_menu_list.cc index d10d4e1..5326ff90 100644 --- a/third_party/blink/renderer/core/layout/layout_menu_list.cc +++ b/third_party/blink/renderer/core/layout/layout_menu_list.cc
@@ -46,10 +46,8 @@ button_text_(nullptr), inner_block_(nullptr), is_empty_(false), - has_updated_active_option_(false), inner_block_height_(LayoutUnit()), - options_width_(0), - last_active_index_(-1) { + options_width_(0) { DCHECK(IsA<HTMLSelectElement>(element)); } @@ -266,8 +264,6 @@ SetText(text.StripWhiteSpace()); - DidUpdateActiveOption(option); - DCHECK(inner_block_); if (HasOptionStyleChanged(inner_block_->StyleRef())) UpdateInnerStyle(); @@ -339,30 +335,6 @@ LayoutBox::ComputeLogicalHeight(logical_height, logical_top, computed_values); } -void LayoutMenuList::DidSelectOption(HTMLOptionElement* option) { - DidUpdateActiveOption(option); -} - -void LayoutMenuList::DidUpdateActiveOption(HTMLOptionElement* option) { - if (!GetDocument().ExistingAXObjectCache()) - return; - - int option_index = option ? option->index() : -1; - if (last_active_index_ == option_index) - return; - last_active_index_ = option_index; - - // We skip sending accessiblity notifications for the very first option, - // otherwise we get extra focus and select events that are undesired. - if (!has_updated_active_option_) { - has_updated_active_option_ = true; - return; - } - - GetDocument().ExistingAXObjectCache()->HandleUpdateActiveMenuOption( - this, option_index); -} - LayoutUnit LayoutMenuList::ClientPaddingLeft() const { return PaddingLeft() + inner_block_->PaddingLeft(); }
diff --git a/third_party/blink/renderer/core/layout/layout_menu_list.h b/third_party/blink/renderer/core/layout/layout_menu_list.h index ba3a7d5a..c8ed491 100644 --- a/third_party/blink/renderer/core/layout/layout_menu_list.h +++ b/third_party/blink/renderer/core/layout/layout_menu_list.h
@@ -31,7 +31,6 @@ namespace blink { -class HTMLOptionElement; class HTMLSelectElement; class LayoutText; @@ -41,7 +40,6 @@ ~LayoutMenuList() override; HTMLSelectElement* SelectElement() const; - void DidSelectOption(HTMLOptionElement*); String GetText() const; const char* GetName() const override { return "LayoutMenuList"; } @@ -103,20 +101,15 @@ void UpdateOptionsWidth() const; void SetIndexToSelectOnCancel(int list_index); - void DidUpdateActiveOption(HTMLOptionElement*); - LayoutText* button_text_; LayoutBlock* inner_block_; bool is_empty_ : 1; - bool has_updated_active_option_ : 1; LayoutUnit inner_block_height_; // m_optionsWidth is calculated and cached on demand. // updateOptionsWidth() should be called before reading them. mutable int options_width_; - int last_active_index_; - scoped_refptr<const ComputedStyle> option_style_; };
diff --git a/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc b/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc index 6f1f6bc..1514dda 100644 --- a/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc +++ b/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc
@@ -249,14 +249,6 @@ return line_height + non_content_height; } -void LayoutTextControlSingleLine::Autoscroll(const PhysicalOffset& position) { - LayoutBox* layout_object = InnerEditorElement()->GetLayoutBox(); - if (!layout_object) - return; - - layout_object->Autoscroll(position); -} - LayoutUnit LayoutTextControlSingleLine::ScrollWidth() const { // If in preview state, fake the scroll width to prevent that any information // about the suggested content can be derived from the size.
diff --git a/third_party/blink/renderer/core/layout/layout_text_control_single_line.h b/third_party/blink/renderer/core/layout/layout_text_control_single_line.h index a49de23..8957bff5 100644 --- a/third_party/blink/renderer/core/layout/layout_text_control_single_line.h +++ b/third_party/blink/renderer/core/layout/layout_text_control_single_line.h
@@ -61,8 +61,6 @@ const PhysicalOffset& accumulated_offset, HitTestAction) final; - void Autoscroll(const PhysicalOffset&) final; - // Subclassed to forward to our inner div. LayoutUnit ScrollWidth() const final; LayoutUnit ScrollHeight() const final;
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.cc b/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.cc index ab449b5..84cdd33 100644 --- a/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.cc +++ b/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.cc
@@ -119,8 +119,8 @@ bool LayoutNGBlockFlowMixin< Base>::PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const { // LayoutNGBlockFlowMixin is in charge of paint invalidation of the first - // line. - if (PaintFragment()) + // line and painting backplates. + if (PaintFragment() || Base::FragmentItems()) return false; if (Base::StyleRef().HasColumnRule())
diff --git a/third_party/blink/renderer/core/loader/base_fetch_context_test.cc b/third_party/blink/renderer/core/loader/base_fetch_context_test.cc index 54d993b..3283e99 100644 --- a/third_party/blink/renderer/core/loader/base_fetch_context_test.cc +++ b/third_party/blink/renderer/core/loader/base_fetch_context_test.cc
@@ -153,11 +153,11 @@ ContentSecurityPolicy* policy = execution_context_->GetContentSecurityPolicy(); policy->DidReceiveHeader("script-src https://foo.test", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + network::mojom::ContentSecurityPolicyType::kEnforce, + network::mojom::ContentSecurityPolicySource::kHTTP); policy->DidReceiveHeader("script-src https://bar.test", - kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceHTTP); + network::mojom::ContentSecurityPolicyType::kReport, + network::mojom::ContentSecurityPolicySource::kHTTP); KURL url(NullURL(), "http://baz.test"); ResourceRequest resource_request(url); @@ -179,11 +179,11 @@ ContentSecurityPolicy* policy = execution_context_->GetContentSecurityPolicy(); policy->DidReceiveHeader("script-src https://foo.test", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + network::mojom::ContentSecurityPolicyType::kEnforce, + network::mojom::ContentSecurityPolicySource::kHTTP); policy->DidReceiveHeader("script-src https://bar.test", - kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceHTTP); + network::mojom::ContentSecurityPolicyType::kReport, + network::mojom::ContentSecurityPolicySource::kHTTP); KURL url(NullURL(), "http://baz.test"); @@ -294,8 +294,8 @@ ContentSecurityPolicy* policy = execution_context_->GetContentSecurityPolicy(); policy->DidReceiveHeader("default-src 'self'", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + network::mojom::ContentSecurityPolicyType::kEnforce, + network::mojom::ContentSecurityPolicySource::kHTTP); KURL data_url("data:image/png;base64,test");
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context.cc b/third_party/blink/renderer/core/loader/frame_fetch_context.cc index 81f8b97..be70be7 100644 --- a/third_party/blink/renderer/core/loader/frame_fetch_context.cc +++ b/third_party/blink/renderer/core/loader/frame_fetch_context.cc
@@ -573,14 +573,9 @@ &enabled_hints); } - // TODO(iclelland): If feature policy control over client hints ships, remove - // the runtime flag check for the next four hints. Currently, when the - // kAllowClientHintsToThirdParty feature is enabled, but the runtime flag is - // *not* set, the behaviour is that these four hints will be sent on all - // eligible requests. Feature policy control is intended to change that - // default. - - if ((!RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() || + // The next 4 hints should be enabled if we're allowing legacy hints to third + // parties, or if FeaturePolicy delegation says they are allowed. + if ((base::FeatureList::IsEnabled(kAllowClientHintsToThirdParty) || policy->IsFeatureEnabledForOrigin( mojom::FeaturePolicyFeature::kClientHintDeviceMemory, resource_origin)) && @@ -593,7 +588,7 @@ } float dpr = GetDevicePixelRatio(); - if ((!RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() || + if ((base::FeatureList::IsEnabled(kAllowClientHintsToThirdParty) || policy->IsFeatureEnabledForOrigin( mojom::FeaturePolicyFeature::kClientHintDPR, resource_origin)) && ShouldSendClientHint(mojom::WebClientHintsType::kDpr, hints_preferences, @@ -601,19 +596,7 @@ request.SetHttpHeaderField("DPR", AtomicString(String::Number(dpr))); } - if ((!RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() || - policy->IsFeatureEnabledForOrigin( - mojom::FeaturePolicyFeature::kClientHintWidth, resource_origin)) && - ShouldSendClientHint(mojom::WebClientHintsType::kResourceWidth, - hints_preferences, enabled_hints)) { - if (resource_width.is_set) { - float physical_width = resource_width.width * dpr; - request.SetHttpHeaderField( - "Width", AtomicString(String::Number(ceil(physical_width)))); - } - } - - if ((!RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() || + if ((base::FeatureList::IsEnabled(kAllowClientHintsToThirdParty) || policy->IsFeatureEnabledForOrigin( mojom::FeaturePolicyFeature::kClientHintViewportWidth, resource_origin)) && @@ -625,6 +608,18 @@ AtomicString(String::Number(GetFrame()->View()->ViewportWidth()))); } + if ((base::FeatureList::IsEnabled(kAllowClientHintsToThirdParty) || + policy->IsFeatureEnabledForOrigin( + mojom::FeaturePolicyFeature::kClientHintWidth, resource_origin)) && + ShouldSendClientHint(mojom::WebClientHintsType::kResourceWidth, + hints_preferences, enabled_hints)) { + if (resource_width.is_set) { + float physical_width = resource_width.width * dpr; + request.SetHttpHeaderField( + "Width", AtomicString(String::Number(ceil(physical_width)))); + } + } + // TODO(iclelland): If feature policy control over client hints ships, remove // the runtime flag check and the 1p origin requirement for the remaining // hints. Currently, even when the kAllowClientHintsToThirdParty feature is
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc b/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc index ea425c88..c07ea3c 100644 --- a/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc +++ b/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc
@@ -655,8 +655,15 @@ ExpectHeader("https://www.example.com/1.gif", "Viewport-Width", false, ""); // Without a feature policy header, the client hints should be sent only to // the first party origins. + // Device-memory is a legacy hint that's sent on Android regardless of Feature + // Policy delegation. +#if defined(OS_ANDROID) + ExpectHeader("https://www.someother-example.com/1.gif", "Device-Memory", true, + "4"); +#else ExpectHeader("https://www.someother-example.com/1.gif", "Device-Memory", false, ""); +#endif } // Verify that client hints are not attached when the resources do not belong to @@ -989,15 +996,28 @@ // With a feature policy header, the client hints should be sent to the // declared third party origins. ExpectHeader("https://www.example.net/1.gif", "Device-Memory", true, "4"); + // Device-memory is a legacy hint that's sent on Android regardless of Feature + // Policy delegation. +#if defined(OS_ANDROID) + ExpectHeader("https://www.someother-example.com/1.gif", "Device-Memory", true, + "4"); +#else ExpectHeader("https://www.someother-example.com/1.gif", "Device-Memory", false, ""); +#endif // `Sec-CH-UA` is special. ExpectHeader("https://www.example.net/1.gif", "Sec-CH-UA", true, ""); // Other hints not declared in the policy are still not attached. ExpectHeader("https://www.example.net/1.gif", "downlink", false, ""); ExpectHeader("https://www.example.net/1.gif", "ect", false, ""); + // DPR is a legacy hint that's sent on Android regardless of Feature Policy + // delegation. +#if defined(OS_ANDROID) + ExpectHeader("https://www.example.net/1.gif", "DPR", true, "1"); +#else ExpectHeader("https://www.example.net/1.gif", "DPR", false, ""); +#endif ExpectHeader("https://www.example.net/1.gif", "Sec-CH-Lang", false, ""); ExpectHeader("https://www.example.net/1.gif", "Sec-CH-UA-Arch", false, ""); ExpectHeader("https://www.example.net/1.gif", "Sec-CH-UA-Platform", false,
diff --git a/third_party/blink/renderer/core/loader/frame_load_request.cc b/third_party/blink/renderer/core/loader/frame_load_request.cc index 3dc7907..54fd2be 100644 --- a/third_party/blink/renderer/core/loader/frame_load_request.cc +++ b/third_party/blink/renderer/core/loader/frame_load_request.cc
@@ -43,11 +43,10 @@ FrameLoadRequest::FrameLoadRequest(Document* origin_document, const ResourceRequest& resource_request) - : origin_document_(origin_document), - resource_request_(resource_request), should_send_referrer_(kMaybeSendReferrer) { // These flags are passed to a service worker which controls the page. + resource_request_.CopyFrom(resource_request); resource_request_.SetMode(network::mojom::RequestMode::kNavigate); resource_request_.SetCredentialsMode( network::mojom::CredentialsMode::kInclude);
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc index e2640cf..69cce372 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.cc +++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -1672,16 +1672,18 @@ // already been passed down. if (origin_policy.has_value() && !csp->HasPolicyFromSource( - kContentSecurityPolicyHeaderSourceOriginPolicy)) { + network::mojom::ContentSecurityPolicySource::kOriginPolicy)) { for (const auto& policy : origin_policy->content_security_policies) { - csp->DidReceiveHeader(policy, kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceOriginPolicy); + csp->DidReceiveHeader( + policy, network::mojom::ContentSecurityPolicyType::kEnforce, + network::mojom::ContentSecurityPolicySource::kOriginPolicy); } for (const auto& policy : origin_policy->content_security_policies_report_only) { - csp->DidReceiveHeader(policy, kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceOriginPolicy); + csp->DidReceiveHeader( + policy, network::mojom::ContentSecurityPolicyType::kReport, + network::mojom::ContentSecurityPolicySource::kOriginPolicy); } } } @@ -1698,14 +1700,14 @@ if (parent_security_origin && ContentSecurityPolicy::ShouldEnforceEmbeddersPolicy( response, parent_security_origin)) { - csp->AddPolicyFromHeaderValue(RequiredCSP(), - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + csp->AddPolicyFromHeaderValue( + RequiredCSP(), network::mojom::ContentSecurityPolicyType::kEnforce, + network::mojom::ContentSecurityPolicySource::kHTTP); } else { auto* required_csp = MakeGarbageCollected<ContentSecurityPolicy>(); required_csp->AddPolicyFromHeaderValue( - RequiredCSP(), kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + RequiredCSP(), network::mojom::ContentSecurityPolicyType::kEnforce, + network::mojom::ContentSecurityPolicySource::kHTTP); if (!required_csp->Subsumes(*csp)) return nullptr; }
diff --git a/third_party/blink/renderer/core/loader/http_equiv.cc b/third_party/blink/renderer/core/loader/http_equiv.cc index 9e41af99..77c76800 100644 --- a/third_party/blink/renderer/core/loader/http_equiv.cc +++ b/third_party/blink/renderer/core/loader/http_equiv.cc
@@ -142,13 +142,13 @@ return; if (EqualIgnoringASCIICase(equiv, "content-security-policy")) { document.GetContentSecurityPolicy()->DidReceiveHeader( - content, kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceMeta); + content, network::mojom::ContentSecurityPolicyType::kEnforce, + network::mojom::ContentSecurityPolicySource::kMeta); } else if (EqualIgnoringASCIICase(equiv, "content-security-policy-report-only")) { document.GetContentSecurityPolicy()->DidReceiveHeader( - content, kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderSourceMeta); + content, network::mojom::ContentSecurityPolicyType::kReport, + network::mojom::ContentSecurityPolicySource::kMeta); } else { NOTREACHED(); }
diff --git a/third_party/blink/renderer/core/loader/link_loader_test.cc b/third_party/blink/renderer/core/loader/link_loader_test.cc index 35caae3f..3667de3 100644 --- a/third_party/blink/renderer/core/loader/link_loader_test.cc +++ b/third_party/blink/renderer/core/loader/link_loader_test.cc
@@ -371,8 +371,8 @@ dummy_page_holder_->GetDocument() .GetContentSecurityPolicy() ->DidReceiveHeader(test_case.content_security_policy, - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + network::mojom::ContentSecurityPolicyType::kEnforce, + network::mojom::ContentSecurityPolicySource::kHTTP); LinkLoadParameters params( LinkRelAttribute("preload"), kCrossOriginAttributeNotSet, String(), "script", String(), test_case.nonce, String(), String(),
diff --git a/third_party/blink/renderer/core/loader/threadable_loader.cc b/third_party/blink/renderer/core/loader/threadable_loader.cc index f0ef7382..1a73e01d 100644 --- a/third_party/blink/renderer/core/loader/threadable_loader.cc +++ b/third_party/blink/renderer/core/loader/threadable_loader.cc
@@ -274,7 +274,8 @@ request_headers_ = request.HttpHeaderFields(); report_upload_progress_ = request.ReportUploadProgress(); - ResourceRequest new_request(request); + ResourceRequest new_request; + new_request.CopyFrom(request); // Set the service worker mode to none if "bypass for network" in DevTools is // enabled. @@ -319,7 +320,7 @@ // Save the request to fallback_request_for_service_worker to use when the // service worker doesn't handle (call respondWith()) a CORS enabled // request. - fallback_request_for_service_worker_ = ResourceRequest(request); + fallback_request_for_service_worker_.CopyFrom(request); // Skip the service worker for the fallback request. fallback_request_for_service_worker_.SetSkipServiceWorker(true); } @@ -356,7 +357,7 @@ std::unique_ptr<ResourceRequest> preflight_request = CreateAccessControlPreflightRequest(actual_request, GetSecurityOrigin()); - actual_request_ = actual_request; + actual_request_.CopyFrom(actual_request); actual_options_ = actual_options; // Explicitly set |skip_service_worker| to true here. Although the page is @@ -405,7 +406,8 @@ return; } - ResourceRequest cross_origin_request(request); + ResourceRequest cross_origin_request; + cross_origin_request.CopyFrom(request); ResourceLoaderOptions cross_origin_options(resource_loader_options_); cross_origin_request.RemoveUserAndPassFromURL(); @@ -678,7 +680,8 @@ // We're initiating a new request (for redirect), so update // |last_request_url_| by destroying |assign_on_scope_exit|. - ResourceRequest cross_origin_request(new_request); + ResourceRequest cross_origin_request; + cross_origin_request.CopyFrom(new_request); cross_origin_request.SetInitialUrlForResourceTiming(initial_request_url_); // Remove any headers that may have been added by the network layer that cause @@ -949,15 +952,17 @@ if (GetResource()) checker_.WillRemoveClient(); ClearResource(); - ResourceRequest fallback_request(fallback_request_for_service_worker_); - fallback_request_for_service_worker_ = ResourceRequest(); + ResourceRequest fallback_request; + fallback_request.CopyFrom(fallback_request_for_service_worker_); + fallback_request_for_service_worker_.CopyFrom(ResourceRequest()); DispatchInitialRequest(fallback_request); } void ThreadableLoader::LoadActualRequest() { - ResourceRequest actual_request = actual_request_; + ResourceRequest actual_request; + actual_request.CopyFrom(actual_request_); ResourceLoaderOptions actual_options = actual_options_; - actual_request_ = ResourceRequest(); + actual_request_.CopyFrom(ResourceRequest()); actual_options_ = ResourceLoaderOptions(); if (GetResource())
diff --git a/third_party/blink/renderer/core/paint/document_marker_painter.cc b/third_party/blink/renderer/core/paint/document_marker_painter.cc index 21521e76..fd46f42 100644 --- a/third_party/blink/renderer/core/paint/document_marker_painter.cc +++ b/third_party/blink/renderer/core/paint/document_marker_painter.cc
@@ -186,7 +186,21 @@ ? style.VisitedDependentColor(GetCSSPropertyWebkitTextFillColor()) : marker.UnderlineColor(); context.SetStrokeColor(marker_color); - + // Set the style of the underline if there is any. + switch (marker.UnderlineStyle()) { + case ui::mojom::ImeTextSpanUnderlineStyle::kDash: + context.SetStrokeStyle(StrokeStyle::kDashedStroke); + break; + case ui::mojom::ImeTextSpanUnderlineStyle::kDot: + context.SetStrokeStyle(StrokeStyle::kDottedStroke); + break; + case ui::mojom::ImeTextSpanUnderlineStyle::kSolid: + context.SetStrokeStyle(StrokeStyle::kSolidStroke); + break; + case ui::mojom::ImeTextSpanUnderlineStyle::kNone: + context.SetStrokeStyle(StrokeStyle::kNoStroke); + break; + } context.SetStrokeThickness(line_thickness); context.DrawLineForText( FloatPoint(
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc index d0cc934..7c64841 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
@@ -167,32 +167,15 @@ // the paragraph level. Store the results in paragraph_backplates. Vector<PhysicalRect> BuildBackplate(NGInlineCursor* descendants, const PhysicalOffset& paint_offset) { - Vector<PhysicalRect> paragraph_backplates; - PhysicalRect current_backplate; - int consecutive_line_breaks = 0; - // The number of consecutive forced breaks that split the backplate by // paragraph. static constexpr int kMaxConsecutiveLineBreaks = 2; - // Build up and paint backplates of all child inline text boxes. We are not - // able to simply use the linebox rect to compute the backplate because the - // backplate should only be painted for inline text and not for atomic - // inlines. - for (; *descendants; descendants->MoveToNext()) { - const NGPaintFragment* child = descendants->CurrentPaintFragment(); - if (!child) // TODO(kojii): Support NGFragmentItem - continue; - const NGPhysicalFragment& child_fragment = child->PhysicalFragment(); - if (child_fragment.IsHiddenForPaint() || child_fragment.IsFloating()) - continue; - if (auto* text_fragment = - DynamicTo<NGPhysicalTextFragment>(child_fragment)) { - if (text_fragment->IsLineBreak()) { - consecutive_line_breaks++; - continue; - } + struct Backplates { + STACK_ALLOCATED(); + public: + void AddTextRect(const PhysicalRect& box_rect) { if (consecutive_line_breaks >= kMaxConsecutiveLineBreaks) { // This is a paragraph point. paragraph_backplates.push_back(current_backplate); @@ -200,15 +183,59 @@ } consecutive_line_breaks = 0; - PhysicalRect box_rect(child->InlineOffsetToContainerBox() + paint_offset, - child->Size()); current_backplate.Unite(box_rect); } + + void AddLineBreak() { consecutive_line_breaks++; } + + Vector<PhysicalRect> paragraph_backplates; + PhysicalRect current_backplate; + int consecutive_line_breaks = 0; + } backplates; + + // Build up and paint backplates of all child inline text boxes. We are not + // able to simply use the linebox rect to compute the backplate because the + // backplate should only be painted for inline text and not for atomic + // inlines. + for (; *descendants; descendants->MoveToNext()) { + if (const NGPaintFragment* child = descendants->CurrentPaintFragment()) { + const NGPhysicalFragment& child_fragment = child->PhysicalFragment(); + if (child_fragment.IsHiddenForPaint() || child_fragment.IsFloating()) + continue; + if (auto* text_fragment = + DynamicTo<NGPhysicalTextFragment>(child_fragment)) { + if (text_fragment->IsLineBreak()) { + backplates.AddLineBreak(); + continue; + } + + PhysicalRect box_rect( + child->InlineOffsetToContainerBox() + paint_offset, child->Size()); + backplates.AddTextRect(box_rect); + } + continue; + } + if (const NGFragmentItem* child_item = descendants->CurrentItem()) { + if (child_item->IsHiddenForPaint()) + continue; + if (child_item->IsText()) { + if (child_item->IsLineBreak()) { + backplates.AddLineBreak(); + continue; + } + + PhysicalRect box_rect(child_item->Offset() + paint_offset, + child_item->Size()); + backplates.AddTextRect(box_rect); + } + continue; + } + NOTREACHED(); } - if (!current_backplate.IsEmpty()) - paragraph_backplates.push_back(current_backplate); - return paragraph_backplates; + if (!backplates.current_backplate.IsEmpty()) + backplates.paragraph_backplates.push_back(backplates.current_backplate); + return backplates.paragraph_backplates; } } // anonymous namespace
diff --git a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc index 84a3aec..ab2989f 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
@@ -506,12 +506,15 @@ return; } // This |layout_object| was fragmented across multiple blocks. + DCHECK_EQ(layout_object, first_fragment->GetLayoutObject()); NGPaintFragment* last_fragment = first_fragment->LastForSameLayoutObject(); last_fragment->next_for_same_layout_object_ = this; return; } - DCHECK(add_result.stored_value->value); - add_result.stored_value->value->next_for_same_layout_object_ = this; + NGPaintFragment* last_fragment = add_result.stored_value->value; + DCHECK(last_fragment) << layout_object; + DCHECK_EQ(layout_object, last_fragment->GetLayoutObject()); + last_fragment->next_for_same_layout_object_ = this; add_result.stored_value->value = this; }
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc index d3cb1c4c..97155f7 100644 --- a/third_party/blink/renderer/core/testing/internals.cc +++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -188,6 +188,7 @@ namespace blink { using ui::mojom::ImeTextSpanThickness; +using ui::mojom::ImeTextSpanUnderlineStyle; namespace { @@ -1133,17 +1134,34 @@ return base::nullopt; } +static base::Optional<ImeTextSpanUnderlineStyle> UnderlineStyleFrom( + const String& underline_style) { + if (EqualIgnoringASCIICase(underline_style, "none")) + return ImeTextSpanUnderlineStyle::kNone; + if (EqualIgnoringASCIICase(underline_style, "solid")) + return ImeTextSpanUnderlineStyle::kSolid; + if (EqualIgnoringASCIICase(underline_style, "dot")) + return ImeTextSpanUnderlineStyle::kDot; + if (EqualIgnoringASCIICase(underline_style, "dash")) + return ImeTextSpanUnderlineStyle::kDash; + return base::nullopt; +} + namespace { -void addStyleableMarkerHelper( - const Range* range, - const String& underline_color_value, - const String& thickness_value, - const String& background_color_value, - ExceptionState& exception_state, - std::function< - void(const EphemeralRange&, Color, ImeTextSpanThickness, Color)> - create_marker) { +void addStyleableMarkerHelper(const Range* range, + const String& underline_color_value, + const String& thickness_value, + const String& underline_style_value, + const String& text_color_value, + const String& background_color_value, + ExceptionState& exception_state, + std::function<void(const EphemeralRange&, + Color, + ImeTextSpanThickness, + ImeTextSpanUnderlineStyle, + Color, + Color)> create_marker) { DCHECK(range); range->OwnerDocument().UpdateStyleAndLayout(); @@ -1156,14 +1174,27 @@ return; } + base::Optional<ImeTextSpanUnderlineStyle> underline_style = + UnderlineStyleFrom(underline_style_value); + if (!underline_style_value) { + exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError, + "The underline style provided ('" + + underline_style_value + + "') is invalid."); + return; + } + Color underline_color; Color background_color; + Color text_color; if (ParseColor(underline_color_value, underline_color, exception_state, "Invalid underline color.") && + ParseColor(text_color_value, text_color, exception_state, + "Invalid text color.") && ParseColor(background_color_value, background_color, exception_state, "Invalid background color.")) { create_marker(EphemeralRange(range), underline_color, thickness.value(), - background_color); + underline_style.value(), text_color, background_color); } } @@ -1172,18 +1203,23 @@ void Internals::addCompositionMarker(const Range* range, const String& underline_color_value, const String& thickness_value, + const String& underline_style_value, + const String& text_color_value, const String& background_color_value, ExceptionState& exception_state) { DocumentMarkerController& document_marker_controller = range->OwnerDocument().Markers(); addStyleableMarkerHelper( - range, underline_color_value, thickness_value, background_color_value, - exception_state, - [&document_marker_controller]( - const EphemeralRange& range, Color underline_color, - ImeTextSpanThickness thickness, Color background_color) { + range, underline_color_value, thickness_value, underline_style_value, + text_color_value, background_color_value, exception_state, + [&document_marker_controller](const EphemeralRange& range, + Color underline_color, + ImeTextSpanThickness thickness, + ImeTextSpanUnderlineStyle underline_style, + Color text_color, Color background_color) { document_marker_controller.AddCompositionMarker( - range, underline_color, thickness, background_color); + range, underline_color, thickness, underline_style, text_color, + background_color); }); } @@ -1192,16 +1228,23 @@ const String& thickness_value, const String& background_color_value, ExceptionState& exception_state) { + // Underline style and text color aren't really supported for suggestions so + // providing default values for now. + String underline_style_value = "solid"; + String text_color_value = "transparent"; DocumentMarkerController& document_marker_controller = range->OwnerDocument().Markers(); addStyleableMarkerHelper( - range, underline_color_value, thickness_value, background_color_value, - exception_state, - [&document_marker_controller]( - const EphemeralRange& range, Color underline_color, - ImeTextSpanThickness thickness, Color background_color) { + range, underline_color_value, thickness_value, underline_style_value, + text_color_value, background_color_value, exception_state, + [&document_marker_controller](const EphemeralRange& range, + Color underline_color, + ImeTextSpanThickness thickness, + ImeTextSpanUnderlineStyle underline_style, + Color text_color, Color background_color) { document_marker_controller.AddActiveSuggestionMarker( - range, underline_color, thickness, background_color); + range, underline_color, thickness, underline_style, text_color, + background_color); }); } @@ -1213,6 +1256,10 @@ const String& thickness_value, const String& background_color_value, ExceptionState& exception_state) { + // Underline style and text color aren't really supported for suggestions so + // providing default values for now. + String underline_style_value = "solid"; + String text_color_value = "transparent"; Color suggestion_highlight_color; if (!ParseColor(suggestion_highlight_color_value, suggestion_highlight_color, exception_state, "Invalid suggestion highlight color.")) @@ -1221,11 +1268,13 @@ DocumentMarkerController& document_marker_controller = range->OwnerDocument().Markers(); addStyleableMarkerHelper( - range, underline_color_value, thickness_value, background_color_value, - exception_state, + range, underline_color_value, thickness_value, underline_style_value, + text_color_value, background_color_value, exception_state, [&document_marker_controller, &suggestions, &suggestion_highlight_color]( const EphemeralRange& range, Color underline_color, - ImeTextSpanThickness thickness, Color background_color) { + ImeTextSpanThickness thickness, + ImeTextSpanUnderlineStyle underline_style, Color text_color, + Color background_color) { document_marker_controller.AddSuggestionMarker( range, SuggestionMarkerProperties::Builder() @@ -1234,6 +1283,8 @@ .SetHighlightColor(suggestion_highlight_color) .SetUnderlineColor(underline_color) .SetThickness(thickness) + .SetUnderlineStyle(underline_style) + .SetTextColor(text_color) .SetBackgroundColor(background_color) .Build()); });
diff --git a/third_party/blink/renderer/core/testing/internals.h b/third_party/blink/renderer/core/testing/internals.h index fe4ccfe..8430aa2f 100644 --- a/third_party/blink/renderer/core/testing/internals.h +++ b/third_party/blink/renderer/core/testing/internals.h
@@ -204,6 +204,8 @@ void addCompositionMarker(const Range*, const String& underline_color_value, const String& thickness_value, + const String& underline_style_value, + const String& text_color_value, const String& background_color_value, ExceptionState&); void addActiveSuggestionMarker(const Range*,
diff --git a/third_party/blink/renderer/core/testing/internals.idl b/third_party/blink/renderer/core/testing/internals.idl index fa12b72a..18e52658 100644 --- a/third_party/blink/renderer/core/testing/internals.idl +++ b/third_party/blink/renderer/core/testing/internals.idl
@@ -114,7 +114,7 @@ [RaisesException] unsigned long markerBackgroundColorForNode(Node node, DOMString markerType, unsigned long index); [RaisesException] unsigned long markerUnderlineColorForNode(Node node, DOMString markerType, unsigned long index); [RaisesException] void addTextMatchMarker(Range range, DOMString matchStatus); - [RaisesException] void addCompositionMarker(Range range, DOMString underlineColorValue, DOMString thicknessValue, DOMString backgroundColorValue); + [RaisesException] void addCompositionMarker(Range range, DOMString underlineColorValue, DOMString thicknessValue, DOMString underlineStyleValue, DOMString textColorValue, DOMString backgroundColorValue); [RaisesException] void addActiveSuggestionMarker(Range range, DOMString underlineColorValue, DOMString thicknessValue, DOMString backgroundColorValue); [RaisesException] void addSuggestionMarker(Range range, sequence<DOMString> suggestions, DOMString suggestionHighlightColorValue, DOMString underlineColorValue, DOMString thicknessValue, DOMString backgroundColorValue); void setTextMatchMarkersActive(Node node, unsigned long startOffset, unsigned long endOffset, boolean active);
diff --git a/third_party/blink/renderer/core/trustedtypes/trusted_types_util_test.cc b/third_party/blink/renderer/core/trustedtypes/trusted_types_util_test.cc index 29619bd4..5bc3ed31 100644 --- a/third_party/blink/renderer/core/trustedtypes/trusted_types_util_test.cc +++ b/third_party/blink/renderer/core/trustedtypes/trusted_types_util_test.cc
@@ -28,8 +28,8 @@ string_or_trusted_type) { auto* document = MakeGarbageCollected<Document>(); document->GetContentSecurityPolicy()->DidReceiveHeader( - "trusted-types *", kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceMeta); + "trusted-types *", network::mojom::ContentSecurityPolicyType::kEnforce, + network::mojom::ContentSecurityPolicySource::kMeta); DummyExceptionStateForTesting exception_state; ASSERT_FALSE(exception_state.HadException()); String s = GetStringFromTrustedType(string_or_trusted_type, document, @@ -44,8 +44,8 @@ auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600)); Document& document = dummy_page_holder->GetDocument(); document.GetContentSecurityPolicy()->DidReceiveHeader( - "trusted-types *", kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceMeta); + "trusted-types *", network::mojom::ContentSecurityPolicyType::kEnforce, + network::mojom::ContentSecurityPolicySource::kMeta); V8TestingScope scope; DummyExceptionStateForTesting exception_state; ASSERT_FALSE(exception_state.HadException()); @@ -61,8 +61,8 @@ auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600)); Document& document = dummy_page_holder->GetDocument(); document.GetContentSecurityPolicy()->DidReceiveHeader( - "trusted-types *", kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceMeta); + "trusted-types *", network::mojom::ContentSecurityPolicyType::kEnforce, + network::mojom::ContentSecurityPolicySource::kMeta); V8TestingScope scope; DummyExceptionStateForTesting exception_state; ASSERT_FALSE(exception_state.HadException()); @@ -78,8 +78,8 @@ auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600)); Document& document = dummy_page_holder->GetDocument(); document.GetContentSecurityPolicy()->DidReceiveHeader( - "trusted-types *", kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceMeta); + "trusted-types *", network::mojom::ContentSecurityPolicyType::kEnforce, + network::mojom::ContentSecurityPolicySource::kMeta); V8TestingScope scope; DummyExceptionStateForTesting exception_state; ASSERT_FALSE(exception_state.HadException()); @@ -97,8 +97,8 @@ String expected) { auto* document = MakeGarbageCollected<Document>(); document->GetContentSecurityPolicy()->DidReceiveHeader( - "trusted-types *", kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceMeta); + "trusted-types *", network::mojom::ContentSecurityPolicyType::kEnforce, + network::mojom::ContentSecurityPolicySource::kMeta); DummyExceptionStateForTesting exception_state; String s = GetStringFromTrustedType(string_or_trusted_type, document, exception_state); @@ -111,8 +111,8 @@ auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600)); Document& document = dummy_page_holder->GetDocument(); document.GetContentSecurityPolicy()->DidReceiveHeader( - "trusted-types *", kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceMeta); + "trusted-types *", network::mojom::ContentSecurityPolicyType::kEnforce, + network::mojom::ContentSecurityPolicySource::kMeta); V8TestingScope scope; DummyExceptionStateForTesting exception_state; String s = GetStringFromTrustedHTML(string_or_trusted_html, &document, @@ -126,8 +126,8 @@ auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600)); Document& document = dummy_page_holder->GetDocument(); document.GetContentSecurityPolicy()->DidReceiveHeader( - "trusted-types *", kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceMeta); + "trusted-types *", network::mojom::ContentSecurityPolicyType::kEnforce, + network::mojom::ContentSecurityPolicySource::kMeta); V8TestingScope scope; DummyExceptionStateForTesting exception_state; String s = GetStringFromTrustedScript(string_or_trusted_script, &document, @@ -141,8 +141,8 @@ auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600)); Document& document = dummy_page_holder->GetDocument(); document.GetContentSecurityPolicy()->DidReceiveHeader( - "trusted-types *", kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceMeta); + "trusted-types *", network::mojom::ContentSecurityPolicyType::kEnforce, + network::mojom::ContentSecurityPolicySource::kMeta); V8TestingScope scope; DummyExceptionStateForTesting exception_state; String s = GetStringFromTrustedScriptURL(string_or_trusted_script_url,
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_test.cc b/third_party/blink/renderer/core/workers/dedicated_worker_test.cc index 9cf493a..d1957bb 100644 --- a/third_party/blink/renderer/core/workers/dedicated_worker_test.cc +++ b/third_party/blink/renderer/core/workers/dedicated_worker_test.cc
@@ -125,7 +125,8 @@ KURL script_url("http://fake.url/"); security_origin_ = SecurityOrigin::Create(script_url); Vector<CSPHeaderAndType> headers{ - {"contentSecurityPolicy", kContentSecurityPolicyHeaderTypeReport}}; + {"contentSecurityPolicy", + network::mojom::ContentSecurityPolicyType::kReport}}; auto worker_settings = std::make_unique<WorkerSettings>( To<Document>(GetExecutionContext())->GetSettings()); InitializeWorkerThread(
diff --git a/third_party/blink/renderer/core/workers/main_thread_worklet_test.cc b/third_party/blink/renderer/core/workers/main_thread_worklet_test.cc index c546f637..0356222 100644 --- a/third_party/blink/renderer/core/workers/main_thread_worklet_test.cc +++ b/third_party/blink/renderer/core/workers/main_thread_worklet_test.cc
@@ -57,8 +57,9 @@ // Set up the CSP for Document before starting MainThreadWorklet because // MainThreadWorklet inherits the owner Document's CSP. auto* csp = MakeGarbageCollected<ContentSecurityPolicy>(); - csp->DidReceiveHeader(csp_header, kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + csp->DidReceiveHeader(csp_header, + network::mojom::ContentSecurityPolicyType::kEnforce, + network::mojom::ContentSecurityPolicySource::kHTTP); document->InitContentSecurityPolicy(csp); reporting_proxy_ = @@ -161,7 +162,7 @@ // At this point check that the CSP that was set is indeed invalid. EXPECT_EQ(1ul, csp->Headers().size()); EXPECT_EQ("invalid-csp", csp->Headers().at(0).first); - EXPECT_EQ(kContentSecurityPolicyHeaderTypeEnforce, + EXPECT_EQ(network::mojom::ContentSecurityPolicyType::kEnforce, csp->Headers().at(0).second); }
diff --git a/third_party/blink/renderer/core/workers/threaded_worklet_test.cc b/third_party/blink/renderer/core/workers/threaded_worklet_test.cc index 9841826a..38dc3a06 100644 --- a/third_party/blink/renderer/core/workers/threaded_worklet_test.cc +++ b/third_party/blink/renderer/core/workers/threaded_worklet_test.cc
@@ -124,7 +124,7 @@ ContentSecurityPolicy* csp = GlobalScope()->GetContentSecurityPolicy(); EXPECT_EQ(1ul, csp->Headers().size()); EXPECT_EQ("invalid-csp", csp->Headers().at(0).first); - EXPECT_EQ(kContentSecurityPolicyHeaderTypeEnforce, + EXPECT_EQ(network::mojom::ContentSecurityPolicyType::kEnforce, csp->Headers().at(0).second); PostCrossThreadTask(*GetParentTaskRunnerForTesting(), FROM_HERE, @@ -277,8 +277,8 @@ // ThreadedWorklet inherits the owner Document's CSP. auto* csp = MakeGarbageCollected<ContentSecurityPolicy>(); csp->DidReceiveHeader("script-src 'self' https://allowed.example.com", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + network::mojom::ContentSecurityPolicyType::kEnforce, + network::mojom::ContentSecurityPolicySource::kHTTP); GetDocument().InitContentSecurityPolicy(csp); MessagingProxy()->Start(); @@ -293,8 +293,9 @@ TEST_F(ThreadedWorkletTest, InvalidContentSecurityPolicy) { auto* csp = MakeGarbageCollected<ContentSecurityPolicy>(); - csp->DidReceiveHeader("invalid-csp", kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + csp->DidReceiveHeader("invalid-csp", + network::mojom::ContentSecurityPolicyType::kEnforce, + network::mojom::ContentSecurityPolicySource::kHTTP); GetDocument().InitContentSecurityPolicy(csp); MessagingProxy()->Start();
diff --git a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc index edf45d8..8aecf58e3 100644 --- a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc +++ b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
@@ -365,7 +365,7 @@ for (const auto& policy_and_type : outside_content_security_policy_headers_) { content_security_policy->DidReceiveHeader( policy_and_type.first, policy_and_type.second, - kContentSecurityPolicyHeaderSourceHTTP); + network::mojom::ContentSecurityPolicySource::kHTTP); } OutsideSettingsCSPDelegate* csp_delegate = @@ -438,7 +438,7 @@ for (const auto& policy_and_type : headers) { GetContentSecurityPolicy()->DidReceiveHeader( policy_and_type.first, policy_and_type.second, - kContentSecurityPolicyHeaderSourceHTTP); + network::mojom::ContentSecurityPolicySource::kHTTP); } }
diff --git a/third_party/blink/renderer/core/workers/worker_thread_test.cc b/third_party/blink/renderer/core/workers/worker_thread_test.cc index 2023f78d..53dee725 100644 --- a/third_party/blink/renderer/core/workers/worker_thread_test.cc +++ b/third_party/blink/renderer/core/workers/worker_thread_test.cc
@@ -381,7 +381,8 @@ EXPECT_CALL(*reporting_proxy_, DidTerminateWorkerThread()).Times(1); Vector<CSPHeaderAndType> headers{ - {"contentSecurityPolicy", kContentSecurityPolicyHeaderTypeReport}}; + {"contentSecurityPolicy", + network::mojom::ContentSecurityPolicyType::kReport}}; auto global_scope_creation_params = std::make_unique<GlobalScopeCreationParams>(
diff --git a/third_party/blink/renderer/core/workers/worker_thread_test_helper.h b/third_party/blink/renderer/core/workers/worker_thread_test_helper.h index 8cd6bf9..a089b222 100644 --- a/third_party/blink/renderer/core/workers/worker_thread_test_helper.h +++ b/third_party/blink/renderer/core/workers/worker_thread_test_helper.h
@@ -121,7 +121,8 @@ const KURL& script_url = KURL("http://fake.url/"), WorkerClients* worker_clients = nullptr) { Vector<CSPHeaderAndType> headers{ - {"contentSecurityPolicy", kContentSecurityPolicyHeaderTypeReport}}; + {"contentSecurityPolicy", + network::mojom::ContentSecurityPolicyType::kReport}}; auto creation_params = std::make_unique<GlobalScopeCreationParams>( script_url, mojom::ScriptType::kClassic, OffMainThreadWorkerScriptFetchOption::kDisabled,
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc index 0a9be50..497c18c 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
@@ -674,7 +674,7 @@ void CanvasRenderingContext2D::FinalizeFrame() { TRACE_EVENT0("blink", "CanvasRenderingContext2D::FinalizeFrame"); - if (canvas() && canvas()->GetCanvas2DLayerBridge()) + if (IsPaintable()) canvas()->GetCanvas2DLayerBridge()->FinalizeFrame(); usage_counters_.num_frames_since_reset++; }
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc index 3b84e7a..9bda0952 100644 --- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc +++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
@@ -348,6 +348,14 @@ compositor_task_runner_, io_task_runner_, web_stream_, std::move(submitter_), surface_layer_mode_, weak_this_); + // We can receive a call to RequestAnimationFrame() before |compositor_| is + // created. In that case, we suspend the request, and wait until now to + // reiniate it. + if (pending_raf_request_) { + RequestAnimationFrame(); + pending_raf_request_ = false; + } + SetNetworkState(WebMediaPlayer::kNetworkStateLoading); SetReadyState(WebMediaPlayer::kReadyStateHaveNothing); std::string stream_id = @@ -731,7 +739,7 @@ WebSize WebMediaPlayerMS::VisibleRect() const { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - scoped_refptr<media::VideoFrame> video_frame = compositor_->GetCurrentFrame(); + scoped_refptr<media::VideoFrame> video_frame = GetCurrentFrame(); if (!video_frame) return WebSize(); @@ -758,6 +766,11 @@ return std::numeric_limits<double>::infinity(); } +scoped_refptr<media::VideoFrame> WebMediaPlayerMS::GetCurrentFrame() const { + return current_frame_override_ ? current_frame_override_ + : compositor_->GetCurrentFrame(); +} + double WebMediaPlayerMS::CurrentTime() const { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); const base::TimeDelta current_time = compositor_->GetCurrentTime(); @@ -812,7 +825,7 @@ DVLOG(3) << __func__; DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - const scoped_refptr<media::VideoFrame> frame = compositor_->GetCurrentFrame(); + const scoped_refptr<media::VideoFrame> frame = GetCurrentFrame(); viz::ContextProvider* provider = nullptr; if (frame && frame->HasTextures()) { @@ -980,7 +993,7 @@ TRACE_EVENT0("media", "copyVideoTextureToPlatformTexture"); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - scoped_refptr<media::VideoFrame> video_frame = compositor_->GetCurrentFrame(); + scoped_refptr<media::VideoFrame> video_frame = GetCurrentFrame(); if (!video_frame.get() || !video_frame->HasTextures()) return false; @@ -1010,7 +1023,7 @@ TRACE_EVENT0("media", "copyVideoYUVDataToPlatformTexture"); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - scoped_refptr<media::VideoFrame> video_frame = compositor_->GetCurrentFrame(); + scoped_refptr<media::VideoFrame> video_frame = GetCurrentFrame(); if (!video_frame) return false; @@ -1043,8 +1056,7 @@ TRACE_EVENT0("media", "texImageImpl"); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - const scoped_refptr<media::VideoFrame> video_frame = - compositor_->GetCurrentFrame(); + const scoped_refptr<media::VideoFrame> video_frame = GetCurrentFrame(); if (!video_frame || !video_frame->IsMappable() || video_frame->HasTextures() || video_frame->format() != media::PIXEL_FORMAT_Y16) { @@ -1217,4 +1229,44 @@ display_type == WebMediaPlayer::DisplayType::kPictureInPicture)); } +void WebMediaPlayerMS::OnNewFramePresentedCallback( + scoped_refptr<media::VideoFrame> presented_frame, + base::TimeTicks presentation_time, + base::TimeTicks expected_presentation_time, + uint32_t presentation_counter) { + if (!main_render_task_runner_->BelongsToCurrentThread()) { + PostCrossThreadTask( + *main_render_task_runner_, FROM_HERE, + CrossThreadBindOnce(&WebMediaPlayerMS::OnNewFramePresentedCallback, + weak_this_, presented_frame, presentation_time, + expected_presentation_time, presentation_counter)); + return; + } + + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + current_frame_override_ = std::move(presented_frame); + client_->OnRequestAnimationFrame( + presentation_time, expected_presentation_time, presentation_counter, + *current_frame_override_); + current_frame_override_.reset(); +} + +void WebMediaPlayerMS::RequestAnimationFrame() { + DCHECK(RuntimeEnabledFeatures::VideoRequestAnimationFrameEnabled()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + if (!compositor_) { + // Reissue the request after |compositor_| is created, in Load(). + pending_raf_request_ = true; + return; + } + + PostCrossThreadTask( + *compositor_task_runner_, FROM_HERE, + CrossThreadBindOnce( + &WebMediaPlayerMSCompositor::SetOnFramePresentedCallback, compositor_, + CrossThreadBindOnce(&WebMediaPlayerMS::OnNewFramePresentedCallback, + weak_this_))); +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc index a3ec79e..dc4900e 100644 --- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc +++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
@@ -506,7 +506,7 @@ return; const base::TimeDelta timestamp = frame->timestamp(); - SetCurrentFrame(std::move(frame)); + SetCurrentFrame(std::move(frame), deadline_min); const auto& end = timestamps_to_clock_times_.end(); const auto& begin = timestamps_to_clock_times_.begin(); @@ -533,14 +533,15 @@ base::AutoLock auto_lock(current_frame_lock_); if (current_frame_) last_render_length_ = frame->timestamp() - current_frame_->timestamp(); - SetCurrentFrame(std::move(frame)); + SetCurrentFrame(std::move(frame), base::nullopt); } if (video_frame_provider_client_) video_frame_provider_client_->DidReceiveFrame(); } void WebMediaPlayerMSCompositor::SetCurrentFrame( - scoped_refptr<media::VideoFrame> frame) { + scoped_refptr<media::VideoFrame> frame, + base::Optional<base::TimeTicks> expected_presentation_time) { DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread()); current_frame_lock_.AssertAcquired(); TRACE_EVENT_INSTANT1("media", "WebMediaPlayerMSCompositor::SetCurrentFrame", @@ -587,19 +588,26 @@ current_frame_ = std::move(frame); + base::TimeTicks now = base::TimeTicks::Now(); + // Complete the checks after |current_frame_| is accessible to avoid // deadlocks, see https://crbug.com/901744. PostCrossThreadTask( *video_frame_compositor_task_runner_, FROM_HERE, CrossThreadBindOnce(&WebMediaPlayerMSCompositor::CheckForFrameChanges, WrapRefCounted(this), is_first_frame, - has_frame_size_changed, std::move(new_rotation), - std::move(new_opacity))); + has_frame_size_changed, now, + expected_presentation_time.value_or(now), + static_cast<int>(total_frame_count_), + std::move(new_rotation), std::move(new_opacity))); } void WebMediaPlayerMSCompositor::CheckForFrameChanges( bool is_first_frame, bool has_frame_size_changed, + base::TimeTicks presentation_time, + base::TimeTicks expected_presentation_time, + int frame_count, base::Optional<media::VideoRotation> new_frame_rotation, base::Optional<bool> new_frame_opacity) { DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread()); @@ -609,8 +617,16 @@ *main_task_runner_, FROM_HERE, CrossThreadBindOnce(&WebMediaPlayerMS::OnFirstFrameReceived, player_, *new_frame_rotation, *new_frame_opacity)); + + // Complete rAF requests before returning. + if (new_frame_presented_cb_) { + std::move(new_frame_presented_cb_) + .Run(current_frame_, presentation_time, expected_presentation_time, + frame_count); + } return; } + if (new_frame_rotation.has_value()) { PostCrossThreadTask( *main_task_runner_, FROM_HERE, @@ -632,6 +648,12 @@ PostCrossThreadTask( *main_task_runner_, FROM_HERE, CrossThreadBindOnce(&WebMediaPlayerMS::ResetCanvasCache, player_)); + + if (new_frame_presented_cb_) { + std::move(new_frame_presented_cb_) + .Run(current_frame_, presentation_time, expected_presentation_time, + frame_count); + } } void WebMediaPlayerMSCompositor::StartRenderingInternal() { @@ -707,4 +729,10 @@ } } +void WebMediaPlayerMSCompositor::SetOnFramePresentedCallback( + OnNewFramePresentedCB presented_cb) { + DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread()); + new_frame_presented_cb_ = std::move(presented_cb); +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h index bdf8ef6..41cebf2 100644 --- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h +++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h
@@ -21,6 +21,7 @@ #include "third_party/blink/public/platform/web_media_player.h" #include "third_party/blink/public/platform/web_video_frame_submitter.h" #include "third_party/blink/renderer/modules/modules_export.h" +#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" #include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h" namespace base { @@ -58,6 +59,12 @@ public WTF::ThreadSafeRefCounted<WebMediaPlayerMSCompositor, WebMediaPlayerMSCompositorTraits> { public: + using OnNewFramePresentedCB = CrossThreadOnceFunction<void( + scoped_refptr<media::VideoFrame> presented_frame, + base::TimeTicks presentation_time, + base::TimeTicks expected_presentation_time, + uint32_t presentation_counter)>; + WebMediaPlayerMSCompositor( scoped_refptr<base::SingleThreadTaskRunner> task_runner, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, @@ -111,6 +118,10 @@ // preparation for dtor. void StopUsingProvider(); + // Sets a hook to be notified when a new frame is presented, to fulfill a + // prending video.requestAnimationFrame() request. + void SetOnFramePresentedCallback(OnNewFramePresentedCB presented_cb); + private: friend class WTF::ThreadSafeRefCounted<WebMediaPlayerMSCompositor, WebMediaPlayerMSCompositorTraits>; @@ -148,12 +159,17 @@ scoped_refptr<media::VideoFrame> frame); // Update |current_frame_| and |dropped_frame_count_| - void SetCurrentFrame(scoped_refptr<media::VideoFrame> frame); + void SetCurrentFrame( + scoped_refptr<media::VideoFrame> frame, + base::Optional<base::TimeTicks> expected_presentation_time); // Following the update to |current_frame_|, this will check for changes that // require updating video layer. void CheckForFrameChanges( bool is_first_frame, bool has_frame_size_changed, + base::TimeTicks presentation_time, + base::TimeTicks expected_presentation_time, + int frame_count, base::Optional<media::VideoRotation> new_frame_rotation, base::Optional<bool> new_frame_opacity); @@ -217,6 +233,11 @@ bool stopped_; bool render_started_; + // Called when a new frame is enqueued, either in RenderWithoutAlgorithm() or + // in RenderUsingAlgorithm(). Used to fulfill video.requestAnimationFrame() + // requests. + OnNewFramePresentedCB new_frame_presented_cb_; + std::unique_ptr<WebVideoFrameSubmitter> submitter_; // TODO(crbug.com/952716): Replace the use of std::map by WTF::HashMap.
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc index 7081a4e..a5efb69 100644 --- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc +++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc
@@ -39,7 +39,9 @@ using ::testing::NiceMock; using ::testing::Return; using ::testing::ReturnRef; +using ::testing::SaveArg; using ::testing::StrictMock; +using ::testing::WithArgs; namespace blink { @@ -591,6 +593,25 @@ void RequestPause() override {} void RequestMuted(bool muted) override {} Features GetFeatures() override { return Features(); } + void OnRequestAnimationFrame( + base::TimeTicks presentation_time, + base::TimeTicks expected_presentation_time, + uint32_t presentation_counter, + const media::VideoFrame& presented_frame) override { + // Check if we should queue another RAF call. + if (chained_raf_call_count_) { + --chained_raf_call_count_; + player_->RequestAnimationFrame(); + } + + // Verify the frame size here because there is no good way of capturing + // a const media::VideoFrame& using mocks. + EXPECT_EQ(presented_frame.visible_rect().height(), kStandardHeight); + EXPECT_EQ(presented_frame.visible_rect().width(), kStandardWidth); + + DoOnRequestAnimationFrame(presentation_time, expected_presentation_time, + presentation_counter, presented_frame); + } // Implementation of cc::VideoFrameProvider::Client void StopUsingProvider() override; @@ -627,6 +648,12 @@ MOCK_CONST_METHOD0(DisplayType, WebMediaPlayer::DisplayType()); MOCK_CONST_METHOD0(CouldPlayIfEnoughData, bool()); + MOCK_METHOD4(DoOnRequestAnimationFrame, + void(base::TimeTicks, + base::TimeTicks, + uint32_t, + const media::VideoFrame&)); + std::unique_ptr<WebSurfaceLayerBridge> CreateMockSurfaceLayerBridge( WebSurfaceLayerBridgeObserver*, cc::UpdateSubmissionStateCB) { @@ -647,6 +674,7 @@ NiceMock<MockSurfaceLayerBridge>* surface_layer_bridge_ptr_ = nullptr; NiceMock<MockWebVideoFrameSubmitter>* submitter_ptr_ = nullptr; bool enable_surface_layer_for_video_ = false; + int chained_raf_call_count_ = 0; private: // Main function trying to ask WebMediaPlayerMS to submit a frame for @@ -1364,6 +1392,63 @@ } #endif +TEST_P(WebMediaPlayerMSTest, RequestAnimationFrame) { + InitializeWebMediaPlayerMS(); + + MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(true); + + const int kTestBrake = static_cast<int>(FrameType::TEST_BRAKE); + int tokens[] = {0, 33, kTestBrake, 66, 100, 133, 166, + kTestBrake, 200, 233, 266, 300, 333}; + std::vector<int> timestamps(tokens, tokens + sizeof(tokens) / sizeof(int)); + provider->QueueFrames(timestamps); + + base::TimeTicks presentation_time; + base::TimeTicks expected_presentation_time; + + // Verify a basic call to RAF. + player_->RequestAnimationFrame(); + EXPECT_CALL(*this, DoOnRequestAnimationFrame(_, _, _, _)) + .Times(1) + .WillOnce(DoAll(SaveArg<0>(&presentation_time), + SaveArg<1>(&expected_presentation_time))); + message_loop_controller_.RunAndWaitForStatus( + media::PipelineStatus::PIPELINE_OK); + + EXPECT_GT(presentation_time, base::TimeTicks()); + EXPECT_GE(expected_presentation_time, presentation_time); + testing::Mock::VerifyAndClearExpectations(this); + + // Make sure multiple calls to RAF only result in one call per frame to OnRAF. + player_->RequestAnimationFrame(); + player_->RequestAnimationFrame(); + player_->RequestAnimationFrame(); + + EXPECT_CALL(*this, DoOnRequestAnimationFrame(_, _, _, _)).Times(1); + message_loop_controller_.RunAndWaitForStatus( + media::PipelineStatus::PIPELINE_OK); + testing::Mock::VerifyAndClearExpectations(this); + + // Make sure we can chain calls to RAF. + player_->RequestAnimationFrame(); + chained_raf_call_count_ = 3; + + // Verify that the presentation frame counter is monotonically increasing. + // NOTE: 0 is fine here as a starting value, since the counter should already + // be >0, because of the calls above. + uint32_t last_frame_counter = 0; + EXPECT_CALL(*this, DoOnRequestAnimationFrame(_, _, _, _)) + .Times(chained_raf_call_count_ + 1) + .WillRepeatedly(WithArgs<2>([&](uint32_t frame_counter) { + EXPECT_GT(frame_counter, last_frame_counter); + last_frame_counter = frame_counter; + })); + + message_loop_controller_.RunAndWaitForStatus( + media::PipelineStatus::PIPELINE_OK); + testing::Mock::VerifyAndClearExpectations(this); +} + INSTANTIATE_TEST_SUITE_P(All, WebMediaPlayerMSTest, ::testing::Combine(::testing::Bool(),
diff --git a/third_party/blink/renderer/modules/modules_idl_files.gni b/third_party/blink/renderer/modules/modules_idl_files.gni index f2dfeeb..4853457 100644 --- a/third_party/blink/renderer/modules/modules_idl_files.gni +++ b/third_party/blink/renderer/modules/modules_idl_files.gni
@@ -514,12 +514,16 @@ "xr/xr_anchor_set.idl", "xr/xr_bounded_reference_space.idl", "xr/xr_dom_overlay_state.idl", + "xr/xr_cube_map.idl", "xr/xr_frame.idl", "xr/xr_hit_result.idl", "xr/xr_input_source.idl", "xr/xr_input_source_array.idl", "xr/xr_input_source_event.idl", "xr/xr_input_sources_change_event.idl", + "xr/xr_light_estimation.idl", + "xr/xr_light_estimation_state.idl", + "xr/xr_light_probe.idl", "xr/xr_plane.idl", "xr/xr_plane_detection_state.idl", "xr/xr_plane_set.idl", @@ -527,6 +531,7 @@ "xr/xr_ray.idl", "xr/xr_reference_space.idl", "xr/xr_reference_space_event.idl", + "xr/xr_reflection_probe.idl", "xr/xr_render_state.idl", "xr/xr_rigid_transform.idl", "xr/xr_hit_test_result.idl", @@ -534,6 +539,7 @@ "xr/xr_session.idl", "xr/xr_session_event.idl", "xr/xr_space.idl", + "xr/xr_spherical_harmonics.idl", "xr/xr_transient_input_hit_test_result.idl", "xr/xr_transient_input_hit_test_source.idl", "xr/xr_view.idl", @@ -897,6 +903,7 @@ "xr/xr_hit_test_options_init.idl", "xr/xr_input_source_event_init.idl", "xr/xr_input_sources_change_event_init.idl", + "xr/xr_light_estimation_state_init.idl", "xr/xr_plane_detection_state_init.idl", "xr/xr_reference_space_event_init.idl", "xr/xr_render_state_init.idl",
diff --git a/third_party/blink/renderer/modules/nfc/ndef_record.cc b/third_party/blink/renderer/modules/nfc/ndef_record.cc index c31edf40..679d85b 100644 --- a/third_party/blink/renderer/modules/nfc/ndef_record.cc +++ b/third_party/blink/renderer/modules/nfc/ndef_record.cc
@@ -151,21 +151,26 @@ return nullptr; } - String encoding_label = !encoding.IsEmpty() ? encoding : "utf-8"; - if (encoding_label != "utf-8" && encoding_label != "utf-16" && - encoding_label != "utf-16be" && encoding_label != "utf-16le") { - exception_state.ThrowTypeError( - "Encoding must be either \"utf-8\", \"utf-16\", \"utf-16be\", or " - "\"utf-16le\"."); - return nullptr; - } - + String encoding_label = encoding.IsNull() ? "utf-8" : encoding; WTF::Vector<uint8_t> bytes; if (data.IsString()) { + if (encoding_label != "utf-8") { + exception_state.ThrowTypeError( + "A DOMString data source is always encoded as \"utf-8\" so other " + "encodings are not allowed."); + return nullptr; + } StringUTF8Adaptor utf8_string(data.GetAsString()); bytes.Append(utf8_string.data(), utf8_string.size()); } else { DCHECK(IsBufferSource(data)); + if (encoding_label != "utf-8" && encoding_label != "utf-16" && + encoding_label != "utf-16be" && encoding_label != "utf-16le") { + exception_state.ThrowTypeError( + "Encoding must be either \"utf-8\", \"utf-16\", \"utf-16be\", or " + "\"utf-16le\"."); + return nullptr; + } if (!GetBytesOfBufferSource(data, &bytes, exception_state)) { return nullptr; }
diff --git a/third_party/blink/renderer/modules/webtransport/quic_transport.cc b/third_party/blink/renderer/modules/webtransport/quic_transport.cc index 9ccb969..5e3665a2 100644 --- a/third_party/blink/renderer/modules/webtransport/quic_transport.cc +++ b/third_party/blink/renderer/modules/webtransport/quic_transport.cc
@@ -177,6 +177,12 @@ Dispose(); } +void QuicTransport::OnDatagramReceived(base::span<const uint8_t> data) { + DVLOG(1) << "QuicTransport::OnDatagramReceived(size: " << data.size() + << ") this =" << this; + // TODO(ricea): Implement this. +} + void QuicTransport::OnIncomingStreamClosed(uint32_t stream_id, bool fin_received) { DVLOG(1) << "QuicTransport::OnIncomingStreamClosed(" << stream_id << ", "
diff --git a/third_party/blink/renderer/modules/webtransport/quic_transport.h b/third_party/blink/renderer/modules/webtransport/quic_transport.h index 65fbb5f..cef9a9b 100644 --- a/third_party/blink/renderer/modules/webtransport/quic_transport.h +++ b/third_party/blink/renderer/modules/webtransport/quic_transport.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBTRANSPORT_QUIC_TRANSPORT_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBTRANSPORT_QUIC_TRANSPORT_H_ +#include "base/containers/span.h" #include "base/util/type_safety/pass_key.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" @@ -60,6 +61,7 @@ void OnHandshakeFailed() override; // QuicTransportClient implementation + void OnDatagramReceived(base::span<const uint8_t> data) override; void OnIncomingStreamClosed(uint32_t stream_id, bool fin_received) override; // Implementation of ContextLifecycleObserver
diff --git a/third_party/blink/renderer/modules/webtransport/quic_transport_test.cc b/third_party/blink/renderer/modules/webtransport/quic_transport_test.cc index 96b45e9..7213a5a 100644 --- a/third_party/blink/renderer/modules/webtransport/quic_transport_test.cc +++ b/third_party/blink/renderer/modules/webtransport/quic_transport_test.cc
@@ -266,8 +266,8 @@ scope.GetExecutionContext() ->GetContentSecurityPolicyForWorld() ->DidReceiveHeader("connect-src 'none'", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + network::mojom::ContentSecurityPolicyType::kEnforce, + network::mojom::ContentSecurityPolicySource::kHTTP); QuicTransport::Create(scope.GetScriptState(), String("quic-transport://example.com/"), exception_state); @@ -287,8 +287,8 @@ scope.GetExecutionContext() ->GetContentSecurityPolicyForWorld() ->DidReceiveHeader("connect-src quic-transport://example.com", - kContentSecurityPolicyHeaderTypeEnforce, - kContentSecurityPolicyHeaderSourceHTTP); + network::mojom::ContentSecurityPolicyType::kEnforce, + network::mojom::ContentSecurityPolicySource::kHTTP); QuicTransport::Create(scope.GetScriptState(), String("quic-transport://example.com/"), exception_state);
diff --git a/third_party/blink/renderer/modules/xr/BUILD.gn b/third_party/blink/renderer/modules/xr/BUILD.gn index 74a8d76..8f58b52 100644 --- a/third_party/blink/renderer/modules/xr/BUILD.gn +++ b/third_party/blink/renderer/modules/xr/BUILD.gn
@@ -21,6 +21,8 @@ "xr_bounded_reference_space.h", "xr_canvas_input_provider.cc", "xr_canvas_input_provider.h", + "xr_cube_map.cc", + "xr_cube_map.h", "xr_dom_overlay_state.cc", "xr_dom_overlay_state.h", "xr_frame.cc", @@ -45,6 +47,12 @@ "xr_input_source_event.h", "xr_input_sources_change_event.cc", "xr_input_sources_change_event.h", + "xr_light_estimation.cc", + "xr_light_estimation.h", + "xr_light_estimation_state.cc", + "xr_light_estimation_state.h", + "xr_light_probe.cc", + "xr_light_probe.h", "xr_native_origin_information.cc", "xr_native_origin_information.h", "xr_object_space.h", @@ -62,6 +70,8 @@ "xr_reference_space.h", "xr_reference_space_event.cc", "xr_reference_space_event.h", + "xr_reflection_probe.cc", + "xr_reflection_probe.h", "xr_render_state.cc", "xr_render_state.h", "xr_rigid_transform.cc", @@ -73,6 +83,8 @@ "xr_setlike.h", "xr_space.cc", "xr_space.h", + "xr_spherical_harmonics.cc", + "xr_spherical_harmonics.h", "xr_target_ray_space.cc", "xr_target_ray_space.h", "xr_transient_input_hit_test_result.cc",
diff --git a/third_party/blink/renderer/modules/xr/xr_cube_map.cc b/third_party/blink/renderer/modules/xr/xr_cube_map.cc new file mode 100644 index 0000000..b2973a0 --- /dev/null +++ b/third_party/blink/renderer/modules/xr/xr_cube_map.cc
@@ -0,0 +1,105 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/xr/xr_cube_map.h" + +#include "device/vr/public/mojom/vr_service.mojom-blink.h" +#include "third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h" +#include "third_party/blink/renderer/modules/webgl/webgl_texture.h" +#include "third_party/blink/renderer/modules/xr/xr_cube_map.h" +#include "third_party/blink/renderer/platform/bindings/exception_code.h" + +namespace { +bool IsPowerOfTwo(uint32_t value) { + return value && (value & (value - 1)) == 0; +} + +static constexpr char const* kErrorNonCubemapTexture = + "Cannot pass non-cubemap texture"; +static constexpr char const* kErrorContextMismatch = "Context mismatch"; + +} // namespace + +namespace blink { + +XRCubeMap::XRCubeMap(const device::mojom::blink::XRCubeMap& cube_map) { + constexpr auto kNumComponentsPerPixel = + device::mojom::blink::XRCubeMap::kNumComponentsPerPixel; + static_assert(kNumComponentsPerPixel == 4, + "XRCubeMaps are expected to be in the RGBA16F format"); + + // Cube map sides must all be a power-of-two image + bool valid = IsPowerOfTwo(cube_map.width_and_height); + const size_t expected_size = + cube_map.width_and_height * cube_map.width_and_height; + valid &= cube_map.positive_x.size() == expected_size; + valid &= cube_map.negative_x.size() == expected_size; + valid &= cube_map.positive_y.size() == expected_size; + valid &= cube_map.negative_y.size() == expected_size; + valid &= cube_map.positive_z.size() == expected_size; + valid &= cube_map.negative_z.size() == expected_size; + DCHECK(valid); + + width_and_height_ = cube_map.width_and_height; + positive_x_ = cube_map.positive_x; + negative_x_ = cube_map.negative_x; + positive_y_ = cube_map.positive_y; + negative_y_ = cube_map.negative_y; + positive_z_ = cube_map.positive_z; + negative_z_ = cube_map.negative_z; +} + +WebGLTexture* XRCubeMap::updateWebGLEnvironmentCube( + WebGL2RenderingContextBase* context, + WebGLTexture* texture, + ExceptionState& exception_state) const { + // If they haven't supplied us with a texture, Create a new one. + if (!texture) { + texture = MakeGarbageCollected<WebGLTexture>(context); + } else if (texture->HasEverBeenBound() && + texture->GetTarget() != GL_TEXTURE_CUBE_MAP) { + exception_state.ThrowTypeError(kErrorNonCubemapTexture); + return nullptr; + } else if (texture->ContextGroup() != context->ContextGroup()) { + exception_state.ThrowTypeError(kErrorContextMismatch); + return nullptr; + } + + auto* gl = context->ContextGL(); + texture->SetTarget(GL_TEXTURE_CUBE_MAP); + gl->BindTexture(GL_TEXTURE_CUBE_MAP, texture->Object()); + + // Cannot generate mip-maps for half-float textures, so use linear filtering + gl->TexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + gl->TexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + uint16_t const* const cubemap_images[] = { + positive_x_.data()->components, negative_x_.data()->components, + positive_y_.data()->components, negative_y_.data()->components, + positive_z_.data()->components, negative_z_.data()->components, + }; + GLenum const cubemap_targets[] = { + GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, + }; + + // Update image for each side of the cube map + for (int i = 0; i < 6; ++i) { + auto* image = cubemap_images[i]; + auto target = cubemap_targets[i]; + + gl->TexImage2D(target, 0, GL_RGBA16F, width_and_height_, width_and_height_, + 0, GL_RGBA, GL_HALF_FLOAT, image); + } + + gl->BindTexture(GL_TEXTURE_CUBE_MAP, 0); + + // Debug check for success + DCHECK(gl->GetError() == GL_NO_ERROR); + + return texture; +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/xr/xr_cube_map.h b/third_party/blink/renderer/modules/xr/xr_cube_map.h new file mode 100644 index 0000000..7824132 --- /dev/null +++ b/third_party/blink/renderer/modules/xr/xr_cube_map.h
@@ -0,0 +1,42 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_CUBE_MAP_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_CUBE_MAP_H_ + +#include "base/util/type_safety/pass_key.h" +#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h" +#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h" +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" + +namespace blink { + +class WebGL2RenderingContextBase; +class WebGLTexture; +class ExceptionState; + +class XRCubeMap : public ScriptWrappable { + DEFINE_WRAPPERTYPEINFO(); + + public: + explicit XRCubeMap(const device::mojom::blink::XRCubeMap& cube_map); + + WebGLTexture* updateWebGLEnvironmentCube( + WebGL2RenderingContextBase* context, + WebGLTexture* texture, + ExceptionState& exception_state) const; + + private: + uint32_t width_and_height_ = 0; + WTF::Vector<device::RgbaTupleF16> positive_x_; + WTF::Vector<device::RgbaTupleF16> negative_x_; + WTF::Vector<device::RgbaTupleF16> positive_y_; + WTF::Vector<device::RgbaTupleF16> negative_y_; + WTF::Vector<device::RgbaTupleF16> positive_z_; + WTF::Vector<device::RgbaTupleF16> negative_z_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_CUBE_MAP_H_
diff --git a/third_party/blink/renderer/modules/xr/xr_cube_map.idl b/third_party/blink/renderer/modules/xr/xr_cube_map.idl new file mode 100644 index 0000000..fd68d98 --- /dev/null +++ b/third_party/blink/renderer/modules/xr/xr_cube_map.idl
@@ -0,0 +1,14 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[ + SecureContext, + Exposed=Window, + RuntimeEnabled=WebXRIncubations +] +interface XRCubeMap { + [RaisesException] + WebGLTexture updateWebGLEnvironmentCube(WebGL2RenderingContext context, WebGLTexture? texture); +}; +
diff --git a/third_party/blink/renderer/modules/xr/xr_frame_provider.cc b/third_party/blink/renderer/modules/xr/xr_frame_provider.cc index 6b562aab..18924c3 100644 --- a/third_party/blink/renderer/modules/xr/xr_frame_provider.cc +++ b/third_party/blink/renderer/modules/xr/xr_frame_provider.cc
@@ -14,6 +14,7 @@ #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h" #include "third_party/blink/renderer/core/loader/document_loader.h" #include "third_party/blink/renderer/modules/xr/xr.h" +#include "third_party/blink/renderer/modules/xr/xr_light_estimation_state.h" #include "third_party/blink/renderer/modules/xr/xr_plane_detection_state.h" #include "third_party/blink/renderer/modules/xr/xr_session.h" #include "third_party/blink/renderer/modules/xr/xr_viewport.h" @@ -161,7 +162,8 @@ DCHECK(session); auto options = device::mojom::blink::XRFrameDataRequestOptions::New( - session->worldTrackingState()->planeDetectionState()->enabled()); + session->worldTrackingState()->planeDetectionState()->enabled(), + session->worldTrackingState()->lightEstimationState()->enabled()); // Immersive frame logic. if (session->immersive()) { @@ -350,7 +352,8 @@ } else { auto& data_provider = provider->value; auto options = device::mojom::blink::XRFrameDataRequestOptions::New( - session->worldTrackingState()->planeDetectionState()->enabled()); + session->worldTrackingState()->planeDetectionState()->enabled(), + session->worldTrackingState()->lightEstimationState()->enabled()); data_provider->GetFrameData( std::move(options),
diff --git a/third_party/blink/renderer/modules/xr/xr_light_estimation.cc b/third_party/blink/renderer/modules/xr/xr_light_estimation.cc new file mode 100644 index 0000000..cb4c72b --- /dev/null +++ b/third_party/blink/renderer/modules/xr/xr_light_estimation.cc
@@ -0,0 +1,38 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/xr/xr_light_estimation.h" + +#include "device/vr/public/mojom/vr_service.mojom-blink.h" +#include "third_party/blink/renderer/modules/xr/xr_light_probe.h" +#include "third_party/blink/renderer/modules/xr/xr_reflection_probe.h" + +namespace blink { + +XRLightEstimation::XRLightEstimation( + const device::mojom::blink::XRLightEstimationData& data) { + if (data.light_probe) { + light_probe_ = MakeGarbageCollected<XRLightProbe>(*data.light_probe); + } + if (data.reflection_probe) { + reflection_probe_ = + MakeGarbageCollected<XRReflectionProbe>(*data.reflection_probe); + } +} + +XRLightProbe* XRLightEstimation::lightProbe() const { + return light_probe_.Get(); +} + +XRReflectionProbe* XRLightEstimation::reflectionProbe() const { + return reflection_probe_.Get(); +} + +void XRLightEstimation::Trace(Visitor* visitor) { + visitor->Trace(light_probe_); + visitor->Trace(reflection_probe_); + ScriptWrappable::Trace(visitor); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/xr/xr_light_estimation.h b/third_party/blink/renderer/modules/xr/xr_light_estimation.h new file mode 100644 index 0000000..d4d78ab6 --- /dev/null +++ b/third_party/blink/renderer/modules/xr/xr_light_estimation.h
@@ -0,0 +1,35 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_LIGHT_ESTIMATION_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_LIGHT_ESTIMATION_H_ + +#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h" +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" + +namespace blink { + +class XRLightProbe; +class XRReflectionProbe; + +class XRLightEstimation : public ScriptWrappable { + DEFINE_WRAPPERTYPEINFO(); + + public: + explicit XRLightEstimation( + const device::mojom::blink::XRLightEstimationData& data); + + XRLightProbe* lightProbe() const; + XRReflectionProbe* reflectionProbe() const; + + void Trace(Visitor* visitor) override; + + private: + Member<XRLightProbe> light_probe_; + Member<XRReflectionProbe> reflection_probe_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_LIGHT_ESTIMATION_H_
diff --git a/third_party/blink/renderer/modules/xr/xr_light_estimation.idl b/third_party/blink/renderer/modules/xr/xr_light_estimation.idl new file mode 100644 index 0000000..fdc12a6 --- /dev/null +++ b/third_party/blink/renderer/modules/xr/xr_light_estimation.idl
@@ -0,0 +1,14 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[ + SecureContext, + Exposed=Window, + RuntimeEnabled=WebXRIncubations +] +interface XRLightEstimation { + readonly attribute XRLightProbe? lightProbe; + readonly attribute XRReflectionProbe? reflectionProbe; +}; +
diff --git a/third_party/blink/renderer/modules/xr/xr_light_estimation_state.cc b/third_party/blink/renderer/modules/xr/xr_light_estimation_state.cc new file mode 100644 index 0000000..2b2b0b3 --- /dev/null +++ b/third_party/blink/renderer/modules/xr/xr_light_estimation_state.cc
@@ -0,0 +1,20 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/xr/xr_light_estimation_state.h" + +#include "third_party/blink/renderer/modules/xr/xr_light_estimation_state_init.h" + +namespace blink { + +XRLightEstimationState::XRLightEstimationState( + XRLightEstimationStateInit* light_estimation_state_init) { + if (light_estimation_state_init) { + if (light_estimation_state_init->hasEnabled()) { + enabled_ = light_estimation_state_init->enabled(); + } + } +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/xr/xr_light_estimation_state.h b/third_party/blink/renderer/modules/xr/xr_light_estimation_state.h new file mode 100644 index 0000000..c1ab430 --- /dev/null +++ b/third_party/blink/renderer/modules/xr/xr_light_estimation_state.h
@@ -0,0 +1,29 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_LIGHT_ESTIMATION_STATE_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_LIGHT_ESTIMATION_STATE_H_ + +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" + +namespace blink { + +class XRLightEstimationStateInit; + +class XRLightEstimationState : public ScriptWrappable { + DEFINE_WRAPPERTYPEINFO(); + + public: + explicit XRLightEstimationState( + XRLightEstimationStateInit* light_estimation_state_init); + + bool enabled() const { return enabled_; } + + private: + bool enabled_ = false; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_LIGHT_ESTIMATION_STATE_H_
diff --git a/third_party/blink/renderer/modules/xr/xr_light_estimation_state.idl b/third_party/blink/renderer/modules/xr/xr_light_estimation_state.idl new file mode 100644 index 0000000..305f741b --- /dev/null +++ b/third_party/blink/renderer/modules/xr/xr_light_estimation_state.idl
@@ -0,0 +1,13 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[ + SecureContext, + Exposed=Window, + RuntimeEnabled=WebXRIncubations +] +interface XRLightEstimationState { + readonly attribute boolean enabled; +}; +
diff --git a/third_party/blink/renderer/modules/xr/xr_light_estimation_state_init.idl b/third_party/blink/renderer/modules/xr/xr_light_estimation_state_init.idl new file mode 100644 index 0000000..379f6d9 --- /dev/null +++ b/third_party/blink/renderer/modules/xr/xr_light_estimation_state_init.idl
@@ -0,0 +1,7 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +dictionary XRLightEstimationStateInit { + boolean enabled; +};
diff --git a/third_party/blink/renderer/modules/xr/xr_light_probe.cc b/third_party/blink/renderer/modules/xr/xr_light_probe.cc new file mode 100644 index 0000000..46de95dc --- /dev/null +++ b/third_party/blink/renderer/modules/xr/xr_light_probe.cc
@@ -0,0 +1,47 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/xr/xr_light_probe.h" + +#include "device/vr/public/mojom/vr_service.mojom-blink.h" +#include "third_party/blink/renderer/core/geometry/dom_point_read_only.h" +#include "third_party/blink/renderer/modules/xr/xr_spherical_harmonics.h" + +namespace blink { + +XRLightProbe::XRLightProbe( + const device::mojom::blink::XRLightProbe& light_probe) { + spherical_harmonics_ = MakeGarbageCollected<XRSphericalHarmonics>( + *light_probe.spherical_harmonics); + + main_light_direction_ = + DOMPointReadOnly::Create(light_probe.main_light_direction.x(), + light_probe.main_light_direction.y(), + light_probe.main_light_direction.z(), 0); + main_light_intensity_ = + DOMPointReadOnly::Create(light_probe.main_light_intensity.red(), + light_probe.main_light_intensity.green(), + light_probe.main_light_intensity.blue(), 1); +} + +XRSphericalHarmonics* XRLightProbe::sphericalHarmonics() const { + return spherical_harmonics_.Get(); +} + +DOMPointReadOnly* XRLightProbe::mainLightDirection() const { + return main_light_direction_.Get(); +} + +DOMPointReadOnly* XRLightProbe::mainLightIntensity() const { + return main_light_intensity_.Get(); +} + +void XRLightProbe::Trace(Visitor* visitor) { + visitor->Trace(spherical_harmonics_); + visitor->Trace(main_light_direction_); + visitor->Trace(main_light_intensity_); + ScriptWrappable::Trace(visitor); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/xr/xr_light_probe.h b/third_party/blink/renderer/modules/xr/xr_light_probe.h new file mode 100644 index 0000000..06912d2 --- /dev/null +++ b/third_party/blink/renderer/modules/xr/xr_light_probe.h
@@ -0,0 +1,36 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_LIGHT_PROBE_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_LIGHT_PROBE_H_ + +#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h" +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" + +namespace blink { + +class XRSphericalHarmonics; +class DOMPointReadOnly; + +class XRLightProbe : public ScriptWrappable { + DEFINE_WRAPPERTYPEINFO(); + + public: + explicit XRLightProbe(const device::mojom::blink::XRLightProbe& light_probe); + + XRSphericalHarmonics* sphericalHarmonics() const; + DOMPointReadOnly* mainLightDirection() const; + DOMPointReadOnly* mainLightIntensity() const; + + void Trace(Visitor* visitor) override; + + private: + Member<XRSphericalHarmonics> spherical_harmonics_; + Member<DOMPointReadOnly> main_light_direction_; + Member<DOMPointReadOnly> main_light_intensity_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_LIGHT_PROBE_H_
diff --git a/third_party/blink/renderer/modules/xr/xr_light_probe.idl b/third_party/blink/renderer/modules/xr/xr_light_probe.idl new file mode 100644 index 0000000..691c4c66 --- /dev/null +++ b/third_party/blink/renderer/modules/xr/xr_light_probe.idl
@@ -0,0 +1,15 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[ + SecureContext, + Exposed=Window, + RuntimeEnabled=WebXRIncubations +] +interface XRLightProbe { + readonly attribute XRSphericalHarmonics sphericalHarmonics; + readonly attribute DOMPointReadOnly mainLightDirection; + readonly attribute DOMPointReadOnly mainLightIntensity; +}; +
diff --git a/third_party/blink/renderer/modules/xr/xr_plane_detection_state.h b/third_party/blink/renderer/modules/xr/xr_plane_detection_state.h index ff33f51d..22499d76 100644 --- a/third_party/blink/renderer/modules/xr/xr_plane_detection_state.h +++ b/third_party/blink/renderer/modules/xr/xr_plane_detection_state.h
@@ -17,8 +17,8 @@ DEFINE_WRAPPERTYPEINFO(); public: - XRPlaneDetectionState( - XRPlaneDetectionStateInit* plane_detection_state_init = nullptr); + explicit XRPlaneDetectionState( + XRPlaneDetectionStateInit* plane_detection_state_init); bool enabled() const { return enabled_; }
diff --git a/third_party/blink/renderer/modules/xr/xr_reflection_probe.cc b/third_party/blink/renderer/modules/xr/xr_reflection_probe.cc new file mode 100644 index 0000000..81b55d81 --- /dev/null +++ b/third_party/blink/renderer/modules/xr/xr_reflection_probe.cc
@@ -0,0 +1,26 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/xr/xr_reflection_probe.h" + +#include "device/vr/public/mojom/vr_service.mojom-blink.h" +#include "third_party/blink/renderer/modules/xr/xr_cube_map.h" + +namespace blink { + +XRReflectionProbe::XRReflectionProbe( + const device::mojom::blink::XRReflectionProbe& reflection_probe) { + cube_map_ = MakeGarbageCollected<XRCubeMap>(*reflection_probe.cube_map); +} + +XRCubeMap* XRReflectionProbe::cubeMap() const { + return cube_map_.Get(); +} + +void XRReflectionProbe::Trace(Visitor* visitor) { + visitor->Trace(cube_map_); + ScriptWrappable::Trace(visitor); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/xr/xr_reflection_probe.h b/third_party/blink/renderer/modules/xr/xr_reflection_probe.h new file mode 100644 index 0000000..4264caf --- /dev/null +++ b/third_party/blink/renderer/modules/xr/xr_reflection_probe.h
@@ -0,0 +1,33 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_REFLECTION_PROBE_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_REFLECTION_PROBE_H_ + +#include "base/util/type_safety/pass_key.h" +#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h" +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" + +namespace blink { + +class XRCubeMap; + +class XRReflectionProbe : public ScriptWrappable { + DEFINE_WRAPPERTYPEINFO(); + + public: + explicit XRReflectionProbe( + const device::mojom::blink::XRReflectionProbe& reflection_probe); + + XRCubeMap* cubeMap() const; + + void Trace(Visitor* visitor) override; + + private: + Member<XRCubeMap> cube_map_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_REFLECTION_PROBE_H_
diff --git a/third_party/blink/renderer/modules/xr/xr_reflection_probe.idl b/third_party/blink/renderer/modules/xr/xr_reflection_probe.idl new file mode 100644 index 0000000..8d0275a --- /dev/null +++ b/third_party/blink/renderer/modules/xr/xr_reflection_probe.idl
@@ -0,0 +1,13 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[ + SecureContext, + Exposed=Window, + RuntimeEnabled=WebXRIncubations +] +interface XRReflectionProbe { + readonly attribute XRCubeMap cubeMap; +}; +
diff --git a/third_party/blink/renderer/modules/xr/xr_session.cc b/third_party/blink/renderer/modules/xr/xr_session.cc index cf0aa892..b4f3ecf2 100644 --- a/third_party/blink/renderer/modules/xr/xr_session.cc +++ b/third_party/blink/renderer/modules/xr/xr_session.cc
@@ -1455,10 +1455,13 @@ frame_data->detected_planes_data.get(), timestamp); ProcessAnchorsData(frame_data->anchors_data.get(), timestamp); ProcessHitTestData(frame_data->hit_test_subscription_results.get()); + world_information_->ProcessLightEstimationData( + frame_data->light_estimation_data.get(), timestamp); } else { world_information_->ProcessPlaneInformation(nullptr, timestamp); ProcessAnchorsData(nullptr, timestamp); ProcessHitTestData(nullptr); + world_information_->ProcessLightEstimationData(nullptr, timestamp); } }
diff --git a/third_party/blink/renderer/modules/xr/xr_spherical_harmonics.cc b/third_party/blink/renderer/modules/xr/xr_spherical_harmonics.cc new file mode 100644 index 0000000..7d5ec46 --- /dev/null +++ b/third_party/blink/renderer/modules/xr/xr_spherical_harmonics.cc
@@ -0,0 +1,38 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/xr/xr_spherical_harmonics.h" + +#include "device/vr/public/mojom/vr_service.mojom-blink.h" +#include "third_party/blink/renderer/core/geometry/dom_point_read_only.h" + +namespace blink { + +XRSphericalHarmonics::XRSphericalHarmonics( + const device::mojom::blink::XRSphericalHarmonics& spherical_harmonics) { + DCHECK_EQ(spherical_harmonics.coefficients.size(), 9u); + + coefficients_ = DOMFloat32Array::Create( + spherical_harmonics.coefficients.data()->components, + spherical_harmonics.coefficients.size() * + device::RgbTupleF32::kNumComponents); + + orientation_ = DOMPointReadOnly::Create(0, 0, 0, 1); +} + +DOMPointReadOnly* XRSphericalHarmonics::orientation() const { + return orientation_.Get(); +} + +DOMFloat32Array* XRSphericalHarmonics::coefficients() const { + return coefficients_.Get(); +} + +void XRSphericalHarmonics::Trace(Visitor* visitor) { + visitor->Trace(coefficients_); + visitor->Trace(orientation_); + ScriptWrappable::Trace(visitor); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/xr/xr_spherical_harmonics.h b/third_party/blink/renderer/modules/xr/xr_spherical_harmonics.h new file mode 100644 index 0000000..de7378ff --- /dev/null +++ b/third_party/blink/renderer/modules/xr/xr_spherical_harmonics.h
@@ -0,0 +1,35 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_SPHERICAL_HARMONICS_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_SPHERICAL_HARMONICS_H_ + +#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h" +#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h" +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" + +namespace blink { + +class DOMPointReadOnly; + +class XRSphericalHarmonics : public ScriptWrappable { + DEFINE_WRAPPERTYPEINFO(); + + public: + XRSphericalHarmonics( + const device::mojom::blink::XRSphericalHarmonics& spherical_harmonics); + + DOMPointReadOnly* orientation() const; + DOMFloat32Array* coefficients() const; + + void Trace(Visitor* visitor) override; + + private: + Member<DOMFloat32Array> coefficients_; + Member<DOMPointReadOnly> orientation_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_SPHERICAL_HARMONICS_H_
diff --git a/third_party/blink/renderer/modules/xr/xr_spherical_harmonics.idl b/third_party/blink/renderer/modules/xr/xr_spherical_harmonics.idl new file mode 100644 index 0000000..720ea98 --- /dev/null +++ b/third_party/blink/renderer/modules/xr/xr_spherical_harmonics.idl
@@ -0,0 +1,14 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[ + SecureContext, + Exposed=Window, + RuntimeEnabled=WebXRIncubations +] +interface XRSphericalHarmonics { + readonly attribute DOMPointReadOnly orientation; + readonly attribute Float32Array coefficients; +}; +
diff --git a/third_party/blink/renderer/modules/xr/xr_world_information.cc b/third_party/blink/renderer/modules/xr/xr_world_information.cc index dfeaed0..d0fcbae 100644 --- a/third_party/blink/renderer/modules/xr/xr_world_information.cc +++ b/third_party/blink/renderer/modules/xr/xr_world_information.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/xr/xr_world_information.h" #include "base/trace_event/trace_event.h" +#include "third_party/blink/renderer/modules/xr/xr_light_estimation.h" #include "third_party/blink/renderer/modules/xr/xr_session.h" namespace blink { @@ -14,6 +15,7 @@ void XRWorldInformation::Trace(blink::Visitor* visitor) { visitor->Trace(plane_ids_to_planes_); + visitor->Trace(light_estimation_); visitor->Trace(session_); ScriptWrappable::Trace(visitor); } @@ -33,6 +35,10 @@ return MakeGarbageCollected<XRPlaneSet>(result); } +XRLightEstimation* XRWorldInformation::lightEstimation() const { + return light_estimation_.Get(); +} + void XRWorldInformation::ProcessPlaneInformation( const device::mojom::blink::XRPlaneDetectionData* detected_planes_data, double timestamp) { @@ -91,4 +97,16 @@ plane_ids_to_planes_.swap(updated_planes); } +void XRWorldInformation::ProcessLightEstimationData( + const device::mojom::blink::XRLightEstimationData* data, + double timestamp) { + TRACE_EVENT0("xr", __FUNCTION__); + + if (data) { + light_estimation_ = MakeGarbageCollected<XRLightEstimation>(*data); + } else { + light_estimation_ = nullptr; + } +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/xr/xr_world_information.h b/third_party/blink/renderer/modules/xr/xr_world_information.h index cde9e46e..2c63043 100644 --- a/third_party/blink/renderer/modules/xr/xr_world_information.h +++ b/third_party/blink/renderer/modules/xr/xr_world_information.h
@@ -11,6 +11,7 @@ namespace blink { +class XRLightEstimation; class XRSession; class XRWorldInformation : public ScriptWrappable { @@ -23,6 +24,8 @@ // disabled. XRPlaneSet* detectedPlanes() const; + XRLightEstimation* lightEstimation() const; + void Trace(blink::Visitor* visitor) override; // Applies changes to the stored plane information based on the contents of @@ -32,6 +35,10 @@ const device::mojom::blink::XRPlaneDetectionData* detected_planes_data, double timestamp); + void ProcessLightEstimationData( + const device::mojom::blink::XRLightEstimationData* data, + double timestamp); + private: // Signifies if we should return null from `detectedPlanes()`. // This is the case if we have a freshly constructed instance, or if our @@ -39,6 +46,8 @@ bool is_detected_planes_null_ = true; HeapHashMap<uint64_t, Member<XRPlane>> plane_ids_to_planes_; + Member<XRLightEstimation> light_estimation_; + Member<XRSession> session_; };
diff --git a/third_party/blink/renderer/modules/xr/xr_world_information.idl b/third_party/blink/renderer/modules/xr/xr_world_information.idl index b60addc..64ad2fa 100644 --- a/third_party/blink/renderer/modules/xr/xr_world_information.idl +++ b/third_party/blink/renderer/modules/xr/xr_world_information.idl
@@ -11,5 +11,6 @@ ] interface XRWorldInformation { readonly attribute XRPlaneSet? detectedPlanes; + readonly attribute XRLightEstimation? lightEstimation; };
diff --git a/third_party/blink/renderer/modules/xr/xr_world_tracking_state.cc b/third_party/blink/renderer/modules/xr/xr_world_tracking_state.cc index 5367956..1f21a1d 100644 --- a/third_party/blink/renderer/modules/xr/xr_world_tracking_state.cc +++ b/third_party/blink/renderer/modules/xr/xr_world_tracking_state.cc
@@ -3,7 +3,11 @@ // found in the LICENSE file. #include "third_party/blink/renderer/modules/xr/xr_world_tracking_state.h" + +#include "third_party/blink/renderer/modules/xr/xr_light_estimation_state.h" +#include "third_party/blink/renderer/modules/xr/xr_light_estimation_state_init.h" #include "third_party/blink/renderer/modules/xr/xr_plane_detection_state.h" +#include "third_party/blink/renderer/modules/xr/xr_plane_detection_state_init.h" #include "third_party/blink/renderer/modules/xr/xr_world_tracking_state_init.h" namespace blink { @@ -15,12 +19,23 @@ plane_detection_state_ = MakeGarbageCollected<XRPlaneDetectionState>( world_tracking_state_init->planeDetectionState()); } else { - plane_detection_state_ = MakeGarbageCollected<XRPlaneDetectionState>(); + plane_detection_state_ = + MakeGarbageCollected<XRPlaneDetectionState>(nullptr); + } + + if (world_tracking_state_init && + world_tracking_state_init->hasLightEstimationState()) { + light_estimation_state_ = MakeGarbageCollected<XRLightEstimationState>( + world_tracking_state_init->lightEstimationState()); + } else { + light_estimation_state_ = + MakeGarbageCollected<XRLightEstimationState>(nullptr); } } void XRWorldTrackingState::Trace(blink::Visitor* visitor) { visitor->Trace(plane_detection_state_); + visitor->Trace(light_estimation_state_); ScriptWrappable::Trace(visitor); }
diff --git a/third_party/blink/renderer/modules/xr/xr_world_tracking_state.h b/third_party/blink/renderer/modules/xr/xr_world_tracking_state.h index 87625a8c..96df185 100644 --- a/third_party/blink/renderer/modules/xr/xr_world_tracking_state.h +++ b/third_party/blink/renderer/modules/xr/xr_world_tracking_state.h
@@ -7,12 +7,12 @@ #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" -#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" namespace blink { class XRPlaneDetectionState; +class XRLightEstimationState; class XRWorldTrackingStateInit; class XRWorldTrackingState : public ScriptWrappable { @@ -26,10 +26,15 @@ return plane_detection_state_; } + XRLightEstimationState* lightEstimationState() const { + return light_estimation_state_; + } + void Trace(blink::Visitor* visitor) override; private: Member<XRPlaneDetectionState> plane_detection_state_; + Member<XRLightEstimationState> light_estimation_state_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/xr/xr_world_tracking_state.idl b/third_party/blink/renderer/modules/xr/xr_world_tracking_state.idl index ee714c3..b637518 100644 --- a/third_party/blink/renderer/modules/xr/xr_world_tracking_state.idl +++ b/third_party/blink/renderer/modules/xr/xr_world_tracking_state.idl
@@ -11,5 +11,6 @@ ] interface XRWorldTrackingState { readonly attribute XRPlaneDetectionState planeDetectionState; + readonly attribute XRLightEstimationState lightEstimationState; };
diff --git a/third_party/blink/renderer/modules/xr/xr_world_tracking_state_init.idl b/third_party/blink/renderer/modules/xr/xr_world_tracking_state_init.idl index f8fd6bb..2217591 100644 --- a/third_party/blink/renderer/modules/xr/xr_world_tracking_state_init.idl +++ b/third_party/blink/renderer/modules/xr/xr_world_tracking_state_init.idl
@@ -6,5 +6,6 @@ // https://github.com/immersive-web/real-world-geometry/blob/master/plane-detection-explainer.md dictionary XRWorldTrackingStateInit { XRPlaneDetectionStateInit planeDetectionState; + XRLightEstimationStateInit lightEstimationState; };
diff --git a/third_party/blink/renderer/platform/exported/web_url_request.cc b/third_party/blink/renderer/platform/exported/web_url_request.cc index c9cb31c..bba4b096 100644 --- a/third_party/blink/renderer/platform/exported/web_url_request.cc +++ b/third_party/blink/renderer/platform/exported/web_url_request.cc
@@ -58,8 +58,9 @@ // TODO(keishi): Replace with GCWrapper<ResourceRequest> struct WebURLRequest::ResourceRequestContainer { ResourceRequestContainer() = default; - explicit ResourceRequestContainer(const ResourceRequest& r) - : resource_request(r) {} + explicit ResourceRequestContainer(const ResourceRequest& r) { + resource_request.CopyFrom(r); + } ResourceRequest resource_request; }; @@ -84,8 +85,9 @@ // semantics via this operator is just not supported. DCHECK(owned_resource_request_); DCHECK(resource_request_); - if (&r != this) - *resource_request_ = *r.resource_request_; + if (&r != this) { + resource_request_->CopyFrom(*r.resource_request_); + } return *this; }
diff --git a/third_party/blink/renderer/platform/heap/heap.cc b/third_party/blink/renderer/platform/heap/heap.cc index 51f8d08..fb09eeb 100644 --- a/third_party/blink/renderer/platform/heap/heap.cc +++ b/third_party/blink/renderer/platform/heap/heap.cc
@@ -453,14 +453,23 @@ void ThreadHeap::MakeConsistentForGC() { DCHECK(thread_state_->InAtomicMarkingPause()); - for (int i = 0; i < BlinkGC::kNumberOfArenas; ++i) - arenas_[i]->MakeConsistentForGC(); + for (BaseArena* arena : arenas_) { + arena->MakeConsistentForGC(); + } } void ThreadHeap::MakeConsistentForMutator() { DCHECK(thread_state_->InAtomicMarkingPause()); - for (int i = 0; i < BlinkGC::kNumberOfArenas; ++i) - arenas_[i]->MakeConsistentForMutator(); + for (BaseArena* arena : arenas_) { + arena->MakeConsistentForMutator(); + } +} + +void ThreadHeap::Unmark() { + DCHECK(thread_state_->InAtomicMarkingPause()); + for (BaseArena* arena : arenas_) { + arena->Unmark(); + } } void ThreadHeap::Compact() {
diff --git a/third_party/blink/renderer/platform/heap/heap.h b/third_party/blink/renderer/platform/heap/heap.h index a86aee6..4f853630 100644 --- a/third_party/blink/renderer/platform/heap/heap.h +++ b/third_party/blink/renderer/platform/heap/heap.h
@@ -344,6 +344,10 @@ // the executions of mutators. void MakeConsistentForMutator(); + // Unmarks all objects in the entire heap. This is supposed to be called in + // the beginning of major GC. + void Unmark(); + void Compact(); enum class SweepingType : uint8_t { kMutator, kConcurrent };
diff --git a/third_party/blink/renderer/platform/heap/heap_page.cc b/third_party/blink/renderer/platform/heap/heap_page.cc index 083e6a8..676dacba 100644 --- a/third_party/blink/renderer/platform/heap/heap_page.cc +++ b/third_party/blink/renderer/platform/heap/heap_page.cc
@@ -215,6 +215,15 @@ VerifyObjectStartBitmap(); } +void BaseArena::Unmark() { + DCHECK(GetThreadState()->InAtomicMarkingPause()); + DCHECK(SweepingAndFinalizationCompleted()); + + for (BasePage* page : swept_pages_) { + page->Unmark(); + } +} + size_t BaseArena::ObjectPayloadSizeForTesting() { #if DCHECK_IS_ON() DCHECK(IsConsistentForGC()); @@ -1479,7 +1488,9 @@ found_finalizer = false; } object_start_bit_map()->SetBit(header_address); +#if !BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION) header->Unmark<HeapObjectHeader::AccessMode::kAtomic>(); +#endif header_address += size; start_of_gap = header_address; } @@ -1543,7 +1554,9 @@ header_address += size; continue; } +#if !BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION) header->Unmark(); +#endif // Allocate and copy over the live object. Address compact_frontier = current_page->Payload() + allocation_point; if (compact_frontier + size > current_page->PayloadEnd()) { @@ -1635,6 +1648,29 @@ VerifyObjectStartBitmapIsConsistentWithPayload(); } +// This is assumed to be called from the atomic pause, so no concurrency should +// be involved here. +void NormalPage::Unmark() { + const Address current_allocation_point = + ArenaForNormalPage()->CurrentAllocationPoint(); + const size_t allocation_area_size = + ArenaForNormalPage()->RemainingAllocationSize(); + for (Address header_address = Payload(); header_address < PayloadEnd();) { + // Since unmarking can happen inside IncrementalMarkingStart, the current + // allocation point can be set and we need to skip over it. + if (header_address == current_allocation_point && allocation_area_size) { + header_address += allocation_area_size; + continue; + } + HeapObjectHeader* header = + reinterpret_cast<HeapObjectHeader*>(header_address); + if (header->IsMarked()) { + header->Unmark(); + } + header_address += header->size(); + } +} + #if defined(ADDRESS_SANITIZER) void NormalPage::PoisonUnmarkedObjects() { for (Address header_address = Payload(); header_address < PayloadEnd();) { @@ -1791,17 +1827,23 @@ if (!ObjectHeader()->IsMarked()) { return true; } +#if !BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION) ObjectHeader()->Unmark(); +#endif return false; } -void LargeObjectPage::MakeConsistentForMutator() { +void LargeObjectPage::Unmark() { HeapObjectHeader* header = ObjectHeader(); if (header->IsMarked()) { header->Unmark(); } } +void LargeObjectPage::MakeConsistentForMutator() { + Unmark(); +} + void LargeObjectPage::FinalizeSweep(SweepResult action) { if (action == SweepResult::kPageNotEmpty) { MarkAsSwept();
diff --git a/third_party/blink/renderer/platform/heap/heap_page.h b/third_party/blink/renderer/platform/heap/heap_page.h index d413086..205ed22 100644 --- a/third_party/blink/renderer/platform/heap/heap_page.h +++ b/third_party/blink/renderer/platform/heap/heap_page.h
@@ -466,6 +466,7 @@ // Does not create free list entries for empty pages. virtual bool Sweep(FinalizeType) = 0; virtual void MakeConsistentForMutator() = 0; + virtual void Unmark() = 0; // Calls finalizers after sweeping is done. virtual void FinalizeSweep(SweepResult) = 0; @@ -653,6 +654,7 @@ void RemoveFromHeap() override; bool Sweep(FinalizeType) override; void MakeConsistentForMutator() override; + void Unmark() override; void FinalizeSweep(SweepResult) override; #if defined(ADDRESS_SANITIZER) void PoisonUnmarkedObjects() override; @@ -879,6 +881,7 @@ void RemoveFromHeap() override; bool Sweep(FinalizeType) override; void MakeConsistentForMutator() override; + void Unmark() override; void FinalizeSweep(SweepResult) override; void CollectStatistics( @@ -945,6 +948,7 @@ virtual void MakeIterable() {} virtual void MakeConsistentForGC(); void MakeConsistentForMutator(); + void Unmark(); #if DCHECK_IS_ON() virtual bool IsConsistentForGC() = 0; #endif
diff --git a/third_party/blink/renderer/platform/heap/thread_state.cc b/third_party/blink/renderer/platform/heap/thread_state.cc index f88b8ad..d9cbadcd 100644 --- a/third_party/blink/renderer/platform/heap/thread_state.cc +++ b/third_party/blink/renderer/platform/heap/thread_state.cc
@@ -1614,6 +1614,13 @@ Heap().Compaction()->Initialize(this); } +#if BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION) + if (collection_type == BlinkGC::CollectionType::kMajor) { + // Unmark heap before doing major collection cycle. + Heap().Unmark(); + } +#endif + current_gc_data_.reason = reason; current_gc_data_.collection_type = collection_type; current_gc_data_.visitor =
diff --git a/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc b/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc index eea54363..817163d 100644 --- a/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc +++ b/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc
@@ -34,20 +34,22 @@ namespace blink { FetchParameters::FetchParameters(const ResourceRequest& resource_request) - : resource_request_(resource_request), - decoder_options_(TextResourceDecoderOptions::kPlainTextContent), + : decoder_options_(TextResourceDecoderOptions::kPlainTextContent), speculative_preload_type_(SpeculativePreloadType::kNotSpeculative), defer_(kNoDefer), - image_request_optimization_(kNone) {} + image_request_optimization_(kNone) { + resource_request_.CopyFrom(resource_request); +} FetchParameters::FetchParameters(const ResourceRequest& resource_request, const ResourceLoaderOptions& options) - : resource_request_(resource_request), - decoder_options_(TextResourceDecoderOptions::kPlainTextContent), + : decoder_options_(TextResourceDecoderOptions::kPlainTextContent), options_(options), speculative_preload_type_(SpeculativePreloadType::kNotSpeculative), defer_(kNoDefer), - image_request_optimization_(kNone) {} + image_request_optimization_(kNone) { + resource_request_.CopyFrom(resource_request); +} FetchParameters::FetchParameters(FetchParameters&&) = default;
diff --git a/third_party/blink/renderer/platform/loader/fetch/memory_cache_correctness_test.cc b/third_party/blink/renderer/platform/loader/fetch/memory_cache_correctness_test.cc index 814e5c4b..0d452e0 100644 --- a/third_party/blink/renderer/platform/loader/fetch/memory_cache_correctness_test.cc +++ b/third_party/blink/renderer/platform/loader/fetch/memory_cache_correctness_test.cc
@@ -318,7 +318,7 @@ no_cache_request.SetHttpHeaderField(http_names::kCacheControl, "no-cache"); no_cache_request.SetRequestorOrigin(GetSecurityOrigin()); MockResource* no_cache_resource = - ResourceFromResourceRequest(no_cache_request); + ResourceFromResourceRequest(std::move(no_cache_request)); MockResource* fetched = FetchMockResource(); EXPECT_NE(no_cache_resource, fetched); } @@ -349,7 +349,7 @@ no_store_request.SetHttpHeaderField(http_names::kCacheControl, "no-store"); no_store_request.SetRequestorOrigin(GetSecurityOrigin()); MockResource* no_store_resource = - ResourceFromResourceRequest(no_store_request); + ResourceFromResourceRequest(std::move(no_store_request)); MockResource* fetched = FetchMockResource(); EXPECT_NE(no_store_resource, fetched); }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource.cc b/third_party/blink/renderer/platform/loader/fetch/resource.cc index 6fe0c17..9848642 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource.cc
@@ -162,8 +162,8 @@ integrity_disposition_(ResourceIntegrityDisposition::kNotChecked), options_(options), response_timestamp_(Now()), - resource_request_(request), overhead_size_(CalculateOverheadSize()) { + resource_request_.CopyFrom(request); InstanceCounters::IncrementCounter(InstanceCounters::kResourceCounter); if (IsMainThread()) @@ -490,7 +490,7 @@ DCHECK(!request.IsNull()); CHECK(!is_revalidation_start_forbidden_); is_revalidating_ = true; - resource_request_ = request; + resource_request_.CopyFrom(request); status_ = ResourceStatus::kNotStarted; }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource.h b/third_party/blink/renderer/platform/loader/fetch/resource.h index 9b83d43..1b95c041 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource.h
@@ -378,7 +378,7 @@ // in ResourceFetcher::StartLoad() for retry in cache-aware loading, remove // once ResourceRequest is not modified in StartLoad(). crbug.com/632580 void SetResourceRequest(const ResourceRequest& resource_request) { - resource_request_ = resource_request; + resource_request_.CopyFrom(resource_request); } // Used by the MemoryCache to reduce the memory consumption of the entry. @@ -475,7 +475,9 @@ public: explicit RedirectPair(const ResourceRequest& request, const ResourceResponse& redirect_response) - : request_(request), redirect_response_(redirect_response) {} + : redirect_response_(redirect_response) { + request_.CopyFrom(request); + } ResourceRequest request_; ResourceResponse redirect_response_;
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc index 07629c1c..bceba46 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
@@ -389,7 +389,7 @@ // If they are keepalive request && their responses are not observable to web // content, we can have them survive without breaking web content when the // page is put into BackForwardCache. - auto request = resource_->GetResourceRequest(); + auto& request = resource_->GetResourceRequest(); if (!RequestContextObserveResponse(request.GetRequestContext())) { if (FrameScheduler* frame_scheduler = fetcher->GetFrameScheduler()) { feature_handle_for_scheduler_ = frame_scheduler->RegisterFeature( @@ -570,7 +570,8 @@ if (is_cache_aware_loading_activated_) { // Override cache policy for cache-aware loading. If this request fails, a // reload with original request will be triggered in DidFail(). - ResourceRequest cache_aware_request(request); + ResourceRequest cache_aware_request; + cache_aware_request.CopyFrom(request); cache_aware_request.SetCacheMode( mojom::FetchCacheMode::kUnspecifiedOnlyIfCachedStrict); RequestAsynchronously(cache_aware_request); @@ -962,7 +963,8 @@ kEnableCorsHandlingByResourceFetcher && request_mode == network::mojom::RequestMode::kCors && response.WasFallbackRequiredByServiceWorker()) { - ResourceRequest last_request = resource_->LastResourceRequest(); + ResourceRequest last_request; + last_request.CopyFrom(resource_->LastResourceRequest()); DCHECK(!last_request.GetSkipServiceWorker()); // This code handles the case when a controlling service worker doesn't // handle a cross origin request.
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request.cc b/third_party/blink/renderer/platform/loader/fetch/resource_request.cc index ce6c768..f93f035 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_request.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.cc
@@ -82,12 +82,18 @@ network::mojom::CorsPreflightPolicy::kConsiderPreflight), redirect_status_(RedirectStatus::kNoRedirect) {} -ResourceRequest::ResourceRequest(const ResourceRequest&) = default; - ResourceRequest::~ResourceRequest() = default; ResourceRequest& ResourceRequest::operator=(const ResourceRequest&) = default; +ResourceRequest::ResourceRequest(ResourceRequest&&) = default; + +ResourceRequest& ResourceRequest::operator=(ResourceRequest&&) = default; + +void ResourceRequest::CopyFrom(const ResourceRequest& src) { + *this = src; +} + std::unique_ptr<ResourceRequest> ResourceRequest::CreateRedirectRequest( const KURL& new_url, const AtomicString& new_method,
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request.h b/third_party/blink/renderer/platform/loader/fetch/resource_request.h index 5da603e..61d0fb26 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_request.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.h
@@ -70,13 +70,16 @@ explicit ResourceRequest(const String& url_string); explicit ResourceRequest(const KURL&); - // TODO(toyoshim): Use std::unique_ptr as much as possible, and hopefully - // make ResourceRequest DISALLOW_COPY_AND_ASSIGN. See crbug.com/787704. - ResourceRequest(const ResourceRequest&); - ResourceRequest& operator=(const ResourceRequest&); + ResourceRequest(const ResourceRequest&) = delete; + ResourceRequest(ResourceRequest&&); + ResourceRequest& operator=(ResourceRequest&&); ~ResourceRequest(); + // TODO(yoichio): Use move semantics as much as possible. + // See crbug.com/787704. + void CopyFrom(const ResourceRequest&); + // Constructs a new ResourceRequest for a redirect from this instance. std::unique_ptr<ResourceRequest> CreateRedirectRequest( const KURL& new_url, @@ -457,6 +460,8 @@ using SharableExtraData = base::RefCountedData<std::unique_ptr<WebURLRequest::ExtraData>>; + ResourceRequest& operator=(const ResourceRequest&); + const CacheControlHeader& GetCacheControlHeader() const; bool NeedsHTTPOrigin() const;
diff --git a/third_party/blink/renderer/platform/network/content_security_policy_parsers.cc b/third_party/blink/renderer/platform/network/content_security_policy_parsers.cc index 3d106e9..7b69e5d1 100644 --- a/third_party/blink/renderer/platform/network/content_security_policy_parsers.cc +++ b/third_party/blink/renderer/platform/network/content_security_policy_parsers.cc
@@ -58,16 +58,4 @@ return !IsASCIISpace(c) && c != '/'; } -STATIC_ASSERT_ENUM(network::mojom::ContentSecurityPolicyType::kReport, - kContentSecurityPolicyHeaderTypeReport); -STATIC_ASSERT_ENUM(network::mojom::ContentSecurityPolicyType::kEnforce, - kContentSecurityPolicyHeaderTypeEnforce); - -STATIC_ASSERT_ENUM(network::mojom::ContentSecurityPolicySource::kHTTP, - kContentSecurityPolicyHeaderSourceHTTP); -STATIC_ASSERT_ENUM(network::mojom::ContentSecurityPolicySource::kMeta, - kContentSecurityPolicyHeaderSourceMeta); -STATIC_ASSERT_ENUM(network::mojom::ContentSecurityPolicySource::kOriginPolicy, - kContentSecurityPolicyHeaderSourceOriginPolicy); - } // namespace blink
diff --git a/third_party/blink/renderer/platform/network/content_security_policy_parsers.h b/third_party/blink/renderer/platform/network/content_security_policy_parsers.h index e352fa9..4165e18 100644 --- a/third_party/blink/renderer/platform/network/content_security_policy_parsers.h +++ b/third_party/blink/renderer/platform/network/content_security_policy_parsers.h
@@ -13,17 +13,6 @@ typedef std::pair<unsigned, DigestValue> CSPHashValue; -enum ContentSecurityPolicyHeaderType { - kContentSecurityPolicyHeaderTypeReport, - kContentSecurityPolicyHeaderTypeEnforce -}; - -enum ContentSecurityPolicyHeaderSource { - kContentSecurityPolicyHeaderSourceHTTP, - kContentSecurityPolicyHeaderSourceMeta, - kContentSecurityPolicyHeaderSourceOriginPolicy -}; - enum ContentSecurityPolicyHashAlgorithm { kContentSecurityPolicyHashAlgorithmNone = 0, kContentSecurityPolicyHashAlgorithmSha256 = 1 << 2,
diff --git a/third_party/blink/web_tests/FlagExpectations/layout-ng-fragment-item b/third_party/blink/web_tests/FlagExpectations/layout-ng-fragment-item index c962276..3efeb65 100644 --- a/third_party/blink/web_tests/FlagExpectations/layout-ng-fragment-item +++ b/third_party/blink/web_tests/FlagExpectations/layout-ng-fragment-item
@@ -607,7 +607,6 @@ crbug.com/982194 external/wpt/css/css-grid/animation/grid-template-columns-001.html [ Failure ] crbug.com/982194 external/wpt/css/css-grid/animation/grid-template-rows-001.html [ Failure ] crbug.com/982194 external/wpt/css/css-grid/grid-child-percent-basis-resize-1.html [ Failure ] -crbug.com/982194 external/wpt/css/css-grid/grid-layout-properties.html [ Failure ] crbug.com/982194 external/wpt/css/css-grid/grid-model/grid-container-ignores-first-letter-002.html [ Failure ] crbug.com/982194 external/wpt/css/css-images/tiled-gradients.html [ Failure ] crbug.com/982194 external/wpt/css/css-intrinsic-size/intrinsic-size-015.html [ Crash Pass ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 9a99e5d3..29763c1 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -2838,6 +2838,9 @@ crbug.com/641245 external/wpt/css/motion/offset-path-ray-contain-005.html [ Failure ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 [ Linux ] external/wpt/html/cross-origin-opener-policy/coep-blob-popup.https.html [ Timeout ] +crbug.com/626703 [ Mac ] external/wpt/html/cross-origin-opener-policy/coep-blob-popup.https.html [ Timeout ] +crbug.com/626703 [ Win ] external/wpt/html/cross-origin-opener-policy/coep-blob-popup.https.html [ Timeout ] crbug.com/626703 [ Win7 ] external/wpt/pointerevents/pointerevent_touch-action-inherit_child-auto-child-none_touch.html [ Timeout ] crbug.com/626703 [ Win7 ] external/wpt/content-security-policy/object-src/object-src-no-url-allowed.html [ Timeout ] crbug.com/626703 [ Win7 ] external/wpt/content-security-policy/plugin-types/plugintypes-nourl-allowed.html [ Timeout ] @@ -4128,7 +4131,6 @@ crbug.com/759665 external/wpt/css/css-grid/animation/grid-template-columns-001.html [ Failure ] crbug.com/759665 external/wpt/css/css-grid/animation/grid-template-rows-001.html [ Failure ] crbug.com/1018439 external/wpt/css/css-grid/grid-child-percent-basis-resize-1.html [ Failure ] -crbug.com/511177 external/wpt/css/css-grid/grid-layout-properties.html [ Failure ] crbug.com/868380 external/wpt/css/css-grid/grid-model/grid-container-ignores-first-letter-002.html [ Failure ] crbug.com/707359 [ Mac ] fast/css-grid-layout/grid-align-baseline-vertical.html [ Failure ] crbug.com/707359 [ Mac ] fast/css-grid-layout/grid-self-baseline-03.html [ Failure ] @@ -4549,11 +4551,7 @@ crbug.com/683800 [ Win7 Debug ] external/wpt/selection/* [ Failure Pass ] # Arrow function name inferring -crbug.com/916975 http/tests/devtools/console/console-repeat-count.js [ Pass Failure ] -crbug.com/916975 http/tests/devtools/service-workers/lazy-addeventlisteners.js [ Pass Failure ] -crbug.com/916975 http/tests/devtools/sources/debugger-ui/call-stack-show-more.js [ Pass Failure ] crbug.com/916975 http/tests/devtools/tracing/timeline-misc/timeline-event-causes.js [ Pass Failure ] -crbug.com/916975 inspector-protocol/css/media-query-listener-exception.js [ Pass Failure ] crbug.com/916975 virtual/threaded/http/tests/devtools/tracing/timeline-misc/timeline-event-causes.js [ Pass Failure ] # Importing 'fetch' tests from WPT.
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 344f801..4404a856 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -724,5 +724,15 @@ "bases": ["clipboard/async-clipboard", "external/wpt/clipboard-apis/clipboard-item.https.html"], "args": ["--enable-features=RawClipboard"] + }, + { + "prefix": "legacy-client-hints", + "bases": ["external/wpt/client-hints", "wpt_internal/client-hints"], + "args": ["--enable-features=AllowClientHintsToThirdParty"] + }, + { + "prefix": "legacy-client-hints-no-fp-delegation", + "bases": ["external/wpt/client-hints"], + "args": ["--enable-features=AllowClientHintsToThirdParty", "--disable-blink-features=FeaturePolicyForClientHints"] } ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_7.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_7.json index c6e30a60..3f059ef3 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_7.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_7.json
@@ -6183,6 +6183,84 @@ {} ] ], + "native-file-system/native_FileSystemBaseHandle-postMessage-BroadcastChannel-manual.https.tentative.html": [ + [ + "native-file-system/native_FileSystemBaseHandle-postMessage-BroadcastChannel-manual.https.tentative.html", + {} + ] + ], + "native-file-system/native_FileSystemBaseHandle-postMessage-Error-manual.https.tentative.html": [ + [ + "native-file-system/native_FileSystemBaseHandle-postMessage-Error-manual.https.tentative.html", + {} + ] + ], + "native-file-system/native_FileSystemBaseHandle-postMessage-MessagePort-manual.https.tentative.html": [ + [ + "native-file-system/native_FileSystemBaseHandle-postMessage-MessagePort-manual.https.tentative.html", + {} + ] + ], + "native-file-system/native_FileSystemBaseHandle-postMessage-manual.https.tentative.html": [ + [ + "native-file-system/native_FileSystemBaseHandle-postMessage-manual.https.tentative.html", + {} + ] + ], + "native-file-system/native_FileSystemDirectoryHandle-getDirectory-manual.https.tentative.html": [ + [ + "native-file-system/native_FileSystemDirectoryHandle-getDirectory-manual.https.tentative.html", + {} + ] + ], + "native-file-system/native_FileSystemDirectoryHandle-getEntries-manual.https.tentative.html": [ + [ + "native-file-system/native_FileSystemDirectoryHandle-getEntries-manual.https.tentative.html", + {} + ] + ], + "native-file-system/native_FileSystemDirectoryHandle-getFile-manual.https.tentative.html": [ + [ + "native-file-system/native_FileSystemDirectoryHandle-getFile-manual.https.tentative.html", + {} + ] + ], + "native-file-system/native_FileSystemDirectoryHandle-removeEntry-manual.https.tentative.html": [ + [ + "native-file-system/native_FileSystemDirectoryHandle-removeEntry-manual.https.tentative.html", + {} + ] + ], + "native-file-system/native_FileSystemFileHandle-getFile-manual.https.tentative.html": [ + [ + "native-file-system/native_FileSystemFileHandle-getFile-manual.https.tentative.html", + {} + ] + ], + "native-file-system/native_FileSystemWritableFileStream-manual.https.tentative.html": [ + [ + "native-file-system/native_FileSystemWritableFileStream-manual.https.tentative.html", + {} + ] + ], + "native-file-system/native_FileSystemWritableFileStream-piped-manual.https.tentative.html": [ + [ + "native-file-system/native_FileSystemWritableFileStream-piped-manual.https.tentative.html", + {} + ] + ], + "native-file-system/native_FileSystemWritableFileStream-write-manual.https.tentative.html": [ + [ + "native-file-system/native_FileSystemWritableFileStream-write-manual.https.tentative.html", + {} + ] + ], + "native-file-system/native_FileSystemWriter-manual.https.tentative.html": [ + [ + "native-file-system/native_FileSystemWriter-manual.https.tentative.html", + {} + ] + ], "notifications/body-basic-manual.html": [ [ "notifications/body-basic-manual.html", @@ -145587,6 +145665,9 @@ "css/css-pseudo/marker-color-ref.html": [ [] ], + "css/css-pseudo/marker-computed-size-expected.txt": [ + [] + ], "css/css-pseudo/marker-content-001-ref.html": [ [] ], @@ -145824,9 +145905,6 @@ "css/css-shadow-parts/interaction-with-pseudo-elements-expected.txt": [ [] ], - "css/css-shadow-parts/multiple-parts-expected.txt": [ - [] - ], "css/css-shadow-parts/support/shadow-helper.js": [ [] ], @@ -156162,18 +156240,6 @@ "dom/events/scrolling/scroll_support.js": [ [] ], - "dom/events/webkit-animation-end-event-expected.txt": [ - [] - ], - "dom/events/webkit-animation-iteration-event-expected.txt": [ - [] - ], - "dom/events/webkit-animation-start-event-expected.txt": [ - [] - ], - "dom/events/webkit-transition-end-event-expected.txt": [ - [] - ], "dom/historical-expected.txt": [ [] ], @@ -161103,6 +161169,12 @@ "html/cross-origin-opener-policy/README.md": [ [] ], + "html/cross-origin-opener-policy/blob-popup.https.html.headers": [ + [] + ], + "html/cross-origin-opener-policy/coep-blob-popup.https.html.headers": [ + [] + ], "html/cross-origin-opener-policy/coep-navigate-popup.https-expected.txt": [ [] ], @@ -161190,6 +161262,24 @@ "html/cross-origin-opener-policy/historical/popup-same-site-with-same-site.https.html.headers": [ [] ], + "html/cross-origin-opener-policy/iframe-popup-same-origin-allow-popups.https-expected.txt": [ + [] + ], + "html/cross-origin-opener-policy/iframe-popup-same-origin-allow-popups.https.html.headers": [ + [] + ], + "html/cross-origin-opener-policy/iframe-popup-same-origin.https-expected.txt": [ + [] + ], + "html/cross-origin-opener-policy/iframe-popup-same-origin.https.html.headers": [ + [] + ], + "html/cross-origin-opener-policy/iframe-popup-unsafe-none.https-expected.txt": [ + [] + ], + "html/cross-origin-opener-policy/iframe-popup-unsafe-none.https.html.headers": [ + [] + ], "html/cross-origin-opener-policy/no-https-expected.txt": [ [] ], @@ -161286,6 +161376,9 @@ "html/cross-origin-opener-policy/resources/coop-coep.py": [ [] ], + "html/cross-origin-opener-policy/resources/iframe-popup.sub.html": [ + [] + ], "html/cross-origin-opener-policy/resources/postback.html": [ [] ], @@ -167730,6 +167823,9 @@ "import-maps/common/README.md": [ [] ], + "import-maps/common/parsing.tentative-expected.txt": [ + [] + ], "import-maps/common/resources/common-test-helper.js": [ [] ], @@ -167745,6 +167841,39 @@ "import-maps/common/resources/packages-via-trailing-slashes.json": [ [] ], + "import-maps/common/resources/parsing-addresses-absolute.json": [ + [] + ], + "import-maps/common/resources/parsing-addresses-invalid.json": [ + [] + ], + "import-maps/common/resources/parsing-addresses.json": [ + [] + ], + "import-maps/common/resources/parsing-invalid-json.json": [ + [] + ], + "import-maps/common/resources/parsing-schema-normalization.json": [ + [] + ], + "import-maps/common/resources/parsing-schema-scope.json": [ + [] + ], + "import-maps/common/resources/parsing-schema-specifier-map.json": [ + [] + ], + "import-maps/common/resources/parsing-schema-toplevel.json": [ + [] + ], + "import-maps/common/resources/parsing-scope-keys.json": [ + [] + ], + "import-maps/common/resources/parsing-specifier-keys.json": [ + [] + ], + "import-maps/common/resources/parsing-trailing-slashes.json": [ + [] + ], "import-maps/common/resources/scopes-exact-vs-prefix.json": [ [] ], @@ -167778,21 +167907,6 @@ "import-maps/core/static-import.py": [ [] ], - "import-maps/imported/resources/helpers/parsing.js": [ - [] - ], - "import-maps/imported/resources/parsing-addresses.js": [ - [] - ], - "import-maps/imported/resources/parsing-schema.js": [ - [] - ], - "import-maps/imported/resources/parsing-scope-keys.js": [ - [] - ], - "import-maps/imported/resources/parsing-specifier-keys.js": [ - [] - ], "import-maps/resources/empty.js": [ [] ], @@ -170310,6 +170424,15 @@ "native-file-system/README.md": [ [] ], + "native-file-system/native_FileSystemDirectoryHandle-getDirectory-manual.https.tentative-expected.txt": [ + [] + ], + "native-file-system/native_FileSystemWritableFileStream-write-manual.https.tentative-expected.txt": [ + [] + ], + "native-file-system/native_FileSystemWriter-manual.https.tentative-expected.txt": [ + [] + ], "native-file-system/resources/message-target-dedicated-worker.js": [ [] ], @@ -218938,6 +219061,12 @@ {} ] ], + "css/css-pseudo/marker-computed-size.html": [ + [ + "css/css-pseudo/marker-computed-size.html", + {} + ] + ], "css/css-pseudo/marker-default-styles.html": [ [ "css/css-pseudo/marker-default-styles.html", @@ -219828,6 +219957,12 @@ {} ] ], + "css/css-shadow-parts/serialization.html": [ + [ + "css/css-shadow-parts/serialization.html", + {} + ] + ], "css/css-shadow-parts/simple-forward-shorthand.html": [ [ "css/css-shadow-parts/simple-forward-shorthand.html", @@ -251295,6 +251430,18 @@ {} ] ], + "html/cross-origin-opener-policy/blob-popup.https.html": [ + [ + "html/cross-origin-opener-policy/blob-popup.https.html", + {} + ] + ], + "html/cross-origin-opener-policy/coep-blob-popup.https.html": [ + [ + "html/cross-origin-opener-policy/coep-blob-popup.https.html", + {} + ] + ], "html/cross-origin-opener-policy/coep-navigate-popup.https.html": [ [ "html/cross-origin-opener-policy/coep-navigate-popup.https.html", @@ -251393,6 +251540,24 @@ {} ] ], + "html/cross-origin-opener-policy/iframe-popup-same-origin-allow-popups.https.html": [ + [ + "html/cross-origin-opener-policy/iframe-popup-same-origin-allow-popups.https.html", + {} + ] + ], + "html/cross-origin-opener-policy/iframe-popup-same-origin.https.html": [ + [ + "html/cross-origin-opener-policy/iframe-popup-same-origin.https.html", + {} + ] + ], + "html/cross-origin-opener-policy/iframe-popup-unsafe-none.https.html": [ + [ + "html/cross-origin-opener-policy/iframe-popup-unsafe-none.https.html", + {} + ] + ], "html/cross-origin-opener-policy/no-https.html": [ [ "html/cross-origin-opener-policy/no-https.html", @@ -264013,6 +264178,14 @@ {} ] ], + "import-maps/common/parsing.tentative.html": [ + [ + "import-maps/common/parsing.tentative.html", + { + "timeout": "long" + } + ] + ], "import-maps/common/resolving.tentative.html": [ [ "import-maps/common/resolving.tentative.html", @@ -264097,30 +264270,6 @@ {} ] ], - "import-maps/imported/parsing-addresses.tentative.html": [ - [ - "import-maps/imported/parsing-addresses.tentative.html", - {} - ] - ], - "import-maps/imported/parsing-schema.tentative.html": [ - [ - "import-maps/imported/parsing-schema.tentative.html", - {} - ] - ], - "import-maps/imported/parsing-scope-keys.tentative.html": [ - [ - "import-maps/imported/parsing-scope-keys.tentative.html", - {} - ] - ], - "import-maps/imported/parsing-specifier-keys.tentative.html": [ - [ - "import-maps/imported/parsing-specifier-keys.tentative.html", - {} - ] - ], "inert/inert-does-not-match-disabled-selector.tentative.html": [ [ "inert/inert-does-not-match-disabled-selector.tentative.html", @@ -270344,379 +270493,6 @@ } ] ], - "native-file-system/native_FileSystemBaseHandle-postMessage-BroadcastChannel.tentative.https.manual.window.js": [ - [ - "native-file-system/native_FileSystemBaseHandle-postMessage-BroadcastChannel.tentative.https.manual.window.html", - { - "script_metadata": [ - [ - "script", - "/service-workers/service-worker/resources/test-helpers.sub.js" - ], - [ - "script", - "resources/test-helpers.js" - ], - [ - "script", - "resources/native-fs-test-helpers.js" - ], - [ - "script", - "resources/messaging-helpers.js" - ], - [ - "script", - "resources/messaging-serialize-helpers.js" - ], - [ - "script", - "script-tests/FileSystemBaseHandle-postMessage-BroadcastChannel.js" - ] - ] - } - ] - ], - "native-file-system/native_FileSystemBaseHandle-postMessage-Error.tentative.https.manual.window.js": [ - [ - "native-file-system/native_FileSystemBaseHandle-postMessage-Error.tentative.https.manual.window.html", - { - "script_metadata": [ - [ - "script", - "/common/get-host-info.sub.js" - ], - [ - "script", - "/service-workers/service-worker/resources/test-helpers.sub.js" - ], - [ - "script", - "resources/test-helpers.js" - ], - [ - "script", - "resources/native-fs-test-helpers.js" - ], - [ - "script", - "resources/messaging-helpers.js" - ], - [ - "script", - "resources/messaging-blob-helpers.js" - ], - [ - "script", - "resources/messaging-serialize-helpers.js" - ], - [ - "script", - "script-tests/FileSystemBaseHandle-postMessage-Error.js" - ] - ] - } - ] - ], - "native-file-system/native_FileSystemBaseHandle-postMessage-MessagePort.tentative.https.manual.window.js": [ - [ - "native-file-system/native_FileSystemBaseHandle-postMessage-MessagePort.tentative.https.manual.window.html", - { - "script_metadata": [ - [ - "script", - "/service-workers/service-worker/resources/test-helpers.sub.js" - ], - [ - "script", - "resources/test-helpers.js" - ], - [ - "script", - "resources/native-fs-test-helpers.js" - ], - [ - "script", - "resources/messaging-helpers.js" - ], - [ - "script", - "resources/messaging-blob-helpers.js" - ], - [ - "script", - "resources/messaging-serialize-helpers.js" - ], - [ - "script", - "script-tests/FileSystemBaseHandle-postMessage-MessagePort.js" - ] - ] - } - ] - ], - "native-file-system/native_FileSystemBaseHandle-postMessage.tentative.https.manual.window.js": [ - [ - "native-file-system/native_FileSystemBaseHandle-postMessage.tentative.https.manual.window.html", - { - "script_metadata": [ - [ - "script", - "/service-workers/service-worker/resources/test-helpers.sub.js" - ], - [ - "script", - "resources/test-helpers.js" - ], - [ - "script", - "resources/native-fs-test-helpers.js" - ], - [ - "script", - "resources/messaging-helpers.js" - ], - [ - "script", - "resources/messaging-blob-helpers.js" - ], - [ - "script", - "resources/messaging-serialize-helpers.js" - ], - [ - "script", - "script-tests/FileSystemBaseHandle-postMessage.js" - ] - ] - } - ] - ], - "native-file-system/native_FileSystemDirectoryHandle-getDirectory.tentative.https.manual.window.js": [ - [ - "native-file-system/native_FileSystemDirectoryHandle-getDirectory.tentative.https.manual.window.html", - { - "script_metadata": [ - [ - "script", - "/resources/testdriver.js" - ], - [ - "script", - "resources/test-helpers.js" - ], - [ - "script", - "resources/native-fs-test-helpers.js" - ], - [ - "script", - "script-tests/FileSystemDirectoryHandle-getDirectory.js" - ] - ] - } - ] - ], - "native-file-system/native_FileSystemDirectoryHandle-getEntries.tentative.https.manual.window.js": [ - [ - "native-file-system/native_FileSystemDirectoryHandle-getEntries.tentative.https.manual.window.html", - { - "script_metadata": [ - [ - "script", - "/resources/testdriver.js" - ], - [ - "script", - "resources/test-helpers.js" - ], - [ - "script", - "resources/native-fs-test-helpers.js" - ], - [ - "script", - "script-tests/FileSystemDirectoryHandle-getEntries.js" - ] - ] - } - ] - ], - "native-file-system/native_FileSystemDirectoryHandle-getFile.tentative.https.manual.window.js": [ - [ - "native-file-system/native_FileSystemDirectoryHandle-getFile.tentative.https.manual.window.html", - { - "script_metadata": [ - [ - "script", - "/resources/testdriver.js" - ], - [ - "script", - "resources/test-helpers.js" - ], - [ - "script", - "resources/native-fs-test-helpers.js" - ], - [ - "script", - "script-tests/FileSystemDirectoryHandle-getFile.js" - ] - ] - } - ] - ], - "native-file-system/native_FileSystemDirectoryHandle-removeEntry.tentative.https.manual.window.js": [ - [ - "native-file-system/native_FileSystemDirectoryHandle-removeEntry.tentative.https.manual.window.html", - { - "script_metadata": [ - [ - "script", - "/resources/testdriver.js" - ], - [ - "script", - "resources/test-helpers.js" - ], - [ - "script", - "resources/native-fs-test-helpers.js" - ], - [ - "script", - "script-tests/FileSystemDirectoryHandle-removeEntry.js" - ] - ] - } - ] - ], - "native-file-system/native_FileSystemFileHandle-getFile.tentative.https.manual.window.js": [ - [ - "native-file-system/native_FileSystemFileHandle-getFile.tentative.https.manual.window.html", - { - "script_metadata": [ - [ - "script", - "/resources/testdriver.js" - ], - [ - "script", - "resources/test-helpers.js" - ], - [ - "script", - "resources/native-fs-test-helpers.js" - ], - [ - "script", - "script-tests/FileSystemFileHandle-getFile.js" - ] - ] - } - ] - ], - "native-file-system/native_FileSystemWritableFileStream-piped.tentative.https.manual.window.js": [ - [ - "native-file-system/native_FileSystemWritableFileStream-piped.tentative.https.manual.window.html", - { - "script_metadata": [ - [ - "script", - "/resources/testdriver.js" - ], - [ - "script", - "resources/test-helpers.js" - ], - [ - "script", - "resources/native-fs-test-helpers.js" - ], - [ - "script", - "script-tests/FileSystemWritableFileStream-piped.js" - ] - ] - } - ] - ], - "native-file-system/native_FileSystemWritableFileStream-write.tentative.https.manual.window.js": [ - [ - "native-file-system/native_FileSystemWritableFileStream-write.tentative.https.manual.window.html", - { - "script_metadata": [ - [ - "script", - "/resources/testdriver.js" - ], - [ - "script", - "resources/test-helpers.js" - ], - [ - "script", - "resources/native-fs-test-helpers.js" - ], - [ - "script", - "script-tests/FileSystemWritableFileStream-write.js" - ] - ] - } - ] - ], - "native-file-system/native_FileSystemWritableFileStream.tentative.https.manual.window.js": [ - [ - "native-file-system/native_FileSystemWritableFileStream.tentative.https.manual.window.html", - { - "script_metadata": [ - [ - "script", - "/resources/testdriver.js" - ], - [ - "script", - "resources/test-helpers.js" - ], - [ - "script", - "resources/native-fs-test-helpers.js" - ], - [ - "script", - "script-tests/FileSystemWritableFileStream.js" - ] - ] - } - ] - ], - "native-file-system/native_FileSystemWriter.tentative.https.manual.window.js": [ - [ - "native-file-system/native_FileSystemWriter.tentative.https.manual.window.html", - { - "script_metadata": [ - [ - "script", - "/resources/testdriver.js" - ], - [ - "script", - "resources/test-helpers.js" - ], - [ - "script", - "resources/native-fs-test-helpers.js" - ], - [ - "script", - "script-tests/FileSystemWriter.js" - ] - ] - } - ] - ], "native-file-system/opaque-origin.https.window.js": [ [ "native-file-system/opaque-origin.https.window.html", @@ -349654,7 +349430,7 @@ "testharness" ], "client-hints/accept-ch-stickiness/resources/accept-ch-test.js": [ - "ed635513fd70f20ec2c5b51fd88a4b0380b77190", + "0ee5059cb677090c65cdb8b5cade69df7578f901", "support" ], "client-hints/accept-ch-stickiness/resources/accept-ch.html": [ @@ -349662,7 +349438,7 @@ "support" ], "client-hints/accept-ch-stickiness/resources/accept-ch.html.headers": [ - "370f9869226db4bdf8785c876b13d69b415e5abf", + "3f073bfe613cef20e7d9e99761f68ee732bc8802", "support" ], "client-hints/accept-ch-stickiness/resources/clear-site-data.html": [ @@ -350122,7 +349898,7 @@ "support" ], "common/security-features/tools/generate.py": [ - "3c298b5a3e20216f822b420d3460e1bea48e22d5", + "ba997067b3f44640fec79fac9cea10a79ae982af", "support" ], "common/security-features/tools/spec_validator.py": [ @@ -350146,7 +349922,7 @@ "support" ], "common/security-features/tools/util.py": [ - "269f464a547c7d1d23ba88527a55b9767e814304", + "f31029644ddf0e356735f88450d9200238e6737c", "support" ], "common/slow.py": [ @@ -353086,7 +352862,7 @@ "support" ], "content-security-policy/support/checkReport.sub.js": [ - "1ecfa5f52c481cf3ba98236bc21104b33fcdac84", + "3137b926ae8bf41ec37a183e1b6e3be70f5a1143", "support" ], "content-security-policy/support/dedicated-worker-helper.js": [ @@ -371618,7 +371394,7 @@ "testharness" ], "css/css-animations/keyframes-remove-documentElement-crash.html": [ - "aba7f9c6edd71d4a2b9446fb6de890866c41da64", + "9573ce1b0f8d1a413c0fb609207c5d98350053d6", "crashtest" ], "css/css-animations/parsing/animation-computed.html": [ @@ -402417,6 +402193,14 @@ "d45c76696eca826456988d7884adcaa52bfad9cd", "reftest" ], + "css/css-pseudo/marker-computed-size-expected.txt": [ + "6ddc9e65a7640bf2e865f59fefe168ae328aa5f7", + "support" + ], + "css/css-pseudo/marker-computed-size.html": [ + "76851369ab56b7d4eea9c38339f087092ce22f26", + "testharness" + ], "css/css-pseudo/marker-content-001-ref.html": [ "e2c2daa1761563dc6b74ac3bc1bd0de05ff3766a", "support" @@ -403805,10 +403589,6 @@ "5b1fd800790c4e14ec8fbc34bd24eb6c2eb31ab0", "testharness" ], - "css/css-shadow-parts/multiple-parts-expected.txt": [ - "c3a5d4def8b46a31f02df2ff710e4837061eaf0c", - "support" - ], "css/css-shadow-parts/multiple-parts.html": [ "de02a26e164d283e4f05a0d8eba0f6b98c778700", "testharness" @@ -403821,6 +403601,10 @@ "9905cf8b5e46b51dc21326dc31f8c2bc6d7a39b6", "testharness" ], + "css/css-shadow-parts/serialization.html": [ + "50ad3df53a33a3c3ae24d4130356619c8d02d182", + "testharness" + ], "css/css-shadow-parts/simple-forward-shorthand.html": [ "0142967dfdb707a376b86e5347465117033cda01", "testharness" @@ -434286,7 +434070,7 @@ "testharness" ], "css/cssom/selectorSerialize.html": [ - "e95f453ba1c9494d5ff9bc3a602217106fc5174a", + "f3a402f5f079fd33683e44157a996df7daa4eec0", "testharness" ], "css/cssom/selectorText-modification-restyle-001-ref.html": [ @@ -438458,7 +438242,7 @@ "testharness" ], "css/selectors/webkit-pseudo-element.html": [ - "8b4adddba8f2797512791421910ded22c00c8be2", + "5ba98eba21b60e1efa364a8c98dfd0da1983316f", "testharness" ], "css/selectors/x-pseudo-element.html": [ @@ -444449,34 +444233,18 @@ "713555b7d8ab6117d12c70d08185335246e44e1a", "testharness" ], - "dom/events/webkit-animation-end-event-expected.txt": [ - "69527eb7283ddd0e7291d93736a7b2cdba233f74", - "support" - ], "dom/events/webkit-animation-end-event.html": [ "4186f6b7a9d2415f7df6174b7b5ea9e42c550bae", "testharness" ], - "dom/events/webkit-animation-iteration-event-expected.txt": [ - "80fe919f5274d2854ad06c4fca88b5445ac60393", - "support" - ], "dom/events/webkit-animation-iteration-event.html": [ "e6e7ec1459036870424300541612cdf48bb7f8dd", "testharness" ], - "dom/events/webkit-animation-start-event-expected.txt": [ - "c79feb7226beabf65924789fecb9894084c142f0", - "support" - ], "dom/events/webkit-animation-start-event.html": [ "ad1036644a96e15956d5159b886ca7879a916204", "testharness" ], - "dom/events/webkit-transition-end-event-expected.txt": [ - "b98ba4a7562be3562a99a32e10e4e7dd231570ff", - "support" - ], "dom/events/webkit-transition-end-event.html": [ "2741824e3054a2b4fa41d0cfe33488e7a3cdd3ae", "testharness" @@ -457450,7 +457218,7 @@ "support" ], "html/cross-origin-embedder-policy/blob.https.html": [ - "aa4cf969d9e0fe369ce812896e6eb8d13cb02377", + "77af2bc77de3301bcee344cdfbec6b5761c2e89f", "testharness" ], "html/cross-origin-embedder-policy/blob.https.html.headers": [ @@ -457621,6 +457389,22 @@ "3f080c82d25de71d899d3b3011afcc3c553fb2a2", "support" ], + "html/cross-origin-opener-policy/blob-popup.https.html": [ + "4aef1b848917c1f2901eb696a39d5d7f1369a063", + "testharness" + ], + "html/cross-origin-opener-policy/blob-popup.https.html.headers": [ + "46ad58d83bf6e98913ca4c564b7acb8f19fa0093", + "support" + ], + "html/cross-origin-opener-policy/coep-blob-popup.https.html": [ + "c66988d0a659b1c0cf00bd88e06f3b2c3dded975", + "testharness" + ], + "html/cross-origin-opener-policy/coep-blob-popup.https.html.headers": [ + "63b60e490f47f4db77d33d7a4ca2f5b9a4181de8", + "support" + ], "html/cross-origin-opener-policy/coep-navigate-popup.https-expected.txt": [ "992d30596ec1d4cd13ca55af2660f3c66b9a245f", "support" @@ -457801,6 +457585,42 @@ "34bd099a302f893f92586241ea38aac812bf28d0", "support" ], + "html/cross-origin-opener-policy/iframe-popup-same-origin-allow-popups.https-expected.txt": [ + "2a5f69085de9fc47352a4115b2986dbb22d88889", + "support" + ], + "html/cross-origin-opener-policy/iframe-popup-same-origin-allow-popups.https.html": [ + "0c33b40b181b6f6258614e8f30794926d61ddf6b", + "testharness" + ], + "html/cross-origin-opener-policy/iframe-popup-same-origin-allow-popups.https.html.headers": [ + "d83ed86fb9b5d159b9f380424887402edc96cb75", + "support" + ], + "html/cross-origin-opener-policy/iframe-popup-same-origin.https-expected.txt": [ + "fadc943d541061f2bac08de6d8f1d71af530003f", + "support" + ], + "html/cross-origin-opener-policy/iframe-popup-same-origin.https.html": [ + "2b7decd39cf8861b59788003d64bf84ce48ff984", + "testharness" + ], + "html/cross-origin-opener-policy/iframe-popup-same-origin.https.html.headers": [ + "46ad58d83bf6e98913ca4c564b7acb8f19fa0093", + "support" + ], + "html/cross-origin-opener-policy/iframe-popup-unsafe-none.https-expected.txt": [ + "4e74c996e573c20316a59f47e9635280592ac86d", + "support" + ], + "html/cross-origin-opener-policy/iframe-popup-unsafe-none.https.html": [ + "78a18118504bb9ad9a52b25bfc12059721708dd9", + "testharness" + ], + "html/cross-origin-opener-policy/iframe-popup-unsafe-none.https.html.headers": [ + "073ce7adfbd81cb7c0b2f91f96c8349b6677f26c", + "support" + ], "html/cross-origin-opener-policy/no-https-expected.txt": [ "9cd8ef4d5ac82b925031ad0a6bfe876cd26e05fc", "support" @@ -457986,13 +457806,17 @@ "support" ], "html/cross-origin-opener-policy/resources/common.js": [ - "477bc6c948f29cc18dc987e828eb5799b4a946ab", + "59ba33d65b04e26c1db810783b7fdcc96dee8954", "support" ], "html/cross-origin-opener-policy/resources/coop-coep.py": [ "e6f655ab728107e4bac31cd7748711f719b01bd3", "support" ], + "html/cross-origin-opener-policy/resources/iframe-popup.sub.html": [ + "748fd996cfbb5dceec670033308fa68502d70cb0", + "support" + ], "html/cross-origin-opener-policy/resources/postback.html": [ "cf3c93bbe1d3589e9a649db34995e02e2ac9c1e4", "support" @@ -459106,15 +458930,15 @@ "testharness" ], "html/dom/idlharness.https_exclude=(Document_Window_HTML._)-expected.txt": [ - "28ebb6d47a3820bcc9b2c92fc0b45f2df0fc7487", + "df23d7b9680096232149ddf0ba1a5efc64cfeeea", "support" ], "html/dom/idlharness.https_include=(Document_Window)-expected.txt": [ - "cae5ab4d3a7685ab6c82e8ddcd3bc0eaee93abfe", + "4d7c836aec650d40cb224f383b40761161e9ebb8", "support" ], "html/dom/idlharness.https_include=HTML._-expected.txt": [ - "a590e36fc57c60fa74a813d7cb828491584be1da", + "41796d8e7b22348f3ae6149f22b2deea2864f601", "support" ], "html/dom/idlharness.worker-expected.txt": [ @@ -474906,15 +474730,15 @@ "manual" ], "html/webappapis/scripting/events/event-handler-all-global-events-expected.txt": [ - "ecf299baccef3442e58eeaf0e20dc2e2762d15cd", + "869e4682f266ed725252c0ab3f8023e8985037f0", "support" ], "html/webappapis/scripting/events/event-handler-all-global-events.html": [ - "caeac8e8a50d29db7b9a50b7cb6069e76f5d7d0b", + "ee8c34ced313f5406992a1f3dc02edeba41e4f0e", "testharness" ], "html/webappapis/scripting/events/event-handler-attributes-body-window-expected.txt": [ - "69c88f095d8b50b60680d7523bac058d1b64233e", + "53af10eb2c754850c0a11bb4dc94082c9ade27cf", "support" ], "html/webappapis/scripting/events/event-handler-attributes-body-window.html": [ @@ -474922,7 +474746,7 @@ "testharness" ], "html/webappapis/scripting/events/event-handler-attributes-frameset-window-expected.txt": [ - "d0258b802be5d06fa3480277a2392e7a9caf6159", + "386945529da2d85f61e7a62347d73df430d65f63", "support" ], "html/webappapis/scripting/events/event-handler-attributes-frameset-window.html": [ @@ -474934,7 +474758,7 @@ "support" ], "html/webappapis/scripting/events/event-handler-attributes-windowless-body-expected.txt": [ - "d69136c7d99429eab349fec3e29d4cc32d6a56fc", + "39174d9f81539beea77a023243faf9e11d6ee42a", "support" ], "html/webappapis/scripting/events/event-handler-attributes-windowless-body.html": [ @@ -475962,15 +475786,23 @@ "support" ], "import-maps/common/README.md": [ - "cda42d06099f16f13e61e30394c230cbbb34f8c9", + "6092c0d767050d0c1b13cfd2360f7a7f17d656a5", "support" ], + "import-maps/common/parsing.tentative-expected.txt": [ + "f4617a5d94af55830694264c6af6c06205ff1877", + "support" + ], + "import-maps/common/parsing.tentative.html": [ + "d3334d7bbb9b4406397f96b596e71463eb252791", + "testharness" + ], "import-maps/common/resolving.tentative.html": [ "c947232e06322addc60a08004c1f21d317647042", "testharness" ], "import-maps/common/resources/common-test-helper.js": [ - "002c4b51fd06a6db7c07344a3267ae72aac8399e", + "0ddad9fe150b51f4017ea0ae203749ee299d4f57", "support" ], "import-maps/common/resources/data-base-url.json": [ @@ -475989,6 +475821,50 @@ "6b8f0135f50f50cd2691b5d4ee801d9671a3a2f9", "support" ], + "import-maps/common/resources/parsing-addresses-absolute.json": [ + "d392f8224faeb1606193d504188956dc39fadcdf", + "support" + ], + "import-maps/common/resources/parsing-addresses-invalid.json": [ + "7d6502a1bc485cf66f9cce34f6ba16ed6fa69f52", + "support" + ], + "import-maps/common/resources/parsing-addresses.json": [ + "d5bb54f0c8073d168798b400667ae4046d3d8a44", + "support" + ], + "import-maps/common/resources/parsing-invalid-json.json": [ + "1bd1c94e8947a9f5348354a22a67276e93e83ded", + "support" + ], + "import-maps/common/resources/parsing-schema-normalization.json": [ + "a330bb8799b68e277fbb6b9a202079c84e28d926", + "support" + ], + "import-maps/common/resources/parsing-schema-scope.json": [ + "04d09395c32dba689c661528224a8a2a12bc128d", + "support" + ], + "import-maps/common/resources/parsing-schema-specifier-map.json": [ + "926e7a1f5f73cdf0dbe7108e077b6648099314fd", + "support" + ], + "import-maps/common/resources/parsing-schema-toplevel.json": [ + "278cad2295c12a8bb2b615e118dc2c3785e58cc4", + "support" + ], + "import-maps/common/resources/parsing-scope-keys.json": [ + "4b2f1eeada92efc78048aabcf91f4fc886b1ace6", + "support" + ], + "import-maps/common/resources/parsing-specifier-keys.json": [ + "b2d9cf47fa08dac6b009b517775a7854d376ab13", + "support" + ], + "import-maps/common/resources/parsing-trailing-slashes.json": [ + "21e5faa13ec69c8b9ed70a49fc38940f86a067b3", + "support" + ], "import-maps/common/resources/scopes-exact-vs-prefix.json": [ "3d9d50349f0d644264ed257eb84854677c55fda6", "support" @@ -476081,42 +475957,6 @@ "101c33cf84e9fb5e68cf8d5910f4ffbe7949e9d7", "testharness" ], - "import-maps/imported/parsing-addresses.tentative.html": [ - "ddb3b724bb64e2edd60a620dc6ae1cc98f32a92a", - "testharness" - ], - "import-maps/imported/parsing-schema.tentative.html": [ - "6b7c0e5b0eb40eee9c8a415af5b1af87a4af3492", - "testharness" - ], - "import-maps/imported/parsing-scope-keys.tentative.html": [ - "601ac37720d700d3f68e3b2f6aeae3b06c112132", - "testharness" - ], - "import-maps/imported/parsing-specifier-keys.tentative.html": [ - "dd547f01d1dfb2379f6afa893385fadc8f1217d1", - "testharness" - ], - "import-maps/imported/resources/helpers/parsing.js": [ - "daad6d26d220bb0241f8a413816bd100f3af580d", - "support" - ], - "import-maps/imported/resources/parsing-addresses.js": [ - "92d7714ade9b965325372d58775bd990d3a1ce85", - "support" - ], - "import-maps/imported/resources/parsing-schema.js": [ - "f60422ae62bce21079cee8d6880cba0dc0dddaa5", - "support" - ], - "import-maps/imported/resources/parsing-scope-keys.js": [ - "4993f3a9a8bac441b883be55b58d40423114beab", - "support" - ], - "import-maps/imported/resources/parsing-specifier-keys.js": [ - "7ac24bf867b06a6393fbd1ef8e9478d28b2d714d", - "support" - ], "import-maps/resources/empty.js": [ "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", "support" @@ -477174,7 +477014,7 @@ "support" ], "interfaces/dom.idl": [ - "f7a10d890ab892e990bf9a81b87884e54089dcaa", + "ad62c7a59c6ef17b64fb2a0ef6b81c3aac0aa0df", "support" ], "interfaces/element-timing.idl": [ @@ -477482,7 +477322,7 @@ "support" ], "interfaces/wai-aria.idl": [ - "9cae4025d822dcaff47dd25b66dafa3c49a29c09", + "c4fbf11409cf142d8295038d256f5a686d860a55", "support" ], "interfaces/wake-lock.idl": [ @@ -477542,11 +477382,11 @@ "support" ], "interfaces/webrtc-identity.idl": [ - "d1f2a6547609ed1a9614ace180dd15027eb9c791", + "28b6a3b2b7f4acf78fde3889c75d6f8e97c8eb57", "support" ], "interfaces/webrtc-stats.idl": [ - "c5d00ac4462b24abf046cb05db294503bc90c677", + "d1a54898b9a62e85a3c1488704afe736058d5e93", "support" ], "interfaces/webrtc.idl": [ @@ -479750,11 +479590,11 @@ "testharness" ], "mathml/relations/html5-tree/math-global-event-handlers.tentative-expected.txt": [ - "b5ee241d57167a54bda79ff1bfe2b905c153d72f", + "0e9f4d3e39f3c39bac1b83d11022f71f22dc6bb6", "support" ], "mathml/relations/html5-tree/math-global-event-handlers.tentative.html": [ - "d77aa57741c378347d08ca6cd300841bd2194c40", + "7bbdee261105d91f74b0880cd045a35b641745bf", "testharness" ], "mathml/relations/html5-tree/required-extensions-2-ref.html": [ @@ -483810,7 +483650,7 @@ "support" ], "mixed-content/generic/spec_json.js": [ - "2f5212e9ff762d0f9e10a738120035beea618560", + "e49bbd91c9abcfdaccc51e0538f57734754728ba", "support" ], "mixed-content/generic/test-case.sub.js": [ @@ -483845,57 +483685,69 @@ "6905a68e7901ce26bc1a363062304e1536604400", "support" ], - "native-file-system/native_FileSystemBaseHandle-postMessage-BroadcastChannel.tentative.https.manual.window.js": [ - "4bfe84e9c4abf8738002168832fe59b7e6d72896", - "testharness" + "native-file-system/native_FileSystemBaseHandle-postMessage-BroadcastChannel-manual.https.tentative.html": [ + "322b169985bf40e2bac1dba813e840e951f89414", + "manual" ], - "native-file-system/native_FileSystemBaseHandle-postMessage-Error.tentative.https.manual.window.js": [ - "e45271c779341513de5a4400560012d68998f8dd", - "testharness" + "native-file-system/native_FileSystemBaseHandle-postMessage-Error-manual.https.tentative.html": [ + "a503c7e8702957ccc1dba0224bd38aeb3589003c", + "manual" ], - "native-file-system/native_FileSystemBaseHandle-postMessage-MessagePort.tentative.https.manual.window.js": [ - "408b32f13a317e060e88baee4ccca6a5f292a3a4", - "testharness" + "native-file-system/native_FileSystemBaseHandle-postMessage-MessagePort-manual.https.tentative.html": [ + "4b57576688171377b2296c4595917a5b7563b1fb", + "manual" ], - "native-file-system/native_FileSystemBaseHandle-postMessage.tentative.https.manual.window.js": [ - "6045812bff57037de8b1f4972059e8d8e0ee06db", - "testharness" + "native-file-system/native_FileSystemBaseHandle-postMessage-manual.https.tentative.html": [ + "266238c4acc269b4a29b0f849f1807172ce3dd72", + "manual" ], - "native-file-system/native_FileSystemDirectoryHandle-getDirectory.tentative.https.manual.window.js": [ - "cfe729cd1f1dd4b53f00b3b13cd53f64f84ca409", - "testharness" + "native-file-system/native_FileSystemDirectoryHandle-getDirectory-manual.https.tentative-expected.txt": [ + "92bf4bbe5d0fd324fc569822e5295969aa10d4a2", + "support" ], - "native-file-system/native_FileSystemDirectoryHandle-getEntries.tentative.https.manual.window.js": [ - "f27a44d12459cccbbe7192fe13104d77c68795ae", - "testharness" + "native-file-system/native_FileSystemDirectoryHandle-getDirectory-manual.https.tentative.html": [ + "afd95af99d3bb0822ee00439d130c6602bf4643d", + "manual" ], - "native-file-system/native_FileSystemDirectoryHandle-getFile.tentative.https.manual.window.js": [ - "0455cb800919ee353b7f2e87bf47b76ba075519b", - "testharness" + "native-file-system/native_FileSystemDirectoryHandle-getEntries-manual.https.tentative.html": [ + "858bf02f1fa2f5fd2dd01acc96bac149a02896fe", + "manual" ], - "native-file-system/native_FileSystemDirectoryHandle-removeEntry.tentative.https.manual.window.js": [ - "8905a7afdea57c974a9a06790df6b9e692d32139", - "testharness" + "native-file-system/native_FileSystemDirectoryHandle-getFile-manual.https.tentative.html": [ + "085d4371c48271076deb04c3c399b0226cda14a8", + "manual" ], - "native-file-system/native_FileSystemFileHandle-getFile.tentative.https.manual.window.js": [ - "16c68c59b273663fb16847f121f38e03bb94cf19", - "testharness" + "native-file-system/native_FileSystemDirectoryHandle-removeEntry-manual.https.tentative.html": [ + "cedb87587cee3b68f4edf76060679407f61b3c59", + "manual" ], - "native-file-system/native_FileSystemWritableFileStream-piped.tentative.https.manual.window.js": [ - "2c0299df12e9577261cce2f68d12a1bf744158c2", - "testharness" + "native-file-system/native_FileSystemFileHandle-getFile-manual.https.tentative.html": [ + "5a0b1d97b05a48c178cf86e6c766565fa87a7ef0", + "manual" ], - "native-file-system/native_FileSystemWritableFileStream-write.tentative.https.manual.window.js": [ - "0efacf9e607d990bccf185b7d84d5f45220338d8", - "testharness" + "native-file-system/native_FileSystemWritableFileStream-manual.https.tentative.html": [ + "56ff51cd05a7e7088520ab0fbf77ff378a530b4f", + "manual" ], - "native-file-system/native_FileSystemWritableFileStream.tentative.https.manual.window.js": [ - "caf6fbd1c52a3cef603896f8ee98d9618e4dc92e", - "testharness" + "native-file-system/native_FileSystemWritableFileStream-piped-manual.https.tentative.html": [ + "f6c6e6009aadf2b4c37b7926dfcd06962701fefa", + "manual" ], - "native-file-system/native_FileSystemWriter.tentative.https.manual.window.js": [ - "25d8ee995857fa67be2c41f048e882ec473f739d", - "testharness" + "native-file-system/native_FileSystemWritableFileStream-write-manual.https.tentative-expected.txt": [ + "8695c8e7374fbcdfe424804ce4271b065428f0ba", + "support" + ], + "native-file-system/native_FileSystemWritableFileStream-write-manual.https.tentative.html": [ + "280edc27e5ad6f7a18e5f4c476a189efd6418e43", + "manual" + ], + "native-file-system/native_FileSystemWriter-manual.https.tentative-expected.txt": [ + "51ea575934f3e1a9b6eed9915e36ec2e7d95109d", + "support" + ], + "native-file-system/native_FileSystemWriter-manual.https.tentative.html": [ + "fbfbd301e1659a7fac5273507358e4f712b53b3c", + "manual" ], "native-file-system/opaque-origin.https.window.js": [ "2385c31a786a223e5cdc23856edd41a55af783b2", @@ -483934,7 +483786,7 @@ "support" ], "native-file-system/resources/native-fs-test-helpers.js": [ - "bcdfd484cf2b8b12632c964e2b60a390c03c4225", + "d8137c399408cdea10c4b7d473cae36f1c85265b", "support" ], "native-file-system/resources/opaque-origin-sandbox.html": [ @@ -484074,7 +483926,7 @@ "testharness" ], "navigation-timing/idlharness.window.js": [ - "8cc3546b3c27a9d93ee5621584d83d56a308513c", + "504453b9aff1e7b497c64955a98dc384817f1ba6", "testharness" ], "navigation-timing/nav2_data_uri.html": [ @@ -506118,7 +505970,7 @@ "support" ], "referrer-policy/generic/spec_json.js": [ - "cad5e79f1f8b80bdc54f2f8e861d821770b29721", + "27961c5de5c1b488e87dd52e1c79a5afa7070e7b", "support" ], "referrer-policy/generic/subresource-test/area-navigate.html": [ @@ -507758,7 +507610,7 @@ "testharness" ], "server-timing/idlharness.https.any.js": [ - "ded320f0f61f4de1132d5cfb76a7e74a16154f3c", + "b55c741df39e4766afd438daa9037b216b7780ad", "testharness" ], "server-timing/navigation_timing_idl.https.html": [ @@ -516494,7 +516346,7 @@ "support" ], "tools/gitignore/gitignore.py": [ - "d5ea4a6a8f3d64d4aba3b8dcbe5ffe849b74e969", + "0f3d9450d123449c0dcc3ff3c04ca86c81b24bef", "support" ], "tools/lint/__init__.py": [ @@ -516574,7 +516426,7 @@ "support" ], "tools/mypy.ini": [ - "ac8edd37d3ac2904133a12ee9e7550dd5a487238", + "b943b6d089a4b8f81e9b6e23c76880fb93cf665a", "support" ], "tools/py27-flake8.ini": [ @@ -525230,7 +525082,7 @@ "testharness" ], "upgrade-insecure-requests/generic/spec_json.js": [ - "89b17048e22f642255e67aa13bed9bdbecf01bec", + "822afa11397701de01572c7f039be75c9d6e060e", "support" ], "upgrade-insecure-requests/generic/test-case.sub.js": [ @@ -530134,11 +529986,11 @@ "support" ], "webrtc-identity/idlharness.https.window-expected.txt": [ - "74bc96f2f15e4a8a9f09e8901dcd8e9b0d90ddf0", + "432187d249ad1d9d05bb5bf659668253035dd036", "support" ], "webrtc-identity/idlharness.https.window.js": [ - "da1cb85a8e7ef147729d4a4f1a77493862dea48c", + "8c7bf665ef69487f396519e9e6b45a010854bb3a", "testharness" ], "webrtc-quic/META.yml": [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/keyframes-remove-documentElement-crash.html b/third_party/blink/web_tests/external/wpt/css/css-animations/keyframes-remove-documentElement-crash.html index aba7f9c6..9573ce1 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-animations/keyframes-remove-documentElement-crash.html +++ b/third_party/blink/web_tests/external/wpt/css/css-animations/keyframes-remove-documentElement-crash.html
@@ -1,8 +1,7 @@ <!doctype html> +<html class="test-wait"> <title>CSS Animations Test: Chrome crash when removing documentElement and @keyframes stylesheet</title> <link rel="help" href="https://crbug.com/999522"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> <style> @keyframes anim { from { color: pink } @@ -14,9 +13,16 @@ </style> <div></div> <script> - test(() => { - document.body.offsetTop; - document.querySelector("style").remove(); - document.documentElement.remove(); - }, "Removing documentElement and @keyframes sheet should not crash."); +window.addEventListener('load', () => { + document.body.offsetTop; + document.querySelector("style").remove(); + // We need the root later to remove the test-wait class. + const root = document.documentElement; + document.documentElement.remove(); + + // rAF to make sure that style runs. + requestAnimationFrame(() => { + root.classList.remove('test-wait'); + }); +}); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-layout-properties-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-layout-properties-expected.txt new file mode 100644 index 0000000..591d959d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-layout-properties-expected.txt
@@ -0,0 +1,144 @@ +This is a testharness.js-based test. +Found 140 tests; 119 PASS, 21 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS display: grid +PASS display: inline-grid +PASS grid-template-columns +PASS grid-template-columns.initial +PASS grid-template-columns.none +PASS grid-template-columns.<line-names> +PASS grid-template-columns.<track-size>.auto +PASS grid-template-columns.<track-size>.<track-breadth>.<length> +PASS grid-template-columns.<track-size>.<track-breadth>.<percentage> +PASS grid-template-columns.<track-size>.<track-breadth>.<flex> +PASS grid-template-columns.<track-size>.<track-breadth>.min-content +PASS grid-template-columns.<track-size>.<track-breadth>.max-content +PASS grid-template-columns.<track-size>.<track-breadth>.minmax() +PASS grid-template-columns.reset +PASS grid-template-rows +PASS grid-template-rows.initial +PASS grid-template-rows.none +PASS grid-template-rows.<line-names> +PASS grid-template-rows.<track-size>.auto +PASS grid-template-rows.<track-size>.<track-breadth>.<length> +PASS grid-template-rows.<track-size>.<track-breadth>.<percentage> +PASS grid-template-rows.<track-size>.<track-breadth>.<flex> +PASS grid-template-rows.<track-size>.<track-breadth>.min-content +PASS grid-template-rows.<track-size>.<track-breadth>.max-content +PASS grid-template-rows.<track-size>.<track-breadth>.minmax() +PASS grid-template-rows.reset +PASS grid-template-areas +PASS grid-template-areas.initial +PASS grid-template-areas.none +PASS grid-template-areas.<string>+ +PASS grid-template-areas.reset +PASS grid-template +FAIL grid-template.initial assert_equals: initial value of grid-template should be none expected "none" but got "none / none / none" +FAIL grid-template.none assert_equals: none expected "none" but got "none / none / none" +FAIL grid-template.<grid-template-rows> / <grid-template-columns> assert_equals: <grid-template-rows> / <grid-template-columns> expected "100px 100px / 200px 200px" but got "" +FAIL grid-template.<line-names> assert_equals: <line-names> expected "[a] auto [b] auto [c] / [d] auto [e] auto [f]" but got "" +FAIL grid-template.<string>+ assert_equals: <string>+ expected "\"a b\" \"a b\"" but got "" +FAIL grid-template.<string><track-size>+ assert_equals: <string><track-size>+ expected "100px / \"a b\" 50px" but got "" +FAIL grid-template.reset assert_equals: reset expected "none" but got "none / none / none" +PASS grid-auto-columns +PASS grid-auto-columns.initial +PASS grid-auto-columns.<track-size>.auto +PASS grid-auto-columns.<track-size>.<track-breadth>.<length> +PASS grid-auto-columns.<track-size>.<track-breadth>.<percentage> +PASS grid-auto-columns.<track-size>.<track-breadth>.<flex> +PASS grid-auto-columns.<track-size>.<track-breadth>.min-content +PASS grid-auto-columns.<track-size>.<track-breadth>.max-content +PASS grid-auto-columns.<track-size>.<track-breadth>.minmax() +PASS grid-auto-columns.reset +PASS grid-auto-rows +PASS grid-auto-rows.initial +PASS grid-auto-rows.<track-size>.auto +PASS grid-auto-rows.<track-size>.<track-breadth>.<length> +PASS grid-auto-rows.<track-size>.<track-breadth>.<percentage> +PASS grid-auto-rows.<track-size>.<track-breadth>.<flex> +PASS grid-auto-rows.<track-size>.<track-breadth>.min-content +PASS grid-auto-rows.<track-size>.<track-breadth>.max-content +PASS grid-auto-rows.<track-size>.<track-breadth>.minmax() +PASS grid-auto-rows.reset +PASS grid-auto-flow +PASS grid-auto-flow.initial +PASS grid-auto-flow.row +PASS grid-auto-flow.column +FAIL grid-auto-flow.dense assert_equals: dense expected "dense" but got "row dense" +FAIL grid-auto-flow.row dense assert_equals: row dense expected "dense" but got "row dense" +PASS grid-auto-flow.column dense +PASS grid-auto-flow.reset +PASS grid-row-start +PASS grid-row-start.initial +PASS grid-row-start.auto +PASS grid-row-start.<custom-ident> +PASS grid-row-start.<integer> +PASS grid-row-start.<integer> <ident> +PASS grid-row-start.span <integer> +PASS grid-row-start.span <custom-ident> +PASS grid-row-start.span <integer> <custom-ident> +PASS grid-row-start.reset +PASS grid-column-start +PASS grid-column-start.initial +PASS grid-column-start.auto +PASS grid-column-start.<custom-ident> +PASS grid-column-start.<integer> +PASS grid-column-start.<integer> <ident> +PASS grid-column-start.span <integer> +PASS grid-column-start.span <custom-ident> +PASS grid-column-start.span <integer> <custom-ident> +PASS grid-column-start.reset +PASS grid-row-end +PASS grid-row-end.initial +PASS grid-row-end.auto +PASS grid-row-end.<custom-ident> +PASS grid-row-end.<integer> +PASS grid-row-end.<integer> <ident> +PASS grid-row-end.span <integer> +PASS grid-row-end.span <custom-ident> +PASS grid-row-end.span <integer> <custom-ident> +PASS grid-row-end.reset +PASS grid-column-end +PASS grid-column-end.initial +PASS grid-column-end.auto +PASS grid-column-end.<custom-ident> +PASS grid-column-end.<integer> +PASS grid-column-end.<integer> <ident> +PASS grid-column-end.span <integer> +PASS grid-column-end.span <custom-ident> +PASS grid-column-end.span <integer> <custom-ident> +PASS grid-column-end.reset +PASS grid-column +FAIL grid-column.initial assert_equals: initial value of grid-column should be auto expected "auto" but got "auto / auto" +FAIL grid-column.auto assert_equals: auto expected "auto" but got "auto / auto" +PASS grid-column.<custom-ident> +FAIL grid-column.<integer> start assert_equals: <integer> start expected "1" but got "1 / auto" +PASS grid-column.<integer> +PASS grid-column.<integer> <ident> +PASS grid-column.span <integer> +PASS grid-column.span <custom-ident> +PASS grid-column.span <integer> <custom-ident> +FAIL grid-column.reset assert_equals: reset expected "auto" but got "auto / auto" +PASS grid-row +FAIL grid-row.initial assert_equals: initial value of grid-row should be auto expected "auto" but got "auto / auto" +FAIL grid-row.auto assert_equals: auto expected "auto" but got "auto / auto" +PASS grid-row.<custom-ident> +FAIL grid-row.<integer> start assert_equals: <integer> start expected "1" but got "1 / auto" +PASS grid-row.<integer> +PASS grid-row.<integer> <ident> +PASS grid-row.span <integer> +PASS grid-row.span <custom-ident> +PASS grid-row.span <integer> <custom-ident> +FAIL grid-row.reset assert_equals: reset expected "auto" but got "auto / auto" +PASS grid-area +FAIL grid-area.initial assert_equals: initial value of grid-area should be auto expected "auto" but got "auto / auto / auto / auto" +FAIL grid-area.auto assert_equals: auto expected "auto" but got "auto / auto / auto / auto" +PASS grid-area.<custom-ident> +FAIL grid-area.<integer> start assert_equals: <integer> start expected "1 / 2" but got "1 / 2 / auto / auto" +PASS grid-area.<integer> +PASS grid-area.<integer> <ident> +PASS grid-area.span <integer> +PASS grid-area.span <custom-ident> +PASS grid-area.span <integer> <custom-ident> +FAIL grid-area.reset assert_equals: reset expected "auto" but got "auto / auto / auto / auto" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-layout-properties.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-layout-properties.html index 7cdda674..a5376827e 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-layout-properties.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-layout-properties.html
@@ -97,7 +97,7 @@ '<line-names>': ['[a] auto [b] auto [c]', '[a] 50px [b] 50px [c]'], '<track-size>.auto': ['auto', '50px'], '<track-size>.<track-breadth>.<length>': ['100px', '100px'], - '<track-size>.<track-breadth>.<percentage>': ['100%', '50px'], + '<track-size>.<track-breadth>.<percentage>': ['100%', '150px'], '<track-size>.<track-breadth>.<flex>': ['1fr', '50px'], '<track-size>.<track-breadth>.min-content': ['min-content', '50px'], '<track-size>.<track-breadth>.max-content': ['max-content', '50px'], @@ -111,13 +111,13 @@ 'reset': ['none', 'none'], }, 'grid-template': { - initial: '150px / 50px 50px 50px', - 'none': ['', '150px / 50px 50px 50px'], + initial: 'none', + 'none': ['', 'none'], '<grid-template-rows> / <grid-template-columns>': ['100px 100px / 200px 200px', '100px 100px / 200px 200px'], '<line-names>': ['[a] auto [b] auto [c] / [d] auto [e] auto [f]', '[a] auto [b] auto [c] / [d] auto [e] auto [f]'], '<string>+': ['"a b" "a b"', '"a b" "a b"'], '<string><track-size>+': ['100px / "a b" 50px', '100px / "a b" 50px'], - 'reset': ['', '150px / 50px 50px 50px'], + 'reset': ['', 'none'], }, 'grid-auto-columns': { initial: 'auto',
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-area-valid-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-area-valid-expected.txt index d19e955..6ce291e 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-area-valid-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-area-valid-expected.txt
@@ -55,6 +55,6 @@ PASS e.style['grid-column'] = "2 j / span 3 k" should set the property value PASS e.style['grid-column-end'] = "\\31st" should set the property value PASS e.style['grid-column-end'] = "\\31 st" should set the property value -FAIL e.style['grid-column'] = "\\31st / \\31 st" should set the property value assert_in_array: serialization should be sound value "\\31 st / \31 st" not in array ["\\31 st", "\\31st"] +FAIL e.style['grid-column'] = "\\31st / \\31 st" should set the property value assert_in_array: serialization should be sound value "\\31 st / \\31 st" not in array ["\\31 st", "\\31st"] Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/blob.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/blob.https.html index aa4cf96..77af2bc7 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/blob.https.html +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/blob.https.html
@@ -28,14 +28,13 @@ t.add_cleanup(() => { frame.remove(); }); const path = new URL("resources/blob-url-factory.html", window.location).pathname; frame.src = `${origin}${path}?id=${id}&variant=${variant}&crossOrigin=${crossOrigin}`; - window.addEventListener("message", t.step_func(({ data }) => { + window.addEventListener("message", t.step_func_done(({ data }) => { if (data.id !== id) { return; } assert_equals(data.origin, origin); assert_true(data.sameOriginNoCORPSuccess, "Same-origin without CORP did not succeed"); assert_true(data.crossOriginNoCORPFailure, "Cross-origin without CORP did not fail"); - t.done(); })); document.body.append(frame); }, `Cross-Origin-Embedder-Policy and blob: URL from ${origin} in subframe via ${variant}`);
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/blob-popup.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/blob-popup.https.html new file mode 100644 index 0000000..4aef1b8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/blob-popup.https.html
@@ -0,0 +1,39 @@ +<!doctype html> +<title>Cross-Origin-Opener-Policy and a blob URL popup</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src=/common/get-host-info.sub.js></script> +<script src="/common/utils.js"></script> +<script> +async_test(t => { + window.test = t; // Make the test available globally so the blob URL can use it + window.furtherPopup = null; + + const bc = new BroadcastChannel(token()); + bc.onmessage = t.step_func_done(({ data }) => { + assert_equals(data.name, ""); + assert_false(data.opener); + assert_true(furtherPopup.closed); + assert_equals(furtherPopup.document.URL, "about:blank"); + }); + + const blobContents = `<script> +const w = window.open("${get_host_info().HTTPS_REMOTE_ORIGIN}/html/cross-origin-opener-policy/resources/coop-coep.py?coop=x&coep=x&channel=${bc.name}", "${bc.name}"); +window.opener.furtherPopup = w; + +// w will be closed by its postback iframe. When out of process, +// window.close() does not work. +window.opener.test.add_cleanup(() => w.close()); +<\/script>`; + const blob = new Blob([blobContents], { type: "text/html" }); + const blobURL = URL.createObjectURL(blob); + const popup = window.open(blobURL); + t.add_cleanup(() => popup.close()); + popup.onload = t.step_func(() => { + assert_equals(popup.opener, window); + assert_equals(popup.location.href, blobURL); + assert_equals(popup.document.URL, blobURL); + assert_equals(popup.origin, window.origin); + }); +}); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/blob-popup.https.html.headers b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/blob-popup.https.html.headers new file mode 100644 index 0000000..46ad58d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/blob-popup.https.html.headers
@@ -0,0 +1 @@ +Cross-Origin-Opener-Policy: same-origin
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep-blob-popup.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep-blob-popup.https.html new file mode 100644 index 0000000..c66988d0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep-blob-popup.https.html
@@ -0,0 +1,45 @@ +<!doctype html> +<title>Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy: blob URL popup</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src=/common/get-host-info.sub.js></script> +<script src=../cross-origin-embedder-policy/resources/script-factory.js></script> +<script> +["window.open()", "<a>", "<a rel=noopener>"].forEach(type => { + promise_test(t => { + const origins = get_host_info(); + const id = `tut mir leid ${type}`; + const blob = new Blob([createScript(origins.ORIGIN, origins.HTTPS_REMOTE_ORIGIN, "opener", id)], {type: "text/html"}); + const blobURL = URL.createObjectURL(blob); + + if (type === "window.open()") { + const popup = window.open(blobURL); + t.add_cleanup(() => popup.close()); + popup.onload = t.step_func(() => { + assert_equals(popup.opener, window); + assert_equals(popup.location.href, blobURL); + assert_equals(popup.document.URL, blobURL); + assert_equals(popup.origin, window.origin); + }); + } else { + const a = document.createElement("a"); + a.target = type; + if (type === "<a rel=noopener>") { + a.rel = "noopener"; + } + a.href = blobURL; + a.click(); + } + + return new Promise(resolve => { + window.addEventListener("message", t.step_func(({ data }) => { + assert_equals(data.id, id); + assert_equals(data.origin, window.origin); + assert_true(data.sameOriginNoCORPSuccess, "Same-origin without CORP did not succeed"); + assert_true(data.crossOriginNoCORPFailure, "Cross-origin without CORP did not fail"); + resolve(); + })); + }); + }, `COOP+COEP blob URL popup: ${type}`); +}); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep-blob-popup.https.html.headers b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep-blob-popup.https.html.headers new file mode 100644 index 0000000..63b60e4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep-blob-popup.https.html.headers
@@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/dom.idl b/third_party/blink/web_tests/external/wpt/interfaces/dom.idl index f7a10d8..ad62c7a 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/dom.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/dom.idl
@@ -52,7 +52,7 @@ readonly attribute any detail; - void initCustomEvent(DOMString type, optional boolean bubbles = false, optional boolean cancelable = false, optional any detail = null); + void initCustomEvent(DOMString type, optional boolean bubbles = false, optional boolean cancelable = false, optional any detail = null); // historical }; dictionary CustomEventInit : EventInit { @@ -289,7 +289,7 @@ [NewObject] Attr createAttribute(DOMString localName); [NewObject] Attr createAttributeNS(DOMString? namespace, DOMString qualifiedName); - [NewObject] Event createEvent(DOMString interface); + [NewObject] Event createEvent(DOMString interface); // historical [NewObject] Range createRange();
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/wai-aria.idl b/third_party/blink/web_tests/external/wpt/interfaces/wai-aria.idl index 9cae4025..c4fbf11 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/wai-aria.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/wai-aria.idl
@@ -21,7 +21,7 @@ attribute FrozenArray<Element>? ariaControlsElements; attribute DOMString? ariaCurrent; attribute FrozenArray<Element>? ariaDescribedByElements; - attribute Element? ariaDetailsElements; + attribute Element? ariaDetailsElement; attribute DOMString? ariaDisabled; attribute Element? ariaErrorMessageElement; attribute DOMString? ariaExpanded;
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webrtc-identity.idl b/third_party/blink/web_tests/external/wpt/interfaces/webrtc-identity.idl index d1f2a654..28b6a3b2 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/webrtc-identity.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/webrtc-identity.idl
@@ -49,6 +49,10 @@ readonly attribute DOMString? idpErrorInfo; }; +partial dictionary RTCConfiguration { + DOMString peerIdentity; +}; + dictionary RTCIdentityProviderOptions { DOMString protocol = "default"; DOMString usernameHint; @@ -62,6 +66,29 @@ attribute DOMString name; }; +partial interface RTCError { + readonly attribute long? httpRequestStatusCode; +}; + +partial dictionary RTCErrorInit { + long httpRequestStatusCode; +}; + +// This is an extension of RTCErrorDetailType from [[WEBRTC-PC]] +// Unfortunately, WebIDL does not support partial enums (yet). +// +// partial enum RTCErrorDetailType { +enum RTCErrorDetailTypeIdp { + "idp-bad-script-failure", + "idp-execution-failure", + "idp-load-failure", + "idp-need-login", + "idp-timeout", + "idp-tls-failure", + "idp-token-expired", + "idp-token-invalid", +}; + partial dictionary MediaStreamConstraints { DOMString peerIdentity; };
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webrtc-stats.idl b/third_party/blink/web_tests/external/wpt/interfaces/webrtc-stats.idl index c5d00ac..d1a5489 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/webrtc-stats.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/webrtc-stats.idl
@@ -241,9 +241,6 @@ DOMString mediaSourceId; }; -dictionary RTCSenderVideoTrackAttachmentStats : RTCVideoSenderStats { -}; - dictionary RTCVideoReceiverStats : RTCVideoHandlerStats { }; @@ -254,9 +251,6 @@ DOMString mediaSourceId; }; -dictionary RTCSenderAudioTrackAttachmentStats : RTCAudioSenderStats { -}; - dictionary RTCAudioReceiverStats : RTCAudioHandlerStats { }; @@ -366,6 +360,12 @@ sequence<DOMString> trackIds; }; +dictionary RTCSenderVideoTrackAttachmentStats : RTCVideoSenderStats { +}; + +dictionary RTCSenderAudioTrackAttachmentStats : RTCAudioSenderStats { +}; + dictionary RTCReceiverVideoTrackAttachmentStats : RTCVideoReceiverStats {}; dictionary RTCReceiverAudioTrackAttachmentStats : RTCAudioReceiverStats {};
diff --git a/third_party/blink/web_tests/external/wpt/mimesniff/mime-types/parsing.any-expected.txt b/third_party/blink/web_tests/external/wpt/mimesniff/mime-types/parsing.any-expected.txt index 2ab64f8..6d8d4429 100644 --- a/third_party/blink/web_tests/external/wpt/mimesniff/mime-types/parsing.any-expected.txt +++ b/third_party/blink/web_tests/external/wpt/mimesniff/mime-types/parsing.any-expected.txt
@@ -21,8 +21,8 @@ FAIL text/html; charset=gbk (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html; charset=gbk" FAIL text/html;charset= gbk (Blob/File) assert_equals: Blob expected "text/html;charset=\" gbk\"" but got "text/html;charset= gbk" FAIL text/html;charset= gbk (Request/Response) assert_equals: expected "text/html;charset=\" gbk\"" but got "text/html;charset= gbk" -FAIL text/html;charset= "gbk" (Blob/File) assert_equals: Blob expected "text/html;charset=\" \\\"gbk\\"\"" but got "text/html;charset= \"gbk\"" -FAIL text/html;charset= "gbk" (Request/Response) assert_equals: expected "text/html;charset=\" \\\"gbk\\"\"" but got "text/html;charset= \"gbk\"" +FAIL text/html;charset= "gbk" (Blob/File) assert_equals: Blob expected "text/html;charset=\" \\\"gbk\\\"\"" but got "text/html;charset= \"gbk\"" +FAIL text/html;charset= "gbk" (Request/Response) assert_equals: expected "text/html;charset=\" \\\"gbk\\\"\"" but got "text/html;charset= \"gbk\"" FAIL text/html;charset=gbk (Blob/File) assert_equals: Blob expected "text/html" but got "" FAIL text/html;charset=gbk (Request/Response) assert_equals: expected "text/html" but got "" FAIL text/html;charset=gbk (Blob/File) assert_equals: Blob expected "text/html" but got "" @@ -67,8 +67,8 @@ PASS text/html;charset="gbk " (Request/Response) FAIL text/html;charset="\ gbk" (Blob/File) assert_equals: Blob expected "text/html;charset=\" gbk\"" but got "text/html;charset=\"\\ gbk\"" FAIL text/html;charset="\ gbk" (Request/Response) assert_equals: expected "text/html;charset=\" gbk\"" but got "text/html;charset=\"\\ gbk\"" -FAIL text/html;charset="\g\b\k" (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html;charset=\"\\g\b\k\"" -FAIL text/html;charset="\g\b\k" (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html;charset=\"\\g\b\k\"" +FAIL text/html;charset="\g\b\k" (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html;charset=\"\\g\\b\\k\"" +FAIL text/html;charset="\g\b\k" (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html;charset=\"\\g\\b\\k\"" FAIL text/html;charset="gbk"x (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html;charset=\"gbk\"x" FAIL text/html;charset="gbk"x (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html;charset=\"gbk\"x" FAIL text/html;charset="";charset=GBK (Blob/File) assert_equals: Blob expected "text/html;charset=\"\"" but got "text/html;charset=\"\";charset=gbk" @@ -83,12 +83,12 @@ PASS 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789/0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 (Request/Response) FAIL !#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz;!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz (Blob/File) assert_equals: Blob expected "!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz;!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz=!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" but got "!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz;!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz=!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" FAIL !#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz;!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz (Request/Response) assert_equals: expected "!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz;!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz=!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" but got "!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz;!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz=!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" -FAIL x/x;x=" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" (Blob/File) assert_equals: Blob expected "x/x;x=\"\t !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ\"" but got "" -FAIL x/x;x=" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" (Request/Response) assert_equals: expected "x/x;x=\"\t !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ\"" but got "" +FAIL x/x;x=" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" (Blob/File) assert_equals: Blob expected "x/x;x=\"\t !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ\"" but got "" +FAIL x/x;x=" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" (Request/Response) assert_equals: expected "x/x;x=\"\t !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ\"" but got "" FAIL x/x;test (Blob/File) assert_equals: Blob expected "x/x" but got "x/x;test" FAIL x/x;test (Request/Response) assert_equals: expected "x/x" but got "x/x;test" -FAIL x/x;test="\ (Blob/File) assert_equals: Blob expected "x/x;test=\"\\\\"" but got "x/x;test=\"\\" -FAIL x/x;test="\ (Request/Response) assert_equals: expected "x/x;test=\"\\\\"" but got "x/x;test=\"\\" +FAIL x/x;test="\ (Blob/File) assert_equals: Blob expected "x/x;test=\"\\\\\"" but got "x/x;test=\"\\" +FAIL x/x;test="\ (Request/Response) assert_equals: expected "x/x;test=\"\\\\\"" but got "x/x;test=\"\\" FAIL x/x;x= (Blob/File) assert_equals: Blob expected "x/x" but got "x/x;x= " FAIL x/x;x= (Request/Response) assert_equals: expected "x/x" but got "x/x;x=" FAIL x/x;x= (Blob/File) assert_equals: Blob expected "x/x" but got ""
diff --git a/third_party/blink/web_tests/external/wpt/mimesniff/mime-types/parsing.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/mimesniff/mime-types/parsing.any.worker-expected.txt index 2ab64f8..6d8d4429 100644 --- a/third_party/blink/web_tests/external/wpt/mimesniff/mime-types/parsing.any.worker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/mimesniff/mime-types/parsing.any.worker-expected.txt
@@ -21,8 +21,8 @@ FAIL text/html; charset=gbk (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html; charset=gbk" FAIL text/html;charset= gbk (Blob/File) assert_equals: Blob expected "text/html;charset=\" gbk\"" but got "text/html;charset= gbk" FAIL text/html;charset= gbk (Request/Response) assert_equals: expected "text/html;charset=\" gbk\"" but got "text/html;charset= gbk" -FAIL text/html;charset= "gbk" (Blob/File) assert_equals: Blob expected "text/html;charset=\" \\\"gbk\\"\"" but got "text/html;charset= \"gbk\"" -FAIL text/html;charset= "gbk" (Request/Response) assert_equals: expected "text/html;charset=\" \\\"gbk\\"\"" but got "text/html;charset= \"gbk\"" +FAIL text/html;charset= "gbk" (Blob/File) assert_equals: Blob expected "text/html;charset=\" \\\"gbk\\\"\"" but got "text/html;charset= \"gbk\"" +FAIL text/html;charset= "gbk" (Request/Response) assert_equals: expected "text/html;charset=\" \\\"gbk\\\"\"" but got "text/html;charset= \"gbk\"" FAIL text/html;charset=gbk (Blob/File) assert_equals: Blob expected "text/html" but got "" FAIL text/html;charset=gbk (Request/Response) assert_equals: expected "text/html" but got "" FAIL text/html;charset=gbk (Blob/File) assert_equals: Blob expected "text/html" but got "" @@ -67,8 +67,8 @@ PASS text/html;charset="gbk " (Request/Response) FAIL text/html;charset="\ gbk" (Blob/File) assert_equals: Blob expected "text/html;charset=\" gbk\"" but got "text/html;charset=\"\\ gbk\"" FAIL text/html;charset="\ gbk" (Request/Response) assert_equals: expected "text/html;charset=\" gbk\"" but got "text/html;charset=\"\\ gbk\"" -FAIL text/html;charset="\g\b\k" (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html;charset=\"\\g\b\k\"" -FAIL text/html;charset="\g\b\k" (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html;charset=\"\\g\b\k\"" +FAIL text/html;charset="\g\b\k" (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html;charset=\"\\g\\b\\k\"" +FAIL text/html;charset="\g\b\k" (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html;charset=\"\\g\\b\\k\"" FAIL text/html;charset="gbk"x (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html;charset=\"gbk\"x" FAIL text/html;charset="gbk"x (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html;charset=\"gbk\"x" FAIL text/html;charset="";charset=GBK (Blob/File) assert_equals: Blob expected "text/html;charset=\"\"" but got "text/html;charset=\"\";charset=gbk" @@ -83,12 +83,12 @@ PASS 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789/0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 (Request/Response) FAIL !#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz;!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz (Blob/File) assert_equals: Blob expected "!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz;!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz=!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" but got "!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz;!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz=!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" FAIL !#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz;!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz (Request/Response) assert_equals: expected "!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz;!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz=!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" but got "!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz;!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz=!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" -FAIL x/x;x=" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" (Blob/File) assert_equals: Blob expected "x/x;x=\"\t !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ\"" but got "" -FAIL x/x;x=" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" (Request/Response) assert_equals: expected "x/x;x=\"\t !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ\"" but got "" +FAIL x/x;x=" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" (Blob/File) assert_equals: Blob expected "x/x;x=\"\t !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ\"" but got "" +FAIL x/x;x=" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" (Request/Response) assert_equals: expected "x/x;x=\"\t !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ\"" but got "" FAIL x/x;test (Blob/File) assert_equals: Blob expected "x/x" but got "x/x;test" FAIL x/x;test (Request/Response) assert_equals: expected "x/x" but got "x/x;test" -FAIL x/x;test="\ (Blob/File) assert_equals: Blob expected "x/x;test=\"\\\\"" but got "x/x;test=\"\\" -FAIL x/x;test="\ (Request/Response) assert_equals: expected "x/x;test=\"\\\\"" but got "x/x;test=\"\\" +FAIL x/x;test="\ (Blob/File) assert_equals: Blob expected "x/x;test=\"\\\\\"" but got "x/x;test=\"\\" +FAIL x/x;test="\ (Request/Response) assert_equals: expected "x/x;test=\"\\\\\"" but got "x/x;test=\"\\" FAIL x/x;x= (Blob/File) assert_equals: Blob expected "x/x" but got "x/x;x= " FAIL x/x;x= (Request/Response) assert_equals: expected "x/x" but got "x/x;x=" FAIL x/x;x= (Blob/File) assert_equals: Blob expected "x/x" but got ""
diff --git a/third_party/blink/web_tests/external/wpt/referrer-policy/generic/inheritance/iframe-inheritance-data-expected.txt b/third_party/blink/web_tests/external/wpt/referrer-policy/generic/inheritance/iframe-inheritance-data-expected.txt deleted file mode 100644 index 8b4d672..0000000 --- a/third_party/blink/web_tests/external/wpt/referrer-policy/generic/inheritance/iframe-inheritance-data-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL iframes with data url uses no referrer assert_equals: expected (undefined) undefined but got (string) "FAILURE" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/referrer-policy/generic/inheritance/iframe-inheritance-data.html b/third_party/blink/web_tests/external/wpt/referrer-policy/generic/inheritance/iframe-inheritance-data.html index 0a45bb3..368e77e 100644 --- a/third_party/blink/web_tests/external/wpt/referrer-policy/generic/inheritance/iframe-inheritance-data.html +++ b/third_party/blink/web_tests/external/wpt/referrer-policy/generic/inheritance/iframe-inheritance-data.html
@@ -24,7 +24,7 @@ `data:text/html,<script src = "${BASE}/common/security-features/resources/common.sub.js"></` + `script> <script src = "${BASE}/referrer-policy/generic/referrer-policy-test-case.js"></` + `script> <script> - var urlPath = "/referrer-policy/generic/subresource/xhr.py"; + var urlPath = "/common/security-features/subresource/xhr.py"; var url = "${BASE}" + urlPath; requestViaXhr(url).then((msg) => { parent.postMessage({referrer: msg.referrer}, "*")})
diff --git a/third_party/blink/web_tests/external/wpt/resources/chromium/webxr-test.js b/third_party/blink/web_tests/external/wpt/resources/chromium/webxr-test.js index 54788b4..ca62754 100644 --- a/third_party/blink/web_tests/external/wpt/resources/chromium/webxr-test.js +++ b/third_party/blink/web_tests/external/wpt/resources/chromium/webxr-test.js
@@ -551,8 +551,11 @@ // Mojo function implementations. + _injectAdditionalFrameData(options, frameData) { + } + // XRFrameDataProvider implementation. - getFrameData() { + getFrameData(options) { let mojo_space_reset = this.send_mojo_space_reset_; this.send_mojo_space_reset_ = false; if (this.pose_) { @@ -577,18 +580,21 @@ now += diff; now *= 1000000; + let frameData = { + pose: this.pose_, + mojoSpaceReset: mojo_space_reset, + inputState: input_state, + timeDelta: { + microseconds: now, + }, + frameId: this.next_frame_id_++, + bufferHolder: null, + bufferSize: {}, + }; + this._injectAdditionalFrameData(options, frameData); + return Promise.resolve({ - frameData: { - pose: this.pose_, - mojoSpaceReset: mojo_space_reset, - inputState: input_state, - timeDelta: { - microseconds: now, - }, - frameId: this.next_frame_id_++, - bufferHolder: null, - bufferSize: {} - } + frameData: frameData, }); }
diff --git a/third_party/blink/web_tests/external/wpt/resources/testharness.js b/third_party/blink/web_tests/external/wpt/resources/testharness.js index 2c3664d..9ff22b4 100644 --- a/third_party/blink/web_tests/external/wpt/resources/testharness.js +++ b/third_party/blink/web_tests/external/wpt/resources/testharness.js
@@ -1019,7 +1019,7 @@ switch (typeof val) { case "string": - val = val.replace("\\", "\\\\"); + val = val.replace(/\\/g, "\\\\"); for (var p in replacements) { var replace = "\\" + replacements[p]; val = val.replace(RegExp(String.fromCharCode(p), "g"), replace);
diff --git a/third_party/blink/web_tests/external/wpt/tools/gitignore/gitignore.py b/third_party/blink/web_tests/external/wpt/tools/gitignore/gitignore.py index d5ea4a6a8..0f3d9450 100644 --- a/third_party/blink/web_tests/external/wpt/tools/gitignore/gitignore.py +++ b/third_party/blink/web_tests/external/wpt/tools/gitignore/gitignore.py
@@ -269,7 +269,7 @@ target.append(item) dirnames[:] = keep_dirs - assert ".git" not in dirnames + assert not any(".git" == name for name, _ in dirnames) yield orig_dirpath, dirnames, keep_files def __call__(self,
diff --git a/third_party/blink/web_tests/external/wpt/tools/mypy.ini b/third_party/blink/web_tests/external/wpt/tools/mypy.ini index ac8edd3..b943b6d 100644 --- a/third_party/blink/web_tests/external/wpt/tools/mypy.ini +++ b/third_party/blink/web_tests/external/wpt/tools/mypy.ini
@@ -1,12 +1,13 @@ [mypy] #check_untyped_defs = True -disallow_untyped_defs = True disallow_any_generics = True disallow_incomplete_defs = True disallow_subclassing_any = True disallow_untyped_calls = True disallow_untyped_decorators = True +disallow_untyped_defs = True no_implicit_optional = True +strict_equality = True warn_redundant_casts = True warn_return_any = True warn_unused_configs = True
diff --git a/third_party/blink/web_tests/external/wpt/web-nfc/NDEFRecord_constructor.https.html b/third_party/blink/web_tests/external/wpt/web-nfc/NDEFRecord_constructor.https.html index ef38a27..a2ea09f 100644 --- a/third_party/blink/web_tests/external/wpt/web-nfc/NDEFRecord_constructor.https.html +++ b/third_party/blink/web_tests/external/wpt/web-nfc/NDEFRecord_constructor.https.html
@@ -107,6 +107,7 @@ assert_equals(record.recordType, 'text', 'recordType'); assert_equals(record.mediaType, null, 'mediaType'); assert_equals(record.id, test_record_id, 'id'); + // By default, 'utf-8'. assert_equals(record.encoding, 'utf-8', 'encoding'); assert_equals(record.lang, 'en', 'lang'); const decoder = new TextDecoder(); @@ -123,6 +124,7 @@ assert_equals(record.recordType, 'text', 'recordType'); assert_equals(record.mediaType, null, 'mediaType'); assert_equals(record.id, test_record_id, 'id'); + // By default, 'utf-8'. assert_equals(record.encoding, 'utf-8', 'encoding'); assert_equals(record.lang, 'en', 'lang'); const decoder = new TextDecoder(); @@ -133,18 +135,32 @@ }, 'NDEFRecord constructor with text record type and arrayBufferView data'); test(() => { + assert_throws(new TypeError, () => new NDEFRecord(createTextRecord( + test_text_data, 'random-encoding'))); + assert_throws(new TypeError, () => new NDEFRecord(createTextRecord( + test_text_data, 'utf-16'))); + // Only 'utf-8' is OK for a DOMString data source. + const record = new NDEFRecord(createTextRecord(test_text_data, 'utf-8', 'fr')); + assert_equals(record.recordType, 'text', 'recordType'); + assert_equals(record.encoding, 'utf-8', 'encoding'); + assert_equals(record.lang, 'fr', 'lang'); + const decoder = new TextDecoder(); + assert_equals(decoder.decode(record.data), test_text_data, + 'data has the same content with the original text'); + + assert_throws(new TypeError, () => new NDEFRecord(createTextRecord( + encodeTextToArrayBuffer(test_text_data, 'utf-8'), 'random-encoding'))); + // The encoding list valid for a BufferSource data source. const encodings = ['utf-8', 'utf-16', 'utf-16be', 'utf-16le']; for (const encoding of encodings) { - const lang = 'fr'; - const record = new NDEFRecord(createTextRecord(test_text_data, encoding, lang)); + const record = new NDEFRecord(createTextRecord(encodeTextToArrayBuffer( + test_text_data, encoding), encoding, 'fr')); assert_equals(record.recordType, 'text', 'recordType'); - assert_equals(record.mediaType, null, 'mediaType'); - assert_equals(record.id, test_record_id, 'id'); assert_equals(record.encoding, encoding, 'encoding'); - assert_equals(record.lang, lang, 'lang'); - const decoder = new TextDecoder(); + assert_equals(record.lang, 'fr', 'lang'); + const decoder = new TextDecoder(record.encoding); assert_equals(decoder.decode(record.data), test_text_data, - 'data has the same content with the original dictionary'); + 'data has the same content with the original text. encoding: ' + encoding); } }, 'NDEFRecord constructor with text record type, encoding, and lang');
diff --git a/third_party/blink/web_tests/external/wpt/web-nfc/NDEFWriter_write.https.html b/third_party/blink/web_tests/external/wpt/web-nfc/NDEFWriter_write.https.html index d170122..e122473 100644 --- a/third_party/blink/web_tests/external/wpt/web-nfc/NDEFWriter_write.https.html +++ b/third_party/blink/web_tests/external/wpt/web-nfc/NDEFWriter_write.https.html
@@ -33,7 +33,7 @@ // NDEFRecord.encoding for 'text' record must be either "utf-8", // "utf-16", "utf-16le" or "utf-16be". - createMessage([createTextRecord(test_text_data, "chinese")]), + createMessage([createTextRecord(test_buffer_data, "chinese")]), // https://w3c.github.io/web-nfc/#dfn-map-a-url-to-ndef // NDEFRecord must have data.
diff --git a/third_party/blink/web_tests/external/wpt/web-nfc/resources/nfc-helpers.js b/third_party/blink/web_tests/external/wpt/web-nfc/resources/nfc-helpers.js index c60ef62..5bec071 100644 --- a/third_party/blink/web_tests/external/wpt/web-nfc/resources/nfc-helpers.js +++ b/third_party/blink/web_tests/external/wpt/web-nfc/resources/nfc-helpers.js
@@ -74,6 +74,33 @@ // OS-level NFC setting OFF NFCHWStatus.DISABLED = NFCHWStatus.NOT_SUPPORTED + 1; +function encodeTextToArrayBuffer(string, encoding) { + // Only support 'utf-8', 'utf-16', 'utf-16be', and 'utf-16le'. + assert_true( + encoding === 'utf-8' || encoding === 'utf-16' || + encoding === 'utf-16be' || encoding === 'utf-16le'); + + if (encoding === 'utf-8') { + return new TextEncoder().encode(string).buffer; + } + + if (encoding === 'utf-16') { + let uint16array = new Uint16Array(string.length); + for (let i = 0; i < string.length; i++) { + uint16array[i] = string.codePointAt(i); + } + return uint16array.buffer; + } + + const littleEndian = encoding === 'utf-16le'; + const buffer = new ArrayBuffer(string.length * 2); + const view = new DataView(buffer); + for (let i = 0; i < string.length; i++) { + view.setUint16(i * 2, string.codePointAt(i), littleEndian); + } + return buffer; +} + function createMessage(records) { if (records !== undefined) { let message = {};
diff --git a/third_party/blink/web_tests/external/wpt/webrtc-identity/idlharness.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc-identity/idlharness.https.window-expected.txt index 74bc96f..432187d 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc-identity/idlharness.https.window-expected.txt +++ b/third_party/blink/web_tests/external/wpt/webrtc-identity/idlharness.https.window-expected.txt
@@ -1,8 +1,15 @@ This is a testharness.js-based test. +Found 50 tests; 23 PASS, 27 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS idl_test setup PASS idl_test validation PASS Partial interface RTCPeerConnection: original interface defined PASS Partial interface RTCPeerConnection: member names are unique +PASS Partial dictionary RTCConfiguration: original dictionary defined +PASS Partial dictionary RTCConfiguration: member names are unique +PASS Partial interface RTCError: original interface defined +PASS Partial interface RTCError: member names are unique +PASS Partial dictionary RTCErrorInit: original dictionary defined +PASS Partial dictionary RTCErrorInit: member names are unique PASS Partial dictionary MediaStreamConstraints: original dictionary defined PASS Partial dictionary MediaStreamConstraints: member names are unique PASS Partial interface MediaStreamTrack: original interface defined @@ -37,6 +44,7 @@ FAIL RTCPeerConnection interface: new RTCPeerConnection() must inherit property "peerIdentity" with the proper type assert_inherits: property "peerIdentity" not found in prototype chain FAIL RTCPeerConnection interface: new RTCPeerConnection() must inherit property "idpLoginUrl" with the proper type assert_inherits: property "idpLoginUrl" not found in prototype chain FAIL RTCPeerConnection interface: new RTCPeerConnection() must inherit property "idpErrorInfo" with the proper type assert_inherits: property "idpErrorInfo" not found in prototype chain +PASS RTCError interface: attribute httpRequestStatusCode FAIL MediaStreamTrack interface: attribute isolated assert_true: The prototype object must have a property "isolated" expected true got false FAIL MediaStreamTrack interface: attribute onisolationchange assert_true: The prototype object must have a property "onisolationchange" expected true got false FAIL MediaStreamTrack interface: track must inherit property "isolated" with the proper type assert_inherits: property "isolated" not found in prototype chain
diff --git a/third_party/blink/web_tests/external/wpt/webrtc-identity/idlharness.https.window.js b/third_party/blink/web_tests/external/wpt/webrtc-identity/idlharness.https.window.js index da1cb85a..8c7bf665 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc-identity/idlharness.https.window.js +++ b/third_party/blink/web_tests/external/wpt/webrtc-identity/idlharness.https.window.js
@@ -5,7 +5,7 @@ idl_test( ['webrtc-identity'], - ['webrtc', 'mediacapture-streams', 'html', 'dom'], + ['webrtc', 'mediacapture-streams', 'html', 'dom', 'WebIDL'], async idlArray => { idlArray.add_objects({ RTCPeerConnection: [`new RTCPeerConnection()`],
diff --git a/third_party/blink/web_tests/external/wpt/xhr/overridemimetype-blob-expected.txt b/third_party/blink/web_tests/external/wpt/xhr/overridemimetype-blob-expected.txt index 8a5fe93..9be1c4d 100644 --- a/third_party/blink/web_tests/external/wpt/xhr/overridemimetype-blob-expected.txt +++ b/third_party/blink/web_tests/external/wpt/xhr/overridemimetype-blob-expected.txt
@@ -13,7 +13,7 @@ FAIL 8) MIME types need to be parsed and serialized: text/html ;charset=gbk assert_equals: expected "text/html;charset=gbk" but got "text/html" FAIL 9) MIME types need to be parsed and serialized: text/html; charset=gbk assert_equals: expected "text/html;charset=gbk" but got "text/html" FAIL 10) MIME types need to be parsed and serialized: text/html;charset= gbk assert_equals: expected "text/html;charset=\" gbk\"" but got "text/html" -FAIL 11) MIME types need to be parsed and serialized: text/html;charset= "gbk" assert_equals: expected "text/html;charset=\" \\\"gbk\\"\"" but got "text/html" +FAIL 11) MIME types need to be parsed and serialized: text/html;charset= "gbk" assert_equals: expected "text/html;charset=\" \\\"gbk\\\"\"" but got "text/html" FAIL 12) MIME types need to be parsed and serialized: text/html;charset=gbk assert_equals: expected "text/html" but got "application/octet-stream" FAIL 13) MIME types need to be parsed and serialized: text/html;charset=gbk assert_equals: expected "text/html" but got "application/octet-stream" FAIL 14) MIME types need to be parsed and serialized: text/html;charset=gbk assert_equals: expected "text/html" but got "application/octet-stream" @@ -44,9 +44,9 @@ FAIL 39) MIME types need to be parsed and serialized: text/html;0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789=x;charset=gbk assert_equals: expected "text/html;0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789=x;charset=gbk" but got "text/html" PASS 40) MIME types need to be parsed and serialized: 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789/0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 FAIL 41) MIME types need to be parsed and serialized: !#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz;!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz assert_equals: expected "!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz;!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz=!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" but got "!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" -FAIL 42) MIME types need to be parsed and serialized: x/x;x=" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" assert_equals: expected "x/x;x=\"\t !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ\"" but got "x/x" +FAIL 42) MIME types need to be parsed and serialized: x/x;x=" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" assert_equals: expected "x/x;x=\"\t !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ\"" but got "x/x" FAIL 43) MIME types need to be parsed and serialized: x/x;test assert_equals: expected "x/x" but got "application/octet-stream" -FAIL 44) MIME types need to be parsed and serialized: x/x;test="\ assert_equals: expected "x/x;test=\"\\\\"" but got "application/octet-stream" +FAIL 44) MIME types need to be parsed and serialized: x/x;test="\ assert_equals: expected "x/x;test=\"\\\\\"" but got "application/octet-stream" FAIL 45) MIME types need to be parsed and serialized: x/x;x= assert_equals: expected "x/x" but got "application/octet-stream" FAIL 46) MIME types need to be parsed and serialized: x/x;x= assert_equals: expected "x/x" but got "application/octet-stream" FAIL 47) MIME types need to be parsed and serialized: x/x
diff --git a/third_party/blink/web_tests/external/wpt/xhr/send-content-type-charset-expected.txt b/third_party/blink/web_tests/external/wpt/xhr/send-content-type-charset-expected.txt index 6269b565..a229d3b 100644 --- a/third_party/blink/web_tests/external/wpt/xhr/send-content-type-charset-expected.txt +++ b/third_party/blink/web_tests/external/wpt/xhr/send-content-type-charset-expected.txt
@@ -16,7 +16,7 @@ FAIL charset with trailing space that is UTF-8 does not change assert_equals: expected "text/plain;charset=utf-8 ;x=x" but got "text/plain;charset=UTF-8 ;x=x" FAIL charset in double quotes that is UTF-8 does not change assert_equals: expected "text/plain;charset=\"utf-8\"" but got "text/plain;charset=\"UTF-8\"" FAIL charset in double quotes with space assert_equals: expected "text/plain;charset=UTF-8" but got "text/plain;charset=\" UTF-8\"" -FAIL charset in double quotes with backslashes that is UTF-8 does not change assert_equals: expected "text/plain;charset=\"u\\t\f-8\"" but got "text/plain;charset=\"UTF-8\"" +FAIL charset in double quotes with backslashes that is UTF-8 does not change assert_equals: expected "text/plain;charset=\"u\\t\\f-8\"" but got "text/plain;charset=\"UTF-8\"" FAIL unknown parameters need to be preserved assert_equals: expected "yo/yo;charset=UTF-8;yo=YO;x=y" but got "YO/yo;charset=UTF-8;yo=YO; X=y" Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-repeat-count-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-repeat-count-expected.txt index a44e3f7..1cbe3bd3 100644 --- a/third_party/blink/web_tests/http/tests/devtools/console/console-repeat-count-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/console/console-repeat-count-expected.txt
@@ -18,17 +18,17 @@ dumpMessages @ console-repeat-count.js:21 (anonymous) @ console-repeat-count.js:49 2console-repeat-count.js:31 Uncaught Primitive value -setTimeout @ console-repeat-count.js:31 +(anonymous) @ console-repeat-count.js:31 setTimeout (async) throwPrimitiveValues @ console-repeat-count.js:31 (anonymous) @ console-repeat-count.js:50 console-repeat-count.js:26 Uncaught {a: 1} -setTimeout @ console-repeat-count.js:26 +(anonymous) @ console-repeat-count.js:26 setTimeout (async) throwObjects @ console-repeat-count.js:26 (anonymous) @ console-repeat-count.js:51 console-repeat-count.js:26 Uncaught {a: 1} -setTimeout @ console-repeat-count.js:26 +(anonymous) @ console-repeat-count.js:26 setTimeout (async) throwObjects @ console-repeat-count.js:26 (anonymous) @ console-repeat-count.js:51
diff --git a/third_party/blink/web_tests/inspector-protocol/css/media-query-listener-exception-expected.txt b/third_party/blink/web_tests/inspector-protocol/css/media-query-listener-exception-expected.txt index a5fac27f..929e8e7 100644 --- a/third_party/blink/web_tests/inspector-protocol/css/media-query-listener-exception-expected.txt +++ b/third_party/blink/web_tests/inspector-protocol/css/media-query-listener-exception-expected.txt
@@ -1,6 +1,6 @@ Test that uncaught exception in MediaQueryListListener will be reported to the console. On success you should see two exceptions in the listener logged to the console (first time when the media type is overridden and second - when they are restored). https://bugs.webkit.org/show_bug.cgi?id=105162 ReferenceError: objectThatDoesNotExist is not defined - at MediaQueryList.theMediaQueryList.addListener (<anonymous>:3:64) + at MediaQueryList.<anonymous> (<anonymous>:3:64) ReferenceError: objectThatDoesNotExist is not defined - at MediaQueryList.theMediaQueryList.addListener (<anonymous>:3:64) + at MediaQueryList.<anonymous> (<anonymous>:3:64)
diff --git a/third_party/blink/web_tests/paint/markers/composition-marker-basic.html b/third_party/blink/web_tests/paint/markers/composition-marker-basic.html index 40e45e1f..6f23f260 100644 --- a/third_party/blink/web_tests/paint/markers/composition-marker-basic.html +++ b/third_party/blink/web_tests/paint/markers/composition-marker-basic.html
@@ -6,6 +6,8 @@ <p>RTL</p> <div id="markRtlAll" dir="rtl">abcdef</div> <div id="markRtlAllThick">abcdef</div> + <div id="markRtlAllDotted">abcdef</div> + <div id="markRtlAllDashed">abcdef</div> <div id="markRtlBeginning">abcdef</div> <div id="markRtlAllExceptFirstAndLast">abcdef</div> <div id="markRtlEnd">abcdef</div> @@ -16,6 +18,8 @@ <p>LTR</p> <div id="markAll">abcdef</div> <div id="markAllThick">abcdef</div> + <div id="markAllDotted">abcdef</div> + <div id="markAllDashed">abcdef</div> <div id="markAllDifferentColors">abcdef</div> <div id="markBeginning">abcdef</div> <div id="markAllExceptFirstAndLast">abcdef</div> @@ -26,17 +30,17 @@ </div> <script> -function highlightRange(elem, start, end, underlineColor, thick, backgroundColor) { +function highlightRange(elem, start, end, underlineColor, thick, underlineStyle, backgroundColor) { var range = document.createRange(); var textNode = elem.firstChild; range.setStart(textNode, start); range.setEnd(textNode, end); if (typeof internals !== 'undefined') - internals.addCompositionMarker(range, underlineColor, thick, backgroundColor); + internals.addCompositionMarker(range, underlineColor, thick, underlineStyle, 'transparent', backgroundColor); }; function highlightRangeSimple(elem, start, end) { - highlightRange(elem, start, end, 'orange', 'thin', 'lightBlue'); + highlightRange(elem, start, end, 'orange', 'thin', 'solid', 'lightBlue'); }; function highlightAcrossNodes(startNode, start, endNode, end) { @@ -44,13 +48,15 @@ range.setStart(startNode, start); range.setEnd(endNode, end); if (typeof internals !== 'undefined') - internals.addCompositionMarker(range, 'orange', 'thin', 'lightBlue'); + internals.addCompositionMarker(range, 'orange', 'thin', 'solid', 'transparent', 'lightBlue'); }; onload = runAfterLayoutAndPaint(function() { highlightRangeSimple(markAll, 0, 6); - highlightRange(markAllThick, 0, 6, 'orange', 'thick', 'lightBlue'); - highlightRange(markAllDifferentColors, 0, 6, 'purple', 'thick', 'lightYellow'); + highlightRange(markAllThick, 0, 6, 'orange', 'thick', 'solid', 'lightBlue'); + highlightRange(markAllDotted, 0, 6, 'orange', 'thick', 'dot', 'lightBlue'); + highlightRange(markAllDashed, 0, 6, 'orange', 'thick', 'dash', 'lightBlue'); + highlightRange(markAllDifferentColors, 0, 6, 'purple', 'thick', 'solid', 'lightYellow'); highlightRangeSimple(markBeginning, 0, 3); highlightRangeSimple(markAllExceptFirstAndLast, 1, 5); highlightRangeSimple(markEnd, 3, 6); @@ -58,7 +64,9 @@ highlightRangeSimple(markNothingEnd, 6, 6); highlightRangeSimple(markRtlAll, 0, 6); - highlightRange(markRtlAllThick, 0, 6, 'orange', 'thick', 'lightBlue'); + highlightRange(markRtlAllThick, 0, 6, 'orange', 'thick', 'solid', 'lightBlue'); + highlightRange(markRtlAllDotted, 0, 6, 'orange', 'thick', 'dot', 'lightBlue'); + highlightRange(markRtlAllDashed, 0, 6, 'orange', 'thick', 'dash', 'lightBlue'); highlightRangeSimple(markRtlBeginning, 0, 3); highlightRangeSimple(markRtlAllExceptFirstAndLast, 1, 5); highlightRangeSimple(markRtlEnd, 3, 6);
diff --git a/third_party/blink/web_tests/paint/markers/composition-marker-split.html b/third_party/blink/web_tests/paint/markers/composition-marker-split.html index d9b66f2..c373cc7 100644 --- a/third_party/blink/web_tests/paint/markers/composition-marker-split.html +++ b/third_party/blink/web_tests/paint/markers/composition-marker-split.html
@@ -19,7 +19,7 @@ range.setStart(textNode, 0); range.setEnd(textNode, 4); if (typeof internals !== 'undefined') - internals.addCompositionMarker(range, 'orange', 'thin', 'lightBlue'); + internals.addCompositionMarker(range, 'orange', 'thin', 'solid', 'transparent', 'lightBlue'); } onload = runAfterLayoutAndPaint(function() {
diff --git a/third_party/blink/web_tests/paint/markers/ellipsis-ltr-text-in-ltr-flow-with-markers.html b/third_party/blink/web_tests/paint/markers/ellipsis-ltr-text-in-ltr-flow-with-markers.html index b239a28f..3fb7d094 100644 --- a/third_party/blink/web_tests/paint/markers/ellipsis-ltr-text-in-ltr-flow-with-markers.html +++ b/third_party/blink/web_tests/paint/markers/ellipsis-ltr-text-in-ltr-flow-with-markers.html
@@ -31,7 +31,7 @@ range.setStart(textNode, start); range.setEnd(textNode, end); if (typeof internals !== 'undefined') - internals.addCompositionMarker(range, 'orange', 'thin', 'lightBlue'); + internals.addCompositionMarker(range, 'orange', 'thin', 'solid', 'transparent', 'lightBlue'); }; function addSpellingMarker(elem, start, end) {
diff --git a/third_party/blink/web_tests/paint/markers/ellipsis-ltr-text-in-rtl-flow-with-markers.html b/third_party/blink/web_tests/paint/markers/ellipsis-ltr-text-in-rtl-flow-with-markers.html index 382ff5e..411d3ba4 100644 --- a/third_party/blink/web_tests/paint/markers/ellipsis-ltr-text-in-rtl-flow-with-markers.html +++ b/third_party/blink/web_tests/paint/markers/ellipsis-ltr-text-in-rtl-flow-with-markers.html
@@ -31,7 +31,7 @@ range.setStart(textNode, start); range.setEnd(textNode, end); if (typeof internals !== 'undefined') - internals.addCompositionMarker(range, 'orange', 'thin', 'lightBlue'); + internals.addCompositionMarker(range, 'orange', 'thin', 'solid', 'transparent', 'lightBlue'); }; function addSpellingMarker(elem, start, end) {
diff --git a/third_party/blink/web_tests/paint/markers/ellipsis-mixed-text-in-ltr-flow-with-markers.html b/third_party/blink/web_tests/paint/markers/ellipsis-mixed-text-in-ltr-flow-with-markers.html index 1b01bf9a..b08d81e 100644 --- a/third_party/blink/web_tests/paint/markers/ellipsis-mixed-text-in-ltr-flow-with-markers.html +++ b/third_party/blink/web_tests/paint/markers/ellipsis-mixed-text-in-ltr-flow-with-markers.html
@@ -34,7 +34,7 @@ range.setStart(textNode, start); range.setEnd(textNode, end); if (typeof internals !== 'undefined') - internals.addCompositionMarker(range, 'orange', 'thin', 'lightBlue'); + internals.addCompositionMarker(range, 'orange', 'thin', 'solid', 'transparent', 'lightBlue'); }; function addSpellingMarker(elem, start, end) {
diff --git a/third_party/blink/web_tests/paint/markers/ellipsis-mixed-text-in-rtl-flow-with-markers.html b/third_party/blink/web_tests/paint/markers/ellipsis-mixed-text-in-rtl-flow-with-markers.html index dadb4250..433d247 100644 --- a/third_party/blink/web_tests/paint/markers/ellipsis-mixed-text-in-rtl-flow-with-markers.html +++ b/third_party/blink/web_tests/paint/markers/ellipsis-mixed-text-in-rtl-flow-with-markers.html
@@ -34,7 +34,7 @@ range.setStart(textNode, start); range.setEnd(textNode, end); if (typeof internals !== 'undefined') - internals.addCompositionMarker(range, 'orange', 'thin', 'lightBlue'); + internals.addCompositionMarker(range, 'orange', 'thin', 'solid', 'transparent', 'lightBlue'); }; function addSpellingMarker(elem, start, end) {
diff --git a/third_party/blink/web_tests/paint/markers/ellipsis-rtl-text-in-ltr-flow-with-markers.html b/third_party/blink/web_tests/paint/markers/ellipsis-rtl-text-in-ltr-flow-with-markers.html index 5c09bbd..61d01e3 100644 --- a/third_party/blink/web_tests/paint/markers/ellipsis-rtl-text-in-ltr-flow-with-markers.html +++ b/third_party/blink/web_tests/paint/markers/ellipsis-rtl-text-in-ltr-flow-with-markers.html
@@ -31,7 +31,7 @@ range.setStart(textNode, start); range.setEnd(textNode, end); if (typeof internals !== 'undefined') - internals.addCompositionMarker(range, 'orange', 'thin', 'lightBlue'); + internals.addCompositionMarker(range, 'orange', 'thin', 'solid', 'transparent', 'lightBlue'); }; function addSpellingMarker(elem, start, end) {
diff --git a/third_party/blink/web_tests/paint/markers/ellipsis-rtl-text-in-rtl-flow-with-markers.html b/third_party/blink/web_tests/paint/markers/ellipsis-rtl-text-in-rtl-flow-with-markers.html index 31e93e7..0f24f3c 100644 --- a/third_party/blink/web_tests/paint/markers/ellipsis-rtl-text-in-rtl-flow-with-markers.html +++ b/third_party/blink/web_tests/paint/markers/ellipsis-rtl-text-in-rtl-flow-with-markers.html
@@ -31,7 +31,7 @@ range.setStart(textNode, start); range.setEnd(textNode, end); if (typeof internals !== 'undefined') - internals.addCompositionMarker(range, 'orange', 'thin', 'lightBlue'); + internals.addCompositionMarker(range, 'orange', 'thin', 'solid', 'transparent', 'lightBlue'); }; function addSpellingMarker(elem, start, end) {
diff --git a/third_party/blink/web_tests/paint/markers/first-letter.html b/third_party/blink/web_tests/paint/markers/first-letter.html index 86f4228..40742bda 100644 --- a/third_party/blink/web_tests/paint/markers/first-letter.html +++ b/third_party/blink/web_tests/paint/markers/first-letter.html
@@ -15,7 +15,7 @@ range.setStart(textNode, start); range.setEnd(textNode, end); if (typeof internals !== 'undefined') - internals.addCompositionMarker(range, 'orange', 'thin', 'lightBlue'); + internals.addCompositionMarker(range, 'orange', 'thin', 'solid', 'transparent', 'lightBlue'); }; function addSpellingMarker(elem, start, end) {
diff --git a/third_party/blink/web_tests/paint/markers/markers-zoomed.html b/third_party/blink/web_tests/paint/markers/markers-zoomed.html index b15b143..065cf5d 100644 --- a/third_party/blink/web_tests/paint/markers/markers-zoomed.html +++ b/third_party/blink/web_tests/paint/markers/markers-zoomed.html
@@ -30,7 +30,7 @@ range.setStart(textNode, start); range.setEnd(textNode, end); if (typeof internals !== 'undefined') - internals.addCompositionMarker(range, 'orange', 'thin', 'lightBlue'); + internals.addCompositionMarker(range, 'orange', 'thin', 'solid', 'transparent', 'lightBlue'); }; function addSpellingMarker(elem, start, end) {
diff --git a/third_party/blink/web_tests/paint/markers/suggestion-marker-basic.html b/third_party/blink/web_tests/paint/markers/suggestion-marker-basic.html index 46215bd..85eed0c 100644 --- a/third_party/blink/web_tests/paint/markers/suggestion-marker-basic.html +++ b/third_party/blink/web_tests/paint/markers/suggestion-marker-basic.html
@@ -51,7 +51,7 @@ range.setStart(textNode, start); range.setEnd(textNode, end); if (typeof internals !== 'undefined') - internals.addCompositionMarker(range, underlineColor, thick, backgroundColor); + internals.addCompositionMarker(range, underlineColor, thick, 'solid', 'transparent', backgroundColor); }; function addSpellingMarker(elem, start, end) {
diff --git a/third_party/blink/web_tests/paint/markers/vertical-lr.html b/third_party/blink/web_tests/paint/markers/vertical-lr.html index ea154cc..017315a 100644 --- a/third_party/blink/web_tests/paint/markers/vertical-lr.html +++ b/third_party/blink/web_tests/paint/markers/vertical-lr.html
@@ -39,7 +39,7 @@ range.setStart(textNode, start); range.setEnd(textNode, end); if (typeof internals !== 'undefined') - internals.addCompositionMarker(range, 'orange', 'thin', 'lightBlue'); + internals.addCompositionMarker(range, 'orange', 'thin', 'solid', 'transparent', 'lightBlue'); }; function addSpellingMarker(elem, start, end) {
diff --git a/third_party/blink/web_tests/paint/markers/vertical-rl.html b/third_party/blink/web_tests/paint/markers/vertical-rl.html index 91c8043..96a0cdf 100644 --- a/third_party/blink/web_tests/paint/markers/vertical-rl.html +++ b/third_party/blink/web_tests/paint/markers/vertical-rl.html
@@ -39,7 +39,7 @@ range.setStart(textNode, start); range.setEnd(textNode, end); if (typeof internals !== 'undefined') - internals.addCompositionMarker(range, 'orange', 'thin', 'lightBlue'); + internals.addCompositionMarker(range, 'orange', 'thin', 'solid', 'transparent', 'lightBlue'); }; function addSpellingMarker(elem, start, end) {
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/url/url-setters-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/url/url-setters-expected.txt index 9a7e49e2..909a9a91 100644 --- a/third_party/blink/web_tests/platform/linux/external/wpt/url/url-setters-expected.txt +++ b/third_party/blink/web_tests/platform/linux/external/wpt/url/url-setters-expected.txt
@@ -505,9 +505,9 @@ PASS URL: Setting <http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is a segment delimiter for 'special' URLs PASS <a>: Setting <http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is a segment delimiter for 'special' URLs PASS <area>: Setting <http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is a segment delimiter for 'special' URLs -FAIL URL: Setting <view-source+http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is *not* a segment delimiter for non-'special' URLs assert_equals: expected "view-source+http://example.net/\\a\%2E\b\%2e.\c?lang=fr#nav" but got "view-source+http://example.net/home?lang=fr#nav" -FAIL <a>: Setting <view-source+http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is *not* a segment delimiter for non-'special' URLs assert_equals: expected "view-source+http://example.net/\\a\%2E\b\%2e.\c?lang=fr#nav" but got "view-source+http://example.net/home?lang=fr#nav" -FAIL <area>: Setting <view-source+http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is *not* a segment delimiter for non-'special' URLs assert_equals: expected "view-source+http://example.net/\\a\%2E\b\%2e.\c?lang=fr#nav" but got "view-source+http://example.net/home?lang=fr#nav" +FAIL URL: Setting <view-source+http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is *not* a segment delimiter for non-'special' URLs assert_equals: expected "view-source+http://example.net/\\a\\%2E\\b\\%2e.\\c?lang=fr#nav" but got "view-source+http://example.net/home?lang=fr#nav" +FAIL <a>: Setting <view-source+http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is *not* a segment delimiter for non-'special' URLs assert_equals: expected "view-source+http://example.net/\\a\\%2E\\b\\%2e.\\c?lang=fr#nav" but got "view-source+http://example.net/home?lang=fr#nav" +FAIL <area>: Setting <view-source+http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is *not* a segment delimiter for non-'special' URLs assert_equals: expected "view-source+http://example.net/\\a\\%2E\\b\\%2e.\\c?lang=fr#nav" but got "view-source+http://example.net/home?lang=fr#nav" FAIL URL: Setting <a:/>.pathname = '\0 \r !"#$%&'()*+,-./09:;<=>?@AZ[\]^_`az{|}~Éé' UTF-8 percent encoding with the default encode set. Tabs and newlines are removed. assert_equals: expected "a:/%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E%3F@AZ[\\]^_%60az%7B|%7D~%7F%C2%80%C2%81%C3%89%C3%A9" but got "a:/" FAIL <a>: Setting <a:/>.pathname = '\0
diff --git a/third_party/blink/web_tests/platform/linux/paint/markers/composition-marker-basic-expected.png b/third_party/blink/web_tests/platform/linux/paint/markers/composition-marker-basic-expected.png index 5ed8a860..228bc8b 100644 --- a/third_party/blink/web_tests/platform/linux/paint/markers/composition-marker-basic-expected.png +++ b/third_party/blink/web_tests/platform/linux/paint/markers/composition-marker-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/stable/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/stable/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt new file mode 100644 index 0000000..f4d71871 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/stable/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt
@@ -0,0 +1,9 @@ +This is a testharness.js-based test. +PASS Cross-Origin-Embedder-Policy and blob: URL from https://web-platform.test:8444 in subframe via subframe +PASS Cross-Origin-Embedder-Policy and blob: URL from https://web-platform.test:8444 in subframe via navigate +FAIL Cross-Origin-Embedder-Policy and blob: URL from https://www1.web-platform.test:8444 in subframe via subframe assert_true: Cross-origin without CORP did not fail expected true got false +PASS Cross-Origin-Embedder-Policy and blob: URL from https://www1.web-platform.test:8444 in subframe via navigate +PASS Cross-Origin-Embedder-Policy and blob: URL from https://not-web-platform.test:8444 in subframe via subframe +PASS Cross-Origin-Embedder-Policy and blob: URL from https://not-web-platform.test:8444 in subframe via navigate +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/virtual/stable/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.11/virtual/stable/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt new file mode 100644 index 0000000..7989b8df --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.11/virtual/stable/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt
@@ -0,0 +1,9 @@ +This is a testharness.js-based test. +FAIL Cross-Origin-Embedder-Policy and blob: URL from https://web-platform.test:8444 in subframe via subframe assert_true: Cross-origin without CORP did not fail expected true got false +PASS Cross-Origin-Embedder-Policy and blob: URL from https://web-platform.test:8444 in subframe via navigate +PASS Cross-Origin-Embedder-Policy and blob: URL from https://www1.web-platform.test:8444 in subframe via subframe +PASS Cross-Origin-Embedder-Policy and blob: URL from https://www1.web-platform.test:8444 in subframe via navigate +PASS Cross-Origin-Embedder-Policy and blob: URL from https://not-web-platform.test:8444 in subframe via subframe +PASS Cross-Origin-Embedder-Policy and blob: URL from https://not-web-platform.test:8444 in subframe via navigate +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/mac-retina/virtual/stable/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt b/third_party/blink/web_tests/platform/mac-retina/virtual/stable/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt new file mode 100644 index 0000000..7989b8df --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-retina/virtual/stable/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt
@@ -0,0 +1,9 @@ +This is a testharness.js-based test. +FAIL Cross-Origin-Embedder-Policy and blob: URL from https://web-platform.test:8444 in subframe via subframe assert_true: Cross-origin without CORP did not fail expected true got false +PASS Cross-Origin-Embedder-Policy and blob: URL from https://web-platform.test:8444 in subframe via navigate +PASS Cross-Origin-Embedder-Policy and blob: URL from https://www1.web-platform.test:8444 in subframe via subframe +PASS Cross-Origin-Embedder-Policy and blob: URL from https://www1.web-platform.test:8444 in subframe via navigate +PASS Cross-Origin-Embedder-Policy and blob: URL from https://not-web-platform.test:8444 in subframe via subframe +PASS Cross-Origin-Embedder-Policy and blob: URL from https://not-web-platform.test:8444 in subframe via navigate +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/url/url-setters-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/url/url-setters-expected.txt index 9a7e49e2..909a9a91 100644 --- a/third_party/blink/web_tests/platform/mac/external/wpt/url/url-setters-expected.txt +++ b/third_party/blink/web_tests/platform/mac/external/wpt/url/url-setters-expected.txt
@@ -505,9 +505,9 @@ PASS URL: Setting <http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is a segment delimiter for 'special' URLs PASS <a>: Setting <http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is a segment delimiter for 'special' URLs PASS <area>: Setting <http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is a segment delimiter for 'special' URLs -FAIL URL: Setting <view-source+http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is *not* a segment delimiter for non-'special' URLs assert_equals: expected "view-source+http://example.net/\\a\%2E\b\%2e.\c?lang=fr#nav" but got "view-source+http://example.net/home?lang=fr#nav" -FAIL <a>: Setting <view-source+http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is *not* a segment delimiter for non-'special' URLs assert_equals: expected "view-source+http://example.net/\\a\%2E\b\%2e.\c?lang=fr#nav" but got "view-source+http://example.net/home?lang=fr#nav" -FAIL <area>: Setting <view-source+http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is *not* a segment delimiter for non-'special' URLs assert_equals: expected "view-source+http://example.net/\\a\%2E\b\%2e.\c?lang=fr#nav" but got "view-source+http://example.net/home?lang=fr#nav" +FAIL URL: Setting <view-source+http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is *not* a segment delimiter for non-'special' URLs assert_equals: expected "view-source+http://example.net/\\a\\%2E\\b\\%2e.\\c?lang=fr#nav" but got "view-source+http://example.net/home?lang=fr#nav" +FAIL <a>: Setting <view-source+http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is *not* a segment delimiter for non-'special' URLs assert_equals: expected "view-source+http://example.net/\\a\\%2E\\b\\%2e.\\c?lang=fr#nav" but got "view-source+http://example.net/home?lang=fr#nav" +FAIL <area>: Setting <view-source+http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is *not* a segment delimiter for non-'special' URLs assert_equals: expected "view-source+http://example.net/\\a\\%2E\\b\\%2e.\\c?lang=fr#nav" but got "view-source+http://example.net/home?lang=fr#nav" FAIL URL: Setting <a:/>.pathname = '\0 \r !"#$%&'()*+,-./09:;<=>?@AZ[\]^_`az{|}~Éé' UTF-8 percent encoding with the default encode set. Tabs and newlines are removed. assert_equals: expected "a:/%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E%3F@AZ[\\]^_%60az%7B|%7D~%7F%C2%80%C2%81%C3%89%C3%A9" but got "a:/" FAIL <a>: Setting <a:/>.pathname = '\0
diff --git a/third_party/blink/web_tests/platform/mac/paint/markers/composition-marker-basic-expected.png b/third_party/blink/web_tests/platform/mac/paint/markers/composition-marker-basic-expected.png index a2e12a9..76f8ef9 100644 --- a/third_party/blink/web_tests/platform/mac/paint/markers/composition-marker-basic-expected.png +++ b/third_party/blink/web_tests/platform/mac/paint/markers/composition-marker-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/stable/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/stable/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt new file mode 100644 index 0000000..f4d71871 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/virtual/stable/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt
@@ -0,0 +1,9 @@ +This is a testharness.js-based test. +PASS Cross-Origin-Embedder-Policy and blob: URL from https://web-platform.test:8444 in subframe via subframe +PASS Cross-Origin-Embedder-Policy and blob: URL from https://web-platform.test:8444 in subframe via navigate +FAIL Cross-Origin-Embedder-Policy and blob: URL from https://www1.web-platform.test:8444 in subframe via subframe assert_true: Cross-origin without CORP did not fail expected true got false +PASS Cross-Origin-Embedder-Policy and blob: URL from https://www1.web-platform.test:8444 in subframe via navigate +PASS Cross-Origin-Embedder-Policy and blob: URL from https://not-web-platform.test:8444 in subframe via subframe +PASS Cross-Origin-Embedder-Policy and blob: URL from https://not-web-platform.test:8444 in subframe via navigate +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/url/url-setters-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/url/url-setters-expected.txt index 4ab4dca..bf6a894 100644 --- a/third_party/blink/web_tests/platform/win/external/wpt/url/url-setters-expected.txt +++ b/third_party/blink/web_tests/platform/win/external/wpt/url/url-setters-expected.txt
@@ -505,9 +505,9 @@ PASS URL: Setting <http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is a segment delimiter for 'special' URLs PASS <a>: Setting <http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is a segment delimiter for 'special' URLs PASS <area>: Setting <http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is a segment delimiter for 'special' URLs -FAIL URL: Setting <view-source+http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is *not* a segment delimiter for non-'special' URLs assert_equals: expected "view-source+http://example.net/\\a\%2E\b\%2e.\c?lang=fr#nav" but got "view-source+http://example.net/home?lang=fr#nav" -FAIL <a>: Setting <view-source+http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is *not* a segment delimiter for non-'special' URLs assert_equals: expected "view-source+http://example.net/\\a\%2E\b\%2e.\c?lang=fr#nav" but got "view-source+http://example.net/home?lang=fr#nav" -FAIL <area>: Setting <view-source+http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is *not* a segment delimiter for non-'special' URLs assert_equals: expected "view-source+http://example.net/\\a\%2E\b\%2e.\c?lang=fr#nav" but got "view-source+http://example.net/home?lang=fr#nav" +FAIL URL: Setting <view-source+http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is *not* a segment delimiter for non-'special' URLs assert_equals: expected "view-source+http://example.net/\\a\\%2E\\b\\%2e.\\c?lang=fr#nav" but got "view-source+http://example.net/home?lang=fr#nav" +FAIL <a>: Setting <view-source+http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is *not* a segment delimiter for non-'special' URLs assert_equals: expected "view-source+http://example.net/\\a\\%2E\\b\\%2e.\\c?lang=fr#nav" but got "view-source+http://example.net/home?lang=fr#nav" +FAIL <area>: Setting <view-source+http://example.net/home?lang=fr#nav>.pathname = '\a\%2E\b\%2e.\c' \ is *not* a segment delimiter for non-'special' URLs assert_equals: expected "view-source+http://example.net/\\a\\%2E\\b\\%2e.\\c?lang=fr#nav" but got "view-source+http://example.net/home?lang=fr#nav" FAIL URL: Setting <a:/>.pathname = '\0 \r !"#$%&'()*+,-./09:;<=>?@AZ[\]^_`az{|}~Éé' UTF-8 percent encoding with the default encode set. Tabs and newlines are removed. assert_equals: expected "a:/%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E%3F@AZ[\\]^_%60az%7B|%7D~%7F%C2%80%C2%81%C3%89%C3%A9" but got "file:///%00%01%09%0A%0D%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E%3F@AZ[/]%5E_%60az%7B%7C%7D~%7F%C2%80%C2%81%C3%89%C3%A9" FAIL <a>: Setting <a:/>.pathname = '\0
diff --git a/third_party/blink/web_tests/platform/win/paint/markers/composition-marker-basic-expected.png b/third_party/blink/web_tests/platform/win/paint/markers/composition-marker-basic-expected.png index 0e26730..337138d 100644 --- a/third_party/blink/web_tests/platform/win/paint/markers/composition-marker-basic-expected.png +++ b/third_party/blink/web_tests/platform/win/paint/markers/composition-marker-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/stable/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt b/third_party/blink/web_tests/platform/win/virtual/stable/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt new file mode 100644 index 0000000..7989b8df --- /dev/null +++ b/third_party/blink/web_tests/platform/win/virtual/stable/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt
@@ -0,0 +1,9 @@ +This is a testharness.js-based test. +FAIL Cross-Origin-Embedder-Policy and blob: URL from https://web-platform.test:8444 in subframe via subframe assert_true: Cross-origin without CORP did not fail expected true got false +PASS Cross-Origin-Embedder-Policy and blob: URL from https://web-platform.test:8444 in subframe via navigate +PASS Cross-Origin-Embedder-Policy and blob: URL from https://www1.web-platform.test:8444 in subframe via subframe +PASS Cross-Origin-Embedder-Policy and blob: URL from https://www1.web-platform.test:8444 in subframe via navigate +PASS Cross-Origin-Embedder-Policy and blob: URL from https://not-web-platform.test:8444 in subframe via subframe +PASS Cross-Origin-Embedder-Policy and blob: URL from https://not-web-platform.test:8444 in subframe via navigate +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/resources/testharness.js b/third_party/blink/web_tests/resources/testharness.js index d40817c..975eab4 100644 --- a/third_party/blink/web_tests/resources/testharness.js +++ b/third_party/blink/web_tests/resources/testharness.js
@@ -919,7 +919,7 @@ switch (typeof val) { case "string": - val = val.replace("\\", "\\\\"); + val = val.replace(/\\/g, "\\\\"); for (var p in replacements) { var replace = "\\" + replacements[p]; val = val.replace(RegExp(String.fromCharCode(p), "g"), replace);
diff --git a/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/README.md b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/README.md new file mode 100644 index 0000000..c1a219c --- /dev/null +++ b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/README.md
@@ -0,0 +1 @@ +This virtual test suite is for testing the legacy Client Hints behavior when Feature Policy delegation is disabled, and see that when the flag is on, legacy hints are sent to third party origins.
diff --git a/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-feature-policy-navigation.https-expected.txt b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-feature-policy-navigation.https-expected.txt new file mode 100644 index 0000000..ca061fd0 --- /dev/null +++ b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-feature-policy-navigation.https-expected.txt
@@ -0,0 +1,7 @@ +This is a testharness.js-based test. +FAIL Client hints loaded on cross-origin iframe request with feature policy. promise_test: Unhandled rejection with value: "FAIL Device-Memory True None" +FAIL Client hints loaded on same-origin iframe request with feature policy. promise_test: Unhandled rejection with value: "FAIL DPR False 1" +PASS Iframe trying to set Accept-CH-Lifetime. +FAIL Client hints loaded on cross-origin iframe request with feature policy after attempting to set independently. promise_test: Unhandled rejection with value: "FAIL Device-Memory True None" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/cross-origin-navigation.https-expected.txt b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/cross-origin-navigation.https-expected.txt new file mode 100644 index 0000000..fbe2763 --- /dev/null +++ b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/cross-origin-navigation.https-expected.txt
@@ -0,0 +1,6 @@ +This is a testharness.js-based test. +PASS cross origin navigation precondition: Test that the browser does not have client hints preferences cached +PASS cross origin navigation set Accept-CH +FAIL cross origin navigation got client hints according to expectations. assert_equals: message from opened page expected "PASS" but got "FAIL" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/http-equiv-cross-origin-navigation.https-expected.txt b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/http-equiv-cross-origin-navigation.https-expected.txt new file mode 100644 index 0000000..c1d3017 --- /dev/null +++ b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/http-equiv-cross-origin-navigation.https-expected.txt
@@ -0,0 +1,6 @@ +This is a testharness.js-based test. +PASS http-equiv cross origin navigation precondition: Test that the browser does not have client hints preferences cached +PASS http-equiv cross origin navigation set Accept-CH +FAIL http-equiv cross origin navigation got client hints according to expectations. assert_equals: message from opened page expected "PASS" but got "FAIL" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/http-equiv-same-origin-iframe.https-expected.txt b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/http-equiv-same-origin-iframe.https-expected.txt new file mode 100644 index 0000000..d6d5932 --- /dev/null +++ b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/http-equiv-same-origin-iframe.https-expected.txt
@@ -0,0 +1,6 @@ +This is a testharness.js-based test. +PASS http-equiv same origin iframe precondition: Test that the browser does not have client hints preferences cached +PASS http-equiv same origin iframe set Accept-CH +FAIL http-equiv same origin iframe got client hints according to expectations. assert_equals: message from opened page expected "PASS" but got "FAIL" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/http-equiv-same-origin-navigation.https-expected.txt b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/http-equiv-same-origin-navigation.https-expected.txt new file mode 100644 index 0000000..87ef280 --- /dev/null +++ b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/http-equiv-same-origin-navigation.https-expected.txt
@@ -0,0 +1,6 @@ +This is a testharness.js-based test. +PASS http-equiv same origin navigation precondition: Test that the browser does not have client hints preferences cached +PASS http-equiv same origin navigation set Accept-CH +FAIL http-equiv same origin navigation got client hints according to expectations. assert_equals: message from opened page expected "PASS" but got "FAIL" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/same-origin-iframe.https-expected.txt b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/same-origin-iframe.https-expected.txt new file mode 100644 index 0000000..8158aa96 --- /dev/null +++ b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/same-origin-iframe.https-expected.txt
@@ -0,0 +1,6 @@ +This is a testharness.js-based test. +PASS same origin iframe precondition: Test that the browser does not have client hints preferences cached +PASS same origin iframe set Accept-CH +FAIL same origin iframe got client hints according to expectations. assert_equals: message from opened page expected "PASS" but got "FAIL" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/same-origin-navigation.https-expected.txt b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/same-origin-navigation.https-expected.txt new file mode 100644 index 0000000..5e95cf2 --- /dev/null +++ b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept-ch-stickiness/same-origin-navigation.https-expected.txt
@@ -0,0 +1,6 @@ +This is a testharness.js-based test. +PASS same origin navigation precondition: Test that the browser does not have client hints preferences cached +PASS same origin navigation set Accept-CH +FAIL same origin navigation got client hints according to expectations. assert_equals: message from opened page expected "PASS" but got "FAIL" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept_ch.tentative.https-expected.txt b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept_ch.tentative.https-expected.txt new file mode 100644 index 0000000..ab428623 --- /dev/null +++ b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept_ch.tentative.https-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +PASS Precondition: Test that the browser does not have client hints preferences cached +FAIL Loading of resources/expect_client_hints_headers.html did not finish. assert_equals: expected "PASS" but got "FAIL" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept_ch.tentative.sub.https-expected.txt b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept_ch.tentative.sub.https-expected.txt new file mode 100644 index 0000000..e459a582 --- /dev/null +++ b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept_ch.tentative.sub.https-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +PASS Accept-CH header test +FAIL Cross-Origin Accept-CH header test assert_false: device-memory-received expected false got true +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept_ch_feature_policy.tentative.sub.https-expected.txt b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept_ch_feature_policy.tentative.sub.https-expected.txt new file mode 100644 index 0000000..f8d4755 --- /dev/null +++ b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept_ch_feature_policy.tentative.sub.https-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +FAIL Accept-CH header test assert_false: dpr-received expected false got true +FAIL Cross-Origin Accept-CH header test assert_false: dpr-received expected false got true +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept_ch_no_feature_policy.tentative.sub.https-expected.txt b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept_ch_no_feature_policy.tentative.sub.https-expected.txt new file mode 100644 index 0000000..e459a582 --- /dev/null +++ b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/accept_ch_no_feature_policy.tentative.sub.https-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +PASS Accept-CH header test +FAIL Cross-Origin Accept-CH header test assert_false: device-memory-received expected false got true +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/http_equiv_accept_ch.tentative.https-expected.txt b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/http_equiv_accept_ch.tentative.https-expected.txt new file mode 100644 index 0000000..5d7785d --- /dev/null +++ b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/http_equiv_accept_ch.tentative.https-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +PASS Test that the browser attaches client hints on subresources in the same navigation +FAIL Loading of resources/expect_client_hints_headers.html did not finish. assert_equals: expected "PASS" but got "FAIL" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/http_equiv_accept_ch.tentative.sub.https-expected.txt b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/http_equiv_accept_ch.tentative.sub.https-expected.txt new file mode 100644 index 0000000..d404bc1 --- /dev/null +++ b/third_party/blink/web_tests/virtual/legacy-client-hints-no-fp-delegation/external/wpt/client-hints/http_equiv_accept_ch.tentative.sub.https-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +PASS Same origin Accept-CH http-equiv test +FAIL Cross-Origin Accept-CH http-equiv test assert_false: device-memory-received expected false got true +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/legacy-client-hints/README.md b/third_party/blink/web_tests/virtual/legacy-client-hints/README.md new file mode 100644 index 0000000..3100d3c0 --- /dev/null +++ b/third_party/blink/web_tests/virtual/legacy-client-hints/README.md
@@ -0,0 +1 @@ +This virtual test suite is for testing the legacy Client Hints behavior alongside Feature Policy delegation, and see that when the flag is on, legacy hints are sent regardless of Feature Policy opt-in.
diff --git a/third_party/blink/web_tests/virtual/legacy-client-hints/external/wpt/client-hints/accept_ch.tentative.sub.https-expected.txt b/third_party/blink/web_tests/virtual/legacy-client-hints/external/wpt/client-hints/accept_ch.tentative.sub.https-expected.txt new file mode 100644 index 0000000..e459a582 --- /dev/null +++ b/third_party/blink/web_tests/virtual/legacy-client-hints/external/wpt/client-hints/accept_ch.tentative.sub.https-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +PASS Accept-CH header test +FAIL Cross-Origin Accept-CH header test assert_false: device-memory-received expected false got true +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/legacy-client-hints/external/wpt/client-hints/accept_ch_feature_policy.tentative.sub.https-expected.txt b/third_party/blink/web_tests/virtual/legacy-client-hints/external/wpt/client-hints/accept_ch_feature_policy.tentative.sub.https-expected.txt new file mode 100644 index 0000000..f8d4755 --- /dev/null +++ b/third_party/blink/web_tests/virtual/legacy-client-hints/external/wpt/client-hints/accept_ch_feature_policy.tentative.sub.https-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +FAIL Accept-CH header test assert_false: dpr-received expected false got true +FAIL Cross-Origin Accept-CH header test assert_false: dpr-received expected false got true +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/legacy-client-hints/external/wpt/client-hints/accept_ch_no_feature_policy.tentative.sub.https-expected.txt b/third_party/blink/web_tests/virtual/legacy-client-hints/external/wpt/client-hints/accept_ch_no_feature_policy.tentative.sub.https-expected.txt new file mode 100644 index 0000000..e459a582 --- /dev/null +++ b/third_party/blink/web_tests/virtual/legacy-client-hints/external/wpt/client-hints/accept_ch_no_feature_policy.tentative.sub.https-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +PASS Accept-CH header test +FAIL Cross-Origin Accept-CH header test assert_false: device-memory-received expected false got true +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/legacy-client-hints/external/wpt/client-hints/http_equiv_accept_ch.tentative.sub.https-expected.txt b/third_party/blink/web_tests/virtual/legacy-client-hints/external/wpt/client-hints/http_equiv_accept_ch.tentative.sub.https-expected.txt new file mode 100644 index 0000000..d404bc1 --- /dev/null +++ b/third_party/blink/web_tests/virtual/legacy-client-hints/external/wpt/client-hints/http_equiv_accept_ch.tentative.sub.https-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +PASS Same origin Accept-CH http-equiv test +FAIL Cross-Origin Accept-CH http-equiv test assert_false: device-memory-received expected false got true +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/legacy-client-hints/wpt_internal/client-hints/accept_ch_feature_policy_allow_legacy_hints.tentative.sub.https-expected.txt b/third_party/blink/web_tests/virtual/legacy-client-hints/wpt_internal/client-hints/accept_ch_feature_policy_allow_legacy_hints.tentative.sub.https-expected.txt new file mode 100644 index 0000000..8c39bff6 --- /dev/null +++ b/third_party/blink/web_tests/virtual/legacy-client-hints/wpt_internal/client-hints/accept_ch_feature_policy_allow_legacy_hints.tentative.sub.https-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +PASS Accept-CH header test +PASS Cross-Origin Accept-CH header test +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/stable/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt b/third_party/blink/web_tests/virtual/stable/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt deleted file mode 100644 index f327b43..0000000 --- a/third_party/blink/web_tests/virtual/stable/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt +++ /dev/null
@@ -1,9 +0,0 @@ -This is a testharness.js-based test. -FAIL Cross-Origin-Embedder-Policy and blob: URL from https://web-platform.test:8444 in subframe via subframe assert_true: Cross-origin without CORP did not fail expected true got false -FAIL Cross-Origin-Embedder-Policy and blob: URL from https://web-platform.test:8444 in subframe via navigate assert_true: Cross-origin without CORP did not fail expected true got false -FAIL Cross-Origin-Embedder-Policy and blob: URL from https://www1.web-platform.test:8444 in subframe via subframe assert_true: Cross-origin without CORP did not fail expected true got false -FAIL Cross-Origin-Embedder-Policy and blob: URL from https://www1.web-platform.test:8444 in subframe via navigate assert_true: Cross-origin without CORP did not fail expected true got false -FAIL Cross-Origin-Embedder-Policy and blob: URL from https://not-web-platform.test:8444 in subframe via subframe assert_true: Cross-origin without CORP did not fail expected true got false -FAIL Cross-Origin-Embedder-Policy and blob: URL from https://not-web-platform.test:8444 in subframe via navigate assert_true: Cross-origin without CORP did not fail expected true got false -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt index 1da2e3a..e77dd778 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -11146,6 +11146,10 @@ attribute @@toStringTag getter boundsGeometry method constructor +interface XRCubeMap + attribute @@toStringTag + method constructor + method updateWebGLEnvironmentCube interface XRDOMOverlayState attribute @@toStringTag getter type @@ -11201,6 +11205,21 @@ getter removed getter session method constructor +interface XRLightEstimation + attribute @@toStringTag + getter lightProbe + getter reflectionProbe + method constructor +interface XRLightEstimationState + attribute @@toStringTag + getter enabled + method constructor +interface XRLightProbe + attribute @@toStringTag + getter mainLightDirection + getter mainLightIntensity + getter sphericalHarmonics + method constructor interface XRPlane attribute @@toStringTag getter lastChangedTime @@ -11245,6 +11264,10 @@ getter referenceSpace getter transform method constructor +interface XRReflectionProbe + attribute @@toStringTag + getter cubeMap + method constructor interface XRRenderState attribute @@toStringTag getter baseLayer @@ -11298,6 +11321,11 @@ interface XRSpace : EventTarget attribute @@toStringTag method constructor +interface XRSphericalHarmonics + attribute @@toStringTag + getter coefficients + getter orientation + method constructor interface XRTransientInputHitTestResult attribute @@toStringTag getter inputSource @@ -11337,9 +11365,11 @@ interface XRWorldInformation attribute @@toStringTag getter detectedPlanes + getter lightEstimation method constructor interface XRWorldTrackingState attribute @@toStringTag + getter lightEstimationState getter planeDetectionState method constructor interface XSLTProcessor
diff --git a/third_party/blink/web_tests/webmidi/implicit-open-expected.txt b/third_party/blink/web_tests/webmidi/implicit-open-expected.txt index f183f1b..a22f519 100644 --- a/third_party/blink/web_tests/webmidi/implicit-open-expected.txt +++ b/third_party/blink/web_tests/webmidi/implicit-open-expected.txt
@@ -1,4 +1,4 @@ -CONSOLE WARNING: line 61: Web MIDI will ask a permission to use even if the sysex is not specified in the MIDIOptions since M77, around September 2019. See https://www.chromestatus.com/feature/5138066234671104 for more details. +CONSOLE WARNING: line 61: Web MIDI will ask a permission to use even if the sysex is not specified in the MIDIOptions since around M82, around April 2020. See https://www.chromestatus.com/feature/5138066234671104 for more details. Tests MIDIPort implicit open. On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/blink/web_tests/webmidi/open-close-expected.txt b/third_party/blink/web_tests/webmidi/open-close-expected.txt index 83aa5dc..13702e2 100644 --- a/third_party/blink/web_tests/webmidi/open-close-expected.txt +++ b/third_party/blink/web_tests/webmidi/open-close-expected.txt
@@ -1,4 +1,4 @@ -CONSOLE WARNING: line 59: Web MIDI will ask a permission to use even if the sysex is not specified in the MIDIOptions since M77, around September 2019. See https://www.chromestatus.com/feature/5138066234671104 for more details. +CONSOLE WARNING: line 59: Web MIDI will ask a permission to use even if the sysex is not specified in the MIDIOptions since around M82, around April 2020. See https://www.chromestatus.com/feature/5138066234671104 for more details. Tests MIDIPort.open and MIDIPort.close. On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/blink/web_tests/webmidi/requestmidiaccess-basic-expected.txt b/third_party/blink/web_tests/webmidi/requestmidiaccess-basic-expected.txt index 85ab7c6..85a173a 100644 --- a/third_party/blink/web_tests/webmidi/requestmidiaccess-basic-expected.txt +++ b/third_party/blink/web_tests/webmidi/requestmidiaccess-basic-expected.txt
@@ -1,4 +1,4 @@ -CONSOLE WARNING: line 12: Web MIDI will ask a permission to use even if the sysex is not specified in the MIDIOptions since M77, around September 2019. See https://www.chromestatus.com/feature/5138066234671104 for more details. +CONSOLE WARNING: line 12: Web MIDI will ask a permission to use even if the sysex is not specified in the MIDIOptions since around M82, around April 2020. See https://www.chromestatus.com/feature/5138066234671104 for more details. Test if requestMIDIAccess is available. On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/blink/web_tests/webmidi/requestmidiaccess-expected.txt b/third_party/blink/web_tests/webmidi/requestmidiaccess-expected.txt index 124c87ff..29db228 100644 --- a/third_party/blink/web_tests/webmidi/requestmidiaccess-expected.txt +++ b/third_party/blink/web_tests/webmidi/requestmidiaccess-expected.txt
@@ -1,4 +1,4 @@ -CONSOLE WARNING: line 164: Web MIDI will ask a permission to use even if the sysex is not specified in the MIDIOptions since M77, around September 2019. See https://www.chromestatus.com/feature/5138066234671104 for more details. +CONSOLE WARNING: line 164: Web MIDI will ask a permission to use even if the sysex is not specified in the MIDIOptions since around M82, around April 2020. See https://www.chromestatus.com/feature/5138066234671104 for more details. Tests navigator.requestMIDIAccess. On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/blink/web_tests/webmidi/requestmidiaccess-fail-expected.txt b/third_party/blink/web_tests/webmidi/requestmidiaccess-fail-expected.txt index b134e79..afd81d8 100644 --- a/third_party/blink/web_tests/webmidi/requestmidiaccess-fail-expected.txt +++ b/third_party/blink/web_tests/webmidi/requestmidiaccess-fail-expected.txt
@@ -1,4 +1,4 @@ -CONSOLE WARNING: line 33: Web MIDI will ask a permission to use even if the sysex is not specified in the MIDIOptions since M77, around September 2019. See https://www.chromestatus.com/feature/5138066234671104 for more details. +CONSOLE WARNING: line 33: Web MIDI will ask a permission to use even if the sysex is not specified in the MIDIOptions since around M82, around April 2020. See https://www.chromestatus.com/feature/5138066234671104 for more details. Tests navigator.requestMIDIAccess failure. On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/blink/web_tests/webmidi/requestmidiaccess-options-expected.txt b/third_party/blink/web_tests/webmidi/requestmidiaccess-options-expected.txt index 7e4f97d..d7d18d7 100644 --- a/third_party/blink/web_tests/webmidi/requestmidiaccess-options-expected.txt +++ b/third_party/blink/web_tests/webmidi/requestmidiaccess-options-expected.txt
@@ -1,4 +1,4 @@ -CONSOLE WARNING: line 58: Web MIDI will ask a permission to use even if the sysex is not specified in the MIDIOptions since M77, around September 2019. See https://www.chromestatus.com/feature/5138066234671104 for more details. +CONSOLE WARNING: line 58: Web MIDI will ask a permission to use even if the sysex is not specified in the MIDIOptions since around M82, around April 2020. See https://www.chromestatus.com/feature/5138066234671104 for more details. Test requestMIDIAccess with various options. On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/blink/web_tests/webmidi/send-system-messages-expected.txt b/third_party/blink/web_tests/webmidi/send-system-messages-expected.txt index 83cdacb..bac95458 100644 --- a/third_party/blink/web_tests/webmidi/send-system-messages-expected.txt +++ b/third_party/blink/web_tests/webmidi/send-system-messages-expected.txt
@@ -1,4 +1,4 @@ -CONSOLE WARNING: line 40: Web MIDI will ask a permission to use even if the sysex is not specified in the MIDIOptions since M77, around September 2019. See https://www.chromestatus.com/feature/5138066234671104 for more details. +CONSOLE WARNING: line 40: Web MIDI will ask a permission to use even if the sysex is not specified in the MIDIOptions since around M82, around April 2020. See https://www.chromestatus.com/feature/5138066234671104 for more details. Test if various kinds of system messages can be validated. On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/blink/web_tests/wpt_internal/client-hints/accept_ch_feature_policy_allow_legacy_hints.tentative.sub.https-expected.txt b/third_party/blink/web_tests/wpt_internal/client-hints/accept_ch_feature_policy_allow_legacy_hints.tentative.sub.https-expected.txt new file mode 100644 index 0000000..449c807 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/client-hints/accept_ch_feature_policy_allow_legacy_hints.tentative.sub.https-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +FAIL Accept-CH header test assert_true: dpr-received expected true got false +FAIL Cross-Origin Accept-CH header test assert_true: dpr-received expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/wpt_internal/client-hints/accept_ch_feature_policy_allow_legacy_hints.tentative.sub.https.html b/third_party/blink/web_tests/wpt_internal/client-hints/accept_ch_feature_policy_allow_legacy_hints.tentative.sub.https.html new file mode 100644 index 0000000..cd68f50 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/client-hints/accept_ch_feature_policy_allow_legacy_hints.tentative.sub.https.html
@@ -0,0 +1,65 @@ +<html> +<body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script> + +// If the response for the HTML file contains "Accept-CH" in the response +// headers, then the browser should attach the specified client hints in the +// HTTP request headers depending on whether the resource is being fetched from +// the same origin or a different origin. Test this functionality by fetching +// same-origin and cross-origin resources from this page. The response headers +// for this page include "Accept-CH: device-memory, dpr, viewport-width, rtt, downlink, ect". +// +// echo_client_hints_received.py sets the response headers depending on the set +// of client hints it receives in the request headers. + +promise_test(t => { + return fetch(get_host_info()["HTTPS_ORIGIN"] + "/client-hints/echo_client_hints_received.py").then(r => { + assert_equals(r.status, 200) + // Verify that the browser includes client hints in the headers for a + // same-origin fetch which not specifically excluded via Feature-Policy. + assert_true(r.headers.has("device-memory-received"), "device-memory-received"); + assert_true(r.headers.has("dpr-received"), "dpr-received"); + assert_false(r.headers.has("lang-received"), "lang-received"); + assert_true(r.headers.has("viewport-width-received"), "viewport-width-received"); + + assert_true(r.headers.has("rtt-received"), "rtt-received"); + var rtt = parseInt(r.headers.get("rtt-received")); + assert_greater_than_equal(rtt, 0); + assert_less_than_equal(rtt, 3000); + assert_equals(rtt % 50, 0, 'rtt must be a multiple of 50 msec'); + + assert_true(r.headers.has("downlink-received"), "downlink-received"); + var downlinkKbps = r.headers.get("downlink-received") * 1000; + assert_greater_than_equal(downlinkKbps, 0); + assert_less_than_equal(downlinkKbps, 10000); + + assert_in_array(r.headers.get("ect-received"), ["slow-2g", "2g", + "3g", "4g"], 'ect-received is unexpected'); + }); +}, "Accept-CH header test"); + +promise_test(t => { + return fetch(get_host_info()["HTTPS_REMOTE_ORIGIN"] + "/client-hints/echo_client_hints_received.py").then(r => { + assert_equals(r.status, 200) + // Verify that the browser includes client hints in the headers for a + // cross-origin fetch which are specifically requested via Feature-Policy. + // The 3 hints below are added regardless of Feature Policy, due to legacy constraints + assert_true(r.headers.has("device-memory-received"), "device-memory-received"); + assert_true(r.headers.has("dpr-received"), "dpr-received"); + assert_true(r.headers.has("viewport-width-received"), "viewport-width-received"); + assert_false(r.headers.has("lang-received"), "lang-received"); + assert_false(r.headers.has("rtt-received"), "rtt-received"); + assert_false(r.headers.has("downlink-received"), "downlink-received"); + assert_false(r.headers.has("ect-received"), "ect-received"); + }); +}, "Cross-Origin Accept-CH header test"); + + + +</script> + +</body> +</html>
diff --git a/third_party/blink/web_tests/wpt_internal/client-hints/accept_ch_feature_policy_allow_legacy_hints.tentative.sub.https.html.headers b/third_party/blink/web_tests/wpt_internal/client-hints/accept_ch_feature_policy_allow_legacy_hints.tentative.sub.https.html.headers new file mode 100644 index 0000000..31e3b5b --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/client-hints/accept_ch_feature_policy_allow_legacy_hints.tentative.sub.https.html.headers
@@ -0,0 +1,2 @@ +Accept-CH: device-memory, dpr, viewport-width, rtt, downlink, ect, lang +Feature-Policy: ch-device-memory *; ch-dpr 'none'; ch-viewport-width 'self'; ch-lang 'none'
diff --git a/third_party/blink/web_tests/wpt_internal/webxr/ar/ar_light_estimation.https.html b/third_party/blink/web_tests/wpt_internal/webxr/ar/ar_light_estimation.https.html new file mode 100644 index 0000000..3d417ff3 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/webxr/ar/ar_light_estimation.https.html
@@ -0,0 +1,148 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script>let additionalChromiumResources = ["../resources/xr-internal-device-mocking.js"];</script> +<script src="/webxr/resources/webxr_util.js"></script> +<script src="/webxr/resources/webxr_test_constants.js"></script> +<script src="/webxr/resources/webxr_test_asserts.js"></script> +<canvas /> + +<script> +// Because AR is not yet in the core webxr spec, this is an internal-chrome only test. +let fakeDeviceInitParams = { supportedModes: ["immersive-ar"], + views: VALID_VIEWS, + supportedFeatures: ALL_FEATURES }; + +function assert_defined(v, description) { + assert_not_equals(v, undefined, description); +} + +// Verifies the structure of |XRCubeMap| +// Defined in 'third_party/blink/renderer/modules/xr/xr_cube_map.idl' +function verifyXRCubeMap(cubeMap) { + assert_defined(cubeMap.updateWebGLEnvironmentCube); +} + +// Verifies the structure of |XRReflectionProbe| +// Defined in 'third_party/blink/renderer/modules/xr/xr_reflection_probe.idl' +function verifyXRReflectionProbe(reflectionProbe) { + assert_defined(reflectionProbe.cubeMap); + verifyXRCubeMap(reflectionProbe.cubeMap); +} + +// Verifies the structure of |XRSphericalHarmonics| +// Defined in 'third_party/blink/renderer/modules/xr/xr_spherical_harmonics.idl' +function verifyXRSphericalHarmonics(sphericalHarmonics) { + assert_equals(sphericalHarmonics.orientation.x, 0); + assert_equals(sphericalHarmonics.orientation.y, 0); + assert_equals(sphericalHarmonics.orientation.z, 0); + assert_equals(sphericalHarmonics.orientation.w, 1); + assert_array_equals(Array.from(sphericalHarmonics.coefficients), new Array(9).fill().map((x, i) => [i, i, i]).flat()); +} + +// Verifies the structure of |XRLightProbe| +// Defined in 'third_party/blink/renderer/modules/xr/xr_light_probe.idl' +function verifyXRLightProbe(lightProbe) { + assert_defined(lightProbe.sphericalHarmonics); + verifyXRSphericalHarmonics(lightProbe.sphericalHarmonics); + + assert_equals(lightProbe.mainLightDirection.x, 0); + assert_equals(lightProbe.mainLightDirection.y, 1); + assert_equals(lightProbe.mainLightDirection.z, 0); + assert_equals(lightProbe.mainLightDirection.w, 0); + + assert_equals(lightProbe.mainLightIntensity.x, 1); + assert_equals(lightProbe.mainLightIntensity.y, 1); + assert_equals(lightProbe.mainLightIntensity.z, 1); + assert_equals(lightProbe.mainLightIntensity.w, 1); +} + +// Verifies the structure of |XRLightEstimationData| +// Defined in 'third_party/blink/renderer/modules/xr/xr_light_estimation.idl' +function verifyXRLightEstimationData(lightEstimation) { + assert_defined(lightEstimation.lightProbe); + if (lightEstimation.lightProbe !== null) { + verifyXRLightProbe(lightEstimation.lightProbe); + } + + assert_defined(lightEstimation.reflectionProbe); + if (lightEstimation.reflectionProbe !== null) { + verifyXRReflectionProbe(lightEstimation.reflectionProbe); + } +} + +// Verifies the structure of |XRFrame| (as it relates to light estimation) +// for a session that's expected to suppot light estimation. +// Defined in 'third_party/blink/renderer/modules/xr/xr_frame.idl' +function verifyLightEstimationExists(t, resolve, count, session, frame) { + t.step(() => { + assert_not_equals(count, 0, "Did not get lighting information with a reasonable number of frames"); + assert_defined(frame.worldInformation); + assert_defined(frame.worldInformation.lightEstimation); + + if (frame.worldInformation.lightEstimation === null) { + // Check if we get lighting information next frame + session.requestAnimationFrame((time, frame) => { + verifyLightEstimationExists(t, resolve, count - 1, session, frame); + }); + } else { + verifyXRLightEstimationData(frame.worldInformation.lightEstimation); + resolve(); + } + }); +} + +let lightingInformationExistsName = "Ensures lighting estimation feature works when enabled"; +function lightingInformationExists(session, fakeDeviceController, t) { + session.updateWorldTrackingState({ lightEstimationState: { enabled: true }}); + + return new Promise((resolve, reject) => { + session.requestAnimationFrame((time, frame) => { + verifyLightEstimationExists(t, resolve, 10, session, frame); + }); + }); +} + +function verifyLightEstimationDoesNotExist(t, resolve, count, session, frame) { + t.step(() => { + if (count === 0) { + resolve(); + return; + } + + // Lighting estimation should exist, but be null + assert_defined(frame.worldInformation); + assert_equals(frame.worldInformation.lightEstimation, null); + + // Run another frame + session.requestAnimationFrame((time, frame) => { + verifyLightEstimationDoesNotExist(t, resolve, count - 1, session, frame); + }); + }); +} + +let lightingInformationDoesNotExistName = "Ensure lighting estimation feature does not work when not explicitly enabled"; +function lightingInformationDoesNotExist(session, fakeDeviceController, t) { + return new Promise((resolve, reject) => { + session.requestAnimationFrame((time, frame) => { + verifyLightEstimationDoesNotExist(t, resolve, 10, session, frame); + }); + }); +} + +xr_session_promise_test( + lightingInformationExistsName, + lightingInformationExists, + fakeDeviceInitParams, + 'immersive-ar', + {} +); +xr_session_promise_test( + lightingInformationDoesNotExistName, + lightingInformationDoesNotExist, + fakeDeviceInitParams, + 'immersive-ar', + {} +); + +</script>
diff --git a/third_party/blink/web_tests/wpt_internal/webxr/resources/xr-internal-device-mocking.js b/third_party/blink/web_tests/wpt_internal/webxr/resources/xr-internal-device-mocking.js index 284f563..4e192535 100644 --- a/third_party/blink/web_tests/wpt_internal/webxr/resources/xr-internal-device-mocking.js +++ b/third_party/blink/web_tests/wpt_internal/webxr/resources/xr-internal-device-mocking.js
@@ -27,6 +27,33 @@ return this.presentation_provider_.missing_frame_count_; }; +MockRuntime.prototype._injectAdditionalFrameData = function(options, frameData) { + if (!options || !options.includeLightingEstimationData) { + return; + } + + frameData.lightEstimationData = { + lightProbe: { + sphericalHarmonics: { + coefficients: new Array(9).fill().map((x, i) => { return { red: i, green: i, blue: i }; }), + }, + mainLightDirection: { x: 0, y: 1, z: 0 }, + mainLightIntensity: { red: 1, green: 1, blue: 1 }, + }, + reflectionProbe: { + cubeMap: { + widthAndHeight: 16, + positiveX: new Array(16 * 16).fill({ red: 0, green: 0, blue: 0, alpha: 0 }), + negativeX: new Array(16 * 16).fill({ red: 0, green: 0, blue: 0, alpha: 0 }), + positiveY: new Array(16 * 16).fill({ red: 0, green: 0, blue: 0, alpha: 0 }), + negativeY: new Array(16 * 16).fill({ red: 0, green: 0, blue: 0, alpha: 0 }), + positiveZ: new Array(16 * 16).fill({ red: 0, green: 0, blue: 0, alpha: 0 }), + negativeZ: new Array(16 * 16).fill({ red: 0, green: 0, blue: 0, alpha: 0 }), + }, + }, + }; +}; + // Patch in experimental features. MockRuntime.featureToMojoMap["dom-overlay"] = device.mojom.XRSessionFeature.DOM_OVERLAY;
diff --git a/third_party/wayland-protocols/unstable/remote-shell/remote-shell-unstable-v1.xml b/third_party/wayland-protocols/unstable/remote-shell/remote-shell-unstable-v1.xml index dd3b48d..08f26f4b 100644 --- a/third_party/wayland-protocols/unstable/remote-shell/remote-shell-unstable-v1.xml +++ b/third_party/wayland-protocols/unstable/remote-shell/remote-shell-unstable-v1.xml
@@ -1044,13 +1044,13 @@ </request> <!-- Version 26 additions --> - <request name="set_pip_original_window" since="25"> + <request name="set_pip_original_window" since="26"> <description summary="set the pip original window"> Set this surface the original window for the current PIP window. </description> </request> - <request name="unset_pip_original_window" since="25"> + <request name="unset_pip_original_window" since="26"> <description summary="unset the pip original window"> Unset this surface the original window for the current PIP window. </description>
diff --git a/third_party/webxr_test_pages/webxr-samples/proposals/index.html b/third_party/webxr_test_pages/webxr-samples/proposals/index.html index 84ea285..b147c4d 100644 --- a/third_party/webxr_test_pages/webxr-samples/proposals/index.html +++ b/third_party/webxr_test_pages/webxr-samples/proposals/index.html
@@ -119,6 +119,9 @@ description: 'Demonstrates using the Plane Detection feature, including implementation of ' + 'synchronous hit test in JavaScript leveraging obtained plane data and ' + 'anchors API to position objects.' }, + { title: 'AR Lighting estimation', category: 'Phone AR', + path: 'lighting-estimation.html', + description: 'Demonstrates using the Lighting Estimation feature.' }, ]; let mainElement = document.getElementById("main");
diff --git a/third_party/webxr_test_pages/webxr-samples/proposals/lighting-estimation.html b/third_party/webxr_test_pages/webxr-samples/proposals/lighting-estimation.html new file mode 100644 index 0000000..5c0608d --- /dev/null +++ b/third_party/webxr_test_pages/webxr-samples/proposals/lighting-estimation.html
@@ -0,0 +1,194 @@ +<!doctype html> +<!-- +Copyright 2018 The Immersive Web Community Group + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--> +<html> + <head> + <meta charset="utf-8"> + <meta name='viewport' content='width=device-width, initial-scale=1, user-scalable=no'> + <meta name='mobile-web-app-capable' content='yes'> + <meta name='apple-mobile-web-app-capable' content='yes'> + + <!-- Origin Trial Token, feature = WebXR Device API, origin = https://immersive-web.github.io, expires = 2018-08-28 --> + <meta http-equiv="origin-trial" data-feature="WebXR Device API" data-expires="2018-08-28" content="AnNpu7ceXvLew05ccD8Zr1OZsdZiB2hLQKK82kTTMDwF7oRKtP3QEJ4RzkeHrmB8Sq0vSV6ZNmszpBCZ0I8p9gAAAABceyJvcmlnaW4iOiJodHRwczovL2ltbWVyc2l2ZS13ZWIuZ2l0aHViLmlvOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZSIsImV4cGlyeSI6MTUzNTQxNDQwMH0="> + <link href='../css/common.css' rel='stylesheet'> + + <!--The polyfill is not needed for browser that have native API support, + but is linked by these samples for wider compatibility.--> + <!--script src='https://cdn.jsdelivr.net/npm/webxr-polyfill@latest/build/webxr-polyfill.js'></script--> + <script src='../js/xrray-polyfill.js' type='module'></script> + <script src='../js/webxr-polyfill.js'></script> + + <script src='../js/webxr-button.js'></script> + <script src="https://willcassella.github.io/three.js/build/three.min.js"></script> + + <title>Lighting estimation</title> + + <style> + body { margin: 0; } + canvas { width: 100%; height: 100%; } + </style> + </head> + <body> + <header> + <details open> + <summary>Lighting Estimation</summary> + <p> + This sample demonstrates use of a non-exclusive XRSession to present + Augmented Reality content. + <a class="back" href="./index.html">Back</a> + </p> + </details> + </header> + + <script> + function init() { + const ctx = {}; + + // Create an xrCompatible rendering context + const canvas = document.createElement('canvas'); + ctx.gl = canvas.getContext('webgl2', { xrCompatible: true }); + if (!ctx.gl) { + console.error('This browser does not support WebGL2'); + return; + } + + // Create a Three.js renderer + ctx.renderer = new THREE.WebGLRenderer({ + canvas: canvas, + context: ctx.gl, + }); + + // Set up the lighting estimation environment map + ctx.threeEnvMap = new THREE.CubeTexture(new Array(6)); + ctx.envMap = ctx.gl.createTexture(); + ctx.gl.bindTexture(ctx.gl.TEXTURE_CUBE_MAP, ctx.envMap); + ctx.gl.texImage2D(ctx.gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, ctx.gl.RGBA32F, 16, 16, 0, ctx.gl.RGBA, ctx.gl.FLOAT, new Float32Array(16 * 16 * 4).fill(100)); + ctx.gl.texImage2D(ctx.gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, ctx.gl.RGBA32F, 16, 16, 0, ctx.gl.RGBA, ctx.gl.FLOAT, new Float32Array(16 * 16 * 4).fill(100)); + ctx.gl.texImage2D(ctx.gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, ctx.gl.RGBA32F, 16, 16, 0, ctx.gl.RGBA, ctx.gl.FLOAT, new Float32Array(16 * 16 * 4).fill(100)); + ctx.gl.texImage2D(ctx.gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, ctx.gl.RGBA32F, 16, 16, 0, ctx.gl.RGBA, ctx.gl.FLOAT, new Float32Array(16 * 16 * 4).fill(100)); + ctx.gl.texImage2D(ctx.gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, ctx.gl.RGBA32F, 16, 16, 0, ctx.gl.RGBA, ctx.gl.FLOAT, new Float32Array(16 * 16 * 4).fill(100)); + ctx.gl.texImage2D(ctx.gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, ctx.gl.RGBA32F, 16, 16, 0, ctx.gl.RGBA, ctx.gl.FLOAT, new Float32Array(16 * 16 * 4).fill(100)); + ctx.gl.bindTexture(ctx.gl.TEXTURE_CUBE_MAP, null); + + // Hook into the THREE.js renderer properties for the environment so that we can manage the underlying texture. + let rendererProps = ctx.renderer.properties.get(ctx.threeEnvMap); + rendererProps.__webglInit = true; + rendererProps.__webglTexture = ctx.envMap; + + // Construct a Three.JS scene + ctx.scene = new THREE.Scene(); + + // Set up the camera + ctx.camera = new THREE.Camera(); // WebXR gives us the projection matrix to use, so don't bother with PerspectiveCamera + ctx.scene.add(ctx.camera); + + // Add a sphere + ctx.geometry = new THREE.SphereGeometry(0.2, 32, 32); + ctx.material = new THREE.MeshStandardMaterial({ color: 0xFFFFFF, metalness: 0.0, roughness: 0.0 }); + ctx.sphere = new THREE.Mesh(ctx.geometry, ctx.material); + ctx.scene.add(ctx.sphere); + ctx.sphere.position.y = 1; + ctx.sphere.updateMatrix(); + + // Set up light source + ctx.light_probe = new THREE.LightProbe(); + ctx.light_probe.intensity = 3; + ctx.scene.add(ctx.light_probe); + + ctx.xrButton = new XRDeviceButton({ + onRequestSession: () => onRequestSession(ctx), + onEndSession: session => session.end(), + textEnterXRTitle: "START AR", + textXrNotFoundTitle: "AR NOT FOUND", + textExitXRTitle: "EXIT AR", + supportedSessionTypes: ['immersive-ar'], + }); + document.querySelector('header').appendChild(ctx.xrButton.domElement); + } + + function onRequestSession(ctx) { + navigator.xr.requestSession('immersive-ar', {requiredFeatures: ['local-floor']}).then(session => { + session.addEventListener('end', () => onSessionEnded(ctx)); + + ctx.session = session; + ctx.xrButton.setSession(session); + + session.updateRenderState({ baseLayer: new XRWebGLLayer(session, ctx.gl) }); + session.requestReferenceSpace('local-floor').then(refSpace => onReceivedReferenceSpace(ctx, refSpace)); + session.updateWorldTrackingState({ lightEstimationState: { enabled: true }}); + + session.requestAnimationFrame((t, frame) => update(ctx, t, frame)); + }); + } + + function onReceivedReferenceSpace(ctx, refSpace) { + ctx.referenceSpace = refSpace; + } + + function onSessionEnded(ctx) { + ctx.renderer.setAnimationLoop(null); + ctx.xrButton.setSession(null); + } + + function update(ctx, t, frame) { + // Loop + ctx.session.requestAnimationFrame((t, frame) => update(ctx, t, frame)); + + // Reset renderer state + ctx.renderer.state.reset(); + + // Update rendering parameters + const baseLayer = ctx.session.renderState.baseLayer; + + ctx.renderer.setFramebuffer(baseLayer.framebuffer); + ctx.renderer.setSize(baseLayer.framebufferWidth, baseLayer.framebufferHeight); + + // Update camera pose from reference space + if (ctx.referenceSpace) { + const pose = frame.getViewerPose(ctx.referenceSpace); + if (pose && pose.views.length > 0) { + const view = pose.views[0]; + + ctx.camera.matrix.fromArray(view.transform.matrix); + ctx.camera.updateTransforms(); + ctx.camera.projectionMatrix.fromArray(view.projectionMatrix); + } + } + + // Get ambient lighting estimation + if (frame.worldInformation.lightEstimation) { + ctx.light_probe.sh.fromArray(frame.worldInformation.lightEstimation.lightProbe.sphericalHarmonics.coefficients); + + // Update cubemap texture + frame.worldInformation.lightEstimation.reflectionProbe.cubeMap.updateWebGLEnvironmentCube(ctx.gl, ctx.envMap); + ctx.material.envMap = ctx.threeEnvMap; + } else { + console.log("Session light estimation not available"); + } + + // Render the scene + ctx.renderer.render(ctx.scene, ctx.camera); + } + + init(); + </script> + </body> +</html>
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 8c33ff0..c63d72705 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -23731,6 +23731,7 @@ <suffix name="DownloadPage" label="For DownloadPage feature."/> <suffix name="DownloadPageScreenshot" label="For DownloadPageScreenshot feature."/> + <suffix name="EphemeralTab" label="For Ephemeral Tab."/> <suffix name="ExploreSitesTile" label="For Explore Sites feature."/> <suffix name="FeedCardMenu" label="For FeedCardMenu feature."/> <suffix name="GlobalMediaControls" label="For GlobalMediaControls feature."/>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index d0488dc5..7ff314a5 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -31067,6 +31067,7 @@ <int value="0" label="Got JPEG thumbnail"/> <int value="1" label="Got ETC1 thumbnail"/> <int value="2" label="Got nothing"/> + <int value="3" label="Got different aspect ratio JPEG thumbnail"/> </enum> <enum name="GsaAccountChangeNotificationSource"> @@ -65995,7 +65996,7 @@ <int value="5" label="WebContentsDestroyed"/> <int value="6" label="WriteDataFailed"/> <int value="7" label="UserInstallDeclined"/> - <int value="8" label="ProfileDestroyed"/> + <int value="8" label="DEPRECATED: ProfileDestroyed"/> <int value="9" label="DEPRECATED: WindowOpened"/> <int value="10" label="NotValidManifestForWebApp"/> <int value="11" label="IntentToPlayStore"/> @@ -66008,7 +66009,7 @@ <int value="18" label="NotInstallable"/> <int value="19" label="BookmarkExtensionInstallError"/> <int value="20" label="ApkWebInstallFailed"/> - <int value="21" label="FailedShuttingDown"/> + <int value="21" label="CancelledOnWebAppProviderShuttingDown"/> </enum> <enum name="WebAppInstallSource">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 54c886d..51efaff 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -4141,6 +4141,47 @@ </summary> </histogram> +<histogram name="Android.WebView.AttachedToWindowIn30s" enum="Boolean" + expires_after="M83"> + <owner>michaelbai@chromium.org</owner> + <owner>boliu@chromium.org</owner> + <summary> + Records if WebView was attached to a Android window in 30s since WebView was + created. Nothing will be recorded if WebView has already been destroyed. + </summary> +</histogram> + +<histogram name="Android.WebView.AttachedToWindowIn3m" enum="Boolean" + expires_after="M83"> + <owner>michaelbai@chromium.org</owner> + <owner>boliu@chromium.org</owner> + <summary> + Records if WebView was attached to a Android window in 3m since WebView was + created. Nothing will be recorded if WebView has already been destroyed. + </summary> +</histogram> + +<histogram name="Android.WebView.AttachedToWindowIn5s" enum="Boolean" + expires_after="M83"> + <owner>michaelbai@chromium.org</owner> + <owner>boliu@chromium.org</owner> + <summary> + Records if WebView was attached to a Android window in 5s since WebView was + created. Nothing will be recorded if WebView has already been destroyed. + </summary> +</histogram> + +<histogram name="Android.WebView.AttachedToWindowTime" units="ms" + expires_after="M83"> + <owner>michaelbai@chromium.org</owner> + <owner>boliu@chromium.org</owner> + <summary> + Records how long it took for WebView to be attached to a Android window + since WebView was created. If WebView is never attached to a window, nothing + will be recorded. + </summary> +</histogram> + <histogram name="Android.WebView.Callback.Counts" enum="WebViewCallbackType" expires_after="2020-05-14"> <owner>timvolodine@chromium.org</owner> @@ -4180,6 +4221,16 @@ </summary> </histogram> +<histogram name="Android.WebView.EverAttachedToWindow" enum="Boolean" + expires_after="M83"> + <owner>michaelbai@chromium.org</owner> + <owner>boliu@chromium.org</owner> + <summary> + Records if WebView was ever attached to a window when WebView is destroyed. + If WebView is killed by platform, nothing will be recorded. + </summary> +</histogram> + <histogram name="Android.WebView.Gfx.FunctorStencilEnabled" enum="BooleanEnabled" expires_after="M78"> <obsolete> @@ -63583,8 +63634,9 @@ </histogram> <histogram name="KeyboardAccessory.AccessoryBarShown" - enum="AccessoryBarContents" expires_after="2020-02-23"> + enum="AccessoryBarContents" expires_after="2020-06-28"> <owner>fhorschig@chromium.org</owner> + <owner>ioanap@chromium.org</owner> <summary> Android only. Records how often users encounter the keyboard accessory bar. Its buckets show the contents when it came up. Every bucket may be logged up @@ -110541,18 +110593,18 @@ </histogram> <histogram name="PasswordManager.ShowAllSavedPasswordsAcceptedContext" - enum="ShowAllSavedPasswordsContext" expires_after="M81"> - <owner>jdoerrie@chromium.org</owner> - <owner>melandory@chromium.org</owner> + enum="ShowAllSavedPasswordsContext" expires_after="2020-09-30"> + <owner>vasilii@chromium.org</owner> + <owner>fhorschig@chromium.org</owner> <summary> Recorded when the "Show all saved passwords" fallback is accepted. </summary> </histogram> <histogram name="PasswordManager.ShowAllSavedPasswordsShownContext" - enum="ShowAllSavedPasswordsContext" expires_after="M81"> - <owner>jdoerrie@chromium.org</owner> - <owner>melandory@chromium.org</owner> + enum="ShowAllSavedPasswordsContext" expires_after="2020-09-30"> + <owner>vasilii@chromium.org</owner> + <owner>fhorschig@chromium.org</owner> <summary> Recorded when the "Show all saved passwords" fallback is shown. </summary> @@ -121661,6 +121713,9 @@ <histogram name="Profile.LockedProfilesDuration" units="minutes" expires_after="M79"> + <obsolete> + Deprecated 12/2019. We do not lock profiles anymore. + </obsolete> <owner>msarda@chromium.org</owner> <summary> How long locked profiles have been locked for. This is logged each time any @@ -180361,6 +180416,8 @@ label="In product help download page for screenshot."/> <suffix name="IPH_DownloadSettings" label="In product help to access download settings from download home."/> + <suffix name="IPH_EphemeralTab" + label="New label on the context menu for Ephemeral Tab."/> <suffix name="IPH_ExploreSitesTile" label="For Explore Sites feature."/> <suffix name="IPH_FeedCardMenu" label="In product help feed card menu on NTP."/>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index 9d866709..316683d 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -3038,6 +3038,76 @@ </metric> </event> +<event name="DetachedWindows.Experimental"> + <obsolete> + Deprecated as of 01/2020. + </obsolete> + <owner>bartekn@chromium.org</owner> + <summary> + Metrics related to detached windows. + </summary> + <metric name="NavigationSourceId"> + <summary> + Contains the UKM source id of the navigation as an integer. + </summary> + </metric> + <metric name="NumberOfCallsInDetachedWindowByClosing"> + <summary> + The number of function calls in a window detached by closing/removal. + </summary> + </metric> + <metric name="NumberOfCallsInDetachedWindowByClosing_After10sSinceDetaching"> + <summary> + The number of function calls in a window detached by closing/removal, that + happened at least 10 seconds after detaching. + </summary> + </metric> + <metric name="NumberOfCallsInDetachedWindowByClosing_After1minSinceDetaching"> + <summary> + The number of function calls in a window detached by closing/removal, that + happened at least 1 minute after detaching. + </summary> + </metric> + <metric name="NumberOfCallsInDetachedWindowByNavigation"> + <summary> + The number of function calls in a window detached by navigating away. + </summary> + </metric> + <metric + name="NumberOfCallsInDetachedWindowByNavigation_After10sSinceDetaching"> + <summary> + The number of function calls in a window detached by navigating away, that + happened at least 10 seconds after detaching. + </summary> + </metric> + <metric + name="NumberOfCallsInDetachedWindowByNavigation_After1minSinceDetaching"> + <summary> + The number of function calls in a window detached by navigating away, that + happened at least 1 minute after detaching. + </summary> + </metric> + <metric name="NumberOfCallsInDetachedWindowByOtherReason"> + <summary> + The number of function calls in a window detached by another reason. + </summary> + </metric> + <metric + name="NumberOfCallsInDetachedWindowByOtherReason_After10sSinceDetaching"> + <summary> + The number of function calls in a window detached by another reason, that + happened at least 10 seconds after detaching. + </summary> + </metric> + <metric + name="NumberOfCallsInDetachedWindowByOtherReason_After1minSinceDetaching"> + <summary> + The number of function calls in a window detached by another reason, that + happened at least 1 minute after detaching. + </summary> + </metric> +</event> + <event name="Document.OutliveTimeAfterShutdown"> <owner>hajimehoshi@chromium.org</owner> <owner>keishi@chromium.org</owner> @@ -5202,29 +5272,44 @@ </summary> </metric> <metric name="NumberOfCallsInDetachedWindowByClosing"> + <obsolete> + Deprecated as of 01/2020. + </obsolete> <summary> The number of function calls in a window detached by closing/removal. </summary> </metric> <metric name="NumberOfCallsInDetachedWindowByClosing_After10sSinceDetaching"> + <obsolete> + Deprecated as of 01/2020. + </obsolete> <summary> The number of function calls in a window detached by closing/removal, that happened at least 10 seconds after detaching. </summary> </metric> <metric name="NumberOfCallsInDetachedWindowByClosing_After1minSinceDetaching"> + <obsolete> + Deprecated as of 01/2020. + </obsolete> <summary> The number of function calls in a window detached by closing/removal, that happened at least 1 minute after detaching. </summary> </metric> <metric name="NumberOfCallsInDetachedWindowByNavigation"> + <obsolete> + Deprecated as of 01/2020. + </obsolete> <summary> The number of function calls in a window detached by navigating away. </summary> </metric> <metric name="NumberOfCallsInDetachedWindowByNavigation_After10sSinceDetaching"> + <obsolete> + Deprecated as of 01/2020. + </obsolete> <summary> The number of function calls in a window detached by navigating away, that happened at least 10 seconds after detaching. @@ -5232,18 +5317,27 @@ </metric> <metric name="NumberOfCallsInDetachedWindowByNavigation_After1minSinceDetaching"> + <obsolete> + Deprecated as of 01/2020. + </obsolete> <summary> The number of function calls in a window detached by navigating away, that happened at least 1 minute after detaching. </summary> </metric> <metric name="NumberOfCallsInDetachedWindowByOtherReason"> + <obsolete> + Deprecated as of 01/2020. + </obsolete> <summary> The number of function calls in a window detached by another reason. </summary> </metric> <metric name="NumberOfCallsInDetachedWindowByOtherReason_After10sSinceDetaching"> + <obsolete> + Deprecated as of 01/2020. + </obsolete> <summary> The number of function calls in a window detached by another reason, that happened at least 10 seconds after detaching. @@ -5251,6 +5345,9 @@ </metric> <metric name="NumberOfCallsInDetachedWindowByOtherReason_After1minSinceDetaching"> + <obsolete> + Deprecated as of 01/2020. + </obsolete> <summary> The number of function calls in a window detached by another reason, that happened at least 1 minute after detaching.
diff --git a/tools/perf/benchmarks/system_health_smoke_test.py b/tools/perf/benchmarks/system_health_smoke_test.py index 4788811..664e305 100644 --- a/tools/perf/benchmarks/system_health_smoke_test.py +++ b/tools/perf/benchmarks/system_health_smoke_test.py
@@ -36,189 +36,191 @@ _DISABLED_TESTS = frozenset({ - # crbug.com/983326 - flaky. - 'system_health.memory_desktop/browse_accessibility:media:youtube', + # crbug.com/983326 - flaky. + 'system_health.memory_desktop/browse_accessibility:media:youtube', - # crbug.com/878390 - These stories are already covered by their 2018 or - # 2019 versions and will later be removed. - 'system_health.memory_mobile/background:media:imgur', - 'system_health.memory_mobile/background:news:nytimes', - 'system_health.memory_mobile/background:social:facebook', - 'system_health.memory_mobile/background:search:google', - 'system_health.memory_mobile/browse:chrome:newtab', - 'system_health.memory_mobile/browse:chrome:omnibox', - 'system_health.memory_mobile/browse:media:flickr_infinite_scroll' - 'system_health.memory_mobile/browse:media:imgur' - 'system_health.memory_mobile/browse:tech:discourse_infinite_scroll', - 'system_health.memory_mobile/browse:shopping:amazon', - 'system_health.memory_mobile/browse:social:facebook', - 'system_health.memory_mobile/browse:social:facebook_infinite_scroll', - 'system_health.memory_mobile/browse:social:pinterest_infinite_scroll', - 'system_health.memory_mobile/browse:media:facebook_photos', - 'system_health.memory_mobile/browse:social:instagram', - 'system_health.memory_mobile/browse:news:reddit', - 'system_health.memory_mobile/browse:news:qq', - 'system_health.memory_mobile/browse:shopping:avito', - 'system_health.memory_mobile/browse:social:tumblr_infinite_scroll', - 'system_health.memory_mobile/browse:social:twitter', - 'system_health.memory_mobile/browse:tools:maps', - 'system_health.memory_mobile/browse:news:cnn', - 'system_health.memory_mobile/browse:news:toi', - 'system_health.memory_mobile/browse:news:washingtonpost', - 'system_health.memory_mobile/browse:media:youtube', - 'system_health.memory_mobile/browse:shopping:lazada', - 'system_health.memory_mobile/load:media:facebook_photos', - 'system_health.memory_mobile/load:media:dailymotion', - 'system_health.memory_mobile/load:news:cnn', - 'system_health.memory_mobile/load:news:irctc', - 'system_health.memory_mobile/load:news:nytimes', - 'system_health.memory_mobile/load:news:qq', - 'system_health.memory_mobile/load:news:reddit', - 'system_health.memory_mobile/load:news:washingtonpost', - 'system_health.memory_mobile/load:search:amazon', - 'system_health.memory_mobile/load:search:taobao', - 'system_health.memory_mobile/load:tools:docs', - 'system_health.memory_mobile/load:social:pinterest', - 'system_health.memory_mobile/load:tools:dropbox', - 'system_health.memory_mobile/load:tools:stackoverflow', - 'system_health.memory_mobile/load:tools:weather', - 'system_health.memory_desktop/load_accessibility:shopping:amazon', - 'system_health.memory_desktop/browse_accessibility:tech:codesearch', - 'system_health.memory_desktop/load_accessibility:media:wikipedia', - 'system_health.memory_desktop/browse:tech:discourse_infinite_scroll', - 'system_health.memory_desktop/browse:tools:maps', - 'system_health.memory_desktop/browse:social:facebook_infinite_scroll', - 'system_health.memory_desktop/browse:social:tumblr_infinite_scroll', - 'system_health.memory_desktop/browse:news:flipboard', - 'system_health.memory_desktop/browse:search:google', - 'system_health.memory_desktop/browse:news:hackernews', - 'system_health.memory_desktop/load:search:amazon', - 'system_health.memory_desktop/load:media:dailymotion', - 'system_health.memory_desktop/load:news:bbc', - 'system_health.memory_desktop/load:news:hackernews', - 'system_health.memory_desktop/load:social:instagram', - 'system_health.memory_desktop/load:news:reddit', - 'system_health.memory_desktop/load:search:taobao', - 'system_health.memory_desktop/load:tools:docs', - 'system_health.memory_desktop/load:social:pinterest', - 'system_health.memory_desktop/load:tools:weather', - 'system_health.memory_desktop/multitab:misc:typical24', - 'system_health.memory_desktop/browse:news:reddit', - 'system_health.memory_desktop/browse:media:tumblr', - 'system_health.memory_desktop/browse:social:twitter_infinite_scroll', - 'system_health.memory_mobile/load:social:twitter', - 'system_health.memory_desktop/load:social:vk', + # crbug.com/878390 - These stories are already covered by their 2018 or + # 2019 versions and will later be removed. + 'system_health.memory_mobile/background:media:imgur', + 'system_health.memory_mobile/background:news:nytimes', + 'system_health.memory_mobile/background:social:facebook', + 'system_health.memory_mobile/background:search:google', + 'system_health.memory_mobile/browse:chrome:newtab', + 'system_health.memory_mobile/browse:chrome:omnibox', + 'system_health.memory_mobile/browse:media:flickr_infinite_scroll' + 'system_health.memory_mobile/browse:media:imgur' + 'system_health.memory_mobile/browse:tech:discourse_infinite_scroll', + 'system_health.memory_mobile/browse:shopping:amazon', + 'system_health.memory_mobile/browse:social:facebook', + 'system_health.memory_mobile/browse:social:facebook_infinite_scroll', + 'system_health.memory_mobile/browse:social:pinterest_infinite_scroll', + 'system_health.memory_mobile/browse:media:facebook_photos', + 'system_health.memory_mobile/browse:social:instagram', + 'system_health.memory_mobile/browse:news:reddit', + 'system_health.memory_mobile/browse:news:qq', + 'system_health.memory_mobile/browse:shopping:avito', + 'system_health.memory_mobile/browse:social:tumblr_infinite_scroll', + 'system_health.memory_mobile/browse:social:twitter', + 'system_health.memory_mobile/browse:tools:maps', + 'system_health.memory_mobile/browse:news:cnn', + 'system_health.memory_mobile/browse:news:toi', + 'system_health.memory_mobile/browse:news:washingtonpost', + 'system_health.memory_mobile/browse:media:youtube', + 'system_health.memory_mobile/browse:shopping:lazada', + 'system_health.memory_mobile/load:media:facebook_photos', + 'system_health.memory_mobile/load:media:dailymotion', + 'system_health.memory_mobile/load:news:cnn', + 'system_health.memory_mobile/load:news:irctc', + 'system_health.memory_mobile/load:news:nytimes', + 'system_health.memory_mobile/load:news:qq', + 'system_health.memory_mobile/load:news:reddit', + 'system_health.memory_mobile/load:news:washingtonpost', + 'system_health.memory_mobile/load:search:amazon', + 'system_health.memory_mobile/load:search:taobao', + 'system_health.memory_mobile/load:tools:docs', + 'system_health.memory_mobile/load:social:pinterest', + 'system_health.memory_mobile/load:tools:dropbox', + 'system_health.memory_mobile/load:tools:stackoverflow', + 'system_health.memory_mobile/load:tools:weather', + 'system_health.memory_desktop/load_accessibility:shopping:amazon', + 'system_health.memory_desktop/browse_accessibility:tech:codesearch', + 'system_health.memory_desktop/load_accessibility:media:wikipedia', + 'system_health.memory_desktop/browse:tech:discourse_infinite_scroll', + 'system_health.memory_desktop/browse:tools:maps', + 'system_health.memory_desktop/browse:social:facebook_infinite_scroll', + 'system_health.memory_desktop/browse:social:tumblr_infinite_scroll', + 'system_health.memory_desktop/browse:news:flipboard', + 'system_health.memory_desktop/browse:search:google', + 'system_health.memory_desktop/browse:news:hackernews', + 'system_health.memory_desktop/load:search:amazon', + 'system_health.memory_desktop/load:media:dailymotion', + 'system_health.memory_desktop/load:news:bbc', + 'system_health.memory_desktop/load:news:hackernews', + 'system_health.memory_desktop/load:social:instagram', + 'system_health.memory_desktop/load:news:reddit', + 'system_health.memory_desktop/load:search:taobao', + 'system_health.memory_desktop/load:tools:docs', + 'system_health.memory_desktop/load:tools:gmail', + 'system_health.memory_desktop/load:social:pinterest', + 'system_health.memory_desktop/load:tools:weather', + 'system_health.memory_desktop/multitab:misc:typical24', + 'system_health.memory_desktop/browse:news:reddit', + 'system_health.memory_desktop/browse:media:tumblr', + 'system_health.memory_desktop/browse:social:twitter_infinite_scroll', + 'system_health.memory_mobile/load:social:twitter', + 'system_health.memory_desktop/load:social:vk', - # crbug.com/637230 - 'system_health.memory_desktop/browse:news:cnn', - # Permenently disabled from smoke test for being long-running. - 'system_health.memory_mobile/long_running:tools:gmail-foreground', - 'system_health.memory_mobile/long_running:tools:gmail-background', - 'system_health.memory_desktop/long_running:tools:gmail-foreground', - 'system_health.memory_desktop/long_running:tools:gmail-background', + # crbug.com/637230 + 'system_health.memory_desktop/browse:news:cnn', + # Permenently disabled from smoke test for being long-running. + 'system_health.memory_mobile/long_running:tools:gmail-foreground', + 'system_health.memory_mobile/long_running:tools:gmail-background', + 'system_health.memory_desktop/long_running:tools:gmail-foreground', + 'system_health.memory_desktop/long_running:tools:gmail-background', - # crbug.com/769263 - 'system_health.memory_desktop/play:media:soundcloud', + # crbug.com/769263 + 'system_health.memory_desktop/play:media:soundcloud', - # crbug.com/ - 'system_health.memory_desktop/browse:news:nytimes', + # crbug.com/ + 'system_health.memory_desktop/browse:news:nytimes', - # crbug.com/688190 - 'system_health.memory_mobile/browse:news:washingtonpost', + # crbug.com/688190 + 'system_health.memory_mobile/browse:news:washingtonpost', - # crbug.com/696824 - 'system_health.memory_desktop/load:news:qq', - # crbug.com/893615 - # DESKTOP: - 'system_health.memory_desktop/browse:media:pinterest', - 'system_health.memory_desktop/browse:media:youtube', - 'system_health.memory_desktop/browse:search:google_india', - 'system_health.memory_desktop/load:games:alphabetty', - 'system_health.memory_desktop/load:games:bubbles', - 'system_health.memory_desktop/load:games:miniclip', - 'system_health.memory_desktop/load:games:spychase', - 'system_health.memory_desktop/load:media:flickr', - 'system_health.memory_desktop/load:media:google_images', - 'system_health.memory_desktop/load:media:imgur', - 'system_health.memory_desktop/load:media:soundcloud', - 'system_health.memory_desktop/load:media:youtube', - 'system_health.memory_desktop/load:news:cnn', - 'system_health.memory_desktop/load:news:wikipedia', - 'system_health.memory_desktop/load:search:baidu', - 'system_health.memory_desktop/load:search:ebay', - 'system_health.memory_desktop/load:search:google', - 'system_health.memory_desktop/load:search:yahoo', - 'system_health.memory_desktop/load:search:yandex', - 'system_health.memory_desktop/load:tools:stackoverflow', - 'system_health.memory_mobile/load:media:soundcloud', - # MOBILE: - 'system_health.memory_mobile/load:games:bubbles', - 'system_health.memory_mobile/load:games:spychase', - 'system_health.memory_mobile/load:media:flickr', - 'system_health.memory_mobile/load:media:google_images', - 'system_health.memory_mobile/load:media:imgur', - 'system_health.memory_mobile/load:media:youtube', - 'system_health.memory_mobile/load:news:wikipedia', - 'system_health.memory_mobile/load:search:baidu', - 'system_health.memory_mobile/load:search:ebay', - 'system_health.memory_mobile/load:search:google', - 'system_health.memory_mobile/load:search:yahoo', - 'system_health.memory_mobile/load:search:yandex', + # crbug.com/696824 + 'system_health.memory_desktop/load:news:qq', + # crbug.com/893615 + # DESKTOP: + 'system_health.memory_desktop/browse:media:pinterest', + 'system_health.memory_desktop/browse:media:youtube', + 'system_health.memory_desktop/browse:search:google_india', + 'system_health.memory_desktop/load:games:alphabetty', + 'system_health.memory_desktop/load:games:bubbles', + 'system_health.memory_desktop/load:games:miniclip', + 'system_health.memory_desktop/load:games:spychase', + 'system_health.memory_desktop/load:media:flickr', + 'system_health.memory_desktop/load:media:google_images', + 'system_health.memory_desktop/load:media:imgur', + 'system_health.memory_desktop/load:media:soundcloud', + 'system_health.memory_desktop/load:media:youtube', + 'system_health.memory_desktop/load:news:cnn', + 'system_health.memory_desktop/load:news:wikipedia', + 'system_health.memory_desktop/load:search:baidu', + 'system_health.memory_desktop/load:search:ebay', + 'system_health.memory_desktop/load:search:google', + 'system_health.memory_desktop/load:search:yahoo', + 'system_health.memory_desktop/load:search:yandex', + 'system_health.memory_desktop/load:tools:stackoverflow', + 'system_health.memory_mobile/load:media:soundcloud', + # MOBILE: + 'system_health.memory_mobile/load:games:bubbles', + 'system_health.memory_mobile/load:games:spychase', + 'system_health.memory_mobile/load:media:flickr', + 'system_health.memory_mobile/load:media:google_images', + 'system_health.memory_mobile/load:media:imgur', + 'system_health.memory_mobile/load:media:youtube', + 'system_health.memory_mobile/load:news:wikipedia', + 'system_health.memory_mobile/load:search:baidu', + 'system_health.memory_mobile/load:search:ebay', + 'system_health.memory_mobile/load:search:google', + 'system_health.memory_mobile/load:search:yahoo', + 'system_health.memory_mobile/load:search:yandex', - # crbug.com/698006 - 'system_health.memory_desktop/load:tools:drive', - 'system_health.memory_desktop/load:tools:gmail', + # crbug.com/698006 + 'system_health.memory_desktop/load:tools:drive', + 'system_health.memory_desktop/load:tools:gmail', - # crbug.com/725386 - 'system_health.memory_desktop/browse:social:twitter', + # crbug.com/725386 + 'system_health.memory_desktop/browse:social:twitter', - # crbug.com/816482 - 'system_health.memory_desktop/load:news:nytimes', + # crbug.com/816482 + 'system_health.memory_desktop/load:news:nytimes', - # crbug.com/885320 - 'system_health.memory_desktop/browse:search:google:2018', + # crbug.com/885320 + 'system_health.memory_desktop/browse:search:google:2018', - # crbug.com/893615 - 'system_health.memory_desktop/multitab:misc:typical24:2018', + # crbug.com/893615 + 'system_health.memory_desktop/multitab:misc:typical24:2018', - # crbug.com/903849 - 'system_health.memory_mobile/browse:news:cnn:2018', + # crbug.com/903849 + 'system_health.memory_mobile/browse:news:cnn:2018', - # crbug.com/937006 - 'system_health.memory_mobile/browse:news:toi', + # crbug.com/937006 + 'system_health.memory_mobile/browse:news:toi', - # crbug.com/978358 - 'system_health.memory_desktop/browse:news:flipboard:2018', + # crbug.com/978358 + 'system_health.memory_desktop/browse:news:flipboard:2018', - # crbug.com/1008001 - 'system_health.memory_desktop/browse:tools:sheets:2019', - 'system_health.memory_desktop/browse:tools:maps:2019', + # crbug.com/1008001 + 'system_health.memory_desktop/browse:tools:sheets:2019', + 'system_health.memory_desktop/browse:tools:maps:2019', - # crbug.com/1014661 - 'system_health.memory_desktop/browse:social:tumblr_infinite_scroll:2018' - 'system_health.memory_desktop/browse:search:google_india:2018' + # crbug.com/1014661 + 'system_health.memory_desktop/browse:social:tumblr_infinite_scroll:2018' + 'system_health.memory_desktop/browse:search:google_india:2018' - # The following tests are disabled because they are disabled on the perf - # waterfall (using tools/perf/expectations.config) on one platform or another. - # They may run fine on the CQ, but it isn't worth the bot time to run them. - # [ - # crbug.com/799106 - 'system_health.memory_desktop/browse:media:flickr_infinite_scroll' - # crbug.com/836407 - 'system_health.memory_desktop/browse:tools:maps' - # crbug.com/924330 - 'system_health.memory_desktop/browse:media:pinterest:2018' - # crbug.com/899887 - 'system_health.memory_desktop/browse:social:facebook_infinite_scroll:2018' - # crbug.com/649392 - 'system_health.memory_desktop/play:media:google_play_music' - # crbug.com/934885 - 'system_health.memory_desktop/load_accessibility:media:wikipedia:2018' - # crbug.com/942952 - 'system_health.memory_desktop/browse:news:hackernews:2018', - # crbug.com/992436 - 'system_health.memory_desktop/browse:social:twitter:2018' - # ] + # The following tests are disabled because they are disabled on the perf + # waterfall (using tools/perf/expectations.config) on one platform or + # another. They may run fine on the CQ, but it isn't worth the bot time to + # run them. + # [ + # crbug.com/799106 + 'system_health.memory_desktop/browse:media:flickr_infinite_scroll' + # crbug.com/836407 + 'system_health.memory_desktop/browse:tools:maps' + # crbug.com/924330 + 'system_health.memory_desktop/browse:media:pinterest:2018' + # crbug.com/899887 + 'system_health.memory_desktop/browse:social:facebook_infinite_scroll:2018' + # crbug.com/649392 + 'system_health.memory_desktop/play:media:google_play_music' + # crbug.com/934885 + 'system_health.memory_desktop/load_accessibility:media:wikipedia:2018' + # crbug.com/942952 + 'system_health.memory_desktop/browse:news:hackernews:2018', + # crbug.com/992436 + 'system_health.memory_desktop/browse:social:twitter:2018' + # ] })
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config index b58c7c0..fee24e84 100644 --- a/tools/perf/expectations.config +++ b/tools/perf/expectations.config
@@ -307,6 +307,7 @@ crbug.com/1008001 [ win ] system_health.common_desktop/browse:tools:sheets:2019 [ Skip ] crbug.com/1017244 [ desktop ] system_health.common_desktop/browse_accessibility:media:youtube [ Skip ] crbug.com/1023366 [ desktop ] system_health.common_desktop/browse:media:youtube:2019 [ Skip ] +crbug.com/1042632 [ win ] system_health.common_desktop/load:tools:gmail:2019 [ Skip ] # Benchmark: system_health.common_mobile crbug.com/1013317 [ android ] system_health.common_mobile/load:news:nytimes [ Skip ] @@ -363,8 +364,7 @@ crbug.com/1017290 [ linux ] system_health.memory_desktop/browse:search:google_india:2018 [ Skip ] crbug.com/1017244 [ desktop ] system_health.memory_desktop/browse_accessibility:media:youtube [ Skip ] crbug.com/1017346 [ desktop ] system_health.memory_desktop/browse:media:youtube:2019 [ Skip ] -crbug.com/1036141 [ android-webview ] system_health.memory_mobile/browse:shopping:lazada:2019 [ Skip ] -crbug.com/1039801 [ android-webview ] system_health.memory_mobile/browse:social:pinterest_infinite_scroll:2019 [ Skip ] +crbug.com/1042632 [ win ] system_health.memory_desktop/load:tools:gmail:2019 [ Skip ] # Benchmark: system_health.memory_mobile crbug.com/1013317 [ android ] system_health.memory_mobile/load:news:nytimes [ Skip ] @@ -405,6 +405,8 @@ crbug.com/1017661 [ android-nexus-5x ] system_health.memory_mobile/browse:social:facebook_infinite_scroll:2018 [ Skip ] crbug.com/1017661 [ android-nexus-5x ] system_health.memory_mobile/browse:tech:discourse_infinite_scroll:2018 [ Skip ] crbug.com/1036143 [ android-pixel-2 ] system_health.memory_mobile/browse:chrome:omnibox:2019 [ Skip ] +crbug.com/1036141 [ android-webview ] system_health.memory_mobile/browse:shopping:lazada:2019 [ Skip ] +crbug.com/1039801 [ android-webview ] system_health.memory_mobile/browse:social:pinterest_infinite_scroll:2019 [ Skip ] # Benchmark: tab_switching.typical_25 crbug.com/747026 [ mac ] tab_switching.typical_25/multitab:misc:typical24 [ Skip ]
diff --git a/tools/perf/page_sets/data/system_health_desktop.json b/tools/perf/page_sets/data/system_health_desktop.json index f7546be5..52f8a0c2 100644 --- a/tools/perf/page_sets/data/system_health_desktop.json +++ b/tools/perf/page_sets/data/system_health_desktop.json
@@ -334,6 +334,9 @@ "load:tools:gmail": { "DEFAULT": "system_health_desktop_004.wprgo" }, + "load:tools:gmail:2019": { + "DEFAULT": "system_health_desktop_0e466e2324.wprgo" + }, "load:tools:maps": { "DEFAULT": "system_health_desktop_004.wprgo" },
diff --git a/tools/perf/page_sets/data/system_health_desktop_0e466e2324.wprgo.sha1 b/tools/perf/page_sets/data/system_health_desktop_0e466e2324.wprgo.sha1 new file mode 100644 index 0000000..d1e99e3 --- /dev/null +++ b/tools/perf/page_sets/data/system_health_desktop_0e466e2324.wprgo.sha1
@@ -0,0 +1 @@ +5ca581c9df2bfa6c57af4f9709f626ea1cd22da9 \ No newline at end of file
diff --git a/tools/perf/page_sets/data/system_health_mobile.json b/tools/perf/page_sets/data/system_health_mobile.json index c3fa72d..3987845 100644 --- a/tools/perf/page_sets/data/system_health_mobile.json +++ b/tools/perf/page_sets/data/system_health_mobile.json
@@ -402,6 +402,9 @@ "load:tools:gmail": { "DEFAULT": "system_health_mobile_048.wprgo" }, + "load:tools:gmail:2019": { + "DEFAULT": "system_health_mobile_b8a3bd8e6d.wprgo" + }, "load:tools:maps": { "DEFAULT": "system_health_mobile_004.wprgo" },
diff --git a/tools/perf/page_sets/data/system_health_mobile_b8a3bd8e6d.wprgo.sha1 b/tools/perf/page_sets/data/system_health_mobile_b8a3bd8e6d.wprgo.sha1 new file mode 100644 index 0000000..3da78f16 --- /dev/null +++ b/tools/perf/page_sets/data/system_health_mobile_b8a3bd8e6d.wprgo.sha1
@@ -0,0 +1 @@ +638f0ef8d4a82535c8a28a87d9d4f76d18a640ea \ No newline at end of file
diff --git a/tools/perf/page_sets/login_helpers/google_login.py b/tools/perf/page_sets/login_helpers/google_login.py index 9540886..b6b1013 100644 --- a/tools/perf/page_sets/login_helpers/google_login.py +++ b/tools/perf/page_sets/login_helpers/google_login.py
@@ -3,6 +3,8 @@ # found in the LICENSE file. from page_sets.login_helpers import login_utils +from page_sets.helpers import override_online + # Selectors for the email, password, and next buttons for google login flow. # Use multiple selectors to allow for different versions of the site. _EMAIL_SELECTOR = ','.join([ @@ -56,8 +58,9 @@ credential, credentials_path=credentials_path) action_runner.Navigate( - 'https://accounts.google.com/ServiceLogin?continue=' - 'https%3A%2F%2Faccounts.google.com%2FManageAccount') + 'https://accounts.google.com/ServiceLogin?continue=' + 'https%3A%2F%2Faccounts.google.com%2FManageAccount', + override_online.ALWAYS_ONLINE) # Wait until either the email or password input is visible. action_runner.WaitForJavaScriptCondition('{{ @a }} || {{ @b }}',
diff --git a/tools/perf/page_sets/system_health/loading_stories.py b/tools/perf/page_sets/system_health/loading_stories.py index 4bf11a0..80217873 100644 --- a/tools/perf/page_sets/system_health/loading_stories.py +++ b/tools/perf/page_sets/system_health/loading_stories.py
@@ -9,6 +9,8 @@ from page_sets.login_helpers import dropbox_login from page_sets.login_helpers import google_login +from page_sets.helpers import override_online + from telemetry.util import js_template @@ -16,6 +18,14 @@ """Abstract base class for single-page System Health user stories.""" ABSTRACT_STORY = True + def __init__(self, + story_set, + take_memory_measurement, + extra_browser_args=None): + super(_LoadingStory, self).__init__(story_set, take_memory_measurement, + extra_browser_args) + self.script_to_evaluate_on_commit = override_online.ALWAYS_ONLINE + @classmethod def GenerateStoryDescription(cls): return 'Load %s' % cls.URL @@ -490,6 +500,29 @@ action_runner.WaitForJavaScriptCondition( 'document.getElementById("apploadingdiv").style.height === "0px"') + +class LoadGmailStory2019(_LoadingStory): + NAME = 'load:tools:gmail:2019' + # Needs to be http and not https. + URL = 'http://mail.google.com/' + TAGS = [story_tags.YEAR_2019] + SKIP_LOGIN = False + + def _Login(self, action_runner): + google_login.NewLoginGoogleAccount(action_runner, 'googletest') + + # Navigating to http://mail.google.com immediately leads to an infinite + # redirection loop due to a bug in WPR (see + # https://bugs.chromium.org/p/chromium/issues/detail?id=1036791). We + # therefore first navigate to a dummy sub-URL to set up the session and + # hit the resulting redirection loop. Afterwards, we can safely navigate + # to http://mail.google.com. + action_runner.tab.WaitForDocumentReadyStateToBeComplete() + action_runner.Navigate( + 'https://mail.google.com/mail/mu/mp/872/trigger_redirection_loop') + action_runner.tab.WaitForDocumentReadyStateToBeComplete() + + class LoadStackOverflowStory2018(_LoadingStory): """Load a typical question & answer page of stackoverflow.com""" NAME = 'load:tools:stackoverflow:2018'
diff --git a/tools/perf/system_health_stories.csv b/tools/perf/system_health_stories.csv index aced981..74f3f7ec 100644 --- a/tools/perf/system_health_stories.csv +++ b/tools/perf/system_health_stories.csv
@@ -142,6 +142,7 @@ load:tools:dropbox,,"desktop,mobile",2016 load:tools:dropbox:2019,,mobile,2019 load:tools:gmail,,"desktop,mobile",2016 +load:tools:gmail:2019,,"desktop,mobile",2019 load:tools:stackoverflow:2018,Load a typical question & answer page of stackoverflow.com,"desktop,mobile","2018,health_check" load:tools:weather,,"desktop,mobile","2016,javascript_heavy" load:tools:weather:2019,,"desktop,mobile","2019,javascript_heavy"
diff --git a/tools/polymer/polymer.py b/tools/polymer/polymer.py index 4b47fc5..343b2420 100644 --- a/tools/polymer/polymer.py +++ b/tools/polymer/polymer.py
@@ -491,11 +491,9 @@ # Reconstruct file. # Specify the newline character so that the exact same file is generated # across platforms. - with io.open(os.path.join(out_folder, result[1]), mode='w', encoding='utf-8', newline='\n') as f: + with io.open(os.path.join(out_folder, result[1]), mode='wb') as f: for l in result[0]: - if (type(l) != unicode): - l = unicode(l, encoding='utf-8') - f.write(l) + f.write(l.encode('utf-8')) return
diff --git a/ui/accessibility/ax_language_detection.cc b/ui/accessibility/ax_language_detection.cc index 9946774e..eea64e9 100644 --- a/ui/accessibility/ax_language_detection.cc +++ b/ui/accessibility/ax_language_detection.cc
@@ -96,20 +96,33 @@ top_results_valid_ = true; } -AXLanguageDetectionManager::AXLanguageDetectionManager() +AXLanguageDetectionManager::AXLanguageDetectionManager(AXTree* tree) : short_text_language_identifier_(kShortTextIdentifierMinByteLength, - kShortTextIdentifierMaxByteLength) {} + kShortTextIdentifierMaxByteLength), + tree_(tree) {} + AXLanguageDetectionManager::~AXLanguageDetectionManager() = default; -// Detect languages for a subtree rooted at the given subtree_root. -void AXLanguageDetectionManager::DetectLanguages(AXNode* subtree_root) { +void AXLanguageDetectionManager::RegisterLanguageDetectionObserver() { + // If the dynamic feature flag is not enabled then do nothing. + if (!::switches:: + IsExperimentalAccessibilityLanguageDetectionDynamicEnabled()) { + return; + } + + // Construct our new Observer as requested. + // If there is already an Observer on this Manager then this will destroy it. + language_detection_observer_.reset(new AXLanguageDetectionObserver(tree_)); +} + +// Detect languages for each node. +void AXLanguageDetectionManager::DetectLanguages() { TRACE_EVENT0("accessibility", "AXLanguageInfo::DetectLanguages"); - DCHECK(subtree_root); if (!::switches::IsExperimentalAccessibilityLanguageDetectionEnabled()) { return; } - DetectLanguagesForSubtree(subtree_root); + DetectLanguagesForSubtree(tree_->root()); } // Detect languages for a subtree rooted at the given subtree_root. @@ -165,29 +178,32 @@ if (reliable_results.size()) { AXLanguageInfo* lang_info = node->GetLanguageInfo(); if (lang_info) { + // Clear previously detected and labelled languages. lang_info->detected_languages.clear(); + lang_info->language.clear(); } else { node->SetLanguageInfo(std::make_unique<AXLanguageInfo>()); lang_info = node->GetLanguageInfo(); } + // Keep these results. lang_info->detected_languages = std::move(reliable_results); + + // Update statistics to take these results into account. lang_info_stats_.Add(lang_info->detected_languages); } } -// Label languages for each node in the subtree rooted at the given -// subtree_root. This relies on DetectLanguages having already been run. -void AXLanguageDetectionManager::LabelLanguages(AXNode* subtree_root) { +// Label languages for each node. This relies on DetectLanguages having already +// been run. +void AXLanguageDetectionManager::LabelLanguages() { TRACE_EVENT0("accessibility", "AXLanguageInfo::LabelLanguages"); - DCHECK(subtree_root); - if (!::switches::IsExperimentalAccessibilityLanguageDetectionEnabled()) { return; } - LabelLanguagesForSubtree(subtree_root); + LabelLanguagesForSubtree(tree_->root()); } // Label languages for each node in the subtree rooted at the given @@ -295,4 +311,63 @@ return language_annotation; } +AXLanguageDetectionObserver::AXLanguageDetectionObserver(AXTree* tree) + : tree_(tree) { + // We expect the feature flag to have be checked before this Observer is + // constructed, this should have been checked by + // RegisterLanguageDetectionObserver. + DCHECK( + ::switches::IsExperimentalAccessibilityLanguageDetectionDynamicEnabled()); + + tree_->AddObserver(this); +} + +AXLanguageDetectionObserver::~AXLanguageDetectionObserver() { + tree_->RemoveObserver(this); +} + +void AXLanguageDetectionObserver::OnAtomicUpdateFinished( + ui::AXTree* tree, + bool root_changed, + const std::vector<Change>& changes) { + // TODO(chrishall): We likely want to re-consider updating or resetting + // AXLanguageInfoStats over time to better support detection on long running + // pages. + + // TODO(chrishall): To support pruning deleted node data from stats we should + // consider implementing OnNodeWillBeDeleted. Other options available include: + // 1) move lang info from AXNode into a map on AXTree so that we can fetch + // based on id in here + // 2) AXLanguageInfo destructor could remove itself + + // TODO(chrishall): Possible optimisation: only run detect/label for certain + // change.type(s)), at least NODE_CREATED, NODE_CHANGED, and SUBTREE_CREATED. + + DCHECK(tree->language_detection_manager); + + // Perform Detect and Label for each node changed or created. + // We currently only consider kStaticText for detection. + // + // Note that language inheritance is now handled by AXNode::GetLanguage. + // + // Note that since Label no longer handles language inheritance, we only need + // to call Label and Detect on the nodes that changed and don't need to + // recurse. + // + // We do this in two passes because Detect updates page level statistics which + // are later used by Label in order to make more accurate decisions. + + for (auto& change : changes) { + if (change.node->data().role == ax::mojom::Role::kStaticText) { + tree->language_detection_manager->DetectLanguagesForNode(change.node); + } + } + + for (auto& change : changes) { + if (change.node->data().role == ax::mojom::Role::kStaticText) { + tree->language_detection_manager->LabelLanguagesForNode(change.node); + } + } +} + } // namespace ui
diff --git a/ui/accessibility/ax_language_detection.h b/ui/accessibility/ax_language_detection.h index 79eaa76..0ea327a 100644 --- a/ui/accessibility/ax_language_detection.h +++ b/ui/accessibility/ax_language_detection.h
@@ -5,6 +5,7 @@ #ifndef UI_ACCESSIBILITY_AX_LANGUAGE_DETECTION_H_ #define UI_ACCESSIBILITY_AX_LANGUAGE_DETECTION_H_ +#include <memory> #include <string> #include <unordered_map> #include <utility> @@ -14,6 +15,7 @@ #include "third_party/cld_3/src/src/nnet_language_identifier.h" #include "ui/accessibility/ax_enums.mojom-forward.h" #include "ui/accessibility/ax_export.h" +#include "ui/accessibility/ax_tree_observer.h" namespace ui { @@ -139,24 +141,57 @@ DISALLOW_COPY_AND_ASSIGN(AXLanguageInfoStats); }; +// AXLanguageDetectionObserver is registered as a change observer on an AXTree +// and will run language detection after each update to the tree. +// +// We have kept this observer separate from the AXLanguageDetectionManager as we +// are aiming to launch language detection in two phases and wanted to try keep +// the code paths somewhat separate. +// +// TODO(chrishall): After both features have launched we could consider merging +// AXLanguageDetectionObserver into AXLanguageDetectionManager. +// +// TODO(chrishall): Investigate the cost of using AXTreeObserver, given that it +// has many empty virtual methods which are called for every AXTree change and +// we are only currently interested in OnAtomicUpdateFinished. +class AX_EXPORT AXLanguageDetectionObserver : public ui::AXTreeObserver { + public: + // Observer constructor will register itself with the provided AXTree. + AXLanguageDetectionObserver(AXTree* tree); + + // Observer destructor will remove itself as an observer from the AXTree. + ~AXLanguageDetectionObserver() override; + + private: + void OnAtomicUpdateFinished(ui::AXTree* tree, + bool root_changed, + const std::vector<Change>& changes) override; + + // Non-owning pointer to AXTree, used to de-register observer on destruction. + AXTree* const tree_; + + DISALLOW_COPY_AND_ASSIGN(AXLanguageDetectionObserver); +}; + // AXLanguageDetectionManager manages all of the context needed for language // detection within an AXTree. class AX_EXPORT AXLanguageDetectionManager { public: - AXLanguageDetectionManager(); + // Construct an AXLanguageDetectionManager for the specified tree. + AXLanguageDetectionManager(AXTree* tree); ~AXLanguageDetectionManager(); - // Detect languages for each node in the subtree rooted at the given node. + // Detect languages for each node in the tree managed by this manager. // This is the first pass in detection and labelling. // This only detects the language, it does not label it, for that see // LabelLanguageForSubtree. - void DetectLanguages(AXNode* subtree_root); + void DetectLanguages(); - // Label languages for each node in the subtree rooted at the given node. + // Label languages for each node in the tree manager by this manager. // This is the second pass in detection and labelling. // This will label the language, but relies on the earlier detection phase // having already completed. - void LabelLanguages(AXNode* subtree_root); + void LabelLanguages(); // Sub-node language detection for a given string attribute. // For example, if a node has name: "My name is Fred", then calling @@ -166,8 +201,14 @@ const AXNode& node, ax::mojom::StringAttribute attr); + // Construct and register a dynamic content change observer for this manager. + void RegisterLanguageDetectionObserver(); + private: - AXLanguageInfoStats lang_info_stats_; + friend class AXLanguageDetectionObserver; + + // Allow access from a fixture only used in testing. + friend class AXLanguageDetectionTestFixture; // Perform detection for subtree rooted at subtree_root. void DetectLanguagesForSubtree(AXNode* subtree_root); @@ -188,6 +229,14 @@ // of shorter text (e.g. one character). chrome_lang_id::NNetLanguageIdentifier short_text_language_identifier_; + // The observer to support dynamic content language detection. + std::unique_ptr<AXLanguageDetectionObserver> language_detection_observer_; + + // Non-owning back pointer to the tree which owns this manager. + AXTree* tree_; + + AXLanguageInfoStats lang_info_stats_; + DISALLOW_COPY_AND_ASSIGN(AXLanguageDetectionManager); };
diff --git a/ui/accessibility/ax_language_detection_unittest.cc b/ui/accessibility/ax_language_detection_unittest.cc index af5a5b0..774c48f 100644 --- a/ui/accessibility/ax_language_detection_unittest.cc +++ b/ui/accessibility/ax_language_detection_unittest.cc
@@ -18,7 +18,70 @@ namespace ui { -TEST(AXLanguageDetectionTest, FeatureFlag) { +const std::string kTextEnglish = + "This is text created using Google Translate, it is unlikely to be " + "idiomatic in the given target language. This text is only used to " + "test language detection"; + +const std::string kTextFrench = + "Ce texte a été créé avec Google Translate, il est peu probable qu'il " + "soit idiomatique dans la langue cible indiquée Ce texte est " + "uniquement utilisé pour tester la détection de la langue."; + +const std::string kTextGerman = + "Dies ist ein mit Google Translate erstellter Text. Es ist " + "unwahrscheinlich, dass er in der angegebenen Zielsprache idiomatisch " + "ist. Dieser Text wird nur zum Testen der Spracherkennung verwendet."; + +// This test fixture is a friend of classes in ax_language_detection.h in order +// to enable testing of internals. +// +// When used with TEST_F, the test body is a subclass of this fixture, so we +// need to re-expose any members through this fixture in order for them to +// be accessible from within the test body. +class AXLanguageDetectionTestFixture : public testing::Test { + public: + AXLanguageDetectionTestFixture() = default; + ~AXLanguageDetectionTestFixture() override = default; + + protected: + AXLanguageDetectionObserver* getObserver(AXTree& tree) { + return tree.language_detection_manager->language_detection_observer_.get(); + } + + private: + DISALLOW_COPY_AND_ASSIGN(AXLanguageDetectionTestFixture); +}; + +class AXLanguageDetectionTestStaticContent + : public AXLanguageDetectionTestFixture { + public: + AXLanguageDetectionTestStaticContent() = default; + ~AXLanguageDetectionTestStaticContent() override = default; + + void SetUp() override { + AXLanguageDetectionTestFixture::SetUp(); + + base::CommandLine::ForCurrentProcess()->AppendSwitch( + ::switches::kEnableExperimentalAccessibilityLanguageDetection); + } +}; + +class AXLanguageDetectionTestDynamicContent + : public AXLanguageDetectionTestStaticContent { + public: + AXLanguageDetectionTestDynamicContent() = default; + ~AXLanguageDetectionTestDynamicContent() override = default; + + void SetUp() override { + AXLanguageDetectionTestStaticContent::SetUp(); + + base::CommandLine::ForCurrentProcess()->AppendSwitch( + ::switches::kEnableExperimentalAccessibilityLanguageDetectionDynamic); + } +}; + +TEST(AXLanguageDetectionTest, StaticContentFeatureFlag) { // TODO(crbug/889370): Remove this test once this feature is stable EXPECT_FALSE( ::switches::IsExperimentalAccessibilityLanguageDetectionEnabled()); @@ -42,62 +105,6 @@ ::switches::IsExperimentalAccessibilityLanguageDetectionDynamicEnabled()); } -// Tests that AXNode::GetLanguage() terminates when there is no lang attribute. -TEST(AXLanguageDetectionTest, BoringTree) { - base::CommandLine::ForCurrentProcess()->AppendSwitch( - ::switches::kEnableExperimentalAccessibilityLanguageDetection); - - // This test checks the behaviour of Detect, Label, and GetLanguage on a - // 'boring' tree. - // - // The tree built here contains no lang attributes, nor does it contain any - // text to perform detection on. - // - // Tree: - // 1 - // 2 3 - // 4 - AXTreeUpdate initial_state; - initial_state.root_id = 1; - initial_state.nodes.resize(4); - initial_state.nodes[0].id = 1; - initial_state.nodes[0].child_ids.resize(2); - initial_state.nodes[0].child_ids[0] = 2; - initial_state.nodes[0].child_ids[1] = 3; - initial_state.nodes[1].id = 2; - initial_state.nodes[1].child_ids.resize(1); - initial_state.nodes[1].child_ids[0] = 4; - initial_state.nodes[2].id = 3; - initial_state.nodes[3].id = 4; - - AXTree tree(initial_state); - ASSERT_NE(tree.language_detection_manager, nullptr); - tree.language_detection_manager->DetectLanguages(tree.root()); - tree.language_detection_manager->LabelLanguages(tree.root()); - - // Check that tree parenting conforms to expected shape. - AXNode* node1 = tree.GetFromId(1); - EXPECT_EQ(node1->parent(), nullptr); - - AXNode* node2 = tree.GetFromId(2); - ASSERT_EQ(node2->parent(), node1); - EXPECT_EQ(node2->parent()->parent(), nullptr); - - AXNode* node3 = tree.GetFromId(3); - ASSERT_EQ(node3->parent(), node1); - EXPECT_EQ(node3->parent()->parent(), nullptr); - - AXNode* node4 = tree.GetFromId(4); - ASSERT_EQ(node4->parent(), node2); - ASSERT_EQ(node4->parent()->parent(), node1); - EXPECT_EQ(node4->parent()->parent()->parent(), nullptr); - - EXPECT_EQ(node1->GetLanguage(), ""); - EXPECT_EQ(node2->GetLanguage(), ""); - EXPECT_EQ(node3->GetLanguage(), ""); - EXPECT_EQ(node4->GetLanguage(), ""); -} - TEST(AXLanguageDetectionTest, LangAttrInheritanceFeatureFlagOff) { // Test lang attribute inheritance when feature flag is off. // @@ -161,8 +168,8 @@ AXTree tree(initial_state); ASSERT_NE(tree.language_detection_manager, nullptr); - tree.language_detection_manager->DetectLanguages(tree.root()); - tree.language_detection_manager->LabelLanguages(tree.root()); + tree.language_detection_manager->DetectLanguages(); + tree.language_detection_manager->LabelLanguages(); { AXNode* node1 = tree.GetFromId(1); @@ -262,8 +269,8 @@ AXTree tree(initial_state); ASSERT_NE(tree.language_detection_manager, nullptr); - tree.language_detection_manager->DetectLanguages(tree.root()); - tree.language_detection_manager->LabelLanguages(tree.root()); + tree.language_detection_manager->DetectLanguages(); + tree.language_detection_manager->LabelLanguages(); { AXNode* node1 = tree.GetFromId(1); @@ -300,10 +307,60 @@ } } -TEST(AXLanguageDetectionTest, LanguageDetectionBasic) { - base::CommandLine::ForCurrentProcess()->AppendSwitch( - ::switches::kEnableExperimentalAccessibilityLanguageDetection); +// Tests that AXNode::GetLanguage() terminates when there is no lang attribute. +TEST_F(AXLanguageDetectionTestStaticContent, GetLanguageBoringTree) { + // This test checks the behaviour of Detect, Label, and GetLanguage on a + // 'boring' tree. + // + // The tree built here contains no lang attributes, nor does it contain any + // text to perform detection on. + // + // Tree: + // 1 + // 2 3 + // 4 + AXTreeUpdate initial_state; + initial_state.root_id = 1; + initial_state.nodes.resize(4); + initial_state.nodes[0].id = 1; + initial_state.nodes[0].child_ids.resize(2); + initial_state.nodes[0].child_ids[0] = 2; + initial_state.nodes[0].child_ids[1] = 3; + initial_state.nodes[1].id = 2; + initial_state.nodes[1].child_ids.resize(1); + initial_state.nodes[1].child_ids[0] = 4; + initial_state.nodes[2].id = 3; + initial_state.nodes[3].id = 4; + AXTree tree(initial_state); + ASSERT_NE(tree.language_detection_manager, nullptr); + tree.language_detection_manager->DetectLanguages(); + tree.language_detection_manager->LabelLanguages(); + + // Check that tree parenting conforms to expected shape. + AXNode* node1 = tree.GetFromId(1); + EXPECT_EQ(node1->parent(), nullptr); + + AXNode* node2 = tree.GetFromId(2); + ASSERT_EQ(node2->parent(), node1); + EXPECT_EQ(node2->parent()->parent(), nullptr); + + AXNode* node3 = tree.GetFromId(3); + ASSERT_EQ(node3->parent(), node1); + EXPECT_EQ(node3->parent()->parent(), nullptr); + + AXNode* node4 = tree.GetFromId(4); + ASSERT_EQ(node4->parent(), node2); + ASSERT_EQ(node4->parent()->parent(), node1); + EXPECT_EQ(node4->parent()->parent()->parent(), nullptr); + + EXPECT_EQ(node1->GetLanguage(), ""); + EXPECT_EQ(node2->GetLanguage(), ""); + EXPECT_EQ(node3->GetLanguage(), ""); + EXPECT_EQ(node4->GetLanguage(), ""); +} + +TEST_F(AXLanguageDetectionTestStaticContent, Basic) { // Tree: // 1 // 2 3 @@ -347,11 +404,7 @@ AXNodeData& node3 = initial_state.nodes[2]; node3.id = 3; node3.role = ax::mojom::Role::kStaticText; - std::string node3_text = - "Ce texte a été créé avec Google Translate, il est peu probable qu'il " - "soit idiomatique dans la langue cible indiquée Ce texte est " - "uniquement utilisé pour tester la détection de la langue."; - node3.AddStringAttribute(ax::mojom::StringAttribute::kName, node3_text); + node3.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextFrench); } { @@ -360,23 +413,20 @@ node4.child_ids.resize(1); node4.child_ids[0] = 5; node4.role = ax::mojom::Role::kStaticText; - std::string node4_text = - "This is text created using Google Translate, it is unlikely to be " - "idiomatic in the given target language. This text is only used to " - "test language detection"; - node4.AddStringAttribute(ax::mojom::StringAttribute::kName, node4_text); + node4.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextEnglish); } { AXNodeData& node5 = initial_state.nodes[4]; node5.id = 5; node5.role = ax::mojom::Role::kInlineTextBox; + node5.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextEnglish); } AXTree tree(initial_state); ASSERT_NE(tree.language_detection_manager, nullptr); - tree.language_detection_manager->DetectLanguages(tree.root()); - tree.language_detection_manager->LabelLanguages(tree.root()); + tree.language_detection_manager->DetectLanguages(); + tree.language_detection_manager->LabelLanguages(); { AXNode* node1 = tree.GetFromId(1); @@ -415,10 +465,7 @@ } } -TEST(AXLanguageDetectionTest, LanguageDetectionDetectOnly) { - base::CommandLine::ForCurrentProcess()->AppendSwitch( - ::switches::kEnableExperimentalAccessibilityLanguageDetection); - +TEST_F(AXLanguageDetectionTestStaticContent, DetectOnly) { // This tests a Detect step without any matching Label step. // // Tree: @@ -464,11 +511,7 @@ AXNodeData& node3 = initial_state.nodes[2]; node3.id = 3; node3.role = ax::mojom::Role::kStaticText; - std::string node3_text = - "Ce texte a été créé avec Google Translate, il est peu probable qu'il " - "soit idiomatique dans la langue cible indiquée Ce texte est " - "uniquement utilisé pour tester la détection de la langue."; - node3.AddStringAttribute(ax::mojom::StringAttribute::kName, node3_text); + node3.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextFrench); } { @@ -477,22 +520,19 @@ node4.child_ids.resize(1); node4.child_ids[0] = 5; node4.role = ax::mojom::Role::kStaticText; - std::string node4_text = - "This is text created using Google Translate, it is unlikely to be " - "idiomatic in the given target language. This text is only used to " - "test language detection"; - node4.AddStringAttribute(ax::mojom::StringAttribute::kName, node4_text); + node4.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextEnglish); } { AXNodeData& node5 = initial_state.nodes[4]; node5.id = 5; node5.role = ax::mojom::Role::kInlineTextBox; + node5.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextEnglish); } AXTree tree(initial_state); ASSERT_NE(tree.language_detection_manager, nullptr); - tree.language_detection_manager->DetectLanguages(tree.root()); + tree.language_detection_manager->DetectLanguages(); // Purposefully not calling Label so we can test Detect in isolation. { @@ -538,10 +578,7 @@ } } -TEST(AXLanguageDetectionTest, kLanguageUntouched) { - base::CommandLine::ForCurrentProcess()->AppendSwitch( - ::switches::kEnableExperimentalAccessibilityLanguageDetection); - +TEST_F(AXLanguageDetectionTestStaticContent, kLanguageUntouched) { // This test is to ensure that the kLanguage string attribute is not updated // during language detection and labelling, even when it disagrees with the // detected language. @@ -572,11 +609,7 @@ node2.id = 2; node2.role = ax::mojom::Role::kStaticText; node2.AddStringAttribute(ax::mojom::StringAttribute::kLanguage, "en"); - std::string node2_text = - "Ce texte a été créé avec Google Translate, il est peu probable qu'il " - "soit idiomatique dans la langue cible indiquée Ce texte est " - "uniquement utilisé pour tester la détection de la langue."; - node2.AddStringAttribute(ax::mojom::StringAttribute::kName, node2_text); + node2.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextFrench); } { @@ -584,17 +617,13 @@ node3.id = 3; node3.role = ax::mojom::Role::kStaticText; node3.AddStringAttribute(ax::mojom::StringAttribute::kLanguage, "fr"); - std::string node3_text = - "This is text created using Google Translate, it is unlikely to be " - "idiomatic in the given target language. This text is only used to " - "test language detection"; - node3.AddStringAttribute(ax::mojom::StringAttribute::kName, node3_text); + node3.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextEnglish); } AXTree tree(initial_state); ASSERT_NE(tree.language_detection_manager, nullptr); - tree.language_detection_manager->DetectLanguages(tree.root()); - tree.language_detection_manager->LabelLanguages(tree.root()); + tree.language_detection_manager->DetectLanguages(); + tree.language_detection_manager->LabelLanguages(); { AXNode* node1 = tree.GetFromId(1); @@ -623,6 +652,502 @@ } } +// Test RegisterLanguageDetectionObserver correctly respects the feature flag. +TEST_F(AXLanguageDetectionTestFixture, ObserverRegistrationObeysFlag) { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + ::switches::kEnableExperimentalAccessibilityLanguageDetection); + + // Construct empty tree and check initialisation. + AXTree tree; + ASSERT_NE(tree.language_detection_manager, nullptr); + ASSERT_EQ(getObserver(tree), nullptr); + + // Try registration without enabling Dynamic feature flag, should be a no-op. + tree.language_detection_manager->RegisterLanguageDetectionObserver(); + + ASSERT_EQ(getObserver(tree), nullptr); + + base::CommandLine::ForCurrentProcess()->AppendSwitch( + ::switches::kEnableExperimentalAccessibilityLanguageDetectionDynamic); + + // Try registration without turning on Dynamic feature flag, this should + // do nothing. + tree.language_detection_manager->RegisterLanguageDetectionObserver(); + + // Check our observer was constructed. + ASSERT_NE(getObserver(tree), nullptr); + + // Check our observer was registered in our tree. + ASSERT_TRUE(tree.HasObserver(getObserver(tree))); +} + +TEST_F(AXLanguageDetectionTestDynamicContent, Basic) { + // Tree: + // 1 + // 2 + // + // 1 - kStaticText - English text. + // 2 - kInlineTextBox - English text. + AXTreeUpdate initial_state; + initial_state.root_id = 1; + initial_state.nodes.resize(2); + + // TODO(chrishall): Create more realistic kStaticText with multiple + // kInlineTextBox(es) children. Look at the real-world behaviour of + // kStaticText, kInlineText and kLineBreak around empty divs and empty lines + // within paragraphs of text. + + { + AXNodeData& node1 = initial_state.nodes[0]; + node1.id = 1; + node1.role = ax::mojom::Role::kStaticText; + node1.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextEnglish); + node1.child_ids.resize(1); + node1.child_ids[0] = 2; + } + + { + AXNodeData& node2 = initial_state.nodes[1]; + node2.id = 2; + node2.role = ax::mojom::Role::kInlineTextBox; + node2.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextEnglish); + } + + AXTree tree(initial_state); + ASSERT_NE(tree.language_detection_manager, nullptr); + + // Manually run initial language detection and labelling. + tree.language_detection_manager->DetectLanguages(); + tree.language_detection_manager->LabelLanguages(); + + // Quickly verify "before" state + { + AXNode* node1 = tree.GetFromId(1); + ASSERT_NE(node1, nullptr); + ASSERT_NE(node1->GetLanguageInfo(), nullptr); + ASSERT_EQ(node1->GetLanguage(), "en"); + + AXNode* node2 = tree.GetFromId(2); + ASSERT_NE(node2, nullptr); + // Inherited language not stored in lang info. + ASSERT_EQ(node2->GetLanguageInfo(), nullptr); + // Should still inherit language from parent. + ASSERT_EQ(node2->GetLanguage(), "en"); + } + + // Manually register observer. + AXLanguageDetectionObserver observer(&tree); + + // Observer constructor is responsible for attaching itself to tree. + ASSERT_TRUE(tree.HasObserver(&observer)); + + // Dynamic update + // + // New tree: + // 1 + // 2 + // + // 1 - Text changed to German. + // 2 - Text changed to German. + AXTreeUpdate update_state; + update_state.root_id = 1; + update_state.nodes.resize(2); + + // Change text to German. + { + AXNodeData& node1 = update_state.nodes[0]; + node1.id = 1; + node1.role = ax::mojom::Role::kStaticText; + node1.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextGerman); + node1.child_ids.resize(1); + node1.child_ids[0] = 2; + } + + { + AXNodeData& node2 = update_state.nodes[1]; + node2.id = 2; + node2.role = ax::mojom::Role::kInlineTextBox; + node2.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextGerman); + } + + // Perform update. + ASSERT_TRUE(tree.Unserialize(update_state)); + + // Check language detection was re-run on new content. + { + AXNode* node1 = tree.GetFromId(1); + ASSERT_NE(node1, nullptr); + ASSERT_NE(node1->GetLanguageInfo(), nullptr); + ASSERT_EQ(node1->GetLanguage(), "de"); + } + + { + AXNode* node2 = tree.GetFromId(2); + ASSERT_NE(node2, nullptr); + // Inherited language not stored in lang info. + ASSERT_EQ(node2->GetLanguageInfo(), nullptr); + // Should inherit new language from parent. + ASSERT_EQ(node2->GetLanguage(), "de"); + } +} + +TEST_F(AXLanguageDetectionTestDynamicContent, MultipleUpdates) { + // This test runs language detection a total of 3 times, once for the initial + // 'static' content, and then twice for 'dynamic' updates. + + // Tree: + // 1 + // 2 + // + // 1 - GenericContainer + // 2 - English text + AXTreeUpdate initial_state; + initial_state.root_id = 1; + initial_state.nodes.resize(2); + + { + AXNodeData& node1 = initial_state.nodes[0]; + node1.id = 1; + node1.role = ax::mojom::Role::kGenericContainer; + node1.child_ids.resize(1); + node1.child_ids[0] = 2; + } + + { + AXNodeData& node2 = initial_state.nodes[1]; + node2.id = 2; + node2.role = ax::mojom::Role::kStaticText; + node2.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextEnglish); + } + + AXTree tree(initial_state); + ASSERT_NE(tree.language_detection_manager, nullptr); + + // Run initial language detection and labelling. + tree.language_detection_manager->DetectLanguages(); + tree.language_detection_manager->LabelLanguages(); + + // Quickly verify "before" state + { + AXNode* node1 = tree.GetFromId(1); + ASSERT_NE(node1, nullptr); + ASSERT_EQ(node1->GetLanguage(), ""); + + AXNode* node2 = tree.GetFromId(2); + ASSERT_NE(node2, nullptr); + ASSERT_EQ(node2->GetLanguage(), "en"); + } + + // Register dynamic content observer. + tree.language_detection_manager->RegisterLanguageDetectionObserver(); + ASSERT_NE(getObserver(tree), nullptr); + ASSERT_TRUE(tree.HasObserver(getObserver(tree))); + + // First update + { + // Dynamic update + // + // New tree layout will be: + // 1 + // 2 3 + // + // 1 - GenericContainer, unchanged + // 2 - changed to German text + // 3 - new child, French text + AXTreeUpdate update_state; + update_state.root_id = 1; + update_state.nodes.resize(3); + + // Update node1 to include new child node3. + { + AXNodeData& node1 = update_state.nodes[0]; + node1.id = 1; + node1.role = ax::mojom::Role::kGenericContainer; + node1.child_ids.resize(2); + node1.child_ids[0] = 2; + node1.child_ids[1] = 3; + } + + // Change node2 text to German + { + AXNodeData& node2 = update_state.nodes[1]; + node2.id = 2; + node2.role = ax::mojom::Role::kStaticText; + node2.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextGerman); + } + + // Add new node3 with French text. + { + AXNodeData& node3 = update_state.nodes[2]; + node3.id = 3; + node3.role = ax::mojom::Role::kStaticText; + node3.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextFrench); + } + + // Perform update. + ASSERT_TRUE(tree.Unserialize(update_state)); + + { + AXNode* node1 = tree.GetFromId(1); + ASSERT_NE(node1, nullptr); + ASSERT_EQ(node1->GetLanguage(), ""); + } + + { + // Detection should have been re-run on node2, detecting German. + AXNode* node2 = tree.GetFromId(2); + ASSERT_NE(node2, nullptr); + ASSERT_EQ(node2->GetLanguage(), "de"); + } + + { + // New node3 should have detected French. + AXNode* node3 = tree.GetFromId(3); + ASSERT_NE(node3, nullptr); + ASSERT_EQ(node3->GetLanguage(), "fr"); + } + } + + // Second update + { + // Dynamic update + // + // New tree layout will be: + // 1 + // 2 x + // + // 1 - GenericContainer, unchanged + // 2 - changed to French text + // 3 - deleted + AXTreeUpdate update_state; + update_state.root_id = 1; + update_state.nodes.resize(2); + + // Update node1 to delete child node3. + { + AXNodeData& node1 = update_state.nodes[0]; + node1.id = 1; + node1.role = ax::mojom::Role::kGenericContainer; + node1.child_ids.resize(1); + node1.child_ids[0] = 2; + } + + // Change node2 text to French + { + AXNodeData& node2 = update_state.nodes[1]; + node2.id = 2; + node2.role = ax::mojom::Role::kStaticText; + node2.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextFrench); + } + + // Perform update. + ASSERT_TRUE(tree.Unserialize(update_state)); + + { + AXNode* node1 = tree.GetFromId(1); + ASSERT_NE(node1, nullptr); + ASSERT_EQ(node1->GetLanguage(), ""); + } + + { + // Detection should have been re-run on node2, detecting French. + AXNode* node2 = tree.GetFromId(2); + ASSERT_NE(node2, nullptr); + ASSERT_EQ(node2->GetLanguage(), "fr"); + } + + { + // Node3 should be no more. + AXNode* node3 = tree.GetFromId(3); + ASSERT_EQ(node3, nullptr); + } + } + + // Third update. + { + // Dynamic update + // + // New tree layout will be: + // 1 + // 2 3 + // + // 1 - GenericContainer, unchanged + // 2 - French text, unchanged + // 3 - new node, German text + AXTreeUpdate update_state; + update_state.root_id = 1; + update_state.nodes.resize(2); + + // Update node1 to include new child node3. + { + AXNodeData& node1 = update_state.nodes[0]; + node1.id = 1; + node1.role = ax::mojom::Role::kGenericContainer; + node1.child_ids.resize(2); + node1.child_ids[0] = 2; + node1.child_ids[1] = 3; + } + + // Add new node3 with German text. + { + AXNodeData& node3 = update_state.nodes[1]; + node3.id = 3; + node3.role = ax::mojom::Role::kStaticText; + node3.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextGerman); + } + + // Perform update. + ASSERT_TRUE(tree.Unserialize(update_state)); + + { + AXNode* node1 = tree.GetFromId(1); + ASSERT_NE(node1, nullptr); + ASSERT_EQ(node1->GetLanguage(), ""); + } + + { + AXNode* node2 = tree.GetFromId(2); + ASSERT_NE(node2, nullptr); + ASSERT_EQ(node2->GetLanguage(), "fr"); + } + + { + AXNode* node3 = tree.GetFromId(3); + ASSERT_NE(node3, nullptr); + ASSERT_EQ(node3->GetLanguage(), "de"); + } + } +} + +TEST_F(AXLanguageDetectionTestDynamicContent, NewRoot) { + // Artificial test change which changes the root node. + + // Tree: + // 1 + // + // 1 - GenericContainer + AXTreeUpdate initial_state; + initial_state.root_id = 1; + initial_state.nodes.resize(1); + + { + AXNodeData& node1 = initial_state.nodes[0]; + node1.id = 1; + node1.role = ax::mojom::Role::kGenericContainer; + } + + AXTree tree(initial_state); + ASSERT_NE(tree.language_detection_manager, nullptr); + + // Run initial language detection and labelling. + tree.language_detection_manager->DetectLanguages(); + tree.language_detection_manager->LabelLanguages(); + + // Register dynamic content observer. + tree.language_detection_manager->RegisterLanguageDetectionObserver(); + ASSERT_NE(getObserver(tree), nullptr); + ASSERT_TRUE(tree.HasObserver(getObserver(tree))); + + // New Tree: + // 2 + // 2 - new root, German text + + AXTreeUpdate update_state; + update_state.root_id = 2; + update_state.nodes.resize(1); + + { + AXNodeData& node2 = update_state.nodes[0]; + node2.id = 2; + node2.role = ax::mojom::Role::kStaticText; + node2.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextGerman); + } + + // Perform update. + ASSERT_TRUE(tree.Unserialize(update_state)); + + { + AXNode* node2 = tree.GetFromId(2); + ASSERT_NE(node2, nullptr); + ASSERT_EQ(node2->GetLanguage(), "de"); + } +} + +TEST_F(AXLanguageDetectionTestDynamicContent, ChainOfNewNodes) { + // Artificial test which adds two new nodes in a 'chain', simultaneously + // adding a child of the root and a grandchild of the root. + + // Tree: + // 1 + // + // 1 - GenericContainer + AXTreeUpdate initial_state; + initial_state.root_id = 1; + initial_state.nodes.resize(1); + + { + AXNodeData& node1 = initial_state.nodes[0]; + node1.id = 1; + node1.role = ax::mojom::Role::kGenericContainer; + } + + AXTree tree(initial_state); + ASSERT_NE(tree.language_detection_manager, nullptr); + + // Run initial language detection and labelling. + tree.language_detection_manager->DetectLanguages(); + tree.language_detection_manager->LabelLanguages(); + + // Register dynamic content observer. + tree.language_detection_manager->RegisterLanguageDetectionObserver(); + ASSERT_NE(getObserver(tree), nullptr); + ASSERT_TRUE(tree.HasObserver(getObserver(tree))); + + // New Tree: + // 1 + // 2 + // 3 + // 1 - generic container + // 2 - generic container + // 3 - German text + + AXTreeUpdate update_state; + update_state.root_id = 1; + update_state.nodes.resize(3); + + { + AXNodeData& node1 = update_state.nodes[0]; + node1.id = 1; + node1.role = ax::mojom::Role::kGenericContainer; + node1.child_ids.resize(1); + node1.child_ids[0] = 2; + } + + { + AXNodeData& node2 = update_state.nodes[1]; + node2.id = 2; + node2.role = ax::mojom::Role::kGenericContainer; + node2.child_ids.resize(1); + node2.child_ids[0] = 3; + } + + { + AXNodeData& node3 = update_state.nodes[2]; + node3.id = 3; + node3.role = ax::mojom::Role::kStaticText; + node3.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextGerman); + } + + // Perform update. + ASSERT_TRUE(tree.Unserialize(update_state)); + + { + AXNode* node3 = tree.GetFromId(3); + ASSERT_NE(node3, nullptr); + ASSERT_EQ(node3->GetLanguage(), "de"); + } +} + TEST(AXLanguageDetectionTest, AXLanguageInfoStatsBasic) { AXLanguageInfoStats stats;
diff --git a/ui/accessibility/ax_tree.cc b/ui/accessibility/ax_tree.cc index 71b38686..de66a7d6 100644 --- a/ui/accessibility/ax_tree.cc +++ b/ui/accessibility/ax_tree.cc
@@ -577,13 +577,15 @@ // TODO(chrishall): do we want to initialize all the time, on demand, or only // when feature flag is set? DCHECK(!language_detection_manager); - language_detection_manager = std::make_unique<AXLanguageDetectionManager>(); + language_detection_manager = + std::make_unique<AXLanguageDetectionManager>(this); } AXTree::AXTree(const AXTreeUpdate& initial_state) { CHECK(Unserialize(initial_state)) << error(); DCHECK(!language_detection_manager); - language_detection_manager = std::make_unique<AXLanguageDetectionManager>(); + language_detection_manager = + std::make_unique<AXLanguageDetectionManager>(this); } AXTree::~AXTree() {
diff --git a/ui/base/clipboard/clipboard_android.cc b/ui/base/clipboard/clipboard_android.cc index e5e8275..9d9c5c50 100644 --- a/ui/base/clipboard/clipboard_android.cc +++ b/ui/base/clipboard/clipboard_android.cc
@@ -479,7 +479,7 @@ size_t title_len, const char* url_data, size_t url_len) { - g_map.Get().Set(ClipboardFormatType::GetUrlWType().ToString(), + g_map.Get().Set(ClipboardFormatType::GetUrlType().ToString(), std::string(url_data, url_len)); }
diff --git a/ui/base/clipboard/clipboard_format_type.h b/ui/base/clipboard/clipboard_format_type.h index 741c064..46b4524 100644 --- a/ui/base/clipboard/clipboard_format_type.h +++ b/ui/base/clipboard/clipboard_format_type.h
@@ -47,12 +47,9 @@ // Get format identifiers for various types. static const ClipboardFormatType& GetUrlType(); - static const ClipboardFormatType& GetUrlWType(); static const ClipboardFormatType& GetMozUrlType(); static const ClipboardFormatType& GetPlainTextType(); - static const ClipboardFormatType& GetPlainTextWType(); static const ClipboardFormatType& GetFilenameType(); - static const ClipboardFormatType& GetFilenameWType(); static const ClipboardFormatType& GetWebKitSmartPasteType(); // Win: MS HTML Format, Other: Generic HTML format static const ClipboardFormatType& GetHtmlType(); @@ -64,11 +61,18 @@ static const ClipboardFormatType& GetPepperCustomDataType(); #if defined(OS_WIN) + // ANSI formats. Only Windows differentiates between ANSI and UNICODE formats + // in ClipboardFormatType. Reference: + // https://docs.microsoft.com/en-us/windows/win32/learnwin32/working-with-strings + static const ClipboardFormatType& GetUrlAType(); + static const ClipboardFormatType& GetPlainTextAType(); + static const ClipboardFormatType& GetFilenameAType(); + // Firefox text/html static const ClipboardFormatType& GetTextHtmlType(); static const ClipboardFormatType& GetCFHDropType(); + static const ClipboardFormatType& GetFileDescriptorAType(); static const ClipboardFormatType& GetFileDescriptorType(); - static const ClipboardFormatType& GetFileDescriptorWType(); static const ClipboardFormatType& GetFileContentZeroType(); static const ClipboardFormatType& GetFileContentAtIndexType(LONG index); static const ClipboardFormatType& GetIDListType();
diff --git a/ui/base/clipboard/clipboard_format_type_android.cc b/ui/base/clipboard/clipboard_format_type_android.cc index d4f76ba0..75a8ba08 100644 --- a/ui/base/clipboard/clipboard_format_type_android.cc +++ b/ui/base/clipboard/clipboard_format_type_android.cc
@@ -43,7 +43,7 @@ } // static -const ClipboardFormatType& ClipboardFormatType::GetUrlWType() { +const ClipboardFormatType& ClipboardFormatType::GetUrlType() { static base::NoDestructor<ClipboardFormatType> type(kMimeTypeURIList); return *type; } @@ -55,12 +55,6 @@ } // static -const ClipboardFormatType& ClipboardFormatType::GetPlainTextWType() { - static base::NoDestructor<ClipboardFormatType> type(kMimeTypeText); - return *type; -} - -// static const ClipboardFormatType& ClipboardFormatType::GetWebKitSmartPasteType() { static base::NoDestructor<ClipboardFormatType> type( kMimeTypeWebkitSmartPaste);
diff --git a/ui/base/clipboard/clipboard_format_type_aura.cc b/ui/base/clipboard/clipboard_format_type_aura.cc index d67163b..4ef0a180 100644 --- a/ui/base/clipboard/clipboard_format_type_aura.cc +++ b/ui/base/clipboard/clipboard_format_type_aura.cc
@@ -56,11 +56,6 @@ } // static -const ClipboardFormatType& ClipboardFormatType::GetUrlWType() { - return ClipboardFormatType::GetUrlType(); -} - -// static const ClipboardFormatType& ClipboardFormatType::GetMozUrlType() { static base::NoDestructor<ClipboardFormatType> type(kMimeTypeMozillaURL); return *type; @@ -73,22 +68,12 @@ } // static -const ClipboardFormatType& ClipboardFormatType::GetPlainTextWType() { - return ClipboardFormatType::GetPlainTextType(); -} - -// static const ClipboardFormatType& ClipboardFormatType::GetFilenameType() { static base::NoDestructor<ClipboardFormatType> type(kMimeTypeFilename); return *type; } // static -const ClipboardFormatType& ClipboardFormatType::GetFilenameWType() { - return ClipboardFormatType::GetFilenameType(); -} - -// static const ClipboardFormatType& ClipboardFormatType::GetHtmlType() { static base::NoDestructor<ClipboardFormatType> type(kMimeTypeHTML); return *type;
diff --git a/ui/base/clipboard/clipboard_format_type_mac.mm b/ui/base/clipboard/clipboard_format_type_mac.mm index 61774f8..4dbe0651 100644 --- a/ui/base/clipboard/clipboard_format_type_mac.mm +++ b/ui/base/clipboard/clipboard_format_type_mac.mm
@@ -66,33 +66,18 @@ } // static -const ClipboardFormatType& ClipboardFormatType::GetUrlWType() { - return ClipboardFormatType::GetUrlType(); -} - -// static const ClipboardFormatType& ClipboardFormatType::GetPlainTextType() { static base::NoDestructor<ClipboardFormatType> type(NSPasteboardTypeString); return *type; } // static -const ClipboardFormatType& ClipboardFormatType::GetPlainTextWType() { - return ClipboardFormatType::GetPlainTextType(); -} - -// static const ClipboardFormatType& ClipboardFormatType::GetFilenameType() { static base::NoDestructor<ClipboardFormatType> type(NSFilenamesPboardType); return *type; } // static -const ClipboardFormatType& ClipboardFormatType::GetFilenameWType() { - return ClipboardFormatType::GetFilenameType(); -} - -// static const ClipboardFormatType& ClipboardFormatType::GetHtmlType() { static base::NoDestructor<ClipboardFormatType> type(NSHTMLPboardType); return *type;
diff --git a/ui/base/clipboard/clipboard_format_type_win.cc b/ui/base/clipboard/clipboard_format_type_win.cc index 8b3d0ee4..94823f3 100644 --- a/ui/base/clipboard/clipboard_format_type_win.cc +++ b/ui/base/clipboard/clipboard_format_type_win.cc
@@ -87,13 +87,6 @@ // static const ClipboardFormatType& ClipboardFormatType::GetUrlType() { static base::NoDestructor<ClipboardFormatType> format( - ::RegisterClipboardFormat(CFSTR_INETURLA)); - return *format; -} - -// static -const ClipboardFormatType& ClipboardFormatType::GetUrlWType() { - static base::NoDestructor<ClipboardFormatType> format( ::RegisterClipboardFormat(CFSTR_INETURLW)); return *format; } @@ -107,12 +100,6 @@ // static const ClipboardFormatType& ClipboardFormatType::GetPlainTextType() { - static base::NoDestructor<ClipboardFormatType> format(CF_TEXT); - return *format; -} - -// static -const ClipboardFormatType& ClipboardFormatType::GetPlainTextWType() { static base::NoDestructor<ClipboardFormatType> format(CF_UNICODETEXT); return *format; } @@ -120,13 +107,6 @@ // static const ClipboardFormatType& ClipboardFormatType::GetFilenameType() { static base::NoDestructor<ClipboardFormatType> format( - ::RegisterClipboardFormat(CFSTR_FILENAMEA)); - return *format; -} - -// static -const ClipboardFormatType& ClipboardFormatType::GetFilenameWType() { - static base::NoDestructor<ClipboardFormatType> format( ::RegisterClipboardFormat(CFSTR_FILENAMEW)); return *format; } @@ -155,9 +135,28 @@ return *format; } -// Firefox text/html +// static +const ClipboardFormatType& ClipboardFormatType::GetUrlAType() { + static base::NoDestructor<ClipboardFormatType> format( + ::RegisterClipboardFormat(CFSTR_INETURLA)); + return *format; +} // static +const ClipboardFormatType& ClipboardFormatType::GetPlainTextAType() { + static base::NoDestructor<ClipboardFormatType> format(CF_TEXT); + return *format; +} + +// static +const ClipboardFormatType& ClipboardFormatType::GetFilenameAType() { + static base::NoDestructor<ClipboardFormatType> format( + ::RegisterClipboardFormat(CFSTR_FILENAMEA)); + return *format; +} + +// Firefox text/html +// static const ClipboardFormatType& ClipboardFormatType::GetTextHtmlType() { static base::NoDestructor<ClipboardFormatType> format( ::RegisterClipboardFormat(L"text/html")); @@ -174,14 +173,14 @@ // ANSI format (e.g., it could be that it doesn't support Unicode). So need to // register both the ANSI and Unicode file group descriptors. // static -const ClipboardFormatType& ClipboardFormatType::GetFileDescriptorType() { +const ClipboardFormatType& ClipboardFormatType::GetFileDescriptorAType() { static base::NoDestructor<ClipboardFormatType> format( ::RegisterClipboardFormat(CFSTR_FILEDESCRIPTORA)); return *format; } // static -const ClipboardFormatType& ClipboardFormatType::GetFileDescriptorWType() { +const ClipboardFormatType& ClipboardFormatType::GetFileDescriptorType() { static base::NoDestructor<ClipboardFormatType> format( ::RegisterClipboardFormat(CFSTR_FILEDESCRIPTORW)); return *format;
diff --git a/ui/base/clipboard/clipboard_test_template.h b/ui/base/clipboard/clipboard_test_template.h index 03e86d9..ece02de 100644 --- a/ui/base/clipboard/clipboard_test_template.h +++ b/ui/base/clipboard/clipboard_test_template.h
@@ -113,9 +113,11 @@ EXPECT_TRUE(this->GetAvailableTypes(ClipboardBuffer::kCopyPaste).empty()); EXPECT_FALSE(this->clipboard().IsFormatAvailable( - ClipboardFormatType::GetPlainTextWType(), ClipboardBuffer::kCopyPaste)); - EXPECT_FALSE(this->clipboard().IsFormatAvailable( ClipboardFormatType::GetPlainTextType(), ClipboardBuffer::kCopyPaste)); +#if defined(OS_WIN) + EXPECT_FALSE(this->clipboard().IsFormatAvailable( + ClipboardFormatType::GetPlainTextAType(), ClipboardBuffer::kCopyPaste)); +#endif } TYPED_TEST(ClipboardTest, TextTest) { @@ -130,9 +132,12 @@ EXPECT_THAT(this->GetAvailableTypes(ClipboardBuffer::kCopyPaste), Contains(ASCIIToUTF16(kMimeTypeText))); EXPECT_TRUE(this->clipboard().IsFormatAvailable( - ClipboardFormatType::GetPlainTextWType(), ClipboardBuffer::kCopyPaste)); - EXPECT_TRUE(this->clipboard().IsFormatAvailable( ClipboardFormatType::GetPlainTextType(), ClipboardBuffer::kCopyPaste)); +#if defined(OS_WIN) + EXPECT_TRUE(this->clipboard().IsFormatAvailable( + ClipboardFormatType::GetPlainTextAType(), ClipboardBuffer::kCopyPaste)); +#endif + this->clipboard().ReadText(ClipboardBuffer::kCopyPaste, &text_result); EXPECT_EQ(text, text_result); @@ -306,7 +311,7 @@ } EXPECT_TRUE(this->clipboard().IsFormatAvailable( - ClipboardFormatType::GetUrlWType(), ClipboardBuffer::kCopyPaste)); + ClipboardFormatType::GetUrlType(), ClipboardBuffer::kCopyPaste)); this->clipboard().ReadBookmark(&title_result, &url_result); EXPECT_EQ(title, title_result); EXPECT_EQ(url, url_result); @@ -332,9 +337,11 @@ EXPECT_TRUE(this->clipboard().IsFormatAvailable( ClipboardFormatType::GetHtmlType(), ClipboardBuffer::kCopyPaste)); EXPECT_TRUE(this->clipboard().IsFormatAvailable( - ClipboardFormatType::GetPlainTextWType(), ClipboardBuffer::kCopyPaste)); - EXPECT_TRUE(this->clipboard().IsFormatAvailable( ClipboardFormatType::GetPlainTextType(), ClipboardBuffer::kCopyPaste)); +#if defined(OS_WIN) + EXPECT_TRUE(this->clipboard().IsFormatAvailable( + ClipboardFormatType::GetPlainTextAType(), ClipboardBuffer::kCopyPaste)); +#endif uint32_t fragment_start; uint32_t fragment_end; this->clipboard().ReadHTML(ClipboardBuffer::kCopyPaste, &markup_result, @@ -364,9 +371,11 @@ EXPECT_THAT(this->GetAvailableTypes(ClipboardBuffer::kCopyPaste), Contains(ASCIIToUTF16(kMimeTypeText))); EXPECT_TRUE(this->clipboard().IsFormatAvailable( - ClipboardFormatType::GetPlainTextWType(), ClipboardBuffer::kCopyPaste)); - EXPECT_TRUE(this->clipboard().IsFormatAvailable( ClipboardFormatType::GetPlainTextType(), ClipboardBuffer::kCopyPaste)); +#if defined(OS_WIN) + EXPECT_TRUE(this->clipboard().IsFormatAvailable( + ClipboardFormatType::GetPlainTextAType(), ClipboardBuffer::kCopyPaste)); +#endif base::string16 text_result; this->clipboard().ReadText(ClipboardBuffer::kCopyPaste, &text_result);
diff --git a/ui/base/clipboard/clipboard_util_win.cc b/ui/base/clipboard/clipboard_util_win.cc index 323079b86..be5b03c 100644 --- a/ui/base/clipboard/clipboard_util_win.cc +++ b/ui/base/clipboard/clipboard_util_win.cc
@@ -361,7 +361,7 @@ template <> struct FileGroupDescriptorData<FILEGROUPDESCRIPTORW> { static bool get(IDataObject* data_object, STGMEDIUM* medium) { - return GetData(data_object, ClipboardFormatType::GetFileDescriptorWType(), + return GetData(data_object, ClipboardFormatType::GetFileDescriptorType(), medium); } }; @@ -369,7 +369,7 @@ template <> struct FileGroupDescriptorData<FILEGROUPDESCRIPTORA> { static bool get(IDataObject* data_object, STGMEDIUM* medium) { - return GetData(data_object, ClipboardFormatType::GetFileDescriptorType(), + return GetData(data_object, ClipboardFormatType::GetFileDescriptorAType(), medium); } }; @@ -445,16 +445,16 @@ bool ClipboardUtil::HasUrl(IDataObject* data_object, bool convert_filenames) { DCHECK(data_object); return HasData(data_object, ClipboardFormatType::GetMozUrlType()) || - HasData(data_object, ClipboardFormatType::GetUrlWType()) || HasData(data_object, ClipboardFormatType::GetUrlType()) || + HasData(data_object, ClipboardFormatType::GetUrlAType()) || (convert_filenames && HasFilenames(data_object)); } bool ClipboardUtil::HasFilenames(IDataObject* data_object) { DCHECK(data_object); return HasData(data_object, ClipboardFormatType::GetCFHDropType()) || - HasData(data_object, ClipboardFormatType::GetFilenameWType()) || - HasData(data_object, ClipboardFormatType::GetFilenameType()); + HasData(data_object, ClipboardFormatType::GetFilenameType()) || + HasData(data_object, ClipboardFormatType::GetFilenameAType()); } bool ClipboardUtil::HasVirtualFilenames(IDataObject* data_object) { @@ -463,15 +463,15 @@ return !HasFilenames(data_object) && HasData(data_object, ClipboardFormatType::GetFileContentAtIndexType(0)) && - (HasData(data_object, ClipboardFormatType::GetFileDescriptorWType()) || - HasData(data_object, ClipboardFormatType::GetFileDescriptorType())); + (HasData(data_object, ClipboardFormatType::GetFileDescriptorType()) || + HasData(data_object, ClipboardFormatType::GetFileDescriptorAType())); } bool ClipboardUtil::HasFileContents(IDataObject* data_object) { DCHECK(data_object); return HasData(data_object, ClipboardFormatType::GetFileContentZeroType()) && - (HasData(data_object, ClipboardFormatType::GetFileDescriptorWType()) || - HasData(data_object, ClipboardFormatType::GetFileDescriptorType())); + (HasData(data_object, ClipboardFormatType::GetFileDescriptorType()) || + HasData(data_object, ClipboardFormatType::GetFileDescriptorAType())); } bool ClipboardUtil::HasHtml(IDataObject* data_object) { @@ -482,8 +482,8 @@ bool ClipboardUtil::HasPlainText(IDataObject* data_object) { DCHECK(data_object); - return HasData(data_object, ClipboardFormatType::GetPlainTextWType()) || - HasData(data_object, ClipboardFormatType::GetPlainTextType()); + return HasData(data_object, ClipboardFormatType::GetPlainTextType()) || + HasData(data_object, ClipboardFormatType::GetPlainTextAType()); } bool ClipboardUtil::GetUrl(IDataObject* data_object, @@ -500,7 +500,7 @@ return true; if (GetData(data_object, ClipboardFormatType::GetMozUrlType(), &store) || - GetData(data_object, ClipboardFormatType::GetUrlWType(), &store)) { + GetData(data_object, ClipboardFormatType::GetUrlType(), &store)) { { // Mozilla URL format or Unicode URL base::win::ScopedHGlobal<wchar_t*> data(store.hGlobal); @@ -510,7 +510,7 @@ return url->is_valid(); } - if (GetData(data_object, ClipboardFormatType::GetUrlType(), &store)) { + if (GetData(data_object, ClipboardFormatType::GetUrlAType(), &store)) { { // URL using ASCII base::win::ScopedHGlobal<char*> data(store.hGlobal); @@ -558,7 +558,7 @@ return !filenames->empty(); } - if (GetData(data_object, ClipboardFormatType::GetFilenameWType(), &medium)) { + if (GetData(data_object, ClipboardFormatType::GetFilenameType(), &medium)) { { // filename using Unicode base::win::ScopedHGlobal<wchar_t*> data(medium.hGlobal); @@ -569,7 +569,7 @@ return true; } - if (GetData(data_object, ClipboardFormatType::GetFilenameType(), &medium)) { + if (GetData(data_object, ClipboardFormatType::GetFilenameAType(), &medium)) { { // filename using ASCII base::win::ScopedHGlobal<char*> data(medium.hGlobal); @@ -642,7 +642,7 @@ return false; STGMEDIUM store; - if (GetData(data_object, ClipboardFormatType::GetPlainTextWType(), &store)) { + if (GetData(data_object, ClipboardFormatType::GetPlainTextType(), &store)) { { // Unicode text base::win::ScopedHGlobal<wchar_t*> data(store.hGlobal); @@ -652,7 +652,7 @@ return true; } - if (GetData(data_object, ClipboardFormatType::GetPlainTextType(), &store)) { + if (GetData(data_object, ClipboardFormatType::GetPlainTextAType(), &store)) { { // ASCII text base::win::ScopedHGlobal<char*> data(store.hGlobal);
diff --git a/ui/base/clipboard/clipboard_win.cc b/ui/base/clipboard/clipboard_win.cc index 56a673e..ac1e34f 100644 --- a/ui/base/clipboard/clipboard_win.cc +++ b/ui/base/clipboard/clipboard_win.cc
@@ -267,7 +267,7 @@ types->clear(); if (::IsClipboardFormatAvailable( - ClipboardFormatType::GetPlainTextType().ToFormatEtc().cfFormat)) + ClipboardFormatType::GetPlainTextAType().ToFormatEtc().cfFormat)) types->push_back(base::UTF8ToUTF16(kMimeTypeText)); if (::IsClipboardFormatAvailable( ClipboardFormatType::GetHtmlType().ToFormatEtc().cfFormat)) @@ -524,7 +524,7 @@ return; HANDLE data = ::GetClipboardData( - ClipboardFormatType::GetUrlWType().ToFormatEtc().cfFormat); + ClipboardFormatType::GetUrlType().ToFormatEtc().cfFormat); if (!data) return; @@ -624,7 +624,7 @@ base::string16 wide_bookmark = base::UTF8ToUTF16(bookmark); HGLOBAL glob = CreateGlobalData(wide_bookmark); - WriteToClipboard(ClipboardFormatType::GetUrlWType().ToFormatEtc().cfFormat, + WriteToClipboard(ClipboardFormatType::GetUrlType().ToFormatEtc().cfFormat, glob); }
diff --git a/ui/base/clipboard/test/test_clipboard.cc b/ui/base/clipboard/test/test_clipboard.cc index d3fdc3b..3bbd65e 100644 --- a/ui/base/clipboard/test/test_clipboard.cc +++ b/ui/base/clipboard/test/test_clipboard.cc
@@ -124,7 +124,7 @@ std::string* url) const { const DataStore& store = GetDefaultStore(); if (url) { - auto it = store.data.find(ClipboardFormatType::GetUrlWType()); + auto it = store.data.find(ClipboardFormatType::GetUrlType()); if (it != store.data.end()) *url = it->second; } @@ -170,8 +170,10 @@ void TestClipboard::WriteText(const char* text_data, size_t text_len) { std::string text(text_data, text_len); GetDefaultStore().data[ClipboardFormatType::GetPlainTextType()] = text; +#if defined(OS_WIN) // Create a dummy entry. - GetDefaultStore().data[ClipboardFormatType::GetPlainTextWType()]; + GetDefaultStore().data[ClipboardFormatType::GetPlainTextAType()]; +#endif if (IsSupportedClipboardBuffer(ClipboardBuffer::kSelection)) GetStore(ClipboardBuffer::kSelection) .data[ClipboardFormatType::GetPlainTextType()] = text; @@ -198,7 +200,7 @@ size_t title_len, const char* url_data, size_t url_len) { - GetDefaultStore().data[ClipboardFormatType::GetUrlWType()] = + GetDefaultStore().data[ClipboardFormatType::GetUrlType()] = std::string(url_data, url_len); GetDefaultStore().url_title = std::string(title_data, title_len); }
diff --git a/ui/base/dragdrop/os_exchange_data_provider_win.cc b/ui/base/dragdrop/os_exchange_data_provider_win.cc index 4b7c065..4d0a9fbb 100644 --- a/ui/base/dragdrop/os_exchange_data_provider_win.cc +++ b/ui/base/dragdrop/os_exchange_data_provider_win.cc
@@ -310,12 +310,12 @@ void OSExchangeDataProviderWin::SetString(const base::string16& data) { STGMEDIUM* storage = GetStorageForString(data); data_->contents_.push_back(std::make_unique<DataObjectImpl::StoredDataInfo>( - ClipboardFormatType::GetPlainTextWType().ToFormatEtc(), storage)); + ClipboardFormatType::GetPlainTextType().ToFormatEtc(), storage)); // Also add the UTF8-encoded version. storage = GetStorageForString(base::UTF16ToUTF8(data)); data_->contents_.push_back(std::make_unique<DataObjectImpl::StoredDataInfo>( - ClipboardFormatType::GetPlainTextType().ToFormatEtc(), storage)); + ClipboardFormatType::GetPlainTextAType().ToFormatEtc(), storage)); } void OSExchangeDataProviderWin::SetURL(const GURL& url, @@ -344,10 +344,10 @@ // Add a UniformResourceLocator link for apps like IE and Word. storage = GetStorageForString(base::UTF8ToUTF16(url.spec())); data_->contents_.push_back(std::make_unique<DataObjectImpl::StoredDataInfo>( - ClipboardFormatType::GetUrlWType().ToFormatEtc(), storage)); + ClipboardFormatType::GetUrlType().ToFormatEtc(), storage)); storage = GetStorageForString(url.spec()); data_->contents_.push_back(std::make_unique<DataObjectImpl::StoredDataInfo>( - ClipboardFormatType::GetUrlType().ToFormatEtc(), storage)); + ClipboardFormatType::GetUrlAType().ToFormatEtc(), storage)); // TODO(https://crbug.com/6767): add CF_HTML. @@ -406,7 +406,7 @@ storage->pUnkForRelease = NULL; data_->contents_.push_back(std::make_unique<DataObjectImpl::StoredDataInfo>( - ClipboardFormatType::GetFileDescriptorWType().ToFormatEtc(), storage)); + ClipboardFormatType::GetFileDescriptorType().ToFormatEtc(), storage)); for (size_t i = 0; i < num_files; i++) { // Fill in each FILEDESCRIPTORW with file name. @@ -508,7 +508,7 @@ // Add CFSTR_FILEDESCRIPTORW. STGMEDIUM* storage = GetStorageForFileDescriptor(filename); data_->contents_.push_back(std::make_unique<DataObjectImpl::StoredDataInfo>( - ClipboardFormatType::GetFileDescriptorWType().ToFormatEtc(), storage)); + ClipboardFormatType::GetFileDescriptorType().ToFormatEtc(), storage)); // Add CFSTR_FILECONTENTS. storage = GetStorageForBytes(file_contents.data(), file_contents.length());
diff --git a/ui/base/ime/chromeos/input_method_chromeos.cc b/ui/base/ime/chromeos/input_method_chromeos.cc index acfe76e6..b1cd1e0 100644 --- a/ui/base/ime/chromeos/input_method_chromeos.cc +++ b/ui/base/ime/chromeos/input_method_chromeos.cc
@@ -698,6 +698,7 @@ ImeTextSpan ime_text_span(ui::ImeTextSpan::Type::kComposition, char16_offsets[start], char16_offsets[end], text_ime_text_span.thickness, + ui::ImeTextSpan::UnderlineStyle::kSolid, text_ime_text_span.background_color); ime_text_span.underline_color = text_ime_text_span.underline_color; out_composition->ime_text_spans.push_back(ime_text_span); @@ -708,10 +709,10 @@ if (text.selection.start() < text.selection.end()) { const uint32_t start = text.selection.start(); const uint32_t end = text.selection.end(); - ImeTextSpan ime_text_span(ui::ImeTextSpan::Type::kComposition, - char16_offsets[start], char16_offsets[end], - ui::ImeTextSpan::Thickness::kThick, - SK_ColorTRANSPARENT); + ImeTextSpan ime_text_span( + ui::ImeTextSpan::Type::kComposition, char16_offsets[start], + char16_offsets[end], ui::ImeTextSpan::Thickness::kThick, + ui::ImeTextSpan::UnderlineStyle::kSolid, SK_ColorTRANSPARENT); out_composition->ime_text_spans.push_back(ime_text_span); // If the cursor is at start or end of this ime_text_span, then we treat @@ -728,9 +729,10 @@ // Use a thin underline with text color by default. if (out_composition->ime_text_spans.empty()) { - out_composition->ime_text_spans.push_back( - ImeTextSpan(ui::ImeTextSpan::Type::kComposition, 0, length, - ui::ImeTextSpan::Thickness::kThin, SK_ColorTRANSPARENT)); + out_composition->ime_text_spans.push_back(ImeTextSpan( + ui::ImeTextSpan::Type::kComposition, 0, length, + ui::ImeTextSpan::Thickness::kThin, + ui::ImeTextSpan::UnderlineStyle::kSolid, SK_ColorTRANSPARENT)); } }
diff --git a/ui/base/ime/chromeos/input_method_chromeos_unittest.cc b/ui/base/ime/chromeos/input_method_chromeos_unittest.cc index 19c152c..5ce2721 100644 --- a/ui/base/ime/chromeos/input_method_chromeos_unittest.cc +++ b/ui/base/ime/chromeos/input_method_chromeos_unittest.cc
@@ -580,7 +580,9 @@ CompositionText composition_text; composition_text.text = kSampleText; ImeTextSpan underline(ImeTextSpan::Type::kComposition, 1UL, 4UL, - ui::ImeTextSpan::Thickness::kThin, SK_ColorTRANSPARENT); + ui::ImeTextSpan::Thickness::kThin, + ui::ImeTextSpan::UnderlineStyle::kSolid, + SK_ColorTRANSPARENT); composition_text.ime_text_spans.push_back(underline); CompositionText composition_text2; @@ -612,6 +614,7 @@ composition_text.text = kSampleText; ImeTextSpan underline(ImeTextSpan::Type::kComposition, 1UL, 4UL, ui::ImeTextSpan::Thickness::kThick, + ui::ImeTextSpan::UnderlineStyle::kSolid, SK_ColorTRANSPARENT); composition_text.ime_text_spans.push_back(underline); @@ -643,7 +646,9 @@ CompositionText composition_text; composition_text.text = kSampleText; ImeTextSpan underline(ImeTextSpan::Type::kComposition, 1UL, 4UL, - ui::ImeTextSpan::Thickness::kThin, SK_ColorTRANSPARENT); + ui::ImeTextSpan::Thickness::kThin, + ui::ImeTextSpan::UnderlineStyle::kSolid, + SK_ColorTRANSPARENT); underline.underline_color = SK_ColorRED; composition_text.ime_text_spans.push_back(underline);
diff --git a/ui/base/ime/composition_text_unittest.cc b/ui/base/ime/composition_text_unittest.cc index 9c57c23..991a71f 100644 --- a/ui/base/ime/composition_text_unittest.cc +++ b/ui/base/ime/composition_text_unittest.cc
@@ -13,17 +13,17 @@ TEST(CompositionTextTest, CopyTest) { const base::string16 kSampleText = base::UTF8ToUTF16("Sample Text"); - const ImeTextSpan kSampleUnderline1(ImeTextSpan::Type::kComposition, 10, 20, - ImeTextSpan::Thickness::kThin, - SK_ColorTRANSPARENT); + const ImeTextSpan kSampleUnderline1( + ImeTextSpan::Type::kComposition, 10, 20, ImeTextSpan::Thickness::kThin, + ImeTextSpan::UnderlineStyle::kSolid, SK_ColorTRANSPARENT); - const ImeTextSpan kSampleUnderline2(ImeTextSpan::Type::kComposition, 11, 21, - ImeTextSpan::Thickness::kThick, - SK_ColorTRANSPARENT); + const ImeTextSpan kSampleUnderline2( + ImeTextSpan::Type::kComposition, 11, 21, ImeTextSpan::Thickness::kThick, + ImeTextSpan::UnderlineStyle::kSolid, SK_ColorTRANSPARENT); - ImeTextSpan kSampleUnderline3(ImeTextSpan::Type::kComposition, 12, 22, - ImeTextSpan::Thickness::kThin, - SK_ColorTRANSPARENT); + ImeTextSpan kSampleUnderline3( + ImeTextSpan::Type::kComposition, 12, 22, ImeTextSpan::Thickness::kThin, + ImeTextSpan::UnderlineStyle::kSolid, SK_ColorTRANSPARENT); kSampleUnderline3.underline_color = SK_ColorRED; // Make CompositionText
diff --git a/ui/base/ime/ime_text_span.cc b/ui/base/ime/ime_text_span.cc index 4f3aeadb..1fa3bb0 100644 --- a/ui/base/ime/ime_text_span.cc +++ b/ui/base/ime/ime_text_span.cc
@@ -13,6 +13,7 @@ uint32_t start_offset, uint32_t end_offset, Thickness thickness, + UnderlineStyle underline_style, SkColor background_color, SkColor suggestion_highlight_color, const std::vector<std::string>& suggestions) @@ -20,6 +21,7 @@ start_offset(start_offset), end_offset(end_offset), thickness(thickness), + underline_style(underline_style), background_color(background_color), suggestion_highlight_color(suggestion_highlight_color), suggestions(suggestions) {}
diff --git a/ui/base/ime/ime_text_span.h b/ui/base/ime/ime_text_span.h index 6790249..5f4069a 100644 --- a/ui/base/ime/ime_text_span.h +++ b/ui/base/ime/ime_text_span.h
@@ -37,11 +37,19 @@ kThick, }; + enum class UnderlineStyle { + kNone, + kSolid, + kDot, + kDash, + }; + ImeTextSpan( Type type = Type::kComposition, uint32_t start_offset = 0, uint32_t end_offset = 0, Thickness thickness = Thickness::kThin, + UnderlineStyle underline_style = UnderlineStyle::kSolid, SkColor background_color = SK_ColorTRANSPARENT, SkColor suggestion_highlight_color = SK_ColorTRANSPARENT, const std::vector<std::string>& suggestions = std::vector<std::string>()); @@ -56,6 +64,8 @@ (this->end_offset == rhs.end_offset) && (this->underline_color == rhs.underline_color) && (this->thickness == rhs.thickness) && + (this->underline_style == rhs.underline_style) && + (this->text_color == rhs.text_color) && (this->background_color == rhs.background_color) && (this->suggestion_highlight_color == rhs.suggestion_highlight_color) && @@ -71,6 +81,8 @@ uint32_t end_offset; SkColor underline_color = SK_ColorTRANSPARENT; Thickness thickness; + UnderlineStyle underline_style; + SkColor text_color = SK_ColorTRANSPARENT; SkColor background_color; SkColor suggestion_highlight_color; bool remove_on_finish_composing = false;
diff --git a/ui/base/ime/linux/composition_text_util_pango.cc b/ui/base/ime/linux/composition_text_util_pango.cc index cf75310..84ccf53 100644 --- a/ui/base/ime/linux/composition_text_util_pango.cc +++ b/ui/base/ime/linux/composition_text_util_pango.cc
@@ -76,10 +76,10 @@ if (background_attr || underline_attr) { // Use a thin underline with text color by default. - ImeTextSpan ime_text_span(ImeTextSpan::Type::kComposition, - char16_offsets[start], char16_offsets[end], - ImeTextSpan::Thickness::kThin, - SK_ColorTRANSPARENT); + ImeTextSpan ime_text_span( + ImeTextSpan::Type::kComposition, char16_offsets[start], + char16_offsets[end], ImeTextSpan::Thickness::kThin, + ImeTextSpan::UnderlineStyle::kSolid, SK_ColorTRANSPARENT); // Always use thick underline for a range with background color, which // is usually the selection range. @@ -113,7 +113,8 @@ if (composition->ime_text_spans.empty()) { composition->ime_text_spans.push_back( ImeTextSpan(ImeTextSpan::Type::kComposition, 0, length, - ImeTextSpan::Thickness::kThin, SK_ColorTRANSPARENT)); + ImeTextSpan::Thickness::kThin, + ImeTextSpan::UnderlineStyle::kSolid, SK_ColorTRANSPARENT)); } }
diff --git a/ui/base/ime/mojom/ime_types.mojom b/ui/base/ime/mojom/ime_types.mojom index 2dd665a..d359acd3 100644 --- a/ui/base/ime/mojom/ime_types.mojom +++ b/ui/base/ime/mojom/ime_types.mojom
@@ -47,6 +47,20 @@ kThick, }; +// This enum represents the style of an underline segment of text, +// the underline style of a ui::ImeTextSpan element. +// The possible values are: +// * kNone: When you don't want to paint the underline. +// * kSolid: For regular style. +// * kDot: For dotted underlines. +// * kDash: For dashed underlines. +enum ImeTextSpanUnderlineStyle { + kNone, + kSolid, + kDot, + kDash, +}; + // Represents an underlined segment of text currently composed by IME. // Corresponds to ui::ImeTextSpan. struct ImeTextSpan { @@ -55,6 +69,8 @@ uint32 end_offset; uint32 underline_color; ImeTextSpanThickness thickness; + ImeTextSpanUnderlineStyle underline_style; + uint32 text_color; uint32 background_color; uint32 suggestion_highlight_color; bool remove_on_finish_composing;
diff --git a/ui/base/ime/mojom/ime_types.typemap b/ui/base/ime/mojom/ime_types.typemap index 9b431c4..3f76dfa 100644 --- a/ui/base/ime/mojom/ime_types.typemap +++ b/ui/base/ime/mojom/ime_types.typemap
@@ -21,5 +21,6 @@ type_mappings = [ "ui.mojom.ImeTextSpan=::ui::ImeTextSpan", "ui.mojom.ImeTextSpanThickness=::ui::ImeTextSpan::Thickness", + "ui.mojom.ImeTextSpanUnderlineStyle=::ui::ImeTextSpan::UnderlineStyle", "ui.mojom.TextInputType=::ui::TextInputType", ]
diff --git a/ui/base/ime/mojom/ime_types_mojom_traits.cc b/ui/base/ime/mojom/ime_types_mojom_traits.cc index 90be5c6..a088821 100644 --- a/ui/base/ime/mojom/ime_types_mojom_traits.cc +++ b/ui/base/ime/mojom/ime_types_mojom_traits.cc
@@ -84,6 +84,9 @@ out->underline_color = data.underline_color(); if (!data.ReadThickness(&out->thickness)) return false; + if (!data.ReadUnderlineStyle(&out->underline_style)) + return false; + out->text_color = data.text_color(); out->background_color = data.background_color(); out->suggestion_highlight_color = data.suggestion_highlight_color(); out->remove_on_finish_composing = data.remove_on_finish_composing(); @@ -166,4 +169,48 @@ return false; } +// static +ui::mojom::ImeTextSpanUnderlineStyle EnumTraits< + ui::mojom::ImeTextSpanUnderlineStyle, + ui::ImeTextSpan::UnderlineStyle>::ToMojom(ui::ImeTextSpan::UnderlineStyle + underline_style) { + switch (underline_style) { + case ui::ImeTextSpan::UnderlineStyle::kNone: + return ui::mojom::ImeTextSpanUnderlineStyle::kNone; + case ui::ImeTextSpan::UnderlineStyle::kSolid: + return ui::mojom::ImeTextSpanUnderlineStyle::kSolid; + case ui::ImeTextSpan::UnderlineStyle::kDot: + return ui::mojom::ImeTextSpanUnderlineStyle::kDot; + case ui::ImeTextSpan::UnderlineStyle::kDash: + return ui::mojom::ImeTextSpanUnderlineStyle::kDash; + } + + NOTREACHED(); + return ui::mojom::ImeTextSpanUnderlineStyle::kSolid; +} + +// static +bool EnumTraits<ui::mojom::ImeTextSpanUnderlineStyle, + ui::ImeTextSpan::UnderlineStyle>:: + FromMojom(ui::mojom::ImeTextSpanUnderlineStyle input, + ui::ImeTextSpan::UnderlineStyle* out) { + switch (input) { + case ui::mojom::ImeTextSpanUnderlineStyle::kNone: + *out = ui::ImeTextSpan::UnderlineStyle::kNone; + return true; + case ui::mojom::ImeTextSpanUnderlineStyle::kSolid: + *out = ui::ImeTextSpan::UnderlineStyle::kSolid; + return true; + case ui::mojom::ImeTextSpanUnderlineStyle::kDot: + *out = ui::ImeTextSpan::UnderlineStyle::kDot; + return true; + case ui::mojom::ImeTextSpanUnderlineStyle::kDash: + *out = ui::ImeTextSpan::UnderlineStyle::kDash; + return true; + } + + NOTREACHED(); + return false; +} + } // namespace mojo
diff --git a/ui/base/ime/mojom/ime_types_mojom_traits.h b/ui/base/ime/mojom/ime_types_mojom_traits.h index dfb92bb4..58d192e2 100644 --- a/ui/base/ime/mojom/ime_types_mojom_traits.h +++ b/ui/base/ime/mojom/ime_types_mojom_traits.h
@@ -32,6 +32,11 @@ static ui::ImeTextSpan::Thickness thickness(const ui::ImeTextSpan& i) { return i.thickness; } + static ui::ImeTextSpan::UnderlineStyle underline_style( + const ui::ImeTextSpan& i) { + return i.underline_style; + } + static uint32_t text_color(const ui::ImeTextSpan& c) { return c.text_color; } static uint32_t background_color(const ui::ImeTextSpan& c) { return c.background_color; } @@ -63,6 +68,15 @@ ui::ImeTextSpan::Thickness* out); }; +template <> +struct EnumTraits<ui::mojom::ImeTextSpanUnderlineStyle, + ui::ImeTextSpan::UnderlineStyle> { + static ui::mojom::ImeTextSpanUnderlineStyle ToMojom( + ui::ImeTextSpan::UnderlineStyle underline_style); + static bool FromMojom(ui::mojom::ImeTextSpanUnderlineStyle input, + ui::ImeTextSpan::UnderlineStyle* out); +}; + } // namespace mojo #endif // UI_BASE_IME_MOJOM_IME_TYPES_MOJOM_TRAITS_H_
diff --git a/ui/base/ime/win/tsf_text_store.cc b/ui/base/ime/win/tsf_text_store.cc index 6f75654b8..88e321d07 100644 --- a/ui/base/ime/win/tsf_text_store.cc +++ b/ui/base/ime/win/tsf_text_store.cc
@@ -1055,16 +1055,14 @@ if (*committed_size < static_cast<size_t>(start_pos + length)) *committed_size = start_pos + length; } else { + // Check for the formats of the actively composed text. ImeTextSpan span; span.start_offset = start_pos; span.end_offset = start_pos + length; span.underline_color = SK_ColorBLACK; span.background_color = SK_ColorTRANSPARENT; - if (has_display_attribute) { - span.thickness = display_attribute.fBoldLine - ? ImeTextSpan::Thickness::kThick - : ImeTextSpan::Thickness::kThin; - } + if (has_display_attribute) + GetStyle(display_attribute, &span); spans->push_back(span); } } @@ -1417,4 +1415,44 @@ } } +void TSFTextStore::GetStyle(const TF_DISPLAYATTRIBUTE& attribute, + ImeTextSpan* span) { + // Use the display attribute to pick the right formats for the underline and + // text. + // Set the default values first and then check if display attribute has + // any style or not. + span->thickness = attribute.fBoldLine ? ImeTextSpan::Thickness::kThick + : ImeTextSpan::Thickness::kThin; + span->underline_style = ImeTextSpan::UnderlineStyle::kSolid; + if (attribute.lsStyle != TF_LS_NONE) { + switch (attribute.lsStyle) { + case TF_LS_SOLID: { + span->underline_style = ImeTextSpan::UnderlineStyle::kSolid; + break; + } + case TF_LS_DOT: { + span->underline_style = ImeTextSpan::UnderlineStyle::kDot; + break; + } + case TF_LS_DASH: { + span->underline_style = ImeTextSpan::UnderlineStyle::kDash; + break; + } + default: { + span->underline_style = ImeTextSpan::UnderlineStyle::kSolid; + } + } + } + if (attribute.crText.type != TF_CT_NONE) { + span->text_color = SkColorSetRGB(GetRValue(attribute.crText.cr), + GetGValue(attribute.crText.cr), + GetBValue(attribute.crText.cr)); + } + if (attribute.crLine.type != TF_CT_NONE) { + span->underline_color = SkColorSetRGB(GetRValue(attribute.crLine.cr), + GetGValue(attribute.crLine.cr), + GetBValue(attribute.crLine.cr)); + } +} + } // namespace ui
diff --git a/ui/base/ime/win/tsf_text_store.h b/ui/base/ime/win/tsf_text_store.h index 2f03a383..7d64d45 100644 --- a/ui/base/ime/win/tsf_text_store.h +++ b/ui/base/ime/win/tsf_text_store.h
@@ -304,7 +304,11 @@ size_t* committed_size, ImeTextSpans* spans); - // The refrence count of this instance. + // Gets the style information from the display attribute for the actively + // composed text. + void GetStyle(const TF_DISPLAYATTRIBUTE& attribute, ImeTextSpan* span); + + // The reference count of this instance. volatile LONG ref_count_ = 0; // A pointer of ITextStoreACPSink, this instance is given in AdviseSink.
diff --git a/ui/base/ime/win/tsf_text_store_unittest.cc b/ui/base/ime/win/tsf_text_store_unittest.cc index b6f8222e7..7cb99f74 100644 --- a/ui/base/ime/win/tsf_text_store_unittest.cc +++ b/ui/base/ime/win/tsf_text_store_unittest.cc
@@ -3226,5 +3226,74 @@ EXPECT_EQ(S_OK, result); } +class UnderlineStyleTestCallback : public TSFTextStoreTestCallback { + public: + explicit UnderlineStyleTestCallback(TSFTextStore* text_store) + : TSFTextStoreTestCallback(text_store) {} + + HRESULT LockGranted1(DWORD flags) { + SetTextTest(0, 0, L"a", S_OK); + + GetTextTest(0, -1, L"a", 1); + + SetSelectionTest(0, 1, S_OK); + + text_spans()->clear(); + ImeTextSpan text_span; + text_span.start_offset = 0; + text_span.end_offset = 1; + text_span.underline_color = SK_ColorBLACK; + text_span.thickness = ImeTextSpan::Thickness::kThin; + text_span.underline_style = ImeTextSpan::UnderlineStyle::kSolid; + text_span.background_color = SK_ColorTRANSPARENT; + text_spans()->push_back(text_span); + *edit_flag() = true; + *composition_start() = 0; + composition_range()->set_start(0); + composition_range()->set_end(1); + *has_composition_range() = true; + + return S_OK; + } + + void SetCompositionText1(const ui::CompositionText& composition) { + EXPECT_EQ(L"a", composition.text); + EXPECT_EQ(0u, composition.selection.start()); + EXPECT_EQ(1u, composition.selection.end()); + ASSERT_EQ(1u, composition.ime_text_spans.size()); + EXPECT_EQ(SK_ColorBLACK, composition.ime_text_spans[0].underline_color); + EXPECT_EQ(SK_ColorTRANSPARENT, + composition.ime_text_spans[0].background_color); + EXPECT_EQ(0u, composition.ime_text_spans[0].start_offset); + EXPECT_EQ(1u, composition.ime_text_spans[0].end_offset); + EXPECT_EQ(ImeTextSpan::Thickness::kThin, + composition.ime_text_spans[0].thickness); + EXPECT_EQ(ImeTextSpan::UnderlineStyle::kSolid, + composition.ime_text_spans[0].underline_style); + SetHasCompositionText(true); + } + + private: + DISALLOW_COPY_AND_ASSIGN(UnderlineStyleTestCallback); +}; + +TEST_F(TSFTextStoreTest, UnderlineStyleTest) { + UnderlineStyleTestCallback callback(text_store_.get()); + EXPECT_CALL(text_input_client_, SetCompositionText(_)) + .WillOnce( + Invoke(&callback, &UnderlineStyleTestCallback::SetCompositionText1)); + + EXPECT_CALL(*sink_, OnLockGranted(_)) + .WillOnce(Invoke(&callback, &UnderlineStyleTestCallback::LockGranted1)); + + ON_CALL(text_input_client_, HasCompositionText()) + .WillByDefault( + Invoke(&callback, &TSFTextStoreTestCallback::HasCompositionText)); + + HRESULT result = kInvalidResult; + EXPECT_EQ(S_OK, text_store_->RequestLock(TS_LF_READWRITE, &result)); + EXPECT_EQ(S_OK, result); +} + } // namespace } // namespace ui
diff --git a/ui/events/event.cc b/ui/events/event.cc index e4728f5..9b1120a0 100644 --- a/ui/events/event.cc +++ b/ui/events/event.cc
@@ -30,6 +30,7 @@ #include "ui/events/devices/x11/touch_factory_x11.h" // nogncheck #include "ui/events/keycodes/keyboard_code_conversion_x.h" // nogncheck #include "ui/events/x/events_x_utils.h" // nogncheck +#include "ui/events/x/x11_event_translation.h" #include "ui/gfx/x/x11.h" // nogncheck #elif defined(USE_OZONE) #include "ui/events/ozone/layout/keyboard_layout_engine.h" // nogncheck @@ -52,31 +53,6 @@ return event && (event->xkey.state & ~kAllStateMask) != 0; } - -Event::Properties GetEventPropertiesFromXEvent(EventType type, - const XEvent& xev) { - using Values = std::vector<uint8_t>; - Event::Properties properties; - if (type == ET_KEY_PRESSED || type == ET_KEY_RELEASED) { - // Keyboard group - uint8_t group = XkbGroupForCoreState(xev.xkey.state); - properties.emplace(kPropertyKeyboardGroup, Values{group}); - - // IBus-gtk specific flags - uint8_t ibus_flags = (xev.xkey.state >> kPropertyKeyboardIBusFlagOffset) & - kPropertyKeyboardIBusFlagMask; - properties.emplace(kPropertyKeyboardIBusFlag, Values{ibus_flags}); - - } else if (type == ET_MOUSE_EXITED) { - // NotifyVirtual events are created for intermediate windows that the - // pointer crosses through. These occur when middle clicking. - // Change these into mouse move events. - bool crossing_intermediate_window = xev.xcrossing.detail == NotifyVirtual; - properties.emplace(kPropertyMouseCrossedIntermediateWindow, - crossing_intermediate_window); - } - return properties; -} #endif constexpr int kChangedButtonFlagMask =
diff --git a/ui/events/event_utils.h b/ui/events/event_utils.h index 23da212..5f798ae 100644 --- a/ui/events/event_utils.h +++ b/ui/events/event_utils.h
@@ -43,6 +43,9 @@ // Key used to store keyboard 'group' values in Event::Properties constexpr char kPropertyKeyboardGroup[] = "_keyevent_kbd_group_"; +// Key used to store 'hardware key code' values in Event::Properties +constexpr char kPropertyKeyboardHwKeyCode[] = "_keyevent_kbd_hw_keycode_"; + // IBus specific Event::Properties constants. ibus-gtk in async mode uses // gtk-specific XKeyEvent::state bits 24 and 25 for its key events. // https://mail.gnome.org/archives/gtk-devel-list/2013-June/msg00003.html
diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev.cc b/ui/events/ozone/evdev/touch_event_converter_evdev.cc index dfe22c7..a6082ce 100644 --- a/ui/events/ozone/evdev/touch_event_converter_evdev.cc +++ b/ui/events/ozone/evdev/touch_event_converter_evdev.cc
@@ -18,6 +18,7 @@ #include "base/bind.h" #include "base/callback.h" #include "base/command_line.h" +#include "base/feature_list.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" #include "base/strings/string_number_conversions.h" @@ -36,6 +37,7 @@ #include "ui/events/ozone/evdev/touch_filter/false_touch_finder.h" #include "ui/events/ozone/evdev/touch_filter/palm_detection_filter.h" #include "ui/events/ozone/evdev/touch_filter/palm_detection_filter_factory.h" +#include "ui/events/ozone/features.h" #include "ui/ozone/public/input_controller.h" namespace { @@ -115,7 +117,9 @@ input_device_fd_(std::move(fd)), dispatcher_(dispatcher), palm_detection_filter_( - CreatePalmDetectionFilter(devinfo, shared_palm_state)) { + CreatePalmDetectionFilter(devinfo, shared_palm_state)), + palm_on_touch_major_max_( + base::FeatureList::IsEnabled(kEnablePalmOnMaxTouchMajor)) { touch_evdev_debug_buffer_.Initialize(devinfo); } @@ -508,7 +512,8 @@ bool TouchEventConverterEvdev::IsPalm(const InProgressTouchEvdev& touch) { return touch.tool_type == MT_TOOL_PALM || - (major_max_ > 0 && touch.major == major_max_); + (palm_on_touch_major_max_ && major_max_ > 0 && + touch.major == major_max_); } void TouchEventConverterEvdev::ReportEvents(base::TimeTicks timestamp) {
diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev.h b/ui/events/ozone/evdev/touch_event_converter_evdev.h index 00942b1..c1c7225 100644 --- a/ui/events/ozone/evdev/touch_event_converter_evdev.h +++ b/ui/events/ozone/evdev/touch_event_converter_evdev.h
@@ -189,6 +189,9 @@ // Callback to enable/disable palm suppression. base::RepeatingCallback<void(bool)> enable_palm_suppression_callback_; + // Do we mark a touch as palm when touch_major is the max? + const bool palm_on_touch_major_max_; + DISALLOW_COPY_AND_ASSIGN(TouchEventConverterEvdev); };
diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc b/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc index 51070c47..8d9dd1a 100644 --- a/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc +++ b/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc
@@ -33,6 +33,7 @@ #include "ui/events/ozone/evdev/touch_filter/false_touch_finder.h" #include "ui/events/ozone/evdev/touch_filter/shared_palm_detection_filter_state.h" #include "ui/events/ozone/evdev/touch_filter/touch_filter.h" +#include "ui/events/ozone/features.h" #include "ui/events/platform/platform_event_dispatcher.h" #include "ui/events/platform/platform_event_source.h" #include "ui/events/test/scoped_event_test_tick_clock.h" @@ -233,6 +234,15 @@ // Overridden from testing::Test: void SetUp() override { + // By default, tests disable single-cancel and enable palm on touch_major == + // major_max. + scoped_feature_list_.reset(new base::test::ScopedFeatureList); + scoped_feature_list_->InitWithFeatures({kEnablePalmOnMaxTouchMajor}, + {kEnableSingleCancelTouch}); + SetUpDevice(); + } + + void SetUpDevice() { // Set up pipe to satisfy message pump (unused). int evdev_io[2]; if (pipe(evdev_io)) @@ -255,10 +265,6 @@ test_clock_ = std::make_unique<ui::test::ScopedEventTestTickClock>(); ui::DeviceDataManager::CreateInstance(); - - // By default, tests disable single-cancel. - scoped_feature_list_.reset(new base::test::ScopedFeatureList); - scoped_feature_list_->InitAndDisableFeature(kEnableSingleCancelTouch); } void TearDown() override { @@ -732,6 +738,88 @@ EXPECT_EQ(2u, size()); } +TEST_F(TouchEventConverterEvdevTest, MaxMajorNotCancelTouch) { + // By default, tests disable single-cancel and enable palm on touch_major == + // major_max. So we disable that behavior: and expect to see a RELEASED rather + // than cancelled. + scoped_feature_list_.reset(new base::test::ScopedFeatureList); + scoped_feature_list_->InitWithFeatures( + {}, {kEnablePalmOnMaxTouchMajor, kEnableSingleCancelTouch}); + SetUpDevice(); + + ui::MockTouchEventConverterEvdev* dev = device(); + + EventDeviceInfo devinfo; + EXPECT_TRUE(CapabilitiesToDeviceInfo(kLinkWithToolTypeTouchscreen, &devinfo)); + + timeval time; + time = {1429651083, 686882}; + int major_max = devinfo.GetAbsMaximum(ABS_MT_TOUCH_MAJOR); + struct input_event mock_kernel_queue_max_major[] = { + {time, EV_ABS, ABS_MT_SLOT, 0}, + {time, EV_ABS, ABS_MT_TRACKING_ID, 0}, + {time, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER}, + {time, EV_ABS, ABS_MT_POSITION_X, 1003}, + {time, EV_ABS, ABS_MT_POSITION_Y, 749}, + {time, EV_ABS, ABS_MT_PRESSURE, 50}, + {time, EV_ABS, ABS_MT_TOUCH_MAJOR, 116}, + {time, EV_ABS, ABS_MT_SLOT, 1}, + {time, EV_ABS, ABS_MT_TRACKING_ID, 1}, + {time, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER}, + {time, EV_ABS, ABS_MT_POSITION_X, 1103}, + {time, EV_ABS, ABS_MT_POSITION_Y, 649}, + {time, EV_ABS, ABS_MT_PRESSURE, 50}, + {time, EV_ABS, ABS_MT_TOUCH_MAJOR, 116}, + {time, EV_KEY, BTN_TOUCH, 1}, + {time, EV_ABS, ABS_X, 1003}, + {time, EV_ABS, ABS_Y, 749}, + {time, EV_ABS, ABS_PRESSURE, 50}, + {time, EV_SYN, SYN_REPORT, 0}, + {time, EV_ABS, ABS_MT_SLOT, 0}, + {time, EV_ABS, ABS_MT_TOUCH_MAJOR, major_max}, + {time, EV_SYN, SYN_REPORT, 0}, + {time, EV_ABS, ABS_MT_TRACKING_ID, -1}, + {time, EV_ABS, ABS_MT_SLOT, 1}, + {time, EV_ABS, ABS_MT_TRACKING_ID, -1}, + {time, EV_SYN, SYN_REPORT, 0}, + }; + + // Set test now time to ensure above timestamps are in the past. + SetTestNowTime(time); + + // Initialize the device. + dev->Initialize(devinfo); + + dev->ConfigureReadMock(mock_kernel_queue_max_major, + base::size(mock_kernel_queue_max_major), 0); + dev->ReadNow(); + EXPECT_EQ(5u, size()); + + ui::TouchEventParams ev1_1 = dispatched_touch_event(0); + EXPECT_EQ(ET_TOUCH_PRESSED, ev1_1.type); + EXPECT_EQ(0, ev1_1.slot); + EXPECT_EQ(1003, ev1_1.location.x()); + EXPECT_EQ(749, ev1_1.location.y()); + + ui::TouchEventParams ev1_2 = dispatched_touch_event(1); + EXPECT_EQ(ET_TOUCH_PRESSED, ev1_2.type); + EXPECT_EQ(1, ev1_2.slot); + EXPECT_EQ(1103, ev1_2.location.x()); + EXPECT_EQ(649, ev1_2.location.y()); + + ui::TouchEventParams ev1_3 = dispatched_touch_event(2); + EXPECT_EQ(ET_TOUCH_MOVED, ev1_3.type); + EXPECT_EQ(0, ev1_3.slot); + + ui::TouchEventParams ev1_4 = dispatched_touch_event(3); + EXPECT_EQ(ET_TOUCH_RELEASED, ev1_4.type); + EXPECT_EQ(0, ev1_4.slot); + + ui::TouchEventParams ev1_5 = dispatched_touch_event(4); + EXPECT_EQ(ET_TOUCH_RELEASED, ev1_5.type); + EXPECT_EQ(1, ev1_5.slot); +} + TEST_F(TouchEventConverterEvdevTest, PalmShouldCancelTouch) { ui::MockTouchEventConverterEvdev* dev = device();
diff --git a/ui/events/ozone/features.cc b/ui/events/ozone/features.cc index 44bc14b..aa14b0f0 100644 --- a/ui/events/ozone/features.cc +++ b/ui/events/ozone/features.cc
@@ -15,6 +15,9 @@ const base::Feature kEnableNeuralStylusReportFilter{ "EnableNeuralStylusReportFilter", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kEnablePalmOnMaxTouchMajor{ + "EnablePalmOnMaxTouchMajor", base::FEATURE_ENABLED_BY_DEFAULT}; + extern const base::FeatureParam<std::string> kNeuralPalmRadiusPolynomial{ &kEnableNeuralPalmDetectionFilter, "neural_palm_radius_polynomial", ""};
diff --git a/ui/events/ozone/features.h b/ui/events/ozone/features.h index fa2b2c5..3b4f727c 100644 --- a/ui/events/ozone/features.h +++ b/ui/events/ozone/features.h
@@ -21,6 +21,9 @@ extern const base::Feature kEnableNeuralStylusReportFilter; COMPONENT_EXPORT(EVENTS_OZONE) +extern const base::Feature kEnablePalmOnMaxTouchMajor; + +COMPONENT_EXPORT(EVENTS_OZONE) extern const base::FeatureParam<std::string> kNeuralPalmRadiusPolynomial; COMPONENT_EXPORT(EVENTS_OZONE)
diff --git a/ui/events/x/x11_event_translation.cc b/ui/events/x/x11_event_translation.cc index 168b01a..923c91d 100644 --- a/ui/events/x/x11_event_translation.cc +++ b/ui/events/x/x11_event_translation.cc
@@ -6,7 +6,6 @@ #include <vector> -#include "ui/events/event.h" #include "ui/events/event_utils.h" #include "ui/events/keycodes/keyboard_code_conversion_x.h" #include "ui/events/x/events_x_utils.h" @@ -16,22 +15,6 @@ namespace { -Event::Properties GetEventPropertiesFromXKeyEvent(const XKeyEvent& xev) { - using Values = std::vector<uint8_t>; - Event::Properties properties; - - // Keyboard group - uint8_t group = XkbGroupForCoreState(xev.state); - properties.emplace(kPropertyKeyboardGroup, Values{group}); - - // IBus-gtk specific flags - uint8_t ibus_flags = (xev.state >> kPropertyKeyboardIBusFlagOffset) & - kPropertyKeyboardIBusFlagMask; - properties.emplace(kPropertyKeyboardIBusFlag, Values{ibus_flags}); - - return properties; -} - std::unique_ptr<KeyEvent> CreateKeyEvent(EventType event_type, const XEvent& xev) { KeyboardCode key_code = KeyboardCodeFromXKeyEvent(&xev); @@ -52,7 +35,7 @@ #endif DCHECK(event); - event->SetProperties(GetEventPropertiesFromXKeyEvent(xev.xkey)); + event->SetProperties(GetEventPropertiesFromXEvent(event_type, xev)); return event; } @@ -229,4 +212,35 @@ return std::unique_ptr<MouseWheelEvent>{event.release()->AsMouseWheelEvent()}; } +// TODO(crbug.com/965991): Make this private once PlatformEvent migration in +// Aura/X11 is done. +Event::Properties GetEventPropertiesFromXEvent(EventType type, + const XEvent& xev) { + using Values = std::vector<uint8_t>; + Event::Properties properties; + if (type == ET_KEY_PRESSED || type == ET_KEY_RELEASED) { + // Keyboard group + uint8_t group = XkbGroupForCoreState(xev.xkey.state); + properties.emplace(kPropertyKeyboardGroup, Values{group}); + + // Hardware keycode + uint8_t hw_keycode = xev.xkey.keycode; + properties.emplace(kPropertyKeyboardHwKeyCode, Values{hw_keycode}); + + // IBus-gtk specific flags + uint8_t ibus_flags = (xev.xkey.state >> kPropertyKeyboardIBusFlagOffset) & + kPropertyKeyboardIBusFlagMask; + properties.emplace(kPropertyKeyboardIBusFlag, Values{ibus_flags}); + + } else if (type == ET_MOUSE_EXITED) { + // NotifyVirtual events are created for intermediate windows that the + // pointer crosses through. These occur when middle clicking. + // Change these into mouse move events. + bool crossing_intermediate_window = xev.xcrossing.detail == NotifyVirtual; + properties.emplace(kPropertyMouseCrossedIntermediateWindow, + crossing_intermediate_window); + } + return properties; +} + } // namespace ui
diff --git a/ui/events/x/x11_event_translation.h b/ui/events/x/x11_event_translation.h index 986fc6d..fad6daa 100644 --- a/ui/events/x/x11_event_translation.h +++ b/ui/events/x/x11_event_translation.h
@@ -8,6 +8,7 @@ #include <memory> #include "base/component_export.h" +#include "ui/events/event.h" #include "ui/events/events_export.h" #include "ui/gfx/x/x11_types.h" @@ -38,6 +39,9 @@ EVENTS_EXPORT std::unique_ptr<TouchEvent> BuildTouchEventFromXEvent( const XEvent& xev); +EVENTS_EXPORT Event::Properties GetEventPropertiesFromXEvent(EventType type, + const XEvent& xev); + } // namespace ui #endif // UI_EVENTS_X_X11_EVENT_TRANSLATION_H_
diff --git a/ui/file_manager/file_manager/foreground/js/quick_view_controller.js b/ui/file_manager/file_manager/foreground/js/quick_view_controller.js index 17fbe1d..92e0d3e 100644 --- a/ui/file_manager/file_manager/foreground/js/quick_view_controller.js +++ b/ui/file_manager/file_manager/foreground/js/quick_view_controller.js
@@ -66,7 +66,7 @@ this.entries_ = []; /** - * The current selection when in check-select mode. + * The current selection index of this.entries_. * @private {number} */ this.currentSelection_ = 0; @@ -197,7 +197,10 @@ } /** - * Changes the currently selected in single-select mode. + * Changes the currently selected entry when in single-select mode. Sets + * the models |selectedIndex| to indirectly trigger onFileSelectionChanged_ + * and populate |this.entries_|. + * * @param {boolean} down True if user pressed down arrow, false if up. * @private */ @@ -220,8 +223,8 @@ } /** - * Changes the currently selected in multi-select mode (aka what the file - * list calls "check-select" mode). + * Changes the currently selected entry when in multi-select mode (file + * list calls this "check-select" mode). * * @param {boolean} down True if user pressed down arrow, false if up. * @private @@ -252,7 +255,7 @@ * @private */ display_(wayToOpen) { - // On opening, always initalise the single-select mode selection. + // On opening Quick View, always reset the current selection index. this.currentSelection_ = 0; this.updateQuickView_().then(() => {
diff --git a/ui/file_manager/integration_tests/file_manager/quick_view.js b/ui/file_manager/integration_tests/file_manager/quick_view.js index b2c7b304..5117a5c 100644 --- a/ui/file_manager/integration_tests/file_manager/quick_view.js +++ b/ui/file_manager/integration_tests/file_manager/quick_view.js
@@ -1342,4 +1342,114 @@ await remoteCall.waitForElement(appId, query.query); } }; + + /** + * Tests the tab-index focus order when sending tab keys when an audio file is + * shown in Quick View. + */ + testcase.openQuickViewTabIndexAudio = async () => { + // Open Files app on Downloads containing ENTRIES.beautiful song. + const appId = await setupAndWaitUntilReady( + RootPath.DOWNLOADS, [ENTRIES.beautiful], []); + + // Open the file in Quick View. + await openQuickView(appId, ENTRIES.beautiful.nameText); + + // Prepare a list of tab-index focus queries. + const tabQueries = [ + {'query': ['#quick-view', '[aria-label="Back"]:focus']}, + {'query': ['#quick-view', '[aria-label="Open"]:focus']}, + {'query': ['#quick-view', '[aria-label="File info"]:focus']}, + ]; + + for (const query of tabQueries) { + // Make the browser dispatch a tab key event to FilesApp. + const result = await sendTestMessage( + {name: 'dispatchTabKey', shift: query.shift || false}); + chrome.test.assertEq( + result, 'tabKeyDispatched', 'Tab key dispatch failure'); + + // Note: Allow 500ms between key events to filter out the focus + // traversal problems noted in crbug.com/907380#c10. + await wait(500); + + // Check: the queried element should gain the focus. + await remoteCall.waitForElement(appId, query.query); + } + + // Send tab keys until Back gains the focus again. + while (true) { + // Make the browser dispatch a tab key event to FilesApp. + const result = + await sendTestMessage({name: 'dispatchTabKey', shift: false}); + chrome.test.assertEq( + result, 'tabKeyDispatched', 'Tab key dispatch failure'); + + // Note: Allow 500ms between key events to filter out the focus + // traversal problems noted in crbug.com/907380#c10. + await wait(500); + + // Check: back should eventually get the focus again. + const activeElement = await remoteCall.callRemoteTestUtil( + 'deepGetActiveElement', appId, []); + if (activeElement.attributes['aria-label'] === 'Back') { + break; + } + } + }; + + /** + * Tests the tab-index focus order when sending tab keys when a video file is + * shown in Quick View. + */ + testcase.openQuickViewTabIndexVideo = async () => { + // Open Files app on Downloads containing ENTRIES.webm video. + const appId = + await setupAndWaitUntilReady(RootPath.DOWNLOADS, [ENTRIES.webm], []); + + // Open the file in Quick View. + await openQuickView(appId, ENTRIES.webm.nameText); + + // Prepare a list of tab-index focus queries. + const tabQueries = [ + {'query': ['#quick-view', '[aria-label="Back"]:focus']}, + {'query': ['#quick-view', '[aria-label="Open"]:focus']}, + {'query': ['#quick-view', '[aria-label="File info"]:focus']}, + ]; + + for (const query of tabQueries) { + // Make the browser dispatch a tab key event to FilesApp. + const result = await sendTestMessage( + {name: 'dispatchTabKey', shift: query.shift || false}); + chrome.test.assertEq( + result, 'tabKeyDispatched', 'Tab key dispatch failure'); + + // Note: Allow 500ms between key events to filter out the focus + // traversal problems noted in crbug.com/907380#c10. + await wait(500); + + // Check: the queried element should gain the focus. + await remoteCall.waitForElement(appId, query.query); + } + + // Send tab keys until Back gains the focus again. + while (true) { + // Make the browser dispatch a tab key event to FilesApp. + const result = + await sendTestMessage({name: 'dispatchTabKey', shift: false}); + chrome.test.assertEq( + result, 'tabKeyDispatched', 'Tab key dispatch failure'); + + // Note: Allow 500ms between key events to filter out the focus + // traversal problems noted in crbug.com/907380#c10. + await wait(500); + + // Check: back should eventually get the focus again. + const activeElement = await remoteCall.callRemoteTestUtil( + 'deepGetActiveElement', appId, []); + if (activeElement.attributes['aria-label'] === 'Back') { + break; + } + } + }; })();
diff --git a/ui/gl/gl_share_group.cc b/ui/gl/gl_share_group.cc index e9386c4b..9292b3d0a 100644 --- a/ui/gl/gl_share_group.cc +++ b/ui/gl/gl_share_group.cc
@@ -8,7 +8,6 @@ #include "build/build_config.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_implementation.h" -#include "ui/gl/gl_surface.h" namespace gl { @@ -25,12 +24,8 @@ void GLShareGroup::RemoveContext(GLContext* context) { contexts_.erase(context); - for (const auto& pair : shared_contexts_) { - if (pair.second == context) { - shared_contexts_.erase(pair.first); - return; - } - } + if (shared_context_ == context) + shared_context_ = nullptr; } void* GLShareGroup::GetHandle() { @@ -50,17 +45,9 @@ return NULL; } -void GLShareGroup::SetSharedContext(GLSurface* compatible, GLContext* context) { +void GLShareGroup::SetSharedContext(GLContext* context) { DCHECK(contexts_.find(context) != contexts_.end()); - shared_contexts_[compatible->GetCompatibilityKey()] = context; -} - -GLContext* GLShareGroup::GetSharedContext(GLSurface* compatible) { - unsigned long compatibility_key = compatible->GetCompatibilityKey(); - auto it = shared_contexts_.find(compatibility_key); - if (it == shared_contexts_.end()) - return nullptr; - return it->second; + shared_context_ = context; } #if defined(OS_MACOSX)
diff --git a/ui/gl/gl_share_group.h b/ui/gl/gl_share_group.h index 99ce887..3a5c622 100644 --- a/ui/gl/gl_share_group.h +++ b/ui/gl/gl_share_group.h
@@ -8,6 +8,7 @@ #include <set> #include <unordered_map> +#include "base/logging.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "build/build_config.h" @@ -16,7 +17,6 @@ namespace gl { class GLContext; -class GLSurface; // A group of GL contexts that share an ID namespace. class GL_EXPORT GLShareGroup : public base::RefCounted<GLShareGroup> { @@ -37,8 +37,8 @@ GLContext* GetContext(); // Sets and returns the shared GL context. Used for context virtualization. - void SetSharedContext(GLSurface* compatible, GLContext* context); - GLContext* GetSharedContext(GLSurface* compatible); + void SetSharedContext(GLContext* context); + GLContext* shared_context() { return shared_context_; } #if defined(OS_MACOSX) // Sets and returns the ID of the renderer that all contexts in this share @@ -57,7 +57,7 @@ typedef std::set<GLContext*> ContextSet; ContextSet contexts_; - std::unordered_map<unsigned long, GLContext*> shared_contexts_; + GLContext* shared_context_ = nullptr; #if defined(OS_MACOSX) int renderer_id_;
diff --git a/ui/gl/gl_surface.cc b/ui/gl/gl_surface.cc index d5542b2..95cc263 100644 --- a/ui/gl/gl_surface.cc +++ b/ui/gl/gl_surface.cc
@@ -139,10 +139,6 @@ return NULL; } -unsigned long GLSurface::GetCompatibilityKey() { - return 0; -} - gfx::VSyncProvider* GLSurface::GetVSyncProvider() { return NULL; } @@ -418,10 +414,6 @@ return surface_->GetConfig(); } -unsigned long GLSurfaceAdapter::GetCompatibilityKey() { - return surface_->GetCompatibilityKey(); -} - GLSurfaceFormat GLSurfaceAdapter::GetFormat() { return surface_->GetFormat(); }
diff --git a/ui/gl/gl_surface.h b/ui/gl/gl_surface.h index 433b398..8e103cd 100644 --- a/ui/gl/gl_surface.h +++ b/ui/gl/gl_surface.h
@@ -197,10 +197,6 @@ // Get the platfrom specific configuration for this surface, if available. virtual void* GetConfig(); - // Get the key corresponding to the set of GLSurfaces that can be made current - // with this GLSurface. - virtual unsigned long GetCompatibilityKey(); - // Get the GL pixel format of the surface. Must be implemented in a // subclass, though it's ok to just "return GLSurfaceFormat()" if // the default is appropriate. @@ -371,7 +367,6 @@ void* GetShareHandle() override; void* GetDisplay() override; void* GetConfig() override; - unsigned long GetCompatibilityKey() override; GLSurfaceFormat GetFormat() override; gfx::VSyncProvider* GetVSyncProvider() override; void SetVSyncEnabled(bool enabled) override;
diff --git a/ui/gl/gl_surface_glx.cc b/ui/gl/gl_surface_glx.cc index 7bdc0f81..d0c4907 100644 --- a/ui/gl/gl_surface_glx.cc +++ b/ui/gl/gl_surface_glx.cc
@@ -750,10 +750,6 @@ return GLSurfaceFormat(); } -unsigned long NativeViewGLSurfaceGLX::GetCompatibilityKey() { - return XVisualIDFromVisual(g_visual); -} - gfx::SwapResult NativeViewGLSurfaceGLX::PostSubBuffer( int x, int y, @@ -888,10 +884,6 @@ return GLSurfaceFormat(); } -unsigned long UnmappedNativeViewGLSurfaceGLX::GetCompatibilityKey() { - return XVisualIDFromVisual(g_visual); -} - UnmappedNativeViewGLSurfaceGLX::~UnmappedNativeViewGLSurfaceGLX() { Destroy(); }
diff --git a/ui/gl/gl_surface_glx.h b/ui/gl/gl_surface_glx.h index 685b499..f2f1dab 100644 --- a/ui/gl/gl_surface_glx.h +++ b/ui/gl/gl_surface_glx.h
@@ -55,8 +55,6 @@ // a GLX drawable. void* GetConfig() override = 0; - unsigned long GetCompatibilityKey() override = 0; - protected: ~GLSurfaceGLX() override; @@ -84,7 +82,6 @@ bool SupportsPostSubBuffer() override; void* GetConfig() override; GLSurfaceFormat GetFormat() override; - unsigned long GetCompatibilityKey() override; gfx::SwapResult PostSubBuffer(int x, int y, int width, @@ -148,7 +145,6 @@ void* GetHandle() override; void* GetConfig() override; GLSurfaceFormat GetFormat() override; - unsigned long GetCompatibilityKey() override; protected: ~UnmappedNativeViewGLSurfaceGLX() override;
diff --git a/ui/ozone/platform/wayland/host/wayland_input_method_context.cc b/ui/ozone/platform/wayland/host/wayland_input_method_context.cc index 37feebe..81a75d4 100644 --- a/ui/ozone/platform/wayland/host/wayland_input_method_context.cc +++ b/ui/ozone/platform/wayland/host/wayland_input_method_context.cc
@@ -90,9 +90,9 @@ auto length = preedit.text.size(); preedit.selection = gfx::Range(length); - preedit.ime_text_spans.push_back( - ImeTextSpan(ImeTextSpan::Type::kComposition, 0, length, - ImeTextSpan::Thickness::kThin, SK_ColorTRANSPARENT)); + preedit.ime_text_spans.push_back(ImeTextSpan( + ImeTextSpan::Type::kComposition, 0, length, ImeTextSpan::Thickness::kThin, + ImeTextSpan::UnderlineStyle::kSolid, SK_ColorTRANSPARENT)); delegate_->OnPreeditChanged(preedit); }
diff --git a/ui/views/cocoa/text_input_host.mm b/ui/views/cocoa/text_input_host.mm index ddeba0c4..e7fa009 100644 --- a/ui/views/cocoa/text_input_host.mm +++ b/ui/views/cocoa/text_input_host.mm
@@ -292,9 +292,10 @@ // the Chrome renderer. Add code to extract underlines from |text| once our // render text implementation supports thick underlines and discontinuous // underlines for consecutive characters. See http://crbug.com/612675. - composition.ime_text_spans.push_back( - ui::ImeTextSpan(ui::ImeTextSpan::Type::kComposition, 0, text.length(), - ui::ImeTextSpan::Thickness::kThin, SK_ColorTRANSPARENT)); + composition.ime_text_spans.push_back(ui::ImeTextSpan( + ui::ImeTextSpan::Type::kComposition, 0, text.length(), + ui::ImeTextSpan::Thickness::kThin, + ui::ImeTextSpan::UnderlineStyle::kSolid, SK_ColorTRANSPARENT)); text_input_client_->SetCompositionText(composition); }